Cross-merge networking fixes after downstream PR. No conflicts (or adjacent changes of note).
Unified · Split
| @@ -377,6 +377,7 @@ Matthew Wilcox <willy@infradead.org> <willy@debian.org> · 376 unmodified lines | |||
| 377 | Matthew Wilcox <willy@infradead.org> <willy@linux.intel.com> | 377 | Matthew Wilcox <willy@infradead.org> <willy@linux.intel.com> |
| 378 | Matthew Wilcox <willy@infradead.org> <willy@parisc-linux.org> | 378 | Matthew Wilcox <willy@infradead.org> <willy@parisc-linux.org> |
| 379 | Matthias Fuchs <socketcan@esd.eu> <matthias.fuchs@esd.eu> | 379 | Matthias Fuchs <socketcan@esd.eu> <matthias.fuchs@esd.eu> |
| 380 | Matthieu Baerts <matttbe@kernel.org> <matthieu.baerts@tessares.net> | ||
| 380 | Matthieu CASTET <castet.matthieu@free.fr> | 381 | Matthieu CASTET <castet.matthieu@free.fr> |
| 381 | Matti Vaittinen <mazziesaccount@gmail.com> <matti.vaittinen@fi.rohmeurope.com> | 382 | Matti Vaittinen <mazziesaccount@gmail.com> <matti.vaittinen@fi.rohmeurope.com> |
| 382 | Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting> | 383 | Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting> |
| @@ -92,6 +92,13 @@ Brief summary of control files. · 91 unmodified lines | |||
| 92 | memory.oom_control set/show oom controls. | 92 | memory.oom_control set/show oom controls. |
| 93 | memory.numa_stat show the number of memory usage per numa | 93 | memory.numa_stat show the number of memory usage per numa |
| 94 | node | 94 | node |
| 95 | memory.kmem.limit_in_bytes Deprecated knob to set and read the kernel | ||
| 96 | memory hard limit. Kernel hard limit is not | ||
| 97 | supported since 5.16. Writing any value to | ||
| 98 | do file will not have any effect same as if | ||
| 99 | nokmem kernel parameter was specified. | ||
| 100 | Kernel memory is still charged and reported | ||
| 101 | by memory.kmem.usage_in_bytes. | ||
| 95 | memory.kmem.usage_in_bytes show current kernel memory allocation | 102 | memory.kmem.usage_in_bytes show current kernel memory allocation |
| 96 | memory.kmem.failcnt show the number of kernel memory usage | 103 | memory.kmem.failcnt show the number of kernel memory usage |
| 97 | hits limits | 104 | hits limits |
| @@ -175,6 +175,8 @@ infrastructure: · 174 unmodified lines | |||
| 175 | +------------------------------+---------+---------+ | 175 | +------------------------------+---------+---------+ |
| 176 | | Name | bits | visible | | 176 | | Name | bits | visible | |
| 177 | +------------------------------+---------+---------+ | 177 | +------------------------------+---------+---------+ |
| 178 | | SME | [27-24] | y | | ||
| 179 | +------------------------------+---------+---------+ | ||
| 178 | | MTE | [11-8] | y | | 180 | | MTE | [11-8] | y | |
| 179 | +------------------------------+---------+---------+ | 181 | +------------------------------+---------+---------+ |
| 180 | | SSBS | [7-4] | y | | 182 | | SSBS | [7-4] | y | |
| @@ -288,8 +290,18 @@ infrastructure: · 107 unmodified lines | |||
| 288 | +------------------------------+---------+---------+ | 290 | +------------------------------+---------+---------+ |
| 289 | | Name | bits | visible | | 291 | | Name | bits | visible | |
| 290 | +------------------------------+---------+---------+ | 292 | +------------------------------+---------+---------+ |
| 293 | | CSSC | [55-52] | y | | ||
| 294 | +------------------------------+---------+---------+ | ||
| 295 | | RPRFM | [51-48] | y | | ||
| 296 | +------------------------------+---------+---------+ | ||
| 297 | | BC | [23-20] | y | | ||
| 298 | +------------------------------+---------+---------+ | ||
| 291 | | MOPS | [19-16] | y | | 299 | | MOPS | [19-16] | y | |
| 292 | +------------------------------+---------+---------+ | 300 | +------------------------------+---------+---------+ |
| 301 | | APA3 | [15-12] | y | | ||
| 302 | +------------------------------+---------+---------+ | ||
| 303 | | GPA3 | [11-8] | y | | ||
| 304 | +------------------------------+---------+---------+ | ||
| 293 | | RPRES | [7-4] | y | | 305 | | RPRES | [7-4] | y | |
| 294 | +------------------------------+---------+---------+ | 306 | +------------------------------+---------+---------+ |
| 295 | | WFXT | [3-0] | y | | 307 | | WFXT | [3-0] | y | |
| @@ -305,6 +305,9 @@ HWCAP2_SMEF16F16 · 304 unmodified lines | |||
| 305 | HWCAP2_MOPS | 305 | HWCAP2_MOPS |
| 306 | Functionality implied by ID_AA64ISAR2_EL1.MOPS == 0b0001. | 306 | Functionality implied by ID_AA64ISAR2_EL1.MOPS == 0b0001. |
| 307 | 307 | ||
| 308 | HWCAP2_HBC | ||
| 309 | Functionality implied by ID_AA64ISAR2_EL1.BC == 0b0001. | ||
| 310 | |||
| 308 | 4. Unused AT_HWCAP bits | 311 | 4. Unused AT_HWCAP bits |
| 309 | ----------------------- | 312 | ----------------------- |
| 310 | 313 | ||
| @@ -381,9 +381,9 @@ Documentation of LoongArch ISA: · 380 unmodified lines | |||
| 381 | 381 | ||
| 382 | Documentation of LoongArch ELF psABI: | 382 | Documentation of LoongArch ELF psABI: |
| 383 | 383 | ||
| 384 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-CN.pdf (in Chinese) | 384 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-CN.pdf (in Chinese) |
| 385 | 385 | ||
| 386 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-EN.pdf (in English) | 386 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-EN.pdf (in English) |
| 387 | 387 | ||
| 388 | Linux kernel repository of Loongson and LoongArch: | 388 | Linux kernel repository of Loongson and LoongArch: |
| 389 | 389 | ||
| @@ -38,6 +38,7 @@ patternProperties: · 37 unmodified lines | |||
| 38 | ID number 0 and the slave drive will have ID number 1. The PATA port | 38 | ID number 0 and the slave drive will have ID number 1. The PATA port |
| 39 | nodes will be named "ide-port". | 39 | nodes will be named "ide-port". |
| 40 | type: object | 40 | type: object |
| 41 | additionalProperties: false | ||
| 41 | 42 | ||
| 42 | properties: | 43 | properties: |
| 43 | reg: | 44 | reg: |
| @@ -37,6 +37,9 @@ properties: · 36 unmodified lines | |||
| 37 | maxItems: 1 | 37 | maxItems: 1 |
| 38 | 38 | ||
| 39 | '#clock-cells': | 39 | '#clock-cells': |
| 40 | description: | ||
| 41 | The index in the assigned-clocks is mapped to the output clock as below | ||
| 42 | 0 - REF, 1 - SE1, 2 - SE2, 3 - SE3, 4 - DIFF1, 5 - DIFF2. | ||
| 40 | const: 1 | 43 | const: 1 |
| 41 | 44 | ||
| 42 | clocks: | 45 | clocks: |
| @@ -68,7 +71,7 @@ examples: · 25 unmodified lines | |||
| 68 | reg = <0x68>; | 71 | reg = <0x68>; |
| 69 | #clock-cells = <1>; | 72 | #clock-cells = <1>; |
| 70 | 73 | ||
| 71 | clocks = <&x1_x2>; | 74 | clocks = <&x1>; |
| 72 | 75 | ||
| 73 | renesas,settings = [ | 76 | renesas,settings = [ |
| 74 | 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf | 77 | 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf |
| @@ -79,8 +82,8 @@ examples: · 4 unmodified lines | |||
| 79 | assigned-clocks = <&versa3 0>, <&versa3 1>, | 82 | assigned-clocks = <&versa3 0>, <&versa3 1>, |
| 80 | <&versa3 2>, <&versa3 3>, | 83 | <&versa3 2>, <&versa3 3>, |
| 81 | <&versa3 4>, <&versa3 5>; | 84 | <&versa3 4>, <&versa3 5>; |
| 82 | assigned-clock-rates = <12288000>, <25000000>, | 85 | assigned-clock-rates = <24000000>, <11289600>, |
| 83 | <12000000>, <11289600>, | 86 | <11289600>, <12000000>, |
| 84 | <11289600>, <24000000>; | 87 | <25000000>, <12288000>; |
| 85 | }; | 88 | }; |
| 86 | }; | 89 | }; |
| @@ -9,6 +9,9 @@ title: Freescale MXS Inter IC (I2C) Controller · 8 unmodified lines | |||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Shawn Guo <shawnguo@kernel.org> | 10 | - Shawn Guo <shawnguo@kernel.org> |
| 11 | 11 | ||
| 12 | allOf: | ||
| 13 | - $ref: /schemas/i2c/i2c-controller.yaml# | ||
| 14 | |||
| 12 | properties: | 15 | properties: |
| 13 | compatible: | 16 | compatible: |
| 14 | enum: | 17 | enum: |
| @@ -37,7 +40,7 @@ required: · 22 unmodified lines | |||
| 37 | - dmas | 40 | - dmas |
| 38 | - dma-names | 41 | - dma-names |
| 39 | 42 | ||
| 40 | additionalProperties: false | 43 | unevaluatedProperties: false |
| 41 | 44 | ||
| 42 | examples: | 45 | examples: |
| 43 | - | | 46 | - | |
| @@ -270,6 +270,7 @@ allOf: · 269 unmodified lines | |||
| 270 | contains: | 270 | contains: |
| 271 | enum: | 271 | enum: |
| 272 | - qcom,msm8998-smmu-v2 | 272 | - qcom,msm8998-smmu-v2 |
| 273 | - qcom,sdm630-smmu-v2 | ||
| 273 | then: | 274 | then: |
| 274 | anyOf: | 275 | anyOf: |
| 275 | - properties: | 276 | - properties: |
| @@ -311,7 +312,6 @@ allOf: · 35 unmodified lines | |||
| 311 | compatible: | 312 | compatible: |
| 312 | contains: | 313 | contains: |
| 313 | enum: | 314 | enum: |
| 314 | - qcom,sdm630-smmu-v2 | ||
| 315 | - qcom,sm6375-smmu-v2 | 315 | - qcom,sm6375-smmu-v2 |
| 316 | then: | 316 | then: |
| 317 | anyOf: | 317 | anyOf: |
| @@ -31,10 +31,6 @@ properties: · 30 unmodified lines | |||
| 31 | charger: | 31 | charger: |
| 32 | $ref: /schemas/power/supply/maxim,max77693.yaml | 32 | $ref: /schemas/power/supply/maxim,max77693.yaml |
| 33 | 33 | ||
| 34 | connector: | ||
| 35 | $ref: /schemas/connector/usb-connector.yaml# | ||
| 36 | unevaluatedProperties: false | ||
| 37 | |||
| 38 | led: | 34 | led: |
| 39 | $ref: /schemas/leds/maxim,max77693.yaml | 35 | $ref: /schemas/leds/maxim,max77693.yaml |
| 40 | 36 | ||
| @@ -11,11 +11,16 @@ maintainers: · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | properties: | 12 | properties: |
| 13 | compatible: | 13 | compatible: |
| 14 | items: | 14 | oneOf: |
| 15 | - enum: | 15 | - items: |
| 16 | - loongson,ls2k0500-pmc | 16 | - const: loongson,ls2k0500-pmc |
| 17 | - loongson,ls2k1000-pmc | 17 | - const: syscon |
| 18 | - const: syscon | 18 | - items: |
| 19 | - enum: | ||
| 20 | - loongson,ls2k1000-pmc | ||
| 21 | - loongson,ls2k2000-pmc | ||
| 22 | - const: loongson,ls2k0500-pmc | ||
| 23 | - const: syscon | ||
| 19 | 24 | ||
| 20 | reg: | 25 | reg: |
| 21 | maxItems: 1 | 26 | maxItems: 1 |
| @@ -32,6 +37,18 @@ properties: · 10 unmodified lines | |||
| 32 | addition, the PM need according to it to indicate that current | 37 | addition, the PM need according to it to indicate that current |
| 33 | SoC whether support Suspend To RAM. | 38 | SoC whether support Suspend To RAM. |
| 34 | 39 | ||
| 40 | syscon-poweroff: | ||
| 41 | $ref: /schemas/power/reset/syscon-poweroff.yaml# | ||
| 42 | type: object | ||
| 43 | description: | ||
| 44 | Node for power off method | ||
| 45 | |||
| 46 | syscon-reboot: | ||
| 47 | $ref: /schemas/power/reset/syscon-reboot.yaml# | ||
| 48 | type: object | ||
| 49 | description: | ||
| 50 | Node for reboot method | ||
| 51 | |||
| 35 | required: | 52 | required: |
| 36 | - compatible | 53 | - compatible |
| 37 | - reg | 54 | - reg |
| @@ -44,9 +61,23 @@ examples: · 6 unmodified lines | |||
| 44 | #include <dt-bindings/interrupt-controller/irq.h> | 61 | #include <dt-bindings/interrupt-controller/irq.h> |
| 45 | 62 | ||
| 46 | power-management@1fe27000 { | 63 | power-management@1fe27000 { |
| 47 | compatible = "loongson,ls2k1000-pmc", "syscon"; | 64 | compatible = "loongson,ls2k1000-pmc", "loongson,ls2k0500-pmc", "syscon"; |
| 48 | reg = <0x1fe27000 0x58>; | 65 | reg = <0x1fe27000 0x58>; |
| 49 | interrupt-parent = <&liointc1>; | 66 | interrupt-parent = <&liointc1>; |
| 50 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | 67 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; |
| 51 | loongson,suspend-address = <0x0 0x1c000500>; | 68 | loongson,suspend-address = <0x0 0x1c000500>; |
| 69 | |||
| 70 | syscon-reboot { | ||
| 71 | compatible = "syscon-reboot"; | ||
| 72 | offset = <0x30>; | ||
| 73 | mask = <0x1>; | ||
| 74 | }; | ||
| 75 | |||
| 76 | syscon-poweroff { | ||
| 77 | compatible = "syscon-poweroff"; | ||
| 78 | regmap = <&pmc>; | ||
| 79 | offset = <0x14>; | ||
| 80 | mask = <0x3c00>; | ||
| 81 | value = <0x3c00>; | ||
| 82 | }; | ||
| 52 | }; | 83 | }; |
| @@ -22,6 +22,13 @@ properties: · 21 unmodified lines | |||
| 22 | - const: fsl,imx35-cspi | 22 | - const: fsl,imx35-cspi |
| 23 | - const: fsl,imx51-ecspi | 23 | - const: fsl,imx51-ecspi |
| 24 | - const: fsl,imx53-ecspi | 24 | - const: fsl,imx53-ecspi |
| 25 | - items: | ||
| 26 | - enum: | ||
| 27 | - fsl,imx25-cspi | ||
| 28 | - fsl,imx50-cspi | ||
| 29 | - fsl,imx51-cspi | ||
| 30 | - fsl,imx53-cspi | ||
| 31 | - const: fsl,imx35-cspi | ||
| 25 | - items: | 32 | - items: |
| 26 | - const: fsl,imx8mp-ecspi | 33 | - const: fsl,imx8mp-ecspi |
| 27 | - const: fsl,imx6ul-ecspi | 34 | - const: fsl,imx6ul-ecspi |
| @@ -949,3 +949,99 @@ mmap_lock held. All in-tree users have been audited and do not seem to · 948 unmodified lines | |||
| 949 | depend on the mmap_lock being held, but out of tree users should verify | 949 | depend on the mmap_lock being held, but out of tree users should verify |
| 950 | for themselves. If they do need it, they can return VM_FAULT_RETRY to | 950 | for themselves. If they do need it, they can return VM_FAULT_RETRY to |
| 951 | be called with the mmap_lock held. | 951 | be called with the mmap_lock held. |
| 952 | |||
| 953 | --- | ||
| 954 | |||
| 955 | **mandatory** | ||
| 956 | |||
| 957 | The order of opening block devices and matching or creating superblocks has | ||
| 958 | changed. | ||
| 959 | |||
| 960 | The old logic opened block devices first and then tried to find a | ||
| 961 | suitable superblock to reuse based on the block device pointer. | ||
| 962 | |||
| 963 | The new logic tries to find a suitable superblock first based on the device | ||
| 964 | number, and opening the block device afterwards. | ||
| 965 | |||
| 966 | Since opening block devices cannot happen under s_umount because of lock | ||
| 967 | ordering requirements s_umount is now dropped while opening block devices and | ||
| 968 | reacquired before calling fill_super(). | ||
| 969 | |||
| 970 | In the old logic concurrent mounters would find the superblock on the list of | ||
| 971 | superblocks for the filesystem type. Since the first opener of the block device | ||
| 972 | would hold s_umount they would wait until the superblock became either born or | ||
| 973 | was discarded due to initialization failure. | ||
| 974 | |||
| 975 | Since the new logic drops s_umount concurrent mounters could grab s_umount and | ||
| 976 | would spin. Instead they are now made to wait using an explicit wait-wake | ||
| 977 | mechanism without having to hold s_umount. | ||
| 978 | |||
| 979 | --- | ||
| 980 | |||
| 981 | **mandatory** | ||
| 982 | |||
| 983 | The holder of a block device is now the superblock. | ||
| 984 | |||
| 985 | The holder of a block device used to be the file_system_type which wasn't | ||
| 986 | particularly useful. It wasn't possible to go from block device to owning | ||
| 987 | superblock without matching on the device pointer stored in the superblock. | ||
| 988 | This mechanism would only work for a single device so the block layer couldn't | ||
| 989 | find the owning superblock of any additional devices. | ||
| 990 | |||
| 991 | In the old mechanism reusing or creating a superblock for a racing mount(2) and | ||
| 992 | umount(2) relied on the file_system_type as the holder. This was severly | ||
| 993 | underdocumented however: | ||
| 994 | |||
| 995 | (1) Any concurrent mounter that managed to grab an active reference on an | ||
| 996 | existing superblock was made to wait until the superblock either became | ||
| 997 | ready or until the superblock was removed from the list of superblocks of | ||
| 998 | the filesystem type. If the superblock is ready the caller would simple | ||
| 999 | reuse it. | ||
| 1000 | |||
| 1001 | (2) If the mounter came after deactivate_locked_super() but before | ||
| 1002 | the superblock had been removed from the list of superblocks of the | ||
| 1003 | filesystem type the mounter would wait until the superblock was shutdown, | ||
| 1004 | reuse the block device and allocate a new superblock. | ||
| 1005 | |||
| 1006 | (3) If the mounter came after deactivate_locked_super() and after | ||
| 1007 | the superblock had been removed from the list of superblocks of the | ||
| 1008 | filesystem type the mounter would reuse the block device and allocate a new | ||
| 1009 | superblock (the bd_holder point may still be set to the filesystem type). | ||
| 1010 | |||
| 1011 | Because the holder of the block device was the file_system_type any concurrent | ||
| 1012 | mounter could open the block devices of any superblock of the same | ||
| 1013 | file_system_type without risking seeing EBUSY because the block device was | ||
| 1014 | still in use by another superblock. | ||
| 1015 | |||
| 1016 | Making the superblock the owner of the block device changes this as the holder | ||
| 1017 | is now a unique superblock and thus block devices associated with it cannot be | ||
| 1018 | reused by concurrent mounters. So a concurrent mounter in (2) could suddenly | ||
| 1019 | see EBUSY when trying to open a block device whose holder was a different | ||
| 1020 | superblock. | ||
| 1021 | |||
| 1022 | The new logic thus waits until the superblock and the devices are shutdown in | ||
| 1023 | ->kill_sb(). Removal of the superblock from the list of superblocks of the | ||
| 1024 | filesystem type is now moved to a later point when the devices are closed: | ||
| 1025 | |||
| 1026 | (1) Any concurrent mounter managing to grab an active reference on an existing | ||
| 1027 | superblock is made to wait until the superblock is either ready or until | ||
| 1028 | the superblock and all devices are shutdown in ->kill_sb(). If the | ||
| 1029 | superblock is ready the caller will simply reuse it. | ||
| 1030 | |||
| 1031 | (2) If the mounter comes after deactivate_locked_super() but before | ||
| 1032 | the superblock has been removed from the list of superblocks of the | ||
| 1033 | filesystem type the mounter is made to wait until the superblock and the | ||
| 1034 | devices are shut down in ->kill_sb() and the superblock is removed from the | ||
| 1035 | list of superblocks of the filesystem type. The mounter will allocate a new | ||
| 1036 | superblock and grab ownership of the block device (the bd_holder pointer of | ||
| 1037 | the block device will be set to the newly allocated superblock). | ||
| 1038 | |||
| 1039 | (3) This case is now collapsed into (2) as the superblock is left on the list | ||
| 1040 | of superblocks of the filesystem type until all devices are shutdown in | ||
| 1041 | ->kill_sb(). In other words, if the superblock isn't on the list of | ||
| 1042 | superblock of the filesystem type anymore then it has given up ownership of | ||
| 1043 | all associated block devices (the bd_holder pointer is NULL). | ||
| 1044 | |||
| 1045 | As this is a VFS level change it has no practical consequences for filesystems | ||
| 1046 | other than that all of them must use one of the provided kill_litter_super(), | ||
| 1047 | kill_anon_super(), or kill_block_super() helpers. | ||
| @@ -573,6 +573,32 @@ above, leading to: · 572 unmodified lines | |||
| 573 | bool "Support for foo hardware" | 573 | bool "Support for foo hardware" |
| 574 | depends on ARCH_FOO_VENDOR || COMPILE_TEST | 574 | depends on ARCH_FOO_VENDOR || COMPILE_TEST |
| 575 | 575 | ||
| 576 | Optional dependencies | ||
| 577 | ~~~~~~~~~~~~~~~~~~~~~ | ||
| 578 | |||
| 579 | Some drivers are able to optionally use a feature from another module | ||
| 580 | or build cleanly with that module disabled, but cause a link failure | ||
| 581 | when trying to use that loadable module from a built-in driver. | ||
| 582 | |||
| 583 | The most common way to express this optional dependency in Kconfig logic | ||
| 584 | uses the slightly counterintuitive:: | ||
| 585 | |||
| 586 | config FOO | ||
| 587 | tristate "Support for foo hardware" | ||
| 588 | depends on BAR || !BAR | ||
| 589 | |||
| 590 | This means that there is either a dependency on BAR that disallows | ||
| 591 | the combination of FOO=y with BAR=m, or BAR is completely disabled. | ||
| 592 | For a more formalized approach if there are multiple drivers that have | ||
| 593 | the same dependency, a helper symbol can be used, like:: | ||
| 594 | |||
| 595 | config FOO | ||
| 596 | tristate "Support for foo hardware" | ||
| 597 | depends on BAR_OPTIONAL | ||
| 598 | |||
| 599 | config BAR_OPTIONAL | ||
| 600 | def_tristate BAR || !BAR | ||
| 601 | |||
| 576 | Kconfig recursive dependency limitations | 602 | Kconfig recursive dependency limitations |
| 577 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 603 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 578 | 604 | ||
| @@ -36,11 +36,11 @@ EXAMPLE · 35 unmodified lines | |||
| 36 | In the example below, **rtla timerlat hist** is set to run for *10* minutes, | 36 | In the example below, **rtla timerlat hist** is set to run for *10* minutes, |
| 37 | in the cpus *0-4*, *skipping zero* only lines. Moreover, **rtla timerlat | 37 | in the cpus *0-4*, *skipping zero* only lines. Moreover, **rtla timerlat |
| 38 | hist** will change the priority of the *timerlat* threads to run under | 38 | hist** will change the priority of the *timerlat* threads to run under |
| 39 | *SCHED_DEADLINE* priority, with a *10us* runtime every *1ms* period. The | 39 | *SCHED_DEADLINE* priority, with a *100us* runtime every *1ms* period. The |
| 40 | *1ms* period is also passed to the *timerlat* tracer. Auto-analysis is disabled | 40 | *1ms* period is also passed to the *timerlat* tracer. Auto-analysis is disabled |
| 41 | to reduce overhead :: | 41 | to reduce overhead :: |
| 42 | 42 | ||
| 43 | [root@alien ~]# timerlat hist -d 10m -c 0-4 -P d:100us:1ms -p 1ms --no-aa | 43 | [root@alien ~]# timerlat hist -d 10m -c 0-4 -P d:100us:1ms -p 1000 --no-aa |
| 44 | # RTLA timerlat histogram | 44 | # RTLA timerlat histogram |
| 45 | # Time unit is microseconds (us) | 45 | # Time unit is microseconds (us) |
| 46 | # Duration: 0 00:10:00 | 46 | # Duration: 0 00:10:00 |
| @@ -344,9 +344,9 @@ LoongArch指令集架构的文档: · 343 unmodified lines | |||
| 344 | 344 | ||
| 345 | LoongArch的ELF psABI文档: | 345 | LoongArch的ELF psABI文档: |
| 346 | 346 | ||
| 347 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-CN.pdf (中文版) | 347 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-CN.pdf (中文版) |
| 348 | 348 | ||
| 349 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-EN.pdf (英文版) | 349 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-EN.pdf (英文版) |
| 350 | 350 | ||
| 351 | Loongson与LoongArch的Linux内核源码仓库: | 351 | Loongson与LoongArch的Linux内核源码仓库: |
| 352 | 352 | ||
| @@ -470,7 +470,6 @@ F: drivers/hwmon/adm1029.c · 469 unmodified lines | |||
| 470 | ADM8211 WIRELESS DRIVER | 470 | ADM8211 WIRELESS DRIVER |
| 471 | L: linux-wireless@vger.kernel.org | 471 | L: linux-wireless@vger.kernel.org |
| 472 | S: Orphan | 472 | S: Orphan |
| 473 | W: https://wireless.wiki.kernel.org/ | ||
| 474 | F: drivers/net/wireless/admtek/adm8211.* | 473 | F: drivers/net/wireless/admtek/adm8211.* |
| 475 | 474 | ||
| 476 | ADP1653 FLASH CONTROLLER DRIVER | 475 | ADP1653 FLASH CONTROLLER DRIVER |
| @@ -1662,7 +1661,7 @@ F: arch/arm*/include/asm/perf_event.h · 1185 unmodified lines | |||
| 1662 | F: arch/arm*/kernel/hw_breakpoint.c | 1661 | F: arch/arm*/kernel/hw_breakpoint.c |
| 1663 | F: arch/arm*/kernel/perf_* | 1662 | F: arch/arm*/kernel/perf_* |
| 1664 | F: drivers/perf/ | 1663 | F: drivers/perf/ |
| 1665 | F: include/linux/perf/arm_pmu.h | 1664 | F: include/linux/perf/arm_pmu*.h |
| 1666 | 1665 | ||
| 1667 | ARM PORT | 1666 | ARM PORT |
| 1668 | M: Russell King <linux@armlinux.org.uk> | 1667 | M: Russell King <linux@armlinux.org.uk> |
| @@ -1963,12 +1962,12 @@ F: drivers/irqchip/irq-aspeed-i2c-ic.c · 294 unmodified lines | |||
| 1963 | 1962 | ||
| 1964 | ARM/ASPEED MACHINE SUPPORT | 1963 | ARM/ASPEED MACHINE SUPPORT |
| 1965 | M: Joel Stanley <joel@jms.id.au> | 1964 | M: Joel Stanley <joel@jms.id.au> |
| 1966 | R: Andrew Jeffery <andrew@aj.id.au> | 1965 | R: Andrew Jeffery <andrew@codeconstruct.com.au> |
| 1967 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1966 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1968 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) | 1967 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) |
| 1969 | S: Supported | 1968 | S: Supported |
| 1970 | Q: https://patchwork.ozlabs.org/project/linux-aspeed/list/ | 1969 | Q: https://patchwork.ozlabs.org/project/linux-aspeed/list/ |
| 1971 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git | 1970 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc.git |
| 1972 | F: Documentation/devicetree/bindings/arm/aspeed/ | 1971 | F: Documentation/devicetree/bindings/arm/aspeed/ |
| 1973 | F: arch/arm/boot/dts/aspeed/ | 1972 | F: arch/arm/boot/dts/aspeed/ |
| 1974 | F: arch/arm/mach-aspeed/ | 1973 | F: arch/arm/mach-aspeed/ |
| @@ -3058,7 +3057,7 @@ F: Documentation/devicetree/bindings/peci/peci-aspeed.yaml · 1083 unmodified lines | |||
| 3058 | F: drivers/peci/controller/peci-aspeed.c | 3057 | F: drivers/peci/controller/peci-aspeed.c |
| 3059 | 3058 | ||
| 3060 | ASPEED PINCTRL DRIVERS | 3059 | ASPEED PINCTRL DRIVERS |
| 3061 | M: Andrew Jeffery <andrew@aj.id.au> | 3060 | M: Andrew Jeffery <andrew@codeconstruct.com.au> |
| 3062 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) | 3061 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) |
| 3063 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) | 3062 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) |
| 3064 | L: linux-gpio@vger.kernel.org | 3063 | L: linux-gpio@vger.kernel.org |
| @@ -3075,7 +3074,7 @@ F: drivers/irqchip/irq-aspeed-scu-ic.c · 10 unmodified lines | |||
| 3075 | F: include/dt-bindings/interrupt-controller/aspeed-scu-ic.h | 3074 | F: include/dt-bindings/interrupt-controller/aspeed-scu-ic.h |
| 3076 | 3075 | ||
| 3077 | ASPEED SD/MMC DRIVER | 3076 | ASPEED SD/MMC DRIVER |
| 3078 | M: Andrew Jeffery <andrew@aj.id.au> | 3077 | M: Andrew Jeffery <andrew@codeconstruct.com.au> |
| 3079 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) | 3078 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) |
| 3080 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) | 3079 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) |
| 3081 | L: linux-mmc@vger.kernel.org | 3080 | L: linux-mmc@vger.kernel.org |
| @@ -4083,7 +4082,7 @@ F: drivers/net/wireless/broadcom/brcm80211/ · 1001 unmodified lines | |||
| 4083 | 4082 | ||
| 4084 | BROADCOM BRCMSTB GPIO DRIVER | 4083 | BROADCOM BRCMSTB GPIO DRIVER |
| 4085 | M: Doug Berger <opendmb@gmail.com> | 4084 | M: Doug Berger <opendmb@gmail.com> |
| 4086 | M: Florian Fainelli <florian.fainelli@broadcom> | 4085 | M: Florian Fainelli <florian.fainelli@broadcom.com> |
| 4087 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> | 4086 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 4088 | S: Supported | 4087 | S: Supported |
| 4089 | F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 4088 | F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml |
| @@ -6656,9 +6655,9 @@ F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml · 2566 unmodified lines | |||
| 6656 | F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c | 6655 | F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c |
| 6657 | 6656 | ||
| 6658 | DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS | 6657 | DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS |
| 6659 | M: Ben Skeggs <bskeggs@redhat.com> | ||
| 6660 | M: Karol Herbst <kherbst@redhat.com> | 6658 | M: Karol Herbst <kherbst@redhat.com> |
| 6661 | M: Lyude Paul <lyude@redhat.com> | 6659 | M: Lyude Paul <lyude@redhat.com> |
| 6660 | M: Danilo Krummrich <dakr@redhat.com> | ||
| 6662 | L: dri-devel@lists.freedesktop.org | 6661 | L: dri-devel@lists.freedesktop.org |
| 6663 | L: nouveau@lists.freedesktop.org | 6662 | L: nouveau@lists.freedesktop.org |
| 6664 | S: Supported | 6663 | S: Supported |
| @@ -8885,7 +8884,7 @@ F: drivers/gpio/gpio-mockup.c · 2220 unmodified lines | |||
| 8885 | F: tools/testing/selftests/gpio/ | 8884 | F: tools/testing/selftests/gpio/ |
| 8886 | 8885 | ||
| 8887 | GPIO REGMAP | 8886 | GPIO REGMAP |
| 8888 | R: Michael Walle <michael@walle.cc> | 8887 | M: Michael Walle <michael@walle.cc> |
| 8889 | S: Maintained | 8888 | S: Maintained |
| 8890 | F: drivers/gpio/gpio-regmap.c | 8889 | F: drivers/gpio/gpio-regmap.c |
| 8891 | F: include/linux/gpio/regmap.h | 8890 | F: include/linux/gpio/regmap.h |
| @@ -9542,10 +9541,8 @@ F: Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml · 650 unmodified lines | |||
| 9542 | F: drivers/iio/pressure/mprls0025pa.c | 9541 | F: drivers/iio/pressure/mprls0025pa.c |
| 9543 | 9542 | ||
| 9544 | HOST AP DRIVER | 9543 | HOST AP DRIVER |
| 9545 | M: Jouni Malinen <j@w1.fi> | ||
| 9546 | L: linux-wireless@vger.kernel.org | 9544 | L: linux-wireless@vger.kernel.org |
| 9547 | S: Obsolete | 9545 | S: Obsolete |
| 9548 | W: http://w1.fi/hostap-driver.html | ||
| 9549 | F: drivers/net/wireless/intersil/hostap/ | 9546 | F: drivers/net/wireless/intersil/hostap/ |
| 9550 | 9547 | ||
| 9551 | HP BIOSCFG DRIVER | 9548 | HP BIOSCFG DRIVER |
| @@ -13627,6 +13624,7 @@ F: drivers/net/ethernet/mellanox/mlxfw/ · 4075 unmodified lines | |||
| 13627 | 13624 | ||
| 13628 | MELLANOX HARDWARE PLATFORM SUPPORT | 13625 | MELLANOX HARDWARE PLATFORM SUPPORT |
| 13629 | M: Hans de Goede <hdegoede@redhat.com> | 13626 | M: Hans de Goede <hdegoede@redhat.com> |
| 13627 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | ||
| 13630 | M: Mark Gross <markgross@kernel.org> | 13628 | M: Mark Gross <markgross@kernel.org> |
| 13631 | M: Vadim Pasternak <vadimp@nvidia.com> | 13629 | M: Vadim Pasternak <vadimp@nvidia.com> |
| 13632 | L: platform-driver-x86@vger.kernel.org | 13630 | L: platform-driver-x86@vger.kernel.org |
| @@ -14221,6 +14219,7 @@ F: drivers/platform/surface/surface_gpe.c · 588 unmodified lines | |||
| 14221 | 14219 | ||
| 14222 | MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT | 14220 | MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT |
| 14223 | M: Hans de Goede <hdegoede@redhat.com> | 14221 | M: Hans de Goede <hdegoede@redhat.com> |
| 14222 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | ||
| 14224 | M: Mark Gross <markgross@kernel.org> | 14223 | M: Mark Gross <markgross@kernel.org> |
| 14225 | M: Maximilian Luz <luzmaximilian@gmail.com> | 14224 | M: Maximilian Luz <luzmaximilian@gmail.com> |
| 14226 | L: platform-driver-x86@vger.kernel.org | 14225 | L: platform-driver-x86@vger.kernel.org |
| @@ -14958,7 +14957,7 @@ K: macsec · 731 unmodified lines | |||
| 14958 | K: \bmdo_ | 14957 | K: \bmdo_ |
| 14959 | 14958 | ||
| 14960 | NETWORKING [MPTCP] | 14959 | NETWORKING [MPTCP] |
| 14961 | M: Matthieu Baerts <matthieu.baerts@tessares.net> | 14960 | M: Matthieu Baerts <matttbe@kernel.org> |
| 14962 | M: Mat Martineau <martineau@kernel.org> | 14961 | M: Mat Martineau <martineau@kernel.org> |
| 14963 | L: netdev@vger.kernel.org | 14962 | L: netdev@vger.kernel.org |
| 14964 | L: mptcp@lists.linux.dev | 14963 | L: mptcp@lists.linux.dev |
| @@ -17613,6 +17612,7 @@ M: Kalle Valo <kvalo@kernel.org> · 2648 unmodified lines | |||
| 17613 | M: Jeff Johnson <quic_jjohnson@quicinc.com> | 17612 | M: Jeff Johnson <quic_jjohnson@quicinc.com> |
| 17614 | L: ath12k@lists.infradead.org | 17613 | L: ath12k@lists.infradead.org |
| 17615 | S: Supported | 17614 | S: Supported |
| 17615 | W: https://wireless.wiki.kernel.org/en/users/Drivers/ath12k | ||
| 17616 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git | 17616 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git |
| 17617 | F: drivers/net/wireless/ath/ath12k/ | 17617 | F: drivers/net/wireless/ath/ath12k/ |
| 17618 | 17618 | ||
| @@ -18143,8 +18143,6 @@ REALTEK WIRELESS DRIVER (rtlwifi family) · 524 unmodified lines | |||
| 18143 | M: Ping-Ke Shih <pkshih@realtek.com> | 18143 | M: Ping-Ke Shih <pkshih@realtek.com> |
| 18144 | L: linux-wireless@vger.kernel.org | 18144 | L: linux-wireless@vger.kernel.org |
| 18145 | S: Maintained | 18145 | S: Maintained |
| 18146 | W: https://wireless.wiki.kernel.org/ | ||
| 18147 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | ||
| 18148 | F: drivers/net/wireless/realtek/rtlwifi/ | 18146 | F: drivers/net/wireless/realtek/rtlwifi/ |
| 18149 | 18147 | ||
| 18150 | REALTEK WIRELESS DRIVER (rtw88) | 18148 | REALTEK WIRELESS DRIVER (rtw88) |
| @@ -18672,7 +18670,6 @@ F: drivers/media/dvb-frontends/rtl2832_sdr* · 521 unmodified lines | |||
| 18672 | RTL8180 WIRELESS DRIVER | 18670 | RTL8180 WIRELESS DRIVER |
| 18673 | L: linux-wireless@vger.kernel.org | 18671 | L: linux-wireless@vger.kernel.org |
| 18674 | S: Orphan | 18672 | S: Orphan |
| 18675 | W: https://wireless.wiki.kernel.org/ | ||
| 18676 | F: drivers/net/wireless/realtek/rtl818x/rtl8180/ | 18673 | F: drivers/net/wireless/realtek/rtl818x/rtl8180/ |
| 18677 | 18674 | ||
| 18678 | RTL8187 WIRELESS DRIVER | 18675 | RTL8187 WIRELESS DRIVER |
| @@ -18680,14 +18677,12 @@ M: Hin-Tak Leung <hintak.leung@gmail.com> · 1 unmodified line | |||
| 18680 | M: Larry Finger <Larry.Finger@lwfinger.net> | 18677 | M: Larry Finger <Larry.Finger@lwfinger.net> |
| 18681 | L: linux-wireless@vger.kernel.org | 18678 | L: linux-wireless@vger.kernel.org |
| 18682 | S: Maintained | 18679 | S: Maintained |
| 18683 | W: https://wireless.wiki.kernel.org/ | ||
| 18684 | F: drivers/net/wireless/realtek/rtl818x/rtl8187/ | 18680 | F: drivers/net/wireless/realtek/rtl818x/rtl8187/ |
| 18685 | 18681 | ||
| 18686 | RTL8XXXU WIRELESS DRIVER (rtl8xxxu) | 18682 | RTL8XXXU WIRELESS DRIVER (rtl8xxxu) |
| 18687 | M: Jes Sorensen <Jes.Sorensen@gmail.com> | 18683 | M: Jes Sorensen <Jes.Sorensen@gmail.com> |
| 18688 | L: linux-wireless@vger.kernel.org | 18684 | L: linux-wireless@vger.kernel.org |
| 18689 | S: Maintained | 18685 | S: Maintained |
| 18690 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel | ||
| 18691 | F: drivers/net/wireless/realtek/rtl8xxxu/ | 18686 | F: drivers/net/wireless/realtek/rtl8xxxu/ |
| 18692 | 18687 | ||
| 18693 | RTRS TRANSPORT DRIVERS | 18688 | RTRS TRANSPORT DRIVERS |
| @@ -21669,7 +21664,6 @@ L: linux-wireless@vger.kernel.org · 2975 unmodified lines | |||
| 21669 | S: Orphan | 21664 | S: Orphan |
| 21670 | W: https://wireless.wiki.kernel.org/en/users/Drivers/wl12xx | 21665 | W: https://wireless.wiki.kernel.org/en/users/Drivers/wl12xx |
| 21671 | W: https://wireless.wiki.kernel.org/en/users/Drivers/wl1251 | 21666 | W: https://wireless.wiki.kernel.org/en/users/Drivers/wl1251 |
| 21672 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git | ||
| 21673 | F: drivers/net/wireless/ti/ | 21667 | F: drivers/net/wireless/ti/ |
| 21674 | 21668 | ||
| 21675 | TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER | 21669 | TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER |
| @@ -23436,9 +23430,11 @@ F: drivers/platform/x86/x86-android-tablets/ · 1760 unmodified lines | |||
| 23436 | 23430 | ||
| 23437 | X86 PLATFORM DRIVERS | 23431 | X86 PLATFORM DRIVERS |
| 23438 | M: Hans de Goede <hdegoede@redhat.com> | 23432 | M: Hans de Goede <hdegoede@redhat.com> |
| 23433 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | ||
| 23439 | M: Mark Gross <markgross@kernel.org> | 23434 | M: Mark Gross <markgross@kernel.org> |
| 23440 | L: platform-driver-x86@vger.kernel.org | 23435 | L: platform-driver-x86@vger.kernel.org |
| 23441 | S: Maintained | 23436 | S: Maintained |
| 23437 | Q: https://patchwork.kernel.org/project/platform-driver-x86/list/ | ||
| 23442 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git | 23438 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git |
| 23443 | F: drivers/platform/olpc/ | 23439 | F: drivers/platform/olpc/ |
| 23444 | F: drivers/platform/x86/ | 23440 | F: drivers/platform/x86/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 6 | 3 | PATCHLEVEL = 6 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Hurr durr I'ma ninja sloth | 6 | NAME = Hurr durr I'ma ninja sloth |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -614,12 +614,12 @@ · 613 unmodified lines | |||
| 614 | /* Configure pwm clock source for timers 8 & 9 */ | 614 | /* Configure pwm clock source for timers 8 & 9 */ |
| 615 | &timer8 { | 615 | &timer8 { |
| 616 | assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; | 616 | assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; |
| 617 | assigned-clock-parents = <&sys_clkin_ck>; | 617 | assigned-clock-parents = <&sys_32k_ck>; |
| 618 | }; | 618 | }; |
| 619 | 619 | ||
| 620 | &timer9 { | 620 | &timer9 { |
| 621 | assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; | 621 | assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; |
| 622 | assigned-clock-parents = <&sys_clkin_ck>; | 622 | assigned-clock-parents = <&sys_32k_ck>; |
| 623 | }; | 623 | }; |
| 624 | 624 | ||
| 625 | /* | 625 | /* |
| @@ -640,6 +640,7 @@ · 14 unmodified lines | |||
| 640 | &uart3 { | 640 | &uart3 { |
| 641 | interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH | 641 | interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH |
| 642 | &omap4_pmx_core 0x17c>; | 642 | &omap4_pmx_core 0x17c>; |
| 643 | overrun-throttle-ms = <500>; | ||
| 643 | }; | 644 | }; |
| 644 | 645 | ||
| 645 | &uart4 { | 646 | &uart4 { |
| @@ -12,8 +12,7 @@ cpu_thermal: cpu-thermal { · 11 unmodified lines | |||
| 12 | polling-delay = <1000>; /* milliseconds */ | 12 | polling-delay = <1000>; /* milliseconds */ |
| 13 | coefficients = <0 20000>; | 13 | coefficients = <0 20000>; |
| 14 | 14 | ||
| 15 | /* sensor ID */ | 15 | thermal-sensors = <&bandgap>; |
| 16 | thermal-sensors = <&bandgap 0>; | ||
| 17 | 16 | ||
| 18 | cpu_trips: trips { | 17 | cpu_trips: trips { |
| 19 | cpu_alert0: cpu_alert { | 18 | cpu_alert0: cpu_alert { |
| @@ -12,7 +12,10 @@ cpu_thermal: cpu_thermal { · 11 unmodified lines | |||
| 12 | polling-delay-passive = <250>; /* milliseconds */ | 12 | polling-delay-passive = <250>; /* milliseconds */ |
| 13 | polling-delay = <1000>; /* milliseconds */ | 13 | polling-delay = <1000>; /* milliseconds */ |
| 14 | 14 | ||
| 15 | /* sensor ID */ | 15 | /* |
| 16 | * See 44xx files for single sensor addressing, omap5 and dra7 need | ||
| 17 | * also sensor ID for addressing. | ||
| 18 | */ | ||
| 16 | thermal-sensors = <&bandgap 0>; | 19 | thermal-sensors = <&bandgap 0>; |
| 17 | 20 | ||
| 18 | cpu_trips: trips { | 21 | cpu_trips: trips { |
| @@ -69,6 +69,7 @@ · 68 unmodified lines | |||
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | &cpu_thermal { | 71 | &cpu_thermal { |
| 72 | thermal-sensors = <&bandgap>; | ||
| 72 | coefficients = <0 20000>; | 73 | coefficients = <0 20000>; |
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| @@ -79,6 +79,7 @@ · 78 unmodified lines | |||
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | &cpu_thermal { | 81 | &cpu_thermal { |
| 82 | thermal-sensors = <&bandgap>; | ||
| 82 | coefficients = <348 (-9301)>; | 83 | coefficients = <348 (-9301)>; |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| @@ -195,7 +195,7 @@ struct locomo_driver { · 194 unmodified lines | |||
| 195 | 195 | ||
| 196 | #define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name) | 196 | #define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name) |
| 197 | 197 | ||
| 198 | void locomo_lcd_power(struct locomo_dev *, int, unsigned int); | 198 | extern void locomolcd_power(int on); |
| 199 | 199 | ||
| 200 | int locomo_driver_register(struct locomo_driver *); | 200 | int locomo_driver_register(struct locomo_driver *); |
| 201 | void locomo_driver_unregister(struct locomo_driver *); | 201 | void locomo_driver_unregister(struct locomo_driver *); |
| @@ -99,7 +99,7 @@ static int omap4_pm_suspend(void) · 98 unmodified lines | |||
| 99 | * possible causes. | 99 | * possible causes. |
| 100 | * http://www.spinics.net/lists/arm-kernel/msg218641.html | 100 | * http://www.spinics.net/lists/arm-kernel/msg218641.html |
| 101 | */ | 101 | */ |
| 102 | pr_warn("A possible cause could be an old bootloader - try u-boot >= v2012.07\n"); | 102 | pr_debug("A possible cause could be an old bootloader - try u-boot >= v2012.07\n"); |
| 103 | } else { | 103 | } else { |
| 104 | pr_info("Successfully put all powerdomains to target state\n"); | 104 | pr_info("Successfully put all powerdomains to target state\n"); |
| 105 | } | 105 | } |
| @@ -257,7 +257,7 @@ int __init omap4_pm_init(void) · 151 unmodified lines | |||
| 257 | * http://www.spinics.net/lists/arm-kernel/msg218641.html | 257 | * http://www.spinics.net/lists/arm-kernel/msg218641.html |
| 258 | */ | 258 | */ |
| 259 | if (cpu_is_omap44xx()) | 259 | if (cpu_is_omap44xx()) |
| 260 | pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); | 260 | pr_debug("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); |
| 261 | 261 | ||
| 262 | ret = pwrdm_for_each(pwrdms_setup, NULL); | 262 | ret = pwrdm_for_each(pwrdms_setup, NULL); |
| 263 | if (ret) { | 263 | if (ret) { |
| @@ -16,8 +16,6 @@ · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | #include "hardware.h" /* Gives GPIO_MAX */ | 17 | #include "hardware.h" /* Gives GPIO_MAX */ |
| 18 | 18 | ||
| 19 | extern void locomolcd_power(int on); | ||
| 20 | |||
| 21 | #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) | 19 | #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) |
| 22 | #define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0) | 20 | #define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0) |
| 23 | #define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12 | 21 | #define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12 |
| @@ -58,11 +58,13 @@ · 57 unmodified lines | |||
| 58 | ((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_RANGE) | 58 | ((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_RANGE) |
| 59 | 59 | ||
| 60 | /** | 60 | /** |
| 61 | * uniphier_cache_data - UniPhier outer cache specific data | 61 | * struct uniphier_cache_data - UniPhier outer cache specific data |
| 62 | * | 62 | * |
| 63 | * @ctrl_base: virtual base address of control registers | 63 | * @ctrl_base: virtual base address of control registers |
| 64 | * @rev_base: virtual base address of revision registers | 64 | * @rev_base: virtual base address of revision registers |
| 65 | * @op_base: virtual base address of operation registers | 65 | * @op_base: virtual base address of operation registers |
| 66 | * @way_ctrl_base: virtual address of the way control registers for this | ||
| 67 | * SoC revision | ||
| 66 | * @way_mask: each bit specifies if the way is present | 68 | * @way_mask: each bit specifies if the way is present |
| 67 | * @nsets: number of associativity sets | 69 | * @nsets: number of associativity sets |
| 68 | * @line_size: line size in bytes | 70 | * @line_size: line size in bytes |
| @@ -66,6 +66,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-mx8menlo.dtb · 65 unmodified lines | |||
| 66 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb | 66 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb |
| 67 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb | 67 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb |
| 68 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb | 68 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb |
| 69 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb | ||
| 69 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb | 70 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb |
| 70 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb | 71 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb |
| 71 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb | 72 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | port { | 27 | port { |
| 28 | hdmi_connector_in: endpoint { | 28 | hdmi_connector_in: endpoint { |
| 29 | remote-endpoint = <&adv7533_out>; | 29 | remote-endpoint = <&adv7535_out>; |
| 30 | }; | 30 | }; |
| 31 | }; | 31 | }; |
| 32 | }; | 32 | }; |
| @@ -72,6 +72,13 @@ · 39 unmodified lines | |||
| 72 | enable-active-high; | 72 | enable-active-high; |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | reg_vddext_3v3: regulator-vddext-3v3 { | ||
| 76 | compatible = "regulator-fixed"; | ||
| 77 | regulator-name = "VDDEXT_3V3"; | ||
| 78 | regulator-min-microvolt = <3300000>; | ||
| 79 | regulator-max-microvolt = <3300000>; | ||
| 80 | }; | ||
| 81 | |||
| 75 | backlight: backlight { | 82 | backlight: backlight { |
| 76 | compatible = "pwm-backlight"; | 83 | compatible = "pwm-backlight"; |
| 77 | pwms = <&pwm1 0 5000000 0>; | 84 | pwms = <&pwm1 0 5000000 0>; |
| @@ -317,15 +324,16 @@ · 239 unmodified lines | |||
| 317 | 324 | ||
| 318 | hdmi@3d { | 325 | hdmi@3d { |
| 319 | compatible = "adi,adv7535"; | 326 | compatible = "adi,adv7535"; |
| 320 | reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>; | 327 | reg = <0x3d>; |
| 321 | reg-names = "main", "cec", "edid", "packet"; | 328 | interrupt-parent = <&gpio1>; |
| 329 | interrupts = <9 IRQ_TYPE_EDGE_FALLING>; | ||
| 322 | adi,dsi-lanes = <4>; | 330 | adi,dsi-lanes = <4>; |
| 323 | 331 | avdd-supply = <&buck5_reg>; | |
| 324 | adi,input-depth = <8>; | 332 | dvdd-supply = <&buck5_reg>; |
| 325 | adi,input-colorspace = "rgb"; | 333 | pvdd-supply = <&buck5_reg>; |
| 326 | adi,input-clock = "1x"; | 334 | a2vdd-supply = <&buck5_reg>; |
| 327 | adi,input-style = <1>; | 335 | v3p3-supply = <®_vddext_3v3>; |
| 328 | adi,input-justification = "evenly"; | 336 | v1p2-supply = <&buck5_reg>; |
| 329 | 337 | ||
| 330 | ports { | 338 | ports { |
| 331 | #address-cells = <1>; | 339 | #address-cells = <1>; |
| @@ -334,7 +342,7 @@ · 2 unmodified lines | |||
| 334 | port@0 { | 342 | port@0 { |
| 335 | reg = <0>; | 343 | reg = <0>; |
| 336 | 344 | ||
| 337 | adv7533_in: endpoint { | 345 | adv7535_in: endpoint { |
| 338 | remote-endpoint = <&dsi_out>; | 346 | remote-endpoint = <&dsi_out>; |
| 339 | }; | 347 | }; |
| 340 | }; | 348 | }; |
| @@ -342,7 +350,7 @@ · 1 unmodified line | |||
| 342 | port@1 { | 350 | port@1 { |
| 343 | reg = <1>; | 351 | reg = <1>; |
| 344 | 352 | ||
| 345 | adv7533_out: endpoint { | 353 | adv7535_out: endpoint { |
| 346 | remote-endpoint = <&hdmi_connector_in>; | 354 | remote-endpoint = <&hdmi_connector_in>; |
| 347 | }; | 355 | }; |
| 348 | }; | 356 | }; |
| @@ -448,7 +456,7 @@ · 99 unmodified lines | |||
| 448 | reg = <1>; | 456 | reg = <1>; |
| 449 | 457 | ||
| 450 | dsi_out: endpoint { | 458 | dsi_out: endpoint { |
| 451 | remote-endpoint = <&adv7533_in>; | 459 | remote-endpoint = <&adv7535_in>; |
| 452 | data-lanes = <1 2 3 4>; | 460 | data-lanes = <1 2 3 4>; |
| 453 | }; | 461 | }; |
| 454 | }; | 462 | }; |
| @@ -381,9 +381,10 @@ · 380 unmodified lines | |||
| 381 | &sai3 { | 381 | &sai3 { |
| 382 | pinctrl-names = "default"; | 382 | pinctrl-names = "default"; |
| 383 | pinctrl-0 = <&pinctrl_sai3>; | 383 | pinctrl-0 = <&pinctrl_sai3>; |
| 384 | assigned-clocks = <&clk IMX8MP_CLK_SAI3>; | 384 | assigned-clocks = <&clk IMX8MP_CLK_SAI3>, |
| 385 | <&clk IMX8MP_AUDIO_PLL2> ; | ||
| 385 | assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; | 386 | assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; |
| 386 | assigned-clock-rates = <12288000>; | 387 | assigned-clock-rates = <12288000>, <361267200>; |
| 387 | fsl,sai-mclk-direction-output; | 388 | fsl,sai-mclk-direction-output; |
| 388 | status = "okay"; | 389 | status = "okay"; |
| 389 | }; | 390 | }; |
| @@ -790,6 +790,12 @@ · 789 unmodified lines | |||
| 790 | reg = <IMX8MP_POWER_DOMAIN_AUDIOMIX>; | 790 | reg = <IMX8MP_POWER_DOMAIN_AUDIOMIX>; |
| 791 | clocks = <&clk IMX8MP_CLK_AUDIO_ROOT>, | 791 | clocks = <&clk IMX8MP_CLK_AUDIO_ROOT>, |
| 792 | <&clk IMX8MP_CLK_AUDIO_AXI>; | 792 | <&clk IMX8MP_CLK_AUDIO_AXI>; |
| 793 | assigned-clocks = <&clk IMX8MP_CLK_AUDIO_AHB>, | ||
| 794 | <&clk IMX8MP_CLK_AUDIO_AXI_SRC>; | ||
| 795 | assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>, | ||
| 796 | <&clk IMX8MP_SYS_PLL1_800M>; | ||
| 797 | assigned-clock-rates = <400000000>, | ||
| 798 | <600000000>; | ||
| 793 | }; | 799 | }; |
| 794 | 800 | ||
| 795 | pgc_gpu2d: power-domain@6 { | 801 | pgc_gpu2d: power-domain@6 { |
| @@ -81,7 +81,7 @@ · 80 unmodified lines | |||
| 81 | &gpio1 { | 81 | &gpio1 { |
| 82 | pmic-irq-hog { | 82 | pmic-irq-hog { |
| 83 | gpio-hog; | 83 | gpio-hog; |
| 84 | gpios = <2 GPIO_ACTIVE_LOW>; | 84 | gpios = <3 GPIO_ACTIVE_LOW>; |
| 85 | input; | 85 | input; |
| 86 | line-name = "PMIC_IRQ#"; | 86 | line-name = "PMIC_IRQ#"; |
| 87 | }; | 87 | }; |
| @@ -2957,7 +2957,7 @@ · 2956 unmodified lines | |||
| 2957 | clock-names = "merge","merge_async"; | 2957 | clock-names = "merge","merge_async"; |
| 2958 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2958 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2959 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xc000 0x1000>; | 2959 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xc000 0x1000>; |
| 2960 | mediatek,merge-mute = <1>; | 2960 | mediatek,merge-mute; |
| 2961 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>; | 2961 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>; |
| 2962 | }; | 2962 | }; |
| 2963 | 2963 | ||
| @@ -2970,7 +2970,7 @@ · 6 unmodified lines | |||
| 2970 | clock-names = "merge","merge_async"; | 2970 | clock-names = "merge","merge_async"; |
| 2971 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2971 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2972 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xd000 0x1000>; | 2972 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xd000 0x1000>; |
| 2973 | mediatek,merge-mute = <1>; | 2973 | mediatek,merge-mute; |
| 2974 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>; | 2974 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>; |
| 2975 | }; | 2975 | }; |
| 2976 | 2976 | ||
| @@ -2983,7 +2983,7 @@ · 6 unmodified lines | |||
| 2983 | clock-names = "merge","merge_async"; | 2983 | clock-names = "merge","merge_async"; |
| 2984 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2984 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2985 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xe000 0x1000>; | 2985 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xe000 0x1000>; |
| 2986 | mediatek,merge-mute = <1>; | 2986 | mediatek,merge-mute; |
| 2987 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>; | 2987 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>; |
| 2988 | }; | 2988 | }; |
| 2989 | 2989 | ||
| @@ -2996,7 +2996,7 @@ · 6 unmodified lines | |||
| 2996 | clock-names = "merge","merge_async"; | 2996 | clock-names = "merge","merge_async"; |
| 2997 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2997 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2998 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xf000 0x1000>; | 2998 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xf000 0x1000>; |
| 2999 | mediatek,merge-mute = <1>; | 2999 | mediatek,merge-mute; |
| 3000 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>; | 3000 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>; |
| 3001 | }; | 3001 | }; |
| 3002 | 3002 | ||
| @@ -3009,7 +3009,7 @@ · 6 unmodified lines | |||
| 3009 | clock-names = "merge","merge_async"; | 3009 | clock-names = "merge","merge_async"; |
| 3010 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 3010 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 3011 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x0000 0x1000>; | 3011 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x0000 0x1000>; |
| 3012 | mediatek,merge-fifo-en = <1>; | 3012 | mediatek,merge-fifo-en; |
| 3013 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>; | 3013 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>; |
| 3014 | }; | 3014 | }; |
| 3015 | 3015 | ||
| @@ -636,6 +636,7 @@ CONFIG_POWER_RESET_MSM=y · 635 unmodified lines | |||
| 636 | CONFIG_POWER_RESET_QCOM_PON=m | 636 | CONFIG_POWER_RESET_QCOM_PON=m |
| 637 | CONFIG_POWER_RESET_XGENE=y | 637 | CONFIG_POWER_RESET_XGENE=y |
| 638 | CONFIG_POWER_RESET_SYSCON=y | 638 | CONFIG_POWER_RESET_SYSCON=y |
| 639 | CONFIG_POWER_RESET_SYSCON_POWEROFF=y | ||
| 639 | CONFIG_SYSCON_REBOOT_MODE=y | 640 | CONFIG_SYSCON_REBOOT_MODE=y |
| 640 | CONFIG_NVMEM_REBOOT_MODE=m | 641 | CONFIG_NVMEM_REBOOT_MODE=m |
| 641 | CONFIG_BATTERY_SBS=m | 642 | CONFIG_BATTERY_SBS=m |
| @@ -1175,7 +1176,6 @@ CONFIG_COMMON_CLK_S2MPS11=y · 533 unmodified lines | |||
| 1175 | CONFIG_COMMON_CLK_PWM=y | 1176 | CONFIG_COMMON_CLK_PWM=y |
| 1176 | CONFIG_COMMON_CLK_RS9_PCIE=y | 1177 | CONFIG_COMMON_CLK_RS9_PCIE=y |
| 1177 | CONFIG_COMMON_CLK_VC5=y | 1178 | CONFIG_COMMON_CLK_VC5=y |
| 1178 | CONFIG_COMMON_CLK_NPCM8XX=y | ||
| 1179 | CONFIG_COMMON_CLK_BD718XX=m | 1179 | CONFIG_COMMON_CLK_BD718XX=m |
| 1180 | CONFIG_CLK_RASPBERRYPI=m | 1180 | CONFIG_CLK_RASPBERRYPI=m |
| 1181 | CONFIG_CLK_IMX8MM=y | 1181 | CONFIG_CLK_IMX8MM=y |
| @@ -663,7 +663,7 @@ static inline bool supports_clearbhb(int scope) · 662 unmodified lines | |||
| 663 | isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); | 663 | isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); |
| 664 | 664 | ||
| 665 | return cpuid_feature_extract_unsigned_field(isar2, | 665 | return cpuid_feature_extract_unsigned_field(isar2, |
| 666 | ID_AA64ISAR2_EL1_BC_SHIFT); | 666 | ID_AA64ISAR2_EL1_CLRBHB_SHIFT); |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | const struct cpumask *system_32bit_el0_cpumask(void); | 669 | const struct cpumask *system_32bit_el0_cpumask(void); |
| @@ -28,7 +28,7 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags); · 27 unmodified lines | |||
| 28 | #define arch_make_huge_pte arch_make_huge_pte | 28 | #define arch_make_huge_pte arch_make_huge_pte |
| 29 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 29 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 30 | extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 30 | extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 31 | pte_t *ptep, pte_t pte); | 31 | pte_t *ptep, pte_t pte, unsigned long sz); |
| 32 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS | 32 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS |
| 33 | extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, | 33 | extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, |
| 34 | unsigned long addr, pte_t *ptep, | 34 | unsigned long addr, pte_t *ptep, |
| @@ -118,7 +118,7 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu); · 117 unmodified lines | |||
| 118 | 118 | ||
| 119 | u64 __guest_enter(struct kvm_vcpu *vcpu); | 119 | u64 __guest_enter(struct kvm_vcpu *vcpu); |
| 120 | 120 | ||
| 121 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt); | 121 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id); |
| 122 | 122 | ||
| 123 | #ifdef __KVM_NVHE_HYPERVISOR__ | 123 | #ifdef __KVM_NVHE_HYPERVISOR__ |
| 124 | void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, | 124 | void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, |
| @@ -222,7 +222,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { · 221 unmodified lines | |||
| 222 | static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { | 222 | static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { |
| 223 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0), | 223 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0), |
| 224 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0), | 224 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0), |
| 225 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), | 225 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0), |
| 226 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), | ||
| 226 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0), | 227 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0), |
| 227 | ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), | 228 | ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), |
| 228 | FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0), | 229 | FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0), |
| @@ -12,6 +12,6 @@ · 11 unmodified lines | |||
| 12 | #define FFA_MAX_FUNC_NUM 0x7F | 12 | #define FFA_MAX_FUNC_NUM 0x7F |
| 13 | 13 | ||
| 14 | int hyp_ffa_init(void *pages); | 14 | int hyp_ffa_init(void *pages); |
| 15 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt); | 15 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id); |
| 16 | 16 | ||
| 17 | #endif /* __KVM_HYP_FFA_H */ | 17 | #endif /* __KVM_HYP_FFA_H */ |
| @@ -634,9 +634,8 @@ out_handled: · 633 unmodified lines | |||
| 634 | return true; | 634 | return true; |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt) | 637 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) |
| 638 | { | 638 | { |
| 639 | DECLARE_REG(u64, func_id, host_ctxt, 0); | ||
| 640 | struct arm_smccc_res res; | 639 | struct arm_smccc_res res; |
| 641 | 640 | ||
| 642 | /* | 641 | /* |
| @@ -57,6 +57,7 @@ __do_hyp_init: · 56 unmodified lines | |||
| 57 | cmp x0, #HVC_STUB_HCALL_NR | 57 | cmp x0, #HVC_STUB_HCALL_NR |
| 58 | b.lo __kvm_handle_stub_hvc | 58 | b.lo __kvm_handle_stub_hvc |
| 59 | 59 | ||
| 60 | bic x0, x0, #ARM_SMCCC_CALL_HINTS | ||
| 60 | mov x3, #KVM_HOST_SMCCC_FUNC(__kvm_hyp_init) | 61 | mov x3, #KVM_HOST_SMCCC_FUNC(__kvm_hyp_init) |
| 61 | cmp x0, x3 | 62 | cmp x0, x3 |
| 62 | b.eq 1f | 63 | b.eq 1f |
| @@ -368,6 +368,7 @@ static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) · 367 unmodified lines | |||
| 368 | if (static_branch_unlikely(&kvm_protected_mode_initialized)) | 368 | if (static_branch_unlikely(&kvm_protected_mode_initialized)) |
| 369 | hcall_min = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize; | 369 | hcall_min = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize; |
| 370 | 370 | ||
| 371 | id &= ~ARM_SMCCC_CALL_HINTS; | ||
| 371 | id -= KVM_HOST_SMCCC_ID(0); | 372 | id -= KVM_HOST_SMCCC_ID(0); |
| 372 | 373 | ||
| 373 | if (unlikely(id < hcall_min || id >= ARRAY_SIZE(host_hcall))) | 374 | if (unlikely(id < hcall_min || id >= ARRAY_SIZE(host_hcall))) |
| @@ -392,11 +393,14 @@ static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) · 18 unmodified lines | |||
| 392 | 393 | ||
| 393 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) | 394 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) |
| 394 | { | 395 | { |
| 396 | DECLARE_REG(u64, func_id, host_ctxt, 0); | ||
| 395 | bool handled; | 397 | bool handled; |
| 396 | 398 | ||
| 397 | handled = kvm_host_psci_handler(host_ctxt); | 399 | func_id &= ~ARM_SMCCC_CALL_HINTS; |
| 400 | |||
| 401 | handled = kvm_host_psci_handler(host_ctxt, func_id); | ||
| 398 | if (!handled) | 402 | if (!handled) |
| 399 | handled = kvm_host_ffa_handler(host_ctxt); | 403 | handled = kvm_host_ffa_handler(host_ctxt, func_id); |
| 400 | if (!handled) | 404 | if (!handled) |
| 401 | default_host_smc_handler(host_ctxt); | 405 | default_host_smc_handler(host_ctxt); |
| 402 | 406 | ||
| @@ -273,9 +273,8 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ · 272 unmodified lines | |||
| 273 | } | 273 | } |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt) | 276 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) |
| 277 | { | 277 | { |
| 278 | DECLARE_REG(u64, func_id, host_ctxt, 0); | ||
| 279 | unsigned long ret; | 278 | unsigned long ret; |
| 280 | 279 | ||
| 281 | switch (kvm_host_psci_config.version) { | 280 | switch (kvm_host_psci_config.version) { |
| @@ -652,6 +652,9 @@ int hyp_alloc_private_va_range(size_t size, unsigned long *haddr) · 651 unmodified lines | |||
| 652 | 652 | ||
| 653 | mutex_unlock(&kvm_hyp_pgd_mutex); | 653 | mutex_unlock(&kvm_hyp_pgd_mutex); |
| 654 | 654 | ||
| 655 | if (!ret) | ||
| 656 | *haddr = base; | ||
| 657 | |||
| 655 | return ret; | 658 | return ret; |
| 656 | } | 659 | } |
| 657 | 660 | ||
| @@ -241,15 +241,8 @@ static void clear_flush(struct mm_struct *mm, · 240 unmodified lines | |||
| 241 | flush_tlb_range(&vma, saddr, addr); | 241 | flush_tlb_range(&vma, saddr, addr); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry) | ||
| 245 | { | ||
| 246 | VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry)); | ||
| 247 | |||
| 248 | return page_folio(pfn_to_page(swp_offset_pfn(entry))); | ||
| 249 | } | ||
| 250 | |||
| 251 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 244 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 252 | pte_t *ptep, pte_t pte) | 245 | pte_t *ptep, pte_t pte, unsigned long sz) |
| 253 | { | 246 | { |
| 254 | size_t pgsize; | 247 | size_t pgsize; |
| 255 | int i; | 248 | int i; |
| @@ -257,13 +250,10 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 1 unmodified line | |||
| 257 | unsigned long pfn, dpfn; | 250 | unsigned long pfn, dpfn; |
| 258 | pgprot_t hugeprot; | 251 | pgprot_t hugeprot; |
| 259 | 252 | ||
| 260 | if (!pte_present(pte)) { | 253 | ncontig = num_contig_ptes(sz, &pgsize); |
| 261 | struct folio *folio; | ||
| 262 | |||
| 263 | folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte)); | ||
| 264 | ncontig = num_contig_ptes(folio_size(folio), &pgsize); | ||
| 265 | 254 | ||
| 266 | for (i = 0; i < ncontig; i++, ptep++) | 255 | if (!pte_present(pte)) { |
| 256 | for (i = 0; i < ncontig; i++, ptep++, addr += pgsize) | ||
| 267 | set_pte_at(mm, addr, ptep, pte); | 257 | set_pte_at(mm, addr, ptep, pte); |
| 268 | return; | 258 | return; |
| 269 | } | 259 | } |
| @@ -273,7 +263,6 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 3 unmodified lines | |||
| 273 | return; | 263 | return; |
| 274 | } | 264 | } |
| 275 | 265 | ||
| 276 | ncontig = find_num_contig(mm, addr, ptep, &pgsize); | ||
| 277 | pfn = pte_pfn(pte); | 266 | pfn = pte_pfn(pte); |
| 278 | dpfn = pgsize >> PAGE_SHIFT; | 267 | dpfn = pgsize >> PAGE_SHIFT; |
| 279 | hugeprot = pte_pgprot(pte); | 268 | hugeprot = pte_pgprot(pte); |
| @@ -571,5 +560,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr · 291 unmodified lines | |||
| 571 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, | 560 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, |
| 572 | pte_t old_pte, pte_t pte) | 561 | pte_t old_pte, pte_t pte) |
| 573 | { | 562 | { |
| 574 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 563 | unsigned long psize = huge_page_size(hstate_vma(vma)); |
| 564 | |||
| 565 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize); | ||
| 575 | } | 566 | } |
| @@ -1347,7 +1347,11 @@ UnsignedEnum 51:48 RPRFM · 1346 unmodified lines | |||
| 1347 | 0b0000 NI | 1347 | 0b0000 NI |
| 1348 | 0b0001 IMP | 1348 | 0b0001 IMP |
| 1349 | EndEnum | 1349 | EndEnum |
| 1350 | Res0 47:28 | 1350 | Res0 47:32 |
| 1351 | UnsignedEnum 31:28 CLRBHB | ||
| 1352 | 0b0000 NI | ||
| 1353 | 0b0001 IMP | ||
| 1354 | EndEnum | ||
| 1351 | UnsignedEnum 27:24 PAC_frac | 1355 | UnsignedEnum 27:24 PAC_frac |
| 1352 | 0b0000 NI | 1356 | 0b0000 NI |
| 1353 | 0b0001 IMP | 1357 | 0b0001 IMP |
| @@ -907,3 +907,7 @@ EXPORT_SYMBOL(acpi_unregister_ioapic); · 906 unmodified lines | |||
| 907 | * TBD when IA64 starts to support suspend... | 907 | * TBD when IA64 starts to support suspend... |
| 908 | */ | 908 | */ |
| 909 | int acpi_suspend_lowlevel(void) { return 0; } | 909 | int acpi_suspend_lowlevel(void) { return 0; } |
| 910 | |||
| 911 | void acpi_proc_quirk_mwait_check(void) | ||
| 912 | { | ||
| 913 | } | ||
| @@ -19,7 +19,7 @@ · 18 unmodified lines | |||
| 19 | */ | 19 | */ |
| 20 | #ifndef __ASSEMBLY__ | 20 | #ifndef __ASSEMBLY__ |
| 21 | #ifndef PHYS_OFFSET | 21 | #ifndef PHYS_OFFSET |
| 22 | #define PHYS_OFFSET _AC(0, UL) | 22 | #define PHYS_OFFSET _UL(0) |
| 23 | #endif | 23 | #endif |
| 24 | extern unsigned long vm_map_base; | 24 | extern unsigned long vm_map_base; |
| 25 | #endif /* __ASSEMBLY__ */ | 25 | #endif /* __ASSEMBLY__ */ |
| @@ -43,7 +43,7 @@ extern unsigned long vm_map_base; · 17 unmodified lines | |||
| 43 | * Memory above this physical address will be considered highmem. | 43 | * Memory above this physical address will be considered highmem. |
| 44 | */ | 44 | */ |
| 45 | #ifndef HIGHMEM_START | 45 | #ifndef HIGHMEM_START |
| 46 | #define HIGHMEM_START (_AC(1, UL) << _AC(DMW_PABITS, UL)) | 46 | #define HIGHMEM_START (_UL(1) << _UL(DMW_PABITS)) |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) | 49 | #define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) |
| @@ -65,16 +65,16 @@ extern unsigned long vm_map_base; · 15 unmodified lines | |||
| 65 | #define _ATYPE_ | 65 | #define _ATYPE_ |
| 66 | #define _ATYPE32_ | 66 | #define _ATYPE32_ |
| 67 | #define _ATYPE64_ | 67 | #define _ATYPE64_ |
| 68 | #define _CONST64_(x) x | ||
| 69 | #else | 68 | #else |
| 70 | #define _ATYPE_ __PTRDIFF_TYPE__ | 69 | #define _ATYPE_ __PTRDIFF_TYPE__ |
| 71 | #define _ATYPE32_ int | 70 | #define _ATYPE32_ int |
| 72 | #define _ATYPE64_ __s64 | 71 | #define _ATYPE64_ __s64 |
| 72 | #endif | ||
| 73 | |||
| 73 | #ifdef CONFIG_64BIT | 74 | #ifdef CONFIG_64BIT |
| 74 | #define _CONST64_(x) x ## UL | 75 | #define _CONST64_(x) _UL(x) |
| 75 | #else | 76 | #else |
| 76 | #define _CONST64_(x) x ## ULL | 77 | #define _CONST64_(x) _ULL(x) |
| 77 | #endif | ||
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | /* | 80 | /* |
| @@ -111,6 +111,15 @@ · 110 unmodified lines | |||
| 111 | #define R_LARCH_TLS_GD_HI20 98 | 111 | #define R_LARCH_TLS_GD_HI20 98 |
| 112 | #define R_LARCH_32_PCREL 99 | 112 | #define R_LARCH_32_PCREL 99 |
| 113 | #define R_LARCH_RELAX 100 | 113 | #define R_LARCH_RELAX 100 |
| 114 | #define R_LARCH_DELETE 101 | ||
| 115 | #define R_LARCH_ALIGN 102 | ||
| 116 | #define R_LARCH_PCREL20_S2 103 | ||
| 117 | #define R_LARCH_CFA 104 | ||
| 118 | #define R_LARCH_ADD6 105 | ||
| 119 | #define R_LARCH_SUB6 106 | ||
| 120 | #define R_LARCH_ADD_ULEB128 107 | ||
| 121 | #define R_LARCH_SUB_ULEB128 108 | ||
| 122 | #define R_LARCH_64_PCREL 109 | ||
| 114 | 123 | ||
| 115 | #ifndef ELF_ARCH | 124 | #ifndef ELF_ARCH |
| 116 | 125 | ||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | |||
| 3 | #ifndef __ASM_EXCEPTION_H | ||
| 4 | #define __ASM_EXCEPTION_H | ||
| 5 | |||
| 6 | #include <asm/ptrace.h> | ||
| 7 | #include <linux/kprobes.h> | ||
| 8 | |||
| 9 | void show_registers(struct pt_regs *regs); | ||
| 10 | |||
| 11 | asmlinkage void cache_parity_error(void); | ||
| 12 | asmlinkage void noinstr do_ade(struct pt_regs *regs); | ||
| 13 | asmlinkage void noinstr do_ale(struct pt_regs *regs); | ||
| 14 | asmlinkage void noinstr do_bce(struct pt_regs *regs); | ||
| 15 | asmlinkage void noinstr do_bp(struct pt_regs *regs); | ||
| 16 | asmlinkage void noinstr do_ri(struct pt_regs *regs); | ||
| 17 | asmlinkage void noinstr do_fpu(struct pt_regs *regs); | ||
| 18 | asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr); | ||
| 19 | asmlinkage void noinstr do_lsx(struct pt_regs *regs); | ||
| 20 | asmlinkage void noinstr do_lasx(struct pt_regs *regs); | ||
| 21 | asmlinkage void noinstr do_lbt(struct pt_regs *regs); | ||
| 22 | asmlinkage void noinstr do_watch(struct pt_regs *regs); | ||
| 23 | asmlinkage void noinstr do_syscall(struct pt_regs *regs); | ||
| 24 | asmlinkage void noinstr do_reserved(struct pt_regs *regs); | ||
| 25 | asmlinkage void noinstr do_vint(struct pt_regs *regs, unsigned long sp); | ||
| 26 | asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | ||
| 27 | unsigned long write, unsigned long address); | ||
| 28 | |||
| 29 | asmlinkage void handle_ade(void); | ||
| 30 | asmlinkage void handle_ale(void); | ||
| 31 | asmlinkage void handle_bce(void); | ||
| 32 | asmlinkage void handle_sys(void); | ||
| 33 | asmlinkage void handle_bp(void); | ||
| 34 | asmlinkage void handle_ri(void); | ||
| 35 | asmlinkage void handle_fpu(void); | ||
| 36 | asmlinkage void handle_fpe(void); | ||
| 37 | asmlinkage void handle_lsx(void); | ||
| 38 | asmlinkage void handle_lasx(void); | ||
| 39 | asmlinkage void handle_lbt(void); | ||
| 40 | asmlinkage void handle_watch(void); | ||
| 41 | asmlinkage void handle_reserved(void); | ||
| 42 | asmlinkage void handle_vint(void); | ||
| 43 | asmlinkage void noinstr handle_loongarch_irq(struct pt_regs *regs); | ||
| 44 | |||
| 45 | #endif /* __ASM_EXCEPTION_H */ | ||
| @@ -10,8 +10,6 @@ · 9 unmodified lines | |||
| 10 | #include <asm/io.h> | 10 | #include <asm/io.h> |
| 11 | #include <asm/pgtable.h> | 11 | #include <asm/pgtable.h> |
| 12 | 12 | ||
| 13 | #define __HAVE_ARCH_SHADOW_MAP | ||
| 14 | |||
| 15 | #define KASAN_SHADOW_SCALE_SHIFT 3 | 13 | #define KASAN_SHADOW_SCALE_SHIFT 3 |
| 16 | #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) | 14 | #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) |
| 17 | 15 | ||
| @@ -62,61 +60,22 @@ · 44 unmodified lines | |||
| 62 | extern bool kasan_early_stage; | 60 | extern bool kasan_early_stage; |
| 63 | extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; | 61 | extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; |
| 64 | 62 | ||
| 63 | #define kasan_mem_to_shadow kasan_mem_to_shadow | ||
| 64 | void *kasan_mem_to_shadow(const void *addr); | ||
| 65 | |||
| 66 | #define kasan_shadow_to_mem kasan_shadow_to_mem | ||
| 67 | const void *kasan_shadow_to_mem(const void *shadow_addr); | ||
| 68 | |||
| 65 | #define kasan_arch_is_ready kasan_arch_is_ready | 69 | #define kasan_arch_is_ready kasan_arch_is_ready |
| 66 | static __always_inline bool kasan_arch_is_ready(void) | 70 | static __always_inline bool kasan_arch_is_ready(void) |
| 67 | { | 71 | { |
| 68 | return !kasan_early_stage; | 72 | return !kasan_early_stage; |
| 69 | } | 73 | } |
| 70 | 74 | ||
| 71 | static inline void *kasan_mem_to_shadow(const void *addr) | 75 | #define addr_has_metadata addr_has_metadata |
| 72 | { | 76 | static __always_inline bool addr_has_metadata(const void *addr) |
| 73 | if (!kasan_arch_is_ready()) { | ||
| 74 | return (void *)(kasan_early_shadow_page); | ||
| 75 | } else { | ||
| 76 | unsigned long maddr = (unsigned long)addr; | ||
| 77 | unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; | ||
| 78 | unsigned long offset = 0; | ||
| 79 | |||
| 80 | maddr &= XRANGE_SHADOW_MASK; | ||
| 81 | switch (xrange) { | ||
| 82 | case XKPRANGE_CC_SEG: | ||
| 83 | offset = XKPRANGE_CC_SHADOW_OFFSET; | ||
| 84 | break; | ||
| 85 | case XKPRANGE_UC_SEG: | ||
| 86 | offset = XKPRANGE_UC_SHADOW_OFFSET; | ||
| 87 | break; | ||
| 88 | case XKVRANGE_VC_SEG: | ||
| 89 | offset = XKVRANGE_VC_SHADOW_OFFSET; | ||
| 90 | break; | ||
| 91 | default: | ||
| 92 | WARN_ON(1); | ||
| 93 | return NULL; | ||
| 94 | } | ||
| 95 | |||
| 96 | return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | static inline const void *kasan_shadow_to_mem(const void *shadow_addr) | ||
| 101 | { | 77 | { |
| 102 | unsigned long addr = (unsigned long)shadow_addr; | 78 | return (kasan_mem_to_shadow((void *)addr) != NULL); |
| 103 | |||
| 104 | if (unlikely(addr > KASAN_SHADOW_END) || | ||
| 105 | unlikely(addr < KASAN_SHADOW_START)) { | ||
| 106 | WARN_ON(1); | ||
| 107 | return NULL; | ||
| 108 | } | ||
| 109 | |||
| 110 | if (addr >= XKVRANGE_VC_SHADOW_OFFSET) | ||
| 111 | return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START); | ||
| 112 | else if (addr >= XKPRANGE_UC_SHADOW_OFFSET) | ||
| 113 | return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START); | ||
| 114 | else if (addr >= XKPRANGE_CC_SHADOW_OFFSET) | ||
| 115 | return (void *)(((addr - XKPRANGE_CC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_CC_START); | ||
| 116 | else { | ||
| 117 | WARN_ON(1); | ||
| 118 | return NULL; | ||
| 119 | } | ||
| 120 | } | 79 | } |
| 121 | 80 | ||
| 122 | void kasan_init(void); | 81 | void kasan_init(void); |
| @@ -70,6 +70,7 @@ struct secondary_data { · 69 unmodified lines | |||
| 70 | extern struct secondary_data cpuboot_data; | 70 | extern struct secondary_data cpuboot_data; |
| 71 | 71 | ||
| 72 | extern asmlinkage void smpboot_entry(void); | 72 | extern asmlinkage void smpboot_entry(void); |
| 73 | extern asmlinkage void start_secondary(void); | ||
| 73 | 74 | ||
| 74 | extern void calculate_cpu_foreign_map(void); | 75 | extern void calculate_cpu_foreign_map(void); |
| 75 | 76 | ||
| @@ -19,6 +19,10 @@ obj-$(CONFIG_CPU_HAS_LBT) += lbt.o · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o | 20 | obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o |
| 21 | 21 | ||
| 22 | CFLAGS_module.o += $(call cc-option,-Wno-override-init,) | ||
| 23 | CFLAGS_syscall.o += $(call cc-option,-Wno-override-init,) | ||
| 24 | CFLAGS_perf_event.o += $(call cc-option,-Wno-override-init,) | ||
| 25 | |||
| 22 | ifdef CONFIG_FUNCTION_TRACER | 26 | ifdef CONFIG_FUNCTION_TRACER |
| 23 | ifndef CONFIG_DYNAMIC_FTRACE | 27 | ifndef CONFIG_DYNAMIC_FTRACE |
| 24 | obj-y += mcount.o ftrace.o | 28 | obj-y += mcount.o ftrace.o |
| @@ -281,7 +281,6 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) · 280 unmodified lines | |||
| 281 | pr_info("SRAT: PXM %u -> CPU 0x%02x -> Node %u\n", pxm, pa->apic_id, node); | 281 | pr_info("SRAT: PXM %u -> CPU 0x%02x -> Node %u\n", pxm, pa->apic_id, node); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | void __init acpi_numa_arch_fixup(void) {} | ||
| 285 | #endif | 284 | #endif |
| 286 | 285 | ||
| 287 | void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) | 286 | void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) |
| @@ -50,7 +50,6 @@ void __init memblock_init(void) · 49 unmodified lines | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | memblock_set_current_limit(PFN_PHYS(max_low_pfn)); | 52 | memblock_set_current_limit(PFN_PHYS(max_low_pfn)); |
| 53 | memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); | ||
| 54 | 53 | ||
| 55 | /* Reserve the first 2MB */ | 54 | /* Reserve the first 2MB */ |
| 56 | memblock_reserve(PHYS_OFFSET, 0x200000); | 55 | memblock_reserve(PHYS_OFFSET, 0x200000); |
| @@ -58,4 +57,7 @@ void __init memblock_init(void) · 1 unmodified line | |||
| 58 | /* Reserve the kernel text/data/bss */ | 57 | /* Reserve the kernel text/data/bss */ |
| 59 | memblock_reserve(__pa_symbol(&_text), | 58 | memblock_reserve(__pa_symbol(&_text), |
| 60 | __pa_symbol(&_end) - __pa_symbol(&_text)); | 59 | __pa_symbol(&_end) - __pa_symbol(&_text)); |
| 60 | |||
| 61 | memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); | ||
| 62 | memblock_set_node(0, PHYS_ADDR_MAX, &memblock.reserved, 0); | ||
| 61 | } | 63 | } |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/elf.h> | 6 | #include <linux/elf.h> |
| 7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/moduleloader.h> | ||
| 9 | #include <linux/ftrace.h> | 10 | #include <linux/ftrace.h> |
| 10 | 11 | ||
| 11 | Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val) | 12 | Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val) |
| @@ -367,6 +367,24 @@ static int apply_r_larch_got_pc(struct module *mod, · 366 unmodified lines | |||
| 367 | return apply_r_larch_pcala(mod, location, got, rela_stack, rela_stack_top, type); | 367 | return apply_r_larch_pcala(mod, location, got, rela_stack, rela_stack_top, type); |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_Addr v, | ||
| 371 | s64 *rela_stack, size_t *rela_stack_top, unsigned int type) | ||
| 372 | { | ||
| 373 | ptrdiff_t offset = (void *)v - (void *)location; | ||
| 374 | |||
| 375 | *(u32 *)location = offset; | ||
| 376 | return 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | static int apply_r_larch_64_pcrel(struct module *mod, u32 *location, Elf_Addr v, | ||
| 380 | s64 *rela_stack, size_t *rela_stack_top, unsigned int type) | ||
| 381 | { | ||
| 382 | ptrdiff_t offset = (void *)v - (void *)location; | ||
| 383 | |||
| 384 | *(u64 *)location = offset; | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 370 | /* | 388 | /* |
| 371 | * reloc_handlers_rela() - Apply a particular relocation to a module | 389 | * reloc_handlers_rela() - Apply a particular relocation to a module |
| 372 | * @mod: the module to apply the reloc to | 390 | * @mod: the module to apply the reloc to |
| @@ -382,7 +400,7 @@ typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_Addr v, · 9 unmodified lines | |||
| 382 | 400 | ||
| 383 | /* The handlers for known reloc types */ | 401 | /* The handlers for known reloc types */ |
| 384 | static reloc_rela_handler reloc_rela_handlers[] = { | 402 | static reloc_rela_handler reloc_rela_handlers[] = { |
| 385 | [R_LARCH_NONE ... R_LARCH_RELAX] = apply_r_larch_error, | 403 | [R_LARCH_NONE ... R_LARCH_64_PCREL] = apply_r_larch_error, |
| 386 | 404 | ||
| 387 | [R_LARCH_NONE] = apply_r_larch_none, | 405 | [R_LARCH_NONE] = apply_r_larch_none, |
| 388 | [R_LARCH_32] = apply_r_larch_32, | 406 | [R_LARCH_32] = apply_r_larch_32, |
| @@ -396,6 +414,8 @@ static reloc_rela_handler reloc_rela_handlers[] = { · 7 unmodified lines | |||
| 396 | [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field, | 414 | [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field, |
| 397 | [R_LARCH_ADD32 ... R_LARCH_SUB64] = apply_r_larch_add_sub, | 415 | [R_LARCH_ADD32 ... R_LARCH_SUB64] = apply_r_larch_add_sub, |
| 398 | [R_LARCH_PCALA_HI20...R_LARCH_PCALA64_HI12] = apply_r_larch_pcala, | 416 | [R_LARCH_PCALA_HI20...R_LARCH_PCALA64_HI12] = apply_r_larch_pcala, |
| 417 | [R_LARCH_32_PCREL] = apply_r_larch_32_pcrel, | ||
| 418 | [R_LARCH_64_PCREL] = apply_r_larch_64_pcrel, | ||
| 399 | }; | 419 | }; |
| 400 | 420 | ||
| 401 | int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, | 421 | int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, |
| @@ -436,7 +436,7 @@ void __init paging_init(void) · 435 unmodified lines | |||
| 436 | 436 | ||
| 437 | void __init mem_init(void) | 437 | void __init mem_init(void) |
| 438 | { | 438 | { |
| 439 | high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); | 439 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
| 440 | memblock_free_all(); | 440 | memblock_free_all(); |
| 441 | } | 441 | } |
| 442 | 442 | ||
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include <asm/bootinfo.h> | 37 | #include <asm/bootinfo.h> |
| 38 | #include <asm/cpu.h> | 38 | #include <asm/cpu.h> |
| 39 | #include <asm/elf.h> | 39 | #include <asm/elf.h> |
| 40 | #include <asm/exec.h> | ||
| 40 | #include <asm/fpu.h> | 41 | #include <asm/fpu.h> |
| 41 | #include <asm/lbt.h> | 42 | #include <asm/lbt.h> |
| 42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
| @@ -72,7 +72,6 @@ copy_word: · 71 unmodified lines | |||
| 72 | LONG_ADDI s5, s5, -1 | 72 | LONG_ADDI s5, s5, -1 |
| 73 | beqz s5, process_entry | 73 | beqz s5, process_entry |
| 74 | b copy_word | 74 | b copy_word |
| 75 | b process_entry | ||
| 76 | 75 | ||
| 77 | done: | 76 | done: |
| 78 | ibar 0 | 77 | ibar 0 |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/audit.h> | 13 | #include <linux/audit.h> |
| 14 | #include <linux/cache.h> | 14 | #include <linux/cache.h> |
| 15 | #include <linux/context_tracking.h> | 15 | #include <linux/context_tracking.h> |
| 16 | #include <linux/entry-common.h> | ||
| 16 | #include <linux/irqflags.h> | 17 | #include <linux/irqflags.h> |
| 17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 18 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
| @@ -891,8 +892,8 @@ static unsigned long setup_extcontext(struct extctx_layout *extctx, unsigned lon · 872 unmodified lines | |||
| 891 | return new_sp; | 892 | return new_sp; |
| 892 | } | 893 | } |
| 893 | 894 | ||
| 894 | void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, | 895 | static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, |
| 895 | struct extctx_layout *extctx) | 896 | struct extctx_layout *extctx) |
| 896 | { | 897 | { |
| 897 | unsigned long sp; | 898 | unsigned long sp; |
| 898 | 899 | ||
| @@ -922,7 +923,7 @@ void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, · 23 unmodified lines | |||
| 922 | * Atomically swap in the new signal mask, and wait for a signal. | 923 | * Atomically swap in the new signal mask, and wait for a signal. |
| 923 | */ | 924 | */ |
| 924 | 925 | ||
| 925 | asmlinkage long sys_rt_sigreturn(void) | 926 | SYSCALL_DEFINE0(rt_sigreturn) |
| 926 | { | 927 | { |
| 927 | int sig; | 928 | int sig; |
| 928 | sigset_t set; | 929 | sigset_t set; |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/cpumask.h> | 13 | #include <linux/cpumask.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
| 16 | #include <linux/profile.h> | ||
| 16 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
| 17 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
| 18 | #include <linux/threads.h> | 19 | #include <linux/threads.h> |
| @@ -556,10 +557,12 @@ void smp_send_stop(void) · 537 unmodified lines | |||
| 556 | smp_call_function(stop_this_cpu, NULL, 0); | 557 | smp_call_function(stop_this_cpu, NULL, 0); |
| 557 | } | 558 | } |
| 558 | 559 | ||
| 560 | #ifdef CONFIG_PROFILING | ||
| 559 | int setup_profiling_timer(unsigned int multiplier) | 561 | int setup_profiling_timer(unsigned int multiplier) |
| 560 | { | 562 | { |
| 561 | return 0; | 563 | return 0; |
| 562 | } | 564 | } |
| 565 | #endif | ||
| 563 | 566 | ||
| 564 | static void flush_tlb_all_ipi(void *info) | 567 | static void flush_tlb_all_ipi(void *info) |
| 565 | { | 568 | { |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/unistd.h> | 13 | #include <linux/unistd.h> |
| 14 | 14 | ||
| 15 | #include <asm/asm.h> | 15 | #include <asm/asm.h> |
| 16 | #include <asm/exception.h> | ||
| 16 | #include <asm/signal.h> | 17 | #include <asm/signal.h> |
| 17 | #include <asm/switch_to.h> | 18 | #include <asm/switch_to.h> |
| 18 | #include <asm-generic/syscalls.h> | 19 | #include <asm-generic/syscalls.h> |
| @@ -29,7 +29,7 @@ static void constant_event_handler(struct clock_event_device *dev) · 28 unmodified lines | |||
| 29 | { | 29 | { |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | irqreturn_t constant_timer_interrupt(int irq, void *data) | 32 | static irqreturn_t constant_timer_interrupt(int irq, void *data) |
| 33 | { | 33 | { |
| 34 | int cpu = smp_processor_id(); | 34 | int cpu = smp_processor_id(); |
| 35 | struct clock_event_device *cd; | 35 | struct clock_event_device *cd; |
| @@ -1,4 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/acpi.h> | ||
| 2 | #include <linux/cpu.h> | 3 | #include <linux/cpu.h> |
| 3 | #include <linux/cpumask.h> | 4 | #include <linux/cpumask.h> |
| 4 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| @@ -7,6 +8,8 @@ · 2 unmodified lines | |||
| 7 | #include <linux/percpu.h> | 8 | #include <linux/percpu.h> |
| 8 | #include <asm/bootinfo.h> | 9 | #include <asm/bootinfo.h> |
| 9 | 10 | ||
| 11 | #include <acpi/processor.h> | ||
| 12 | |||
| 10 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 13 | static DEFINE_PER_CPU(struct cpu, cpu_devices); |
| 11 | 14 | ||
| 12 | #ifdef CONFIG_HOTPLUG_CPU | 15 | #ifdef CONFIG_HOTPLUG_CPU |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
| 26 | #include <linux/kgdb.h> | 26 | #include <linux/kgdb.h> |
| 27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
| 28 | #include <linux/kprobes.h> | ||
| 29 | #include <linux/notifier.h> | 28 | #include <linux/notifier.h> |
| 30 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
| 31 | #include <linux/perf_event.h> | 30 | #include <linux/perf_event.h> |
| @@ -35,6 +34,7 @@ · 3 unmodified lines | |||
| 35 | #include <asm/branch.h> | 34 | #include <asm/branch.h> |
| 36 | #include <asm/break.h> | 35 | #include <asm/break.h> |
| 37 | #include <asm/cpu.h> | 36 | #include <asm/cpu.h> |
| 37 | #include <asm/exception.h> | ||
| 38 | #include <asm/fpu.h> | 38 | #include <asm/fpu.h> |
| 39 | #include <asm/lbt.h> | 39 | #include <asm/lbt.h> |
| 40 | #include <asm/inst.h> | 40 | #include <asm/inst.h> |
| @@ -53,21 +53,6 @@ · 12 unmodified lines | |||
| 53 | 53 | ||
| 54 | #include "access-helper.h" | 54 | #include "access-helper.h" |
| 55 | 55 | ||
| 56 | extern asmlinkage void handle_ade(void); | ||
| 57 | extern asmlinkage void handle_ale(void); | ||
| 58 | extern asmlinkage void handle_bce(void); | ||
| 59 | extern asmlinkage void handle_sys(void); | ||
| 60 | extern asmlinkage void handle_bp(void); | ||
| 61 | extern asmlinkage void handle_ri(void); | ||
| 62 | extern asmlinkage void handle_fpu(void); | ||
| 63 | extern asmlinkage void handle_fpe(void); | ||
| 64 | extern asmlinkage void handle_lbt(void); | ||
| 65 | extern asmlinkage void handle_lsx(void); | ||
| 66 | extern asmlinkage void handle_lasx(void); | ||
| 67 | extern asmlinkage void handle_reserved(void); | ||
| 68 | extern asmlinkage void handle_watch(void); | ||
| 69 | extern asmlinkage void handle_vint(void); | ||
| 70 | |||
| 71 | static void show_backtrace(struct task_struct *task, const struct pt_regs *regs, | 56 | static void show_backtrace(struct task_struct *task, const struct pt_regs *regs, |
| 72 | const char *loglvl, bool user) | 57 | const char *loglvl, bool user) |
| 73 | { | 58 | { |
| @@ -439,8 +424,8 @@ static inline void setup_vint_size(unsigned int size) · 365 unmodified lines | |||
| 439 | * happen together with Overflow or Underflow, and `ptrace' can set | 424 | * happen together with Overflow or Underflow, and `ptrace' can set |
| 440 | * any bits. | 425 | * any bits. |
| 441 | */ | 426 | */ |
| 442 | void force_fcsr_sig(unsigned long fcsr, void __user *fault_addr, | 427 | static void force_fcsr_sig(unsigned long fcsr, |
| 443 | struct task_struct *tsk) | 428 | void __user *fault_addr, struct task_struct *tsk) |
| 444 | { | 429 | { |
| 445 | int si_code = FPE_FLTUNK; | 430 | int si_code = FPE_FLTUNK; |
| 446 | 431 | ||
| @@ -458,7 +443,7 @@ void force_fcsr_sig(unsigned long fcsr, void __user *fault_addr, · 11 unmodified lines | |||
| 458 | force_sig_fault(SIGFPE, si_code, fault_addr); | 443 | force_sig_fault(SIGFPE, si_code, fault_addr); |
| 459 | } | 444 | } |
| 460 | 445 | ||
| 461 | int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcsr) | 446 | static int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcsr) |
| 462 | { | 447 | { |
| 463 | int si_code; | 448 | int si_code; |
| 464 | 449 | ||
| @@ -824,7 +809,7 @@ out: · 359 unmodified lines | |||
| 824 | asmlinkage void noinstr do_ri(struct pt_regs *regs) | 809 | asmlinkage void noinstr do_ri(struct pt_regs *regs) |
| 825 | { | 810 | { |
| 826 | int status = SIGILL; | 811 | int status = SIGILL; |
| 827 | unsigned int opcode = 0; | 812 | unsigned int __maybe_unused opcode; |
| 828 | unsigned int __user *era = (unsigned int __user *)exception_era(regs); | 813 | unsigned int __user *era = (unsigned int __user *)exception_era(regs); |
| 829 | irqentry_state_t state = irqentry_enter(regs); | 814 | irqentry_state_t state = irqentry_enter(regs); |
| 830 | 815 | ||
| @@ -53,33 +53,6 @@ SECTIONS · 52 unmodified lines | |||
| 53 | . = ALIGN(PECOFF_SEGMENT_ALIGN); | 53 | . = ALIGN(PECOFF_SEGMENT_ALIGN); |
| 54 | _etext = .; | 54 | _etext = .; |
| 55 | 55 | ||
| 56 | /* | ||
| 57 | * struct alt_inst entries. From the header (alternative.h): | ||
| 58 | * "Alternative instructions for different CPU types or capabilities" | ||
| 59 | * Think locking instructions on spinlocks. | ||
| 60 | */ | ||
| 61 | . = ALIGN(4); | ||
| 62 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { | ||
| 63 | __alt_instructions = .; | ||
| 64 | *(.altinstructions) | ||
| 65 | __alt_instructions_end = .; | ||
| 66 | } | ||
| 67 | |||
| 68 | #ifdef CONFIG_RELOCATABLE | ||
| 69 | . = ALIGN(8); | ||
| 70 | .la_abs : AT(ADDR(.la_abs) - LOAD_OFFSET) { | ||
| 71 | __la_abs_begin = .; | ||
| 72 | *(.la_abs) | ||
| 73 | __la_abs_end = .; | ||
| 74 | } | ||
| 75 | #endif | ||
| 76 | |||
| 77 | .got : ALIGN(16) { *(.got) } | ||
| 78 | .plt : ALIGN(16) { *(.plt) } | ||
| 79 | .got.plt : ALIGN(16) { *(.got.plt) } | ||
| 80 | |||
| 81 | .data.rel : { *(.data.rel*) } | ||
| 82 | |||
| 83 | . = ALIGN(PECOFF_SEGMENT_ALIGN); | 56 | . = ALIGN(PECOFF_SEGMENT_ALIGN); |
| 84 | __init_begin = .; | 57 | __init_begin = .; |
| 85 | __inittext_begin = .; | 58 | __inittext_begin = .; |
| @@ -94,6 +67,18 @@ SECTIONS · 8 unmodified lines | |||
| 94 | 67 | ||
| 95 | __initdata_begin = .; | 68 | __initdata_begin = .; |
| 96 | 69 | ||
| 70 | /* | ||
| 71 | * struct alt_inst entries. From the header (alternative.h): | ||
| 72 | * "Alternative instructions for different CPU types or capabilities" | ||
| 73 | * Think locking instructions on spinlocks. | ||
| 74 | */ | ||
| 75 | . = ALIGN(4); | ||
| 76 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { | ||
| 77 | __alt_instructions = .; | ||
| 78 | *(.altinstructions) | ||
| 79 | __alt_instructions_end = .; | ||
| 80 | } | ||
| 81 | |||
| 97 | INIT_DATA_SECTION(16) | 82 | INIT_DATA_SECTION(16) |
| 98 | .exit.data : { | 83 | .exit.data : { |
| 99 | EXIT_DATA | 84 | EXIT_DATA |
| @@ -113,6 +98,11 @@ SECTIONS · 13 unmodified lines | |||
| 113 | 98 | ||
| 114 | _sdata = .; | 99 | _sdata = .; |
| 115 | RO_DATA(4096) | 100 | RO_DATA(4096) |
| 101 | |||
| 102 | .got : ALIGN(16) { *(.got) } | ||
| 103 | .plt : ALIGN(16) { *(.plt) } | ||
| 104 | .got.plt : ALIGN(16) { *(.got.plt) } | ||
| 105 | |||
| 116 | RW_DATA(1 << CONFIG_L1_CACHE_SHIFT, PAGE_SIZE, THREAD_SIZE) | 106 | RW_DATA(1 << CONFIG_L1_CACHE_SHIFT, PAGE_SIZE, THREAD_SIZE) |
| 117 | 107 | ||
| 118 | .rela.dyn : ALIGN(8) { | 108 | .rela.dyn : ALIGN(8) { |
| @@ -121,6 +111,17 @@ SECTIONS · 2 unmodified lines | |||
| 121 | __rela_dyn_end = .; | 111 | __rela_dyn_end = .; |
| 122 | } | 112 | } |
| 123 | 113 | ||
| 114 | .data.rel : { *(.data.rel*) } | ||
| 115 | |||
| 116 | #ifdef CONFIG_RELOCATABLE | ||
| 117 | . = ALIGN(8); | ||
| 118 | .la_abs : AT(ADDR(.la_abs) - LOAD_OFFSET) { | ||
| 119 | __la_abs_begin = .; | ||
| 120 | *(.la_abs) | ||
| 121 | __la_abs_end = .; | ||
| 122 | } | ||
| 123 | #endif | ||
| 124 | |||
| 124 | .sdata : { | 125 | .sdata : { |
| 125 | *(.sdata) | 126 | *(.sdata) |
| 126 | } | 127 | } |
| @@ -20,12 +20,12 @@ · 19 unmodified lines | |||
| 20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
| 21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
| 22 | #include <linux/kdebug.h> | 22 | #include <linux/kdebug.h> |
| 23 | #include <linux/kprobes.h> | ||
| 24 | #include <linux/perf_event.h> | 23 | #include <linux/perf_event.h> |
| 25 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
| 26 | #include <linux/kfence.h> | 25 | #include <linux/kfence.h> |
| 27 | 26 | ||
| 28 | #include <asm/branch.h> | 27 | #include <asm/branch.h> |
| 28 | #include <asm/exception.h> | ||
| 29 | #include <asm/mmu_context.h> | 29 | #include <asm/mmu_context.h> |
| 30 | #include <asm/ptrace.h> | 30 | #include <asm/ptrace.h> |
| 31 | 31 | ||
| @@ -50,18 +50,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, · 49 unmodified lines | |||
| 50 | return (pte_t *) pmd; | 50 | return (pte_t *) pmd; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | /* | ||
| 54 | * This function checks for proper alignment of input addr and len parameters. | ||
| 55 | */ | ||
| 56 | int is_aligned_hugepage_range(unsigned long addr, unsigned long len) | ||
| 57 | { | ||
| 58 | if (len & ~HPAGE_MASK) | ||
| 59 | return -EINVAL; | ||
| 60 | if (addr & ~HPAGE_MASK) | ||
| 61 | return -EINVAL; | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | int pmd_huge(pmd_t pmd) | 53 | int pmd_huge(pmd_t pmd) |
| 66 | { | 54 | { |
| 67 | return (pmd_val(pmd) & _PAGE_HUGE) != 0; | 55 | return (pmd_val(pmd) & _PAGE_HUGE) != 0; |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <asm/io.h> | 6 | #include <asm/io.h> |
| 7 | #include <asm-generic/early_ioremap.h> | ||
| 7 | 8 | ||
| 8 | void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size) | 9 | void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size) |
| 9 | { | 10 | { |
| @@ -35,6 +35,57 @@ static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | bool kasan_early_stage = true; | 36 | bool kasan_early_stage = true; |
| 37 | 37 | ||
| 38 | void *kasan_mem_to_shadow(const void *addr) | ||
| 39 | { | ||
| 40 | if (!kasan_arch_is_ready()) { | ||
| 41 | return (void *)(kasan_early_shadow_page); | ||
| 42 | } else { | ||
| 43 | unsigned long maddr = (unsigned long)addr; | ||
| 44 | unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; | ||
| 45 | unsigned long offset = 0; | ||
| 46 | |||
| 47 | maddr &= XRANGE_SHADOW_MASK; | ||
| 48 | switch (xrange) { | ||
| 49 | case XKPRANGE_CC_SEG: | ||
| 50 | offset = XKPRANGE_CC_SHADOW_OFFSET; | ||
| 51 | break; | ||
| 52 | case XKPRANGE_UC_SEG: | ||
| 53 | offset = XKPRANGE_UC_SHADOW_OFFSET; | ||
| 54 | break; | ||
| 55 | case XKVRANGE_VC_SEG: | ||
| 56 | offset = XKVRANGE_VC_SHADOW_OFFSET; | ||
| 57 | break; | ||
| 58 | default: | ||
| 59 | WARN_ON(1); | ||
| 60 | return NULL; | ||
| 61 | } | ||
| 62 | |||
| 63 | return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | const void *kasan_shadow_to_mem(const void *shadow_addr) | ||
| 68 | { | ||
| 69 | unsigned long addr = (unsigned long)shadow_addr; | ||
| 70 | |||
| 71 | if (unlikely(addr > KASAN_SHADOW_END) || | ||
| 72 | unlikely(addr < KASAN_SHADOW_START)) { | ||
| 73 | WARN_ON(1); | ||
| 74 | return NULL; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (addr >= XKVRANGE_VC_SHADOW_OFFSET) | ||
| 78 | return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START); | ||
| 79 | else if (addr >= XKPRANGE_UC_SHADOW_OFFSET) | ||
| 80 | return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START); | ||
| 81 | else if (addr >= XKPRANGE_CC_SHADOW_OFFSET) | ||
| 82 | return (void *)(((addr - XKPRANGE_CC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_CC_START); | ||
| 83 | else { | ||
| 84 | WARN_ON(1); | ||
| 85 | return NULL; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 38 | /* | 89 | /* |
| 39 | * Alloc memory for shadow memory page table. | 90 | * Alloc memory for shadow memory page table. |
| 40 | */ | 91 | */ |
| @@ -261,7 +261,7 @@ unsigned long pcpu_handlers[NR_CPUS]; · 260 unmodified lines | |||
| 261 | #endif | 261 | #endif |
| 262 | extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; | 262 | extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; |
| 263 | 263 | ||
| 264 | void setup_tlb_handler(int cpu) | 264 | static void setup_tlb_handler(int cpu) |
| 265 | { | 265 | { |
| 266 | setup_ptwalker(); | 266 | setup_ptwalker(); |
| 267 | local_flush_tlb_all(); | 267 | local_flush_tlb_all(); |
| @@ -164,6 +164,7 @@ static struct platform_device db1x00_audio_dev = { · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | /******************************************************************************/ | 165 | /******************************************************************************/ |
| 166 | 166 | ||
| 167 | #ifdef CONFIG_MMC_AU1X | ||
| 167 | static irqreturn_t db1100_mmc_cd(int irq, void *ptr) | 168 | static irqreturn_t db1100_mmc_cd(int irq, void *ptr) |
| 168 | { | 169 | { |
| 169 | mmc_detect_change(ptr, msecs_to_jiffies(500)); | 170 | mmc_detect_change(ptr, msecs_to_jiffies(500)); |
| @@ -369,6 +370,7 @@ static struct platform_device db1100_mmc1_dev = { · 199 unmodified lines | |||
| 369 | .num_resources = ARRAY_SIZE(au1100_mmc1_res), | 370 | .num_resources = ARRAY_SIZE(au1100_mmc1_res), |
| 370 | .resource = au1100_mmc1_res, | 371 | .resource = au1100_mmc1_res, |
| 371 | }; | 372 | }; |
| 373 | #endif /* CONFIG_MMC_AU1X */ | ||
| 372 | 374 | ||
| 373 | /******************************************************************************/ | 375 | /******************************************************************************/ |
| 374 | 376 | ||
| @@ -440,8 +442,10 @@ static struct platform_device *db1x00_devs[] = { · 65 unmodified lines | |||
| 440 | 442 | ||
| 441 | static struct platform_device *db1100_devs[] = { | 443 | static struct platform_device *db1100_devs[] = { |
| 442 | &au1100_lcd_device, | 444 | &au1100_lcd_device, |
| 445 | #ifdef CONFIG_MMC_AU1X | ||
| 443 | &db1100_mmc0_dev, | 446 | &db1100_mmc0_dev, |
| 444 | &db1100_mmc1_dev, | 447 | &db1100_mmc1_dev, |
| 448 | #endif | ||
| 445 | }; | 449 | }; |
| 446 | 450 | ||
| 447 | int __init db1000_dev_setup(void) | 451 | int __init db1000_dev_setup(void) |
| @@ -326,6 +326,7 @@ static struct platform_device db1200_ide_dev = { · 325 unmodified lines | |||
| 326 | 326 | ||
| 327 | /**********************************************************************/ | 327 | /**********************************************************************/ |
| 328 | 328 | ||
| 329 | #ifdef CONFIG_MMC_AU1X | ||
| 329 | /* SD carddetects: they're supposed to be edge-triggered, but ack | 330 | /* SD carddetects: they're supposed to be edge-triggered, but ack |
| 330 | * doesn't seem to work (CPLD Rev 2). Instead, the screaming one | 331 | * doesn't seem to work (CPLD Rev 2). Instead, the screaming one |
| 331 | * is disabled and its counterpart enabled. The 200ms timeout is | 332 | * is disabled and its counterpart enabled. The 200ms timeout is |
| @@ -584,6 +585,7 @@ static struct platform_device pb1200_mmc1_dev = { · 252 unmodified lines | |||
| 584 | .num_resources = ARRAY_SIZE(au1200_mmc1_res), | 585 | .num_resources = ARRAY_SIZE(au1200_mmc1_res), |
| 585 | .resource = au1200_mmc1_res, | 586 | .resource = au1200_mmc1_res, |
| 586 | }; | 587 | }; |
| 588 | #endif /* CONFIG_MMC_AU1X */ | ||
| 587 | 589 | ||
| 588 | /**********************************************************************/ | 590 | /**********************************************************************/ |
| 589 | 591 | ||
| @@ -751,7 +753,9 @@ static struct platform_device db1200_audiodma_dev = { · 161 unmodified lines | |||
| 751 | static struct platform_device *db1200_devs[] __initdata = { | 753 | static struct platform_device *db1200_devs[] __initdata = { |
| 752 | NULL, /* PSC0, selected by S6.8 */ | 754 | NULL, /* PSC0, selected by S6.8 */ |
| 753 | &db1200_ide_dev, | 755 | &db1200_ide_dev, |
| 756 | #ifdef CONFIG_MMC_AU1X | ||
| 754 | &db1200_mmc0_dev, | 757 | &db1200_mmc0_dev, |
| 758 | #endif | ||
| 755 | &au1200_lcd_dev, | 759 | &au1200_lcd_dev, |
| 756 | &db1200_eth_dev, | 760 | &db1200_eth_dev, |
| 757 | &db1200_nand_dev, | 761 | &db1200_nand_dev, |
| @@ -762,7 +766,9 @@ static struct platform_device *db1200_devs[] __initdata = { · 4 unmodified lines | |||
| 762 | }; | 766 | }; |
| 763 | 767 | ||
| 764 | static struct platform_device *pb1200_devs[] __initdata = { | 768 | static struct platform_device *pb1200_devs[] __initdata = { |
| 769 | #ifdef CONFIG_MMC_AU1X | ||
| 765 | &pb1200_mmc1_dev, | 770 | &pb1200_mmc1_dev, |
| 771 | #endif | ||
| 766 | }; | 772 | }; |
| 767 | 773 | ||
| 768 | /* Some peripheral base addresses differ on the PB1200 */ | 774 | /* Some peripheral base addresses differ on the PB1200 */ |
| @@ -450,6 +450,7 @@ static struct platform_device db1300_ide_dev = { · 449 unmodified lines | |||
| 450 | 450 | ||
| 451 | /**********************************************************************/ | 451 | /**********************************************************************/ |
| 452 | 452 | ||
| 453 | #ifdef CONFIG_MMC_AU1X | ||
| 453 | static irqreturn_t db1300_mmc_cd(int irq, void *ptr) | 454 | static irqreturn_t db1300_mmc_cd(int irq, void *ptr) |
| 454 | { | 455 | { |
| 455 | disable_irq_nosync(irq); | 456 | disable_irq_nosync(irq); |
| @@ -632,6 +633,7 @@ static struct platform_device db1300_sd0_dev = { · 176 unmodified lines | |||
| 632 | .resource = au1300_sd0_res, | 633 | .resource = au1300_sd0_res, |
| 633 | .num_resources = ARRAY_SIZE(au1300_sd0_res), | 634 | .num_resources = ARRAY_SIZE(au1300_sd0_res), |
| 634 | }; | 635 | }; |
| 636 | #endif /* CONFIG_MMC_AU1X */ | ||
| 635 | 637 | ||
| 636 | /**********************************************************************/ | 638 | /**********************************************************************/ |
| 637 | 639 | ||
| @@ -767,8 +769,10 @@ static struct platform_device *db1300_dev[] __initdata = { · 129 unmodified lines | |||
| 767 | &db1300_5waysw_dev, | 769 | &db1300_5waysw_dev, |
| 768 | &db1300_nand_dev, | 770 | &db1300_nand_dev, |
| 769 | &db1300_ide_dev, | 771 | &db1300_ide_dev, |
| 772 | #ifdef CONFIG_MMC_AU1X | ||
| 770 | &db1300_sd0_dev, | 773 | &db1300_sd0_dev, |
| 771 | &db1300_sd1_dev, | 774 | &db1300_sd1_dev, |
| 775 | #endif | ||
| 772 | &db1300_lcd_dev, | 776 | &db1300_lcd_dev, |
| 773 | &db1300_ac97_dev, | 777 | &db1300_ac97_dev, |
| 774 | &db1300_i2s_dev, | 778 | &db1300_i2s_dev, |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 7 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 8 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 8 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 9 | pte_t *ptep, pte_t pte); | 9 | pte_t *ptep, pte_t pte, unsigned long sz); |
| 10 | 10 | ||
| 11 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR | 11 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR |
| 12 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, | 12 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, |
| @@ -140,7 +140,7 @@ static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 139 unmodified lines | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 142 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 143 | pte_t *ptep, pte_t entry) | 143 | pte_t *ptep, pte_t entry, unsigned long sz) |
| 144 | { | 144 | { |
| 145 | __set_huge_pte_at(mm, addr, ptep, entry); | 145 | __set_huge_pte_at(mm, addr, ptep, entry); |
| 146 | } | 146 | } |
| @@ -46,7 +46,8 @@ static inline int check_and_get_huge_psize(int shift) · 45 unmodified lines | |||
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 48 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 49 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); | 49 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, |
| 50 | pte_t pte, unsigned long sz); | ||
| 50 | 51 | ||
| 51 | #define __HAVE_ARCH_HUGE_PTE_CLEAR | 52 | #define __HAVE_ARCH_HUGE_PTE_CLEAR |
| 52 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, | 53 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, |
| @@ -73,29 +73,12 @@ int __no_sanitize_address arch_stack_walk_reliable(stack_trace_consume_fn consum · 72 unmodified lines | |||
| 73 | bool firstframe; | 73 | bool firstframe; |
| 74 | 74 | ||
| 75 | stack_end = stack_page + THREAD_SIZE; | 75 | stack_end = stack_page + THREAD_SIZE; |
| 76 | if (!is_idle_task(task)) { | 76 | |
| 77 | /* | 77 | // See copy_thread() for details. |
| 78 | * For user tasks, this is the SP value loaded on | 78 | if (task->flags & PF_KTHREAD) |
| 79 | * kernel entry, see "PACAKSAVE(r13)" in _switch() and | ||
| 80 | * system_call_common(). | ||
| 81 | * | ||
| 82 | * Likewise for non-swapper kernel threads, | ||
| 83 | * this also happens to be the top of the stack | ||
| 84 | * as setup by copy_thread(). | ||
| 85 | * | ||
| 86 | * Note that stack backlinks are not properly setup by | ||
| 87 | * copy_thread() and thus, a forked task() will have | ||
| 88 | * an unreliable stack trace until it's been | ||
| 89 | * _switch()'ed to for the first time. | ||
| 90 | */ | ||
| 91 | stack_end -= STACK_USER_INT_FRAME_SIZE; | ||
| 92 | } else { | ||
| 93 | /* | ||
| 94 | * idle tasks have a custom stack layout, | ||
| 95 | * c.f. cpu_idle_thread_init(). | ||
| 96 | */ | ||
| 97 | stack_end -= STACK_FRAME_MIN_SIZE; | 79 | stack_end -= STACK_FRAME_MIN_SIZE; |
| 98 | } | 80 | else |
| 81 | stack_end -= STACK_USER_INT_FRAME_SIZE; | ||
| 99 | 82 | ||
| 100 | if (task == current) | 83 | if (task == current) |
| 101 | sp = current_stack_frame(); | 84 | sp = current_stack_frame(); |
| @@ -143,11 +143,14 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, · 142 unmodified lines | |||
| 143 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, | 143 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, |
| 144 | pte_t *ptep, pte_t old_pte, pte_t pte) | 144 | pte_t *ptep, pte_t old_pte, pte_t pte) |
| 145 | { | 145 | { |
| 146 | unsigned long psize; | ||
| 146 | 147 | ||
| 147 | if (radix_enabled()) | 148 | if (radix_enabled()) |
| 148 | return radix__huge_ptep_modify_prot_commit(vma, addr, ptep, | 149 | return radix__huge_ptep_modify_prot_commit(vma, addr, ptep, |
| 149 | old_pte, pte); | 150 | old_pte, pte); |
| 150 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 151 | |
| 152 | psize = huge_page_size(hstate_vma(vma)); | ||
| 153 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize); | ||
| 151 | } | 154 | } |
| 152 | 155 | ||
| 153 | void __init hugetlbpage_init_defaultsize(void) | 156 | void __init hugetlbpage_init_defaultsize(void) |
| @@ -47,6 +47,7 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma, · 46 unmodified lines | |||
| 47 | pte_t old_pte, pte_t pte) | 47 | pte_t old_pte, pte_t pte) |
| 48 | { | 48 | { |
| 49 | struct mm_struct *mm = vma->vm_mm; | 49 | struct mm_struct *mm = vma->vm_mm; |
| 50 | unsigned long psize = huge_page_size(hstate_vma(vma)); | ||
| 50 | 51 | ||
| 51 | /* | 52 | /* |
| 52 | * POWER9 NMMU must flush the TLB after clearing the PTE before | 53 | * POWER9 NMMU must flush the TLB after clearing the PTE before |
| @@ -58,5 +59,5 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma, · 5 unmodified lines | |||
| 58 | atomic_read(&mm->context.copros) > 0) | 59 | atomic_read(&mm->context.copros) > 0) |
| 59 | radix__flush_hugetlb_page(vma, addr); | 60 | radix__flush_hugetlb_page(vma, addr); |
| 60 | 61 | ||
| 61 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 62 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize); |
| 62 | } | 63 | } |
| @@ -91,7 +91,8 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa, · 90 unmodified lines | |||
| 91 | if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot))) | 91 | if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot))) |
| 92 | return -EINVAL; | 92 | return -EINVAL; |
| 93 | 93 | ||
| 94 | set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot))); | 94 | set_huge_pte_at(&init_mm, va, ptep, |
| 95 | pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)), psize); | ||
| 95 | 96 | ||
| 96 | return 0; | 97 | return 0; |
| 97 | } | 98 | } |
| @@ -288,7 +288,8 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma, · 287 unmodified lines | |||
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | #if defined(CONFIG_PPC_8xx) | 290 | #if defined(CONFIG_PPC_8xx) |
| 291 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) | 291 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, |
| 292 | pte_t pte, unsigned long sz) | ||
| 292 | { | 293 | { |
| 293 | pmd_t *pmd = pmd_off(mm, addr); | 294 | pmd_t *pmd = pmd_off(mm, addr); |
| 294 | pte_basic_t val; | 295 | pte_basic_t val; |
| @@ -262,7 +262,7 @@ · 261 unmodified lines | |||
| 262 | reg = <0x100000 0x400000>; | 262 | reg = <0x100000 0x400000>; |
| 263 | }; | 263 | }; |
| 264 | reserved-data@600000 { | 264 | reserved-data@600000 { |
| 265 | reg = <0x600000 0x1000000>; | 265 | reg = <0x600000 0xa00000>; |
| 266 | }; | 266 | }; |
| 267 | }; | 267 | }; |
| 268 | }; | 268 | }; |
| @@ -440,30 +440,6 @@ · 171 unmodified lines | |||
| 440 | }; | 440 | }; |
| 441 | }; | 441 | }; |
| 442 | 442 | ||
| 443 | uart0_pins: uart0-0 { | ||
| 444 | tx-pins { | ||
| 445 | pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX, | ||
| 446 | GPOEN_ENABLE, | ||
| 447 | GPI_NONE)>; | ||
| 448 | bias-disable; | ||
| 449 | drive-strength = <12>; | ||
| 450 | input-disable; | ||
| 451 | input-schmitt-disable; | ||
| 452 | slew-rate = <0>; | ||
| 453 | }; | ||
| 454 | |||
| 455 | rx-pins { | ||
| 456 | pinmux = <GPIOMUX(6, GPOUT_LOW, | ||
| 457 | GPOEN_DISABLE, | ||
| 458 | GPI_SYS_UART0_RX)>; | ||
| 459 | bias-disable; /* external pull-up */ | ||
| 460 | drive-strength = <2>; | ||
| 461 | input-enable; | ||
| 462 | input-schmitt-enable; | ||
| 463 | slew-rate = <0>; | ||
| 464 | }; | ||
| 465 | }; | ||
| 466 | |||
| 467 | tdm_pins: tdm-0 { | 443 | tdm_pins: tdm-0 { |
| 468 | tx-pins { | 444 | tx-pins { |
| 469 | pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD, | 445 | pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD, |
| @@ -497,6 +473,30 @@ · 27 unmodified lines | |||
| 497 | input-enable; | 473 | input-enable; |
| 498 | }; | 474 | }; |
| 499 | }; | 475 | }; |
| 476 | |||
| 477 | uart0_pins: uart0-0 { | ||
| 478 | tx-pins { | ||
| 479 | pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX, | ||
| 480 | GPOEN_ENABLE, | ||
| 481 | GPI_NONE)>; | ||
| 482 | bias-disable; | ||
| 483 | drive-strength = <12>; | ||
| 484 | input-disable; | ||
| 485 | input-schmitt-disable; | ||
| 486 | slew-rate = <0>; | ||
| 487 | }; | ||
| 488 | |||
| 489 | rx-pins { | ||
| 490 | pinmux = <GPIOMUX(6, GPOUT_LOW, | ||
| 491 | GPOEN_DISABLE, | ||
| 492 | GPI_SYS_UART0_RX)>; | ||
| 493 | bias-disable; /* external pull-up */ | ||
| 494 | drive-strength = <2>; | ||
| 495 | input-enable; | ||
| 496 | input-schmitt-enable; | ||
| 497 | slew-rate = <0>; | ||
| 498 | }; | ||
| 499 | }; | ||
| 500 | }; | 500 | }; |
| 501 | 501 | ||
| 502 | &tdm { | 502 | &tdm { |
| @@ -513,6 +513,7 @@ · 10 unmodified lines | |||
| 513 | 513 | ||
| 514 | &usb0 { | 514 | &usb0 { |
| 515 | dr_mode = "peripheral"; | 515 | dr_mode = "peripheral"; |
| 516 | status = "okay"; | ||
| 516 | }; | 517 | }; |
| 517 | 518 | ||
| 518 | &U74_1 { | 519 | &U74_1 { |
| @@ -18,7 +18,8 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr, · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 19 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 20 | void set_huge_pte_at(struct mm_struct *mm, | 20 | void set_huge_pte_at(struct mm_struct *mm, |
| 21 | unsigned long addr, pte_t *ptep, pte_t pte); | 21 | unsigned long addr, pte_t *ptep, pte_t pte, |
| 22 | unsigned long sz); | ||
| 22 | 23 | ||
| 23 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR | 24 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR |
| 24 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | 25 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
| @@ -460,8 +460,11 @@ static int riscv_vcpu_get_isa_ext_single(struct kvm_vcpu *vcpu, · 459 unmodified lines | |||
| 460 | reg_num >= ARRAY_SIZE(kvm_isa_ext_arr)) | 460 | reg_num >= ARRAY_SIZE(kvm_isa_ext_arr)) |
| 461 | return -ENOENT; | 461 | return -ENOENT; |
| 462 | 462 | ||
| 463 | *reg_val = 0; | ||
| 464 | host_isa_ext = kvm_isa_ext_arr[reg_num]; | 463 | host_isa_ext = kvm_isa_ext_arr[reg_num]; |
| 464 | if (!__riscv_isa_extension_available(NULL, host_isa_ext)) | ||
| 465 | return -ENOENT; | ||
| 466 | |||
| 467 | *reg_val = 0; | ||
| 465 | if (__riscv_isa_extension_available(vcpu->arch.isa, host_isa_ext)) | 468 | if (__riscv_isa_extension_available(vcpu->arch.isa, host_isa_ext)) |
| 466 | *reg_val = 1; /* Mark the given extension as available */ | 469 | *reg_val = 1; /* Mark the given extension as available */ |
| 467 | 470 | ||
| @@ -842,7 +845,7 @@ static int copy_isa_ext_reg_indices(const struct kvm_vcpu *vcpu, · 374 unmodified lines | |||
| 842 | u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_ISA_EXT | i; | 845 | u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_ISA_EXT | i; |
| 843 | 846 | ||
| 844 | isa_ext = kvm_isa_ext_arr[i]; | 847 | isa_ext = kvm_isa_ext_arr[i]; |
| 845 | if (!__riscv_isa_extension_available(vcpu->arch.isa, isa_ext)) | 848 | if (!__riscv_isa_extension_available(NULL, isa_ext)) |
| 846 | continue; | 849 | continue; |
| 847 | 850 | ||
| 848 | if (uindices) { | 851 | if (uindices) { |
| @@ -180,7 +180,8 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) · 179 unmodified lines | |||
| 180 | void set_huge_pte_at(struct mm_struct *mm, | 180 | void set_huge_pte_at(struct mm_struct *mm, |
| 181 | unsigned long addr, | 181 | unsigned long addr, |
| 182 | pte_t *ptep, | 182 | pte_t *ptep, |
| 183 | pte_t pte) | 183 | pte_t pte, |
| 184 | unsigned long sz) | ||
| 184 | { | 185 | { |
| 185 | int i, pte_num; | 186 | int i, pte_num; |
| 186 | 187 | ||
| @@ -40,23 +40,25 @@ CONFIG_SCHED_AUTOGROUP=y · 39 unmodified lines | |||
| 40 | CONFIG_EXPERT=y | 40 | CONFIG_EXPERT=y |
| 41 | # CONFIG_SYSFS_SYSCALL is not set | 41 | # CONFIG_SYSFS_SYSCALL is not set |
| 42 | CONFIG_PROFILING=y | 42 | CONFIG_PROFILING=y |
| 43 | CONFIG_KEXEC_FILE=y | ||
| 44 | CONFIG_KEXEC_SIG=y | ||
| 45 | CONFIG_CRASH_DUMP=y | ||
| 43 | CONFIG_LIVEPATCH=y | 46 | CONFIG_LIVEPATCH=y |
| 44 | CONFIG_MARCH_ZEC12=y | 47 | CONFIG_MARCH_ZEC12=y |
| 45 | CONFIG_TUNE_ZEC12=y | 48 | CONFIG_TUNE_ZEC12=y |
| 46 | CONFIG_NR_CPUS=512 | 49 | CONFIG_NR_CPUS=512 |
| 47 | CONFIG_NUMA=y | 50 | CONFIG_NUMA=y |
| 48 | CONFIG_HZ_100=y | 51 | CONFIG_HZ_100=y |
| 49 | CONFIG_KEXEC_FILE=y | 52 | CONFIG_CERT_STORE=y |
| 50 | CONFIG_KEXEC_SIG=y | ||
| 51 | CONFIG_EXPOLINE=y | 53 | CONFIG_EXPOLINE=y |
| 52 | CONFIG_EXPOLINE_AUTO=y | 54 | CONFIG_EXPOLINE_AUTO=y |
| 53 | CONFIG_CHSC_SCH=y | 55 | CONFIG_CHSC_SCH=y |
| 54 | CONFIG_VFIO_CCW=m | 56 | CONFIG_VFIO_CCW=m |
| 55 | CONFIG_VFIO_AP=m | 57 | CONFIG_VFIO_AP=m |
| 56 | CONFIG_CRASH_DUMP=y | ||
| 57 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y | 58 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y |
| 58 | CONFIG_CMM=m | 59 | CONFIG_CMM=m |
| 59 | CONFIG_APPLDATA_BASE=y | 60 | CONFIG_APPLDATA_BASE=y |
| 61 | CONFIG_S390_HYPFS_FS=y | ||
| 60 | CONFIG_KVM=m | 62 | CONFIG_KVM=m |
| 61 | CONFIG_S390_UNWIND_SELFTEST=m | 63 | CONFIG_S390_UNWIND_SELFTEST=m |
| 62 | CONFIG_S390_KPROBES_SANITY_TEST=m | 64 | CONFIG_S390_KPROBES_SANITY_TEST=m |
| @@ -434,6 +436,7 @@ CONFIG_SCSI_DH_EMC=m · 371 unmodified lines | |||
| 434 | CONFIG_SCSI_DH_ALUA=m | 436 | CONFIG_SCSI_DH_ALUA=m |
| 435 | CONFIG_MD=y | 437 | CONFIG_MD=y |
| 436 | CONFIG_BLK_DEV_MD=y | 438 | CONFIG_BLK_DEV_MD=y |
| 439 | # CONFIG_MD_BITMAP_FILE is not set | ||
| 437 | CONFIG_MD_LINEAR=m | 440 | CONFIG_MD_LINEAR=m |
| 438 | CONFIG_MD_MULTIPATH=m | 441 | CONFIG_MD_MULTIPATH=m |
| 439 | CONFIG_MD_FAULTY=m | 442 | CONFIG_MD_FAULTY=m |
| @@ -577,6 +580,7 @@ CONFIG_SOFT_WATCHDOG=m · 137 unmodified lines | |||
| 577 | CONFIG_DIAG288_WATCHDOG=m | 580 | CONFIG_DIAG288_WATCHDOG=m |
| 578 | # CONFIG_DRM_DEBUG_MODESET_LOCK is not set | 581 | # CONFIG_DRM_DEBUG_MODESET_LOCK is not set |
| 579 | CONFIG_FB=y | 582 | CONFIG_FB=y |
| 583 | # CONFIG_FB_DEVICE is not set | ||
| 580 | CONFIG_FRAMEBUFFER_CONSOLE=y | 584 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 581 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | 585 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y |
| 582 | # CONFIG_HID_SUPPORT is not set | 586 | # CONFIG_HID_SUPPORT is not set |
| @@ -647,6 +651,7 @@ CONFIG_PROC_KCORE=y · 64 unmodified lines | |||
| 647 | CONFIG_TMPFS=y | 651 | CONFIG_TMPFS=y |
| 648 | CONFIG_TMPFS_POSIX_ACL=y | 652 | CONFIG_TMPFS_POSIX_ACL=y |
| 649 | CONFIG_TMPFS_INODE64=y | 653 | CONFIG_TMPFS_INODE64=y |
| 654 | CONFIG_TMPFS_QUOTA=y | ||
| 650 | CONFIG_HUGETLBFS=y | 655 | CONFIG_HUGETLBFS=y |
| 651 | CONFIG_ECRYPT_FS=m | 656 | CONFIG_ECRYPT_FS=m |
| 652 | CONFIG_CRAMFS=m | 657 | CONFIG_CRAMFS=m |
| @@ -703,6 +708,7 @@ CONFIG_IMA_WRITE_POLICY=y · 50 unmodified lines | |||
| 703 | CONFIG_IMA_APPRAISE=y | 708 | CONFIG_IMA_APPRAISE=y |
| 704 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" | 709 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" |
| 705 | CONFIG_INIT_STACK_NONE=y | 710 | CONFIG_INIT_STACK_NONE=y |
| 711 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 706 | CONFIG_CRYPTO_USER=m | 712 | CONFIG_CRYPTO_USER=m |
| 707 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set | 713 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set |
| 708 | CONFIG_CRYPTO_PCRYPT=m | 714 | CONFIG_CRYPTO_PCRYPT=m |
| @@ -825,9 +831,9 @@ CONFIG_LOCK_STAT=y · 116 unmodified lines | |||
| 825 | CONFIG_DEBUG_ATOMIC_SLEEP=y | 831 | CONFIG_DEBUG_ATOMIC_SLEEP=y |
| 826 | CONFIG_DEBUG_LOCKING_API_SELFTESTS=y | 832 | CONFIG_DEBUG_LOCKING_API_SELFTESTS=y |
| 827 | CONFIG_DEBUG_IRQFLAGS=y | 833 | CONFIG_DEBUG_IRQFLAGS=y |
| 834 | CONFIG_DEBUG_LIST=y | ||
| 828 | CONFIG_DEBUG_SG=y | 835 | CONFIG_DEBUG_SG=y |
| 829 | CONFIG_DEBUG_NOTIFIERS=y | 836 | CONFIG_DEBUG_NOTIFIERS=y |
| 830 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 831 | CONFIG_DEBUG_CREDENTIALS=y | 837 | CONFIG_DEBUG_CREDENTIALS=y |
| 832 | CONFIG_RCU_TORTURE_TEST=m | 838 | CONFIG_RCU_TORTURE_TEST=m |
| 833 | CONFIG_RCU_REF_SCALE_TEST=m | 839 | CONFIG_RCU_REF_SCALE_TEST=m |
| @@ -38,23 +38,25 @@ CONFIG_SCHED_AUTOGROUP=y · 37 unmodified lines | |||
| 38 | CONFIG_EXPERT=y | 38 | CONFIG_EXPERT=y |
| 39 | # CONFIG_SYSFS_SYSCALL is not set | 39 | # CONFIG_SYSFS_SYSCALL is not set |
| 40 | CONFIG_PROFILING=y | 40 | CONFIG_PROFILING=y |
| 41 | CONFIG_KEXEC_FILE=y | ||
| 42 | CONFIG_KEXEC_SIG=y | ||
| 43 | CONFIG_CRASH_DUMP=y | ||
| 41 | CONFIG_LIVEPATCH=y | 44 | CONFIG_LIVEPATCH=y |
| 42 | CONFIG_MARCH_ZEC12=y | 45 | CONFIG_MARCH_ZEC12=y |
| 43 | CONFIG_TUNE_ZEC12=y | 46 | CONFIG_TUNE_ZEC12=y |
| 44 | CONFIG_NR_CPUS=512 | 47 | CONFIG_NR_CPUS=512 |
| 45 | CONFIG_NUMA=y | 48 | CONFIG_NUMA=y |
| 46 | CONFIG_HZ_100=y | 49 | CONFIG_HZ_100=y |
| 47 | CONFIG_KEXEC_FILE=y | 50 | CONFIG_CERT_STORE=y |
| 48 | CONFIG_KEXEC_SIG=y | ||
| 49 | CONFIG_EXPOLINE=y | 51 | CONFIG_EXPOLINE=y |
| 50 | CONFIG_EXPOLINE_AUTO=y | 52 | CONFIG_EXPOLINE_AUTO=y |
| 51 | CONFIG_CHSC_SCH=y | 53 | CONFIG_CHSC_SCH=y |
| 52 | CONFIG_VFIO_CCW=m | 54 | CONFIG_VFIO_CCW=m |
| 53 | CONFIG_VFIO_AP=m | 55 | CONFIG_VFIO_AP=m |
| 54 | CONFIG_CRASH_DUMP=y | ||
| 55 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y | 56 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y |
| 56 | CONFIG_CMM=m | 57 | CONFIG_CMM=m |
| 57 | CONFIG_APPLDATA_BASE=y | 58 | CONFIG_APPLDATA_BASE=y |
| 59 | CONFIG_S390_HYPFS_FS=y | ||
| 58 | CONFIG_KVM=m | 60 | CONFIG_KVM=m |
| 59 | CONFIG_S390_UNWIND_SELFTEST=m | 61 | CONFIG_S390_UNWIND_SELFTEST=m |
| 60 | CONFIG_S390_KPROBES_SANITY_TEST=m | 62 | CONFIG_S390_KPROBES_SANITY_TEST=m |
| @@ -424,6 +426,7 @@ CONFIG_SCSI_DH_EMC=m · 363 unmodified lines | |||
| 424 | CONFIG_SCSI_DH_ALUA=m | 426 | CONFIG_SCSI_DH_ALUA=m |
| 425 | CONFIG_MD=y | 427 | CONFIG_MD=y |
| 426 | CONFIG_BLK_DEV_MD=y | 428 | CONFIG_BLK_DEV_MD=y |
| 429 | # CONFIG_MD_BITMAP_FILE is not set | ||
| 427 | CONFIG_MD_LINEAR=m | 430 | CONFIG_MD_LINEAR=m |
| 428 | CONFIG_MD_MULTIPATH=m | 431 | CONFIG_MD_MULTIPATH=m |
| 429 | CONFIG_MD_FAULTY=m | 432 | CONFIG_MD_FAULTY=m |
| @@ -566,6 +569,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y · 136 unmodified lines | |||
| 566 | CONFIG_SOFT_WATCHDOG=m | 569 | CONFIG_SOFT_WATCHDOG=m |
| 567 | CONFIG_DIAG288_WATCHDOG=m | 570 | CONFIG_DIAG288_WATCHDOG=m |
| 568 | CONFIG_FB=y | 571 | CONFIG_FB=y |
| 572 | # CONFIG_FB_DEVICE is not set | ||
| 569 | CONFIG_FRAMEBUFFER_CONSOLE=y | 573 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 570 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | 574 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y |
| 571 | # CONFIG_HID_SUPPORT is not set | 575 | # CONFIG_HID_SUPPORT is not set |
| @@ -632,6 +636,7 @@ CONFIG_PROC_KCORE=y · 60 unmodified lines | |||
| 632 | CONFIG_TMPFS=y | 636 | CONFIG_TMPFS=y |
| 633 | CONFIG_TMPFS_POSIX_ACL=y | 637 | CONFIG_TMPFS_POSIX_ACL=y |
| 634 | CONFIG_TMPFS_INODE64=y | 638 | CONFIG_TMPFS_INODE64=y |
| 639 | CONFIG_TMPFS_QUOTA=y | ||
| 635 | CONFIG_HUGETLBFS=y | 640 | CONFIG_HUGETLBFS=y |
| 636 | CONFIG_CONFIGFS_FS=m | 641 | CONFIG_CONFIGFS_FS=m |
| 637 | CONFIG_ECRYPT_FS=m | 642 | CONFIG_ECRYPT_FS=m |
| @@ -687,6 +692,7 @@ CONFIG_IMA_WRITE_POLICY=y · 49 unmodified lines | |||
| 687 | CONFIG_IMA_APPRAISE=y | 692 | CONFIG_IMA_APPRAISE=y |
| 688 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" | 693 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" |
| 689 | CONFIG_INIT_STACK_NONE=y | 694 | CONFIG_INIT_STACK_NONE=y |
| 695 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 690 | CONFIG_CRYPTO_FIPS=y | 696 | CONFIG_CRYPTO_FIPS=y |
| 691 | CONFIG_CRYPTO_USER=m | 697 | CONFIG_CRYPTO_USER=m |
| 692 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set | 698 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set |
| @@ -781,7 +787,6 @@ CONFIG_PTDUMP_DEBUGFS=y · 88 unmodified lines | |||
| 781 | CONFIG_DEBUG_MEMORY_INIT=y | 787 | CONFIG_DEBUG_MEMORY_INIT=y |
| 782 | CONFIG_PANIC_ON_OOPS=y | 788 | CONFIG_PANIC_ON_OOPS=y |
| 783 | CONFIG_TEST_LOCKUP=m | 789 | CONFIG_TEST_LOCKUP=m |
| 784 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 785 | CONFIG_RCU_TORTURE_TEST=m | 790 | CONFIG_RCU_TORTURE_TEST=m |
| 786 | CONFIG_RCU_REF_SCALE_TEST=m | 791 | CONFIG_RCU_REF_SCALE_TEST=m |
| 787 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 792 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
| @@ -8,6 +8,7 @@ CONFIG_BPF_SYSCALL=y · 7 unmodified lines | |||
| 8 | # CONFIG_NET_NS is not set | 8 | # CONFIG_NET_NS is not set |
| 9 | CONFIG_BLK_DEV_INITRD=y | 9 | CONFIG_BLK_DEV_INITRD=y |
| 10 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 10 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
| 11 | CONFIG_CRASH_DUMP=y | ||
| 11 | CONFIG_MARCH_ZEC12=y | 12 | CONFIG_MARCH_ZEC12=y |
| 12 | CONFIG_TUNE_ZEC12=y | 13 | CONFIG_TUNE_ZEC12=y |
| 13 | # CONFIG_COMPAT is not set | 14 | # CONFIG_COMPAT is not set |
| @@ -15,9 +16,8 @@ CONFIG_NR_CPUS=2 · 1 unmodified line | |||
| 15 | CONFIG_HZ_100=y | 16 | CONFIG_HZ_100=y |
| 16 | # CONFIG_CHSC_SCH is not set | 17 | # CONFIG_CHSC_SCH is not set |
| 17 | # CONFIG_SCM_BUS is not set | 18 | # CONFIG_SCM_BUS is not set |
| 18 | CONFIG_CRASH_DUMP=y | ||
| 19 | # CONFIG_PFAULT is not set | 19 | # CONFIG_PFAULT is not set |
| 20 | # CONFIG_S390_HYPFS_FS is not set | 20 | # CONFIG_S390_HYPFS is not set |
| 21 | # CONFIG_VIRTUALIZATION is not set | 21 | # CONFIG_VIRTUALIZATION is not set |
| 22 | # CONFIG_S390_GUEST is not set | 22 | # CONFIG_S390_GUEST is not set |
| 23 | # CONFIG_SECCOMP is not set | 23 | # CONFIG_SECCOMP is not set |
| @@ -16,6 +16,8 @@ · 15 unmodified lines | |||
| 16 | #define hugepages_supported() (MACHINE_HAS_EDAT1) | 16 | #define hugepages_supported() (MACHINE_HAS_EDAT1) |
| 17 | 17 | ||
| 18 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 18 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 19 | pte_t *ptep, pte_t pte, unsigned long sz); | ||
| 20 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 19 | pte_t *ptep, pte_t pte); | 21 | pte_t *ptep, pte_t pte); |
| 20 | pte_t huge_ptep_get(pte_t *ptep); | 22 | pte_t huge_ptep_get(pte_t *ptep); |
| 21 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | 23 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
| @@ -65,7 +67,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, · 43 unmodified lines | |||
| 65 | int changed = !pte_same(huge_ptep_get(ptep), pte); | 67 | int changed = !pte_same(huge_ptep_get(ptep), pte); |
| 66 | if (changed) { | 68 | if (changed) { |
| 67 | huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); | 69 | huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); |
| 68 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 70 | __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); |
| 69 | } | 71 | } |
| 70 | return changed; | 72 | return changed; |
| 71 | } | 73 | } |
| @@ -74,7 +76,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, · 2 unmodified lines | |||
| 74 | unsigned long addr, pte_t *ptep) | 76 | unsigned long addr, pte_t *ptep) |
| 75 | { | 77 | { |
| 76 | pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep); | 78 | pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep); |
| 77 | set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte)); | 79 | __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte)); |
| 78 | } | 80 | } |
| 79 | 81 | ||
| 80 | static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot) | 82 | static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot) |
| @@ -432,15 +432,16 @@ static char *get_key_description(struct vcssb *vcssb, const struct vce *vce) · 431 unmodified lines | |||
| 432 | char *desc; | 432 | char *desc; |
| 433 | 433 | ||
| 434 | cs_token = vcssb->cs_token; | 434 | cs_token = vcssb->cs_token; |
| 435 | /* Description string contains "%64s:%04u:%08u\0". */ | 435 | /* Description string contains "%64s:%05u:%010u\0". */ |
| 436 | name_len = sizeof(vce->vce_hdr.vc_name); | 436 | name_len = sizeof(vce->vce_hdr.vc_name); |
| 437 | len = name_len + 1 + 4 + 1 + 8 + 1; | 437 | len = name_len + 1 + 5 + 1 + 10 + 1; |
| 438 | desc = kmalloc(len, GFP_KERNEL); | 438 | desc = kmalloc(len, GFP_KERNEL); |
| 439 | if (!desc) | 439 | if (!desc) |
| 440 | return NULL; | 440 | return NULL; |
| 441 | 441 | ||
| 442 | memcpy(desc, vce->vce_hdr.vc_name, name_len); | 442 | memcpy(desc, vce->vce_hdr.vc_name, name_len); |
| 443 | sprintf(desc + name_len, ":%04u:%08u", vce->vce_hdr.vc_index, cs_token); | 443 | snprintf(desc + name_len, len - name_len, ":%05u:%010u", |
| 444 | vce->vce_hdr.vc_index, cs_token); | ||
| 444 | 445 | ||
| 445 | return desc; | 446 | return desc; |
| 446 | } | 447 | } |
| @@ -142,7 +142,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste) · 141 unmodified lines | |||
| 142 | __storage_key_init_range(paddr, paddr + size - 1); | 142 | __storage_key_init_range(paddr, paddr + size - 1); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 145 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 146 | pte_t *ptep, pte_t pte) | 146 | pte_t *ptep, pte_t pte) |
| 147 | { | 147 | { |
| 148 | unsigned long rste; | 148 | unsigned long rste; |
| @@ -163,6 +163,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 14 unmodified lines | |||
| 163 | set_pte(ptep, __pte(rste)); | 163 | set_pte(ptep, __pte(rste)); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 167 | pte_t *ptep, pte_t pte, unsigned long sz) | ||
| 168 | { | ||
| 169 | __set_huge_pte_at(mm, addr, ptep, pte); | ||
| 170 | } | ||
| 171 | |||
| 166 | pte_t huge_ptep_get(pte_t *ptep) | 172 | pte_t huge_ptep_get(pte_t *ptep) |
| 167 | { | 173 | { |
| 168 | return __rste_to_pte(pte_val(*ptep)); | 174 | return __rste_to_pte(pte_val(*ptep)); |
| @@ -2513,7 +2513,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, · 2512 unmodified lines | |||
| 2513 | return -E2BIG; | 2513 | return -E2BIG; |
| 2514 | } | 2514 | } |
| 2515 | 2515 | ||
| 2516 | return ret; | 2516 | return tjit.common.prg; |
| 2517 | } | 2517 | } |
| 2518 | 2518 | ||
| 2519 | bool bpf_jit_supports_subprog_tailcalls(void) | 2519 | bool bpf_jit_supports_subprog_tailcalls(void) |
| @@ -72,8 +72,8 @@ __ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot) · 71 unmodified lines | |||
| 72 | #define __ioremap_29bit(offset, size, prot) NULL | 72 | #define __ioremap_29bit(offset, size, prot) NULL |
| 73 | #endif /* CONFIG_29BIT */ | 73 | #endif /* CONFIG_29BIT */ |
| 74 | 74 | ||
| 75 | void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, | 75 | void __iomem __ref *ioremap_prot(phys_addr_t phys_addr, size_t size, |
| 76 | unsigned long prot) | 76 | unsigned long prot) |
| 77 | { | 77 | { |
| 78 | void __iomem *mapped; | 78 | void __iomem *mapped; |
| 79 | pgprot_t pgprot = __pgprot(prot); | 79 | pgprot_t pgprot = __pgprot(prot); |
| @@ -14,6 +14,8 @@ extern struct pud_huge_patch_entry __pud_huge_patch, __pud_huge_patch_end; · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 15 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 16 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 16 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 17 | pte_t *ptep, pte_t pte, unsigned long sz); | ||
| 18 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 17 | pte_t *ptep, pte_t pte); | 19 | pte_t *ptep, pte_t pte); |
| 18 | 20 | ||
| 19 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR | 21 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR |
| @@ -32,7 +34,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, · 12 unmodified lines | |||
| 32 | unsigned long addr, pte_t *ptep) | 34 | unsigned long addr, pte_t *ptep) |
| 33 | { | 35 | { |
| 34 | pte_t old_pte = *ptep; | 36 | pte_t old_pte = *ptep; |
| 35 | set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); | 37 | __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS | 40 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS |
| @@ -42,7 +44,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, · 3 unmodified lines | |||
| 42 | { | 44 | { |
| 43 | int changed = !pte_same(*ptep, pte); | 45 | int changed = !pte_same(*ptep, pte); |
| 44 | if (changed) { | 46 | if (changed) { |
| 45 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 47 | __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); |
| 46 | flush_tlb_page(vma, addr); | 48 | flush_tlb_page(vma, addr); |
| 47 | } | 49 | } |
| 48 | return changed; | 50 | return changed; |
| @@ -328,7 +328,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, · 327 unmodified lines | |||
| 328 | return pte_offset_huge(pmd, addr); | 328 | return pte_offset_huge(pmd, addr); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 331 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 332 | pte_t *ptep, pte_t entry) | 332 | pte_t *ptep, pte_t entry) |
| 333 | { | 333 | { |
| 334 | unsigned int nptes, orig_shift, shift; | 334 | unsigned int nptes, orig_shift, shift; |
| @@ -364,6 +364,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 29 unmodified lines | |||
| 364 | orig_shift); | 364 | orig_shift); |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 368 | pte_t *ptep, pte_t entry, unsigned long sz) | ||
| 369 | { | ||
| 370 | __set_huge_pte_at(mm, addr, ptep, entry); | ||
| 371 | } | ||
| 372 | |||
| 367 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, | 373 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, |
| 368 | pte_t *ptep) | 374 | pte_t *ptep) |
| 369 | { | 375 | { |
| @@ -534,8 +534,12 @@ static void amd_pmu_cpu_reset(int cpu) · 533 unmodified lines | |||
| 534 | /* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */ | 534 | /* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */ |
| 535 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); | 535 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); |
| 536 | 536 | ||
| 537 | /* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */ | 537 | /* |
| 538 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask); | 538 | * Clear freeze and overflow bits i.e. PerfCntrGLobalStatus.LbrFreeze |
| 539 | * and PerfCntrGLobalStatus.PerfCntrOvfl | ||
| 540 | */ | ||
| 541 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, | ||
| 542 | GLOBAL_STATUS_LBRS_FROZEN | amd_pmu_global_cntr_mask); | ||
| 539 | } | 543 | } |
| 540 | 544 | ||
| 541 | static int amd_pmu_cpu_prepare(int cpu) | 545 | static int amd_pmu_cpu_prepare(int cpu) |
| @@ -570,6 +574,7 @@ static void amd_pmu_cpu_starting(int cpu) · 28 unmodified lines | |||
| 570 | int i, nb_id; | 574 | int i, nb_id; |
| 571 | 575 | ||
| 572 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; | 576 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; |
| 577 | amd_pmu_cpu_reset(cpu); | ||
| 573 | 578 | ||
| 574 | if (!x86_pmu.amd_nb_constraints) | 579 | if (!x86_pmu.amd_nb_constraints) |
| 575 | return; | 580 | return; |
| @@ -591,8 +596,6 @@ static void amd_pmu_cpu_starting(int cpu) · 15 unmodified lines | |||
| 591 | 596 | ||
| 592 | cpuc->amd_nb->nb_id = nb_id; | 597 | cpuc->amd_nb->nb_id = nb_id; |
| 593 | cpuc->amd_nb->refcnt++; | 598 | cpuc->amd_nb->refcnt++; |
| 594 | |||
| 595 | amd_pmu_cpu_reset(cpu); | ||
| 596 | } | 599 | } |
| 597 | 600 | ||
| 598 | static void amd_pmu_cpu_dead(int cpu) | 601 | static void amd_pmu_cpu_dead(int cpu) |
| @@ -601,6 +604,7 @@ static void amd_pmu_cpu_dead(int cpu) · 2 unmodified lines | |||
| 601 | 604 | ||
| 602 | kfree(cpuhw->lbr_sel); | 605 | kfree(cpuhw->lbr_sel); |
| 603 | cpuhw->lbr_sel = NULL; | 606 | cpuhw->lbr_sel = NULL; |
| 607 | amd_pmu_cpu_reset(cpu); | ||
| 604 | 608 | ||
| 605 | if (!x86_pmu.amd_nb_constraints) | 609 | if (!x86_pmu.amd_nb_constraints) |
| 606 | return; | 610 | return; |
| @@ -613,8 +617,6 @@ static void amd_pmu_cpu_dead(int cpu) · 6 unmodified lines | |||
| 613 | 617 | ||
| 614 | cpuhw->amd_nb = NULL; | 618 | cpuhw->amd_nb = NULL; |
| 615 | } | 619 | } |
| 616 | |||
| 617 | amd_pmu_cpu_reset(cpu); | ||
| 618 | } | 620 | } |
| 619 | 621 | ||
| 620 | static inline void amd_pmu_set_global_ctl(u64 ctl) | 622 | static inline void amd_pmu_set_global_ctl(u64 ctl) |
| @@ -884,7 +886,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs) · 263 unmodified lines | |||
| 884 | struct hw_perf_event *hwc; | 886 | struct hw_perf_event *hwc; |
| 885 | struct perf_event *event; | 887 | struct perf_event *event; |
| 886 | int handled = 0, idx; | 888 | int handled = 0, idx; |
| 887 | u64 status, mask; | 889 | u64 reserved, status, mask; |
| 888 | bool pmu_enabled; | 890 | bool pmu_enabled; |
| 889 | 891 | ||
| 890 | /* | 892 | /* |
| @@ -909,6 +911,14 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs) · 18 unmodified lines | |||
| 909 | status &= ~GLOBAL_STATUS_LBRS_FROZEN; | 911 | status &= ~GLOBAL_STATUS_LBRS_FROZEN; |
| 910 | } | 912 | } |
| 911 | 913 | ||
| 914 | reserved = status & ~amd_pmu_global_cntr_mask; | ||
| 915 | if (reserved) | ||
| 916 | pr_warn_once("Reserved PerfCntrGlobalStatus bits are set (0x%llx), please consider updating microcode\n", | ||
| 917 | reserved); | ||
| 918 | |||
| 919 | /* Clear any reserved bits set by buggy microcode */ | ||
| 920 | status &= amd_pmu_global_cntr_mask; | ||
| 921 | |||
| 912 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 922 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
| 913 | if (!test_bit(idx, cpuc->active_mask)) | 923 | if (!test_bit(idx, cpuc->active_mask)) |
| 914 | continue; | 924 | continue; |
| @@ -1419,7 +1419,6 @@ struct kvm_arch { · 1418 unmodified lines | |||
| 1419 | * the thread holds the MMU lock in write mode. | 1419 | * the thread holds the MMU lock in write mode. |
| 1420 | */ | 1420 | */ |
| 1421 | spinlock_t tdp_mmu_pages_lock; | 1421 | spinlock_t tdp_mmu_pages_lock; |
| 1422 | struct workqueue_struct *tdp_mmu_zap_wq; | ||
| 1423 | #endif /* CONFIG_X86_64 */ | 1422 | #endif /* CONFIG_X86_64 */ |
| 1424 | 1423 | ||
| 1425 | /* | 1424 | /* |
| @@ -1835,7 +1834,7 @@ void kvm_mmu_vendor_module_exit(void); · 409 unmodified lines | |||
| 1835 | 1834 | ||
| 1836 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu); | 1835 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu); |
| 1837 | int kvm_mmu_create(struct kvm_vcpu *vcpu); | 1836 | int kvm_mmu_create(struct kvm_vcpu *vcpu); |
| 1838 | int kvm_mmu_init_vm(struct kvm *kvm); | 1837 | void kvm_mmu_init_vm(struct kvm *kvm); |
| 1839 | void kvm_mmu_uninit_vm(struct kvm *kvm); | 1838 | void kvm_mmu_uninit_vm(struct kvm *kvm); |
| 1840 | 1839 | ||
| 1841 | void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); | 1840 | void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); |
| @@ -105,6 +105,13 @@ · 104 unmodified lines | |||
| 105 | CFI_POST_PADDING \ | 105 | CFI_POST_PADDING \ |
| 106 | SYM_FUNC_END(__cfi_##name) | 106 | SYM_FUNC_END(__cfi_##name) |
| 107 | 107 | ||
| 108 | /* UML needs to be able to override memcpy() and friends for KASAN. */ | ||
| 109 | #ifdef CONFIG_UML | ||
| 110 | # define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS_WEAK | ||
| 111 | #else | ||
| 112 | # define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS | ||
| 113 | #endif | ||
| 114 | |||
| 108 | /* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */ | 115 | /* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */ |
| 109 | #define SYM_TYPED_FUNC_START(name) \ | 116 | #define SYM_TYPED_FUNC_START(name) \ |
| 110 | SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN) \ | 117 | SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN) \ |
| @@ -186,8 +186,7 @@ do { \ · 185 unmodified lines | |||
| 186 | #else | 186 | #else |
| 187 | #define deactivate_mm(tsk, mm) \ | 187 | #define deactivate_mm(tsk, mm) \ |
| 188 | do { \ | 188 | do { \ |
| 189 | if (!tsk->vfork_done) \ | 189 | shstk_free(tsk); \ |
| 190 | shstk_free(tsk); \ | ||
| 191 | load_gs_index(0); \ | 190 | load_gs_index(0); \ |
| 192 | loadsegment(fs, 0); \ | 191 | loadsegment(fs, 0); \ |
| 193 | } while (0) | 192 | } while (0) |
| @@ -955,6 +955,14 @@ static inline int pte_same(pte_t a, pte_t b) · 954 unmodified lines | |||
| 955 | return a.pte == b.pte; | 955 | return a.pte == b.pte; |
| 956 | } | 956 | } |
| 957 | 957 | ||
| 958 | static inline pte_t pte_next_pfn(pte_t pte) | ||
| 959 | { | ||
| 960 | if (__pte_needs_invert(pte_val(pte))) | ||
| 961 | return __pte(pte_val(pte) - (1UL << PFN_PTE_SHIFT)); | ||
| 962 | return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT)); | ||
| 963 | } | ||
| 964 | #define pte_next_pfn pte_next_pfn | ||
| 965 | |||
| 958 | static inline int pte_present(pte_t a) | 966 | static inline int pte_present(pte_t a) |
| 959 | { | 967 | { |
| 960 | return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE); | 968 | return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE); |
| @@ -683,13 +683,11 @@ extern u16 get_llc_id(unsigned int cpu); · 682 unmodified lines | |||
| 683 | #ifdef CONFIG_CPU_SUP_AMD | 683 | #ifdef CONFIG_CPU_SUP_AMD |
| 684 | extern u32 amd_get_nodes_per_socket(void); | 684 | extern u32 amd_get_nodes_per_socket(void); |
| 685 | extern u32 amd_get_highest_perf(void); | 685 | extern u32 amd_get_highest_perf(void); |
| 686 | extern bool cpu_has_ibpb_brtype_microcode(void); | ||
| 687 | extern void amd_clear_divider(void); | 686 | extern void amd_clear_divider(void); |
| 688 | extern void amd_check_microcode(void); | 687 | extern void amd_check_microcode(void); |
| 689 | #else | 688 | #else |
| 690 | static inline u32 amd_get_nodes_per_socket(void) { return 0; } | 689 | static inline u32 amd_get_nodes_per_socket(void) { return 0; } |
| 691 | static inline u32 amd_get_highest_perf(void) { return 0; } | 690 | static inline u32 amd_get_highest_perf(void) { return 0; } |
| 692 | static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } | ||
| 693 | static inline void amd_clear_divider(void) { } | 691 | static inline void amd_clear_divider(void) { } |
| 694 | static inline void amd_check_microcode(void) { } | 692 | static inline void amd_check_microcode(void) { } |
| 695 | #endif | 693 | #endif |
| @@ -720,13 +720,8 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end) · 719 unmodified lines | |||
| 720 | { | 720 | { |
| 721 | s32 *s; | 721 | s32 *s; |
| 722 | 722 | ||
| 723 | /* | 723 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) |
| 724 | * Do not patch out the default return thunks if those needed are the | 724 | static_call_force_reinit(); |
| 725 | * ones generated by the compiler. | ||
| 726 | */ | ||
| 727 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK) && | ||
| 728 | (x86_return_thunk == __x86_return_thunk)) | ||
| 729 | return; | ||
| 730 | 725 | ||
| 731 | for (s = start; s < end; s++) { | 726 | for (s = start; s < end; s++) { |
| 732 | void *dest = NULL, *addr = (void *)s + *s; | 727 | void *dest = NULL, *addr = (void *)s + *s; |
| @@ -272,7 +272,6 @@ void __init callthunks_patch_builtin_calls(void) · 271 unmodified lines | |||
| 272 | pr_info("Setting up call depth tracking\n"); | 272 | pr_info("Setting up call depth tracking\n"); |
| 273 | mutex_lock(&text_mutex); | 273 | mutex_lock(&text_mutex); |
| 274 | callthunks_setup(&cs, &builtin_coretext); | 274 | callthunks_setup(&cs, &builtin_coretext); |
| 275 | static_call_force_reinit(); | ||
| 276 | thunks_initialized = true; | 275 | thunks_initialized = true; |
| 277 | mutex_unlock(&text_mutex); | 276 | mutex_unlock(&text_mutex); |
| 278 | } | 277 | } |
| @@ -766,6 +766,15 @@ static void early_init_amd(struct cpuinfo_x86 *c) · 765 unmodified lines | |||
| 766 | 766 | ||
| 767 | if (cpu_has(c, X86_FEATURE_TOPOEXT)) | 767 | if (cpu_has(c, X86_FEATURE_TOPOEXT)) |
| 768 | smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; | 768 | smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; |
| 769 | |||
| 770 | if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) { | ||
| 771 | if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB)) | ||
| 772 | setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); | ||
| 773 | else if (c->x86 >= 0x19 && !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { | ||
| 774 | setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); | ||
| 775 | setup_force_cpu_cap(X86_FEATURE_SBPB); | ||
| 776 | } | ||
| 777 | } | ||
| 769 | } | 778 | } |
| 770 | 779 | ||
| 771 | static void init_amd_k8(struct cpuinfo_x86 *c) | 780 | static void init_amd_k8(struct cpuinfo_x86 *c) |
| @@ -1301,25 +1310,6 @@ void amd_check_microcode(void) · 529 unmodified lines | |||
| 1301 | on_each_cpu(zenbleed_check_cpu, NULL, 1); | 1310 | on_each_cpu(zenbleed_check_cpu, NULL, 1); |
| 1302 | } | 1311 | } |
| 1303 | 1312 | ||
| 1304 | bool cpu_has_ibpb_brtype_microcode(void) | ||
| 1305 | { | ||
| 1306 | switch (boot_cpu_data.x86) { | ||
| 1307 | /* Zen1/2 IBPB flushes branch type predictions too. */ | ||
| 1308 | case 0x17: | ||
| 1309 | return boot_cpu_has(X86_FEATURE_AMD_IBPB); | ||
| 1310 | case 0x19: | ||
| 1311 | /* Poke the MSR bit on Zen3/4 to check its presence. */ | ||
| 1312 | if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { | ||
| 1313 | setup_force_cpu_cap(X86_FEATURE_SBPB); | ||
| 1314 | return true; | ||
| 1315 | } else { | ||
| 1316 | return false; | ||
| 1317 | } | ||
| 1318 | default: | ||
| 1319 | return false; | ||
| 1320 | } | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | /* | 1313 | /* |
| 1324 | * Issue a DIV 0/1 insn to clear any division data from previous DIV | 1314 | * Issue a DIV 0/1 insn to clear any division data from previous DIV |
| 1325 | * operations. | 1315 | * operations. |
| @@ -2404,26 +2404,15 @@ early_param("spec_rstack_overflow", srso_parse_cmdline); · 2403 unmodified lines | |||
| 2404 | 2404 | ||
| 2405 | static void __init srso_select_mitigation(void) | 2405 | static void __init srso_select_mitigation(void) |
| 2406 | { | 2406 | { |
| 2407 | bool has_microcode; | 2407 | bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE); |
| 2408 | 2408 | ||
| 2409 | if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) | 2409 | if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) |
| 2410 | goto pred_cmd; | 2410 | goto pred_cmd; |
| 2411 | 2411 | ||
| 2412 | /* | ||
| 2413 | * The first check is for the kernel running as a guest in order | ||
| 2414 | * for guests to verify whether IBPB is a viable mitigation. | ||
| 2415 | */ | ||
| 2416 | has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode(); | ||
| 2417 | if (!has_microcode) { | 2412 | if (!has_microcode) { |
| 2418 | pr_warn("IBPB-extending microcode not applied!\n"); | 2413 | pr_warn("IBPB-extending microcode not applied!\n"); |
| 2419 | pr_warn(SRSO_NOTICE); | 2414 | pr_warn(SRSO_NOTICE); |
| 2420 | } else { | 2415 | } else { |
| 2421 | /* | ||
| 2422 | * Enable the synthetic (even if in a real CPUID leaf) | ||
| 2423 | * flags for guests. | ||
| 2424 | */ | ||
| 2425 | setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); | ||
| 2426 | |||
| 2427 | /* | 2416 | /* |
| 2428 | * Zen1/2 with SMT off aren't vulnerable after the right | 2417 | * Zen1/2 with SMT off aren't vulnerable after the right |
| 2429 | * IBPB microcode has been applied. | 2418 | * IBPB microcode has been applied. |
| @@ -2444,7 +2433,7 @@ static void __init srso_select_mitigation(void) · 14 unmodified lines | |||
| 2444 | 2433 | ||
| 2445 | switch (srso_cmd) { | 2434 | switch (srso_cmd) { |
| 2446 | case SRSO_CMD_OFF: | 2435 | case SRSO_CMD_OFF: |
| 2447 | return; | 2436 | goto pred_cmd; |
| 2448 | 2437 | ||
| 2449 | case SRSO_CMD_MICROCODE: | 2438 | case SRSO_CMD_MICROCODE: |
| 2450 | if (has_microcode) { | 2439 | if (has_microcode) { |
| @@ -2717,7 +2706,7 @@ static ssize_t srso_show_state(char *buf) · 266 unmodified lines | |||
| 2717 | 2706 | ||
| 2718 | return sysfs_emit(buf, "%s%s\n", | 2707 | return sysfs_emit(buf, "%s%s\n", |
| 2719 | srso_strings[srso_mitigation], | 2708 | srso_strings[srso_mitigation], |
| 2720 | (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); | 2709 | boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode"); |
| 2721 | } | 2710 | } |
| 2722 | 2711 | ||
| 2723 | static ssize_t gds_show_state(char *buf) | 2712 | static ssize_t gds_show_state(char *buf) |
| @@ -1303,7 +1303,7 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { · 1302 unmodified lines | |||
| 1303 | VULNBL_AMD(0x15, RETBLEED), | 1303 | VULNBL_AMD(0x15, RETBLEED), |
| 1304 | VULNBL_AMD(0x16, RETBLEED), | 1304 | VULNBL_AMD(0x16, RETBLEED), |
| 1305 | VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), | 1305 | VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), |
| 1306 | VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), | 1306 | VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO), |
| 1307 | VULNBL_AMD(0x19, SRSO), | 1307 | VULNBL_AMD(0x19, SRSO), |
| 1308 | {} | 1308 | {} |
| 1309 | }; | 1309 | }; |
| @@ -235,6 +235,21 @@ static struct sgx_epc_page *sgx_encl_eldu(struct sgx_encl_page *encl_page, · 234 unmodified lines | |||
| 235 | return epc_page; | 235 | return epc_page; |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | /* | ||
| 239 | * Ensure the SECS page is not swapped out. Must be called with encl->lock | ||
| 240 | * to protect the enclave states including SECS and ensure the SECS page is | ||
| 241 | * not swapped out again while being used. | ||
| 242 | */ | ||
| 243 | static struct sgx_epc_page *sgx_encl_load_secs(struct sgx_encl *encl) | ||
| 244 | { | ||
| 245 | struct sgx_epc_page *epc_page = encl->secs.epc_page; | ||
| 246 | |||
| 247 | if (!epc_page) | ||
| 248 | epc_page = sgx_encl_eldu(&encl->secs, NULL); | ||
| 249 | |||
| 250 | return epc_page; | ||
| 251 | } | ||
| 252 | |||
| 238 | static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, | 253 | static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, |
| 239 | struct sgx_encl_page *entry) | 254 | struct sgx_encl_page *entry) |
| 240 | { | 255 | { |
| @@ -248,11 +263,9 @@ static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, · 7 unmodified lines | |||
| 248 | return entry; | 263 | return entry; |
| 249 | } | 264 | } |
| 250 | 265 | ||
| 251 | if (!(encl->secs.epc_page)) { | 266 | epc_page = sgx_encl_load_secs(encl); |
| 252 | epc_page = sgx_encl_eldu(&encl->secs, NULL); | 267 | if (IS_ERR(epc_page)) |
| 253 | if (IS_ERR(epc_page)) | 268 | return ERR_CAST(epc_page); |
| 254 | return ERR_CAST(epc_page); | ||
| 255 | } | ||
| 256 | 269 | ||
| 257 | epc_page = sgx_encl_eldu(entry, encl->secs.epc_page); | 270 | epc_page = sgx_encl_eldu(entry, encl->secs.epc_page); |
| 258 | if (IS_ERR(epc_page)) | 271 | if (IS_ERR(epc_page)) |
| @@ -339,6 +352,13 @@ static vm_fault_t sgx_encl_eaug_page(struct vm_area_struct *vma, · 80 unmodified lines | |||
| 339 | 352 | ||
| 340 | mutex_lock(&encl->lock); | 353 | mutex_lock(&encl->lock); |
| 341 | 354 | ||
| 355 | epc_page = sgx_encl_load_secs(encl); | ||
| 356 | if (IS_ERR(epc_page)) { | ||
| 357 | if (PTR_ERR(epc_page) == -EBUSY) | ||
| 358 | vmret = VM_FAULT_NOPAGE; | ||
| 359 | goto err_out_unlock; | ||
| 360 | } | ||
| 361 | |||
| 342 | epc_page = sgx_alloc_epc_page(encl_page, false); | 362 | epc_page = sgx_alloc_epc_page(encl_page, false); |
| 343 | if (IS_ERR(epc_page)) { | 363 | if (IS_ERR(epc_page)) { |
| 344 | if (PTR_ERR(epc_page) == -EBUSY) | 364 | if (PTR_ERR(epc_page) == -EBUSY) |
| @@ -695,7 +695,6 @@ void kgdb_arch_exit(void) · 694 unmodified lines | |||
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | /** | 697 | /** |
| 698 | * | ||
| 699 | * kgdb_skipexception - Bail out of KGDB when we've been triggered. | 698 | * kgdb_skipexception - Bail out of KGDB when we've been triggered. |
| 700 | * @exception: Exception vector number | 699 | * @exception: Exception vector number |
| 701 | * @regs: Current &struct pt_regs. | 700 | * @regs: Current &struct pt_regs. |
| @@ -257,13 +257,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 256 unmodified lines | |||
| 257 | if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP))) | 257 | if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP))) |
| 258 | io_bitmap_share(p); | 258 | io_bitmap_share(p); |
| 259 | 259 | ||
| 260 | /* | ||
| 261 | * If copy_thread() if failing, don't leak the shadow stack possibly | ||
| 262 | * allocated in shstk_alloc_thread_stack() above. | ||
| 263 | */ | ||
| 264 | if (ret) | ||
| 265 | shstk_free(p); | ||
| 266 | |||
| 267 | return ret; | 260 | return ret; |
| 268 | } | 261 | } |
| 269 | 262 | ||
| @@ -358,15 +358,11 @@ static void __init add_early_ima_buffer(u64 phys_addr) · 357 unmodified lines | |||
| 358 | #if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE) | 358 | #if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE) |
| 359 | int __init ima_free_kexec_buffer(void) | 359 | int __init ima_free_kexec_buffer(void) |
| 360 | { | 360 | { |
| 361 | int rc; | ||
| 362 | |||
| 363 | if (!ima_kexec_buffer_size) | 361 | if (!ima_kexec_buffer_size) |
| 364 | return -ENOENT; | 362 | return -ENOENT; |
| 365 | 363 | ||
| 366 | rc = memblock_phys_free(ima_kexec_buffer_phys, | 364 | memblock_free_late(ima_kexec_buffer_phys, |
| 367 | ima_kexec_buffer_size); | 365 | ima_kexec_buffer_size); |
| 368 | if (rc) | ||
| 369 | return rc; | ||
| 370 | 366 | ||
| 371 | ima_kexec_buffer_phys = 0; | 367 | ima_kexec_buffer_phys = 0; |
| 372 | ima_kexec_buffer_size = 0; | 368 | ima_kexec_buffer_size = 0; |
| @@ -205,10 +205,21 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long cl · 204 unmodified lines | |||
| 205 | return 0; | 205 | return 0; |
| 206 | 206 | ||
| 207 | /* | 207 | /* |
| 208 | * For CLONE_VM, except vfork, the child needs a separate shadow | 208 | * For CLONE_VFORK the child will share the parents shadow stack. |
| 209 | * Make sure to clear the internal tracking of the thread shadow | ||
| 210 | * stack so the freeing logic run for child knows to leave it alone. | ||
| 211 | */ | ||
| 212 | if (clone_flags & CLONE_VFORK) { | ||
| 213 | shstk->base = 0; | ||
| 214 | shstk->size = 0; | ||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | /* | ||
| 219 | * For !CLONE_VM the child will use a copy of the parents shadow | ||
| 209 | * stack. | 220 | * stack. |
| 210 | */ | 221 | */ |
| 211 | if ((clone_flags & (CLONE_VFORK | CLONE_VM)) != CLONE_VM) | 222 | if (!(clone_flags & CLONE_VM)) |
| 212 | return 0; | 223 | return 0; |
| 213 | 224 | ||
| 214 | size = adjust_shstk_size(stack_size); | 225 | size = adjust_shstk_size(stack_size); |
| @@ -408,7 +419,25 @@ void shstk_free(struct task_struct *tsk) · 193 unmodified lines | |||
| 408 | if (!tsk->mm || tsk->mm != current->mm) | 419 | if (!tsk->mm || tsk->mm != current->mm) |
| 409 | return; | 420 | return; |
| 410 | 421 | ||
| 422 | /* | ||
| 423 | * If shstk->base is NULL, then this task is not managing its | ||
| 424 | * own shadow stack (CLONE_VFORK). So skip freeing it. | ||
| 425 | */ | ||
| 426 | if (!shstk->base) | ||
| 427 | return; | ||
| 428 | |||
| 429 | /* | ||
| 430 | * shstk->base is NULL for CLONE_VFORK child tasks, and so is | ||
| 431 | * normal. But size = 0 on a shstk->base is not normal and | ||
| 432 | * indicated an attempt to free the thread shadow stack twice. | ||
| 433 | * Warn about it. | ||
| 434 | */ | ||
| 435 | if (WARN_ON(!shstk->size)) | ||
| 436 | return; | ||
| 437 | |||
| 411 | unmap_shadow_stack(shstk->base, shstk->size); | 438 | unmap_shadow_stack(shstk->base, shstk->size); |
| 439 | |||
| 440 | shstk->size = 0; | ||
| 412 | } | 441 | } |
| 413 | 442 | ||
| 414 | static int wrss_control(bool enable) | 443 | static int wrss_control(bool enable) |
| @@ -6167,20 +6167,15 @@ static bool kvm_has_zapped_obsolete_pages(struct kvm *kvm) · 6166 unmodified lines | |||
| 6167 | return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages)); | 6167 | return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages)); |
| 6168 | } | 6168 | } |
| 6169 | 6169 | ||
| 6170 | int kvm_mmu_init_vm(struct kvm *kvm) | 6170 | void kvm_mmu_init_vm(struct kvm *kvm) |
| 6171 | { | 6171 | { |
| 6172 | int r; | ||
| 6173 | |||
| 6174 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); | 6172 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); |
| 6175 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); | 6173 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); |
| 6176 | INIT_LIST_HEAD(&kvm->arch.possible_nx_huge_pages); | 6174 | INIT_LIST_HEAD(&kvm->arch.possible_nx_huge_pages); |
| 6177 | spin_lock_init(&kvm->arch.mmu_unsync_pages_lock); | 6175 | spin_lock_init(&kvm->arch.mmu_unsync_pages_lock); |
| 6178 | 6176 | ||
| 6179 | if (tdp_mmu_enabled) { | 6177 | if (tdp_mmu_enabled) |
| 6180 | r = kvm_mmu_init_tdp_mmu(kvm); | 6178 | kvm_mmu_init_tdp_mmu(kvm); |
| 6181 | if (r < 0) | ||
| 6182 | return r; | ||
| 6183 | } | ||
| 6184 | 6179 | ||
| 6185 | kvm->arch.split_page_header_cache.kmem_cache = mmu_page_header_cache; | 6180 | kvm->arch.split_page_header_cache.kmem_cache = mmu_page_header_cache; |
| 6186 | kvm->arch.split_page_header_cache.gfp_zero = __GFP_ZERO; | 6181 | kvm->arch.split_page_header_cache.gfp_zero = __GFP_ZERO; |
| @@ -6189,8 +6184,6 @@ int kvm_mmu_init_vm(struct kvm *kvm) · 2 unmodified lines | |||
| 6189 | 6184 | ||
| 6190 | kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache; | 6185 | kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache; |
| 6191 | kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO; | 6186 | kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO; |
| 6192 | |||
| 6193 | return 0; | ||
| 6194 | } | 6187 | } |
| 6195 | 6188 | ||
| 6196 | static void mmu_free_vm_memory_caches(struct kvm *kvm) | 6189 | static void mmu_free_vm_memory_caches(struct kvm *kvm) |
| @@ -6246,7 +6239,6 @@ static bool kvm_rmap_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_e · 49 unmodified lines | |||
| 6246 | void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) | 6239 | void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) |
| 6247 | { | 6240 | { |
| 6248 | bool flush; | 6241 | bool flush; |
| 6249 | int i; | ||
| 6250 | 6242 | ||
| 6251 | if (WARN_ON_ONCE(gfn_end <= gfn_start)) | 6243 | if (WARN_ON_ONCE(gfn_end <= gfn_start)) |
| 6252 | return; | 6244 | return; |
| @@ -6257,11 +6249,8 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) · 4 unmodified lines | |||
| 6257 | 6249 | ||
| 6258 | flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); | 6250 | flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); |
| 6259 | 6251 | ||
| 6260 | if (tdp_mmu_enabled) { | 6252 | if (tdp_mmu_enabled) |
| 6261 | for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) | 6253 | flush = kvm_tdp_mmu_zap_leafs(kvm, gfn_start, gfn_end, flush); |
| 6262 | flush = kvm_tdp_mmu_zap_leafs(kvm, i, gfn_start, | ||
| 6263 | gfn_end, true, flush); | ||
| 6264 | } | ||
| 6265 | 6254 | ||
| 6266 | if (flush) | 6255 | if (flush) |
| 6267 | kvm_flush_remote_tlbs_range(kvm, gfn_start, gfn_end - gfn_start); | 6256 | kvm_flush_remote_tlbs_range(kvm, gfn_start, gfn_end - gfn_start); |
| @@ -58,7 +58,12 @@ struct kvm_mmu_page { · 57 unmodified lines | |||
| 58 | 58 | ||
| 59 | bool tdp_mmu_page; | 59 | bool tdp_mmu_page; |
| 60 | bool unsync; | 60 | bool unsync; |
| 61 | u8 mmu_valid_gen; | 61 | union { |
| 62 | u8 mmu_valid_gen; | ||
| 63 | |||
| 64 | /* Only accessed under slots_lock. */ | ||
| 65 | bool tdp_mmu_scheduled_root_to_zap; | ||
| 66 | }; | ||
| 62 | 67 | ||
| 63 | /* | 68 | /* |
| 64 | * The shadow page can't be replaced by an equivalent huge page | 69 | * The shadow page can't be replaced by an equivalent huge page |
| @@ -100,13 +105,7 @@ struct kvm_mmu_page { · 35 unmodified lines | |||
| 100 | struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */ | 105 | struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */ |
| 101 | tdp_ptep_t ptep; | 106 | tdp_ptep_t ptep; |
| 102 | }; | 107 | }; |
| 103 | union { | 108 | DECLARE_BITMAP(unsync_child_bitmap, 512); |
| 104 | DECLARE_BITMAP(unsync_child_bitmap, 512); | ||
| 105 | struct { | ||
| 106 | struct work_struct tdp_mmu_async_work; | ||
| 107 | void *tdp_mmu_async_data; | ||
| 108 | }; | ||
| 109 | }; | ||
| 110 | 109 | ||
| 111 | /* | 110 | /* |
| 112 | * Tracks shadow pages that, if zapped, would allow KVM to create an NX | 111 | * Tracks shadow pages that, if zapped, would allow KVM to create an NX |
| @@ -12,18 +12,10 @@ · 11 unmodified lines | |||
| 12 | #include <trace/events/kvm.h> | 12 | #include <trace/events/kvm.h> |
| 13 | 13 | ||
| 14 | /* Initializes the TDP MMU for the VM, if enabled. */ | 14 | /* Initializes the TDP MMU for the VM, if enabled. */ |
| 15 | int kvm_mmu_init_tdp_mmu(struct kvm *kvm) | 15 | void kvm_mmu_init_tdp_mmu(struct kvm *kvm) |
| 16 | { | 16 | { |
| 17 | struct workqueue_struct *wq; | ||
| 18 | |||
| 19 | wq = alloc_workqueue("kvm", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_CPU_INTENSIVE, 0); | ||
| 20 | if (!wq) | ||
| 21 | return -ENOMEM; | ||
| 22 | |||
| 23 | INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); | 17 | INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); |
| 24 | spin_lock_init(&kvm->arch.tdp_mmu_pages_lock); | 18 | spin_lock_init(&kvm->arch.tdp_mmu_pages_lock); |
| 25 | kvm->arch.tdp_mmu_zap_wq = wq; | ||
| 26 | return 1; | ||
| 27 | } | 19 | } |
| 28 | 20 | ||
| 29 | /* Arbitrarily returns true so that this may be used in if statements. */ | 21 | /* Arbitrarily returns true so that this may be used in if statements. */ |
| @@ -46,20 +38,15 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) · 16 unmodified lines | |||
| 46 | * ultimately frees all roots. | 38 | * ultimately frees all roots. |
| 47 | */ | 39 | */ |
| 48 | kvm_tdp_mmu_invalidate_all_roots(kvm); | 40 | kvm_tdp_mmu_invalidate_all_roots(kvm); |
| 49 | 41 | kvm_tdp_mmu_zap_invalidated_roots(kvm); | |
| 50 | /* | ||
| 51 | * Destroying a workqueue also first flushes the workqueue, i.e. no | ||
| 52 | * need to invoke kvm_tdp_mmu_zap_invalidated_roots(). | ||
| 53 | */ | ||
| 54 | destroy_workqueue(kvm->arch.tdp_mmu_zap_wq); | ||
| 55 | 42 | ||
| 56 | WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages)); | 43 | WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages)); |
| 57 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); | 44 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); |
| 58 | 45 | ||
| 59 | /* | 46 | /* |
| 60 | * Ensure that all the outstanding RCU callbacks to free shadow pages | 47 | * Ensure that all the outstanding RCU callbacks to free shadow pages |
| 61 | * can run before the VM is torn down. Work items on tdp_mmu_zap_wq | 48 | * can run before the VM is torn down. Putting the last reference to |
| 62 | * can call kvm_tdp_mmu_put_root and create new callbacks. | 49 | * zapped roots will create new callbacks. |
| 63 | */ | 50 | */ |
| 64 | rcu_barrier(); | 51 | rcu_barrier(); |
| 65 | } | 52 | } |
| @@ -86,46 +73,6 @@ static void tdp_mmu_free_sp_rcu_callback(struct rcu_head *head) · 20 unmodified lines | |||
| 86 | tdp_mmu_free_sp(sp); | 73 | tdp_mmu_free_sp(sp); |
| 87 | } | 74 | } |
| 88 | 75 | ||
| 89 | static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root, | ||
| 90 | bool shared); | ||
| 91 | |||
| 92 | static void tdp_mmu_zap_root_work(struct work_struct *work) | ||
| 93 | { | ||
| 94 | struct kvm_mmu_page *root = container_of(work, struct kvm_mmu_page, | ||
| 95 | tdp_mmu_async_work); | ||
| 96 | struct kvm *kvm = root->tdp_mmu_async_data; | ||
| 97 | |||
| 98 | read_lock(&kvm->mmu_lock); | ||
| 99 | |||
| 100 | /* | ||
| 101 | * A TLB flush is not necessary as KVM performs a local TLB flush when | ||
| 102 | * allocating a new root (see kvm_mmu_load()), and when migrating vCPU | ||
| 103 | * to a different pCPU. Note, the local TLB flush on reuse also | ||
| 104 | * invalidates any paging-structure-cache entries, i.e. TLB entries for | ||
| 105 | * intermediate paging structures, that may be zapped, as such entries | ||
| 106 | * are associated with the ASID on both VMX and SVM. | ||
| 107 | */ | ||
| 108 | tdp_mmu_zap_root(kvm, root, true); | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Drop the refcount using kvm_tdp_mmu_put_root() to test its logic for | ||
| 112 | * avoiding an infinite loop. By design, the root is reachable while | ||
| 113 | * it's being asynchronously zapped, thus a different task can put its | ||
| 114 | * last reference, i.e. flowing through kvm_tdp_mmu_put_root() for an | ||
| 115 | * asynchronously zapped root is unavoidable. | ||
| 116 | */ | ||
| 117 | kvm_tdp_mmu_put_root(kvm, root, true); | ||
| 118 | |||
| 119 | read_unlock(&kvm->mmu_lock); | ||
| 120 | } | ||
| 121 | |||
| 122 | static void tdp_mmu_schedule_zap_root(struct kvm *kvm, struct kvm_mmu_page *root) | ||
| 123 | { | ||
| 124 | root->tdp_mmu_async_data = kvm; | ||
| 125 | INIT_WORK(&root->tdp_mmu_async_work, tdp_mmu_zap_root_work); | ||
| 126 | queue_work(kvm->arch.tdp_mmu_zap_wq, &root->tdp_mmu_async_work); | ||
| 127 | } | ||
| 128 | |||
| 129 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, | 76 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, |
| 130 | bool shared) | 77 | bool shared) |
| 131 | { | 78 | { |
| @@ -211,8 +158,12 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, · 79 unmodified lines | |||
| 211 | #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ | 158 | #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ |
| 212 | __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) | 159 | __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) |
| 213 | 160 | ||
| 214 | #define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id) \ | 161 | #define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _shared) \ |
| 215 | __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, false, false) | 162 | for (_root = tdp_mmu_next_root(_kvm, NULL, _shared, false); \ |
| 163 | _root; \ | ||
| 164 | _root = tdp_mmu_next_root(_kvm, _root, _shared, false)) \ | ||
| 165 | if (!kvm_lockdep_assert_mmu_lock_held(_kvm, _shared)) { \ | ||
| 166 | } else | ||
| 216 | 167 | ||
| 217 | /* | 168 | /* |
| 218 | * Iterate over all TDP MMU roots. Requires that mmu_lock be held for write, | 169 | * Iterate over all TDP MMU roots. Requires that mmu_lock be held for write, |
| @@ -292,7 +243,7 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu) · 73 unmodified lines | |||
| 292 | * by a memslot update or by the destruction of the VM. Initialize the | 243 | * by a memslot update or by the destruction of the VM. Initialize the |
| 293 | * refcount to two; one reference for the vCPU, and one reference for | 244 | * refcount to two; one reference for the vCPU, and one reference for |
| 294 | * the TDP MMU itself, which is held until the root is invalidated and | 245 | * the TDP MMU itself, which is held until the root is invalidated and |
| 295 | * is ultimately put by tdp_mmu_zap_root_work(). | 246 | * is ultimately put by kvm_tdp_mmu_zap_invalidated_roots(). |
| 296 | */ | 247 | */ |
| 297 | refcount_set(&root->tdp_mmu_root_count, 2); | 248 | refcount_set(&root->tdp_mmu_root_count, 2); |
| 298 | 249 | ||
| @@ -877,13 +828,12 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root, · 578 unmodified lines | |||
| 877 | * true if a TLB flush is needed before releasing the MMU lock, i.e. if one or | 828 | * true if a TLB flush is needed before releasing the MMU lock, i.e. if one or |
| 878 | * more SPTEs were zapped since the MMU lock was last acquired. | 829 | * more SPTEs were zapped since the MMU lock was last acquired. |
| 879 | */ | 830 | */ |
| 880 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end, | 831 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush) |
| 881 | bool can_yield, bool flush) | ||
| 882 | { | 832 | { |
| 883 | struct kvm_mmu_page *root; | 833 | struct kvm_mmu_page *root; |
| 884 | 834 | ||
| 885 | for_each_tdp_mmu_root_yield_safe(kvm, root, as_id) | 835 | for_each_tdp_mmu_root_yield_safe(kvm, root, false) |
| 886 | flush = tdp_mmu_zap_leafs(kvm, root, start, end, can_yield, flush); | 836 | flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush); |
| 887 | 837 | ||
| 888 | return flush; | 838 | return flush; |
| 889 | } | 839 | } |
| @@ -891,7 +841,6 @@ bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end, · 1 unmodified line | |||
| 891 | void kvm_tdp_mmu_zap_all(struct kvm *kvm) | 841 | void kvm_tdp_mmu_zap_all(struct kvm *kvm) |
| 892 | { | 842 | { |
| 893 | struct kvm_mmu_page *root; | 843 | struct kvm_mmu_page *root; |
| 894 | int i; | ||
| 895 | 844 | ||
| 896 | /* | 845 | /* |
| 897 | * Zap all roots, including invalid roots, as all SPTEs must be dropped | 846 | * Zap all roots, including invalid roots, as all SPTEs must be dropped |
| @@ -905,10 +854,8 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) · 7 unmodified lines | |||
| 905 | * is being destroyed or the userspace VMM has exited. In both cases, | 854 | * is being destroyed or the userspace VMM has exited. In both cases, |
| 906 | * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. | 855 | * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. |
| 907 | */ | 856 | */ |
| 908 | for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { | 857 | for_each_tdp_mmu_root_yield_safe(kvm, root, false) |
| 909 | for_each_tdp_mmu_root_yield_safe(kvm, root, i) | 858 | tdp_mmu_zap_root(kvm, root, false); |
| 910 | tdp_mmu_zap_root(kvm, root, false); | ||
| 911 | } | ||
| 912 | } | 859 | } |
| 913 | 860 | ||
| 914 | /* | 861 | /* |
| @@ -917,18 +864,47 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) · 2 unmodified lines | |||
| 917 | */ | 864 | */ |
| 918 | void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm) | 865 | void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm) |
| 919 | { | 866 | { |
| 920 | flush_workqueue(kvm->arch.tdp_mmu_zap_wq); | 867 | struct kvm_mmu_page *root; |
| 868 | |||
| 869 | read_lock(&kvm->mmu_lock); | ||
| 870 | |||
| 871 | for_each_tdp_mmu_root_yield_safe(kvm, root, true) { | ||
| 872 | if (!root->tdp_mmu_scheduled_root_to_zap) | ||
| 873 | continue; | ||
| 874 | |||
| 875 | root->tdp_mmu_scheduled_root_to_zap = false; | ||
| 876 | KVM_BUG_ON(!root->role.invalid, kvm); | ||
| 877 | |||
| 878 | /* | ||
| 879 | * A TLB flush is not necessary as KVM performs a local TLB | ||
| 880 | * flush when allocating a new root (see kvm_mmu_load()), and | ||
| 881 | * when migrating a vCPU to a different pCPU. Note, the local | ||
| 882 | * TLB flush on reuse also invalidates paging-structure-cache | ||
| 883 | * entries, i.e. TLB entries for intermediate paging structures, | ||
| 884 | * that may be zapped, as such entries are associated with the | ||
| 885 | * ASID on both VMX and SVM. | ||
| 886 | */ | ||
| 887 | tdp_mmu_zap_root(kvm, root, true); | ||
| 888 | |||
| 889 | /* | ||
| 890 | * The referenced needs to be put *after* zapping the root, as | ||
| 891 | * the root must be reachable by mmu_notifiers while it's being | ||
| 892 | * zapped | ||
| 893 | */ | ||
| 894 | kvm_tdp_mmu_put_root(kvm, root, true); | ||
| 895 | } | ||
| 896 | |||
| 897 | read_unlock(&kvm->mmu_lock); | ||
| 921 | } | 898 | } |
| 922 | 899 | ||
| 923 | /* | 900 | /* |
| 924 | * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that | 901 | * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that |
| 925 | * is about to be zapped, e.g. in response to a memslots update. The actual | 902 | * is about to be zapped, e.g. in response to a memslots update. The actual |
| 926 | * zapping is performed asynchronously. Using a separate workqueue makes it | 903 | * zapping is done separately so that it happens with mmu_lock with read, |
| 927 | * easy to ensure that the destruction is performed before the "fast zap" | 904 | * whereas invalidating roots must be done with mmu_lock held for write (unless |
| 928 | * completes, without keeping a separate list of invalidated roots; the list is | 905 | * the VM is being destroyed). |
| 929 | * effectively the list of work items in the workqueue. | ||
| 930 | * | 906 | * |
| 931 | * Note, the asynchronous worker is gifted the TDP MMU's reference. | 907 | * Note, kvm_tdp_mmu_zap_invalidated_roots() is gifted the TDP MMU's reference. |
| 932 | * See kvm_tdp_mmu_get_vcpu_root_hpa(). | 908 | * See kvm_tdp_mmu_get_vcpu_root_hpa(). |
| 933 | */ | 909 | */ |
| 934 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) | 910 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) |
| @@ -953,19 +929,20 @@ void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) · 18 unmodified lines | |||
| 953 | /* | 929 | /* |
| 954 | * As above, mmu_lock isn't held when destroying the VM! There can't | 930 | * As above, mmu_lock isn't held when destroying the VM! There can't |
| 955 | * be other references to @kvm, i.e. nothing else can invalidate roots | 931 | * be other references to @kvm, i.e. nothing else can invalidate roots |
| 956 | * or be consuming roots, but walking the list of roots does need to be | 932 | * or get/put references to roots. |
| 957 | * guarded against roots being deleted by the asynchronous zap worker. | ||
| 958 | */ | 933 | */ |
| 959 | rcu_read_lock(); | 934 | list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) { |
| 960 | 935 | /* | |
| 961 | list_for_each_entry_rcu(root, &kvm->arch.tdp_mmu_roots, link) { | 936 | * Note, invalid roots can outlive a memslot update! Invalid |
| 937 | * roots must be *zapped* before the memslot update completes, | ||
| 938 | * but a different task can acquire a reference and keep the | ||
| 939 | * root alive after its been zapped. | ||
| 940 | */ | ||
| 962 | if (!root->role.invalid) { | 941 | if (!root->role.invalid) { |
| 942 | root->tdp_mmu_scheduled_root_to_zap = true; | ||
| 963 | root->role.invalid = true; | 943 | root->role.invalid = true; |
| 964 | tdp_mmu_schedule_zap_root(kvm, root); | ||
| 965 | } | 944 | } |
| 966 | } | 945 | } |
| 967 | |||
| 968 | rcu_read_unlock(); | ||
| 969 | } | 946 | } |
| 970 | 947 | ||
| 971 | /* | 948 | /* |
| @@ -1146,8 +1123,13 @@ retry: · 174 unmodified lines | |||
| 1146 | bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, | 1123 | bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, |
| 1147 | bool flush) | 1124 | bool flush) |
| 1148 | { | 1125 | { |
| 1149 | return kvm_tdp_mmu_zap_leafs(kvm, range->slot->as_id, range->start, | 1126 | struct kvm_mmu_page *root; |
| 1150 | range->end, range->may_block, flush); | 1127 | |
| 1128 | __for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false, false) | ||
| 1129 | flush = tdp_mmu_zap_leafs(kvm, root, range->start, range->end, | ||
| 1130 | range->may_block, flush); | ||
| 1131 | |||
| 1132 | return flush; | ||
| 1151 | } | 1133 | } |
| 1152 | 1134 | ||
| 1153 | typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter, | 1135 | typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter, |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include "spte.h" | 8 | #include "spte.h" |
| 9 | 9 | ||
| 10 | int kvm_mmu_init_tdp_mmu(struct kvm *kvm); | 10 | void kvm_mmu_init_tdp_mmu(struct kvm *kvm); |
| 11 | void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm); | 11 | void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm); |
| 12 | 12 | ||
| 13 | hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu); | 13 | hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu); |
| @@ -20,8 +20,7 @@ __must_check static inline bool kvm_tdp_mmu_get_root(struct kvm_mmu_page *root) · 6 unmodified lines | |||
| 20 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, | 20 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, |
| 21 | bool shared); | 21 | bool shared); |
| 22 | 22 | ||
| 23 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, | 23 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush); |
| 24 | gfn_t end, bool can_yield, bool flush); | ||
| 25 | bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp); | 24 | bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp); |
| 26 | void kvm_tdp_mmu_zap_all(struct kvm *kvm); | 25 | void kvm_tdp_mmu_zap_all(struct kvm *kvm); |
| 27 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm); | 26 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm); |
| @@ -2962,6 +2962,32 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) · 2961 unmodified lines | |||
| 2962 | count, in); | 2962 | count, in); |
| 2963 | } | 2963 | } |
| 2964 | 2964 | ||
| 2965 | static void sev_es_vcpu_after_set_cpuid(struct vcpu_svm *svm) | ||
| 2966 | { | ||
| 2967 | struct kvm_vcpu *vcpu = &svm->vcpu; | ||
| 2968 | |||
| 2969 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) { | ||
| 2970 | bool v_tsc_aux = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP) || | ||
| 2971 | guest_cpuid_has(vcpu, X86_FEATURE_RDPID); | ||
| 2972 | |||
| 2973 | set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, v_tsc_aux, v_tsc_aux); | ||
| 2974 | } | ||
| 2975 | } | ||
| 2976 | |||
| 2977 | void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm) | ||
| 2978 | { | ||
| 2979 | struct kvm_vcpu *vcpu = &svm->vcpu; | ||
| 2980 | struct kvm_cpuid_entry2 *best; | ||
| 2981 | |||
| 2982 | /* For sev guests, the memory encryption bit is not reserved in CR3. */ | ||
| 2983 | best = kvm_find_cpuid_entry(vcpu, 0x8000001F); | ||
| 2984 | if (best) | ||
| 2985 | vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); | ||
| 2986 | |||
| 2987 | if (sev_es_guest(svm->vcpu.kvm)) | ||
| 2988 | sev_es_vcpu_after_set_cpuid(svm); | ||
| 2989 | } | ||
| 2990 | |||
| 2965 | static void sev_es_init_vmcb(struct vcpu_svm *svm) | 2991 | static void sev_es_init_vmcb(struct vcpu_svm *svm) |
| 2966 | { | 2992 | { |
| 2967 | struct vmcb *vmcb = svm->vmcb01.ptr; | 2993 | struct vmcb *vmcb = svm->vmcb01.ptr; |
| @@ -3024,14 +3050,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm) · 56 unmodified lines | |||
| 3024 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); | 3050 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); |
| 3025 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); | 3051 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); |
| 3026 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); | 3052 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); |
| 3027 | |||
| 3028 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && | ||
| 3029 | (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP) || | ||
| 3030 | guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDPID))) { | ||
| 3031 | set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, 1, 1); | ||
| 3032 | if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP)) | ||
| 3033 | svm_clr_intercept(svm, INTERCEPT_RDTSCP); | ||
| 3034 | } | ||
| 3035 | } | 3053 | } |
| 3036 | 3054 | ||
| 3037 | void sev_init_vmcb(struct vcpu_svm *svm) | 3055 | void sev_init_vmcb(struct vcpu_svm *svm) |
| @@ -683,6 +683,21 @@ static int svm_hardware_enable(void) · 682 unmodified lines | |||
| 683 | 683 | ||
| 684 | amd_pmu_enable_virt(); | 684 | amd_pmu_enable_virt(); |
| 685 | 685 | ||
| 686 | /* | ||
| 687 | * If TSC_AUX virtualization is supported, TSC_AUX becomes a swap type | ||
| 688 | * "B" field (see sev_es_prepare_switch_to_guest()) for SEV-ES guests. | ||
| 689 | * Since Linux does not change the value of TSC_AUX once set, prime the | ||
| 690 | * TSC_AUX field now to avoid a RDMSR on every vCPU run. | ||
| 691 | */ | ||
| 692 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) { | ||
| 693 | struct sev_es_save_area *hostsa; | ||
| 694 | u32 msr_hi; | ||
| 695 | |||
| 696 | hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400); | ||
| 697 | |||
| 698 | rdmsr(MSR_TSC_AUX, hostsa->tsc_aux, msr_hi); | ||
| 699 | } | ||
| 700 | |||
| 686 | return 0; | 701 | return 0; |
| 687 | } | 702 | } |
| 688 | 703 | ||
| @@ -1532,7 +1547,14 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) · 843 unmodified lines | |||
| 1532 | if (tsc_scaling) | 1547 | if (tsc_scaling) |
| 1533 | __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); | 1548 | __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); |
| 1534 | 1549 | ||
| 1535 | if (likely(tsc_aux_uret_slot >= 0)) | 1550 | /* |
| 1551 | * TSC_AUX is always virtualized for SEV-ES guests when the feature is | ||
| 1552 | * available. The user return MSR support is not required in this case | ||
| 1553 | * because TSC_AUX is restored on #VMEXIT from the host save area | ||
| 1554 | * (which has been initialized in svm_hardware_enable()). | ||
| 1555 | */ | ||
| 1556 | if (likely(tsc_aux_uret_slot >= 0) && | ||
| 1557 | (!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm))) | ||
| 1536 | kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); | 1558 | kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); |
| 1537 | 1559 | ||
| 1538 | svm->guest_state_loaded = true; | 1560 | svm->guest_state_loaded = true; |
| @@ -3086,6 +3108,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) · 1547 unmodified lines | |||
| 3086 | svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0; | 3108 | svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0; |
| 3087 | break; | 3109 | break; |
| 3088 | case MSR_TSC_AUX: | 3110 | case MSR_TSC_AUX: |
| 3111 | /* | ||
| 3112 | * TSC_AUX is always virtualized for SEV-ES guests when the | ||
| 3113 | * feature is available. The user return MSR support is not | ||
| 3114 | * required in this case because TSC_AUX is restored on #VMEXIT | ||
| 3115 | * from the host save area (which has been initialized in | ||
| 3116 | * svm_hardware_enable()). | ||
| 3117 | */ | ||
| 3118 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && sev_es_guest(vcpu->kvm)) | ||
| 3119 | break; | ||
| 3120 | |||
| 3089 | /* | 3121 | /* |
| 3090 | * TSC_AUX is usually changed only during boot and never read | 3122 | * TSC_AUX is usually changed only during boot and never read |
| 3091 | * directly. Intercept TSC_AUX instead of exposing it to the | 3123 | * directly. Intercept TSC_AUX instead of exposing it to the |
| @@ -4284,7 +4316,6 @@ static bool svm_has_emulated_msr(struct kvm *kvm, u32 index) · 1192 unmodified lines | |||
| 4284 | static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) | 4316 | static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) |
| 4285 | { | 4317 | { |
| 4286 | struct vcpu_svm *svm = to_svm(vcpu); | 4318 | struct vcpu_svm *svm = to_svm(vcpu); |
| 4287 | struct kvm_cpuid_entry2 *best; | ||
| 4288 | 4319 | ||
| 4289 | /* | 4320 | /* |
| 4290 | * SVM doesn't provide a way to disable just XSAVES in the guest, KVM | 4321 | * SVM doesn't provide a way to disable just XSAVES in the guest, KVM |
| @@ -4328,12 +4359,8 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) · 37 unmodified lines | |||
| 4328 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_FLUSH_CMD, 0, | 4359 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_FLUSH_CMD, 0, |
| 4329 | !!guest_cpuid_has(vcpu, X86_FEATURE_FLUSH_L1D)); | 4360 | !!guest_cpuid_has(vcpu, X86_FEATURE_FLUSH_L1D)); |
| 4330 | 4361 | ||
| 4331 | /* For sev guests, the memory encryption bit is not reserved in CR3. */ | 4362 | if (sev_guest(vcpu->kvm)) |
| 4332 | if (sev_guest(vcpu->kvm)) { | 4363 | sev_vcpu_after_set_cpuid(svm); |
| 4333 | best = kvm_find_cpuid_entry(vcpu, 0x8000001F); | ||
| 4334 | if (best) | ||
| 4335 | vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); | ||
| 4336 | } | ||
| 4337 | 4364 | ||
| 4338 | init_vmcb_after_set_cpuid(vcpu); | 4365 | init_vmcb_after_set_cpuid(vcpu); |
| 4339 | } | 4366 | } |
| @@ -684,6 +684,7 @@ void __init sev_hardware_setup(void); · 683 unmodified lines | |||
| 684 | void sev_hardware_unsetup(void); | 684 | void sev_hardware_unsetup(void); |
| 685 | int sev_cpu_init(struct svm_cpu_data *sd); | 685 | int sev_cpu_init(struct svm_cpu_data *sd); |
| 686 | void sev_init_vmcb(struct vcpu_svm *svm); | 686 | void sev_init_vmcb(struct vcpu_svm *svm); |
| 687 | void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm); | ||
| 687 | void sev_free_vcpu(struct kvm_vcpu *vcpu); | 688 | void sev_free_vcpu(struct kvm_vcpu *vcpu); |
| 688 | int sev_handle_vmgexit(struct kvm_vcpu *vcpu); | 689 | int sev_handle_vmgexit(struct kvm_vcpu *vcpu); |
| 689 | int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); | 690 | int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); |
| @@ -12308,9 +12308,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 12307 unmodified lines | |||
| 12308 | if (ret) | 12308 | if (ret) |
| 12309 | goto out; | 12309 | goto out; |
| 12310 | 12310 | ||
| 12311 | ret = kvm_mmu_init_vm(kvm); | 12311 | kvm_mmu_init_vm(kvm); |
| 12312 | if (ret) | ||
| 12313 | goto out_page_track; | ||
| 12314 | 12312 | ||
| 12315 | ret = static_call(kvm_x86_vm_init)(kvm); | 12313 | ret = static_call(kvm_x86_vm_init)(kvm); |
| 12316 | if (ret) | 12314 | if (ret) |
| @@ -12355,7 +12353,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 38 unmodified lines | |||
| 12355 | 12353 | ||
| 12356 | out_uninit_mmu: | 12354 | out_uninit_mmu: |
| 12357 | kvm_mmu_uninit_vm(kvm); | 12355 | kvm_mmu_uninit_vm(kvm); |
| 12358 | out_page_track: | ||
| 12359 | kvm_page_track_cleanup(kvm); | 12356 | kvm_page_track_cleanup(kvm); |
| 12360 | out: | 12357 | out: |
| 12361 | return ret; | 12358 | return ret; |
| @@ -40,7 +40,7 @@ SYM_TYPED_FUNC_START(__memcpy) · 39 unmodified lines | |||
| 40 | SYM_FUNC_END(__memcpy) | 40 | SYM_FUNC_END(__memcpy) |
| 41 | EXPORT_SYMBOL(__memcpy) | 41 | EXPORT_SYMBOL(__memcpy) |
| 42 | 42 | ||
| 43 | SYM_FUNC_ALIAS(memcpy, __memcpy) | 43 | SYM_FUNC_ALIAS_MEMFUNC(memcpy, __memcpy) |
| 44 | EXPORT_SYMBOL(memcpy) | 44 | EXPORT_SYMBOL(memcpy) |
| 45 | 45 | ||
| 46 | SYM_FUNC_START_LOCAL(memcpy_orig) | 46 | SYM_FUNC_START_LOCAL(memcpy_orig) |
| @@ -212,5 +212,5 @@ SYM_FUNC_START(__memmove) · 211 unmodified lines | |||
| 212 | SYM_FUNC_END(__memmove) | 212 | SYM_FUNC_END(__memmove) |
| 213 | EXPORT_SYMBOL(__memmove) | 213 | EXPORT_SYMBOL(__memmove) |
| 214 | 214 | ||
| 215 | SYM_FUNC_ALIAS(memmove, __memmove) | 215 | SYM_FUNC_ALIAS_MEMFUNC(memmove, __memmove) |
| 216 | EXPORT_SYMBOL(memmove) | 216 | EXPORT_SYMBOL(memmove) |
| @@ -40,7 +40,7 @@ SYM_FUNC_START(__memset) · 39 unmodified lines | |||
| 40 | SYM_FUNC_END(__memset) | 40 | SYM_FUNC_END(__memset) |
| 41 | EXPORT_SYMBOL(__memset) | 41 | EXPORT_SYMBOL(__memset) |
| 42 | 42 | ||
| 43 | SYM_FUNC_ALIAS(memset, __memset) | 43 | SYM_FUNC_ALIAS_MEMFUNC(memset, __memset) |
| 44 | EXPORT_SYMBOL(memset) | 44 | EXPORT_SYMBOL(memset) |
| 45 | 45 | ||
| 46 | SYM_FUNC_START_LOCAL(memset_orig) | 46 | SYM_FUNC_START_LOCAL(memset_orig) |
| @@ -9,8 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) | 11 | # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) |
| 12 | KBUILD_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include | 12 | KBUILD_CFLAGS += -fno-builtin |
| 13 | HOSTFLAGS += -Iarch/$(ARCH)/boot/include | ||
| 14 | 13 | ||
| 15 | subdir-y := lib | 14 | subdir-y := lib |
| 16 | targets += vmlinux.bin vmlinux.bin.gz | 15 | targets += vmlinux.bin vmlinux.bin.gz |
| @@ -4,13 +4,14 @@ · 3 unmodified lines | |||
| 4 | /* bits taken from ppc */ | 4 | /* bits taken from ppc */ |
| 5 | 5 | ||
| 6 | extern void *avail_ram, *end_avail; | 6 | extern void *avail_ram, *end_avail; |
| 7 | void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); | ||
| 7 | 8 | ||
| 8 | void exit (void) | 9 | static void exit(void) |
| 9 | { | 10 | { |
| 10 | for (;;); | 11 | for (;;); |
| 11 | } | 12 | } |
| 12 | 13 | ||
| 13 | void *zalloc(unsigned size) | 14 | static void *zalloc(unsigned int size) |
| 14 | { | 15 | { |
| 15 | void *p = avail_ram; | 16 | void *p = avail_ram; |
| 16 | 17 | ||
| @@ -6,6 +6,10 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #include <variant/core.h> | 7 | #include <variant/core.h> |
| 8 | 8 | ||
| 9 | #ifndef XCHAL_HAVE_DIV32 | ||
| 10 | #define XCHAL_HAVE_DIV32 0 | ||
| 11 | #endif | ||
| 12 | |||
| 9 | #ifndef XCHAL_HAVE_EXCLUSIVE | 13 | #ifndef XCHAL_HAVE_EXCLUSIVE |
| 10 | #define XCHAL_HAVE_EXCLUSIVE 0 | 14 | #define XCHAL_HAVE_EXCLUSIVE 0 |
| 11 | #endif | 15 | #endif |
| @@ -48,6 +48,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp); · 47 unmodified lines | |||
| 48 | void hw_breakpoint_pmu_read(struct perf_event *bp); | 48 | void hw_breakpoint_pmu_read(struct perf_event *bp); |
| 49 | int check_hw_breakpoint(struct pt_regs *regs); | 49 | int check_hw_breakpoint(struct pt_regs *regs); |
| 50 | void clear_ptrace_hw_breakpoint(struct task_struct *tsk); | 50 | void clear_ptrace_hw_breakpoint(struct task_struct *tsk); |
| 51 | void restore_dbreak(void); | ||
| 51 | 52 | ||
| 52 | #else | 53 | #else |
| 53 | 54 | ||
| @@ -14,6 +14,8 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
| 16 | #include <linux/stringify.h> | 16 | #include <linux/stringify.h> |
| 17 | |||
| 18 | #include <asm/bootparam.h> | ||
| 17 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
| 18 | #include <asm/types.h> | 20 | #include <asm/types.h> |
| 19 | #include <asm/regs.h> | 21 | #include <asm/regs.h> |
| @@ -217,6 +219,9 @@ struct mm_struct; · 197 unmodified lines | |||
| 217 | 219 | ||
| 218 | extern unsigned long __get_wchan(struct task_struct *p); | 220 | extern unsigned long __get_wchan(struct task_struct *p); |
| 219 | 221 | ||
| 222 | void init_arch(bp_tag_t *bp_start); | ||
| 223 | void do_notify_resume(struct pt_regs *regs); | ||
| 224 | |||
| 220 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) | 225 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) |
| 221 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) | 226 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) |
| 222 | 227 | ||
| @@ -106,6 +106,9 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) · 105 unmodified lines | |||
| 106 | return regs->areg[2]; | 106 | return regs->areg[2]; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | int do_syscall_trace_enter(struct pt_regs *regs); | ||
| 110 | void do_syscall_trace_leave(struct pt_regs *regs); | ||
| 111 | |||
| 109 | #else /* __ASSEMBLY__ */ | 112 | #else /* __ASSEMBLY__ */ |
| 110 | 113 | ||
| 111 | # include <asm/asm-offsets.h> | 114 | # include <asm/asm-offsets.h> |
| @@ -23,6 +23,7 @@ struct cpumask; · 22 unmodified lines | |||
| 23 | void arch_send_call_function_ipi_mask(const struct cpumask *mask); | 23 | void arch_send_call_function_ipi_mask(const struct cpumask *mask); |
| 24 | void arch_send_call_function_single_ipi(int cpu); | 24 | void arch_send_call_function_single_ipi(int cpu); |
| 25 | 25 | ||
| 26 | void secondary_start_kernel(void); | ||
| 26 | void smp_init_cpus(void); | 27 | void smp_init_cpus(void); |
| 27 | void secondary_init_irq(void); | 28 | void secondary_init_irq(void); |
| 28 | void ipi_init(void); | 29 | void ipi_init(void); |
| @@ -18,4 +18,6 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte) | 19 | #define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte) |
| 20 | 20 | ||
| 21 | void check_tlb_sanity(void); | ||
| 22 | |||
| 21 | #endif /* _XTENSA_TLB_H */ | 23 | #endif /* _XTENSA_TLB_H */ |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
| 14 | #include <linux/perf_event.h> | 14 | #include <linux/perf_event.h> |
| 15 | #include <asm/core.h> | 15 | #include <asm/core.h> |
| 16 | #include <asm/hw_breakpoint.h> | ||
| 16 | 17 | ||
| 17 | /* Breakpoint currently in use for each IBREAKA. */ | 18 | /* Breakpoint currently in use for each IBREAKA. */ |
| 18 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]); | 19 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]); |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include <asm/mxregs.h> | 28 | #include <asm/mxregs.h> |
| 29 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
| 30 | #include <asm/platform.h> | 30 | #include <asm/platform.h> |
| 31 | #include <asm/traps.h> | ||
| 31 | 32 | ||
| 32 | DECLARE_PER_CPU(unsigned long, nmi_count); | 33 | DECLARE_PER_CPU(unsigned long, nmi_count); |
| 33 | 34 | ||
| @@ -541,7 +541,6 @@ long arch_ptrace(struct task_struct *child, long request, · 540 unmodified lines | |||
| 541 | return ret; | 541 | return ret; |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | void do_syscall_trace_leave(struct pt_regs *regs); | ||
| 545 | int do_syscall_trace_enter(struct pt_regs *regs) | 544 | int do_syscall_trace_enter(struct pt_regs *regs) |
| 546 | { | 545 | { |
| 547 | if (regs->syscall == NO_SYSCALL) | 546 | if (regs->syscall == NO_SYSCALL) |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | |||
| 26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
| 27 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
| 28 | #include <asm/coprocessor.h> | 28 | #include <asm/coprocessor.h> |
| 29 | #include <asm/processor.h> | ||
| 30 | #include <asm/syscall.h> | ||
| 29 | #include <asm/unistd.h> | 31 | #include <asm/unistd.h> |
| 30 | 32 | ||
| 31 | extern struct task_struct *coproc_owners[]; | 33 | extern struct task_struct *coproc_owners[]; |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
| 22 | #include <linux/kdebug.h> | 22 | #include <linux/kdebug.h> |
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/profile.h> | ||
| 24 | #include <linux/sched/mm.h> | 25 | #include <linux/sched/mm.h> |
| 25 | #include <linux/sched/hotplug.h> | 26 | #include <linux/sched/hotplug.h> |
| 26 | #include <linux/sched/task_stack.h> | 27 | #include <linux/sched/task_stack.h> |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
| 13 | #include <linux/stacktrace.h> | 13 | #include <linux/stacktrace.h> |
| 14 | 14 | ||
| 15 | #include <asm/ftrace.h> | ||
| 15 | #include <asm/stacktrace.h> | 16 | #include <asm/stacktrace.h> |
| 16 | #include <asm/traps.h> | 17 | #include <asm/traps.h> |
| 17 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | * for more details. | 23 | * for more details. |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <linux/cpu.h> | ||
| 26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| 27 | #include <linux/sched/signal.h> | 28 | #include <linux/sched/signal.h> |
| 28 | #include <linux/sched/debug.h> | 29 | #include <linux/sched/debug.h> |
| @@ -3,7 +3,9 @@ · 2 unmodified lines | |||
| 3 | #include <asm/asmmacro.h> | 3 | #include <asm/asmmacro.h> |
| 4 | #include <asm/core.h> | 4 | #include <asm/core.h> |
| 5 | 5 | ||
| 6 | #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16 | 6 | #if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32 || XCHAL_HAVE_MAC16 |
| 7 | #define XCHAL_NO_MUL 0 | ||
| 8 | #else | ||
| 7 | #define XCHAL_NO_MUL 1 | 9 | #define XCHAL_NO_MUL 1 |
| 8 | #endif | 10 | #endif |
| 9 | 11 | ||
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <asm/mmu_context.h> | 20 | #include <asm/mmu_context.h> |
| 21 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
| 22 | #include <asm/hardirq.h> | 22 | #include <asm/hardirq.h> |
| 23 | #include <asm/traps.h> | ||
| 23 | 24 | ||
| 24 | void bad_page_fault(struct pt_regs*, unsigned long, int); | 25 | void bad_page_fault(struct pt_regs*, unsigned long, int); |
| 25 | 26 | ||
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
| 19 | #include <asm/mmu_context.h> | 19 | #include <asm/mmu_context.h> |
| 20 | #include <asm/tlb.h> | ||
| 20 | #include <asm/tlbflush.h> | 21 | #include <asm/tlbflush.h> |
| 21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
| 22 | 23 | ||
| @@ -201,7 +201,7 @@ static int tuntap_write(struct iss_net_private *lp, struct sk_buff **skb) · 200 unmodified lines | |||
| 201 | return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); | 201 | return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | unsigned short tuntap_protocol(struct sk_buff *skb) | 204 | static unsigned short tuntap_protocol(struct sk_buff *skb) |
| 205 | { | 205 | { |
| 206 | return eth_type_trans(skb, skb->dev); | 206 | return eth_type_trans(skb, skb->dev); |
| 207 | } | 207 | } |
| @@ -441,7 +441,7 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu) · 233 unmodified lines | |||
| 441 | return -EINVAL; | 441 | return -EINVAL; |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | void iss_net_user_timer_expire(struct timer_list *unused) | 444 | static void iss_net_user_timer_expire(struct timer_list *unused) |
| 445 | { | 445 | { |
| 446 | } | 446 | } |
| 447 | 447 | ||
| @@ -270,7 +270,7 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data, · 269 unmodified lines | |||
| 270 | finish_wait(&rqw->wait, &data.wq); | 270 | finish_wait(&rqw->wait, &data.wq); |
| 271 | 271 | ||
| 272 | /* | 272 | /* |
| 273 | * We raced with wbt_wake_function() getting a token, | 273 | * We raced with rq_qos_wake_function() getting a token, |
| 274 | * which means we now have two. Put our local token | 274 | * which means we now have two. Put our local token |
| 275 | * and wake anyone else potentially waiting for one. | 275 | * and wake anyone else potentially waiting for one. |
| 276 | */ | 276 | */ |
| @@ -290,7 +290,6 @@ EXPORT_SYMBOL(disk_check_media_change); · 289 unmodified lines | |||
| 290 | /** | 290 | /** |
| 291 | * disk_force_media_change - force a media change event | 291 | * disk_force_media_change - force a media change event |
| 292 | * @disk: the disk which will raise the event | 292 | * @disk: the disk which will raise the event |
| 293 | * @events: the events to raise | ||
| 294 | * | 293 | * |
| 295 | * Should be called when the media changes for @disk. Generates a uevent | 294 | * Should be called when the media changes for @disk. Generates a uevent |
| 296 | * and attempts to free all dentries and inodes and invalidates all block | 295 | * and attempts to free all dentries and inodes and invalidates all block |
| @@ -278,10 +278,14 @@ int sm2_compute_z_digest(struct shash_desc *desc, · 277 unmodified lines | |||
| 278 | if (!ec) | 278 | if (!ec) |
| 279 | return -ENOMEM; | 279 | return -ENOMEM; |
| 280 | 280 | ||
| 281 | err = __sm2_set_pub_key(ec, key, keylen); | 281 | err = sm2_ec_ctx_init(ec); |
| 282 | if (err) | 282 | if (err) |
| 283 | goto out_free_ec; | 283 | goto out_free_ec; |
| 284 | 284 | ||
| 285 | err = __sm2_set_pub_key(ec, key, keylen); | ||
| 286 | if (err) | ||
| 287 | goto out_deinit_ec; | ||
| 288 | |||
| 285 | bits_len = SM2_DEFAULT_USERID_LEN * 8; | 289 | bits_len = SM2_DEFAULT_USERID_LEN * 8; |
| 286 | entl[0] = bits_len >> 8; | 290 | entl[0] = bits_len >> 8; |
| 287 | entl[1] = bits_len & 0xff; | 291 | entl[1] = bits_len & 0xff; |
| @@ -327,7 +327,7 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev) · 326 unmodified lines | |||
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | if (!ret) | 329 | if (!ret) |
| 330 | ivpu_info(vdev, "VPU ready message received successfully\n"); | 330 | ivpu_dbg(vdev, PM, "VPU ready message received successfully\n"); |
| 331 | else | 331 | else |
| 332 | ivpu_hw_diagnose_failure(vdev); | 332 | ivpu_hw_diagnose_failure(vdev); |
| 333 | 333 | ||
| @@ -634,6 +634,7 @@ static void ivpu_dev_fini(struct ivpu_device *vdev) · 300 unmodified lines | |||
| 634 | 634 | ||
| 635 | static struct pci_device_id ivpu_pci_ids[] = { | 635 | static struct pci_device_id ivpu_pci_ids[] = { |
| 636 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, | 636 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, |
| 637 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) }, | ||
| 637 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, | 638 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, |
| 638 | { } | 639 | { } |
| 639 | }; | 640 | }; |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #define DRIVER_DATE "20230117" | 23 | #define DRIVER_DATE "20230117" |
| 24 | 24 | ||
| 25 | #define PCI_DEVICE_ID_MTL 0x7d1d | 25 | #define PCI_DEVICE_ID_MTL 0x7d1d |
| 26 | #define PCI_DEVICE_ID_ARL 0xad1d | ||
| 26 | #define PCI_DEVICE_ID_LNL 0x643e | 27 | #define PCI_DEVICE_ID_LNL 0x643e |
| 27 | 28 | ||
| 28 | #define IVPU_HW_37XX 37 | 29 | #define IVPU_HW_37XX 37 |
| @@ -165,6 +166,7 @@ static inline int ivpu_hw_gen(struct ivpu_device *vdev) · 136 unmodified lines | |||
| 165 | { | 166 | { |
| 166 | switch (ivpu_device_id(vdev)) { | 167 | switch (ivpu_device_id(vdev)) { |
| 167 | case PCI_DEVICE_ID_MTL: | 168 | case PCI_DEVICE_ID_MTL: |
| 169 | case PCI_DEVICE_ID_ARL: | ||
| 168 | return IVPU_HW_37XX; | 170 | return IVPU_HW_37XX; |
| 169 | case PCI_DEVICE_ID_LNL: | 171 | case PCI_DEVICE_ID_LNL: |
| 170 | return IVPU_HW_40XX; | 172 | return IVPU_HW_40XX; |
| @@ -220,7 +220,8 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) · 219 unmodified lines | |||
| 220 | if (ret) | 220 | if (ret) |
| 221 | return ret; | 221 | return ret; |
| 222 | 222 | ||
| 223 | fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, DRM_IVPU_BO_WC); | 223 | fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, |
| 224 | DRM_IVPU_BO_CACHED | DRM_IVPU_BO_NOSNOOP); | ||
| 224 | if (!fw->mem) { | 225 | if (!fw->mem) { |
| 225 | ivpu_err(vdev, "Failed to allocate firmware runtime memory\n"); | 226 | ivpu_err(vdev, "Failed to allocate firmware runtime memory\n"); |
| 226 | return -ENOMEM; | 227 | return -ENOMEM; |
| @@ -330,7 +331,7 @@ int ivpu_fw_load(struct ivpu_device *vdev) · 103 unmodified lines | |||
| 330 | memset(start, 0, size); | 331 | memset(start, 0, size); |
| 331 | } | 332 | } |
| 332 | 333 | ||
| 333 | wmb(); /* Flush WC buffers after writing fw->mem */ | 334 | clflush_cache_range(fw->mem->kvaddr, fw->mem->base.size); |
| 334 | 335 | ||
| 335 | return 0; | 336 | return 0; |
| 336 | } | 337 | } |
| @@ -432,6 +433,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 95 unmodified lines | |||
| 432 | if (!ivpu_fw_is_cold_boot(vdev)) { | 433 | if (!ivpu_fw_is_cold_boot(vdev)) { |
| 433 | boot_params->save_restore_ret_address = 0; | 434 | boot_params->save_restore_ret_address = 0; |
| 434 | vdev->pm->is_warmboot = true; | 435 | vdev->pm->is_warmboot = true; |
| 436 | clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); | ||
| 435 | return; | 437 | return; |
| 436 | } | 438 | } |
| 437 | 439 | ||
| @@ -493,7 +495,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 55 unmodified lines | |||
| 493 | boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); | 495 | boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); |
| 494 | boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev); | 496 | boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev); |
| 495 | 497 | ||
| 496 | wmb(); /* Flush WC buffers after writing bootparams */ | 498 | clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); |
| 497 | 499 | ||
| 498 | ivpu_fw_boot_params_print(vdev, boot_params); | 500 | ivpu_fw_boot_params_print(vdev, boot_params); |
| 499 | } | 501 | } |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_gem.h> | 8 | #include <drm/drm_gem.h> |
| 9 | #include <drm/drm_mm.h> | 9 | #include <drm/drm_mm.h> |
| 10 | 10 | ||
| 11 | #define DRM_IVPU_BO_NOSNOOP 0x10000000 | ||
| 12 | |||
| 11 | struct dma_buf; | 13 | struct dma_buf; |
| 12 | struct ivpu_bo_ops; | 14 | struct ivpu_bo_ops; |
| 13 | struct ivpu_file_priv; | 15 | struct ivpu_file_priv; |
| @@ -83,6 +85,9 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo) · 69 unmodified lines | |||
| 83 | 85 | ||
| 84 | static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) | 86 | static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) |
| 85 | { | 87 | { |
| 88 | if (bo->flags & DRM_IVPU_BO_NOSNOOP) | ||
| 89 | return false; | ||
| 90 | |||
| 86 | return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED; | 91 | return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED; |
| 87 | } | 92 | } |
| 88 | 93 | ||
| @@ -57,8 +57,7 @@ · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | #define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK) | 58 | #define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK) |
| 59 | 59 | ||
| 60 | #define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)) | \ | 60 | #define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \ |
| 61 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \ | ||
| 62 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \ | 61 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \ |
| 63 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \ | 62 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \ |
| 64 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR)) | \ | 63 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR)) | \ |
| @@ -196,6 +195,14 @@ static int ivpu_pll_wait_for_status_ready(struct ivpu_device *vdev) · 131 unmodified lines | |||
| 196 | return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US); | 195 | return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US); |
| 197 | } | 196 | } |
| 198 | 197 | ||
| 198 | static int ivpu_wait_for_clock_own_resource_ack(struct ivpu_device *vdev) | ||
| 199 | { | ||
| 200 | if (ivpu_is_simics(vdev)) | ||
| 201 | return 0; | ||
| 202 | |||
| 203 | return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US); | ||
| 204 | } | ||
| 205 | |||
| 199 | static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev) | 206 | static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev) |
| 200 | { | 207 | { |
| 201 | struct ivpu_hw_info *hw = vdev->hw; | 208 | struct ivpu_hw_info *hw = vdev->hw; |
| @@ -556,6 +563,12 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev) · 354 unmodified lines | |||
| 556 | { | 563 | { |
| 557 | int ret; | 564 | int ret; |
| 558 | 565 | ||
| 566 | ret = ivpu_wait_for_clock_own_resource_ack(vdev); | ||
| 567 | if (ret) { | ||
| 568 | ivpu_err(vdev, "Timed out waiting for clock own resource ACK\n"); | ||
| 569 | return ret; | ||
| 570 | } | ||
| 571 | |||
| 559 | ivpu_boot_pwr_island_trickle_drive(vdev, true); | 572 | ivpu_boot_pwr_island_trickle_drive(vdev, true); |
| 560 | ivpu_boot_pwr_island_drive(vdev, true); | 573 | ivpu_boot_pwr_island_drive(vdev, true); |
| 561 | 574 | ||
| @@ -1046,8 +1059,6 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq) · 484 unmodified lines | |||
| 1046 | if (status == 0) | 1059 | if (status == 0) |
| 1047 | return IRQ_NONE; | 1060 | return IRQ_NONE; |
| 1048 | 1061 | ||
| 1049 | REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status); | ||
| 1050 | |||
| 1051 | if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status)) | 1062 | if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status)) |
| 1052 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE"); | 1063 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE"); |
| 1053 | 1064 | ||
| @@ -1092,6 +1103,9 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq) · 38 unmodified lines | |||
| 1092 | schedule_recovery = true; | 1103 | schedule_recovery = true; |
| 1093 | } | 1104 | } |
| 1094 | 1105 | ||
| 1106 | /* This must be done after interrupts are cleared at the source. */ | ||
| 1107 | REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status); | ||
| 1108 | |||
| 1095 | if (schedule_recovery) | 1109 | if (schedule_recovery) |
| 1096 | ivpu_pm_schedule_recovery(vdev); | 1110 | ivpu_pm_schedule_recovery(vdev); |
| 1097 | 1111 | ||
| @@ -1103,9 +1117,14 @@ static irqreturn_t ivpu_hw_40xx_irq_handler(int irq, void *ptr) · 5 unmodified lines | |||
| 1103 | struct ivpu_device *vdev = ptr; | 1117 | struct ivpu_device *vdev = ptr; |
| 1104 | irqreturn_t ret = IRQ_NONE; | 1118 | irqreturn_t ret = IRQ_NONE; |
| 1105 | 1119 | ||
| 1120 | REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1); | ||
| 1121 | |||
| 1106 | ret |= ivpu_hw_40xx_irqv_handler(vdev, irq); | 1122 | ret |= ivpu_hw_40xx_irqv_handler(vdev, irq); |
| 1107 | ret |= ivpu_hw_40xx_irqb_handler(vdev, irq); | 1123 | ret |= ivpu_hw_40xx_irqb_handler(vdev, irq); |
| 1108 | 1124 | ||
| 1125 | /* Re-enable global interrupts to re-trigger MSI for pending interrupts */ | ||
| 1126 | REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0); | ||
| 1127 | |||
| 1109 | if (ret & IRQ_WAKE_THREAD) | 1128 | if (ret & IRQ_WAKE_THREAD) |
| 1110 | return IRQ_WAKE_THREAD; | 1129 | return IRQ_WAKE_THREAD; |
| 1111 | 1130 | ||
| @@ -70,6 +70,8 @@ · 69 unmodified lines | |||
| 70 | #define VPU_40XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0) | 70 | #define VPU_40XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0) |
| 71 | #define VPU_40XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1) | 71 | #define VPU_40XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1) |
| 72 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2) | 72 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2) |
| 73 | #define VPU_40XX_BUTTRESS_VPU_STATUS_CLOCK_RESOURCE_OWN_ACK_MASK BIT_MASK(6) | ||
| 74 | #define VPU_40XX_BUTTRESS_VPU_STATUS_POWER_RESOURCE_OWN_ACK_MASK BIT_MASK(7) | ||
| 73 | #define VPU_40XX_BUTTRESS_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11) | 75 | #define VPU_40XX_BUTTRESS_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11) |
| 74 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12) | 76 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12) |
| 75 | 77 | ||
| @@ -209,10 +209,10 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, · 208 unmodified lines | |||
| 209 | struct ivpu_ipc_rx_msg *rx_msg; | 209 | struct ivpu_ipc_rx_msg *rx_msg; |
| 210 | int wait_ret, ret = 0; | 210 | int wait_ret, ret = 0; |
| 211 | 211 | ||
| 212 | wait_ret = wait_event_interruptible_timeout(cons->rx_msg_wq, | 212 | wait_ret = wait_event_timeout(cons->rx_msg_wq, |
| 213 | (IS_KTHREAD() && kthread_should_stop()) || | 213 | (IS_KTHREAD() && kthread_should_stop()) || |
| 214 | !list_empty(&cons->rx_msg_list), | 214 | !list_empty(&cons->rx_msg_list), |
| 215 | msecs_to_jiffies(timeout_ms)); | 215 | msecs_to_jiffies(timeout_ms)); |
| 216 | 216 | ||
| 217 | if (IS_KTHREAD() && kthread_should_stop()) | 217 | if (IS_KTHREAD() && kthread_should_stop()) |
| 218 | return -EINTR; | 218 | return -EINTR; |
| @@ -220,9 +220,6 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, · 1 unmodified line | |||
| 220 | if (wait_ret == 0) | 220 | if (wait_ret == 0) |
| 221 | return -ETIMEDOUT; | 221 | return -ETIMEDOUT; |
| 222 | 222 | ||
| 223 | if (wait_ret < 0) | ||
| 224 | return -ERESTARTSYS; | ||
| 225 | |||
| 226 | spin_lock_irq(&cons->rx_msg_lock); | 223 | spin_lock_irq(&cons->rx_msg_lock); |
| 227 | rx_msg = list_first_entry_or_null(&cons->rx_msg_list, struct ivpu_ipc_rx_msg, link); | 224 | rx_msg = list_first_entry_or_null(&cons->rx_msg_list, struct ivpu_ipc_rx_msg, link); |
| 228 | if (!rx_msg) { | 225 | if (!rx_msg) { |
| @@ -2057,7 +2057,9 @@ static int acpi_video_bus_add(struct acpi_device *device) · 2056 unmodified lines | |||
| 2057 | !auto_detect) | 2057 | !auto_detect) |
| 2058 | acpi_video_bus_register_backlight(video); | 2058 | acpi_video_bus_register_backlight(video); |
| 2059 | 2059 | ||
| 2060 | acpi_video_bus_add_notify_handler(video); | 2060 | error = acpi_video_bus_add_notify_handler(video); |
| 2061 | if (error) | ||
| 2062 | goto err_del; | ||
| 2061 | 2063 | ||
| 2062 | error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, | 2064 | error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, |
| 2063 | acpi_video_bus_notify); | 2065 | acpi_video_bus_notify); |
| @@ -2067,10 +2069,11 @@ static int acpi_video_bus_add(struct acpi_device *device) · 3 unmodified lines | |||
| 2067 | return 0; | 2069 | return 0; |
| 2068 | 2070 | ||
| 2069 | err_remove: | 2071 | err_remove: |
| 2072 | acpi_video_bus_remove_notify_handler(video); | ||
| 2073 | err_del: | ||
| 2070 | mutex_lock(&video_list_lock); | 2074 | mutex_lock(&video_list_lock); |
| 2071 | list_del(&video->entry); | 2075 | list_del(&video->entry); |
| 2072 | mutex_unlock(&video_list_lock); | 2076 | mutex_unlock(&video_list_lock); |
| 2073 | acpi_video_bus_remove_notify_handler(video); | ||
| 2074 | acpi_video_bus_unregister_backlight(video); | 2077 | acpi_video_bus_unregister_backlight(video); |
| 2075 | err_put_video: | 2078 | err_put_video: |
| 2076 | acpi_video_bus_put_devices(video); | 2079 | acpi_video_bus_put_devices(video); |
| @@ -855,7 +855,7 @@ static size_t sizeof_idt(struct acpi_nfit_interleave *idt) · 854 unmodified lines | |||
| 855 | { | 855 | { |
| 856 | if (idt->header.length < sizeof(*idt)) | 856 | if (idt->header.length < sizeof(*idt)) |
| 857 | return 0; | 857 | return 0; |
| 858 | return sizeof(*idt) + sizeof(u32) * (idt->line_count - 1); | 858 | return sizeof(*idt) + sizeof(u32) * idt->line_count; |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | static bool add_idt(struct acpi_nfit_desc *acpi_desc, | 861 | static bool add_idt(struct acpi_nfit_desc *acpi_desc, |
| @@ -19,6 +19,7 @@ static void acpi_set_pdc_bits(u32 *buf) · 18 unmodified lines | |||
| 19 | { | 19 | { |
| 20 | buf[0] = ACPI_PDC_REVISION_ID; | 20 | buf[0] = ACPI_PDC_REVISION_ID; |
| 21 | buf[1] = 1; | 21 | buf[1] = 1; |
| 22 | buf[2] = 0; | ||
| 22 | 23 | ||
| 23 | /* Twiddle arch-specific bits needed for _PDC */ | 24 | /* Twiddle arch-specific bits needed for _PDC */ |
| 24 | arch_acpi_set_proc_cap_bits(&buf[2]); | 25 | arch_acpi_set_proc_cap_bits(&buf[2]); |
| @@ -1972,6 +1972,96 @@ retry: · 1971 unmodified lines | |||
| 1972 | return rc; | 1972 | return rc; |
| 1973 | } | 1973 | } |
| 1974 | 1974 | ||
| 1975 | /** | ||
| 1976 | * ata_dev_power_set_standby - Set a device power mode to standby | ||
| 1977 | * @dev: target device | ||
| 1978 | * | ||
| 1979 | * Issue a STANDBY IMMEDIATE command to set a device power mode to standby. | ||
| 1980 | * For an HDD device, this spins down the disks. | ||
| 1981 | * | ||
| 1982 | * LOCKING: | ||
| 1983 | * Kernel thread context (may sleep). | ||
| 1984 | */ | ||
| 1985 | void ata_dev_power_set_standby(struct ata_device *dev) | ||
| 1986 | { | ||
| 1987 | unsigned long ap_flags = dev->link->ap->flags; | ||
| 1988 | struct ata_taskfile tf; | ||
| 1989 | unsigned int err_mask; | ||
| 1990 | |||
| 1991 | /* Issue STANDBY IMMEDIATE command only if supported by the device */ | ||
| 1992 | if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) | ||
| 1993 | return; | ||
| 1994 | |||
| 1995 | /* | ||
| 1996 | * Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5) | ||
| 1997 | * causing some drives to spin up and down again. For these, do nothing | ||
| 1998 | * if we are being called on shutdown. | ||
| 1999 | */ | ||
| 2000 | if ((ap_flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) && | ||
| 2001 | system_state == SYSTEM_POWER_OFF) | ||
| 2002 | return; | ||
| 2003 | |||
| 2004 | if ((ap_flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && | ||
| 2005 | system_entering_hibernation()) | ||
| 2006 | return; | ||
| 2007 | |||
| 2008 | ata_tf_init(dev, &tf); | ||
| 2009 | tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | ||
| 2010 | tf.protocol = ATA_PROT_NODATA; | ||
| 2011 | tf.command = ATA_CMD_STANDBYNOW1; | ||
| 2012 | |||
| 2013 | ata_dev_notice(dev, "Entering standby power mode\n"); | ||
| 2014 | |||
| 2015 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); | ||
| 2016 | if (err_mask) | ||
| 2017 | ata_dev_err(dev, "STANDBY IMMEDIATE failed (err_mask=0x%x)\n", | ||
| 2018 | err_mask); | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | /** | ||
| 2022 | * ata_dev_power_set_active - Set a device power mode to active | ||
| 2023 | * @dev: target device | ||
| 2024 | * | ||
| 2025 | * Issue a VERIFY command to enter to ensure that the device is in the | ||
| 2026 | * active power mode. For a spun-down HDD (standby or idle power mode), | ||
| 2027 | * the VERIFY command will complete after the disk spins up. | ||
| 2028 | * | ||
| 2029 | * LOCKING: | ||
| 2030 | * Kernel thread context (may sleep). | ||
| 2031 | */ | ||
| 2032 | void ata_dev_power_set_active(struct ata_device *dev) | ||
| 2033 | { | ||
| 2034 | struct ata_taskfile tf; | ||
| 2035 | unsigned int err_mask; | ||
| 2036 | |||
| 2037 | /* | ||
| 2038 | * Issue READ VERIFY SECTORS command for 1 sector at lba=0 only | ||
| 2039 | * if supported by the device. | ||
| 2040 | */ | ||
| 2041 | if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) | ||
| 2042 | return; | ||
| 2043 | |||
| 2044 | ata_tf_init(dev, &tf); | ||
| 2045 | tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | ||
| 2046 | tf.protocol = ATA_PROT_NODATA; | ||
| 2047 | tf.command = ATA_CMD_VERIFY; | ||
| 2048 | tf.nsect = 1; | ||
| 2049 | if (dev->flags & ATA_DFLAG_LBA) { | ||
| 2050 | tf.flags |= ATA_TFLAG_LBA; | ||
| 2051 | tf.device |= ATA_LBA; | ||
| 2052 | } else { | ||
| 2053 | /* CHS */ | ||
| 2054 | tf.lbal = 0x1; /* sect */ | ||
| 2055 | } | ||
| 2056 | |||
| 2057 | ata_dev_notice(dev, "Entering active power mode\n"); | ||
| 2058 | |||
| 2059 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); | ||
| 2060 | if (err_mask) | ||
| 2061 | ata_dev_err(dev, "VERIFY failed (err_mask=0x%x)\n", | ||
| 2062 | err_mask); | ||
| 2063 | } | ||
| 2064 | |||
| 1975 | /** | 2065 | /** |
| 1976 | * ata_read_log_page - read a specific log page | 2066 | * ata_read_log_page - read a specific log page |
| 1977 | * @dev: target device | 2067 | * @dev: target device |
| @@ -2529,7 +2619,7 @@ static int ata_dev_config_lba(struct ata_device *dev) · 551 unmodified lines | |||
| 2529 | { | 2619 | { |
| 2530 | const u16 *id = dev->id; | 2620 | const u16 *id = dev->id; |
| 2531 | const char *lba_desc; | 2621 | const char *lba_desc; |
| 2532 | char ncq_desc[24]; | 2622 | char ncq_desc[32]; |
| 2533 | int ret; | 2623 | int ret; |
| 2534 | 2624 | ||
| 2535 | dev->flags |= ATA_DFLAG_LBA; | 2625 | dev->flags |= ATA_DFLAG_LBA; |
| @@ -5037,17 +5127,19 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, · 2501 unmodified lines | |||
| 5037 | struct ata_link *link; | 5127 | struct ata_link *link; |
| 5038 | unsigned long flags; | 5128 | unsigned long flags; |
| 5039 | 5129 | ||
| 5040 | /* Previous resume operation might still be in | 5130 | spin_lock_irqsave(ap->lock, flags); |
| 5041 | * progress. Wait for PM_PENDING to clear. | 5131 | |
| 5132 | /* | ||
| 5133 | * A previous PM operation might still be in progress. Wait for | ||
| 5134 | * ATA_PFLAG_PM_PENDING to clear. | ||
| 5042 | */ | 5135 | */ |
| 5043 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { | 5136 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { |
| 5137 | spin_unlock_irqrestore(ap->lock, flags); | ||
| 5044 | ata_port_wait_eh(ap); | 5138 | ata_port_wait_eh(ap); |
| 5045 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | 5139 | spin_lock_irqsave(ap->lock, flags); |
| 5046 | } | 5140 | } |
| 5047 | 5141 | ||
| 5048 | /* request PM ops to EH */ | 5142 | /* Request PM operation to EH */ |
| 5049 | spin_lock_irqsave(ap->lock, flags); | ||
| 5050 | |||
| 5051 | ap->pm_mesg = mesg; | 5143 | ap->pm_mesg = mesg; |
| 5052 | ap->pflags |= ATA_PFLAG_PM_PENDING; | 5144 | ap->pflags |= ATA_PFLAG_PM_PENDING; |
| 5053 | ata_for_each_link(link, ap, HOST_FIRST) { | 5145 | ata_for_each_link(link, ap, HOST_FIRST) { |
| @@ -5059,10 +5151,8 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, · 5 unmodified lines | |||
| 5059 | 5151 | ||
| 5060 | spin_unlock_irqrestore(ap->lock, flags); | 5152 | spin_unlock_irqrestore(ap->lock, flags); |
| 5061 | 5153 | ||
| 5062 | if (!async) { | 5154 | if (!async) |
| 5063 | ata_port_wait_eh(ap); | 5155 | ata_port_wait_eh(ap); |
| 5064 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | ||
| 5065 | } | ||
| 5066 | } | 5156 | } |
| 5067 | 5157 | ||
| 5068 | /* | 5158 | /* |
| @@ -5078,11 +5168,27 @@ static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET · 9 unmodified lines | |||
| 5078 | 5168 | ||
| 5079 | static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) | 5169 | static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) |
| 5080 | { | 5170 | { |
| 5171 | /* | ||
| 5172 | * We are about to suspend the port, so we do not care about | ||
| 5173 | * scsi_rescan_device() calls scheduled by previous resume operations. | ||
| 5174 | * The next resume will schedule the rescan again. So cancel any rescan | ||
| 5175 | * that is not done yet. | ||
| 5176 | */ | ||
| 5177 | cancel_delayed_work_sync(&ap->scsi_rescan_task); | ||
| 5178 | |||
| 5081 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); | 5179 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); |
| 5082 | } | 5180 | } |
| 5083 | 5181 | ||
| 5084 | static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) | 5182 | static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) |
| 5085 | { | 5183 | { |
| 5184 | /* | ||
| 5185 | * We are about to suspend the port, so we do not care about | ||
| 5186 | * scsi_rescan_device() calls scheduled by previous resume operations. | ||
| 5187 | * The next resume will schedule the rescan again. So cancel any rescan | ||
| 5188 | * that is not done yet. | ||
| 5189 | */ | ||
| 5190 | cancel_delayed_work_sync(&ap->scsi_rescan_task); | ||
| 5191 | |||
| 5086 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); | 5192 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); |
| 5087 | } | 5193 | } |
| 5088 | 5194 | ||
| @@ -5229,7 +5335,7 @@ EXPORT_SYMBOL_GPL(ata_host_resume); · 140 unmodified lines | |||
| 5229 | #endif | 5335 | #endif |
| 5230 | 5336 | ||
| 5231 | const struct device_type ata_port_type = { | 5337 | const struct device_type ata_port_type = { |
| 5232 | .name = "ata_port", | 5338 | .name = ATA_PORT_TYPE_NAME, |
| 5233 | #ifdef CONFIG_PM | 5339 | #ifdef CONFIG_PM |
| 5234 | .pm = &ata_port_pm_ops, | 5340 | .pm = &ata_port_pm_ops, |
| 5235 | #endif | 5341 | #endif |
| @@ -5948,11 +6054,30 @@ static void ata_port_detach(struct ata_port *ap) · 712 unmodified lines | |||
| 5948 | struct ata_link *link; | 6054 | struct ata_link *link; |
| 5949 | struct ata_device *dev; | 6055 | struct ata_device *dev; |
| 5950 | 6056 | ||
| 5951 | /* tell EH we're leaving & flush EH */ | 6057 | /* Wait for any ongoing EH */ |
| 6058 | ata_port_wait_eh(ap); | ||
| 6059 | |||
| 6060 | mutex_lock(&ap->scsi_scan_mutex); | ||
| 5952 | spin_lock_irqsave(ap->lock, flags); | 6061 | spin_lock_irqsave(ap->lock, flags); |
| 6062 | |||
| 6063 | /* Remove scsi devices */ | ||
| 6064 | ata_for_each_link(link, ap, HOST_FIRST) { | ||
| 6065 | ata_for_each_dev(dev, link, ALL) { | ||
| 6066 | if (dev->sdev) { | ||
| 6067 | spin_unlock_irqrestore(ap->lock, flags); | ||
| 6068 | scsi_remove_device(dev->sdev); | ||
| 6069 | spin_lock_irqsave(ap->lock, flags); | ||
| 6070 | dev->sdev = NULL; | ||
| 6071 | } | ||
| 6072 | } | ||
| 6073 | } | ||
| 6074 | |||
| 6075 | /* Tell EH to disable all devices */ | ||
| 5953 | ap->pflags |= ATA_PFLAG_UNLOADING; | 6076 | ap->pflags |= ATA_PFLAG_UNLOADING; |
| 5954 | ata_port_schedule_eh(ap); | 6077 | ata_port_schedule_eh(ap); |
| 6078 | |||
| 5955 | spin_unlock_irqrestore(ap->lock, flags); | 6079 | spin_unlock_irqrestore(ap->lock, flags); |
| 6080 | mutex_unlock(&ap->scsi_scan_mutex); | ||
| 5956 | 6081 | ||
| 5957 | /* wait till EH commits suicide */ | 6082 | /* wait till EH commits suicide */ |
| 5958 | ata_port_wait_eh(ap); | 6083 | ata_port_wait_eh(ap); |
| @@ -147,6 +147,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { · 146 unmodified lines | |||
| 147 | .timeouts = ata_eh_other_timeouts, }, | 147 | .timeouts = ata_eh_other_timeouts, }, |
| 148 | { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), | 148 | { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), |
| 149 | .timeouts = ata_eh_flush_timeouts }, | 149 | .timeouts = ata_eh_flush_timeouts }, |
| 150 | { .commands = CMDS(ATA_CMD_VERIFY), | ||
| 151 | .timeouts = ata_eh_reset_timeouts }, | ||
| 150 | }; | 152 | }; |
| 151 | #undef CMDS | 153 | #undef CMDS |
| 152 | 154 | ||
| @@ -498,7 +500,19 @@ static void ata_eh_unload(struct ata_port *ap) · 345 unmodified lines | |||
| 498 | struct ata_device *dev; | 500 | struct ata_device *dev; |
| 499 | unsigned long flags; | 501 | unsigned long flags; |
| 500 | 502 | ||
| 501 | /* Restore SControl IPM and SPD for the next driver and | 503 | /* |
| 504 | * Unless we are restarting, transition all enabled devices to | ||
| 505 | * standby power mode. | ||
| 506 | */ | ||
| 507 | if (system_state != SYSTEM_RESTART) { | ||
| 508 | ata_for_each_link(link, ap, PMP_FIRST) { | ||
| 509 | ata_for_each_dev(dev, link, ENABLED) | ||
| 510 | ata_dev_power_set_standby(dev); | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 514 | /* | ||
| 515 | * Restore SControl IPM and SPD for the next driver and | ||
| 502 | * disable attached devices. | 516 | * disable attached devices. |
| 503 | */ | 517 | */ |
| 504 | ata_for_each_link(link, ap, PMP_FIRST) { | 518 | ata_for_each_link(link, ap, PMP_FIRST) { |
| @@ -684,6 +698,10 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) · 179 unmodified lines | |||
| 684 | ehc->saved_xfer_mode[devno] = dev->xfer_mode; | 698 | ehc->saved_xfer_mode[devno] = dev->xfer_mode; |
| 685 | if (ata_ncq_enabled(dev)) | 699 | if (ata_ncq_enabled(dev)) |
| 686 | ehc->saved_ncq_enabled |= 1 << devno; | 700 | ehc->saved_ncq_enabled |= 1 << devno; |
| 701 | |||
| 702 | /* If we are resuming, wake up the device */ | ||
| 703 | if (ap->pflags & ATA_PFLAG_RESUMING) | ||
| 704 | ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE; | ||
| 687 | } | 705 | } |
| 688 | } | 706 | } |
| 689 | 707 | ||
| @@ -743,6 +761,8 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) · 53 unmodified lines | |||
| 743 | /* clean up */ | 761 | /* clean up */ |
| 744 | spin_lock_irqsave(ap->lock, flags); | 762 | spin_lock_irqsave(ap->lock, flags); |
| 745 | 763 | ||
| 764 | ap->pflags &= ~ATA_PFLAG_RESUMING; | ||
| 765 | |||
| 746 | if (ap->pflags & ATA_PFLAG_LOADING) | 766 | if (ap->pflags & ATA_PFLAG_LOADING) |
| 747 | ap->pflags &= ~ATA_PFLAG_LOADING; | 767 | ap->pflags &= ~ATA_PFLAG_LOADING; |
| 748 | else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) && | 768 | else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) && |
| @@ -1218,6 +1238,13 @@ void ata_eh_detach_dev(struct ata_device *dev) · 469 unmodified lines | |||
| 1218 | struct ata_eh_context *ehc = &link->eh_context; | 1238 | struct ata_eh_context *ehc = &link->eh_context; |
| 1219 | unsigned long flags; | 1239 | unsigned long flags; |
| 1220 | 1240 | ||
| 1241 | /* | ||
| 1242 | * If the device is still enabled, transition it to standby power mode | ||
| 1243 | * (i.e. spin down HDDs). | ||
| 1244 | */ | ||
| 1245 | if (ata_dev_enabled(dev)) | ||
| 1246 | ata_dev_power_set_standby(dev); | ||
| 1247 | |||
| 1221 | ata_dev_disable(dev); | 1248 | ata_dev_disable(dev); |
| 1222 | 1249 | ||
| 1223 | spin_lock_irqsave(ap->lock, flags); | 1250 | spin_lock_irqsave(ap->lock, flags); |
| @@ -2305,7 +2332,7 @@ static void ata_eh_link_report(struct ata_link *link) · 1081 unmodified lines | |||
| 2305 | struct ata_eh_context *ehc = &link->eh_context; | 2332 | struct ata_eh_context *ehc = &link->eh_context; |
| 2306 | struct ata_queued_cmd *qc; | 2333 | struct ata_queued_cmd *qc; |
| 2307 | const char *frozen, *desc; | 2334 | const char *frozen, *desc; |
| 2308 | char tries_buf[6] = ""; | 2335 | char tries_buf[16] = ""; |
| 2309 | int tag, nr_failed = 0; | 2336 | int tag, nr_failed = 0; |
| 2310 | 2337 | ||
| 2311 | if (ehc->i.flags & ATA_EHI_QUIET) | 2338 | if (ehc->i.flags & ATA_EHI_QUIET) |
| @@ -3016,6 +3043,15 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, · 704 unmodified lines | |||
| 3016 | if (ehc->i.flags & ATA_EHI_DID_RESET) | 3043 | if (ehc->i.flags & ATA_EHI_DID_RESET) |
| 3017 | readid_flags |= ATA_READID_POSTRESET; | 3044 | readid_flags |= ATA_READID_POSTRESET; |
| 3018 | 3045 | ||
| 3046 | /* | ||
| 3047 | * When resuming, before executing any command, make sure to | ||
| 3048 | * transition the device to the active power mode. | ||
| 3049 | */ | ||
| 3050 | if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) { | ||
| 3051 | ata_dev_power_set_active(dev); | ||
| 3052 | ata_eh_done(link, dev, ATA_EH_SET_ACTIVE); | ||
| 3053 | } | ||
| 3054 | |||
| 3019 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { | 3055 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { |
| 3020 | WARN_ON(dev->class == ATA_DEV_PMP); | 3056 | WARN_ON(dev->class == ATA_DEV_PMP); |
| 3021 | 3057 | ||
| @@ -3989,6 +4025,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) · 967 unmodified lines | |||
| 3989 | unsigned long flags; | 4025 | unsigned long flags; |
| 3990 | int rc = 0; | 4026 | int rc = 0; |
| 3991 | struct ata_device *dev; | 4027 | struct ata_device *dev; |
| 4028 | struct ata_link *link; | ||
| 3992 | 4029 | ||
| 3993 | /* are we suspending? */ | 4030 | /* are we suspending? */ |
| 3994 | spin_lock_irqsave(ap->lock, flags); | 4031 | spin_lock_irqsave(ap->lock, flags); |
| @@ -4001,6 +4038,12 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) · 6 unmodified lines | |||
| 4001 | 4038 | ||
| 4002 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); | 4039 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); |
| 4003 | 4040 | ||
| 4041 | /* Set all devices attached to the port in standby mode */ | ||
| 4042 | ata_for_each_link(link, ap, HOST_FIRST) { | ||
| 4043 | ata_for_each_dev(dev, link, ENABLED) | ||
| 4044 | ata_dev_power_set_standby(dev); | ||
| 4045 | } | ||
| 4046 | |||
| 4004 | /* | 4047 | /* |
| 4005 | * If we have a ZPODD attached, check its zero | 4048 | * If we have a ZPODD attached, check its zero |
| 4006 | * power ready status before the port is frozen. | 4049 | * power ready status before the port is frozen. |
| @@ -4083,6 +4126,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) · 76 unmodified lines | |||
| 4083 | /* update the flags */ | 4126 | /* update the flags */ |
| 4084 | spin_lock_irqsave(ap->lock, flags); | 4127 | spin_lock_irqsave(ap->lock, flags); |
| 4085 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); | 4128 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); |
| 4129 | ap->pflags |= ATA_PFLAG_RESUMING; | ||
| 4086 | spin_unlock_irqrestore(ap->lock, flags); | 4130 | spin_unlock_irqrestore(ap->lock, flags); |
| 4087 | } | 4131 | } |
| 4088 | #endif /* CONFIG_PM */ | 4132 | #endif /* CONFIG_PM */ |
| @@ -1050,14 +1050,13 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) · 1049 unmodified lines | |||
| 1050 | } | 1050 | } |
| 1051 | } else { | 1051 | } else { |
| 1052 | sdev->sector_size = ata_id_logical_sector_size(dev->id); | 1052 | sdev->sector_size = ata_id_logical_sector_size(dev->id); |
| 1053 | |||
| 1053 | /* | 1054 | /* |
| 1054 | * Stop the drive on suspend but do not issue START STOP UNIT | 1055 | * Ask the sd driver to issue START STOP UNIT on runtime suspend |
| 1055 | * on resume as this is not necessary and may fail: the device | 1056 | * and resume only. For system level suspend/resume, devices |
| 1056 | * will be woken up by ata_port_pm_resume() with a port reset | 1057 | * power state is handled directly by libata EH. |
| 1057 | * and device revalidation. | ||
| 1058 | */ | 1058 | */ |
| 1059 | sdev->manage_start_stop = 1; | 1059 | sdev->manage_runtime_start_stop = true; |
| 1060 | sdev->no_start_on_resume = 1; | ||
| 1061 | } | 1060 | } |
| 1062 | 1061 | ||
| 1063 | /* | 1062 | /* |
| @@ -1089,6 +1088,42 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) · 25 unmodified lines | |||
| 1089 | return 0; | 1088 | return 0; |
| 1090 | } | 1089 | } |
| 1091 | 1090 | ||
| 1091 | /** | ||
| 1092 | * ata_scsi_slave_alloc - Early setup of SCSI device | ||
| 1093 | * @sdev: SCSI device to examine | ||
| 1094 | * | ||
| 1095 | * This is called from scsi_alloc_sdev() when the scsi device | ||
| 1096 | * associated with an ATA device is scanned on a port. | ||
| 1097 | * | ||
| 1098 | * LOCKING: | ||
| 1099 | * Defined by SCSI layer. We don't really care. | ||
| 1100 | */ | ||
| 1101 | |||
| 1102 | int ata_scsi_slave_alloc(struct scsi_device *sdev) | ||
| 1103 | { | ||
| 1104 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
| 1105 | struct device_link *link; | ||
| 1106 | |||
| 1107 | ata_scsi_sdev_config(sdev); | ||
| 1108 | |||
| 1109 | /* | ||
| 1110 | * Create a link from the ata_port device to the scsi device to ensure | ||
| 1111 | * that PM does suspend/resume in the correct order: the scsi device is | ||
| 1112 | * consumer (child) and the ata port the supplier (parent). | ||
| 1113 | */ | ||
| 1114 | link = device_link_add(&sdev->sdev_gendev, &ap->tdev, | ||
| 1115 | DL_FLAG_STATELESS | | ||
| 1116 | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); | ||
| 1117 | if (!link) { | ||
| 1118 | ata_port_err(ap, "Failed to create link to scsi device %s\n", | ||
| 1119 | dev_name(&sdev->sdev_gendev)); | ||
| 1120 | return -ENODEV; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | return 0; | ||
| 1124 | } | ||
| 1125 | EXPORT_SYMBOL_GPL(ata_scsi_slave_alloc); | ||
| 1126 | |||
| 1092 | /** | 1127 | /** |
| 1093 | * ata_scsi_slave_config - Set SCSI device attributes | 1128 | * ata_scsi_slave_config - Set SCSI device attributes |
| 1094 | * @sdev: SCSI device to examine | 1129 | * @sdev: SCSI device to examine |
| @@ -1105,14 +1140,11 @@ int ata_scsi_slave_config(struct scsi_device *sdev) · 10 unmodified lines | |||
| 1105 | { | 1140 | { |
| 1106 | struct ata_port *ap = ata_shost_to_port(sdev->host); | 1141 | struct ata_port *ap = ata_shost_to_port(sdev->host); |
| 1107 | struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); | 1142 | struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); |
| 1108 | int rc = 0; | ||
| 1109 | |||
| 1110 | ata_scsi_sdev_config(sdev); | ||
| 1111 | 1143 | ||
| 1112 | if (dev) | 1144 | if (dev) |
| 1113 | rc = ata_scsi_dev_config(sdev, dev); | 1145 | return ata_scsi_dev_config(sdev, dev); |
| 1114 | 1146 | ||
| 1115 | return rc; | 1147 | return 0; |
| 1116 | } | 1148 | } |
| 1117 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); | 1149 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); |
| 1118 | 1150 | ||
| @@ -1136,6 +1168,8 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) · 17 unmodified lines | |||
| 1136 | unsigned long flags; | 1168 | unsigned long flags; |
| 1137 | struct ata_device *dev; | 1169 | struct ata_device *dev; |
| 1138 | 1170 | ||
| 1171 | device_link_remove(&sdev->sdev_gendev, &ap->tdev); | ||
| 1172 | |||
| 1139 | spin_lock_irqsave(ap->lock, flags); | 1173 | spin_lock_irqsave(ap->lock, flags); |
| 1140 | dev = __ata_scsi_find_dev(ap, sdev); | 1174 | dev = __ata_scsi_find_dev(ap, sdev); |
| 1141 | if (dev && dev->sdev) { | 1175 | if (dev && dev->sdev) { |
| @@ -1195,7 +1229,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) · 53 unmodified lines | |||
| 1195 | } | 1229 | } |
| 1196 | 1230 | ||
| 1197 | if (cdb[4] & 0x1) { | 1231 | if (cdb[4] & 0x1) { |
| 1198 | tf->nsect = 1; /* 1 sector, lba=0 */ | 1232 | tf->nsect = 1; /* 1 sector, lba=0 */ |
| 1199 | 1233 | ||
| 1200 | if (qc->dev->flags & ATA_DFLAG_LBA) { | 1234 | if (qc->dev->flags & ATA_DFLAG_LBA) { |
| 1201 | tf->flags |= ATA_TFLAG_LBA; | 1235 | tf->flags |= ATA_TFLAG_LBA; |
| @@ -1211,7 +1245,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) · 9 unmodified lines | |||
| 1211 | tf->lbah = 0x0; /* cyl high */ | 1245 | tf->lbah = 0x0; /* cyl high */ |
| 1212 | } | 1246 | } |
| 1213 | 1247 | ||
| 1214 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ | 1248 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ |
| 1215 | } else { | 1249 | } else { |
| 1216 | /* Some odd clown BIOSen issue spindown on power off (ACPI S4 | 1250 | /* Some odd clown BIOSen issue spindown on power off (ACPI S4 |
| 1217 | * or S5) causing some drives to spin up and down again. | 1251 | * or S5) causing some drives to spin up and down again. |
| @@ -1221,7 +1255,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) · 3 unmodified lines | |||
| 1221 | goto skip; | 1255 | goto skip; |
| 1222 | 1256 | ||
| 1223 | if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && | 1257 | if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && |
| 1224 | system_entering_hibernation()) | 1258 | system_entering_hibernation()) |
| 1225 | goto skip; | 1259 | goto skip; |
| 1226 | 1260 | ||
| 1227 | /* Issue ATA STANDBY IMMEDIATE command */ | 1261 | /* Issue ATA STANDBY IMMEDIATE command */ |
| @@ -1835,6 +1869,9 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) · 607 unmodified lines | |||
| 1835 | hdr[2] = 0x7; /* claim SPC-5 version compatibility */ | 1869 | hdr[2] = 0x7; /* claim SPC-5 version compatibility */ |
| 1836 | } | 1870 | } |
| 1837 | 1871 | ||
| 1872 | if (args->dev->flags & ATA_DFLAG_CDL) | ||
| 1873 | hdr[2] = 0xd; /* claim SPC-6 version compatibility */ | ||
| 1874 | |||
| 1838 | memcpy(rbuf, hdr, sizeof(hdr)); | 1875 | memcpy(rbuf, hdr, sizeof(hdr)); |
| 1839 | memcpy(&rbuf[8], "ATA ", 8); | 1876 | memcpy(&rbuf[8], "ATA ", 8); |
| 1840 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); | 1877 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); |
| @@ -4312,7 +4349,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) · 2471 unmodified lines | |||
| 4312 | break; | 4349 | break; |
| 4313 | 4350 | ||
| 4314 | case MAINTENANCE_IN: | 4351 | case MAINTENANCE_IN: |
| 4315 | if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES) | 4352 | if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) |
| 4316 | ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); | 4353 | ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); |
| 4317 | else | 4354 | else |
| 4318 | ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); | 4355 | ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); |
| @@ -4722,7 +4759,7 @@ void ata_scsi_dev_rescan(struct work_struct *work) · 403 unmodified lines | |||
| 4722 | struct ata_link *link; | 4759 | struct ata_link *link; |
| 4723 | struct ata_device *dev; | 4760 | struct ata_device *dev; |
| 4724 | unsigned long flags; | 4761 | unsigned long flags; |
| 4725 | bool delay_rescan = false; | 4762 | int ret = 0; |
| 4726 | 4763 | ||
| 4727 | mutex_lock(&ap->scsi_scan_mutex); | 4764 | mutex_lock(&ap->scsi_scan_mutex); |
| 4728 | spin_lock_irqsave(ap->lock, flags); | 4765 | spin_lock_irqsave(ap->lock, flags); |
| @@ -4731,37 +4768,34 @@ void ata_scsi_dev_rescan(struct work_struct *work) · 2 unmodified lines | |||
| 4731 | ata_for_each_dev(dev, link, ENABLED) { | 4768 | ata_for_each_dev(dev, link, ENABLED) { |
| 4732 | struct scsi_device *sdev = dev->sdev; | 4769 | struct scsi_device *sdev = dev->sdev; |
| 4733 | 4770 | ||
| 4771 | /* | ||
| 4772 | * If the port was suspended before this was scheduled, | ||
| 4773 | * bail out. | ||
| 4774 | */ | ||
| 4775 | if (ap->pflags & ATA_PFLAG_SUSPENDED) | ||
| 4776 | goto unlock; | ||
| 4777 | |||
| 4734 | if (!sdev) | 4778 | if (!sdev) |
| 4735 | continue; | 4779 | continue; |
| 4736 | if (scsi_device_get(sdev)) | 4780 | if (scsi_device_get(sdev)) |
| 4737 | continue; | 4781 | continue; |
| 4738 | 4782 | ||
| 4739 | /* | ||
| 4740 | * If the rescan work was scheduled because of a resume | ||
| 4741 | * event, the port is already fully resumed, but the | ||
| 4742 | * SCSI device may not yet be fully resumed. In such | ||
| 4743 | * case, executing scsi_rescan_device() may cause a | ||
| 4744 | * deadlock with the PM code on device_lock(). Prevent | ||
| 4745 | * this by giving up and retrying rescan after a short | ||
| 4746 | * delay. | ||
| 4747 | */ | ||
| 4748 | delay_rescan = sdev->sdev_gendev.power.is_suspended; | ||
| 4749 | if (delay_rescan) { | ||
| 4750 | scsi_device_put(sdev); | ||
| 4751 | break; | ||
| 4752 | } | ||
| 4753 | |||
| 4754 | spin_unlock_irqrestore(ap->lock, flags); | 4783 | spin_unlock_irqrestore(ap->lock, flags); |
| 4755 | scsi_rescan_device(sdev); | 4784 | ret = scsi_rescan_device(sdev); |
| 4756 | scsi_device_put(sdev); | 4785 | scsi_device_put(sdev); |
| 4757 | spin_lock_irqsave(ap->lock, flags); | 4786 | spin_lock_irqsave(ap->lock, flags); |
| 4787 | |||
| 4788 | if (ret) | ||
| 4789 | goto unlock; | ||
| 4758 | } | 4790 | } |
| 4759 | } | 4791 | } |
| 4760 | 4792 | ||
| 4793 | unlock: | ||
| 4761 | spin_unlock_irqrestore(ap->lock, flags); | 4794 | spin_unlock_irqrestore(ap->lock, flags); |
| 4762 | mutex_unlock(&ap->scsi_scan_mutex); | 4795 | mutex_unlock(&ap->scsi_scan_mutex); |
| 4763 | 4796 | ||
| 4764 | if (delay_rescan) | 4797 | /* Reschedule with a delay if scsi_rescan_device() returned an error */ |
| 4798 | if (ret) | ||
| 4765 | schedule_delayed_work(&ap->scsi_rescan_task, | 4799 | schedule_delayed_work(&ap->scsi_rescan_task, |
| 4766 | msecs_to_jiffies(5)); | 4800 | msecs_to_jiffies(5)); |
| 4767 | } | 4801 | } |
| @@ -266,6 +266,10 @@ void ata_tport_delete(struct ata_port *ap) · 265 unmodified lines | |||
| 266 | put_device(dev); | 266 | put_device(dev); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | static const struct device_type ata_port_sas_type = { | ||
| 270 | .name = ATA_PORT_TYPE_NAME, | ||
| 271 | }; | ||
| 272 | |||
| 269 | /** ata_tport_add - initialize a transport ATA port structure | 273 | /** ata_tport_add - initialize a transport ATA port structure |
| 270 | * | 274 | * |
| 271 | * @parent: parent device | 275 | * @parent: parent device |
| @@ -283,7 +287,10 @@ int ata_tport_add(struct device *parent, · 11 unmodified lines | |||
| 283 | struct device *dev = &ap->tdev; | 287 | struct device *dev = &ap->tdev; |
| 284 | 288 | ||
| 285 | device_initialize(dev); | 289 | device_initialize(dev); |
| 286 | dev->type = &ata_port_type; | 290 | if (ap->flags & ATA_FLAG_SAS_HOST) |
| 291 | dev->type = &ata_port_sas_type; | ||
| 292 | else | ||
| 293 | dev->type = &ata_port_type; | ||
| 287 | 294 | ||
| 288 | dev->parent = parent; | 295 | dev->parent = parent; |
| 289 | ata_host_get(ap->host); | 296 | ata_host_get(ap->host); |
| @@ -30,6 +30,8 @@ enum { · 29 unmodified lines | |||
| 30 | ATA_DNXFER_QUIET = (1 << 31), | 30 | ATA_DNXFER_QUIET = (1 << 31), |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | #define ATA_PORT_TYPE_NAME "ata_port" | ||
| 34 | |||
| 33 | extern atomic_t ata_print_id; | 35 | extern atomic_t ata_print_id; |
| 34 | extern int atapi_passthru16; | 36 | extern int atapi_passthru16; |
| 35 | extern int libata_fua; | 37 | extern int libata_fua; |
| @@ -60,6 +62,8 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags); · 24 unmodified lines | |||
| 60 | extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | 62 | extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, |
| 61 | unsigned int readid_flags); | 63 | unsigned int readid_flags); |
| 62 | extern int ata_dev_configure(struct ata_device *dev); | 64 | extern int ata_dev_configure(struct ata_device *dev); |
| 65 | extern void ata_dev_power_set_standby(struct ata_device *dev); | ||
| 66 | extern void ata_dev_power_set_active(struct ata_device *dev); | ||
| 63 | extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); | 67 | extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); |
| 64 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); | 68 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); |
| 65 | extern unsigned int ata_dev_set_feature(struct ata_device *dev, | 69 | extern unsigned int ata_dev_set_feature(struct ata_device *dev, |
| @@ -453,7 +453,8 @@ static int regcache_rbtree_write(struct regmap *map, unsigned int reg, · 452 unmodified lines | |||
| 453 | if (!rbnode) | 453 | if (!rbnode) |
| 454 | return -ENOMEM; | 454 | return -ENOMEM; |
| 455 | regcache_rbtree_set_register(map, rbnode, | 455 | regcache_rbtree_set_register(map, rbnode, |
| 456 | reg - rbnode->base_reg, value); | 456 | (reg - rbnode->base_reg) / map->reg_stride, |
| 457 | value); | ||
| 457 | regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); | 458 | regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); |
| 458 | rbtree_ctx->cached_rbnode = rbnode; | 459 | rbtree_ctx->cached_rbnode = rbnode; |
| 459 | } | 460 | } |
| @@ -632,9 +632,8 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...) · 631 unmodified lines | |||
| 632 | static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); | 632 | static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); |
| 633 | 633 | ||
| 634 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); | 634 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); |
| 635 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); | 635 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, |
| 636 | static int rbd_dev_header_info(struct rbd_device *rbd_dev); | 636 | struct rbd_image_header *header); |
| 637 | static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev); | ||
| 638 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, | 637 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, |
| 639 | u64 snap_id); | 638 | u64 snap_id); |
| 640 | static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, | 639 | static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, |
| @@ -995,15 +994,24 @@ static void rbd_init_layout(struct rbd_device *rbd_dev) · 354 unmodified lines | |||
| 995 | RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); | 994 | RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); |
| 996 | } | 995 | } |
| 997 | 996 | ||
| 997 | static void rbd_image_header_cleanup(struct rbd_image_header *header) | ||
| 998 | { | ||
| 999 | kfree(header->object_prefix); | ||
| 1000 | ceph_put_snap_context(header->snapc); | ||
| 1001 | kfree(header->snap_sizes); | ||
| 1002 | kfree(header->snap_names); | ||
| 1003 | |||
| 1004 | memset(header, 0, sizeof(*header)); | ||
| 1005 | } | ||
| 1006 | |||
| 998 | /* | 1007 | /* |
| 999 | * Fill an rbd image header with information from the given format 1 | 1008 | * Fill an rbd image header with information from the given format 1 |
| 1000 | * on-disk header. | 1009 | * on-disk header. |
| 1001 | */ | 1010 | */ |
| 1002 | static int rbd_header_from_disk(struct rbd_device *rbd_dev, | 1011 | static int rbd_header_from_disk(struct rbd_image_header *header, |
| 1003 | struct rbd_image_header_ondisk *ondisk) | 1012 | struct rbd_image_header_ondisk *ondisk, |
| 1013 | bool first_time) | ||
| 1004 | { | 1014 | { |
| 1005 | struct rbd_image_header *header = &rbd_dev->header; | ||
| 1006 | bool first_time = header->object_prefix == NULL; | ||
| 1007 | struct ceph_snap_context *snapc; | 1015 | struct ceph_snap_context *snapc; |
| 1008 | char *object_prefix = NULL; | 1016 | char *object_prefix = NULL; |
| 1009 | char *snap_names = NULL; | 1017 | char *snap_names = NULL; |
| @@ -1070,11 +1078,6 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev, · 60 unmodified lines | |||
| 1070 | if (first_time) { | 1078 | if (first_time) { |
| 1071 | header->object_prefix = object_prefix; | 1079 | header->object_prefix = object_prefix; |
| 1072 | header->obj_order = ondisk->options.order; | 1080 | header->obj_order = ondisk->options.order; |
| 1073 | rbd_init_layout(rbd_dev); | ||
| 1074 | } else { | ||
| 1075 | ceph_put_snap_context(header->snapc); | ||
| 1076 | kfree(header->snap_names); | ||
| 1077 | kfree(header->snap_sizes); | ||
| 1078 | } | 1081 | } |
| 1079 | 1082 | ||
| 1080 | /* The remaining fields always get updated (when we refresh) */ | 1083 | /* The remaining fields always get updated (when we refresh) */ |
| @@ -4859,7 +4862,9 @@ out_req: · 3778 unmodified lines | |||
| 4859 | * return, the rbd_dev->header field will contain up-to-date | 4862 | * return, the rbd_dev->header field will contain up-to-date |
| 4860 | * information about the image. | 4863 | * information about the image. |
| 4861 | */ | 4864 | */ |
| 4862 | static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) | 4865 | static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev, |
| 4866 | struct rbd_image_header *header, | ||
| 4867 | bool first_time) | ||
| 4863 | { | 4868 | { |
| 4864 | struct rbd_image_header_ondisk *ondisk = NULL; | 4869 | struct rbd_image_header_ondisk *ondisk = NULL; |
| 4865 | u32 snap_count = 0; | 4870 | u32 snap_count = 0; |
| @@ -4907,7 +4912,7 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) · 41 unmodified lines | |||
| 4907 | snap_count = le32_to_cpu(ondisk->snap_count); | 4912 | snap_count = le32_to_cpu(ondisk->snap_count); |
| 4908 | } while (snap_count != want_count); | 4913 | } while (snap_count != want_count); |
| 4909 | 4914 | ||
| 4910 | ret = rbd_header_from_disk(rbd_dev, ondisk); | 4915 | ret = rbd_header_from_disk(header, ondisk, first_time); |
| 4911 | out: | 4916 | out: |
| 4912 | kfree(ondisk); | 4917 | kfree(ondisk); |
| 4913 | 4918 | ||
| @@ -4931,39 +4936,6 @@ static void rbd_dev_update_size(struct rbd_device *rbd_dev) · 17 unmodified lines | |||
| 4931 | } | 4936 | } |
| 4932 | } | 4937 | } |
| 4933 | 4938 | ||
| 4934 | static int rbd_dev_refresh(struct rbd_device *rbd_dev) | ||
| 4935 | { | ||
| 4936 | u64 mapping_size; | ||
| 4937 | int ret; | ||
| 4938 | |||
| 4939 | down_write(&rbd_dev->header_rwsem); | ||
| 4940 | mapping_size = rbd_dev->mapping.size; | ||
| 4941 | |||
| 4942 | ret = rbd_dev_header_info(rbd_dev); | ||
| 4943 | if (ret) | ||
| 4944 | goto out; | ||
| 4945 | |||
| 4946 | /* | ||
| 4947 | * If there is a parent, see if it has disappeared due to the | ||
| 4948 | * mapped image getting flattened. | ||
| 4949 | */ | ||
| 4950 | if (rbd_dev->parent) { | ||
| 4951 | ret = rbd_dev_v2_parent_info(rbd_dev); | ||
| 4952 | if (ret) | ||
| 4953 | goto out; | ||
| 4954 | } | ||
| 4955 | |||
| 4956 | rbd_assert(!rbd_is_snap(rbd_dev)); | ||
| 4957 | rbd_dev->mapping.size = rbd_dev->header.image_size; | ||
| 4958 | |||
| 4959 | out: | ||
| 4960 | up_write(&rbd_dev->header_rwsem); | ||
| 4961 | if (!ret && mapping_size != rbd_dev->mapping.size) | ||
| 4962 | rbd_dev_update_size(rbd_dev); | ||
| 4963 | |||
| 4964 | return ret; | ||
| 4965 | } | ||
| 4966 | |||
| 4967 | static const struct blk_mq_ops rbd_mq_ops = { | 4939 | static const struct blk_mq_ops rbd_mq_ops = { |
| 4968 | .queue_rq = rbd_queue_rq, | 4940 | .queue_rq = rbd_queue_rq, |
| 4969 | }; | 4941 | }; |
| @@ -5503,17 +5475,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, · 533 unmodified lines | |||
| 5503 | return 0; | 5475 | return 0; |
| 5504 | } | 5476 | } |
| 5505 | 5477 | ||
| 5506 | static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) | 5478 | static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev, |
| 5507 | { | 5479 | char **pobject_prefix) |
| 5508 | return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, | ||
| 5509 | &rbd_dev->header.obj_order, | ||
| 5510 | &rbd_dev->header.image_size); | ||
| 5511 | } | ||
| 5512 | |||
| 5513 | static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) | ||
| 5514 | { | 5480 | { |
| 5515 | size_t size; | 5481 | size_t size; |
| 5516 | void *reply_buf; | 5482 | void *reply_buf; |
| 5483 | char *object_prefix; | ||
| 5517 | int ret; | 5484 | int ret; |
| 5518 | void *p; | 5485 | void *p; |
| 5519 | 5486 | ||
| @@ -5531,16 +5498,16 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) · 11 unmodified lines | |||
| 5531 | goto out; | 5498 | goto out; |
| 5532 | 5499 | ||
| 5533 | p = reply_buf; | 5500 | p = reply_buf; |
| 5534 | rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, | 5501 | object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL, |
| 5535 | p + ret, NULL, GFP_NOIO); | 5502 | GFP_NOIO); |
| 5503 | if (IS_ERR(object_prefix)) { | ||
| 5504 | ret = PTR_ERR(object_prefix); | ||
| 5505 | goto out; | ||
| 5506 | } | ||
| 5536 | ret = 0; | 5507 | ret = 0; |
| 5537 | 5508 | ||
| 5538 | if (IS_ERR(rbd_dev->header.object_prefix)) { | 5509 | *pobject_prefix = object_prefix; |
| 5539 | ret = PTR_ERR(rbd_dev->header.object_prefix); | 5510 | dout(" object_prefix = %s\n", object_prefix); |
| 5540 | rbd_dev->header.object_prefix = NULL; | ||
| 5541 | } else { | ||
| 5542 | dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); | ||
| 5543 | } | ||
| 5544 | out: | 5511 | out: |
| 5545 | kfree(reply_buf); | 5512 | kfree(reply_buf); |
| 5546 | 5513 | ||
| @@ -5591,13 +5558,6 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, · 44 unmodified lines | |||
| 5591 | return 0; | 5558 | return 0; |
| 5592 | } | 5559 | } |
| 5593 | 5560 | ||
| 5594 | static int rbd_dev_v2_features(struct rbd_device *rbd_dev) | ||
| 5595 | { | ||
| 5596 | return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, | ||
| 5597 | rbd_is_ro(rbd_dev), | ||
| 5598 | &rbd_dev->header.features); | ||
| 5599 | } | ||
| 5600 | |||
| 5601 | /* | 5561 | /* |
| 5602 | * These are generic image flags, but since they are used only for | 5562 | * These are generic image flags, but since they are used only for |
| 5603 | * object map, store them in rbd_dev->object_map_flags. | 5563 | * object map, store them in rbd_dev->object_map_flags. |
| @@ -5634,6 +5594,14 @@ struct parent_image_info { · 30 unmodified lines | |||
| 5634 | u64 overlap; | 5594 | u64 overlap; |
| 5635 | }; | 5595 | }; |
| 5636 | 5596 | ||
| 5597 | static void rbd_parent_info_cleanup(struct parent_image_info *pii) | ||
| 5598 | { | ||
| 5599 | kfree(pii->pool_ns); | ||
| 5600 | kfree(pii->image_id); | ||
| 5601 | |||
| 5602 | memset(pii, 0, sizeof(*pii)); | ||
| 5603 | } | ||
| 5604 | |||
| 5637 | /* | 5605 | /* |
| 5638 | * The caller is responsible for @pii. | 5606 | * The caller is responsible for @pii. |
| 5639 | */ | 5607 | */ |
| @@ -5703,6 +5671,9 @@ static int __get_parent_info(struct rbd_device *rbd_dev, · 63 unmodified lines | |||
| 5703 | if (pii->has_overlap) | 5671 | if (pii->has_overlap) |
| 5704 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); | 5672 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); |
| 5705 | 5673 | ||
| 5674 | dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", | ||
| 5675 | __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, | ||
| 5676 | pii->has_overlap, pii->overlap); | ||
| 5706 | return 0; | 5677 | return 0; |
| 5707 | 5678 | ||
| 5708 | e_inval: | 5679 | e_inval: |
| @@ -5741,14 +5712,17 @@ static int __get_parent_info_legacy(struct rbd_device *rbd_dev, · 32 unmodified lines | |||
| 5741 | pii->has_overlap = true; | 5712 | pii->has_overlap = true; |
| 5742 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); | 5713 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); |
| 5743 | 5714 | ||
| 5715 | dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", | ||
| 5716 | __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, | ||
| 5717 | pii->has_overlap, pii->overlap); | ||
| 5744 | return 0; | 5718 | return 0; |
| 5745 | 5719 | ||
| 5746 | e_inval: | 5720 | e_inval: |
| 5747 | return -EINVAL; | 5721 | return -EINVAL; |
| 5748 | } | 5722 | } |
| 5749 | 5723 | ||
| 5750 | static int get_parent_info(struct rbd_device *rbd_dev, | 5724 | static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev, |
| 5751 | struct parent_image_info *pii) | 5725 | struct parent_image_info *pii) |
| 5752 | { | 5726 | { |
| 5753 | struct page *req_page, *reply_page; | 5727 | struct page *req_page, *reply_page; |
| 5754 | void *p; | 5728 | void *p; |
| @@ -5776,7 +5750,7 @@ static int get_parent_info(struct rbd_device *rbd_dev, · 21 unmodified lines | |||
| 5776 | return ret; | 5750 | return ret; |
| 5777 | } | 5751 | } |
| 5778 | 5752 | ||
| 5779 | static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) | 5753 | static int rbd_dev_setup_parent(struct rbd_device *rbd_dev) |
| 5780 | { | 5754 | { |
| 5781 | struct rbd_spec *parent_spec; | 5755 | struct rbd_spec *parent_spec; |
| 5782 | struct parent_image_info pii = { 0 }; | 5756 | struct parent_image_info pii = { 0 }; |
| @@ -5786,37 +5760,12 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) · 3 unmodified lines | |||
| 5786 | if (!parent_spec) | 5760 | if (!parent_spec) |
| 5787 | return -ENOMEM; | 5761 | return -ENOMEM; |
| 5788 | 5762 | ||
| 5789 | ret = get_parent_info(rbd_dev, &pii); | 5763 | ret = rbd_dev_v2_parent_info(rbd_dev, &pii); |
| 5790 | if (ret) | 5764 | if (ret) |
| 5791 | goto out_err; | 5765 | goto out_err; |
| 5792 | 5766 | ||
| 5793 | dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", | 5767 | if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) |
| 5794 | __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id, | ||
| 5795 | pii.has_overlap, pii.overlap); | ||
| 5796 | |||
| 5797 | if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) { | ||
| 5798 | /* | ||
| 5799 | * Either the parent never existed, or we have | ||
| 5800 | * record of it but the image got flattened so it no | ||
| 5801 | * longer has a parent. When the parent of a | ||
| 5802 | * layered image disappears we immediately set the | ||
| 5803 | * overlap to 0. The effect of this is that all new | ||
| 5804 | * requests will be treated as if the image had no | ||
| 5805 | * parent. | ||
| 5806 | * | ||
| 5807 | * If !pii.has_overlap, the parent image spec is not | ||
| 5808 | * applicable. It's there to avoid duplication in each | ||
| 5809 | * snapshot record. | ||
| 5810 | */ | ||
| 5811 | if (rbd_dev->parent_overlap) { | ||
| 5812 | rbd_dev->parent_overlap = 0; | ||
| 5813 | rbd_dev_parent_put(rbd_dev); | ||
| 5814 | pr_info("%s: clone image has been flattened\n", | ||
| 5815 | rbd_dev->disk->disk_name); | ||
| 5816 | } | ||
| 5817 | |||
| 5818 | goto out; /* No parent? No problem. */ | 5768 | goto out; /* No parent? No problem. */ |
| 5819 | } | ||
| 5820 | 5769 | ||
| 5821 | /* The ceph file layout needs to fit pool id in 32 bits */ | 5770 | /* The ceph file layout needs to fit pool id in 32 bits */ |
| 5822 | 5771 | ||
| @@ -5828,58 +5777,46 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) · 5 unmodified lines | |||
| 5828 | } | 5777 | } |
| 5829 | 5778 | ||
| 5830 | /* | 5779 | /* |
| 5831 | * The parent won't change (except when the clone is | 5780 | * The parent won't change except when the clone is flattened, |
| 5832 | * flattened, already handled that). So we only need to | 5781 | * so we only need to record the parent image spec once. |
| 5833 | * record the parent spec we have not already done so. | ||
| 5834 | */ | 5782 | */ |
| 5835 | if (!rbd_dev->parent_spec) { | 5783 | parent_spec->pool_id = pii.pool_id; |
| 5836 | parent_spec->pool_id = pii.pool_id; | 5784 | if (pii.pool_ns && *pii.pool_ns) { |
| 5837 | if (pii.pool_ns && *pii.pool_ns) { | 5785 | parent_spec->pool_ns = pii.pool_ns; |
| 5838 | parent_spec->pool_ns = pii.pool_ns; | 5786 | pii.pool_ns = NULL; |
| 5839 | pii.pool_ns = NULL; | ||
| 5840 | } | ||
| 5841 | parent_spec->image_id = pii.image_id; | ||
| 5842 | pii.image_id = NULL; | ||
| 5843 | parent_spec->snap_id = pii.snap_id; | ||
| 5844 | |||
| 5845 | rbd_dev->parent_spec = parent_spec; | ||
| 5846 | parent_spec = NULL; /* rbd_dev now owns this */ | ||
| 5847 | } | 5787 | } |
| 5788 | parent_spec->image_id = pii.image_id; | ||
| 5789 | pii.image_id = NULL; | ||
| 5790 | parent_spec->snap_id = pii.snap_id; | ||
| 5791 | |||
| 5792 | rbd_assert(!rbd_dev->parent_spec); | ||
| 5793 | rbd_dev->parent_spec = parent_spec; | ||
| 5794 | parent_spec = NULL; /* rbd_dev now owns this */ | ||
| 5848 | 5795 | ||
| 5849 | /* | 5796 | /* |
| 5850 | * We always update the parent overlap. If it's zero we issue | 5797 | * Record the parent overlap. If it's zero, issue a warning as |
| 5851 | * a warning, as we will proceed as if there was no parent. | 5798 | * we will proceed as if there is no parent. |
| 5852 | */ | 5799 | */ |
| 5853 | if (!pii.overlap) { | 5800 | if (!pii.overlap) |
| 5854 | if (parent_spec) { | 5801 | rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); |
| 5855 | /* refresh, careful to warn just once */ | ||
| 5856 | if (rbd_dev->parent_overlap) | ||
| 5857 | rbd_warn(rbd_dev, | ||
| 5858 | "clone now standalone (overlap became 0)"); | ||
| 5859 | } else { | ||
| 5860 | /* initial probe */ | ||
| 5861 | rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); | ||
| 5862 | } | ||
| 5863 | } | ||
| 5864 | rbd_dev->parent_overlap = pii.overlap; | 5802 | rbd_dev->parent_overlap = pii.overlap; |
| 5865 | 5803 | ||
| 5866 | out: | 5804 | out: |
| 5867 | ret = 0; | 5805 | ret = 0; |
| 5868 | out_err: | 5806 | out_err: |
| 5869 | kfree(pii.pool_ns); | 5807 | rbd_parent_info_cleanup(&pii); |
| 5870 | kfree(pii.image_id); | ||
| 5871 | rbd_spec_put(parent_spec); | 5808 | rbd_spec_put(parent_spec); |
| 5872 | return ret; | 5809 | return ret; |
| 5873 | } | 5810 | } |
| 5874 | 5811 | ||
| 5875 | static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) | 5812 | static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev, |
| 5813 | u64 *stripe_unit, u64 *stripe_count) | ||
| 5876 | { | 5814 | { |
| 5877 | struct { | 5815 | struct { |
| 5878 | __le64 stripe_unit; | 5816 | __le64 stripe_unit; |
| 5879 | __le64 stripe_count; | 5817 | __le64 stripe_count; |
| 5880 | } __attribute__ ((packed)) striping_info_buf = { 0 }; | 5818 | } __attribute__ ((packed)) striping_info_buf = { 0 }; |
| 5881 | size_t size = sizeof (striping_info_buf); | 5819 | size_t size = sizeof (striping_info_buf); |
| 5882 | void *p; | ||
| 5883 | int ret; | 5820 | int ret; |
| 5884 | 5821 | ||
| 5885 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, | 5822 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, |
| @@ -5891,27 +5828,33 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) · 5 unmodified lines | |||
| 5891 | if (ret < size) | 5828 | if (ret < size) |
| 5892 | return -ERANGE; | 5829 | return -ERANGE; |
| 5893 | 5830 | ||
| 5894 | p = &striping_info_buf; | 5831 | *stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit); |
| 5895 | rbd_dev->header.stripe_unit = ceph_decode_64(&p); | 5832 | *stripe_count = le64_to_cpu(striping_info_buf.stripe_count); |
| 5896 | rbd_dev->header.stripe_count = ceph_decode_64(&p); | 5833 | dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit, |
| 5834 | *stripe_count); | ||
| 5835 | |||
| 5897 | return 0; | 5836 | return 0; |
| 5898 | } | 5837 | } |
| 5899 | 5838 | ||
| 5900 | static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) | 5839 | static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id) |
| 5901 | { | 5840 | { |
| 5902 | __le64 data_pool_id; | 5841 | __le64 data_pool_buf; |
| 5903 | int ret; | 5842 | int ret; |
| 5904 | 5843 | ||
| 5905 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, | 5844 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, |
| 5906 | &rbd_dev->header_oloc, "get_data_pool", | 5845 | &rbd_dev->header_oloc, "get_data_pool", |
| 5907 | NULL, 0, &data_pool_id, sizeof(data_pool_id)); | 5846 | NULL, 0, &data_pool_buf, |
| 5847 | sizeof(data_pool_buf)); | ||
| 5848 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); | ||
| 5908 | if (ret < 0) | 5849 | if (ret < 0) |
| 5909 | return ret; | 5850 | return ret; |
| 5910 | if (ret < sizeof(data_pool_id)) | 5851 | if (ret < sizeof(data_pool_buf)) |
| 5911 | return -EBADMSG; | 5852 | return -EBADMSG; |
| 5912 | 5853 | ||
| 5913 | rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); | 5854 | *data_pool_id = le64_to_cpu(data_pool_buf); |
| 5914 | WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); | 5855 | dout(" data_pool_id = %lld\n", *data_pool_id); |
| 5856 | WARN_ON(*data_pool_id == CEPH_NOPOOL); | ||
| 5857 | |||
| 5915 | return 0; | 5858 | return 0; |
| 5916 | } | 5859 | } |
| 5917 | 5860 | ||
| @@ -6103,7 +6046,8 @@ out_err: · 185 unmodified lines | |||
| 6103 | return ret; | 6046 | return ret; |
| 6104 | } | 6047 | } |
| 6105 | 6048 | ||
| 6106 | static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) | 6049 | static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, |
| 6050 | struct ceph_snap_context **psnapc) | ||
| 6107 | { | 6051 | { |
| 6108 | size_t size; | 6052 | size_t size; |
| 6109 | int ret; | 6053 | int ret; |
| @@ -6164,9 +6108,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) · 54 unmodified lines | |||
| 6164 | for (i = 0; i < snap_count; i++) | 6108 | for (i = 0; i < snap_count; i++) |
| 6165 | snapc->snaps[i] = ceph_decode_64(&p); | 6109 | snapc->snaps[i] = ceph_decode_64(&p); |
| 6166 | 6110 | ||
| 6167 | ceph_put_snap_context(rbd_dev->header.snapc); | 6111 | *psnapc = snapc; |
| 6168 | rbd_dev->header.snapc = snapc; | ||
| 6169 | |||
| 6170 | dout(" snap context seq = %llu, snap_count = %u\n", | 6112 | dout(" snap context seq = %llu, snap_count = %u\n", |
| 6171 | (unsigned long long)seq, (unsigned int)snap_count); | 6113 | (unsigned long long)seq, (unsigned int)snap_count); |
| 6172 | out: | 6114 | out: |
| @@ -6215,38 +6157,42 @@ out: · 42 unmodified lines | |||
| 6215 | return snap_name; | 6157 | return snap_name; |
| 6216 | } | 6158 | } |
| 6217 | 6159 | ||
| 6218 | static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) | 6160 | static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev, |
| 6161 | struct rbd_image_header *header, | ||
| 6162 | bool first_time) | ||
| 6219 | { | 6163 | { |
| 6220 | bool first_time = rbd_dev->header.object_prefix == NULL; | ||
| 6221 | int ret; | 6164 | int ret; |
| 6222 | 6165 | ||
| 6223 | ret = rbd_dev_v2_image_size(rbd_dev); | 6166 | ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, |
| 6167 | first_time ? &header->obj_order : NULL, | ||
| 6168 | &header->image_size); | ||
| 6224 | if (ret) | 6169 | if (ret) |
| 6225 | return ret; | 6170 | return ret; |
| 6226 | 6171 | ||
| 6227 | if (first_time) { | 6172 | if (first_time) { |
| 6228 | ret = rbd_dev_v2_header_onetime(rbd_dev); | 6173 | ret = rbd_dev_v2_header_onetime(rbd_dev, header); |
| 6229 | if (ret) | 6174 | if (ret) |
| 6230 | return ret; | 6175 | return ret; |
| 6231 | } | 6176 | } |
| 6232 | 6177 | ||
| 6233 | ret = rbd_dev_v2_snap_context(rbd_dev); | 6178 | ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); |
| 6234 | if (ret && first_time) { | 6179 | if (ret) |
| 6235 | kfree(rbd_dev->header.object_prefix); | 6180 | return ret; |
| 6236 | rbd_dev->header.object_prefix = NULL; | ||
| 6237 | } | ||
| 6238 | 6181 | ||
| 6239 | return ret; | 6182 | return 0; |
| 6240 | } | 6183 | } |
| 6241 | 6184 | ||
| 6242 | static int rbd_dev_header_info(struct rbd_device *rbd_dev) | 6185 | static int rbd_dev_header_info(struct rbd_device *rbd_dev, |
| 6186 | struct rbd_image_header *header, | ||
| 6187 | bool first_time) | ||
| 6243 | { | 6188 | { |
| 6244 | rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); | 6189 | rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); |
| 6190 | rbd_assert(!header->object_prefix && !header->snapc); | ||
| 6245 | 6191 | ||
| 6246 | if (rbd_dev->image_format == 1) | 6192 | if (rbd_dev->image_format == 1) |
| 6247 | return rbd_dev_v1_header_info(rbd_dev); | 6193 | return rbd_dev_v1_header_info(rbd_dev, header, first_time); |
| 6248 | 6194 | ||
| 6249 | return rbd_dev_v2_header_info(rbd_dev); | 6195 | return rbd_dev_v2_header_info(rbd_dev, header, first_time); |
| 6250 | } | 6196 | } |
| 6251 | 6197 | ||
| 6252 | /* | 6198 | /* |
| @@ -6734,60 +6680,49 @@ out: · 481 unmodified lines | |||
| 6734 | */ | 6680 | */ |
| 6735 | static void rbd_dev_unprobe(struct rbd_device *rbd_dev) | 6681 | static void rbd_dev_unprobe(struct rbd_device *rbd_dev) |
| 6736 | { | 6682 | { |
| 6737 | struct rbd_image_header *header; | ||
| 6738 | |||
| 6739 | rbd_dev_parent_put(rbd_dev); | 6683 | rbd_dev_parent_put(rbd_dev); |
| 6740 | rbd_object_map_free(rbd_dev); | 6684 | rbd_object_map_free(rbd_dev); |
| 6741 | rbd_dev_mapping_clear(rbd_dev); | 6685 | rbd_dev_mapping_clear(rbd_dev); |
| 6742 | 6686 | ||
| 6743 | /* Free dynamic fields from the header, then zero it out */ | 6687 | /* Free dynamic fields from the header, then zero it out */ |
| 6744 | 6688 | ||
| 6745 | header = &rbd_dev->header; | 6689 | rbd_image_header_cleanup(&rbd_dev->header); |
| 6746 | ceph_put_snap_context(header->snapc); | ||
| 6747 | kfree(header->snap_sizes); | ||
| 6748 | kfree(header->snap_names); | ||
| 6749 | kfree(header->object_prefix); | ||
| 6750 | memset(header, 0, sizeof (*header)); | ||
| 6751 | } | 6690 | } |
| 6752 | 6691 | ||
| 6753 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) | 6692 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, |
| 6693 | struct rbd_image_header *header) | ||
| 6754 | { | 6694 | { |
| 6755 | int ret; | 6695 | int ret; |
| 6756 | 6696 | ||
| 6757 | ret = rbd_dev_v2_object_prefix(rbd_dev); | 6697 | ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); |
| 6758 | if (ret) | 6698 | if (ret) |
| 6759 | goto out_err; | 6699 | return ret; |
| 6760 | 6700 | ||
| 6761 | /* | 6701 | /* |
| 6762 | * Get the and check features for the image. Currently the | 6702 | * Get the and check features for the image. Currently the |
| 6763 | * features are assumed to never change. | 6703 | * features are assumed to never change. |
| 6764 | */ | 6704 | */ |
| 6765 | ret = rbd_dev_v2_features(rbd_dev); | 6705 | ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, |
| 6706 | rbd_is_ro(rbd_dev), &header->features); | ||
| 6766 | if (ret) | 6707 | if (ret) |
| 6767 | goto out_err; | 6708 | return ret; |
| 6768 | 6709 | ||
| 6769 | /* If the image supports fancy striping, get its parameters */ | 6710 | /* If the image supports fancy striping, get its parameters */ |
| 6770 | 6711 | ||
| 6771 | if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { | 6712 | if (header->features & RBD_FEATURE_STRIPINGV2) { |
| 6772 | ret = rbd_dev_v2_striping_info(rbd_dev); | 6713 | ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, |
| 6773 | if (ret < 0) | 6714 | &header->stripe_count); |
| 6774 | goto out_err; | 6715 | if (ret) |
| 6716 | return ret; | ||
| 6775 | } | 6717 | } |
| 6776 | 6718 | ||
| 6777 | if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { | 6719 | if (header->features & RBD_FEATURE_DATA_POOL) { |
| 6778 | ret = rbd_dev_v2_data_pool(rbd_dev); | 6720 | ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); |
| 6779 | if (ret) | 6721 | if (ret) |
| 6780 | goto out_err; | 6722 | return ret; |
| 6781 | } | 6723 | } |
| 6782 | 6724 | ||
| 6783 | rbd_init_layout(rbd_dev); | ||
| 6784 | return 0; | 6725 | return 0; |
| 6785 | |||
| 6786 | out_err: | ||
| 6787 | rbd_dev->header.features = 0; | ||
| 6788 | kfree(rbd_dev->header.object_prefix); | ||
| 6789 | rbd_dev->header.object_prefix = NULL; | ||
| 6790 | return ret; | ||
| 6791 | } | 6726 | } |
| 6792 | 6727 | ||
| 6793 | /* | 6728 | /* |
| @@ -6982,13 +6917,15 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) · 188 unmodified lines | |||
| 6982 | if (!depth) | 6917 | if (!depth) |
| 6983 | down_write(&rbd_dev->header_rwsem); | 6918 | down_write(&rbd_dev->header_rwsem); |
| 6984 | 6919 | ||
| 6985 | ret = rbd_dev_header_info(rbd_dev); | 6920 | ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); |
| 6986 | if (ret) { | 6921 | if (ret) { |
| 6987 | if (ret == -ENOENT && !need_watch) | 6922 | if (ret == -ENOENT && !need_watch) |
| 6988 | rbd_print_dne(rbd_dev, false); | 6923 | rbd_print_dne(rbd_dev, false); |
| 6989 | goto err_out_probe; | 6924 | goto err_out_probe; |
| 6990 | } | 6925 | } |
| 6991 | 6926 | ||
| 6927 | rbd_init_layout(rbd_dev); | ||
| 6928 | |||
| 6992 | /* | 6929 | /* |
| 6993 | * If this image is the one being mapped, we have pool name and | 6930 | * If this image is the one being mapped, we have pool name and |
| 6994 | * id, image name and id, and snap name - need to fill snap id. | 6931 | * id, image name and id, and snap name - need to fill snap id. |
| @@ -7017,7 +6954,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) · 22 unmodified lines | |||
| 7017 | } | 6954 | } |
| 7018 | 6955 | ||
| 7019 | if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { | 6956 | if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { |
| 7020 | ret = rbd_dev_v2_parent_info(rbd_dev); | 6957 | ret = rbd_dev_setup_parent(rbd_dev); |
| 7021 | if (ret) | 6958 | if (ret) |
| 7022 | goto err_out_probe; | 6959 | goto err_out_probe; |
| 7023 | } | 6960 | } |
| @@ -7043,6 +6980,107 @@ err_out_format: · 19 unmodified lines | |||
| 7043 | return ret; | 6980 | return ret; |
| 7044 | } | 6981 | } |
| 7045 | 6982 | ||
| 6983 | static void rbd_dev_update_header(struct rbd_device *rbd_dev, | ||
| 6984 | struct rbd_image_header *header) | ||
| 6985 | { | ||
| 6986 | rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); | ||
| 6987 | rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ | ||
| 6988 | |||
| 6989 | if (rbd_dev->header.image_size != header->image_size) { | ||
| 6990 | rbd_dev->header.image_size = header->image_size; | ||
| 6991 | |||
| 6992 | if (!rbd_is_snap(rbd_dev)) { | ||
| 6993 | rbd_dev->mapping.size = header->image_size; | ||
| 6994 | rbd_dev_update_size(rbd_dev); | ||
| 6995 | } | ||
| 6996 | } | ||
| 6997 | |||
| 6998 | ceph_put_snap_context(rbd_dev->header.snapc); | ||
| 6999 | rbd_dev->header.snapc = header->snapc; | ||
| 7000 | header->snapc = NULL; | ||
| 7001 | |||
| 7002 | if (rbd_dev->image_format == 1) { | ||
| 7003 | kfree(rbd_dev->header.snap_names); | ||
| 7004 | rbd_dev->header.snap_names = header->snap_names; | ||
| 7005 | header->snap_names = NULL; | ||
| 7006 | |||
| 7007 | kfree(rbd_dev->header.snap_sizes); | ||
| 7008 | rbd_dev->header.snap_sizes = header->snap_sizes; | ||
| 7009 | header->snap_sizes = NULL; | ||
| 7010 | } | ||
| 7011 | } | ||
| 7012 | |||
| 7013 | static void rbd_dev_update_parent(struct rbd_device *rbd_dev, | ||
| 7014 | struct parent_image_info *pii) | ||
| 7015 | { | ||
| 7016 | if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) { | ||
| 7017 | /* | ||
| 7018 | * Either the parent never existed, or we have | ||
| 7019 | * record of it but the image got flattened so it no | ||
| 7020 | * longer has a parent. When the parent of a | ||
| 7021 | * layered image disappears we immediately set the | ||
| 7022 | * overlap to 0. The effect of this is that all new | ||
| 7023 | * requests will be treated as if the image had no | ||
| 7024 | * parent. | ||
| 7025 | * | ||
| 7026 | * If !pii.has_overlap, the parent image spec is not | ||
| 7027 | * applicable. It's there to avoid duplication in each | ||
| 7028 | * snapshot record. | ||
| 7029 | */ | ||
| 7030 | if (rbd_dev->parent_overlap) { | ||
| 7031 | rbd_dev->parent_overlap = 0; | ||
| 7032 | rbd_dev_parent_put(rbd_dev); | ||
| 7033 | pr_info("%s: clone has been flattened\n", | ||
| 7034 | rbd_dev->disk->disk_name); | ||
| 7035 | } | ||
| 7036 | } else { | ||
| 7037 | rbd_assert(rbd_dev->parent_spec); | ||
| 7038 | |||
| 7039 | /* | ||
| 7040 | * Update the parent overlap. If it became zero, issue | ||
| 7041 | * a warning as we will proceed as if there is no parent. | ||
| 7042 | */ | ||
| 7043 | if (!pii->overlap && rbd_dev->parent_overlap) | ||
| 7044 | rbd_warn(rbd_dev, | ||
| 7045 | "clone has become standalone (overlap 0)"); | ||
| 7046 | rbd_dev->parent_overlap = pii->overlap; | ||
| 7047 | } | ||
| 7048 | } | ||
| 7049 | |||
| 7050 | static int rbd_dev_refresh(struct rbd_device *rbd_dev) | ||
| 7051 | { | ||
| 7052 | struct rbd_image_header header = { 0 }; | ||
| 7053 | struct parent_image_info pii = { 0 }; | ||
| 7054 | int ret; | ||
| 7055 | |||
| 7056 | dout("%s rbd_dev %p\n", __func__, rbd_dev); | ||
| 7057 | |||
| 7058 | ret = rbd_dev_header_info(rbd_dev, &header, false); | ||
| 7059 | if (ret) | ||
| 7060 | goto out; | ||
| 7061 | |||
| 7062 | /* | ||
| 7063 | * If there is a parent, see if it has disappeared due to the | ||
| 7064 | * mapped image getting flattened. | ||
| 7065 | */ | ||
| 7066 | if (rbd_dev->parent) { | ||
| 7067 | ret = rbd_dev_v2_parent_info(rbd_dev, &pii); | ||
| 7068 | if (ret) | ||
| 7069 | goto out; | ||
| 7070 | } | ||
| 7071 | |||
| 7072 | down_write(&rbd_dev->header_rwsem); | ||
| 7073 | rbd_dev_update_header(rbd_dev, &header); | ||
| 7074 | if (rbd_dev->parent) | ||
| 7075 | rbd_dev_update_parent(rbd_dev, &pii); | ||
| 7076 | up_write(&rbd_dev->header_rwsem); | ||
| 7077 | |||
| 7078 | out: | ||
| 7079 | rbd_parent_info_cleanup(&pii); | ||
| 7080 | rbd_image_header_cleanup(&header); | ||
| 7081 | return ret; | ||
| 7082 | } | ||
| 7083 | |||
| 7046 | static ssize_t do_rbd_add(const char *buf, size_t count) | 7084 | static ssize_t do_rbd_add(const char *buf, size_t count) |
| 7047 | { | 7085 | { |
| 7048 | struct rbd_device *rbd_dev = NULL; | 7086 | struct rbd_device *rbd_dev = NULL; |
| @@ -4419,6 +4419,7 @@ static int btusb_probe(struct usb_interface *intf, · 4418 unmodified lines | |||
| 4419 | 4419 | ||
| 4420 | if (id->driver_info & BTUSB_QCA_ROME) { | 4420 | if (id->driver_info & BTUSB_QCA_ROME) { |
| 4421 | data->setup_on_usb = btusb_setup_qca; | 4421 | data->setup_on_usb = btusb_setup_qca; |
| 4422 | hdev->shutdown = btusb_shutdown_qca; | ||
| 4422 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; | 4423 | hdev->set_bdaddr = btusb_set_bdaddr_ath3012; |
| 4423 | hdev->cmd_timeout = btusb_qca_cmd_timeout; | 4424 | hdev->cmd_timeout = btusb_qca_cmd_timeout; |
| 4424 | set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); | 4425 | set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); |
| @@ -38,6 +38,7 @@ enum sysc_soc { · 37 unmodified lines | |||
| 38 | SOC_2420, | 38 | SOC_2420, |
| 39 | SOC_2430, | 39 | SOC_2430, |
| 40 | SOC_3430, | 40 | SOC_3430, |
| 41 | SOC_AM35, | ||
| 41 | SOC_3630, | 42 | SOC_3630, |
| 42 | SOC_4430, | 43 | SOC_4430, |
| 43 | SOC_4460, | 44 | SOC_4460, |
| @@ -1097,6 +1098,11 @@ static int sysc_enable_module(struct device *dev) · 1053 unmodified lines | |||
| 1097 | if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | | 1098 | if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | |
| 1098 | SYSC_QUIRK_SWSUP_SIDLE_ACT)) { | 1099 | SYSC_QUIRK_SWSUP_SIDLE_ACT)) { |
| 1099 | best_mode = SYSC_IDLE_NO; | 1100 | best_mode = SYSC_IDLE_NO; |
| 1101 | |||
| 1102 | /* Clear WAKEUP */ | ||
| 1103 | if (regbits->enwkup_shift >= 0 && | ||
| 1104 | ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) | ||
| 1105 | reg &= ~BIT(regbits->enwkup_shift); | ||
| 1100 | } else { | 1106 | } else { |
| 1101 | best_mode = fls(ddata->cfg.sidlemodes) - 1; | 1107 | best_mode = fls(ddata->cfg.sidlemodes) - 1; |
| 1102 | if (best_mode > SYSC_IDLE_MASK) { | 1108 | if (best_mode > SYSC_IDLE_MASK) { |
| @@ -1224,6 +1230,13 @@ set_sidle: · 121 unmodified lines | |||
| 1224 | } | 1230 | } |
| 1225 | } | 1231 | } |
| 1226 | 1232 | ||
| 1233 | if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) { | ||
| 1234 | /* Set WAKEUP */ | ||
| 1235 | if (regbits->enwkup_shift >= 0 && | ||
| 1236 | ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) | ||
| 1237 | reg |= BIT(regbits->enwkup_shift); | ||
| 1238 | } | ||
| 1239 | |||
| 1227 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); | 1240 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); |
| 1228 | reg |= best_mode << regbits->sidle_shift; | 1241 | reg |= best_mode << regbits->sidle_shift; |
| 1229 | if (regbits->autoidle_shift >= 0 && | 1242 | if (regbits->autoidle_shift >= 0 && |
| @@ -1518,16 +1531,16 @@ struct sysc_revision_quirk { · 288 unmodified lines | |||
| 1518 | static const struct sysc_revision_quirk sysc_revision_quirks[] = { | 1531 | static const struct sysc_revision_quirk sysc_revision_quirks[] = { |
| 1519 | /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ | 1532 | /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ |
| 1520 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, | 1533 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, |
| 1521 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1534 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1522 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, | 1535 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, |
| 1523 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1536 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1524 | /* Uarts on omap4 and later */ | 1537 | /* Uarts on omap4 and later */ |
| 1525 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, | 1538 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, |
| 1526 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1539 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1527 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, | 1540 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, |
| 1528 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1541 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1529 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, | 1542 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, |
| 1530 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1543 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1531 | 1544 | ||
| 1532 | /* Quirks that need to be set based on the module address */ | 1545 | /* Quirks that need to be set based on the module address */ |
| 1533 | SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, | 1546 | SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, |
| @@ -1862,7 +1875,7 @@ static void sysc_pre_reset_quirk_dss(struct sysc *ddata) · 328 unmodified lines | |||
| 1862 | dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n", | 1875 | dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n", |
| 1863 | __func__, val, irq_mask); | 1876 | __func__, val, irq_mask); |
| 1864 | 1877 | ||
| 1865 | if (sysc_soc->soc == SOC_3430) { | 1878 | if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) { |
| 1866 | /* Clear DSS_SDI_CONTROL */ | 1879 | /* Clear DSS_SDI_CONTROL */ |
| 1867 | sysc_write(ddata, 0x44, 0); | 1880 | sysc_write(ddata, 0x44, 0); |
| 1868 | 1881 | ||
| @@ -2150,8 +2163,7 @@ static int sysc_reset(struct sysc *ddata) · 281 unmodified lines | |||
| 2150 | } | 2163 | } |
| 2151 | 2164 | ||
| 2152 | if (ddata->cfg.srst_udelay) | 2165 | if (ddata->cfg.srst_udelay) |
| 2153 | usleep_range(ddata->cfg.srst_udelay, | 2166 | fsleep(ddata->cfg.srst_udelay); |
| 2154 | ddata->cfg.srst_udelay * 2); | ||
| 2155 | 2167 | ||
| 2156 | if (ddata->post_reset_quirk) | 2168 | if (ddata->post_reset_quirk) |
| 2157 | ddata->post_reset_quirk(ddata); | 2169 | ddata->post_reset_quirk(ddata); |
| @@ -3025,6 +3037,7 @@ static void ti_sysc_idle(struct work_struct *work) · 867 unmodified lines | |||
| 3025 | static const struct soc_device_attribute sysc_soc_match[] = { | 3037 | static const struct soc_device_attribute sysc_soc_match[] = { |
| 3026 | SOC_FLAG("OMAP242*", SOC_2420), | 3038 | SOC_FLAG("OMAP242*", SOC_2420), |
| 3027 | SOC_FLAG("OMAP243*", SOC_2430), | 3039 | SOC_FLAG("OMAP243*", SOC_2430), |
| 3040 | SOC_FLAG("AM35*", SOC_AM35), | ||
| 3028 | SOC_FLAG("OMAP3[45]*", SOC_3430), | 3041 | SOC_FLAG("OMAP3[45]*", SOC_3430), |
| 3029 | SOC_FLAG("OMAP3[67]*", SOC_3630), | 3042 | SOC_FLAG("OMAP3[67]*", SOC_3630), |
| 3030 | SOC_FLAG("OMAP443*", SOC_4430), | 3043 | SOC_FLAG("OMAP443*", SOC_4430), |
| @@ -3229,7 +3242,7 @@ static int sysc_check_active_timer(struct sysc *ddata) · 198 unmodified lines | |||
| 3229 | * can be dropped if we stop supporting old beagleboard revisions | 3242 | * can be dropped if we stop supporting old beagleboard revisions |
| 3230 | * A to B4 at some point. | 3243 | * A to B4 at some point. |
| 3231 | */ | 3244 | */ |
| 3232 | if (sysc_soc->soc == SOC_3430) | 3245 | if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) |
| 3233 | error = -ENXIO; | 3246 | error = -ENXIO; |
| 3234 | else | 3247 | else |
| 3235 | error = -EBUSY; | 3248 | error = -EBUSY; |
| @@ -96,7 +96,7 @@ static int si521xx_regmap_i2c_write(void *context, unsigned int reg, · 95 unmodified lines | |||
| 96 | unsigned int val) | 96 | unsigned int val) |
| 97 | { | 97 | { |
| 98 | struct i2c_client *i2c = context; | 98 | struct i2c_client *i2c = context; |
| 99 | const u8 data[3] = { reg, 1, val }; | 99 | const u8 data[2] = { reg, val }; |
| 100 | const int count = ARRAY_SIZE(data); | 100 | const int count = ARRAY_SIZE(data); |
| 101 | int ret; | 101 | int ret; |
| 102 | 102 | ||
| @@ -146,7 +146,7 @@ static int si521xx_regmap_i2c_read(void *context, unsigned int reg, · 43 unmodified lines | |||
| 146 | static const struct regmap_config si521xx_regmap_config = { | 146 | static const struct regmap_config si521xx_regmap_config = { |
| 147 | .reg_bits = 8, | 147 | .reg_bits = 8, |
| 148 | .val_bits = 8, | 148 | .val_bits = 8, |
| 149 | .cache_type = REGCACHE_NONE, | 149 | .cache_type = REGCACHE_FLAT, |
| 150 | .max_register = SI521XX_REG_DA, | 150 | .max_register = SI521XX_REG_DA, |
| 151 | .rd_table = &si521xx_readable_table, | 151 | .rd_table = &si521xx_readable_table, |
| 152 | .wr_table = &si521xx_writeable_table, | 152 | .wr_table = &si521xx_writeable_table, |
| @@ -281,9 +281,10 @@ static int si521xx_probe(struct i2c_client *client) · 128 unmodified lines | |||
| 281 | { | 281 | { |
| 282 | const u16 chip_info = (u16)(uintptr_t)device_get_match_data(&client->dev); | 282 | const u16 chip_info = (u16)(uintptr_t)device_get_match_data(&client->dev); |
| 283 | const struct clk_parent_data clk_parent_data = { .index = 0 }; | 283 | const struct clk_parent_data clk_parent_data = { .index = 0 }; |
| 284 | struct si521xx *si; | 284 | const u8 data[3] = { SI521XX_REG_BC, 1, 1 }; |
| 285 | unsigned char name[6] = "DIFF0"; | 285 | unsigned char name[6] = "DIFF0"; |
| 286 | struct clk_init_data init = {}; | 286 | struct clk_init_data init = {}; |
| 287 | struct si521xx *si; | ||
| 287 | int i, ret; | 288 | int i, ret; |
| 288 | 289 | ||
| 289 | if (!chip_info) | 290 | if (!chip_info) |
| @@ -308,7 +309,7 @@ static int si521xx_probe(struct i2c_client *client) · 18 unmodified lines | |||
| 308 | "Failed to allocate register map\n"); | 309 | "Failed to allocate register map\n"); |
| 309 | 310 | ||
| 310 | /* Always read back 1 Byte via I2C */ | 311 | /* Always read back 1 Byte via I2C */ |
| 311 | ret = regmap_write(si->regmap, SI521XX_REG_BC, 1); | 312 | ret = i2c_master_send(client, data, ARRAY_SIZE(data)); |
| 312 | if (ret < 0) | 313 | if (ret < 0) |
| 313 | return ret; | 314 | return ret; |
| 314 | 315 | ||
| @@ -118,21 +118,21 @@ enum vc3_div { · 117 unmodified lines | |||
| 118 | VC3_DIV5, | 118 | VC3_DIV5, |
| 119 | }; | 119 | }; |
| 120 | 120 | ||
| 121 | enum vc3_clk_mux { | ||
| 122 | VC3_DIFF2_MUX, | ||
| 123 | VC3_DIFF1_MUX, | ||
| 124 | VC3_SE3_MUX, | ||
| 125 | VC3_SE2_MUX, | ||
| 126 | VC3_SE1_MUX, | ||
| 127 | }; | ||
| 128 | |||
| 129 | enum vc3_clk { | 121 | enum vc3_clk { |
| 130 | VC3_DIFF2, | ||
| 131 | VC3_DIFF1, | ||
| 132 | VC3_SE3, | ||
| 133 | VC3_SE2, | ||
| 134 | VC3_SE1, | ||
| 135 | VC3_REF, | 122 | VC3_REF, |
| 123 | VC3_SE1, | ||
| 124 | VC3_SE2, | ||
| 125 | VC3_SE3, | ||
| 126 | VC3_DIFF1, | ||
| 127 | VC3_DIFF2, | ||
| 128 | }; | ||
| 129 | |||
| 130 | enum vc3_clk_mux { | ||
| 131 | VC3_SE1_MUX = VC3_SE1 - 1, | ||
| 132 | VC3_SE2_MUX = VC3_SE2 - 1, | ||
| 133 | VC3_SE3_MUX = VC3_SE3 - 1, | ||
| 134 | VC3_DIFF1_MUX = VC3_DIFF1 - 1, | ||
| 135 | VC3_DIFF2_MUX = VC3_DIFF2 - 1, | ||
| 136 | }; | 136 | }; |
| 137 | 137 | ||
| 138 | struct vc3_clk_data { | 138 | struct vc3_clk_data { |
| @@ -401,11 +401,10 @@ static long vc3_pll_round_rate(struct clk_hw *hw, unsigned long rate, · 262 unmodified lines | |||
| 401 | /* Determine best fractional part, which is 16 bit wide */ | 401 | /* Determine best fractional part, which is 16 bit wide */ |
| 402 | div_frc = rate % *parent_rate; | 402 | div_frc = rate % *parent_rate; |
| 403 | div_frc *= BIT(16) - 1; | 403 | div_frc *= BIT(16) - 1; |
| 404 | do_div(div_frc, *parent_rate); | ||
| 405 | 404 | ||
| 406 | vc3->div_frc = (u32)div_frc; | 405 | vc3->div_frc = min_t(u64, div64_ul(div_frc, *parent_rate), U16_MAX); |
| 407 | rate = (*parent_rate * | 406 | rate = (*parent_rate * |
| 408 | (vc3->div_int * VC3_2_POW_16 + div_frc) / VC3_2_POW_16); | 407 | (vc3->div_int * VC3_2_POW_16 + vc3->div_frc) / VC3_2_POW_16); |
| 409 | } else { | 408 | } else { |
| 410 | rate = *parent_rate * vc3->div_int; | 409 | rate = *parent_rate * vc3->div_int; |
| 411 | } | 410 | } |
| @@ -897,33 +896,33 @@ static struct vc3_hw_data clk_div[] = { · 485 unmodified lines | |||
| 897 | }; | 896 | }; |
| 898 | 897 | ||
| 899 | static struct vc3_hw_data clk_mux[] = { | 898 | static struct vc3_hw_data clk_mux[] = { |
| 900 | [VC3_DIFF2_MUX] = { | 899 | [VC3_SE1_MUX] = { |
| 901 | .data = &(struct vc3_clk_data) { | 900 | .data = &(struct vc3_clk_data) { |
| 902 | .offs = VC3_DIFF2_CTRL_REG, | 901 | .offs = VC3_SE1_DIV4_CTRL, |
| 903 | .bitmsk = VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL | 902 | .bitmsk = VC3_SE1_DIV4_CTRL_SE1_CLK_SEL |
| 904 | }, | 903 | }, |
| 905 | .hw.init = &(struct clk_init_data){ | 904 | .hw.init = &(struct clk_init_data){ |
| 906 | .name = "diff2_mux", | 905 | .name = "se1_mux", |
| 907 | .ops = &vc3_clk_mux_ops, | 906 | .ops = &vc3_clk_mux_ops, |
| 908 | .parent_hws = (const struct clk_hw *[]) { | 907 | .parent_hws = (const struct clk_hw *[]) { |
| 909 | &clk_div[VC3_DIV1].hw, | 908 | &clk_div[VC3_DIV5].hw, |
| 910 | &clk_div[VC3_DIV3].hw | 909 | &clk_div[VC3_DIV4].hw |
| 911 | }, | 910 | }, |
| 912 | .num_parents = 2, | 911 | .num_parents = 2, |
| 913 | .flags = CLK_SET_RATE_PARENT | 912 | .flags = CLK_SET_RATE_PARENT |
| 914 | } | 913 | } |
| 915 | }, | 914 | }, |
| 916 | [VC3_DIFF1_MUX] = { | 915 | [VC3_SE2_MUX] = { |
| 917 | .data = &(struct vc3_clk_data) { | 916 | .data = &(struct vc3_clk_data) { |
| 918 | .offs = VC3_DIFF1_CTRL_REG, | 917 | .offs = VC3_SE2_CTRL_REG0, |
| 919 | .bitmsk = VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL | 918 | .bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL |
| 920 | }, | 919 | }, |
| 921 | .hw.init = &(struct clk_init_data){ | 920 | .hw.init = &(struct clk_init_data){ |
| 922 | .name = "diff1_mux", | 921 | .name = "se2_mux", |
| 923 | .ops = &vc3_clk_mux_ops, | 922 | .ops = &vc3_clk_mux_ops, |
| 924 | .parent_hws = (const struct clk_hw *[]) { | 923 | .parent_hws = (const struct clk_hw *[]) { |
| 925 | &clk_div[VC3_DIV1].hw, | 924 | &clk_div[VC3_DIV5].hw, |
| 926 | &clk_div[VC3_DIV3].hw | 925 | &clk_div[VC3_DIV4].hw |
| 927 | }, | 926 | }, |
| 928 | .num_parents = 2, | 927 | .num_parents = 2, |
| 929 | .flags = CLK_SET_RATE_PARENT | 928 | .flags = CLK_SET_RATE_PARENT |
| @@ -945,33 +944,33 @@ static struct vc3_hw_data clk_mux[] = { · 15 unmodified lines | |||
| 945 | .flags = CLK_SET_RATE_PARENT | 944 | .flags = CLK_SET_RATE_PARENT |
| 946 | } | 945 | } |
| 947 | }, | 946 | }, |
| 948 | [VC3_SE2_MUX] = { | 947 | [VC3_DIFF1_MUX] = { |
| 949 | .data = &(struct vc3_clk_data) { | 948 | .data = &(struct vc3_clk_data) { |
| 950 | .offs = VC3_SE2_CTRL_REG0, | 949 | .offs = VC3_DIFF1_CTRL_REG, |
| 951 | .bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL | 950 | .bitmsk = VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL |
| 952 | }, | 951 | }, |
| 953 | .hw.init = &(struct clk_init_data){ | 952 | .hw.init = &(struct clk_init_data){ |
| 954 | .name = "se2_mux", | 953 | .name = "diff1_mux", |
| 955 | .ops = &vc3_clk_mux_ops, | 954 | .ops = &vc3_clk_mux_ops, |
| 956 | .parent_hws = (const struct clk_hw *[]) { | 955 | .parent_hws = (const struct clk_hw *[]) { |
| 957 | &clk_div[VC3_DIV5].hw, | 956 | &clk_div[VC3_DIV1].hw, |
| 958 | &clk_div[VC3_DIV4].hw | 957 | &clk_div[VC3_DIV3].hw |
| 959 | }, | 958 | }, |
| 960 | .num_parents = 2, | 959 | .num_parents = 2, |
| 961 | .flags = CLK_SET_RATE_PARENT | 960 | .flags = CLK_SET_RATE_PARENT |
| 962 | } | 961 | } |
| 963 | }, | 962 | }, |
| 964 | [VC3_SE1_MUX] = { | 963 | [VC3_DIFF2_MUX] = { |
| 965 | .data = &(struct vc3_clk_data) { | 964 | .data = &(struct vc3_clk_data) { |
| 966 | .offs = VC3_SE1_DIV4_CTRL, | 965 | .offs = VC3_DIFF2_CTRL_REG, |
| 967 | .bitmsk = VC3_SE1_DIV4_CTRL_SE1_CLK_SEL | 966 | .bitmsk = VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL |
| 968 | }, | 967 | }, |
| 969 | .hw.init = &(struct clk_init_data){ | 968 | .hw.init = &(struct clk_init_data){ |
| 970 | .name = "se1_mux", | 969 | .name = "diff2_mux", |
| 971 | .ops = &vc3_clk_mux_ops, | 970 | .ops = &vc3_clk_mux_ops, |
| 972 | .parent_hws = (const struct clk_hw *[]) { | 971 | .parent_hws = (const struct clk_hw *[]) { |
| 973 | &clk_div[VC3_DIV5].hw, | 972 | &clk_div[VC3_DIV1].hw, |
| 974 | &clk_div[VC3_DIV4].hw | 973 | &clk_div[VC3_DIV3].hw |
| 975 | }, | 974 | }, |
| 976 | .num_parents = 2, | 975 | .num_parents = 2, |
| 977 | .flags = CLK_SET_RATE_PARENT | 976 | .flags = CLK_SET_RATE_PARENT |
| @@ -1110,7 +1109,7 @@ static int vc3_probe(struct i2c_client *client) · 132 unmodified lines | |||
| 1110 | name, 0, CLK_SET_RATE_PARENT, 1, 1); | 1109 | name, 0, CLK_SET_RATE_PARENT, 1, 1); |
| 1111 | else | 1110 | else |
| 1112 | clk_out[i] = devm_clk_hw_register_fixed_factor_parent_hw(dev, | 1111 | clk_out[i] = devm_clk_hw_register_fixed_factor_parent_hw(dev, |
| 1113 | name, &clk_mux[i].hw, CLK_SET_RATE_PARENT, 1, 1); | 1112 | name, &clk_mux[i - 1].hw, CLK_SET_RATE_PARENT, 1, 1); |
| 1114 | 1113 | ||
| 1115 | if (IS_ERR(clk_out[i])) | 1114 | if (IS_ERR(clk_out[i])) |
| 1116 | return PTR_ERR(clk_out[i]); | 1115 | return PTR_ERR(clk_out[i]); |
| @@ -800,7 +800,7 @@ static SPRD_MUX_CLK_DATA(uart1_clk, "uart1-clk", uart_parents, · 799 unmodified lines | |||
| 800 | 0x250, 0, 3, UMS512_MUX_FLAG); | 800 | 0x250, 0, 3, UMS512_MUX_FLAG); |
| 801 | 801 | ||
| 802 | static const struct clk_parent_data thm_parents[] = { | 802 | static const struct clk_parent_data thm_parents[] = { |
| 803 | { .fw_name = "ext-32m" }, | 803 | { .fw_name = "ext-32k" }, |
| 804 | { .hw = &clk_250k.hw }, | 804 | { .hw = &clk_250k.hw }, |
| 805 | }; | 805 | }; |
| 806 | static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, | 806 | static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, |
| @@ -159,7 +159,7 @@ static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw, · 158 unmodified lines | |||
| 159 | 159 | ||
| 160 | err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); | 160 | err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); |
| 161 | if (err < 0) | 161 | if (err < 0) |
| 162 | return err; | 162 | return 0; |
| 163 | 163 | ||
| 164 | return response.rate; | 164 | return response.rate; |
| 165 | } | 165 | } |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | struct cxl_cxims_data { | 15 | struct cxl_cxims_data { |
| 16 | int nr_maps; | 16 | int nr_maps; |
| 17 | u64 xormaps[]; | 17 | u64 xormaps[] __counted_by(nr_maps); |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | /* | 20 | /* |
| @@ -112,9 +112,9 @@ static int cxl_parse_cxims(union acpi_subtable_headers *header, void *arg, · 91 unmodified lines | |||
| 112 | GFP_KERNEL); | 112 | GFP_KERNEL); |
| 113 | if (!cximsd) | 113 | if (!cximsd) |
| 114 | return -ENOMEM; | 114 | return -ENOMEM; |
| 115 | cximsd->nr_maps = nr_maps; | ||
| 115 | memcpy(cximsd->xormaps, cxims->xormap_list, | 116 | memcpy(cximsd->xormaps, cxims->xormap_list, |
| 116 | nr_maps * sizeof(*cximsd->xormaps)); | 117 | nr_maps * sizeof(*cximsd->xormaps)); |
| 117 | cximsd->nr_maps = nr_maps; | ||
| 118 | cxlrd->platform_data = cximsd; | 118 | cxlrd->platform_data = cximsd; |
| 119 | 119 | ||
| 120 | return 0; | 120 | return 0; |
| @@ -715,24 +715,25 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel) · 714 unmodified lines | |||
| 715 | for (i = 0; i < cel_entries; i++) { | 715 | for (i = 0; i < cel_entries; i++) { |
| 716 | u16 opcode = le16_to_cpu(cel_entry[i].opcode); | 716 | u16 opcode = le16_to_cpu(cel_entry[i].opcode); |
| 717 | struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); | 717 | struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); |
| 718 | int enabled = 0; | ||
| 718 | 719 | ||
| 719 | if (!cmd && (!cxl_is_poison_command(opcode) || | 720 | if (cmd) { |
| 720 | !cxl_is_security_command(opcode))) { | ||
| 721 | dev_dbg(dev, | ||
| 722 | "Opcode 0x%04x unsupported by driver\n", opcode); | ||
| 723 | continue; | ||
| 724 | } | ||
| 725 | |||
| 726 | if (cmd) | ||
| 727 | set_bit(cmd->info.id, mds->enabled_cmds); | 721 | set_bit(cmd->info.id, mds->enabled_cmds); |
| 722 | enabled++; | ||
| 723 | } | ||
| 728 | 724 | ||
| 729 | if (cxl_is_poison_command(opcode)) | 725 | if (cxl_is_poison_command(opcode)) { |
| 730 | cxl_set_poison_cmd_enabled(&mds->poison, opcode); | 726 | cxl_set_poison_cmd_enabled(&mds->poison, opcode); |
| 727 | enabled++; | ||
| 728 | } | ||
| 731 | 729 | ||
| 732 | if (cxl_is_security_command(opcode)) | 730 | if (cxl_is_security_command(opcode)) { |
| 733 | cxl_set_security_cmd_enabled(&mds->security, opcode); | 731 | cxl_set_security_cmd_enabled(&mds->security, opcode); |
| 732 | enabled++; | ||
| 733 | } | ||
| 734 | 734 | ||
| 735 | dev_dbg(dev, "Opcode 0x%04x enabled\n", opcode); | 735 | dev_dbg(dev, "Opcode 0x%04x %s\n", opcode, |
| 736 | enabled ? "enabled" : "unsupported by driver"); | ||
| 736 | } | 737 | } |
| 737 | } | 738 | } |
| 738 | 739 | ||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* Copyright(c) 2020 Intel Corporation. All rights reserved. */ | 2 | /* Copyright(c) 2020 Intel Corporation. All rights reserved. */ |
| 3 | #include <linux/platform_device.h> | ||
| 3 | #include <linux/memregion.h> | 4 | #include <linux/memregion.h> |
| 4 | #include <linux/workqueue.h> | 5 | #include <linux/workqueue.h> |
| 5 | #include <linux/debugfs.h> | 6 | #include <linux/debugfs.h> |
| @@ -706,16 +707,20 @@ static int cxl_setup_comp_regs(struct device *dev, struct cxl_register_map *map, · 700 unmodified lines | |||
| 706 | return cxl_setup_regs(map); | 707 | return cxl_setup_regs(map); |
| 707 | } | 708 | } |
| 708 | 709 | ||
| 709 | static inline int cxl_port_setup_regs(struct cxl_port *port, | 710 | static int cxl_port_setup_regs(struct cxl_port *port, |
| 710 | resource_size_t component_reg_phys) | 711 | resource_size_t component_reg_phys) |
| 711 | { | 712 | { |
| 713 | if (dev_is_platform(port->uport_dev)) | ||
| 714 | return 0; | ||
| 712 | return cxl_setup_comp_regs(&port->dev, &port->comp_map, | 715 | return cxl_setup_comp_regs(&port->dev, &port->comp_map, |
| 713 | component_reg_phys); | 716 | component_reg_phys); |
| 714 | } | 717 | } |
| 715 | 718 | ||
| 716 | static inline int cxl_dport_setup_regs(struct cxl_dport *dport, | 719 | static int cxl_dport_setup_regs(struct cxl_dport *dport, |
| 717 | resource_size_t component_reg_phys) | 720 | resource_size_t component_reg_phys) |
| 718 | { | 721 | { |
| 722 | if (dev_is_platform(dport->dport_dev)) | ||
| 723 | return 0; | ||
| 719 | return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map, | 724 | return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map, |
| 720 | component_reg_phys); | 725 | component_reg_phys); |
| 721 | } | 726 | } |
| @@ -717,13 +717,35 @@ static int match_free_decoder(struct device *dev, void *data) · 716 unmodified lines | |||
| 717 | return 0; | 717 | return 0; |
| 718 | } | 718 | } |
| 719 | 719 | ||
| 720 | static int match_auto_decoder(struct device *dev, void *data) | ||
| 721 | { | ||
| 722 | struct cxl_region_params *p = data; | ||
| 723 | struct cxl_decoder *cxld; | ||
| 724 | struct range *r; | ||
| 725 | |||
| 726 | if (!is_switch_decoder(dev)) | ||
| 727 | return 0; | ||
| 728 | |||
| 729 | cxld = to_cxl_decoder(dev); | ||
| 730 | r = &cxld->hpa_range; | ||
| 731 | |||
| 732 | if (p->res && p->res->start == r->start && p->res->end == r->end) | ||
| 733 | return 1; | ||
| 734 | |||
| 735 | return 0; | ||
| 736 | } | ||
| 737 | |||
| 720 | static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port, | 738 | static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port, |
| 721 | struct cxl_region *cxlr) | 739 | struct cxl_region *cxlr) |
| 722 | { | 740 | { |
| 723 | struct device *dev; | 741 | struct device *dev; |
| 724 | int id = 0; | 742 | int id = 0; |
| 725 | 743 | ||
| 726 | dev = device_find_child(&port->dev, &id, match_free_decoder); | 744 | if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) |
| 745 | dev = device_find_child(&port->dev, &cxlr->params, | ||
| 746 | match_auto_decoder); | ||
| 747 | else | ||
| 748 | dev = device_find_child(&port->dev, &id, match_free_decoder); | ||
| 727 | if (!dev) | 749 | if (!dev) |
| 728 | return NULL; | 750 | return NULL; |
| 729 | /* | 751 | /* |
| @@ -1154,16 +1176,15 @@ static int cxl_port_setup_targets(struct cxl_port *port, · 424 unmodified lines | |||
| 1154 | } | 1176 | } |
| 1155 | 1177 | ||
| 1156 | /* | 1178 | /* |
| 1157 | * If @parent_port is masking address bits, pick the next unused address | 1179 | * Interleave granularity is a multiple of @parent_port granularity. |
| 1158 | * bit to route @port's targets. | 1180 | * Multiplier is the parent port interleave ways. |
| 1159 | */ | 1181 | */ |
| 1160 | if (parent_iw > 1 && cxl_rr->nr_targets > 1) { | 1182 | rc = granularity_to_eig(parent_ig * parent_iw, &eig); |
| 1161 | u32 address_bit = max(peig + peiw, eiw + peig); | 1183 | if (rc) { |
| 1162 | 1184 | dev_dbg(&cxlr->dev, | |
| 1163 | eig = address_bit - eiw + 1; | 1185 | "%s: invalid granularity calculation (%d * %d)\n", |
| 1164 | } else { | 1186 | dev_name(&parent_port->dev), parent_ig, parent_iw); |
| 1165 | eiw = peiw; | 1187 | return rc; |
| 1166 | eig = peig; | ||
| 1167 | } | 1188 | } |
| 1168 | 1189 | ||
| 1169 | rc = eig_to_granularity(eig, &ig); | 1190 | rc = eig_to_granularity(eig, &ig); |
| @@ -529,7 +529,6 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type, · 528 unmodified lines | |||
| 529 | 529 | ||
| 530 | static int cxl_pci_ras_unmask(struct pci_dev *pdev) | 530 | static int cxl_pci_ras_unmask(struct pci_dev *pdev) |
| 531 | { | 531 | { |
| 532 | struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus); | ||
| 533 | struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); | 532 | struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); |
| 534 | void __iomem *addr; | 533 | void __iomem *addr; |
| 535 | u32 orig_val, val, mask; | 534 | u32 orig_val, val, mask; |
| @@ -541,9 +540,9 @@ static int cxl_pci_ras_unmask(struct pci_dev *pdev) · 5 unmodified lines | |||
| 541 | return 0; | 540 | return 0; |
| 542 | } | 541 | } |
| 543 | 542 | ||
| 544 | /* BIOS has CXL error control */ | 543 | /* BIOS has PCIe AER error control */ |
| 545 | if (!host_bridge->native_cxl_error) | 544 | if (!pcie_aer_is_native(pdev)) |
| 546 | return -ENXIO; | 545 | return 0; |
| 547 | 546 | ||
| 548 | rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap); | 547 | rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap); |
| 549 | if (rc) | 548 | if (rc) |
| @@ -558,6 +558,9 @@ int k3_udma_glue_tx_get_irq(struct k3_udma_glue_tx_channel *tx_chn) · 557 unmodified lines | |||
| 558 | tx_chn->virq = k3_ringacc_get_ring_irq_num(tx_chn->ringtxcq); | 558 | tx_chn->virq = k3_ringacc_get_ring_irq_num(tx_chn->ringtxcq); |
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | if (!tx_chn->virq) | ||
| 562 | return -ENXIO; | ||
| 563 | |||
| 561 | return tx_chn->virq; | 564 | return tx_chn->virq; |
| 562 | } | 565 | } |
| 563 | EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_irq); | 566 | EXPORT_SYMBOL_GPL(k3_udma_glue_tx_get_irq); |
| @@ -81,7 +81,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " · 80 unmodified lines | |||
| 81 | * | 81 | * |
| 82 | * - power condition | 82 | * - power condition |
| 83 | * Set the power condition field in the START STOP UNIT commands sent by | 83 | * Set the power condition field in the START STOP UNIT commands sent by |
| 84 | * sd_mod on suspend, resume, and shutdown (if manage_start_stop is on). | 84 | * sd_mod on suspend, resume, and shutdown (if manage_system_start_stop or |
| 85 | * manage_runtime_start_stop is on). | ||
| 85 | * Some disks need this to spin down or to resume properly. | 86 | * Some disks need this to spin down or to resume properly. |
| 86 | * | 87 | * |
| 87 | * - override internal blacklist | 88 | * - override internal blacklist |
| @@ -1517,8 +1518,10 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) · 1429 unmodified lines | |||
| 1517 | 1518 | ||
| 1518 | sdev->use_10_for_rw = 1; | 1519 | sdev->use_10_for_rw = 1; |
| 1519 | 1520 | ||
| 1520 | if (sbp2_param_exclusive_login) | 1521 | if (sbp2_param_exclusive_login) { |
| 1521 | sdev->manage_start_stop = 1; | 1522 | sdev->manage_system_start_stop = true; |
| 1523 | sdev->manage_runtime_start_stop = true; | ||
| 1524 | } | ||
| 1522 | 1525 | ||
| 1523 | if (sdev->type == TYPE_ROM) | 1526 | if (sdev->type == TYPE_ROM) |
| 1524 | sdev->use_10_for_ms = 1; | 1527 | sdev->use_10_for_ms = 1; |
| @@ -397,6 +397,19 @@ static u32 ffa_get_num_pages_sg(struct scatterlist *sg) · 396 unmodified lines | |||
| 397 | return num_pages; | 397 | return num_pages; |
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | static u8 ffa_memory_attributes_get(u32 func_id) | ||
| 401 | { | ||
| 402 | /* | ||
| 403 | * For the memory lend or donate operation, if the receiver is a PE or | ||
| 404 | * a proxy endpoint, the owner/sender must not specify the attributes | ||
| 405 | */ | ||
| 406 | if (func_id == FFA_FN_NATIVE(MEM_LEND) || | ||
| 407 | func_id == FFA_MEM_LEND) | ||
| 408 | return 0; | ||
| 409 | |||
| 410 | return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE; | ||
| 411 | } | ||
| 412 | |||
| 400 | static int | 413 | static int |
| 401 | ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, | 414 | ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, |
| 402 | struct ffa_mem_ops_args *args) | 415 | struct ffa_mem_ops_args *args) |
| @@ -413,8 +426,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, · 10 unmodified lines | |||
| 413 | mem_region->tag = args->tag; | 426 | mem_region->tag = args->tag; |
| 414 | mem_region->flags = args->flags; | 427 | mem_region->flags = args->flags; |
| 415 | mem_region->sender_id = drv_info->vm_id; | 428 | mem_region->sender_id = drv_info->vm_id; |
| 416 | mem_region->attributes = FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | | 429 | mem_region->attributes = ffa_memory_attributes_get(func_id); |
| 417 | FFA_MEM_INNER_SHAREABLE; | ||
| 418 | ep_mem_access = &mem_region->ep_mem_access[0]; | 430 | ep_mem_access = &mem_region->ep_mem_access[0]; |
| 419 | 431 | ||
| 420 | for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { | 432 | for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { |
| @@ -1080,6 +1080,8 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) · 1079 unmodified lines | |||
| 1080 | if (!pinfo) | 1080 | if (!pinfo) |
| 1081 | return -ENOMEM; | 1081 | return -ENOMEM; |
| 1082 | 1082 | ||
| 1083 | pinfo->version = version; | ||
| 1084 | |||
| 1083 | ret = scmi_perf_attributes_get(ph, pinfo); | 1085 | ret = scmi_perf_attributes_get(ph, pinfo); |
| 1084 | if (ret) | 1086 | if (ret) |
| 1085 | return ret; | 1087 | return ret; |
| @@ -1104,8 +1106,6 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) · 18 unmodified lines | |||
| 1104 | if (ret) | 1106 | if (ret) |
| 1105 | return ret; | 1107 | return ret; |
| 1106 | 1108 | ||
| 1107 | pinfo->version = version; | ||
| 1108 | |||
| 1109 | return ph->set_priv(ph, pinfo); | 1109 | return ph->set_priv(ph, pinfo); |
| 1110 | } | 1110 | } |
| 1111 | 1111 | ||
| @@ -623,6 +623,34 @@ static __init int match_config_table(const efi_guid_t *guid, · 622 unmodified lines | |||
| 623 | return 0; | 623 | return 0; |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | /** | ||
| 627 | * reserve_unaccepted - Map and reserve unaccepted configuration table | ||
| 628 | * @unaccepted: Pointer to unaccepted memory table | ||
| 629 | * | ||
| 630 | * memblock_add() makes sure that the table is mapped in direct mapping. During | ||
| 631 | * normal boot it happens automatically because the table is allocated from | ||
| 632 | * usable memory. But during crashkernel boot only memory specifically reserved | ||
| 633 | * for crash scenario is mapped. memblock_add() forces the table to be mapped | ||
| 634 | * in crashkernel case. | ||
| 635 | * | ||
| 636 | * Align the range to the nearest page borders. Ranges smaller than page size | ||
| 637 | * are not going to be mapped. | ||
| 638 | * | ||
| 639 | * memblock_reserve() makes sure that future allocations will not touch the | ||
| 640 | * table. | ||
| 641 | */ | ||
| 642 | |||
| 643 | static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted) | ||
| 644 | { | ||
| 645 | phys_addr_t start, size; | ||
| 646 | |||
| 647 | start = PAGE_ALIGN_DOWN(efi.unaccepted); | ||
| 648 | size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size); | ||
| 649 | |||
| 650 | memblock_add(start, size); | ||
| 651 | memblock_reserve(start, size); | ||
| 652 | } | ||
| 653 | |||
| 626 | int __init efi_config_parse_tables(const efi_config_table_t *config_tables, | 654 | int __init efi_config_parse_tables(const efi_config_table_t *config_tables, |
| 627 | int count, | 655 | int count, |
| 628 | const efi_config_table_type_t *arch_tables) | 656 | const efi_config_table_type_t *arch_tables) |
| @@ -751,11 +779,9 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables, · 122 unmodified lines | |||
| 751 | 779 | ||
| 752 | unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted)); | 780 | unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted)); |
| 753 | if (unaccepted) { | 781 | if (unaccepted) { |
| 754 | unsigned long size; | ||
| 755 | 782 | ||
| 756 | if (unaccepted->version == 1) { | 783 | if (unaccepted->version == 1) { |
| 757 | size = sizeof(*unaccepted) + unaccepted->size; | 784 | reserve_unaccepted(unaccepted); |
| 758 | memblock_reserve(efi.unaccepted, size); | ||
| 759 | } else { | 785 | } else { |
| 760 | efi.unaccepted = EFI_INVALID_TABLE_ADDR; | 786 | efi.unaccepted = EFI_INVALID_TABLE_ADDR; |
| 761 | } | 787 | } |
| @@ -114,6 +114,7 @@ static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) · 113 unmodified lines | |||
| 114 | dsp_chan->idx = i % 2; | 114 | dsp_chan->idx = i % 2; |
| 115 | dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); | 115 | dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); |
| 116 | if (IS_ERR(dsp_chan->ch)) { | 116 | if (IS_ERR(dsp_chan->ch)) { |
| 117 | kfree(dsp_chan->name); | ||
| 117 | ret = PTR_ERR(dsp_chan->ch); | 118 | ret = PTR_ERR(dsp_chan->ch); |
| 118 | if (ret != -EPROBE_DEFER) | 119 | if (ret != -EPROBE_DEFER) |
| 119 | dev_err(dev, "Failed to request mbox chan %s ret %d\n", | 120 | dev_err(dev, "Failed to request mbox chan %s ret %d\n", |
| @@ -352,6 +352,7 @@ static int sprd_pmic_eic_probe(struct platform_device *pdev) · 351 unmodified lines | |||
| 352 | pmic_eic->chip.set_config = sprd_pmic_eic_set_config; | 352 | pmic_eic->chip.set_config = sprd_pmic_eic_set_config; |
| 353 | pmic_eic->chip.set = sprd_pmic_eic_set; | 353 | pmic_eic->chip.set = sprd_pmic_eic_set; |
| 354 | pmic_eic->chip.get = sprd_pmic_eic_get; | 354 | pmic_eic->chip.get = sprd_pmic_eic_get; |
| 355 | pmic_eic->chip.can_sleep = true; | ||
| 355 | 356 | ||
| 356 | irq = &pmic_eic->chip.irq; | 357 | irq = &pmic_eic->chip.irq; |
| 357 | gpio_irq_chip_set_chip(irq, &pmic_eic_irq_chip); | 358 | gpio_irq_chip_set_chip(irq, &pmic_eic_irq_chip); |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
| 20 | #include <linux/irq_sim.h> | 20 | #include <linux/irq_sim.h> |
| 21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
| 22 | #include <linux/minmax.h> | ||
| 22 | #include <linux/mod_devicetable.h> | 23 | #include <linux/mod_devicetable.h> |
| 23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
| @@ -685,52 +686,32 @@ gpio_sim_device_config_live_show(struct config_item *item, char *page) · 660 unmodified lines | |||
| 685 | return sprintf(page, "%c\n", live ? '1' : '0'); | 686 | return sprintf(page, "%c\n", live ? '1' : '0'); |
| 686 | } | 687 | } |
| 687 | 688 | ||
| 688 | static char **gpio_sim_make_line_names(struct gpio_sim_bank *bank, | 689 | static unsigned int gpio_sim_get_line_names_size(struct gpio_sim_bank *bank) |
| 689 | unsigned int *line_names_size) | ||
| 690 | { | 690 | { |
| 691 | unsigned int max_offset = 0; | ||
| 692 | bool has_line_names = false; | ||
| 693 | struct gpio_sim_line *line; | 691 | struct gpio_sim_line *line; |
| 694 | char **line_names; | 692 | unsigned int size = 0; |
| 695 | 693 | ||
| 696 | list_for_each_entry(line, &bank->line_list, siblings) { | 694 | list_for_each_entry(line, &bank->line_list, siblings) { |
| 697 | if (line->offset >= bank->num_lines) | 695 | if (!line->name || (line->offset >= bank->num_lines)) |
| 698 | continue; | 696 | continue; |
| 699 | 697 | ||
| 700 | if (line->name) { | 698 | size = max(size, line->offset + 1); |
| 701 | if (line->offset > max_offset) | ||
| 702 | max_offset = line->offset; | ||
| 703 | |||
| 704 | /* | ||
| 705 | * max_offset can stay at 0 so it's not an indicator | ||
| 706 | * of whether line names were configured at all. | ||
| 707 | */ | ||
| 708 | has_line_names = true; | ||
| 709 | } | ||
| 710 | } | 699 | } |
| 711 | 700 | ||
| 712 | if (!has_line_names) | 701 | return size; |
| 713 | /* | 702 | } |
| 714 | * This is not an error - NULL means, there are no line | ||
| 715 | * names configured. | ||
| 716 | */ | ||
| 717 | return NULL; | ||
| 718 | |||
| 719 | *line_names_size = max_offset + 1; | ||
| 720 | 703 | ||
| 721 | line_names = kcalloc(*line_names_size, sizeof(*line_names), GFP_KERNEL); | 704 | static void |
| 722 | if (!line_names) | 705 | gpio_sim_set_line_names(struct gpio_sim_bank *bank, char **line_names) |
| 723 | return ERR_PTR(-ENOMEM); | 706 | { |
| 707 | struct gpio_sim_line *line; | ||
| 724 | 708 | ||
| 725 | list_for_each_entry(line, &bank->line_list, siblings) { | 709 | list_for_each_entry(line, &bank->line_list, siblings) { |
| 726 | if (line->offset >= bank->num_lines) | 710 | if (!line->name || (line->offset >= bank->num_lines)) |
| 727 | continue; | 711 | continue; |
| 728 | 712 | ||
| 729 | if (line->name && (line->offset <= max_offset)) | 713 | line_names[line->offset] = line->name; |
| 730 | line_names[line->offset] = line->name; | ||
| 731 | } | 714 | } |
| 732 | |||
| 733 | return line_names; | ||
| 734 | } | 715 | } |
| 735 | 716 | ||
| 736 | static void gpio_sim_remove_hogs(struct gpio_sim_device *dev) | 717 | static void gpio_sim_remove_hogs(struct gpio_sim_device *dev) |
| @@ -834,7 +815,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, · 97 unmodified lines | |||
| 834 | struct fwnode_handle *parent) | 815 | struct fwnode_handle *parent) |
| 835 | { | 816 | { |
| 836 | struct property_entry properties[GPIO_SIM_PROP_MAX]; | 817 | struct property_entry properties[GPIO_SIM_PROP_MAX]; |
| 837 | unsigned int prop_idx = 0, line_names_size = 0; | 818 | unsigned int prop_idx = 0, line_names_size; |
| 838 | char **line_names __free(kfree) = NULL; | 819 | char **line_names __free(kfree) = NULL; |
| 839 | 820 | ||
| 840 | memset(properties, 0, sizeof(properties)); | 821 | memset(properties, 0, sizeof(properties)); |
| @@ -845,14 +826,19 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, · 4 unmodified lines | |||
| 845 | properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label", | 826 | properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label", |
| 846 | bank->label); | 827 | bank->label); |
| 847 | 828 | ||
| 848 | line_names = gpio_sim_make_line_names(bank, &line_names_size); | 829 | line_names_size = gpio_sim_get_line_names_size(bank); |
| 849 | if (IS_ERR(line_names)) | 830 | if (line_names_size) { |
| 850 | return ERR_CAST(line_names); | 831 | line_names = kcalloc(line_names_size, sizeof(*line_names), |
| 832 | GFP_KERNEL); | ||
| 833 | if (!line_names) | ||
| 834 | return ERR_PTR(-ENOMEM); | ||
| 835 | |||
| 836 | gpio_sim_set_line_names(bank, line_names); | ||
| 851 | 837 | ||
| 852 | if (line_names) | ||
| 853 | properties[prop_idx++] = PROPERTY_ENTRY_STRING_ARRAY_LEN( | 838 | properties[prop_idx++] = PROPERTY_ENTRY_STRING_ARRAY_LEN( |
| 854 | "gpio-line-names", | 839 | "gpio-line-names", |
| 855 | line_names, line_names_size); | 840 | line_names, line_names_size); |
| 841 | } | ||
| 856 | 842 | ||
| 857 | return fwnode_create_software_node(properties, parent); | 843 | return fwnode_create_software_node(properties, parent); |
| 858 | } | 844 | } |
| @@ -195,7 +195,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 194 unmodified lines | |||
| 195 | handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, | 195 | handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, |
| 196 | IRQ_GC_INIT_MASK_CACHE); | 196 | IRQ_GC_INIT_MASK_CACHE); |
| 197 | if (ret) | 197 | if (ret) |
| 198 | return ret; | 198 | goto err_remove_domain; |
| 199 | 199 | ||
| 200 | gc = tb10x_gpio->domain->gc->gc[0]; | 200 | gc = tb10x_gpio->domain->gc->gc[0]; |
| 201 | gc->reg_base = tb10x_gpio->base; | 201 | gc->reg_base = tb10x_gpio->base; |
| @@ -209,6 +209,10 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | return 0; | 211 | return 0; |
| 212 | |||
| 213 | err_remove_domain: | ||
| 214 | irq_domain_remove(tb10x_gpio->domain); | ||
| 215 | return ret; | ||
| 212 | } | 216 | } |
| 213 | 217 | ||
| 214 | static int tb10x_gpio_remove(struct platform_device *pdev) | 218 | static int tb10x_gpio_remove(struct platform_device *pdev) |
| @@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, · 42 unmodified lines | |||
| 43 | unsigned offset, bool enabled) | 43 | unsigned offset, bool enabled) |
| 44 | { | 44 | { |
| 45 | struct timbgpio *tgpio = gpiochip_get_data(gpio); | 45 | struct timbgpio *tgpio = gpiochip_get_data(gpio); |
| 46 | unsigned long flags; | ||
| 46 | u32 reg; | 47 | u32 reg; |
| 47 | 48 | ||
| 48 | spin_lock(&tgpio->lock); | 49 | spin_lock_irqsave(&tgpio->lock, flags); |
| 49 | reg = ioread32(tgpio->membase + offset); | 50 | reg = ioread32(tgpio->membase + offset); |
| 50 | 51 | ||
| 51 | if (enabled) | 52 | if (enabled) |
| @@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, · 2 unmodified lines | |||
| 54 | reg &= ~(1 << index); | 55 | reg &= ~(1 << index); |
| 55 | 56 | ||
| 56 | iowrite32(reg, tgpio->membase + offset); | 57 | iowrite32(reg, tgpio->membase + offset); |
| 57 | spin_unlock(&tgpio->lock); | 58 | spin_unlock_irqrestore(&tgpio->lock, flags); |
| 58 | 59 | ||
| 59 | return 0; | 60 | return 0; |
| 60 | } | 61 | } |
| @@ -136,7 +136,7 @@ config DRM_FBDEV_EMULATION · 135 unmodified lines | |||
| 136 | bool "Enable legacy fbdev support for your modesetting driver" | 136 | bool "Enable legacy fbdev support for your modesetting driver" |
| 137 | depends on DRM | 137 | depends on DRM |
| 138 | select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE | 138 | select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE |
| 139 | default y | 139 | default FB |
| 140 | help | 140 | help |
| 141 | Choose this option if you have a need for the legacy fbdev | 141 | Choose this option if you have a need for the legacy fbdev |
| 142 | support. Note that this support also provides the linux console | 142 | support. Note that this support also provides the linux console |
| @@ -1776,7 +1776,7 @@ static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev, · 1775 unmodified lines | |||
| 1776 | struct amdgpu_device *adev = drm_to_adev(ddev); | 1776 | struct amdgpu_device *adev = drm_to_adev(ddev); |
| 1777 | struct atom_context *ctx = adev->mode_info.atom_context; | 1777 | struct atom_context *ctx = adev->mode_info.atom_context; |
| 1778 | 1778 | ||
| 1779 | return sysfs_emit(buf, "%s\n", ctx->vbios_ver_str); | 1779 | return sysfs_emit(buf, "%s\n", ctx->vbios_pn); |
| 1780 | } | 1780 | } |
| 1781 | 1781 | ||
| 1782 | static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version, | 1782 | static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version, |
| @@ -801,6 +801,7 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, · 800 unmodified lines | |||
| 801 | enable ? "enable":"disable", | 801 | enable ? "enable":"disable", |
| 802 | get_ras_block_str(head), | 802 | get_ras_block_str(head), |
| 803 | amdgpu_ras_is_poison_mode_supported(adev), ret); | 803 | amdgpu_ras_is_poison_mode_supported(adev), ret); |
| 804 | kfree(info); | ||
| 804 | return ret; | 805 | return ret; |
| 805 | } | 806 | } |
| 806 | 807 | ||
| @@ -216,7 +216,7 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, · 215 unmodified lines | |||
| 216 | 216 | ||
| 217 | if (q->wptr_bo) { | 217 | if (q->wptr_bo) { |
| 218 | wptr_addr_off = (uint64_t)q->properties.write_ptr & (PAGE_SIZE - 1); | 218 | wptr_addr_off = (uint64_t)q->properties.write_ptr & (PAGE_SIZE - 1); |
| 219 | queue_input.wptr_mc_addr = ((uint64_t)q->wptr_bo->tbo.resource->start << PAGE_SHIFT) + wptr_addr_off; | 219 | queue_input.wptr_mc_addr = amdgpu_bo_gpu_offset(q->wptr_bo) + wptr_addr_off; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | queue_input.is_kfd_process = 1; | 222 | queue_input.is_kfd_process = 1; |
| @@ -6098,8 +6098,6 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 6097 unmodified lines | |||
| 6098 | 6098 | ||
| 6099 | if (recalculate_timing) | 6099 | if (recalculate_timing) |
| 6100 | drm_mode_set_crtcinfo(&saved_mode, 0); | 6100 | drm_mode_set_crtcinfo(&saved_mode, 0); |
| 6101 | else if (!old_stream) | ||
| 6102 | drm_mode_set_crtcinfo(&mode, 0); | ||
| 6103 | 6101 | ||
| 6104 | /* | 6102 | /* |
| 6105 | * If scaling is enabled and refresh rate didn't change | 6103 | * If scaling is enabled and refresh rate didn't change |
| @@ -6661,6 +6659,8 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec · 555 unmodified lines | |||
| 6661 | goto fail; | 6659 | goto fail; |
| 6662 | } | 6660 | } |
| 6663 | 6661 | ||
| 6662 | drm_mode_set_crtcinfo(mode, 0); | ||
| 6663 | |||
| 6664 | stream = create_validate_stream_for_sink(aconnector, mode, | 6664 | stream = create_validate_stream_for_sink(aconnector, mode, |
| 6665 | to_dm_connector_state(connector->state), | 6665 | to_dm_connector_state(connector->state), |
| 6666 | NULL); | 6666 | NULL); |
| @@ -1178,12 +1178,15 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) · 1177 unmodified lines | |||
| 1178 | dto_params.otg_inst = tg->inst; | 1178 | dto_params.otg_inst = tg->inst; |
| 1179 | dto_params.timing = &pipe_ctx->stream->timing; | 1179 | dto_params.timing = &pipe_ctx->stream->timing; |
| 1180 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | 1180 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; |
| 1181 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | 1181 | if (dccg) { |
| 1182 | dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); | 1182 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); |
| 1183 | dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); | 1183 | dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); |
| 1184 | } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST && dccg->funcs->disable_symclk_se) | 1184 | dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); |
| 1185 | } | ||
| 1186 | } else if (dccg && dccg->funcs->disable_symclk_se) { | ||
| 1185 | dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, | 1187 | dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, |
| 1186 | link_enc->transmitter - TRANSMITTER_UNIPHY_A); | 1188 | link_enc->transmitter - TRANSMITTER_UNIPHY_A); |
| 1189 | } | ||
| 1187 | 1190 | ||
| 1188 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { | 1191 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { |
| 1189 | /* TODO: This looks like a bug to me as we are disabling HPO IO when | 1192 | /* TODO: This looks like a bug to me as we are disabling HPO IO when |
| @@ -2658,11 +2661,11 @@ void dce110_prepare_bandwidth( · 1468 unmodified lines | |||
| 2658 | struct clk_mgr *dccg = dc->clk_mgr; | 2661 | struct clk_mgr *dccg = dc->clk_mgr; |
| 2659 | 2662 | ||
| 2660 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); | 2663 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); |
| 2661 | 2664 | if (dccg) | |
| 2662 | dccg->funcs->update_clocks( | 2665 | dccg->funcs->update_clocks( |
| 2663 | dccg, | 2666 | dccg, |
| 2664 | context, | 2667 | context, |
| 2665 | false); | 2668 | false); |
| 2666 | } | 2669 | } |
| 2667 | 2670 | ||
| 2668 | void dce110_optimize_bandwidth( | 2671 | void dce110_optimize_bandwidth( |
| @@ -2673,10 +2676,11 @@ void dce110_optimize_bandwidth( · 4 unmodified lines | |||
| 2673 | 2676 | ||
| 2674 | dce110_set_displaymarks(dc, context); | 2677 | dce110_set_displaymarks(dc, context); |
| 2675 | 2678 | ||
| 2676 | dccg->funcs->update_clocks( | 2679 | if (dccg) |
| 2677 | dccg, | 2680 | dccg->funcs->update_clocks( |
| 2678 | context, | 2681 | dccg, |
| 2679 | true); | 2682 | context, |
| 2683 | true); | ||
| 2680 | } | 2684 | } |
| 2681 | 2685 | ||
| 2682 | static void dce110_program_front_end_for_pipe( | 2686 | static void dce110_program_front_end_for_pipe( |
| @@ -2692,8 +2692,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 2691 unmodified lines | |||
| 2692 | struct dce_hwseq *hws = dc->hwseq; | 2692 | struct dce_hwseq *hws = dc->hwseq; |
| 2693 | unsigned int k1_div = PIXEL_RATE_DIV_NA; | 2693 | unsigned int k1_div = PIXEL_RATE_DIV_NA; |
| 2694 | unsigned int k2_div = PIXEL_RATE_DIV_NA; | 2694 | unsigned int k2_div = PIXEL_RATE_DIV_NA; |
| 2695 | struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); | ||
| 2696 | struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; | ||
| 2697 | 2695 | ||
| 2698 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { | 2696 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { |
| 2699 | if (dc->hwseq->funcs.setup_hpo_hw_control) | 2697 | if (dc->hwseq->funcs.setup_hpo_hw_control) |
| @@ -2713,10 +2711,8 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 13 unmodified lines | |||
| 2713 | dto_params.timing = &pipe_ctx->stream->timing; | 2711 | dto_params.timing = &pipe_ctx->stream->timing; |
| 2714 | dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); | 2712 | dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); |
| 2715 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | 2713 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); |
| 2716 | } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST && dccg->funcs->enable_symclk_se) | 2714 | } else { |
| 2717 | dccg->funcs->enable_symclk_se(dccg, | 2715 | } |
| 2718 | stream_enc->stream_enc_inst, link_enc->transmitter - TRANSMITTER_UNIPHY_A); | ||
| 2719 | |||
| 2720 | if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) { | 2716 | if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) { |
| 2721 | hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div); | 2717 | hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div); |
| 2722 | 2718 | ||
| @@ -75,7 +75,7 @@ void mpc32_power_on_blnd_lut( · 74 unmodified lines | |||
| 75 | if (power_on) { | 75 | if (power_on) { |
| 76 | REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_FORCE, 0); | 76 | REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_FORCE, 0); |
| 77 | REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_STATE, 0, 1, 5); | 77 | REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_STATE, 0, 1, 5); |
| 78 | } else { | 78 | } else if (!mpc->ctx->dc->debug.disable_mem_low_power) { |
| 79 | ASSERT(false); | 79 | ASSERT(false); |
| 80 | /* TODO: change to mpc | 80 | /* TODO: change to mpc |
| 81 | * dpp_base->ctx->dc->optimized_required = true; | 81 | * dpp_base->ctx->dc->optimized_required = true; |
| @@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, · 99 unmodified lines | |||
| 100 | st->nents = 0; | 100 | st->nents = 0; |
| 101 | for (i = 0; i < page_count; i++) { | 101 | for (i = 0; i < page_count; i++) { |
| 102 | struct folio *folio; | 102 | struct folio *folio; |
| 103 | unsigned long nr_pages; | ||
| 103 | const unsigned int shrink[] = { | 104 | const unsigned int shrink[] = { |
| 104 | I915_SHRINK_BOUND | I915_SHRINK_UNBOUND, | 105 | I915_SHRINK_BOUND | I915_SHRINK_UNBOUND, |
| 105 | 0, | 106 | 0, |
| @@ -150,6 +151,8 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, · 44 unmodified lines | |||
| 150 | } | 151 | } |
| 151 | } while (1); | 152 | } while (1); |
| 152 | 153 | ||
| 154 | nr_pages = min_t(unsigned long, | ||
| 155 | folio_nr_pages(folio), page_count - i); | ||
| 153 | if (!i || | 156 | if (!i || |
| 154 | sg->length >= max_segment || | 157 | sg->length >= max_segment || |
| 155 | folio_pfn(folio) != next_pfn) { | 158 | folio_pfn(folio) != next_pfn) { |
| @@ -157,13 +160,13 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, · 1 unmodified line | |||
| 157 | sg = sg_next(sg); | 160 | sg = sg_next(sg); |
| 158 | 161 | ||
| 159 | st->nents++; | 162 | st->nents++; |
| 160 | sg_set_folio(sg, folio, folio_size(folio), 0); | 163 | sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0); |
| 161 | } else { | 164 | } else { |
| 162 | /* XXX: could overflow? */ | 165 | /* XXX: could overflow? */ |
| 163 | sg->length += folio_size(folio); | 166 | sg->length += nr_pages * PAGE_SIZE; |
| 164 | } | 167 | } |
| 165 | next_pfn = folio_pfn(folio) + folio_nr_pages(folio); | 168 | next_pfn = folio_pfn(folio) + nr_pages; |
| 166 | i += folio_nr_pages(folio) - 1; | 169 | i += nr_pages - 1; |
| 167 | 170 | ||
| 168 | /* Check that the i965g/gm workaround works. */ | 171 | /* Check that the i965g/gm workaround works. */ |
| 169 | GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x00100000UL); | 172 | GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x00100000UL); |
| @@ -558,7 +558,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, · 557 unmodified lines | |||
| 558 | DRIVER_CAPS(i915)->has_logical_contexts = true; | 558 | DRIVER_CAPS(i915)->has_logical_contexts = true; |
| 559 | 559 | ||
| 560 | ewma__engine_latency_init(&engine->latency); | 560 | ewma__engine_latency_init(&engine->latency); |
| 561 | seqcount_init(&engine->stats.execlists.lock); | ||
| 562 | 561 | ||
| 563 | ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); | 562 | ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); |
| 564 | 563 | ||
| @@ -3550,6 +3550,8 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine) · 3549 unmodified lines | |||
| 3550 | logical_ring_default_vfuncs(engine); | 3550 | logical_ring_default_vfuncs(engine); |
| 3551 | logical_ring_default_irqs(engine); | 3551 | logical_ring_default_irqs(engine); |
| 3552 | 3552 | ||
| 3553 | seqcount_init(&engine->stats.execlists.lock); | ||
| 3554 | |||
| 3553 | if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) | 3555 | if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) |
| 3554 | rcs_submission_override(engine); | 3556 | rcs_submission_override(engine); |
| 3555 | 3557 | ||
| @@ -511,20 +511,31 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm, · 510 unmodified lines | |||
| 511 | vm->clear_range(vm, vma_res->start, vma_res->vma_size); | 511 | vm->clear_range(vm, vma_res->start, vma_res->vma_size); |
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | /* | ||
| 515 | * Reserve the top of the GuC address space for firmware images. Addresses | ||
| 516 | * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC, | ||
| 517 | * which makes for a suitable range to hold GuC/HuC firmware images if the | ||
| 518 | * size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT | ||
| 519 | * is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk | ||
| 520 | * of the same size anyway, which is far more than needed, to keep the logic | ||
| 521 | * in uc_fw_ggtt_offset() simple. | ||
| 522 | */ | ||
| 523 | #define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP) | ||
| 524 | |||
| 514 | static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) | 525 | static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) |
| 515 | { | 526 | { |
| 516 | u64 size; | 527 | u64 offset; |
| 517 | int ret; | 528 | int ret; |
| 518 | 529 | ||
| 519 | if (!intel_uc_uses_guc(&ggtt->vm.gt->uc)) | 530 | if (!intel_uc_uses_guc(&ggtt->vm.gt->uc)) |
| 520 | return 0; | 531 | return 0; |
| 521 | 532 | ||
| 522 | GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP); | 533 | GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE); |
| 523 | size = ggtt->vm.total - GUC_GGTT_TOP; | 534 | offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE; |
| 524 | 535 | ||
| 525 | ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size, | 536 | ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, |
| 526 | GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE, | 537 | GUC_TOP_RESERVE_SIZE, offset, |
| 527 | PIN_NOEVICT); | 538 | I915_COLOR_UNEVICTABLE, PIN_NOEVICT); |
| 528 | if (ret) | 539 | if (ret) |
| 529 | drm_dbg(&ggtt->vm.i915->drm, | 540 | drm_dbg(&ggtt->vm.i915->drm, |
| 530 | "Failed to reserve top of GGTT for GuC\n"); | 541 | "Failed to reserve top of GGTT for GuC\n"); |
| @@ -1094,6 +1094,9 @@ __lrc_alloc_state(struct intel_context *ce, struct intel_engine_cs *engine) · 1093 unmodified lines | |||
| 1094 | I915_BO_ALLOC_PM_VOLATILE); | 1094 | I915_BO_ALLOC_PM_VOLATILE); |
| 1095 | if (IS_ERR(obj)) { | 1095 | if (IS_ERR(obj)) { |
| 1096 | obj = i915_gem_object_create_shmem(engine->i915, context_size); | 1096 | obj = i915_gem_object_create_shmem(engine->i915, context_size); |
| 1097 | if (IS_ERR(obj)) | ||
| 1098 | return ERR_CAST(obj); | ||
| 1099 | |||
| 1097 | /* | 1100 | /* |
| 1098 | * Wa_22016122933: For Media version 13.0, all Media GT shared | 1101 | * Wa_22016122933: For Media version 13.0, all Media GT shared |
| 1099 | * memory needs to be mapped as WC on CPU side and UC (PAT | 1102 | * memory needs to be mapped as WC on CPU side and UC (PAT |
| @@ -1102,8 +1105,6 @@ __lrc_alloc_state(struct intel_context *ce, struct intel_engine_cs *engine) · 2 unmodified lines | |||
| 1102 | if (intel_gt_needs_wa_22016122933(engine->gt)) | 1105 | if (intel_gt_needs_wa_22016122933(engine->gt)) |
| 1103 | i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); | 1106 | i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); |
| 1104 | } | 1107 | } |
| 1105 | if (IS_ERR(obj)) | ||
| 1106 | return ERR_CAST(obj); | ||
| 1107 | 1108 | ||
| 1108 | vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL); | 1109 | vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL); |
| 1109 | if (IS_ERR(vma)) { | 1110 | if (IS_ERR(vma)) { |
| @@ -1432,6 +1432,36 @@ static void guc_timestamp_ping(struct work_struct *wrk) · 1431 unmodified lines | |||
| 1432 | unsigned long index; | 1432 | unsigned long index; |
| 1433 | int srcu, ret; | 1433 | int srcu, ret; |
| 1434 | 1434 | ||
| 1435 | /* | ||
| 1436 | * Ideally the busyness worker should take a gt pm wakeref because the | ||
| 1437 | * worker only needs to be active while gt is awake. However, the | ||
| 1438 | * gt_park path cancels the worker synchronously and this complicates | ||
| 1439 | * the flow if the worker is also running at the same time. The cancel | ||
| 1440 | * waits for the worker and when the worker releases the wakeref, that | ||
| 1441 | * would call gt_park and would lead to a deadlock. | ||
| 1442 | * | ||
| 1443 | * The resolution is to take the global pm wakeref if runtime pm is | ||
| 1444 | * already active. If not, we don't need to update the busyness stats as | ||
| 1445 | * the stats would already be updated when the gt was parked. | ||
| 1446 | * | ||
| 1447 | * Note: | ||
| 1448 | * - We do not requeue the worker if we cannot take a reference to runtime | ||
| 1449 | * pm since intel_guc_busyness_unpark would requeue the worker in the | ||
| 1450 | * resume path. | ||
| 1451 | * | ||
| 1452 | * - If the gt was parked longer than time taken for GT timestamp to roll | ||
| 1453 | * over, we ignore those rollovers since we don't care about tracking | ||
| 1454 | * the exact GT time. We only care about roll overs when the gt is | ||
| 1455 | * active and running workloads. | ||
| 1456 | * | ||
| 1457 | * - There is a window of time between gt_park and runtime suspend, | ||
| 1458 | * where the worker may run. This is acceptable since the worker will | ||
| 1459 | * not find any new data to update busyness. | ||
| 1460 | */ | ||
| 1461 | wakeref = intel_runtime_pm_get_if_active(>->i915->runtime_pm); | ||
| 1462 | if (!wakeref) | ||
| 1463 | return; | ||
| 1464 | |||
| 1435 | /* | 1465 | /* |
| 1436 | * Synchronize with gt reset to make sure the worker does not | 1466 | * Synchronize with gt reset to make sure the worker does not |
| 1437 | * corrupt the engine/guc stats. NB: can't actually block waiting | 1467 | * corrupt the engine/guc stats. NB: can't actually block waiting |
| @@ -1440,10 +1470,9 @@ static void guc_timestamp_ping(struct work_struct *wrk) · 2 unmodified lines | |||
| 1440 | */ | 1470 | */ |
| 1441 | ret = intel_gt_reset_trylock(gt, &srcu); | 1471 | ret = intel_gt_reset_trylock(gt, &srcu); |
| 1442 | if (ret) | 1472 | if (ret) |
| 1443 | return; | 1473 | goto err_trylock; |
| 1444 | 1474 | ||
| 1445 | with_intel_runtime_pm(>->i915->runtime_pm, wakeref) | 1475 | __update_guc_busyness_stats(guc); |
| 1446 | __update_guc_busyness_stats(guc); | ||
| 1447 | 1476 | ||
| 1448 | /* adjust context stats for overflow */ | 1477 | /* adjust context stats for overflow */ |
| 1449 | xa_for_each(&guc->context_lookup, index, ce) | 1478 | xa_for_each(&guc->context_lookup, index, ce) |
| @@ -1452,6 +1481,9 @@ static void guc_timestamp_ping(struct work_struct *wrk) · 2 unmodified lines | |||
| 1452 | intel_gt_reset_unlock(gt, srcu); | 1481 | intel_gt_reset_unlock(gt, srcu); |
| 1453 | 1482 | ||
| 1454 | guc_enable_busyness_worker(guc); | 1483 | guc_enable_busyness_worker(guc); |
| 1484 | |||
| 1485 | err_trylock: | ||
| 1486 | intel_runtime_pm_put(>->i915->runtime_pm, wakeref); | ||
| 1455 | } | 1487 | } |
| 1456 | 1488 | ||
| 1457 | static int guc_action_enable_usage_stats(struct intel_guc *guc) | 1489 | static int guc_action_enable_usage_stats(struct intel_guc *guc) |
| @@ -334,6 +334,8 @@ static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge, · 333 unmodified lines | |||
| 334 | return; | 334 | return; |
| 335 | 335 | ||
| 336 | cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); | 336 | cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); |
| 337 | |||
| 338 | kfree(edid); | ||
| 337 | } else | 339 | } else |
| 338 | cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); | 340 | cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); |
| 339 | } | 341 | } |
| @@ -189,21 +189,12 @@ u_free(void *addr) · 188 unmodified lines | |||
| 189 | static inline void * | 189 | static inline void * |
| 190 | u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size) | 190 | u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size) |
| 191 | { | 191 | { |
| 192 | void *mem; | 192 | void __user *userptr = u64_to_user_ptr(user); |
| 193 | void __user *userptr = (void __force __user *)(uintptr_t)user; | 193 | size_t bytes; |
| 194 | 194 | ||
| 195 | size *= nmemb; | 195 | if (unlikely(check_mul_overflow(nmemb, size, &bytes))) |
| 196 | 196 | return ERR_PTR(-EOVERFLOW); | |
| 197 | mem = kvmalloc(size, GFP_KERNEL); | 197 | return vmemdup_user(userptr, bytes); |
| 198 | if (!mem) | ||
| 199 | return ERR_PTR(-ENOMEM); | ||
| 200 | |||
| 201 | if (copy_from_user(mem, userptr, size)) { | ||
| 202 | u_free(mem); | ||
| 203 | return ERR_PTR(-EFAULT); | ||
| 204 | } | ||
| 205 | |||
| 206 | return mem; | ||
| 207 | } | 198 | } |
| 208 | 199 | ||
| 209 | #include <nvif/object.h> | 200 | #include <nvif/object.h> |
| @@ -213,7 +213,7 @@ nouveau_exec_job_timeout(struct nouveau_job *job) · 212 unmodified lines | |||
| 213 | 213 | ||
| 214 | nouveau_sched_entity_fini(job->entity); | 214 | nouveau_sched_entity_fini(job->entity); |
| 215 | 215 | ||
| 216 | return DRM_GPU_SCHED_STAT_ENODEV; | 216 | return DRM_GPU_SCHED_STAT_NOMINAL; |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | static struct nouveau_job_ops nouveau_exec_job_ops = { | 219 | static struct nouveau_job_ops nouveau_exec_job_ops = { |
| @@ -207,7 +207,7 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha · 206 unmodified lines | |||
| 207 | int | 207 | int |
| 208 | nouveau_fence_emit(struct nouveau_fence *fence) | 208 | nouveau_fence_emit(struct nouveau_fence *fence) |
| 209 | { | 209 | { |
| 210 | struct nouveau_channel *chan = fence->channel; | 210 | struct nouveau_channel *chan = unrcu_pointer(fence->channel); |
| 211 | struct nouveau_fence_chan *fctx = chan->fence; | 211 | struct nouveau_fence_chan *fctx = chan->fence; |
| 212 | struct nouveau_fence_priv *priv = (void*)chan->drm->fence; | 212 | struct nouveau_fence_priv *priv = (void*)chan->drm->fence; |
| 213 | int ret; | 213 | int ret; |
| @@ -375,14 +375,20 @@ nouveau_sched_run_job(struct drm_sched_job *sched_job) · 374 unmodified lines | |||
| 375 | static enum drm_gpu_sched_stat | 375 | static enum drm_gpu_sched_stat |
| 376 | nouveau_sched_timedout_job(struct drm_sched_job *sched_job) | 376 | nouveau_sched_timedout_job(struct drm_sched_job *sched_job) |
| 377 | { | 377 | { |
| 378 | struct drm_gpu_scheduler *sched = sched_job->sched; | ||
| 378 | struct nouveau_job *job = to_nouveau_job(sched_job); | 379 | struct nouveau_job *job = to_nouveau_job(sched_job); |
| 380 | enum drm_gpu_sched_stat stat = DRM_GPU_SCHED_STAT_NOMINAL; | ||
| 379 | 381 | ||
| 380 | NV_PRINTK(warn, job->cli, "Job timed out.\n"); | 382 | drm_sched_stop(sched, sched_job); |
| 381 | 383 | ||
| 382 | if (job->ops->timeout) | 384 | if (job->ops->timeout) |
| 383 | return job->ops->timeout(job); | 385 | stat = job->ops->timeout(job); |
| 386 | else | ||
| 387 | NV_PRINTK(warn, job->cli, "Generic job timeout.\n"); | ||
| 388 | |||
| 389 | drm_sched_start(sched, true); | ||
| 384 | 390 | ||
| 385 | return DRM_GPU_SCHED_STAT_ENODEV; | 391 | return stat; |
| 386 | } | 392 | } |
| 387 | 393 | ||
| 388 | static void | 394 | static void |
| @@ -939,7 +939,7 @@ static void drm_test_mm_insert_range(struct kunit *test) · 938 unmodified lines | |||
| 939 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max - 1)); | 939 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max - 1)); |
| 940 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max / 2)); | 940 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max / 2)); |
| 941 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, | 941 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, |
| 942 | max / 2, max / 2)); | 942 | max / 2, max)); |
| 943 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, | 943 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, |
| 944 | max / 4 + 1, 3 * max / 4 - 1)); | 944 | max / 4 + 1, 3 * max / 4 - 1)); |
| 945 | 945 | ||
| @@ -361,7 +361,6 @@ static void virtio_gpu_complete_submit(struct virtio_gpu_submit *submit) · 360 unmodified lines | |||
| 361 | submit->buf = NULL; | 361 | submit->buf = NULL; |
| 362 | submit->buflist = NULL; | 362 | submit->buflist = NULL; |
| 363 | submit->sync_file = NULL; | 363 | submit->sync_file = NULL; |
| 364 | submit->out_fence = NULL; | ||
| 365 | submit->out_fence_fd = -1; | 364 | submit->out_fence_fd = -1; |
| 366 | } | 365 | } |
| 367 | 366 | ||
| @@ -441,8 +441,25 @@ err_release_lock: · 440 unmodified lines | |||
| 441 | 441 | ||
| 442 | void __i2c_dw_disable(struct dw_i2c_dev *dev) | 442 | void __i2c_dw_disable(struct dw_i2c_dev *dev) |
| 443 | { | 443 | { |
| 444 | unsigned int raw_intr_stats; | ||
| 445 | unsigned int enable; | ||
| 444 | int timeout = 100; | 446 | int timeout = 100; |
| 447 | bool abort_needed; | ||
| 445 | unsigned int status; | 448 | unsigned int status; |
| 449 | int ret; | ||
| 450 | |||
| 451 | regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats); | ||
| 452 | regmap_read(dev->map, DW_IC_ENABLE, &enable); | ||
| 453 | |||
| 454 | abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD; | ||
| 455 | if (abort_needed) { | ||
| 456 | regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT); | ||
| 457 | ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable, | ||
| 458 | !(enable & DW_IC_ENABLE_ABORT), 10, | ||
| 459 | 100); | ||
| 460 | if (ret) | ||
| 461 | dev_err(dev->dev, "timeout while trying to abort current transfer\n"); | ||
| 462 | } | ||
| 446 | 463 | ||
| 447 | do { | 464 | do { |
| 448 | __i2c_dw_disable_nowait(dev); | 465 | __i2c_dw_disable_nowait(dev); |
| @@ -98,6 +98,7 @@ · 97 unmodified lines | |||
| 98 | #define DW_IC_INTR_START_DET BIT(10) | 98 | #define DW_IC_INTR_START_DET BIT(10) |
| 99 | #define DW_IC_INTR_GEN_CALL BIT(11) | 99 | #define DW_IC_INTR_GEN_CALL BIT(11) |
| 100 | #define DW_IC_INTR_RESTART_DET BIT(12) | 100 | #define DW_IC_INTR_RESTART_DET BIT(12) |
| 101 | #define DW_IC_INTR_MST_ON_HOLD BIT(13) | ||
| 101 | 102 | ||
| 102 | #define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ | 103 | #define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ |
| 103 | DW_IC_INTR_TX_ABRT | \ | 104 | DW_IC_INTR_TX_ABRT | \ |
| @@ -108,6 +109,8 @@ · 4 unmodified lines | |||
| 108 | DW_IC_INTR_RX_UNDER | \ | 109 | DW_IC_INTR_RX_UNDER | \ |
| 109 | DW_IC_INTR_RD_REQ) | 110 | DW_IC_INTR_RD_REQ) |
| 110 | 111 | ||
| 112 | #define DW_IC_ENABLE_ABORT BIT(1) | ||
| 113 | |||
| 111 | #define DW_IC_STATUS_ACTIVITY BIT(0) | 114 | #define DW_IC_STATUS_ACTIVITY BIT(0) |
| 112 | #define DW_IC_STATUS_TFE BIT(2) | 115 | #define DW_IC_STATUS_TFE BIT(2) |
| 113 | #define DW_IC_STATUS_RFNE BIT(3) | 116 | #define DW_IC_STATUS_RFNE BIT(3) |
| @@ -1754,6 +1754,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) · 1753 unmodified lines | |||
| 1754 | "SMBus I801 adapter at %04lx", priv->smba); | 1754 | "SMBus I801 adapter at %04lx", priv->smba); |
| 1755 | err = i2c_add_adapter(&priv->adapter); | 1755 | err = i2c_add_adapter(&priv->adapter); |
| 1756 | if (err) { | 1756 | if (err) { |
| 1757 | platform_device_unregister(priv->tco_pdev); | ||
| 1757 | i801_acpi_remove(priv); | 1758 | i801_acpi_remove(priv); |
| 1758 | return err; | 1759 | return err; |
| 1759 | } | 1760 | } |
| @@ -694,6 +694,7 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, · 693 unmodified lines | |||
| 694 | { | 694 | { |
| 695 | struct i2c_msg *msgs; | 695 | struct i2c_msg *msgs; |
| 696 | int msgs_num; | 696 | int msgs_num; |
| 697 | bool do_complete = false; | ||
| 697 | 698 | ||
| 698 | msgs = bus->msgs; | 699 | msgs = bus->msgs; |
| 699 | msgs_num = bus->msgs_num; | 700 | msgs_num = bus->msgs_num; |
| @@ -722,23 +723,17 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, · 22 unmodified lines | |||
| 722 | msgs[1].flags & I2C_M_RD) | 723 | msgs[1].flags & I2C_M_RD) |
| 723 | msgs[1].len = info; | 724 | msgs[1].len = info; |
| 724 | } | 725 | } |
| 725 | if (completion_done(&bus->cmd_complete) == false) | 726 | do_complete = true; |
| 726 | complete(&bus->cmd_complete); | 727 | break; |
| 727 | break; | ||
| 728 | |||
| 729 | case I2C_NACK_IND: | 728 | case I2C_NACK_IND: |
| 730 | /* MASTER transmit got a NACK before tx all bytes */ | 729 | /* MASTER transmit got a NACK before tx all bytes */ |
| 731 | bus->cmd_err = -ENXIO; | 730 | bus->cmd_err = -ENXIO; |
| 732 | if (bus->master_or_slave == I2C_MASTER) | 731 | do_complete = true; |
| 733 | complete(&bus->cmd_complete); | ||
| 734 | |||
| 735 | break; | 732 | break; |
| 736 | case I2C_BUS_ERR_IND: | 733 | case I2C_BUS_ERR_IND: |
| 737 | /* Bus error */ | 734 | /* Bus error */ |
| 738 | bus->cmd_err = -EAGAIN; | 735 | bus->cmd_err = -EAGAIN; |
| 739 | if (bus->master_or_slave == I2C_MASTER) | 736 | do_complete = true; |
| 740 | complete(&bus->cmd_complete); | ||
| 741 | |||
| 742 | break; | 737 | break; |
| 743 | case I2C_WAKE_UP_IND: | 738 | case I2C_WAKE_UP_IND: |
| 744 | /* I2C wake up */ | 739 | /* I2C wake up */ |
| @@ -752,6 +747,8 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, · 7 unmodified lines | |||
| 752 | if (bus->slave) | 747 | if (bus->slave) |
| 753 | bus->master_or_slave = I2C_SLAVE; | 748 | bus->master_or_slave = I2C_SLAVE; |
| 754 | #endif | 749 | #endif |
| 750 | if (do_complete) | ||
| 751 | complete(&bus->cmd_complete); | ||
| 755 | } | 752 | } |
| 756 | 753 | ||
| 757 | static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus) | 754 | static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus) |
| @@ -710,7 +710,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) · 709 unmodified lines | |||
| 710 | * reset the IP instead of just flush fifos | 710 | * reset the IP instead of just flush fifos |
| 711 | */ | 711 | */ |
| 712 | ret = xiic_reinit(i2c); | 712 | ret = xiic_reinit(i2c); |
| 713 | if (!ret) | 713 | if (ret < 0) |
| 714 | dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); | 714 | dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); |
| 715 | 715 | ||
| 716 | if (i2c->rx_msg) { | 716 | if (i2c->rx_msg) { |
| @@ -341,7 +341,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, · 340 unmodified lines | |||
| 341 | priv->adap.lock_ops = &i2c_parent_lock_ops; | 341 | priv->adap.lock_ops = &i2c_parent_lock_ops; |
| 342 | 342 | ||
| 343 | /* Sanity check on class */ | 343 | /* Sanity check on class */ |
| 344 | if (i2c_mux_parent_classes(parent) & class) | 344 | if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED) |
| 345 | dev_err(&parent->dev, | 345 | dev_err(&parent->dev, |
| 346 | "Segment %d behind mux can't share classes with ancestors\n", | 346 | "Segment %d behind mux can't share classes with ancestors\n", |
| 347 | chan_id); | 347 | chan_id); |
| @@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) · 242 unmodified lines | |||
| 243 | 243 | ||
| 244 | props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); | 244 | props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); |
| 245 | props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); | 245 | props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); |
| 246 | if (!props[i].name || !props[i].value) { | ||
| 247 | err = -ENOMEM; | ||
| 248 | goto err_rollback; | ||
| 249 | } | ||
| 246 | props[i].length = 3; | 250 | props[i].length = 3; |
| 247 | 251 | ||
| 248 | of_changeset_init(&priv->chan[i].chgset); | 252 | of_changeset_init(&priv->chan[i].chgset); |
| @@ -105,8 +105,10 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux, · 104 unmodified lines | |||
| 105 | 105 | ||
| 106 | } else if (is_acpi_node(child)) { | 106 | } else if (is_acpi_node(child)) { |
| 107 | rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); | 107 | rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); |
| 108 | if (rc) | 108 | if (rc) { |
| 109 | fwnode_handle_put(child); | ||
| 109 | return dev_err_probe(dev, rc, "Cannot get address\n"); | 110 | return dev_err_probe(dev, rc, "Cannot get address\n"); |
| 111 | } | ||
| 110 | } | 112 | } |
| 111 | 113 | ||
| 112 | i++; | 114 | i++; |
| @@ -671,8 +671,7 @@ static int apple_dart_attach_dev(struct iommu_domain *domain, · 670 unmodified lines | |||
| 671 | return ret; | 671 | return ret; |
| 672 | 672 | ||
| 673 | switch (domain->type) { | 673 | switch (domain->type) { |
| 674 | case IOMMU_DOMAIN_DMA: | 674 | default: |
| 675 | case IOMMU_DOMAIN_UNMANAGED: | ||
| 676 | ret = apple_dart_domain_add_streams(dart_domain, cfg); | 675 | ret = apple_dart_domain_add_streams(dart_domain, cfg); |
| 677 | if (ret) | 676 | if (ret) |
| 678 | return ret; | 677 | return ret; |
| @@ -186,6 +186,15 @@ static void arm_smmu_free_shared_cd(struct arm_smmu_ctx_desc *cd) · 185 unmodified lines | |||
| 186 | } | 186 | } |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | /* | ||
| 190 | * Cloned from the MAX_TLBI_OPS in arch/arm64/include/asm/tlbflush.h, this | ||
| 191 | * is used as a threshold to replace per-page TLBI commands to issue in the | ||
| 192 | * command queue with an address-space TLBI command, when SMMU w/o a range | ||
| 193 | * invalidation feature handles too many per-page TLBI commands, which will | ||
| 194 | * otherwise result in a soft lockup. | ||
| 195 | */ | ||
| 196 | #define CMDQ_MAX_TLBI_OPS (1 << (PAGE_SHIFT - 3)) | ||
| 197 | |||
| 189 | static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn, | 198 | static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn, |
| 190 | struct mm_struct *mm, | 199 | struct mm_struct *mm, |
| 191 | unsigned long start, | 200 | unsigned long start, |
| @@ -201,8 +210,13 @@ static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn, · 9 unmodified lines | |||
| 201 | * range. So do a simple translation here by calculating size correctly. | 210 | * range. So do a simple translation here by calculating size correctly. |
| 202 | */ | 211 | */ |
| 203 | size = end - start; | 212 | size = end - start; |
| 204 | if (size == ULONG_MAX) | 213 | if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_RANGE_INV)) { |
| 205 | size = 0; | 214 | if (size >= CMDQ_MAX_TLBI_OPS * PAGE_SIZE) |
| 215 | size = 0; | ||
| 216 | } else { | ||
| 217 | if (size == ULONG_MAX) | ||
| 218 | size = 0; | ||
| 219 | } | ||
| 206 | 220 | ||
| 207 | if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) { | 221 | if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) { |
| 208 | if (!size) | 222 | if (!size) |
| @@ -1895,18 +1895,23 @@ static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd, · 1894 unmodified lines | |||
| 1895 | /* Get the leaf page size */ | 1895 | /* Get the leaf page size */ |
| 1896 | tg = __ffs(smmu_domain->domain.pgsize_bitmap); | 1896 | tg = __ffs(smmu_domain->domain.pgsize_bitmap); |
| 1897 | 1897 | ||
| 1898 | num_pages = size >> tg; | ||
| 1899 | |||
| 1898 | /* Convert page size of 12,14,16 (log2) to 1,2,3 */ | 1900 | /* Convert page size of 12,14,16 (log2) to 1,2,3 */ |
| 1899 | cmd->tlbi.tg = (tg - 10) / 2; | 1901 | cmd->tlbi.tg = (tg - 10) / 2; |
| 1900 | 1902 | ||
| 1901 | /* | 1903 | /* |
| 1902 | * Determine what level the granule is at. For non-leaf, io-pgtable | 1904 | * Determine what level the granule is at. For non-leaf, both |
| 1903 | * assumes .tlb_flush_walk can invalidate multiple levels at once, | 1905 | * io-pgtable and SVA pass a nominal last-level granule because |
| 1904 | * so ignore the nominal last-level granule and leave TTL=0. | 1906 | * they don't know what level(s) actually apply, so ignore that |
| 1907 | * and leave TTL=0. However for various errata reasons we still | ||
| 1908 | * want to use a range command, so avoid the SVA corner case | ||
| 1909 | * where both scale and num could be 0 as well. | ||
| 1905 | */ | 1910 | */ |
| 1906 | if (cmd->tlbi.leaf) | 1911 | if (cmd->tlbi.leaf) |
| 1907 | cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3)); | 1912 | cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3)); |
| 1908 | 1913 | else if ((num_pages & CMDQ_TLBI_RANGE_NUM_MAX) == 1) | |
| 1909 | num_pages = size >> tg; | 1914 | num_pages++; |
| 1910 | } | 1915 | } |
| 1911 | 1916 | ||
| 1912 | cmds.num = 0; | 1917 | cmds.num = 0; |
| @@ -2998,13 +2998,6 @@ static int iommu_suspend(void) · 2997 unmodified lines | |||
| 2998 | struct intel_iommu *iommu = NULL; | 2998 | struct intel_iommu *iommu = NULL; |
| 2999 | unsigned long flag; | 2999 | unsigned long flag; |
| 3000 | 3000 | ||
| 3001 | for_each_active_iommu(iommu, drhd) { | ||
| 3002 | iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32), | ||
| 3003 | GFP_KERNEL); | ||
| 3004 | if (!iommu->iommu_state) | ||
| 3005 | goto nomem; | ||
| 3006 | } | ||
| 3007 | |||
| 3008 | iommu_flush_all(); | 3001 | iommu_flush_all(); |
| 3009 | 3002 | ||
| 3010 | for_each_active_iommu(iommu, drhd) { | 3003 | for_each_active_iommu(iommu, drhd) { |
| @@ -3024,12 +3017,6 @@ static int iommu_suspend(void) · 13 unmodified lines | |||
| 3024 | raw_spin_unlock_irqrestore(&iommu->register_lock, flag); | 3017 | raw_spin_unlock_irqrestore(&iommu->register_lock, flag); |
| 3025 | } | 3018 | } |
| 3026 | return 0; | 3019 | return 0; |
| 3027 | |||
| 3028 | nomem: | ||
| 3029 | for_each_active_iommu(iommu, drhd) | ||
| 3030 | kfree(iommu->iommu_state); | ||
| 3031 | |||
| 3032 | return -ENOMEM; | ||
| 3033 | } | 3020 | } |
| 3034 | 3021 | ||
| 3035 | static void iommu_resume(void) | 3022 | static void iommu_resume(void) |
| @@ -3061,9 +3048,6 @@ static void iommu_resume(void) · 25 unmodified lines | |||
| 3061 | 3048 | ||
| 3062 | raw_spin_unlock_irqrestore(&iommu->register_lock, flag); | 3049 | raw_spin_unlock_irqrestore(&iommu->register_lock, flag); |
| 3063 | } | 3050 | } |
| 3064 | |||
| 3065 | for_each_active_iommu(iommu, drhd) | ||
| 3066 | kfree(iommu->iommu_state); | ||
| 3067 | } | 3051 | } |
| 3068 | 3052 | ||
| 3069 | static struct syscore_ops iommu_syscore_ops = { | 3053 | static struct syscore_ops iommu_syscore_ops = { |
| @@ -681,7 +681,7 @@ struct intel_iommu { · 680 unmodified lines | |||
| 681 | struct iopf_queue *iopf_queue; | 681 | struct iopf_queue *iopf_queue; |
| 682 | unsigned char iopfq_name[16]; | 682 | unsigned char iopfq_name[16]; |
| 683 | struct q_inval *qi; /* Queued invalidation info */ | 683 | struct q_inval *qi; /* Queued invalidation info */ |
| 684 | u32 *iommu_state; /* Store iommu states between suspend and resume.*/ | 684 | u32 iommu_state[MAX_SR_DMAR_REGS]; /* Store iommu states between suspend and resume.*/ |
| 685 | 685 | ||
| 686 | #ifdef CONFIG_IRQ_REMAP | 686 | #ifdef CONFIG_IRQ_REMAP |
| 687 | struct ir_table *ir_table; /* Interrupt remapping info */ | 687 | struct ir_table *ir_table; /* Interrupt remapping info */ |
| @@ -262,7 +262,7 @@ struct mtk_iommu_data { · 261 unmodified lines | |||
| 262 | struct device *smicomm_dev; | 262 | struct device *smicomm_dev; |
| 263 | 263 | ||
| 264 | struct mtk_iommu_bank_data *bank; | 264 | struct mtk_iommu_bank_data *bank; |
| 265 | struct mtk_iommu_domain *share_dom; /* For 2 HWs share pgtable */ | 265 | struct mtk_iommu_domain *share_dom; |
| 266 | 266 | ||
| 267 | struct regmap *pericfg; | 267 | struct regmap *pericfg; |
| 268 | struct mutex mutex; /* Protect m4u_group/m4u_dom above */ | 268 | struct mutex mutex; /* Protect m4u_group/m4u_dom above */ |
| @@ -643,8 +643,8 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, · 374 unmodified lines | |||
| 643 | struct mtk_iommu_domain *share_dom = data->share_dom; | 643 | struct mtk_iommu_domain *share_dom = data->share_dom; |
| 644 | const struct mtk_iommu_iova_region *region; | 644 | const struct mtk_iommu_iova_region *region; |
| 645 | 645 | ||
| 646 | /* Always use share domain in sharing pgtable case */ | 646 | /* Share pgtable when 2 MM IOMMU share the pgtable or one IOMMU use multiple iova ranges */ |
| 647 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE) && share_dom) { | 647 | if (share_dom) { |
| 648 | dom->iop = share_dom->iop; | 648 | dom->iop = share_dom->iop; |
| 649 | dom->cfg = share_dom->cfg; | 649 | dom->cfg = share_dom->cfg; |
| 650 | dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap; | 650 | dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap; |
| @@ -677,8 +677,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, · 26 unmodified lines | |||
| 677 | /* Update our support page sizes bitmap */ | 677 | /* Update our support page sizes bitmap */ |
| 678 | dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap; | 678 | dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap; |
| 679 | 679 | ||
| 680 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) | 680 | data->share_dom = dom; |
| 681 | data->share_dom = dom; | ||
| 682 | 681 | ||
| 683 | update_iova_region: | 682 | update_iova_region: |
| 684 | /* Update the iova region for this domain */ | 683 | /* Update the iova region for this domain */ |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/irqdomain.h> | 12 | #include <linux/irqdomain.h> |
| 13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
| 14 | #include <linux/irqchip.h> | 14 | #include <linux/irqchip.h> |
| 15 | #include <linux/irqchip/xtensa-mx.h> | ||
| 15 | #include <linux/of.h> | 16 | #include <linux/of.h> |
| 16 | 17 | ||
| 17 | #include <asm/mxregs.h> | 18 | #include <asm/mxregs.h> |
| @@ -479,10 +479,6 @@ int led_compose_name(struct device *dev, struct led_init_data *init_data, · 478 unmodified lines | |||
| 479 | 479 | ||
| 480 | led_parse_fwnode_props(dev, fwnode, &props); | 480 | led_parse_fwnode_props(dev, fwnode, &props); |
| 481 | 481 | ||
| 482 | /* We want to label LEDs that can produce full range of colors | ||
| 483 | * as RGB, not multicolor */ | ||
| 484 | BUG_ON(props.color == LED_COLOR_ID_MULTI); | ||
| 485 | |||
| 486 | if (props.label) { | 482 | if (props.label) { |
| 487 | /* | 483 | /* |
| 488 | * If init_data.devicename is NULL, then it indicates that | 484 | * If init_data.devicename is NULL, then it indicates that |
| @@ -241,6 +241,7 @@ config MFD_CS42L43 · 240 unmodified lines | |||
| 241 | tristate | 241 | tristate |
| 242 | select MFD_CORE | 242 | select MFD_CORE |
| 243 | select REGMAP | 243 | select REGMAP |
| 244 | select REGMAP_IRQ | ||
| 244 | 245 | ||
| 245 | config MFD_CS42L43_I2C | 246 | config MFD_CS42L43_I2C |
| 246 | tristate "Cirrus Logic CS42L43 (I2C)" | 247 | tristate "Cirrus Logic CS42L43 (I2C)" |
| @@ -1178,8 +1178,8 @@ err: · 1177 unmodified lines | |||
| 1178 | } | 1178 | } |
| 1179 | 1179 | ||
| 1180 | EXPORT_NS_GPL_DEV_PM_OPS(cs42l43_pm_ops, MFD_CS42L43) = { | 1180 | EXPORT_NS_GPL_DEV_PM_OPS(cs42l43_pm_ops, MFD_CS42L43) = { |
| 1181 | SET_SYSTEM_SLEEP_PM_OPS(cs42l43_suspend, cs42l43_resume) | 1181 | SYSTEM_SLEEP_PM_OPS(cs42l43_suspend, cs42l43_resume) |
| 1182 | SET_RUNTIME_PM_OPS(cs42l43_runtime_suspend, cs42l43_runtime_resume, NULL) | 1182 | RUNTIME_PM_OPS(cs42l43_runtime_suspend, cs42l43_runtime_resume, NULL) |
| 1183 | }; | 1183 | }; |
| 1184 | 1184 | ||
| 1185 | MODULE_DESCRIPTION("CS42L43 Core Driver"); | 1185 | MODULE_DESCRIPTION("CS42L43 Core Driver"); |
| @@ -83,63 +83,20 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr) · 82 unmodified lines | |||
| 83 | 83 | ||
| 84 | static void rts5227_init_from_cfg(struct rtsx_pcr *pcr) | 84 | static void rts5227_init_from_cfg(struct rtsx_pcr *pcr) |
| 85 | { | 85 | { |
| 86 | struct pci_dev *pdev = pcr->pci; | ||
| 87 | int l1ss; | ||
| 88 | u32 lval; | ||
| 89 | struct rtsx_cr_option *option = &pcr->option; | 86 | struct rtsx_cr_option *option = &pcr->option; |
| 90 | 87 | ||
| 91 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 92 | if (!l1ss) | ||
| 93 | return; | ||
| 94 | |||
| 95 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 96 | |||
| 97 | if (CHK_PCI_PID(pcr, 0x522A)) { | 88 | if (CHK_PCI_PID(pcr, 0x522A)) { |
| 98 | if (0 == (lval & 0x0F)) | 89 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN |
| 99 | rtsx_pci_enable_oobs_polling(pcr); | 90 | | PM_L1_1_EN | PM_L1_2_EN)) |
| 100 | else | ||
| 101 | rtsx_pci_disable_oobs_polling(pcr); | 91 | rtsx_pci_disable_oobs_polling(pcr); |
| 92 | else | ||
| 93 | rtsx_pci_enable_oobs_polling(pcr); | ||
| 102 | } | 94 | } |
| 103 | 95 | ||
| 104 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 105 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 106 | else | ||
| 107 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 108 | |||
| 109 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 110 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 111 | else | ||
| 112 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 113 | |||
| 114 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 115 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 116 | else | ||
| 117 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | ||
| 118 | |||
| 119 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 120 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 121 | else | ||
| 122 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 123 | |||
| 124 | if (option->ltr_en) { | 96 | if (option->ltr_en) { |
| 125 | u16 val; | 97 | if (option->ltr_enabled) |
| 126 | |||
| 127 | pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); | ||
| 128 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 129 | option->ltr_enabled = true; | ||
| 130 | option->ltr_active = true; | ||
| 131 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 98 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 132 | } else { | ||
| 133 | option->ltr_enabled = false; | ||
| 134 | } | ||
| 135 | } | 99 | } |
| 136 | |||
| 137 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | ||
| 138 | | PM_L1_1_EN | PM_L1_2_EN)) | ||
| 139 | option->force_clkreq_0 = false; | ||
| 140 | else | ||
| 141 | option->force_clkreq_0 = true; | ||
| 142 | |||
| 143 | } | 100 | } |
| 144 | 101 | ||
| 145 | static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) | 102 | static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) |
| @@ -195,7 +152,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) · 49 unmodified lines | |||
| 195 | } | 152 | } |
| 196 | } | 153 | } |
| 197 | 154 | ||
| 198 | if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) | 155 | if (option->force_clkreq_0) |
| 199 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, | 156 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, |
| 200 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | 157 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
| 201 | else | 158 | else |
| @@ -386,59 +386,25 @@ static void rts5228_process_ocp(struct rtsx_pcr *pcr) · 385 unmodified lines | |||
| 386 | 386 | ||
| 387 | static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) | 387 | static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) |
| 388 | { | 388 | { |
| 389 | struct pci_dev *pdev = pcr->pci; | ||
| 390 | int l1ss; | ||
| 391 | u32 lval; | ||
| 392 | struct rtsx_cr_option *option = &pcr->option; | 389 | struct rtsx_cr_option *option = &pcr->option; |
| 393 | 390 | ||
| 394 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | 391 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN |
| 395 | if (!l1ss) | 392 | | PM_L1_1_EN | PM_L1_2_EN)) |
| 396 | return; | ||
| 397 | |||
| 398 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 399 | |||
| 400 | if (0 == (lval & 0x0F)) | ||
| 401 | rtsx_pci_enable_oobs_polling(pcr); | ||
| 402 | else | ||
| 403 | rtsx_pci_disable_oobs_polling(pcr); | 393 | rtsx_pci_disable_oobs_polling(pcr); |
| 404 | |||
| 405 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 406 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 407 | else | ||
| 408 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 409 | |||
| 410 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 411 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 412 | else | ||
| 413 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 414 | |||
| 415 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 416 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 417 | else | 394 | else |
| 418 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | 395 | rtsx_pci_enable_oobs_polling(pcr); |
| 419 | |||
| 420 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 421 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 422 | else | ||
| 423 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 424 | 396 | ||
| 425 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); | 397 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); |
| 426 | if (option->ltr_en) { | ||
| 427 | u16 val; | ||
| 428 | 398 | ||
| 429 | pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); | 399 | if (option->ltr_en) { |
| 430 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | 400 | if (option->ltr_enabled) |
| 431 | option->ltr_enabled = true; | ||
| 432 | option->ltr_active = true; | ||
| 433 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 401 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 434 | } else { | ||
| 435 | option->ltr_enabled = false; | ||
| 436 | } | ||
| 437 | } | 402 | } |
| 438 | } | 403 | } |
| 439 | 404 | ||
| 440 | static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) | 405 | static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) |
| 441 | { | 406 | { |
| 407 | struct rtsx_cr_option *option = &pcr->option; | ||
| 442 | 408 | ||
| 443 | rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, | 409 | rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, |
| 444 | CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); | 410 | CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); |
| @@ -469,6 +435,17 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) · 24 unmodified lines | |||
| 469 | else | 435 | else |
| 470 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); | 436 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); |
| 471 | 437 | ||
| 438 | /* | ||
| 439 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | ||
| 440 | * to drive low, and we forcibly request clock. | ||
| 441 | */ | ||
| 442 | if (option->force_clkreq_0) | ||
| 443 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 444 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | ||
| 445 | else | ||
| 446 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 447 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 448 | |||
| 472 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); | 449 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); |
| 473 | 450 | ||
| 474 | if (pcr->rtd3_en) { | 451 | if (pcr->rtd3_en) { |
| @@ -86,64 +86,22 @@ static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) · 85 unmodified lines | |||
| 86 | 86 | ||
| 87 | static void rts5249_init_from_cfg(struct rtsx_pcr *pcr) | 87 | static void rts5249_init_from_cfg(struct rtsx_pcr *pcr) |
| 88 | { | 88 | { |
| 89 | struct pci_dev *pdev = pcr->pci; | ||
| 90 | int l1ss; | ||
| 91 | struct rtsx_cr_option *option = &(pcr->option); | 89 | struct rtsx_cr_option *option = &(pcr->option); |
| 92 | u32 lval; | ||
| 93 | |||
| 94 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 95 | if (!l1ss) | ||
| 96 | return; | ||
| 97 | |||
| 98 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 99 | 90 | ||
| 100 | if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { | 91 | if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { |
| 101 | if (0 == (lval & 0x0F)) | 92 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN |
| 102 | rtsx_pci_enable_oobs_polling(pcr); | 93 | | PM_L1_1_EN | PM_L1_2_EN)) |
| 103 | else | ||
| 104 | rtsx_pci_disable_oobs_polling(pcr); | 94 | rtsx_pci_disable_oobs_polling(pcr); |
| 95 | else | ||
| 96 | rtsx_pci_enable_oobs_polling(pcr); | ||
| 105 | } | 97 | } |
| 106 | 98 | ||
| 107 | |||
| 108 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 109 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 110 | |||
| 111 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 112 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 113 | |||
| 114 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 115 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 116 | |||
| 117 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 118 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 119 | |||
| 120 | if (option->ltr_en) { | 99 | if (option->ltr_en) { |
| 121 | u16 val; | 100 | if (option->ltr_enabled) |
| 122 | |||
| 123 | pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); | ||
| 124 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 125 | option->ltr_enabled = true; | ||
| 126 | option->ltr_active = true; | ||
| 127 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 101 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 128 | } else { | ||
| 129 | option->ltr_enabled = false; | ||
| 130 | } | ||
| 131 | } | 102 | } |
| 132 | } | 103 | } |
| 133 | 104 | ||
| 134 | static int rts5249_init_from_hw(struct rtsx_pcr *pcr) | ||
| 135 | { | ||
| 136 | struct rtsx_cr_option *option = &(pcr->option); | ||
| 137 | |||
| 138 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | ||
| 139 | | PM_L1_1_EN | PM_L1_2_EN)) | ||
| 140 | option->force_clkreq_0 = false; | ||
| 141 | else | ||
| 142 | option->force_clkreq_0 = true; | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static void rts52xa_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime) | 105 | static void rts52xa_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime) |
| 148 | { | 106 | { |
| 149 | /* Set relink_time to 0 */ | 107 | /* Set relink_time to 0 */ |
| @@ -276,7 +234,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) · 126 unmodified lines | |||
| 276 | struct rtsx_cr_option *option = &(pcr->option); | 234 | struct rtsx_cr_option *option = &(pcr->option); |
| 277 | 235 | ||
| 278 | rts5249_init_from_cfg(pcr); | 236 | rts5249_init_from_cfg(pcr); |
| 279 | rts5249_init_from_hw(pcr); | ||
| 280 | 237 | ||
| 281 | rtsx_pci_init_cmd(pcr); | 238 | rtsx_pci_init_cmd(pcr); |
| 282 | 239 | ||
| @@ -327,11 +284,12 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) · 44 unmodified lines | |||
| 327 | } | 284 | } |
| 328 | } | 285 | } |
| 329 | 286 | ||
| 287 | |||
| 330 | /* | 288 | /* |
| 331 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | 289 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced |
| 332 | * to drive low, and we forcibly request clock. | 290 | * to drive low, and we forcibly request clock. |
| 333 | */ | 291 | */ |
| 334 | if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) | 292 | if (option->force_clkreq_0) |
| 335 | rtsx_pci_write_register(pcr, PETXCFG, | 293 | rtsx_pci_write_register(pcr, PETXCFG, |
| 336 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | 294 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
| 337 | else | 295 | else |
| @@ -480,47 +480,19 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr) · 479 unmodified lines | |||
| 480 | 480 | ||
| 481 | static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) | 481 | static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) |
| 482 | { | 482 | { |
| 483 | struct pci_dev *pdev = pcr->pci; | ||
| 484 | int l1ss; | ||
| 485 | struct rtsx_cr_option *option = &pcr->option; | 483 | struct rtsx_cr_option *option = &pcr->option; |
| 486 | u32 lval; | ||
| 487 | |||
| 488 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 489 | if (!l1ss) | ||
| 490 | return; | ||
| 491 | |||
| 492 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 493 | |||
| 494 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 495 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 496 | |||
| 497 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 498 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 499 | |||
| 500 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 501 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 502 | |||
| 503 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 504 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 505 | 484 | ||
| 506 | rts5260_pwr_saving_setting(pcr); | 485 | rts5260_pwr_saving_setting(pcr); |
| 507 | 486 | ||
| 508 | if (option->ltr_en) { | 487 | if (option->ltr_en) { |
| 509 | u16 val; | 488 | if (option->ltr_enabled) |
| 510 | |||
| 511 | pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); | ||
| 512 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 513 | option->ltr_enabled = true; | ||
| 514 | option->ltr_active = true; | ||
| 515 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 489 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 516 | } else { | ||
| 517 | option->ltr_enabled = false; | ||
| 518 | } | ||
| 519 | } | 490 | } |
| 520 | } | 491 | } |
| 521 | 492 | ||
| 522 | static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) | 493 | static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) |
| 523 | { | 494 | { |
| 495 | struct rtsx_cr_option *option = &pcr->option; | ||
| 524 | 496 | ||
| 525 | /* Set mcu_cnt to 7 to ensure data can be sampled properly */ | 497 | /* Set mcu_cnt to 7 to ensure data can be sampled properly */ |
| 526 | rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); | 498 | rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); |
| @@ -539,6 +511,17 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) · 12 unmodified lines | |||
| 539 | 511 | ||
| 540 | rts5260_init_hw(pcr); | 512 | rts5260_init_hw(pcr); |
| 541 | 513 | ||
| 514 | /* | ||
| 515 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | ||
| 516 | * to drive low, and we forcibly request clock. | ||
| 517 | */ | ||
| 518 | if (option->force_clkreq_0) | ||
| 519 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 520 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | ||
| 521 | else | ||
| 522 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 523 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 524 | |||
| 542 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); | 525 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); |
| 543 | 526 | ||
| 544 | return 0; | 527 | return 0; |
| @@ -454,54 +454,17 @@ static void rts5261_init_from_hw(struct rtsx_pcr *pcr) · 453 unmodified lines | |||
| 454 | 454 | ||
| 455 | static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) | 455 | static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) |
| 456 | { | 456 | { |
| 457 | struct pci_dev *pdev = pcr->pci; | ||
| 458 | int l1ss; | ||
| 459 | u32 lval; | ||
| 460 | struct rtsx_cr_option *option = &pcr->option; | 457 | struct rtsx_cr_option *option = &pcr->option; |
| 461 | 458 | ||
| 462 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 463 | if (!l1ss) | ||
| 464 | return; | ||
| 465 | |||
| 466 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 467 | |||
| 468 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 469 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 470 | else | ||
| 471 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 472 | |||
| 473 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 474 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 475 | else | ||
| 476 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 477 | |||
| 478 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 479 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 480 | else | ||
| 481 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | ||
| 482 | |||
| 483 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 484 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 485 | else | ||
| 486 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 487 | |||
| 488 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); | ||
| 489 | if (option->ltr_en) { | 459 | if (option->ltr_en) { |
| 490 | u16 val; | 460 | if (option->ltr_enabled) |
| 491 | |||
| 492 | pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); | ||
| 493 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 494 | option->ltr_enabled = true; | ||
| 495 | option->ltr_active = true; | ||
| 496 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 461 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 497 | } else { | ||
| 498 | option->ltr_enabled = false; | ||
| 499 | } | ||
| 500 | } | 462 | } |
| 501 | } | 463 | } |
| 502 | 464 | ||
| 503 | static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) | 465 | static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) |
| 504 | { | 466 | { |
| 467 | struct rtsx_cr_option *option = &pcr->option; | ||
| 505 | u32 val; | 468 | u32 val; |
| 506 | 469 | ||
| 507 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, | 470 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, |
| @@ -547,6 +510,17 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) · 39 unmodified lines | |||
| 547 | else | 510 | else |
| 548 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); | 511 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); |
| 549 | 512 | ||
| 513 | /* | ||
| 514 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | ||
| 515 | * to drive low, and we forcibly request clock. | ||
| 516 | */ | ||
| 517 | if (option->force_clkreq_0) | ||
| 518 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 519 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | ||
| 520 | else | ||
| 521 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 522 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 523 | |||
| 550 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); | 524 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); |
| 551 | 525 | ||
| 552 | if (pcr->rtd3_en) { | 526 | if (pcr->rtd3_en) { |
| @@ -1326,11 +1326,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) · 1325 unmodified lines | |||
| 1326 | return err; | 1326 | return err; |
| 1327 | } | 1327 | } |
| 1328 | 1328 | ||
| 1329 | if (pcr->aspm_mode == ASPM_MODE_REG) { | 1329 | if (pcr->aspm_mode == ASPM_MODE_REG) |
| 1330 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); | 1330 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); |
| 1331 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 1332 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 1333 | } | ||
| 1334 | 1331 | ||
| 1335 | /* No CD interrupt if probing driver with card inserted. | 1332 | /* No CD interrupt if probing driver with card inserted. |
| 1336 | * So we need to initialize pcr->card_exist here. | 1333 | * So we need to initialize pcr->card_exist here. |
| @@ -1345,7 +1342,9 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) · 8 unmodified lines | |||
| 1345 | 1342 | ||
| 1346 | static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) | 1343 | static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) |
| 1347 | { | 1344 | { |
| 1348 | int err; | 1345 | struct rtsx_cr_option *option = &(pcr->option); |
| 1346 | int err, l1ss; | ||
| 1347 | u32 lval; | ||
| 1349 | u16 cfg_val; | 1348 | u16 cfg_val; |
| 1350 | u8 val; | 1349 | u8 val; |
| 1351 | 1350 | ||
| @@ -1430,6 +1429,48 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) · 78 unmodified lines | |||
| 1430 | pcr->aspm_enabled = true; | 1429 | pcr->aspm_enabled = true; |
| 1431 | } | 1430 | } |
| 1432 | 1431 | ||
| 1432 | l1ss = pci_find_ext_capability(pcr->pci, PCI_EXT_CAP_ID_L1SS); | ||
| 1433 | if (l1ss) { | ||
| 1434 | pci_read_config_dword(pcr->pci, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 1435 | |||
| 1436 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 1437 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 1438 | else | ||
| 1439 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 1440 | |||
| 1441 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 1442 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 1443 | else | ||
| 1444 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 1445 | |||
| 1446 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 1447 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 1448 | else | ||
| 1449 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | ||
| 1450 | |||
| 1451 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 1452 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 1453 | else | ||
| 1454 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 1455 | |||
| 1456 | pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cfg_val); | ||
| 1457 | if (cfg_val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 1458 | option->ltr_enabled = true; | ||
| 1459 | option->ltr_active = true; | ||
| 1460 | } else { | ||
| 1461 | option->ltr_enabled = false; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | ||
| 1465 | | PM_L1_1_EN | PM_L1_2_EN)) | ||
| 1466 | option->force_clkreq_0 = false; | ||
| 1467 | else | ||
| 1468 | option->force_clkreq_0 = true; | ||
| 1469 | } else { | ||
| 1470 | option->ltr_enabled = false; | ||
| 1471 | option->force_clkreq_0 = true; | ||
| 1472 | } | ||
| 1473 | |||
| 1433 | if (pcr->ops->fetch_vendor_settings) | 1474 | if (pcr->ops->fetch_vendor_settings) |
| 1434 | pcr->ops->fetch_vendor_settings(pcr); | 1475 | pcr->ops->fetch_vendor_settings(pcr); |
| 1435 | 1476 | ||
| @@ -894,6 +894,13 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, · 893 unmodified lines | |||
| 894 | return -EINVAL; | 894 | return -EINVAL; |
| 895 | } | 895 | } |
| 896 | 896 | ||
| 897 | /* UBI cannot work on flashes with zero erasesize. */ | ||
| 898 | if (!mtd->erasesize) { | ||
| 899 | pr_err("ubi: refuse attaching mtd%d - zero erasesize flash is not supported\n", | ||
| 900 | mtd->index); | ||
| 901 | return -EINVAL; | ||
| 902 | } | ||
| 903 | |||
| 897 | if (ubi_num == UBI_DEV_NUM_AUTO) { | 904 | if (ubi_num == UBI_DEV_NUM_AUTO) { |
| 898 | /* Search for an empty slot in the @ubi_devices array */ | 905 | /* Search for an empty slot in the @ubi_devices array */ |
| 899 | for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) | 906 | for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) |
| @@ -2958,14 +2958,16 @@ static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) · 2957 unmodified lines | |||
| 2958 | * from the wrong location resulting in the switch booting | 2958 | * from the wrong location resulting in the switch booting |
| 2959 | * to wrong mode and inoperable. | 2959 | * to wrong mode and inoperable. |
| 2960 | */ | 2960 | */ |
| 2961 | mv88e6xxx_g1_wait_eeprom_done(chip); | 2961 | if (chip->info->ops->get_eeprom) |
| 2962 | mv88e6xxx_g2_eeprom_wait(chip); | ||
| 2962 | 2963 | ||
| 2963 | gpiod_set_value_cansleep(gpiod, 1); | 2964 | gpiod_set_value_cansleep(gpiod, 1); |
| 2964 | usleep_range(10000, 20000); | 2965 | usleep_range(10000, 20000); |
| 2965 | gpiod_set_value_cansleep(gpiod, 0); | 2966 | gpiod_set_value_cansleep(gpiod, 0); |
| 2966 | usleep_range(10000, 20000); | 2967 | usleep_range(10000, 20000); |
| 2967 | 2968 | ||
| 2968 | mv88e6xxx_g1_wait_eeprom_done(chip); | 2969 | if (chip->info->ops->get_eeprom) |
| 2970 | mv88e6xxx_g2_eeprom_wait(chip); | ||
| 2969 | } | 2971 | } |
| 2970 | } | 2972 | } |
| 2971 | 2973 | ||
| @@ -75,37 +75,6 @@ static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip) · 74 unmodified lines | |||
| 75 | return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); | 75 | return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip) | ||
| 79 | { | ||
| 80 | const unsigned long timeout = jiffies + 1 * HZ; | ||
| 81 | u16 val; | ||
| 82 | int err; | ||
| 83 | |||
| 84 | /* Wait up to 1 second for the switch to finish reading the | ||
| 85 | * EEPROM. | ||
| 86 | */ | ||
| 87 | while (time_before(jiffies, timeout)) { | ||
| 88 | err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val); | ||
| 89 | if (err) { | ||
| 90 | dev_err(chip->dev, "Error reading status"); | ||
| 91 | return; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* If the switch is still resetting, it may not | ||
| 95 | * respond on the bus, and so MDIO read returns | ||
| 96 | * 0xffff. Differentiate between that, and waiting for | ||
| 97 | * the EEPROM to be done by bit 0 being set. | ||
| 98 | */ | ||
| 99 | if (val != 0xffff && | ||
| 100 | val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE)) | ||
| 101 | return; | ||
| 102 | |||
| 103 | usleep_range(1000, 2000); | ||
| 104 | } | ||
| 105 | |||
| 106 | dev_err(chip->dev, "Timeout waiting for EEPROM done"); | ||
| 107 | } | ||
| 108 | |||
| 109 | /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 | 78 | /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 |
| 110 | * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 | 79 | * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 |
| 111 | * Offset 0x03: Switch MAC Address Register Bytes 4 & 5 | 80 | * Offset 0x03: Switch MAC Address Register Bytes 4 & 5 |
| @@ -282,7 +282,6 @@ int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr); · 281 unmodified lines | |||
| 282 | int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip); | 282 | int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip); |
| 283 | int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip); | 283 | int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip); |
| 284 | int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip); | 284 | int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip); |
| 285 | void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip); | ||
| 286 | 285 | ||
| 287 | int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip); | 286 | int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip); |
| 288 | int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip); | 287 | int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip); |
| @@ -340,7 +340,7 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip) · 339 unmodified lines | |||
| 340 | * Offset 0x15: EEPROM Addr (for 8-bit data access) | 340 | * Offset 0x15: EEPROM Addr (for 8-bit data access) |
| 341 | */ | 341 | */ |
| 342 | 342 | ||
| 343 | static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) | 343 | int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) |
| 344 | { | 344 | { |
| 345 | int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY); | 345 | int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY); |
| 346 | int err; | 346 | int err; |
| @@ -365,6 +365,7 @@ int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip); · 364 unmodified lines | |||
| 365 | 365 | ||
| 366 | int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, | 366 | int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, |
| 367 | int port); | 367 | int port); |
| 368 | int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip); | ||
| 368 | 369 | ||
| 369 | extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; | 370 | extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; |
| 370 | extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops; | 371 | extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops; |
| @@ -1303,24 +1303,23 @@ static void ibmveth_rx_csum_helper(struct sk_buff *skb, · 1302 unmodified lines | |||
| 1303 | * the user space for finding a flow. During this process, OVS computes | 1303 | * the user space for finding a flow. During this process, OVS computes |
| 1304 | * checksum on the first packet when CHECKSUM_PARTIAL flag is set. | 1304 | * checksum on the first packet when CHECKSUM_PARTIAL flag is set. |
| 1305 | * | 1305 | * |
| 1306 | * So, re-compute TCP pseudo header checksum when configured for | 1306 | * So, re-compute TCP pseudo header checksum. |
| 1307 | * trunk mode. | ||
| 1308 | */ | 1307 | */ |
| 1308 | |||
| 1309 | if (iph_proto == IPPROTO_TCP) { | 1309 | if (iph_proto == IPPROTO_TCP) { |
| 1310 | struct tcphdr *tcph = (struct tcphdr *)(skb->data + iphlen); | 1310 | struct tcphdr *tcph = (struct tcphdr *)(skb->data + iphlen); |
| 1311 | |||
| 1311 | if (tcph->check == 0x0000) { | 1312 | if (tcph->check == 0x0000) { |
| 1312 | /* Recompute TCP pseudo header checksum */ | 1313 | /* Recompute TCP pseudo header checksum */ |
| 1313 | if (adapter->is_active_trunk) { | 1314 | tcphdrlen = skb->len - iphlen; |
| 1314 | tcphdrlen = skb->len - iphlen; | 1315 | if (skb_proto == ETH_P_IP) |
| 1315 | if (skb_proto == ETH_P_IP) | 1316 | tcph->check = |
| 1316 | tcph->check = | 1317 | ~csum_tcpudp_magic(iph->saddr, |
| 1317 | ~csum_tcpudp_magic(iph->saddr, | 1318 | iph->daddr, tcphdrlen, iph_proto, 0); |
| 1318 | iph->daddr, tcphdrlen, iph_proto, 0); | 1319 | else if (skb_proto == ETH_P_IPV6) |
| 1319 | else if (skb_proto == ETH_P_IPV6) | 1320 | tcph->check = |
| 1320 | tcph->check = | 1321 | ~csum_ipv6_magic(&iph6->saddr, |
| 1321 | ~csum_ipv6_magic(&iph6->saddr, | 1322 | &iph6->daddr, tcphdrlen, iph_proto, 0); |
| 1322 | &iph6->daddr, tcphdrlen, iph_proto, 0); | ||
| 1323 | } | ||
| 1324 | /* Setup SKB fields for checksum offload */ | 1323 | /* Setup SKB fields for checksum offload */ |
| 1325 | skb_partial_csum_set(skb, iphlen, | 1324 | skb_partial_csum_set(skb, iphlen, |
| 1326 | offsetof(struct tcphdr, check)); | 1325 | offsetof(struct tcphdr, check)); |
| @@ -2655,12 +2655,14 @@ static int ice_vc_query_rxdid(struct ice_vf *vf) · 2654 unmodified lines | |||
| 2655 | goto err; | 2655 | goto err; |
| 2656 | } | 2656 | } |
| 2657 | 2657 | ||
| 2658 | /* Read flexiflag registers to determine whether the | 2658 | /* RXDIDs supported by DDP package can be read from the register |
| 2659 | * corresponding RXDID is configured and supported or not. | 2659 | * to get the supported RXDID bitmap. But the legacy 32byte RXDID |
| 2660 | * Since Legacy 16byte descriptor format is not supported, | 2660 | * is not listed in DDP package, add it in the bitmap manually. |
| 2661 | * start from Legacy 32byte descriptor. | 2661 | * Legacy 16byte descriptor is not supported. |
| 2662 | */ | 2662 | */ |
| 2663 | for (i = ICE_RXDID_LEGACY_1; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) { | 2663 | rxdid->supported_rxdids |= BIT(ICE_RXDID_LEGACY_1); |
| 2664 | |||
| 2665 | for (i = ICE_RXDID_FLEX_NIC; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) { | ||
| 2664 | regval = rd32(hw, GLFLXP_RXDID_FLAGS(i, 0)); | 2666 | regval = rd32(hw, GLFLXP_RXDID_FLAGS(i, 0)); |
| 2665 | if ((regval >> GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S) | 2667 | if ((regval >> GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S) |
| 2666 | & GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M) | 2668 | & GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M) |
| @@ -2195,7 +2195,7 @@ struct rx_ring_info { · 2194 unmodified lines | |||
| 2195 | struct sk_buff *skb; | 2195 | struct sk_buff *skb; |
| 2196 | dma_addr_t data_addr; | 2196 | dma_addr_t data_addr; |
| 2197 | DEFINE_DMA_UNMAP_LEN(data_size); | 2197 | DEFINE_DMA_UNMAP_LEN(data_size); |
| 2198 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; | 2198 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1]; |
| 2199 | }; | 2199 | }; |
| 2200 | 2200 | ||
| 2201 | enum flow_control { | 2201 | enum flow_control { |
| @@ -3172,8 +3172,8 @@ static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth) · 3171 unmodified lines | |||
| 3172 | 3172 | ||
| 3173 | eth->rx_events++; | 3173 | eth->rx_events++; |
| 3174 | if (likely(napi_schedule_prep(ð->rx_napi))) { | 3174 | if (likely(napi_schedule_prep(ð->rx_napi))) { |
| 3175 | __napi_schedule(ð->rx_napi); | ||
| 3176 | mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); | 3175 | mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); |
| 3176 | __napi_schedule(ð->rx_napi); | ||
| 3177 | } | 3177 | } |
| 3178 | 3178 | ||
| 3179 | return IRQ_HANDLED; | 3179 | return IRQ_HANDLED; |
| @@ -3185,8 +3185,8 @@ static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth) · 5 unmodified lines | |||
| 3185 | 3185 | ||
| 3186 | eth->tx_events++; | 3186 | eth->tx_events++; |
| 3187 | if (likely(napi_schedule_prep(ð->tx_napi))) { | 3187 | if (likely(napi_schedule_prep(ð->tx_napi))) { |
| 3188 | __napi_schedule(ð->tx_napi); | ||
| 3189 | mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); | 3188 | mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); |
| 3189 | __napi_schedule(ð->tx_napi); | ||
| 3190 | } | 3190 | } |
| 3191 | 3191 | ||
| 3192 | return IRQ_HANDLED; | 3192 | return IRQ_HANDLED; |
| @@ -46,6 +46,7 @@ config LAN743X · 45 unmodified lines | |||
| 46 | tristate "LAN743x support" | 46 | tristate "LAN743x support" |
| 47 | depends on PCI | 47 | depends on PCI |
| 48 | depends on PTP_1588_CLOCK_OPTIONAL | 48 | depends on PTP_1588_CLOCK_OPTIONAL |
| 49 | select PHYLIB | ||
| 49 | select FIXED_PHY | 50 | select FIXED_PHY |
| 50 | select CRC16 | 51 | select CRC16 |
| 51 | select CRC32 | 52 | select CRC32 |
| @@ -91,63 +91,137 @@ static unsigned int mana_checksum_info(struct sk_buff *skb) · 90 unmodified lines | |||
| 91 | return 0; | 91 | return 0; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static void mana_add_sge(struct mana_tx_package *tp, struct mana_skb_head *ash, | ||
| 95 | int sg_i, dma_addr_t da, int sge_len, u32 gpa_mkey) | ||
| 96 | { | ||
| 97 | ash->dma_handle[sg_i] = da; | ||
| 98 | ash->size[sg_i] = sge_len; | ||
| 99 | |||
| 100 | tp->wqe_req.sgl[sg_i].address = da; | ||
| 101 | tp->wqe_req.sgl[sg_i].mem_key = gpa_mkey; | ||
| 102 | tp->wqe_req.sgl[sg_i].size = sge_len; | ||
| 103 | } | ||
| 104 | |||
| 94 | static int mana_map_skb(struct sk_buff *skb, struct mana_port_context *apc, | 105 | static int mana_map_skb(struct sk_buff *skb, struct mana_port_context *apc, |
| 95 | struct mana_tx_package *tp) | 106 | struct mana_tx_package *tp, int gso_hs) |
| 96 | { | 107 | { |
| 97 | struct mana_skb_head *ash = (struct mana_skb_head *)skb->head; | 108 | struct mana_skb_head *ash = (struct mana_skb_head *)skb->head; |
| 109 | int hsg = 1; /* num of SGEs of linear part */ | ||
| 98 | struct gdma_dev *gd = apc->ac->gdma_dev; | 110 | struct gdma_dev *gd = apc->ac->gdma_dev; |
| 111 | int skb_hlen = skb_headlen(skb); | ||
| 112 | int sge0_len, sge1_len = 0; | ||
| 99 | struct gdma_context *gc; | 113 | struct gdma_context *gc; |
| 100 | struct device *dev; | 114 | struct device *dev; |
| 101 | skb_frag_t *frag; | 115 | skb_frag_t *frag; |
| 102 | dma_addr_t da; | 116 | dma_addr_t da; |
| 117 | int sg_i; | ||
| 103 | int i; | 118 | int i; |
| 104 | 119 | ||
| 105 | gc = gd->gdma_context; | 120 | gc = gd->gdma_context; |
| 106 | dev = gc->dev; | 121 | dev = gc->dev; |
| 107 | da = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); | ||
| 108 | 122 | ||
| 123 | if (gso_hs && gso_hs < skb_hlen) { | ||
| 124 | sge0_len = gso_hs; | ||
| 125 | sge1_len = skb_hlen - gso_hs; | ||
| 126 | } else { | ||
| 127 | sge0_len = skb_hlen; | ||
| 128 | } | ||
| 129 | |||
| 130 | da = dma_map_single(dev, skb->data, sge0_len, DMA_TO_DEVICE); | ||
| 109 | if (dma_mapping_error(dev, da)) | 131 | if (dma_mapping_error(dev, da)) |
| 110 | return -ENOMEM; | 132 | return -ENOMEM; |
| 111 | 133 | ||
| 112 | ash->dma_handle[0] = da; | 134 | mana_add_sge(tp, ash, 0, da, sge0_len, gd->gpa_mkey); |
| 113 | ash->size[0] = skb_headlen(skb); | ||
| 114 | 135 | ||
| 115 | tp->wqe_req.sgl[0].address = ash->dma_handle[0]; | 136 | if (sge1_len) { |
| 116 | tp->wqe_req.sgl[0].mem_key = gd->gpa_mkey; | 137 | sg_i = 1; |
| 117 | tp->wqe_req.sgl[0].size = ash->size[0]; | 138 | da = dma_map_single(dev, skb->data + sge0_len, sge1_len, |
| 139 | DMA_TO_DEVICE); | ||
| 140 | if (dma_mapping_error(dev, da)) | ||
| 141 | goto frag_err; | ||
| 142 | |||
| 143 | mana_add_sge(tp, ash, sg_i, da, sge1_len, gd->gpa_mkey); | ||
| 144 | hsg = 2; | ||
| 145 | } | ||
| 118 | 146 | ||
| 119 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 147 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
| 148 | sg_i = hsg + i; | ||
| 149 | |||
| 120 | frag = &skb_shinfo(skb)->frags[i]; | 150 | frag = &skb_shinfo(skb)->frags[i]; |
| 121 | da = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), | 151 | da = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), |
| 122 | DMA_TO_DEVICE); | 152 | DMA_TO_DEVICE); |
| 123 | |||
| 124 | if (dma_mapping_error(dev, da)) | 153 | if (dma_mapping_error(dev, da)) |
| 125 | goto frag_err; | 154 | goto frag_err; |
| 126 | 155 | ||
| 127 | ash->dma_handle[i + 1] = da; | 156 | mana_add_sge(tp, ash, sg_i, da, skb_frag_size(frag), |
| 128 | ash->size[i + 1] = skb_frag_size(frag); | 157 | gd->gpa_mkey); |
| 129 | |||
| 130 | tp->wqe_req.sgl[i + 1].address = ash->dma_handle[i + 1]; | ||
| 131 | tp->wqe_req.sgl[i + 1].mem_key = gd->gpa_mkey; | ||
| 132 | tp->wqe_req.sgl[i + 1].size = ash->size[i + 1]; | ||
| 133 | } | 158 | } |
| 134 | 159 | ||
| 135 | return 0; | 160 | return 0; |
| 136 | 161 | ||
| 137 | frag_err: | 162 | frag_err: |
| 138 | for (i = i - 1; i >= 0; i--) | 163 | for (i = sg_i - 1; i >= hsg; i--) |
| 139 | dma_unmap_page(dev, ash->dma_handle[i + 1], ash->size[i + 1], | 164 | dma_unmap_page(dev, ash->dma_handle[i], ash->size[i], |
| 140 | DMA_TO_DEVICE); | 165 | DMA_TO_DEVICE); |
| 141 | 166 | ||
| 142 | dma_unmap_single(dev, ash->dma_handle[0], ash->size[0], DMA_TO_DEVICE); | 167 | for (i = hsg - 1; i >= 0; i--) |
| 168 | dma_unmap_single(dev, ash->dma_handle[i], ash->size[i], | ||
| 169 | DMA_TO_DEVICE); | ||
| 143 | 170 | ||
| 144 | return -ENOMEM; | 171 | return -ENOMEM; |
| 145 | } | 172 | } |
| 146 | 173 | ||
| 174 | /* Handle the case when GSO SKB linear length is too large. | ||
| 175 | * MANA NIC requires GSO packets to put only the packet header to SGE0. | ||
| 176 | * So, we need 2 SGEs for the skb linear part which contains more than the | ||
| 177 | * header. | ||
| 178 | * Return a positive value for the number of SGEs, or a negative value | ||
| 179 | * for an error. | ||
| 180 | */ | ||
| 181 | static int mana_fix_skb_head(struct net_device *ndev, struct sk_buff *skb, | ||
| 182 | int gso_hs) | ||
| 183 | { | ||
| 184 | int num_sge = 1 + skb_shinfo(skb)->nr_frags; | ||
| 185 | int skb_hlen = skb_headlen(skb); | ||
| 186 | |||
| 187 | if (gso_hs < skb_hlen) { | ||
| 188 | num_sge++; | ||
| 189 | } else if (gso_hs > skb_hlen) { | ||
| 190 | if (net_ratelimit()) | ||
| 191 | netdev_err(ndev, | ||
| 192 | "TX nonlinear head: hs:%d, skb_hlen:%d\n", | ||
| 193 | gso_hs, skb_hlen); | ||
| 194 | |||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | |||
| 198 | return num_sge; | ||
| 199 | } | ||
| 200 | |||
| 201 | /* Get the GSO packet's header size */ | ||
| 202 | static int mana_get_gso_hs(struct sk_buff *skb) | ||
| 203 | { | ||
| 204 | int gso_hs; | ||
| 205 | |||
| 206 | if (skb->encapsulation) { | ||
| 207 | gso_hs = skb_inner_tcp_all_headers(skb); | ||
| 208 | } else { | ||
| 209 | if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) { | ||
| 210 | gso_hs = skb_transport_offset(skb) + | ||
| 211 | sizeof(struct udphdr); | ||
| 212 | } else { | ||
| 213 | gso_hs = skb_tcp_all_headers(skb); | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | return gso_hs; | ||
| 218 | } | ||
| 219 | |||
| 147 | netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 220 | netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
| 148 | { | 221 | { |
| 149 | enum mana_tx_pkt_format pkt_fmt = MANA_SHORT_PKT_FMT; | 222 | enum mana_tx_pkt_format pkt_fmt = MANA_SHORT_PKT_FMT; |
| 150 | struct mana_port_context *apc = netdev_priv(ndev); | 223 | struct mana_port_context *apc = netdev_priv(ndev); |
| 224 | int gso_hs = 0; /* zero for non-GSO pkts */ | ||
| 151 | u16 txq_idx = skb_get_queue_mapping(skb); | 225 | u16 txq_idx = skb_get_queue_mapping(skb); |
| 152 | struct gdma_dev *gd = apc->ac->gdma_dev; | 226 | struct gdma_dev *gd = apc->ac->gdma_dev; |
| 153 | bool ipv4 = false, ipv6 = false; | 227 | bool ipv4 = false, ipv6 = false; |
| @@ -159,7 +233,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 5 unmodified lines | |||
| 159 | struct mana_txq *txq; | 233 | struct mana_txq *txq; |
| 160 | struct mana_cq *cq; | 234 | struct mana_cq *cq; |
| 161 | int err, len; | 235 | int err, len; |
| 162 | u16 ihs; | ||
| 163 | 236 | ||
| 164 | if (unlikely(!apc->port_is_up)) | 237 | if (unlikely(!apc->port_is_up)) |
| 165 | goto tx_drop; | 238 | goto tx_drop; |
| @@ -209,19 +282,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 43 unmodified lines | |||
| 209 | pkg.wqe_req.client_data_unit = 0; | 282 | pkg.wqe_req.client_data_unit = 0; |
| 210 | 283 | ||
| 211 | pkg.wqe_req.num_sge = 1 + skb_shinfo(skb)->nr_frags; | 284 | pkg.wqe_req.num_sge = 1 + skb_shinfo(skb)->nr_frags; |
| 212 | WARN_ON_ONCE(pkg.wqe_req.num_sge > MAX_TX_WQE_SGL_ENTRIES); | ||
| 213 | |||
| 214 | if (pkg.wqe_req.num_sge <= ARRAY_SIZE(pkg.sgl_array)) { | ||
| 215 | pkg.wqe_req.sgl = pkg.sgl_array; | ||
| 216 | } else { | ||
| 217 | pkg.sgl_ptr = kmalloc_array(pkg.wqe_req.num_sge, | ||
| 218 | sizeof(struct gdma_sge), | ||
| 219 | GFP_ATOMIC); | ||
| 220 | if (!pkg.sgl_ptr) | ||
| 221 | goto tx_drop_count; | ||
| 222 | |||
| 223 | pkg.wqe_req.sgl = pkg.sgl_ptr; | ||
| 224 | } | ||
| 225 | 285 | ||
| 226 | if (skb->protocol == htons(ETH_P_IP)) | 286 | if (skb->protocol == htons(ETH_P_IP)) |
| 227 | ipv4 = true; | 287 | ipv4 = true; |
| @@ -229,6 +289,26 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1 unmodified line | |||
| 229 | ipv6 = true; | 289 | ipv6 = true; |
| 230 | 290 | ||
| 231 | if (skb_is_gso(skb)) { | 291 | if (skb_is_gso(skb)) { |
| 292 | int num_sge; | ||
| 293 | |||
| 294 | gso_hs = mana_get_gso_hs(skb); | ||
| 295 | |||
| 296 | num_sge = mana_fix_skb_head(ndev, skb, gso_hs); | ||
| 297 | if (num_sge > 0) | ||
| 298 | pkg.wqe_req.num_sge = num_sge; | ||
| 299 | else | ||
| 300 | goto tx_drop_count; | ||
| 301 | |||
| 302 | u64_stats_update_begin(&tx_stats->syncp); | ||
| 303 | if (skb->encapsulation) { | ||
| 304 | tx_stats->tso_inner_packets++; | ||
| 305 | tx_stats->tso_inner_bytes += skb->len - gso_hs; | ||
| 306 | } else { | ||
| 307 | tx_stats->tso_packets++; | ||
| 308 | tx_stats->tso_bytes += skb->len - gso_hs; | ||
| 309 | } | ||
| 310 | u64_stats_update_end(&tx_stats->syncp); | ||
| 311 | |||
| 232 | pkg.tx_oob.s_oob.is_outer_ipv4 = ipv4; | 312 | pkg.tx_oob.s_oob.is_outer_ipv4 = ipv4; |
| 233 | pkg.tx_oob.s_oob.is_outer_ipv6 = ipv6; | 313 | pkg.tx_oob.s_oob.is_outer_ipv6 = ipv6; |
| 234 | 314 | ||
| @@ -252,28 +332,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 17 unmodified lines | |||
| 252 | &ipv6_hdr(skb)->daddr, 0, | 332 | &ipv6_hdr(skb)->daddr, 0, |
| 253 | IPPROTO_TCP, 0); | 333 | IPPROTO_TCP, 0); |
| 254 | } | 334 | } |
| 255 | |||
| 256 | if (skb->encapsulation) { | ||
| 257 | ihs = skb_inner_tcp_all_headers(skb); | ||
| 258 | u64_stats_update_begin(&tx_stats->syncp); | ||
| 259 | tx_stats->tso_inner_packets++; | ||
| 260 | tx_stats->tso_inner_bytes += skb->len - ihs; | ||
| 261 | u64_stats_update_end(&tx_stats->syncp); | ||
| 262 | } else { | ||
| 263 | if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) { | ||
| 264 | ihs = skb_transport_offset(skb) + sizeof(struct udphdr); | ||
| 265 | } else { | ||
| 266 | ihs = skb_tcp_all_headers(skb); | ||
| 267 | if (ipv6_has_hopopt_jumbo(skb)) | ||
| 268 | ihs -= sizeof(struct hop_jumbo_hdr); | ||
| 269 | } | ||
| 270 | |||
| 271 | u64_stats_update_begin(&tx_stats->syncp); | ||
| 272 | tx_stats->tso_packets++; | ||
| 273 | tx_stats->tso_bytes += skb->len - ihs; | ||
| 274 | u64_stats_update_end(&tx_stats->syncp); | ||
| 275 | } | ||
| 276 | |||
| 277 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 335 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 278 | csum_type = mana_checksum_info(skb); | 336 | csum_type = mana_checksum_info(skb); |
| 279 | 337 | ||
| @@ -296,11 +354,25 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 16 unmodified lines | |||
| 296 | } else { | 354 | } else { |
| 297 | /* Can't do offload of this type of checksum */ | 355 | /* Can't do offload of this type of checksum */ |
| 298 | if (skb_checksum_help(skb)) | 356 | if (skb_checksum_help(skb)) |
| 299 | goto free_sgl_ptr; | 357 | goto tx_drop_count; |
| 300 | } | 358 | } |
| 301 | } | 359 | } |
| 302 | 360 | ||
| 303 | if (mana_map_skb(skb, apc, &pkg)) { | 361 | WARN_ON_ONCE(pkg.wqe_req.num_sge > MAX_TX_WQE_SGL_ENTRIES); |
| 362 | |||
| 363 | if (pkg.wqe_req.num_sge <= ARRAY_SIZE(pkg.sgl_array)) { | ||
| 364 | pkg.wqe_req.sgl = pkg.sgl_array; | ||
| 365 | } else { | ||
| 366 | pkg.sgl_ptr = kmalloc_array(pkg.wqe_req.num_sge, | ||
| 367 | sizeof(struct gdma_sge), | ||
| 368 | GFP_ATOMIC); | ||
| 369 | if (!pkg.sgl_ptr) | ||
| 370 | goto tx_drop_count; | ||
| 371 | |||
| 372 | pkg.wqe_req.sgl = pkg.sgl_ptr; | ||
| 373 | } | ||
| 374 | |||
| 375 | if (mana_map_skb(skb, apc, &pkg, gso_hs)) { | ||
| 304 | u64_stats_update_begin(&tx_stats->syncp); | 376 | u64_stats_update_begin(&tx_stats->syncp); |
| 305 | tx_stats->mana_map_err++; | 377 | tx_stats->mana_map_err++; |
| 306 | u64_stats_update_end(&tx_stats->syncp); | 378 | u64_stats_update_end(&tx_stats->syncp); |
| @@ -1258,11 +1330,16 @@ static void mana_unmap_skb(struct sk_buff *skb, struct mana_port_context *apc) · 951 unmodified lines | |||
| 1258 | struct mana_skb_head *ash = (struct mana_skb_head *)skb->head; | 1330 | struct mana_skb_head *ash = (struct mana_skb_head *)skb->head; |
| 1259 | struct gdma_context *gc = apc->ac->gdma_dev->gdma_context; | 1331 | struct gdma_context *gc = apc->ac->gdma_dev->gdma_context; |
| 1260 | struct device *dev = gc->dev; | 1332 | struct device *dev = gc->dev; |
| 1261 | int i; | 1333 | int hsg, i; |
| 1262 | 1334 | ||
| 1263 | dma_unmap_single(dev, ash->dma_handle[0], ash->size[0], DMA_TO_DEVICE); | 1335 | /* Number of SGEs of linear part */ |
| 1336 | hsg = (skb_is_gso(skb) && skb_headlen(skb) > ash->size[0]) ? 2 : 1; | ||
| 1264 | 1337 | ||
| 1265 | for (i = 1; i < skb_shinfo(skb)->nr_frags + 1; i++) | 1338 | for (i = 0; i < hsg; i++) |
| 1339 | dma_unmap_single(dev, ash->dma_handle[i], ash->size[i], | ||
| 1340 | DMA_TO_DEVICE); | ||
| 1341 | |||
| 1342 | for (i = hsg; i < skb_shinfo(skb)->nr_frags + hsg; i++) | ||
| 1266 | dma_unmap_page(dev, ash->dma_handle[i], ash->size[i], | 1343 | dma_unmap_page(dev, ash->dma_handle[i], ash->size[i], |
| 1267 | DMA_TO_DEVICE); | 1344 | DMA_TO_DEVICE); |
| 1268 | } | 1345 | } |
| @@ -1317,19 +1394,23 @@ static void mana_poll_tx_cq(struct mana_cq *cq) · 48 unmodified lines | |||
| 1317 | case CQE_TX_VPORT_IDX_OUT_OF_RANGE: | 1394 | case CQE_TX_VPORT_IDX_OUT_OF_RANGE: |
| 1318 | case CQE_TX_VPORT_DISABLED: | 1395 | case CQE_TX_VPORT_DISABLED: |
| 1319 | case CQE_TX_VLAN_TAGGING_VIOLATION: | 1396 | case CQE_TX_VLAN_TAGGING_VIOLATION: |
| 1320 | WARN_ONCE(1, "TX: CQE error %d: ignored.\n", | 1397 | if (net_ratelimit()) |
| 1321 | cqe_oob->cqe_hdr.cqe_type); | 1398 | netdev_err(ndev, "TX: CQE error %d\n", |
| 1399 | cqe_oob->cqe_hdr.cqe_type); | ||
| 1400 | |||
| 1322 | apc->eth_stats.tx_cqe_err++; | 1401 | apc->eth_stats.tx_cqe_err++; |
| 1323 | break; | 1402 | break; |
| 1324 | 1403 | ||
| 1325 | default: | 1404 | default: |
| 1326 | /* If the CQE type is unexpected, log an error, assert, | 1405 | /* If the CQE type is unknown, log an error, |
| 1327 | * and go through the error path. | 1406 | * and still free the SKB, update tail, etc. |
| 1328 | */ | 1407 | */ |
| 1329 | WARN_ONCE(1, "TX: Unexpected CQE type %d: HW BUG?\n", | 1408 | if (net_ratelimit()) |
| 1330 | cqe_oob->cqe_hdr.cqe_type); | 1409 | netdev_err(ndev, "TX: unknown CQE type %d\n", |
| 1410 | cqe_oob->cqe_hdr.cqe_type); | ||
| 1411 | |||
| 1331 | apc->eth_stats.tx_cqe_unknown_type++; | 1412 | apc->eth_stats.tx_cqe_unknown_type++; |
| 1332 | return; | 1413 | break; |
| 1333 | } | 1414 | } |
| 1334 | 1415 | ||
| 1335 | if (WARN_ON_ONCE(txq->gdma_txq_id != completions[i].wq_num)) | 1416 | if (WARN_ON_ONCE(txq->gdma_txq_id != completions[i].wq_num)) |
| @@ -110,9 +110,9 @@ struct qed_ll2_info { · 109 unmodified lines | |||
| 110 | enum core_tx_dest tx_dest; | 110 | enum core_tx_dest tx_dest; |
| 111 | u8 tx_stats_en; | 111 | u8 tx_stats_en; |
| 112 | bool main_func_queue; | 112 | bool main_func_queue; |
| 113 | struct qed_ll2_cbs cbs; | ||
| 113 | struct qed_ll2_rx_queue rx_queue; | 114 | struct qed_ll2_rx_queue rx_queue; |
| 114 | struct qed_ll2_tx_queue tx_queue; | 115 | struct qed_ll2_tx_queue tx_queue; |
| 115 | struct qed_ll2_cbs cbs; | ||
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | extern const struct qed_ll2_ops qed_ll2_ops_pass; | 118 | extern const struct qed_ll2_ops qed_ll2_ops_pass; |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | * Copyright (C) 2022 Renesas Electronics Corporation | 4 | * Copyright (C) 2022 Renesas Electronics Corporation |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/clk.h> | ||
| 7 | #include <linux/dma-mapping.h> | 8 | #include <linux/dma-mapping.h> |
| 8 | #include <linux/err.h> | 9 | #include <linux/err.h> |
| 9 | #include <linux/etherdevice.h> | 10 | #include <linux/etherdevice.h> |
| @@ -1049,7 +1050,7 @@ static void rswitch_rmac_setting(struct rswitch_etha *etha, const u8 *mac) · 1039 unmodified lines | |||
| 1049 | static void rswitch_etha_enable_mii(struct rswitch_etha *etha) | 1050 | static void rswitch_etha_enable_mii(struct rswitch_etha *etha) |
| 1050 | { | 1051 | { |
| 1051 | rswitch_modify(etha->addr, MPIC, MPIC_PSMCS_MASK | MPIC_PSMHT_MASK, | 1052 | rswitch_modify(etha->addr, MPIC, MPIC_PSMCS_MASK | MPIC_PSMHT_MASK, |
| 1052 | MPIC_PSMCS(0x05) | MPIC_PSMHT(0x06)); | 1053 | MPIC_PSMCS(etha->psmcs) | MPIC_PSMHT(0x06)); |
| 1053 | rswitch_modify(etha->addr, MPSM, 0, MPSM_MFF_C45); | 1054 | rswitch_modify(etha->addr, MPSM, 0, MPSM_MFF_C45); |
| 1054 | } | 1055 | } |
| 1055 | 1056 | ||
| @@ -1693,6 +1694,12 @@ static void rswitch_etha_init(struct rswitch_private *priv, int index) · 637 unmodified lines | |||
| 1693 | etha->index = index; | 1694 | etha->index = index; |
| 1694 | etha->addr = priv->addr + RSWITCH_ETHA_OFFSET + index * RSWITCH_ETHA_SIZE; | 1695 | etha->addr = priv->addr + RSWITCH_ETHA_OFFSET + index * RSWITCH_ETHA_SIZE; |
| 1695 | etha->coma_addr = priv->addr; | 1696 | etha->coma_addr = priv->addr; |
| 1697 | |||
| 1698 | /* MPIC.PSMCS = (clk [MHz] / (MDC frequency [MHz] * 2) - 1. | ||
| 1699 | * Calculating PSMCS value as MDC frequency = 2.5MHz. So, multiply | ||
| 1700 | * both the numerator and the denominator by 10. | ||
| 1701 | */ | ||
| 1702 | etha->psmcs = clk_get_rate(priv->clk) / 100000 / (25 * 2) - 1; | ||
| 1696 | } | 1703 | } |
| 1697 | 1704 | ||
| 1698 | static int rswitch_device_alloc(struct rswitch_private *priv, int index) | 1705 | static int rswitch_device_alloc(struct rswitch_private *priv, int index) |
| @@ -1900,6 +1907,10 @@ static int renesas_eth_sw_probe(struct platform_device *pdev) · 201 unmodified lines | |||
| 1900 | return -ENOMEM; | 1907 | return -ENOMEM; |
| 1901 | spin_lock_init(&priv->lock); | 1908 | spin_lock_init(&priv->lock); |
| 1902 | 1909 | ||
| 1910 | priv->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1911 | if (IS_ERR(priv->clk)) | ||
| 1912 | return PTR_ERR(priv->clk); | ||
| 1913 | |||
| 1903 | attr = soc_device_match(rswitch_soc_no_speed_change); | 1914 | attr = soc_device_match(rswitch_soc_no_speed_change); |
| 1904 | if (attr) | 1915 | if (attr) |
| 1905 | priv->etha_no_runtime_change = true; | 1916 | priv->etha_no_runtime_change = true; |
| @@ -915,6 +915,7 @@ struct rswitch_etha { · 914 unmodified lines | |||
| 915 | bool external_phy; | 915 | bool external_phy; |
| 916 | struct mii_bus *mii; | 916 | struct mii_bus *mii; |
| 917 | phy_interface_t phy_interface; | 917 | phy_interface_t phy_interface; |
| 918 | u32 psmcs; | ||
| 918 | u8 mac_addr[MAX_ADDR_LEN]; | 919 | u8 mac_addr[MAX_ADDR_LEN]; |
| 919 | int link; | 920 | int link; |
| 920 | int speed; | 921 | int speed; |
| @@ -1012,6 +1013,7 @@ struct rswitch_private { · 91 unmodified lines | |||
| 1012 | struct rswitch_mfwd mfwd; | 1013 | struct rswitch_mfwd mfwd; |
| 1013 | 1014 | ||
| 1014 | spinlock_t lock; /* lock interrupt registers' control */ | 1015 | spinlock_t lock; /* lock interrupt registers' control */ |
| 1016 | struct clk *clk; | ||
| 1015 | 1017 | ||
| 1016 | bool etha_no_runtime_change; | 1018 | bool etha_no_runtime_change; |
| 1017 | bool gwca_halt; | 1019 | bool gwca_halt; |
| @@ -104,6 +104,7 @@ struct stm32_ops { · 103 unmodified lines | |||
| 104 | int (*parse_data)(struct stm32_dwmac *dwmac, | 104 | int (*parse_data)(struct stm32_dwmac *dwmac, |
| 105 | struct device *dev); | 105 | struct device *dev); |
| 106 | u32 syscfg_eth_mask; | 106 | u32 syscfg_eth_mask; |
| 107 | bool clk_rx_enable_in_suspend; | ||
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) | 110 | static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) |
| @@ -121,7 +122,8 @@ static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) · 11 unmodified lines | |||
| 121 | if (ret) | 122 | if (ret) |
| 122 | return ret; | 123 | return ret; |
| 123 | 124 | ||
| 124 | if (!dwmac->dev->power.is_suspended) { | 125 | if (!dwmac->ops->clk_rx_enable_in_suspend || |
| 126 | !dwmac->dev->power.is_suspended) { | ||
| 125 | ret = clk_prepare_enable(dwmac->clk_rx); | 127 | ret = clk_prepare_enable(dwmac->clk_rx); |
| 126 | if (ret) { | 128 | if (ret) { |
| 127 | clk_disable_unprepare(dwmac->clk_tx); | 129 | clk_disable_unprepare(dwmac->clk_tx); |
| @@ -508,7 +510,8 @@ static struct stm32_ops stm32mp1_dwmac_data = { · 380 unmodified lines | |||
| 508 | .suspend = stm32mp1_suspend, | 510 | .suspend = stm32mp1_suspend, |
| 509 | .resume = stm32mp1_resume, | 511 | .resume = stm32mp1_resume, |
| 510 | .parse_data = stm32mp1_parse_data, | 512 | .parse_data = stm32mp1_parse_data, |
| 511 | .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK | 513 | .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK, |
| 514 | .clk_rx_enable_in_suspend = true | ||
| 512 | }; | 515 | }; |
| 513 | 516 | ||
| 514 | static const struct of_device_id stm32_dwmac_match[] = { | 517 | static const struct of_device_id stm32_dwmac_match[] = { |
| @@ -6012,33 +6012,6 @@ static irqreturn_t stmmac_msi_intr_rx(int irq, void *data) · 6011 unmodified lines | |||
| 6012 | return IRQ_HANDLED; | 6012 | return IRQ_HANDLED; |
| 6013 | } | 6013 | } |
| 6014 | 6014 | ||
| 6015 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 6016 | /* Polling receive - used by NETCONSOLE and other diagnostic tools | ||
| 6017 | * to allow network I/O with interrupts disabled. | ||
| 6018 | */ | ||
| 6019 | static void stmmac_poll_controller(struct net_device *dev) | ||
| 6020 | { | ||
| 6021 | struct stmmac_priv *priv = netdev_priv(dev); | ||
| 6022 | int i; | ||
| 6023 | |||
| 6024 | /* If adapter is down, do nothing */ | ||
| 6025 | if (test_bit(STMMAC_DOWN, &priv->state)) | ||
| 6026 | return; | ||
| 6027 | |||
| 6028 | if (priv->plat->flags & STMMAC_FLAG_MULTI_MSI_EN) { | ||
| 6029 | for (i = 0; i < priv->plat->rx_queues_to_use; i++) | ||
| 6030 | stmmac_msi_intr_rx(0, &priv->dma_conf.rx_queue[i]); | ||
| 6031 | |||
| 6032 | for (i = 0; i < priv->plat->tx_queues_to_use; i++) | ||
| 6033 | stmmac_msi_intr_tx(0, &priv->dma_conf.tx_queue[i]); | ||
| 6034 | } else { | ||
| 6035 | disable_irq(dev->irq); | ||
| 6036 | stmmac_interrupt(dev->irq, dev); | ||
| 6037 | enable_irq(dev->irq); | ||
| 6038 | } | ||
| 6039 | } | ||
| 6040 | #endif | ||
| 6041 | |||
| 6042 | /** | 6015 | /** |
| 6043 | * stmmac_ioctl - Entry point for the Ioctl | 6016 | * stmmac_ioctl - Entry point for the Ioctl |
| 6044 | * @dev: Device pointer. | 6017 | * @dev: Device pointer. |
| @@ -6999,9 +6972,6 @@ static const struct net_device_ops stmmac_netdev_ops = { · 954 unmodified lines | |||
| 6999 | .ndo_get_stats64 = stmmac_get_stats64, | 6972 | .ndo_get_stats64 = stmmac_get_stats64, |
| 7000 | .ndo_setup_tc = stmmac_setup_tc, | 6973 | .ndo_setup_tc = stmmac_setup_tc, |
| 7001 | .ndo_select_queue = stmmac_select_queue, | 6974 | .ndo_select_queue = stmmac_select_queue, |
| 7002 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 7003 | .ndo_poll_controller = stmmac_poll_controller, | ||
| 7004 | #endif | ||
| 7005 | .ndo_set_mac_address = stmmac_set_mac_address, | 6975 | .ndo_set_mac_address = stmmac_set_mac_address, |
| 7006 | .ndo_vlan_rx_add_vid = stmmac_vlan_rx_add_vid, | 6976 | .ndo_vlan_rx_add_vid = stmmac_vlan_rx_add_vid, |
| 7007 | .ndo_vlan_rx_kill_vid = stmmac_vlan_rx_kill_vid, | 6977 | .ndo_vlan_rx_kill_vid = stmmac_vlan_rx_kill_vid, |
| @@ -874,7 +874,7 @@ static int __maybe_unused stmmac_pltfr_resume(struct device *dev) · 873 unmodified lines | |||
| 874 | struct platform_device *pdev = to_platform_device(dev); | 874 | struct platform_device *pdev = to_platform_device(dev); |
| 875 | int ret; | 875 | int ret; |
| 876 | 876 | ||
| 877 | ret = stmmac_pltfr_init(pdev, priv->plat->bsp_priv); | 877 | ret = stmmac_pltfr_init(pdev, priv->plat); |
| 878 | if (ret) | 878 | if (ret) |
| 879 | return ret; | 879 | return ret; |
| 880 | 880 | ||
| @@ -1747,9 +1747,10 @@ static int am65_cpsw_nuss_init_tx_chns(struct am65_cpsw_common *common) · 1746 unmodified lines | |||
| 1747 | } | 1747 | } |
| 1748 | 1748 | ||
| 1749 | tx_chn->irq = k3_udma_glue_tx_get_irq(tx_chn->tx_chn); | 1749 | tx_chn->irq = k3_udma_glue_tx_get_irq(tx_chn->tx_chn); |
| 1750 | if (tx_chn->irq <= 0) { | 1750 | if (tx_chn->irq < 0) { |
| 1751 | dev_err(dev, "Failed to get tx dma irq %d\n", | 1751 | dev_err(dev, "Failed to get tx dma irq %d\n", |
| 1752 | tx_chn->irq); | 1752 | tx_chn->irq); |
| 1753 | ret = tx_chn->irq; | ||
| 1753 | goto err; | 1754 | goto err; |
| 1754 | } | 1755 | } |
| 1755 | 1756 | ||
| @@ -316,12 +316,12 @@ static int prueth_init_tx_chns(struct prueth_emac *emac) · 315 unmodified lines | |||
| 316 | goto fail; | 316 | goto fail; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | tx_chn->irq = k3_udma_glue_tx_get_irq(tx_chn->tx_chn); | 319 | ret = k3_udma_glue_tx_get_irq(tx_chn->tx_chn); |
| 320 | if (tx_chn->irq <= 0) { | 320 | if (ret < 0) { |
| 321 | ret = -EINVAL; | ||
| 322 | netdev_err(ndev, "failed to get tx irq\n"); | 321 | netdev_err(ndev, "failed to get tx irq\n"); |
| 323 | goto fail; | 322 | goto fail; |
| 324 | } | 323 | } |
| 324 | tx_chn->irq = ret; | ||
| 325 | 325 | ||
| 326 | snprintf(tx_chn->name, sizeof(tx_chn->name), "%s-tx%d", | 326 | snprintf(tx_chn->name, sizeof(tx_chn->name), "%s-tx%d", |
| 327 | dev_name(dev), tx_chn->id); | 327 | dev_name(dev), tx_chn->id); |
| @@ -90,7 +90,9 @@ static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index, · 89 unmodified lines | |||
| 90 | ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN | 90 | ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN |
| 91 | | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 91 | | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 92 | 0, index, &buf, 4); | 92 | 0, index, &buf, 4); |
| 93 | if (unlikely(ret < 0)) { | 93 | if (unlikely(ret < 4)) { |
| 94 | ret = ret < 0 ? ret : -ENODATA; | ||
| 95 | |||
| 94 | netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", | 96 | netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", |
| 95 | index, ret); | 97 | index, ret); |
| 96 | return ret; | 98 | return ret; |
| @@ -34,6 +34,8 @@ · 33 unmodified lines | |||
| 34 | #define TDM_PPPOHT_SLIC_MAXIN | 34 | #define TDM_PPPOHT_SLIC_MAXIN |
| 35 | #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S) | 35 | #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S) |
| 36 | 36 | ||
| 37 | static int uhdlc_close(struct net_device *dev); | ||
| 38 | |||
| 37 | static struct ucc_tdm_info utdm_primary_info = { | 39 | static struct ucc_tdm_info utdm_primary_info = { |
| 38 | .uf_info = { | 40 | .uf_info = { |
| 39 | .tsa = 0, | 41 | .tsa = 0, |
| @@ -708,6 +710,7 @@ static int uhdlc_open(struct net_device *dev) · 668 unmodified lines | |||
| 708 | hdlc_device *hdlc = dev_to_hdlc(dev); | 710 | hdlc_device *hdlc = dev_to_hdlc(dev); |
| 709 | struct ucc_hdlc_private *priv = hdlc->priv; | 711 | struct ucc_hdlc_private *priv = hdlc->priv; |
| 710 | struct ucc_tdm *utdm = priv->utdm; | 712 | struct ucc_tdm *utdm = priv->utdm; |
| 713 | int rc = 0; | ||
| 711 | 714 | ||
| 712 | if (priv->hdlc_busy != 1) { | 715 | if (priv->hdlc_busy != 1) { |
| 713 | if (request_irq(priv->ut_info->uf_info.irq, | 716 | if (request_irq(priv->ut_info->uf_info.irq, |
| @@ -731,10 +734,13 @@ static int uhdlc_open(struct net_device *dev) · 17 unmodified lines | |||
| 731 | napi_enable(&priv->napi); | 734 | napi_enable(&priv->napi); |
| 732 | netdev_reset_queue(dev); | 735 | netdev_reset_queue(dev); |
| 733 | netif_start_queue(dev); | 736 | netif_start_queue(dev); |
| 734 | hdlc_open(dev); | 737 | |
| 738 | rc = hdlc_open(dev); | ||
| 739 | if (rc) | ||
| 740 | uhdlc_close(dev); | ||
| 735 | } | 741 | } |
| 736 | 742 | ||
| 737 | return 0; | 743 | return rc; |
| 738 | } | 744 | } |
| 739 | 745 | ||
| 740 | static void uhdlc_memclean(struct ucc_hdlc_private *priv) | 746 | static void uhdlc_memclean(struct ucc_hdlc_private *priv) |
| @@ -824,6 +830,8 @@ static int uhdlc_close(struct net_device *dev) · 83 unmodified lines | |||
| 824 | netdev_reset_queue(dev); | 830 | netdev_reset_queue(dev); |
| 825 | priv->hdlc_busy = 0; | 831 | priv->hdlc_busy = 0; |
| 826 | 832 | ||
| 833 | hdlc_close(dev); | ||
| 834 | |||
| 827 | return 0; | 835 | return 0; |
| 828 | } | 836 | } |
| 829 | 837 | ||
| @@ -442,7 +442,12 @@ struct brcmf_scan_params_v2_le { · 441 unmodified lines | |||
| 442 | * fixed parameter portion is assumed, otherwise | 442 | * fixed parameter portion is assumed, otherwise |
| 443 | * ssid in the fixed portion is ignored | 443 | * ssid in the fixed portion is ignored |
| 444 | */ | 444 | */ |
| 445 | __le16 channel_list[1]; /* list of chanspecs */ | 445 | union { |
| 446 | __le16 padding; /* Reserve space for at least 1 entry for abort | ||
| 447 | * which uses an on stack brcmf_scan_params_v2_le | ||
| 448 | */ | ||
| 449 | DECLARE_FLEX_ARRAY(__le16, channel_list); /* chanspecs */ | ||
| 450 | }; | ||
| 446 | }; | 451 | }; |
| 447 | 452 | ||
| 448 | struct brcmf_scan_results { | 453 | struct brcmf_scan_results { |
| @@ -702,7 +707,7 @@ struct brcmf_sta_info_le { · 253 unmodified lines | |||
| 702 | 707 | ||
| 703 | struct brcmf_chanspec_list { | 708 | struct brcmf_chanspec_list { |
| 704 | __le32 count; /* # of entries */ | 709 | __le32 count; /* # of entries */ |
| 705 | __le32 element[1]; /* variable length uint32 list */ | 710 | __le32 element[]; /* variable length uint32 list */ |
| 706 | }; | 711 | }; |
| 707 | 712 | ||
| 708 | /* | 713 | /* |
| @@ -310,9 +310,9 @@ struct iwl_fw_ini_fifo_hdr { · 309 unmodified lines | |||
| 310 | struct iwl_fw_ini_error_dump_range { | 310 | struct iwl_fw_ini_error_dump_range { |
| 311 | __le32 range_data_size; | 311 | __le32 range_data_size; |
| 312 | union { | 312 | union { |
| 313 | __le32 internal_base_addr; | 313 | __le32 internal_base_addr __packed; |
| 314 | __le64 dram_base_addr; | 314 | __le64 dram_base_addr __packed; |
| 315 | __le32 page_num; | 315 | __le32 page_num __packed; |
| 316 | struct iwl_fw_ini_fifo_hdr fifo_hdr; | 316 | struct iwl_fw_ini_fifo_hdr fifo_hdr; |
| 317 | struct iwl_cmd_header fw_pkt_hdr; | 317 | struct iwl_cmd_header fw_pkt_hdr; |
| 318 | }; | 318 | }; |
| @@ -802,7 +802,7 @@ out: · 801 unmodified lines | |||
| 802 | mvm->nvm_data->bands[0].n_channels = 1; | 802 | mvm->nvm_data->bands[0].n_channels = 1; |
| 803 | mvm->nvm_data->bands[0].n_bitrates = 1; | 803 | mvm->nvm_data->bands[0].n_bitrates = 1; |
| 804 | mvm->nvm_data->bands[0].bitrates = | 804 | mvm->nvm_data->bands[0].bitrates = |
| 805 | (void *)((u8 *)mvm->nvm_data->channels + 1); | 805 | (void *)(mvm->nvm_data->channels + 1); |
| 806 | mvm->nvm_data->bands[0].bitrates->hw_value = 10; | 806 | mvm->nvm_data->bands[0].bitrates->hw_value = 10; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| @@ -731,73 +731,78 @@ static void iwl_mvm_mld_vif_cfg_changed_station(struct iwl_mvm *mvm, · 730 unmodified lines | |||
| 731 | 731 | ||
| 732 | mvmvif->associated = vif->cfg.assoc; | 732 | mvmvif->associated = vif->cfg.assoc; |
| 733 | 733 | ||
| 734 | if (!(changes & BSS_CHANGED_ASSOC)) | 734 | if (changes & BSS_CHANGED_ASSOC) { |
| 735 | return; | 735 | if (vif->cfg.assoc) { |
| 736 | 736 | /* clear statistics to get clean beacon counter */ | |
| 737 | if (vif->cfg.assoc) { | 737 | iwl_mvm_request_statistics(mvm, true); |
| 738 | /* clear statistics to get clean beacon counter */ | 738 | iwl_mvm_sf_update(mvm, vif, false); |
| 739 | iwl_mvm_request_statistics(mvm, true); | 739 | iwl_mvm_power_vif_assoc(mvm, vif); |
| 740 | iwl_mvm_sf_update(mvm, vif, false); | 740 | |
| 741 | iwl_mvm_power_vif_assoc(mvm, vif); | 741 | for_each_mvm_vif_valid_link(mvmvif, i) { |
| 742 | 742 | memset(&mvmvif->link[i]->beacon_stats, 0, | |
| 743 | for_each_mvm_vif_valid_link(mvmvif, i) { | 743 | sizeof(mvmvif->link[i]->beacon_stats)); |
| 744 | memset(&mvmvif->link[i]->beacon_stats, 0, | 744 | |
| 745 | sizeof(mvmvif->link[i]->beacon_stats)); | 745 | if (vif->p2p) { |
| 746 | iwl_mvm_update_smps(mvm, vif, | ||
| 747 | IWL_MVM_SMPS_REQ_PROT, | ||
| 748 | IEEE80211_SMPS_DYNAMIC, i); | ||
| 749 | } | ||
| 750 | |||
| 751 | rcu_read_lock(); | ||
| 752 | link_conf = rcu_dereference(vif->link_conf[i]); | ||
| 753 | if (link_conf && !link_conf->dtim_period) | ||
| 754 | protect = true; | ||
| 755 | rcu_read_unlock(); | ||
| 756 | } | ||
| 746 | 757 | ||
| 747 | if (vif->p2p) { | 758 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && |
| 748 | iwl_mvm_update_smps(mvm, vif, | 759 | protect) { |
| 749 | IWL_MVM_SMPS_REQ_PROT, | 760 | /* If we're not restarting and still haven't |
| 750 | IEEE80211_SMPS_DYNAMIC, i); | 761 | * heard a beacon (dtim period unknown) then |
| 762 | * make sure we still have enough minimum time | ||
| 763 | * remaining in the time event, since the auth | ||
| 764 | * might actually have taken quite a while | ||
| 765 | * (especially for SAE) and so the remaining | ||
| 766 | * time could be small without us having heard | ||
| 767 | * a beacon yet. | ||
| 768 | */ | ||
| 769 | iwl_mvm_protect_assoc(mvm, vif, 0); | ||
| 751 | } | 770 | } |
| 752 | 771 | ||
| 753 | rcu_read_lock(); | 772 | iwl_mvm_sf_update(mvm, vif, false); |
| 754 | link_conf = rcu_dereference(vif->link_conf[i]); | 773 | |
| 755 | if (link_conf && !link_conf->dtim_period) | 774 | /* FIXME: need to decide about misbehaving AP handling */ |
| 756 | protect = true; | 775 | iwl_mvm_power_vif_assoc(mvm, vif); |
| 757 | rcu_read_unlock(); | 776 | } else if (iwl_mvm_mld_vif_have_valid_ap_sta(mvmvif)) { |
| 758 | } | 777 | iwl_mvm_mei_host_disassociated(mvm); |
| 759 | 778 | ||
| 760 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && | 779 | /* If update fails - SF might be running in associated |
| 761 | protect) { | 780 | * mode while disassociated - which is forbidden. |
| 762 | /* If we're not restarting and still haven't | ||
| 763 | * heard a beacon (dtim period unknown) then | ||
| 764 | * make sure we still have enough minimum time | ||
| 765 | * remaining in the time event, since the auth | ||
| 766 | * might actually have taken quite a while | ||
| 767 | * (especially for SAE) and so the remaining | ||
| 768 | * time could be small without us having heard | ||
| 769 | * a beacon yet. | ||
| 770 | */ | 781 | */ |
| 771 | iwl_mvm_protect_assoc(mvm, vif, 0); | 782 | ret = iwl_mvm_sf_update(mvm, vif, false); |
| 783 | WARN_ONCE(ret && | ||
| 784 | !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, | ||
| 785 | &mvm->status), | ||
| 786 | "Failed to update SF upon disassociation\n"); | ||
| 787 | |||
| 788 | /* If we get an assert during the connection (after the | ||
| 789 | * station has been added, but before the vif is set | ||
| 790 | * to associated), mac80211 will re-add the station and | ||
| 791 | * then configure the vif. Since the vif is not | ||
| 792 | * associated, we would remove the station here and | ||
| 793 | * this would fail the recovery. | ||
| 794 | */ | ||
| 795 | iwl_mvm_mld_vif_delete_all_stas(mvm, vif); | ||
| 772 | } | 796 | } |
| 773 | 797 | ||
| 774 | iwl_mvm_sf_update(mvm, vif, false); | 798 | iwl_mvm_bss_info_changed_station_assoc(mvm, vif, changes); |
| 775 | |||
| 776 | /* FIXME: need to decide about misbehaving AP handling */ | ||
| 777 | iwl_mvm_power_vif_assoc(mvm, vif); | ||
| 778 | } else if (iwl_mvm_mld_vif_have_valid_ap_sta(mvmvif)) { | ||
| 779 | iwl_mvm_mei_host_disassociated(mvm); | ||
| 780 | |||
| 781 | /* If update fails - SF might be running in associated | ||
| 782 | * mode while disassociated - which is forbidden. | ||
| 783 | */ | ||
| 784 | ret = iwl_mvm_sf_update(mvm, vif, false); | ||
| 785 | WARN_ONCE(ret && | ||
| 786 | !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, | ||
| 787 | &mvm->status), | ||
| 788 | "Failed to update SF upon disassociation\n"); | ||
| 789 | |||
| 790 | /* If we get an assert during the connection (after the | ||
| 791 | * station has been added, but before the vif is set | ||
| 792 | * to associated), mac80211 will re-add the station and | ||
| 793 | * then configure the vif. Since the vif is not | ||
| 794 | * associated, we would remove the station here and | ||
| 795 | * this would fail the recovery. | ||
| 796 | */ | ||
| 797 | iwl_mvm_mld_vif_delete_all_stas(mvm, vif); | ||
| 798 | } | 799 | } |
| 799 | 800 | ||
| 800 | iwl_mvm_bss_info_changed_station_assoc(mvm, vif, changes); | 801 | if (changes & BSS_CHANGED_PS) { |
| 802 | ret = iwl_mvm_power_update_mac(mvm); | ||
| 803 | if (ret) | ||
| 804 | IWL_ERR(mvm, "failed to update power mode\n"); | ||
| 805 | } | ||
| 801 | } | 806 | } |
| 802 | 807 | ||
| 803 | static void | 808 | static void |
| @@ -2342,7 +2342,7 @@ iwl_mvm_scan_umac_fill_general_p_v12(struct iwl_mvm *mvm, · 2341 unmodified lines | |||
| 2342 | if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2) | 2342 | if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2) |
| 2343 | gp->num_of_fragments[SCAN_HB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS; | 2343 | gp->num_of_fragments[SCAN_HB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS; |
| 2344 | 2344 | ||
| 2345 | if (version < 12) { | 2345 | if (version < 16) { |
| 2346 | gp->scan_start_mac_or_link_id = scan_vif->id; | 2346 | gp->scan_start_mac_or_link_id = scan_vif->id; |
| 2347 | } else { | 2347 | } else { |
| 2348 | struct iwl_mvm_vif_link_info *link_info; | 2348 | struct iwl_mvm_vif_link_info *link_info; |
| @@ -1612,6 +1612,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, · 1611 unmodified lines | |||
| 1612 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); | 1612 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); |
| 1613 | 1613 | ||
| 1614 | memset(&info->status, 0, sizeof(info->status)); | 1614 | memset(&info->status, 0, sizeof(info->status)); |
| 1615 | info->flags &= ~(IEEE80211_TX_STAT_ACK | IEEE80211_TX_STAT_TX_FILTERED); | ||
| 1615 | 1616 | ||
| 1616 | /* inform mac80211 about what happened with the frame */ | 1617 | /* inform mac80211 about what happened with the frame */ |
| 1617 | switch (status & TX_STATUS_MSK) { | 1618 | switch (status & TX_STATUS_MSK) { |
| @@ -1964,6 +1965,8 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, · 346 unmodified lines | |||
| 1964 | */ | 1965 | */ |
| 1965 | if (!is_flush) | 1966 | if (!is_flush) |
| 1966 | info->flags |= IEEE80211_TX_STAT_ACK; | 1967 | info->flags |= IEEE80211_TX_STAT_ACK; |
| 1968 | else | ||
| 1969 | info->flags &= ~IEEE80211_TX_STAT_ACK; | ||
| 1967 | } | 1970 | } |
| 1968 | 1971 | ||
| 1969 | /* | 1972 | /* |
| @@ -918,9 +918,17 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, · 917 unmodified lines | |||
| 918 | 918 | ||
| 919 | mwifiex_dbg_dump(priv->adapter, EVT_D, "RXBA_SYNC event:", | 919 | mwifiex_dbg_dump(priv->adapter, EVT_D, "RXBA_SYNC event:", |
| 920 | event_buf, len); | 920 | event_buf, len); |
| 921 | while (tlv_buf_left >= sizeof(*tlv_rxba)) { | 921 | while (tlv_buf_left > sizeof(*tlv_rxba)) { |
| 922 | tlv_type = le16_to_cpu(tlv_rxba->header.type); | 922 | tlv_type = le16_to_cpu(tlv_rxba->header.type); |
| 923 | tlv_len = le16_to_cpu(tlv_rxba->header.len); | 923 | tlv_len = le16_to_cpu(tlv_rxba->header.len); |
| 924 | if (size_add(sizeof(tlv_rxba->header), tlv_len) > tlv_buf_left) { | ||
| 925 | mwifiex_dbg(priv->adapter, WARN, | ||
| 926 | "TLV size (%zu) overflows event_buf buf_left=%d\n", | ||
| 927 | size_add(sizeof(tlv_rxba->header), tlv_len), | ||
| 928 | tlv_buf_left); | ||
| 929 | return; | ||
| 930 | } | ||
| 931 | |||
| 924 | if (tlv_type != TLV_TYPE_RXBA_SYNC) { | 932 | if (tlv_type != TLV_TYPE_RXBA_SYNC) { |
| 925 | mwifiex_dbg(priv->adapter, ERROR, | 933 | mwifiex_dbg(priv->adapter, ERROR, |
| 926 | "Wrong TLV id=0x%x\n", tlv_type); | 934 | "Wrong TLV id=0x%x\n", tlv_type); |
| @@ -929,6 +937,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, · 2 unmodified lines | |||
| 929 | 937 | ||
| 930 | tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num); | 938 | tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num); |
| 931 | tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len); | 939 | tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len); |
| 940 | if (size_add(sizeof(*tlv_rxba), tlv_bitmap_len) > tlv_buf_left) { | ||
| 941 | mwifiex_dbg(priv->adapter, WARN, | ||
| 942 | "TLV size (%zu) overflows event_buf buf_left=%d\n", | ||
| 943 | size_add(sizeof(*tlv_rxba), tlv_bitmap_len), | ||
| 944 | tlv_buf_left); | ||
| 945 | return; | ||
| 946 | } | ||
| 947 | |||
| 932 | mwifiex_dbg(priv->adapter, INFO, | 948 | mwifiex_dbg(priv->adapter, INFO, |
| 933 | "%pM tid=%d seq_num=%d bitmap_len=%d\n", | 949 | "%pM tid=%d seq_num=%d bitmap_len=%d\n", |
| 934 | tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num, | 950 | tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num, |
| @@ -965,8 +981,8 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, · 30 unmodified lines | |||
| 965 | } | 981 | } |
| 966 | } | 982 | } |
| 967 | 983 | ||
| 968 | tlv_buf_left -= (sizeof(*tlv_rxba) + tlv_len); | 984 | tlv_buf_left -= (sizeof(tlv_rxba->header) + tlv_len); |
| 969 | tmp = (u8 *)tlv_rxba + tlv_len + sizeof(*tlv_rxba); | 985 | tmp = (u8 *)tlv_rxba + sizeof(tlv_rxba->header) + tlv_len; |
| 970 | tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp; | 986 | tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp; |
| 971 | } | 987 | } |
| 972 | } | 988 | } |
| @@ -779,7 +779,7 @@ struct mwifiex_ie_types_rxba_sync { · 778 unmodified lines | |||
| 779 | u8 reserved; | 779 | u8 reserved; |
| 780 | __le16 seq_num; | 780 | __le16 seq_num; |
| 781 | __le16 bitmap_len; | 781 | __le16 bitmap_len; |
| 782 | u8 bitmap[1]; | 782 | u8 bitmap[]; |
| 783 | } __packed; | 783 | } __packed; |
| 784 | 784 | ||
| 785 | struct chan_band_param_set { | 785 | struct chan_band_param_set { |
| @@ -86,7 +86,8 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv, · 85 unmodified lines | |||
| 86 | rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length); | 86 | rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length); |
| 87 | rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off; | 87 | rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off; |
| 88 | 88 | ||
| 89 | if (sizeof(*rx_pkt_hdr) + rx_pkt_off > skb->len) { | 89 | if (sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rfc1042_header) + |
| 90 | rx_pkt_off > skb->len) { | ||
| 90 | mwifiex_dbg(priv->adapter, ERROR, | 91 | mwifiex_dbg(priv->adapter, ERROR, |
| 91 | "wrong rx packet offset: len=%d, rx_pkt_off=%d\n", | 92 | "wrong rx packet offset: len=%d, rx_pkt_off=%d\n", |
| 92 | skb->len, rx_pkt_off); | 93 | skb->len, rx_pkt_off); |
| @@ -95,12 +96,13 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv, · 2 unmodified lines | |||
| 95 | return -1; | 96 | return -1; |
| 96 | } | 97 | } |
| 97 | 98 | ||
| 98 | if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, | 99 | if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len && |
| 99 | sizeof(bridge_tunnel_header))) || | 100 | ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, |
| 100 | (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, | 101 | sizeof(bridge_tunnel_header))) || |
| 101 | sizeof(rfc1042_header)) && | 102 | (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, |
| 102 | ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && | 103 | sizeof(rfc1042_header)) && |
| 103 | ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) { | 104 | ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && |
| 105 | ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) { | ||
| 104 | /* | 106 | /* |
| 105 | * Replace the 803 header and rfc1042 header (llc/snap) with an | 107 | * Replace the 803 header and rfc1042 header (llc/snap) with an |
| 106 | * EthernetII header, keep the src/dst and snap_type | 108 | * EthernetII header, keep the src/dst and snap_type |
| @@ -93,13 +93,13 @@ __mt76_get_rxwi(struct mt76_dev *dev) · 92 unmodified lines | |||
| 93 | { | 93 | { |
| 94 | struct mt76_txwi_cache *t = NULL; | 94 | struct mt76_txwi_cache *t = NULL; |
| 95 | 95 | ||
| 96 | spin_lock(&dev->wed_lock); | 96 | spin_lock_bh(&dev->wed_lock); |
| 97 | if (!list_empty(&dev->rxwi_cache)) { | 97 | if (!list_empty(&dev->rxwi_cache)) { |
| 98 | t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache, | 98 | t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache, |
| 99 | list); | 99 | list); |
| 100 | list_del(&t->list); | 100 | list_del(&t->list); |
| 101 | } | 101 | } |
| 102 | spin_unlock(&dev->wed_lock); | 102 | spin_unlock_bh(&dev->wed_lock); |
| 103 | 103 | ||
| 104 | return t; | 104 | return t; |
| 105 | } | 105 | } |
| @@ -145,9 +145,9 @@ mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t) · 39 unmodified lines | |||
| 145 | if (!t) | 145 | if (!t) |
| 146 | return; | 146 | return; |
| 147 | 147 | ||
| 148 | spin_lock(&dev->wed_lock); | 148 | spin_lock_bh(&dev->wed_lock); |
| 149 | list_add(&t->list, &dev->rxwi_cache); | 149 | list_add(&t->list, &dev->rxwi_cache); |
| 150 | spin_unlock(&dev->wed_lock); | 150 | spin_unlock_bh(&dev->wed_lock); |
| 151 | } | 151 | } |
| 152 | EXPORT_SYMBOL_GPL(mt76_put_rxwi); | 152 | EXPORT_SYMBOL_GPL(mt76_put_rxwi); |
| 153 | 153 | ||
| @@ -131,15 +131,8 @@ u8 mt76x02_get_lna_gain(struct mt76x02_dev *dev, · 130 unmodified lines | |||
| 131 | s8 *lna_2g, s8 *lna_5g, | 131 | s8 *lna_2g, s8 *lna_5g, |
| 132 | struct ieee80211_channel *chan) | 132 | struct ieee80211_channel *chan) |
| 133 | { | 133 | { |
| 134 | u16 val; | ||
| 135 | u8 lna; | 134 | u8 lna; |
| 136 | 135 | ||
| 137 | val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); | ||
| 138 | if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G) | ||
| 139 | *lna_2g = 0; | ||
| 140 | if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G) | ||
| 141 | memset(lna_5g, 0, sizeof(s8) * 3); | ||
| 142 | |||
| 143 | if (chan->band == NL80211_BAND_2GHZ) | 136 | if (chan->band == NL80211_BAND_2GHZ) |
| 144 | lna = *lna_2g; | 137 | lna = *lna_2g; |
| 145 | else if (chan->hw_value <= 64) | 138 | else if (chan->hw_value <= 64) |
| @@ -256,7 +256,8 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev) · 255 unmodified lines | |||
| 256 | struct ieee80211_channel *chan = dev->mphy.chandef.chan; | 256 | struct ieee80211_channel *chan = dev->mphy.chandef.chan; |
| 257 | int channel = chan->hw_value; | 257 | int channel = chan->hw_value; |
| 258 | s8 lna_5g[3], lna_2g; | 258 | s8 lna_5g[3], lna_2g; |
| 259 | u8 lna; | 259 | bool use_lna; |
| 260 | u8 lna = 0; | ||
| 260 | u16 val; | 261 | u16 val; |
| 261 | 262 | ||
| 262 | if (chan->band == NL80211_BAND_2GHZ) | 263 | if (chan->band == NL80211_BAND_2GHZ) |
| @@ -275,7 +276,15 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev) · 12 unmodified lines | |||
| 275 | dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; | 276 | dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; |
| 276 | dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; | 277 | dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; |
| 277 | 278 | ||
| 278 | lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); | 279 | val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); |
| 280 | if (chan->band == NL80211_BAND_2GHZ) | ||
| 281 | use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_2G); | ||
| 282 | else | ||
| 283 | use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_5G); | ||
| 284 | |||
| 285 | if (use_lna) | ||
| 286 | lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); | ||
| 287 | |||
| 279 | dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); | 288 | dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); |
| 280 | } | 289 | } |
| 281 | EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); | 290 | EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); |
| @@ -46,6 +46,7 @@ struct rtw8723du_efuse { · 45 unmodified lines | |||
| 46 | u8 vender_id[2]; /* 0x100 */ | 46 | u8 vender_id[2]; /* 0x100 */ |
| 47 | u8 product_id[2]; /* 0x102 */ | 47 | u8 product_id[2]; /* 0x102 */ |
| 48 | u8 usb_option; /* 0x104 */ | 48 | u8 usb_option; /* 0x104 */ |
| 49 | u8 res5[2]; /* 0x105 */ | ||
| 49 | u8 mac_addr[ETH_ALEN]; /* 0x107 */ | 50 | u8 mac_addr[ETH_ALEN]; /* 0x107 */ |
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| @@ -229,6 +229,7 @@ int pcie_aer_is_native(struct pci_dev *dev) · 228 unmodified lines | |||
| 229 | 229 | ||
| 230 | return pcie_ports_native || host->native_aer; | 230 | return pcie_ports_native || host->native_aer; |
| 231 | } | 231 | } |
| 232 | EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, CXL); | ||
| 232 | 233 | ||
| 233 | static int pci_enable_pcie_error_reporting(struct pci_dev *dev) | 234 | static int pci_enable_pcie_error_reporting(struct pci_dev *dev) |
| 234 | { | 235 | { |
| @@ -29,10 +29,8 @@ extern bool pcie_ports_dpc_native; · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #ifdef CONFIG_PCIEAER | 30 | #ifdef CONFIG_PCIEAER |
| 31 | int pcie_aer_init(void); | 31 | int pcie_aer_init(void); |
| 32 | int pcie_aer_is_native(struct pci_dev *dev); | ||
| 33 | #else | 32 | #else |
| 34 | static inline int pcie_aer_init(void) { return 0; } | 33 | static inline int pcie_aer_init(void) { return 0; } |
| 35 | static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; } | ||
| 36 | #endif | 34 | #endif |
| 37 | 35 | ||
| 38 | #ifdef CONFIG_HOTPLUG_PCI_PCIE | 36 | #ifdef CONFIG_HOTPLUG_PCI_PCIE |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
| 22 | #include <linux/iopoll.h> | ||
| 22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 24 | 25 | ||
| @@ -231,19 +232,15 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset) · 206 unmodified lines | |||
| 231 | /* Wait till scu status is busy */ | 232 | /* Wait till scu status is busy */ |
| 232 | static inline int busy_loop(struct intel_scu_ipc_dev *scu) | 233 | static inline int busy_loop(struct intel_scu_ipc_dev *scu) |
| 233 | { | 234 | { |
| 234 | unsigned long end = jiffies + IPC_TIMEOUT; | 235 | u8 status; |
| 235 | 236 | int err; | |
| 236 | do { | ||
| 237 | u32 status; | ||
| 238 | |||
| 239 | status = ipc_read_status(scu); | ||
| 240 | if (!(status & IPC_STATUS_BUSY)) | ||
| 241 | return (status & IPC_STATUS_ERR) ? -EIO : 0; | ||
| 242 | 237 | ||
| 243 | usleep_range(50, 100); | 238 | err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY), |
| 244 | } while (time_before(jiffies, end)); | 239 | 100, jiffies_to_usecs(IPC_TIMEOUT)); |
| 240 | if (err) | ||
| 241 | return err; | ||
| 245 | 242 | ||
| 246 | return -ETIMEDOUT; | 243 | return (status & IPC_STATUS_ERR) ? -EIO : 0; |
| 247 | } | 244 | } |
| 248 | 245 | ||
| 249 | /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ | 246 | /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ |
| @@ -251,10 +248,12 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu) · 1 unmodified line | |||
| 251 | { | 248 | { |
| 252 | int status; | 249 | int status; |
| 253 | 250 | ||
| 254 | if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) | 251 | wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT); |
| 255 | return -ETIMEDOUT; | ||
| 256 | 252 | ||
| 257 | status = ipc_read_status(scu); | 253 | status = ipc_read_status(scu); |
| 254 | if (status & IPC_STATUS_BUSY) | ||
| 255 | return -ETIMEDOUT; | ||
| 256 | |||
| 258 | if (status & IPC_STATUS_ERR) | 257 | if (status & IPC_STATUS_ERR) |
| 259 | return -EIO; | 258 | return -EIO; |
| 260 | 259 | ||
| @@ -266,6 +265,24 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu) · 5 unmodified lines | |||
| 266 | return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu); | 265 | return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu); |
| 267 | } | 266 | } |
| 268 | 267 | ||
| 268 | static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu) | ||
| 269 | { | ||
| 270 | u8 status; | ||
| 271 | |||
| 272 | if (!scu) | ||
| 273 | scu = ipcdev; | ||
| 274 | if (!scu) | ||
| 275 | return ERR_PTR(-ENODEV); | ||
| 276 | |||
| 277 | status = ipc_read_status(scu); | ||
| 278 | if (status & IPC_STATUS_BUSY) { | ||
| 279 | dev_dbg(&scu->dev, "device is busy\n"); | ||
| 280 | return ERR_PTR(-EBUSY); | ||
| 281 | } | ||
| 282 | |||
| 283 | return scu; | ||
| 284 | } | ||
| 285 | |||
| 269 | /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ | 286 | /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ |
| 270 | static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, | 287 | static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, |
| 271 | u32 count, u32 op, u32 id) | 288 | u32 count, u32 op, u32 id) |
| @@ -279,11 +296,10 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, · 7 unmodified lines | |||
| 279 | memset(cbuf, 0, sizeof(cbuf)); | 296 | memset(cbuf, 0, sizeof(cbuf)); |
| 280 | 297 | ||
| 281 | mutex_lock(&ipclock); | 298 | mutex_lock(&ipclock); |
| 282 | if (!scu) | 299 | scu = intel_scu_ipc_get(scu); |
| 283 | scu = ipcdev; | 300 | if (IS_ERR(scu)) { |
| 284 | if (!scu) { | ||
| 285 | mutex_unlock(&ipclock); | 301 | mutex_unlock(&ipclock); |
| 286 | return -ENODEV; | 302 | return PTR_ERR(scu); |
| 287 | } | 303 | } |
| 288 | 304 | ||
| 289 | for (nc = 0; nc < count; nc++, offset += 2) { | 305 | for (nc = 0; nc < count; nc++, offset += 2) { |
| @@ -438,13 +454,12 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd, · 148 unmodified lines | |||
| 438 | int err; | 454 | int err; |
| 439 | 455 | ||
| 440 | mutex_lock(&ipclock); | 456 | mutex_lock(&ipclock); |
| 441 | if (!scu) | 457 | scu = intel_scu_ipc_get(scu); |
| 442 | scu = ipcdev; | 458 | if (IS_ERR(scu)) { |
| 443 | if (!scu) { | ||
| 444 | mutex_unlock(&ipclock); | 459 | mutex_unlock(&ipclock); |
| 445 | return -ENODEV; | 460 | return PTR_ERR(scu); |
| 446 | } | 461 | } |
| 447 | scu = ipcdev; | 462 | |
| 448 | cmdval = sub << 12 | cmd; | 463 | cmdval = sub << 12 | cmd; |
| 449 | ipc_command(scu, cmdval); | 464 | ipc_command(scu, cmdval); |
| 450 | err = intel_scu_ipc_check_status(scu); | 465 | err = intel_scu_ipc_check_status(scu); |
| @@ -484,11 +499,10 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd, · 33 unmodified lines | |||
| 484 | return -EINVAL; | 499 | return -EINVAL; |
| 485 | 500 | ||
| 486 | mutex_lock(&ipclock); | 501 | mutex_lock(&ipclock); |
| 487 | if (!scu) | 502 | scu = intel_scu_ipc_get(scu); |
| 488 | scu = ipcdev; | 503 | if (IS_ERR(scu)) { |
| 489 | if (!scu) { | ||
| 490 | mutex_unlock(&ipclock); | 504 | mutex_unlock(&ipclock); |
| 491 | return -ENODEV; | 505 | return PTR_ERR(scu); |
| 492 | } | 506 | } |
| 493 | 507 | ||
| 494 | memcpy(inbuf, in, inlen); | 508 | memcpy(inbuf, in, inlen); |
| @@ -4116,9 +4116,11 @@ static void hotkey_resume(void) · 4115 unmodified lines | |||
| 4116 | { | 4116 | { |
| 4117 | tpacpi_disable_brightness_delay(); | 4117 | tpacpi_disable_brightness_delay(); |
| 4118 | 4118 | ||
| 4119 | mutex_lock(&hotkey_mutex); | ||
| 4119 | if (hotkey_status_set(true) < 0 || | 4120 | if (hotkey_status_set(true) < 0 || |
| 4120 | hotkey_mask_set(hotkey_acpi_mask) < 0) | 4121 | hotkey_mask_set(hotkey_acpi_mask) < 0) |
| 4121 | pr_err("error while attempting to reset the event firmware interface\n"); | 4122 | pr_err("error while attempting to reset the event firmware interface\n"); |
| 4123 | mutex_unlock(&hotkey_mutex); | ||
| 4122 | 4124 | ||
| 4123 | tpacpi_send_radiosw_update(); | 4125 | tpacpi_send_radiosw_update(); |
| 4124 | tpacpi_input_send_tabletsw(); | 4126 | tpacpi_input_send_tabletsw(); |
| @@ -300,7 +300,7 @@ config NVMEM_REBOOT_MODE · 299 unmodified lines | |||
| 300 | 300 | ||
| 301 | config POWER_MLXBF | 301 | config POWER_MLXBF |
| 302 | tristate "Mellanox BlueField power handling driver" | 302 | tristate "Mellanox BlueField power handling driver" |
| 303 | depends on (GPIO_MLXBF2 && ACPI) | 303 | depends on (GPIO_MLXBF2 || GPIO_MLXBF3) && ACPI |
| 304 | help | 304 | help |
| 305 | This driver supports reset or low power mode handling for Mellanox BlueField. | 305 | This driver supports reset or low power mode handling for Mellanox BlueField. |
| 306 | 306 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only or BSD-3-Clause | 1 | // SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. | 4 | * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. |
| @@ -121,7 +121,7 @@ static int vexpress_reset_probe(struct platform_device *pdev) · 120 unmodified lines | |||
| 121 | return PTR_ERR(regmap); | 121 | return PTR_ERR(regmap); |
| 122 | dev_set_drvdata(&pdev->dev, regmap); | 122 | dev_set_drvdata(&pdev->dev, regmap); |
| 123 | 123 | ||
| 124 | switch ((enum vexpress_reset_func)match->data) { | 124 | switch ((uintptr_t)match->data) { |
| 125 | case FUNC_SHUTDOWN: | 125 | case FUNC_SHUTDOWN: |
| 126 | vexpress_power_off_device = &pdev->dev; | 126 | vexpress_power_off_device = &pdev->dev; |
| 127 | pm_power_off = vexpress_power_off; | 127 | pm_power_off = vexpress_power_off; |
| @@ -769,6 +769,7 @@ config BATTERY_RT5033 · 768 unmodified lines | |||
| 769 | config CHARGER_RT5033 | 769 | config CHARGER_RT5033 |
| 770 | tristate "RT5033 battery charger support" | 770 | tristate "RT5033 battery charger support" |
| 771 | depends on MFD_RT5033 | 771 | depends on MFD_RT5033 |
| 772 | depends on EXTCON || !EXTCON | ||
| 772 | help | 773 | help |
| 773 | This adds support for battery charger in Richtek RT5033 PMIC. | 774 | This adds support for battery charger in Richtek RT5033 PMIC. |
| 774 | The device supports pre-charge mode, fast charge mode and | 775 | The device supports pre-charge mode, fast charge mode and |
| @@ -115,7 +115,6 @@ struct ab8500_btemp { · 114 unmodified lines | |||
| 115 | static enum power_supply_property ab8500_btemp_props[] = { | 115 | static enum power_supply_property ab8500_btemp_props[] = { |
| 116 | POWER_SUPPLY_PROP_PRESENT, | 116 | POWER_SUPPLY_PROP_PRESENT, |
| 117 | POWER_SUPPLY_PROP_ONLINE, | 117 | POWER_SUPPLY_PROP_ONLINE, |
| 118 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
| 119 | POWER_SUPPLY_PROP_TEMP, | 118 | POWER_SUPPLY_PROP_TEMP, |
| 120 | }; | 119 | }; |
| 121 | 120 | ||
| @@ -532,12 +531,6 @@ static int ab8500_btemp_get_property(struct power_supply *psy, · 410 unmodified lines | |||
| 532 | else | 531 | else |
| 533 | val->intval = 1; | 532 | val->intval = 1; |
| 534 | break; | 533 | break; |
| 535 | case POWER_SUPPLY_PROP_TECHNOLOGY: | ||
| 536 | if (di->bm->bi) | ||
| 537 | val->intval = di->bm->bi->technology; | ||
| 538 | else | ||
| 539 | val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; | ||
| 540 | break; | ||
| 541 | case POWER_SUPPLY_PROP_TEMP: | 534 | case POWER_SUPPLY_PROP_TEMP: |
| 542 | val->intval = ab8500_btemp_get_temp(di); | 535 | val->intval = ab8500_btemp_get_temp(di); |
| 543 | break; | 536 | break; |
| @@ -662,7 +655,7 @@ static char *supply_interface[] = { · 118 unmodified lines | |||
| 662 | 655 | ||
| 663 | static const struct power_supply_desc ab8500_btemp_desc = { | 656 | static const struct power_supply_desc ab8500_btemp_desc = { |
| 664 | .name = "ab8500_btemp", | 657 | .name = "ab8500_btemp", |
| 665 | .type = POWER_SUPPLY_TYPE_BATTERY, | 658 | .type = POWER_SUPPLY_TYPE_UNKNOWN, |
| 666 | .properties = ab8500_btemp_props, | 659 | .properties = ab8500_btemp_props, |
| 667 | .num_properties = ARRAY_SIZE(ab8500_btemp_props), | 660 | .num_properties = ARRAY_SIZE(ab8500_btemp_props), |
| 668 | .get_property = ab8500_btemp_get_property, | 661 | .get_property = ab8500_btemp_get_property, |
| @@ -1720,7 +1720,7 @@ static char *supply_interface[] = { · 1719 unmodified lines | |||
| 1720 | 1720 | ||
| 1721 | static const struct power_supply_desc ab8500_chargalg_desc = { | 1721 | static const struct power_supply_desc ab8500_chargalg_desc = { |
| 1722 | .name = "ab8500_chargalg", | 1722 | .name = "ab8500_chargalg", |
| 1723 | .type = POWER_SUPPLY_TYPE_BATTERY, | 1723 | .type = POWER_SUPPLY_TYPE_UNKNOWN, |
| 1724 | .properties = ab8500_chargalg_props, | 1724 | .properties = ab8500_chargalg_props, |
| 1725 | .num_properties = ARRAY_SIZE(ab8500_chargalg_props), | 1725 | .num_properties = ARRAY_SIZE(ab8500_chargalg_props), |
| 1726 | .get_property = ab8500_chargalg_get_property, | 1726 | .get_property = ab8500_chargalg_get_property, |
| @@ -324,7 +324,7 @@ static int mt6370_chg_toggle_cfo(struct mt6370_priv *priv) · 323 unmodified lines | |||
| 324 | 324 | ||
| 325 | if (fl_strobe) { | 325 | if (fl_strobe) { |
| 326 | dev_err(priv->dev, "Flash led is still in strobe mode\n"); | 326 | dev_err(priv->dev, "Flash led is still in strobe mode\n"); |
| 327 | return ret; | 327 | return -EINVAL; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | /* cfo off */ | 330 | /* cfo off */ |
| @@ -482,6 +482,13 @@ int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env) · 481 unmodified lines | |||
| 482 | if (ret) | 482 | if (ret) |
| 483 | return ret; | 483 | return ret; |
| 484 | 484 | ||
| 485 | /* | ||
| 486 | * Kernel generates KOBJ_REMOVE uevent in device removal path, after | ||
| 487 | * resources have been freed. Exit early to avoid use-after-free. | ||
| 488 | */ | ||
| 489 | if (psy->removing) | ||
| 490 | return 0; | ||
| 491 | |||
| 485 | prop_buf = (char *)get_zeroed_page(GFP_KERNEL); | 492 | prop_buf = (char *)get_zeroed_page(GFP_KERNEL); |
| 486 | if (!prop_buf) | 493 | if (!prop_buf) |
| 487 | return -ENOMEM; | 494 | return -ENOMEM; |
| @@ -1045,6 +1045,13 @@ static void rk817_charging_monitor(struct work_struct *work) · 1044 unmodified lines | |||
| 1045 | queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); | 1045 | queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); |
| 1046 | } | 1046 | } |
| 1047 | 1047 | ||
| 1048 | static void rk817_cleanup_node(void *data) | ||
| 1049 | { | ||
| 1050 | struct device_node *node = data; | ||
| 1051 | |||
| 1052 | of_node_put(node); | ||
| 1053 | } | ||
| 1054 | |||
| 1048 | static int rk817_charger_probe(struct platform_device *pdev) | 1055 | static int rk817_charger_probe(struct platform_device *pdev) |
| 1049 | { | 1056 | { |
| 1050 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | 1057 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); |
| @@ -1061,11 +1068,13 @@ static int rk817_charger_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 1061 | if (!node) | 1068 | if (!node) |
| 1062 | return -ENODEV; | 1069 | return -ENODEV; |
| 1063 | 1070 | ||
| 1071 | ret = devm_add_action_or_reset(&pdev->dev, rk817_cleanup_node, node); | ||
| 1072 | if (ret) | ||
| 1073 | return ret; | ||
| 1074 | |||
| 1064 | charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); | 1075 | charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); |
| 1065 | if (!charger) { | 1076 | if (!charger) |
| 1066 | of_node_put(node); | ||
| 1067 | return -ENOMEM; | 1077 | return -ENOMEM; |
| 1068 | } | ||
| 1069 | 1078 | ||
| 1070 | charger->rk808 = rk808; | 1079 | charger->rk808 = rk808; |
| 1071 | 1080 | ||
| @@ -1211,3 +1220,4 @@ MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC"); · 139 unmodified lines | |||
| 1211 | MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc@gmail.com>"); | 1220 | MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc@gmail.com>"); |
| 1212 | MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); | 1221 | MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); |
| 1213 | MODULE_LICENSE("GPL"); | 1222 | MODULE_LICENSE("GPL"); |
| 1223 | MODULE_ALIAS("platform:rk817-charger"); | ||
| @@ -598,8 +598,8 @@ static int rt9467_run_aicl(struct rt9467_chg_data *data) · 597 unmodified lines | |||
| 598 | 598 | ||
| 599 | reinit_completion(&data->aicl_done); | 599 | reinit_completion(&data->aicl_done); |
| 600 | ret = wait_for_completion_timeout(&data->aicl_done, msecs_to_jiffies(3500)); | 600 | ret = wait_for_completion_timeout(&data->aicl_done, msecs_to_jiffies(3500)); |
| 601 | if (ret) | 601 | if (ret == 0) |
| 602 | return ret; | 602 | return -ETIMEDOUT; |
| 603 | 603 | ||
| 604 | ret = rt9467_get_value_from_ranges(data, F_IAICR, RT9467_RANGE_IAICR, &aicr_get); | 604 | ret = rt9467_get_value_from_ranges(data, F_IAICR, RT9467_RANGE_IAICR, &aicr_get); |
| 605 | if (ret) { | 605 | if (ret) { |
| @@ -384,7 +384,8 @@ static int ucs1002_get_property(struct power_supply *psy, · 383 unmodified lines | |||
| 384 | case POWER_SUPPLY_PROP_USB_TYPE: | 384 | case POWER_SUPPLY_PROP_USB_TYPE: |
| 385 | return ucs1002_get_usb_type(info, val); | 385 | return ucs1002_get_usb_type(info, val); |
| 386 | case POWER_SUPPLY_PROP_HEALTH: | 386 | case POWER_SUPPLY_PROP_HEALTH: |
| 387 | return val->intval = info->health; | 387 | val->intval = info->health; |
| 388 | return 0; | ||
| 388 | case POWER_SUPPLY_PROP_PRESENT: | 389 | case POWER_SUPPLY_PROP_PRESENT: |
| 389 | val->intval = info->present; | 390 | val->intval = info->present; |
| 390 | return 0; | 391 | return 0; |
| @@ -4046,7 +4046,6 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev) · 4045 unmodified lines | |||
| 4046 | return 0; | 4046 | return 0; |
| 4047 | 4047 | ||
| 4048 | out: | 4048 | out: |
| 4049 | ptp_ocp_dev_release(&bp->dev); | ||
| 4050 | put_device(&bp->dev); | 4049 | put_device(&bp->dev); |
| 4051 | return err; | 4050 | return err; |
| 4052 | } | 4051 | } |
| @@ -5542,6 +5542,8 @@ regulator_register(struct device *dev, · 5541 unmodified lines | |||
| 5542 | goto rinse; | 5542 | goto rinse; |
| 5543 | } | 5543 | } |
| 5544 | device_initialize(&rdev->dev); | 5544 | device_initialize(&rdev->dev); |
| 5545 | dev_set_drvdata(&rdev->dev, rdev); | ||
| 5546 | rdev->dev.class = ®ulator_class; | ||
| 5545 | spin_lock_init(&rdev->err_lock); | 5547 | spin_lock_init(&rdev->err_lock); |
| 5546 | 5548 | ||
| 5547 | /* | 5549 | /* |
| @@ -5603,11 +5605,9 @@ regulator_register(struct device *dev, · 55 unmodified lines | |||
| 5603 | rdev->supply_name = regulator_desc->supply_name; | 5605 | rdev->supply_name = regulator_desc->supply_name; |
| 5604 | 5606 | ||
| 5605 | /* register with sysfs */ | 5607 | /* register with sysfs */ |
| 5606 | rdev->dev.class = ®ulator_class; | ||
| 5607 | rdev->dev.parent = config->dev; | 5608 | rdev->dev.parent = config->dev; |
| 5608 | dev_set_name(&rdev->dev, "regulator.%lu", | 5609 | dev_set_name(&rdev->dev, "regulator.%lu", |
| 5609 | (unsigned long) atomic_inc_return(®ulator_no)); | 5610 | (unsigned long) atomic_inc_return(®ulator_no)); |
| 5610 | dev_set_drvdata(&rdev->dev, rdev); | ||
| 5611 | 5611 | ||
| 5612 | /* set regulator constraints */ | 5612 | /* set regulator constraints */ |
| 5613 | if (init_data) | 5613 | if (init_data) |
| @@ -5724,15 +5724,11 @@ wash: · 110 unmodified lines | |||
| 5724 | mutex_lock(®ulator_list_mutex); | 5724 | mutex_lock(®ulator_list_mutex); |
| 5725 | regulator_ena_gpio_free(rdev); | 5725 | regulator_ena_gpio_free(rdev); |
| 5726 | mutex_unlock(®ulator_list_mutex); | 5726 | mutex_unlock(®ulator_list_mutex); |
| 5727 | put_device(&rdev->dev); | ||
| 5728 | rdev = NULL; | ||
| 5729 | clean: | 5727 | clean: |
| 5730 | if (dangling_of_gpiod) | 5728 | if (dangling_of_gpiod) |
| 5731 | gpiod_put(config->ena_gpiod); | 5729 | gpiod_put(config->ena_gpiod); |
| 5732 | if (rdev && rdev->dev.of_node) | ||
| 5733 | of_node_put(rdev->dev.of_node); | ||
| 5734 | kfree(rdev); | ||
| 5735 | kfree(config); | 5730 | kfree(config); |
| 5731 | put_device(&rdev->dev); | ||
| 5736 | rinse: | 5732 | rinse: |
| 5737 | if (dangling_cfg_gpiod) | 5733 | if (dangling_cfg_gpiod) |
| 5738 | gpiod_put(cfg->ena_gpiod); | 5734 | gpiod_put(cfg->ena_gpiod); |
| @@ -43,7 +43,7 @@ struct mt6358_regulator_info { · 42 unmodified lines | |||
| 43 | .desc = { \ | 43 | .desc = { \ |
| 44 | .name = #vreg, \ | 44 | .name = #vreg, \ |
| 45 | .of_match = of_match_ptr(match), \ | 45 | .of_match = of_match_ptr(match), \ |
| 46 | .ops = &mt6358_volt_range_ops, \ | 46 | .ops = &mt6358_buck_ops, \ |
| 47 | .type = REGULATOR_VOLTAGE, \ | 47 | .type = REGULATOR_VOLTAGE, \ |
| 48 | .id = MT6358_ID_##vreg, \ | 48 | .id = MT6358_ID_##vreg, \ |
| 49 | .owner = THIS_MODULE, \ | 49 | .owner = THIS_MODULE, \ |
| @@ -139,7 +139,7 @@ struct mt6358_regulator_info { · 89 unmodified lines | |||
| 139 | .desc = { \ | 139 | .desc = { \ |
| 140 | .name = #vreg, \ | 140 | .name = #vreg, \ |
| 141 | .of_match = of_match_ptr(match), \ | 141 | .of_match = of_match_ptr(match), \ |
| 142 | .ops = &mt6358_volt_range_ops, \ | 142 | .ops = &mt6358_buck_ops, \ |
| 143 | .type = REGULATOR_VOLTAGE, \ | 143 | .type = REGULATOR_VOLTAGE, \ |
| 144 | .id = MT6366_ID_##vreg, \ | 144 | .id = MT6366_ID_##vreg, \ |
| 145 | .owner = THIS_MODULE, \ | 145 | .owner = THIS_MODULE, \ |
| @@ -450,7 +450,7 @@ static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev) · 304 unmodified lines | |||
| 450 | } | 450 | } |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | static const struct regulator_ops mt6358_volt_range_ops = { | 453 | static const struct regulator_ops mt6358_buck_ops = { |
| 454 | .list_voltage = regulator_list_voltage_linear, | 454 | .list_voltage = regulator_list_voltage_linear, |
| 455 | .map_voltage = regulator_map_voltage_linear, | 455 | .map_voltage = regulator_map_voltage_linear, |
| 456 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 456 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| @@ -464,6 +464,18 @@ static const struct regulator_ops mt6358_volt_range_ops = { · 7 unmodified lines | |||
| 464 | .get_mode = mt6358_regulator_get_mode, | 464 | .get_mode = mt6358_regulator_get_mode, |
| 465 | }; | 465 | }; |
| 466 | 466 | ||
| 467 | static const struct regulator_ops mt6358_volt_range_ops = { | ||
| 468 | .list_voltage = regulator_list_voltage_linear, | ||
| 469 | .map_voltage = regulator_map_voltage_linear, | ||
| 470 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
| 471 | .get_voltage_sel = mt6358_get_buck_voltage_sel, | ||
| 472 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
| 473 | .enable = regulator_enable_regmap, | ||
| 474 | .disable = regulator_disable_regmap, | ||
| 475 | .is_enabled = regulator_is_enabled_regmap, | ||
| 476 | .get_status = mt6358_get_status, | ||
| 477 | }; | ||
| 478 | |||
| 467 | static const struct regulator_ops mt6358_volt_table_ops = { | 479 | static const struct regulator_ops mt6358_volt_table_ops = { |
| 468 | .list_voltage = regulator_list_voltage_table, | 480 | .list_voltage = regulator_list_voltage_table, |
| 469 | .map_voltage = regulator_map_voltage_iterate, | 481 | .map_voltage = regulator_map_voltage_iterate, |
| @@ -518,12 +518,12 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, · 517 unmodified lines | |||
| 518 | if (port) { | 518 | if (port) { |
| 519 | put_device(&port->dev); | 519 | put_device(&port->dev); |
| 520 | retval = -EEXIST; | 520 | retval = -EEXIST; |
| 521 | goto err_out; | 521 | goto err_put; |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); | 524 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); |
| 525 | if (!port) | 525 | if (!port) |
| 526 | goto err_out; | 526 | goto err_put; |
| 527 | 527 | ||
| 528 | rwlock_init(&port->unit_list_lock); | 528 | rwlock_init(&port->unit_list_lock); |
| 529 | INIT_LIST_HEAD(&port->unit_list); | 529 | INIT_LIST_HEAD(&port->unit_list); |
| @@ -546,7 +546,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, · 16 unmodified lines | |||
| 546 | 546 | ||
| 547 | if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { | 547 | if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { |
| 548 | kfree(port); | 548 | kfree(port); |
| 549 | goto err_out; | 549 | goto err_put; |
| 550 | } | 550 | } |
| 551 | retval = -EINVAL; | 551 | retval = -EINVAL; |
| 552 | 552 | ||
| @@ -563,7 +563,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, · 10 unmodified lines | |||
| 563 | 563 | ||
| 564 | return port; | 564 | return port; |
| 565 | 565 | ||
| 566 | err_out: | 566 | err_put: |
| 567 | zfcp_ccw_adapter_put(adapter); | 567 | zfcp_ccw_adapter_put(adapter); |
| 568 | err_out: | ||
| 568 | return ERR_PTR(retval); | 569 | return ERR_PTR(retval); |
| 569 | } | 570 | } |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | #define DRV_NAME "fnic" | 28 | #define DRV_NAME "fnic" |
| 29 | #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" | 29 | #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" |
| 30 | #define DRV_VERSION "1.6.0.56" | 30 | #define DRV_VERSION "1.6.0.57" |
| 31 | #define PFX DRV_NAME ": " | 31 | #define PFX DRV_NAME ": " |
| 32 | #define DFX DRV_NAME "%d: " | 32 | #define DFX DRV_NAME "%d: " |
| 33 | 33 | ||
| @@ -237,6 +237,8 @@ struct fnic { · 203 unmodified lines | |||
| 237 | unsigned int cq_count; | 237 | unsigned int cq_count; |
| 238 | 238 | ||
| 239 | struct mutex sgreset_mutex; | 239 | struct mutex sgreset_mutex; |
| 240 | spinlock_t sgreset_lock; /* lock for sgreset */ | ||
| 241 | struct scsi_cmnd *sgreset_sc; | ||
| 240 | struct dentry *fnic_stats_debugfs_host; | 242 | struct dentry *fnic_stats_debugfs_host; |
| 241 | struct dentry *fnic_stats_debugfs_file; | 243 | struct dentry *fnic_stats_debugfs_file; |
| 242 | struct dentry *fnic_reset_debugfs_file; | 244 | struct dentry *fnic_reset_debugfs_file; |
| @@ -52,6 +52,8 @@ struct fnic_io_req { · 51 unmodified lines | |||
| 52 | unsigned long start_time; /* in jiffies */ | 52 | unsigned long start_time; /* in jiffies */ |
| 53 | struct completion *abts_done; /* completion for abts */ | 53 | struct completion *abts_done; /* completion for abts */ |
| 54 | struct completion *dr_done; /* completion for device reset */ | 54 | struct completion *dr_done; /* completion for device reset */ |
| 55 | unsigned int tag; | ||
| 56 | struct scsi_cmnd *sc; /* midlayer's cmd pointer */ | ||
| 55 | }; | 57 | }; |
| 56 | 58 | ||
| 57 | enum fnic_port_speeds { | 59 | enum fnic_port_speeds { |
| @@ -754,6 +754,8 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 753 unmodified lines | |||
| 754 | for (i = 0; i < FNIC_IO_LOCKS; i++) | 754 | for (i = 0; i < FNIC_IO_LOCKS; i++) |
| 755 | spin_lock_init(&fnic->io_req_lock[i]); | 755 | spin_lock_init(&fnic->io_req_lock[i]); |
| 756 | 756 | ||
| 757 | spin_lock_init(&fnic->sgreset_lock); | ||
| 758 | |||
| 757 | err = -ENOMEM; | 759 | err = -ENOMEM; |
| 758 | fnic->io_req_pool = mempool_create_slab_pool(2, fnic_io_req_cache); | 760 | fnic->io_req_pool = mempool_create_slab_pool(2, fnic_io_req_cache); |
| 759 | if (!fnic->io_req_pool) | 761 | if (!fnic->io_req_pool) |
| @@ -1047,9 +1047,9 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, · 1046 unmodified lines | |||
| 1047 | { | 1047 | { |
| 1048 | u8 type; | 1048 | u8 type; |
| 1049 | u8 hdr_status; | 1049 | u8 hdr_status; |
| 1050 | struct fcpio_tag tag; | 1050 | struct fcpio_tag ftag; |
| 1051 | u32 id; | 1051 | u32 id; |
| 1052 | struct scsi_cmnd *sc; | 1052 | struct scsi_cmnd *sc = NULL; |
| 1053 | struct fnic_io_req *io_req; | 1053 | struct fnic_io_req *io_req; |
| 1054 | struct fnic_stats *fnic_stats = &fnic->fnic_stats; | 1054 | struct fnic_stats *fnic_stats = &fnic->fnic_stats; |
| 1055 | struct abort_stats *abts_stats = &fnic->fnic_stats.abts_stats; | 1055 | struct abort_stats *abts_stats = &fnic->fnic_stats.abts_stats; |
| @@ -1058,27 +1058,43 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, · 2 unmodified lines | |||
| 1058 | unsigned long flags; | 1058 | unsigned long flags; |
| 1059 | spinlock_t *io_lock; | 1059 | spinlock_t *io_lock; |
| 1060 | unsigned long start_time; | 1060 | unsigned long start_time; |
| 1061 | unsigned int tag; | ||
| 1061 | 1062 | ||
| 1062 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); | 1063 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &ftag); |
| 1063 | fcpio_tag_id_dec(&tag, &id); | 1064 | fcpio_tag_id_dec(&ftag, &id); |
| 1064 | 1065 | ||
| 1065 | if ((id & FNIC_TAG_MASK) >= fnic->fnic_max_tag_id) { | 1066 | tag = id & FNIC_TAG_MASK; |
| 1067 | if (tag == fnic->fnic_max_tag_id) { | ||
| 1068 | if (!(id & FNIC_TAG_DEV_RST)) { | ||
| 1069 | shost_printk(KERN_ERR, fnic->lport->host, | ||
| 1070 | "Tag out of range id 0x%x hdr status = %s\n", | ||
| 1071 | id, fnic_fcpio_status_to_str(hdr_status)); | ||
| 1072 | return; | ||
| 1073 | } | ||
| 1074 | } else if (tag > fnic->fnic_max_tag_id) { | ||
| 1066 | shost_printk(KERN_ERR, fnic->lport->host, | 1075 | shost_printk(KERN_ERR, fnic->lport->host, |
| 1067 | "Tag out of range tag %x hdr status = %s\n", | 1076 | "Tag out of range tag 0x%x hdr status = %s\n", |
| 1068 | id, fnic_fcpio_status_to_str(hdr_status)); | 1077 | tag, fnic_fcpio_status_to_str(hdr_status)); |
| 1069 | return; | 1078 | return; |
| 1070 | } | 1079 | } |
| 1071 | 1080 | ||
| 1072 | sc = scsi_host_find_tag(fnic->lport->host, id & FNIC_TAG_MASK); | 1081 | if ((tag == fnic->fnic_max_tag_id) && (id & FNIC_TAG_DEV_RST)) { |
| 1082 | sc = fnic->sgreset_sc; | ||
| 1083 | io_lock = &fnic->sgreset_lock; | ||
| 1084 | } else { | ||
| 1085 | sc = scsi_host_find_tag(fnic->lport->host, id & FNIC_TAG_MASK); | ||
| 1086 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
| 1087 | } | ||
| 1088 | |||
| 1073 | WARN_ON_ONCE(!sc); | 1089 | WARN_ON_ONCE(!sc); |
| 1074 | if (!sc) { | 1090 | if (!sc) { |
| 1075 | atomic64_inc(&fnic_stats->io_stats.sc_null); | 1091 | atomic64_inc(&fnic_stats->io_stats.sc_null); |
| 1076 | shost_printk(KERN_ERR, fnic->lport->host, | 1092 | shost_printk(KERN_ERR, fnic->lport->host, |
| 1077 | "itmf_cmpl sc is null - hdr status = %s tag = 0x%x\n", | 1093 | "itmf_cmpl sc is null - hdr status = %s tag = 0x%x\n", |
| 1078 | fnic_fcpio_status_to_str(hdr_status), id); | 1094 | fnic_fcpio_status_to_str(hdr_status), tag); |
| 1079 | return; | 1095 | return; |
| 1080 | } | 1096 | } |
| 1081 | io_lock = fnic_io_lock_hash(fnic, sc); | 1097 | |
| 1082 | spin_lock_irqsave(io_lock, flags); | 1098 | spin_lock_irqsave(io_lock, flags); |
| 1083 | io_req = fnic_priv(sc)->io_req; | 1099 | io_req = fnic_priv(sc)->io_req; |
| 1084 | WARN_ON_ONCE(!io_req); | 1100 | WARN_ON_ONCE(!io_req); |
| @@ -1089,7 +1105,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, · 4 unmodified lines | |||
| 1089 | shost_printk(KERN_ERR, fnic->lport->host, | 1105 | shost_printk(KERN_ERR, fnic->lport->host, |
| 1090 | "itmf_cmpl io_req is null - " | 1106 | "itmf_cmpl io_req is null - " |
| 1091 | "hdr status = %s tag = 0x%x sc 0x%p\n", | 1107 | "hdr status = %s tag = 0x%x sc 0x%p\n", |
| 1092 | fnic_fcpio_status_to_str(hdr_status), id, sc); | 1108 | fnic_fcpio_status_to_str(hdr_status), tag, sc); |
| 1093 | return; | 1109 | return; |
| 1094 | } | 1110 | } |
| 1095 | start_time = io_req->start_time; | 1111 | start_time = io_req->start_time; |
| @@ -1938,6 +1954,10 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic, · 842 unmodified lines | |||
| 1938 | struct scsi_lun fc_lun; | 1954 | struct scsi_lun fc_lun; |
| 1939 | int ret = 0; | 1955 | int ret = 0; |
| 1940 | unsigned long intr_flags; | 1956 | unsigned long intr_flags; |
| 1957 | unsigned int tag = scsi_cmd_to_rq(sc)->tag; | ||
| 1958 | |||
| 1959 | if (tag == SCSI_NO_TAG) | ||
| 1960 | tag = io_req->tag; | ||
| 1941 | 1961 | ||
| 1942 | spin_lock_irqsave(host->host_lock, intr_flags); | 1962 | spin_lock_irqsave(host->host_lock, intr_flags); |
| 1943 | if (unlikely(fnic_chk_state_flags_locked(fnic, | 1963 | if (unlikely(fnic_chk_state_flags_locked(fnic, |
| @@ -1964,7 +1984,8 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic, · 20 unmodified lines | |||
| 1964 | /* fill in the lun info */ | 1984 | /* fill in the lun info */ |
| 1965 | int_to_scsilun(sc->device->lun, &fc_lun); | 1985 | int_to_scsilun(sc->device->lun, &fc_lun); |
| 1966 | 1986 | ||
| 1967 | fnic_queue_wq_copy_desc_itmf(wq, scsi_cmd_to_rq(sc)->tag | FNIC_TAG_DEV_RST, | 1987 | tag |= FNIC_TAG_DEV_RST; |
| 1988 | fnic_queue_wq_copy_desc_itmf(wq, tag, | ||
| 1968 | 0, FCPIO_ITMF_LUN_RESET, SCSI_NO_TAG, | 1989 | 0, FCPIO_ITMF_LUN_RESET, SCSI_NO_TAG, |
| 1969 | fc_lun.scsi_lun, io_req->port_id, | 1990 | fc_lun.scsi_lun, io_req->port_id, |
| 1970 | fnic->config.ra_tov, fnic->config.ed_tov); | 1991 | fnic->config.ra_tov, fnic->config.ed_tov); |
| @@ -2146,8 +2167,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, · 175 unmodified lines | |||
| 2146 | .ret = SUCCESS, | 2167 | .ret = SUCCESS, |
| 2147 | }; | 2168 | }; |
| 2148 | 2169 | ||
| 2149 | if (new_sc) | 2170 | iter_data.lr_sc = lr_sc; |
| 2150 | iter_data.lr_sc = lr_sc; | ||
| 2151 | 2171 | ||
| 2152 | scsi_host_busy_iter(fnic->lport->host, | 2172 | scsi_host_busy_iter(fnic->lport->host, |
| 2153 | fnic_pending_aborts_iter, &iter_data); | 2173 | fnic_pending_aborts_iter, &iter_data); |
| @@ -2230,8 +2250,14 @@ int fnic_device_reset(struct scsi_cmnd *sc) · 76 unmodified lines | |||
| 2230 | mutex_lock(&fnic->sgreset_mutex); | 2250 | mutex_lock(&fnic->sgreset_mutex); |
| 2231 | tag = fnic->fnic_max_tag_id; | 2251 | tag = fnic->fnic_max_tag_id; |
| 2232 | new_sc = 1; | 2252 | new_sc = 1; |
| 2233 | } | 2253 | fnic->sgreset_sc = sc; |
| 2234 | io_lock = fnic_io_lock_hash(fnic, sc); | 2254 | io_lock = &fnic->sgreset_lock; |
| 2255 | FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, | ||
| 2256 | "fcid: 0x%x lun: 0x%llx flags: 0x%x tag: 0x%x Issuing sgreset\n", | ||
| 2257 | rport->port_id, sc->device->lun, fnic_priv(sc)->flags, tag); | ||
| 2258 | } else | ||
| 2259 | io_lock = fnic_io_lock_hash(fnic, sc); | ||
| 2260 | |||
| 2235 | spin_lock_irqsave(io_lock, flags); | 2261 | spin_lock_irqsave(io_lock, flags); |
| 2236 | io_req = fnic_priv(sc)->io_req; | 2262 | io_req = fnic_priv(sc)->io_req; |
| 2237 | 2263 | ||
| @@ -2247,6 +2273,8 @@ int fnic_device_reset(struct scsi_cmnd *sc) · 9 unmodified lines | |||
| 2247 | } | 2273 | } |
| 2248 | memset(io_req, 0, sizeof(*io_req)); | 2274 | memset(io_req, 0, sizeof(*io_req)); |
| 2249 | io_req->port_id = rport->port_id; | 2275 | io_req->port_id = rport->port_id; |
| 2276 | io_req->tag = tag; | ||
| 2277 | io_req->sc = sc; | ||
| 2250 | fnic_priv(sc)->io_req = io_req; | 2278 | fnic_priv(sc)->io_req = io_req; |
| 2251 | } | 2279 | } |
| 2252 | io_req->dr_done = &tm_done; | 2280 | io_req->dr_done = &tm_done; |
| @@ -2400,8 +2428,10 @@ fnic_device_reset_end: · 147 unmodified lines | |||
| 2400 | (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), | 2428 | (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), |
| 2401 | fnic_flags_and_state(sc)); | 2429 | fnic_flags_and_state(sc)); |
| 2402 | 2430 | ||
| 2403 | if (new_sc) | 2431 | if (new_sc) { |
| 2432 | fnic->sgreset_sc = NULL; | ||
| 2404 | mutex_unlock(&fnic->sgreset_mutex); | 2433 | mutex_unlock(&fnic->sgreset_mutex); |
| 2434 | } | ||
| 2405 | 2435 | ||
| 2406 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | 2436 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, |
| 2407 | "Returning from device reset %s\n", | 2437 | "Returning from device reset %s\n", |
| @@ -613,6 +613,17 @@ void scsi_cdl_check(struct scsi_device *sdev) · 612 unmodified lines | |||
| 613 | bool cdl_supported; | 613 | bool cdl_supported; |
| 614 | unsigned char *buf; | 614 | unsigned char *buf; |
| 615 | 615 | ||
| 616 | /* | ||
| 617 | * Support for CDL was defined in SPC-5. Ignore devices reporting an | ||
| 618 | * lower SPC version. This also avoids problems with old drives choking | ||
| 619 | * on MAINTENANCE_IN / MI_REPORT_SUPPORTED_OPERATION_CODES with a | ||
| 620 | * service action specified, as done in scsi_cdl_check_cmd(). | ||
| 621 | */ | ||
| 622 | if (sdev->scsi_level < SCSI_SPC_5) { | ||
| 623 | sdev->cdl_supported = 0; | ||
| 624 | return; | ||
| 625 | } | ||
| 626 | |||
| 616 | buf = kmalloc(SCSI_CDL_CHECK_BUF_LEN, GFP_KERNEL); | 627 | buf = kmalloc(SCSI_CDL_CHECK_BUF_LEN, GFP_KERNEL); |
| 617 | if (!buf) { | 628 | if (!buf) { |
| 618 | sdev->cdl_supported = 0; | 629 | sdev->cdl_supported = 0; |
| @@ -822,7 +822,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, · 821 unmodified lines | |||
| 822 | * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so | 822 | * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so |
| 823 | * non-zero LUNs can be scanned. | 823 | * non-zero LUNs can be scanned. |
| 824 | */ | 824 | */ |
| 825 | sdev->scsi_level = inq_result[2] & 0x07; | 825 | sdev->scsi_level = inq_result[2] & 0x0f; |
| 826 | if (sdev->scsi_level >= 2 || | 826 | if (sdev->scsi_level >= 2 || |
| 827 | (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1)) | 827 | (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1)) |
| 828 | sdev->scsi_level++; | 828 | sdev->scsi_level++; |
| @@ -1619,12 +1619,24 @@ int scsi_add_device(struct Scsi_Host *host, uint channel, · 790 unmodified lines | |||
| 1619 | } | 1619 | } |
| 1620 | EXPORT_SYMBOL(scsi_add_device); | 1620 | EXPORT_SYMBOL(scsi_add_device); |
| 1621 | 1621 | ||
| 1622 | void scsi_rescan_device(struct scsi_device *sdev) | 1622 | int scsi_rescan_device(struct scsi_device *sdev) |
| 1623 | { | 1623 | { |
| 1624 | struct device *dev = &sdev->sdev_gendev; | 1624 | struct device *dev = &sdev->sdev_gendev; |
| 1625 | int ret = 0; | ||
| 1625 | 1626 | ||
| 1626 | device_lock(dev); | 1627 | device_lock(dev); |
| 1627 | 1628 | ||
| 1629 | /* | ||
| 1630 | * Bail out if the device is not running. Otherwise, the rescan may | ||
| 1631 | * block waiting for commands to be executed, with us holding the | ||
| 1632 | * device lock. This can result in a potential deadlock in the power | ||
| 1633 | * management core code when system resume is on-going. | ||
| 1634 | */ | ||
| 1635 | if (sdev->sdev_state != SDEV_RUNNING) { | ||
| 1636 | ret = -EWOULDBLOCK; | ||
| 1637 | goto unlock; | ||
| 1638 | } | ||
| 1639 | |||
| 1628 | scsi_attach_vpd(sdev); | 1640 | scsi_attach_vpd(sdev); |
| 1629 | scsi_cdl_check(sdev); | 1641 | scsi_cdl_check(sdev); |
| 1630 | 1642 | ||
| @@ -1638,7 +1650,11 @@ void scsi_rescan_device(struct scsi_device *sdev) · 7 unmodified lines | |||
| 1638 | drv->rescan(dev); | 1650 | drv->rescan(dev); |
| 1639 | module_put(dev->driver->owner); | 1651 | module_put(dev->driver->owner); |
| 1640 | } | 1652 | } |
| 1653 | |||
| 1654 | unlock: | ||
| 1641 | device_unlock(dev); | 1655 | device_unlock(dev); |
| 1656 | |||
| 1657 | return ret; | ||
| 1642 | } | 1658 | } |
| 1643 | EXPORT_SYMBOL(scsi_rescan_device); | 1659 | EXPORT_SYMBOL(scsi_rescan_device); |
| 1644 | 1660 | ||
| @@ -201,18 +201,32 @@ cache_type_store(struct device *dev, struct device_attribute *attr, · 200 unmodified lines | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static ssize_t | 203 | static ssize_t |
| 204 | manage_start_stop_show(struct device *dev, struct device_attribute *attr, | 204 | manage_start_stop_show(struct device *dev, |
| 205 | char *buf) | 205 | struct device_attribute *attr, char *buf) |
| 206 | { | 206 | { |
| 207 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 207 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
| 208 | struct scsi_device *sdp = sdkp->device; | 208 | struct scsi_device *sdp = sdkp->device; |
| 209 | 209 | ||
| 210 | return sprintf(buf, "%u\n", sdp->manage_start_stop); | 210 | return sysfs_emit(buf, "%u\n", |
| 211 | sdp->manage_system_start_stop && | ||
| 212 | sdp->manage_runtime_start_stop); | ||
| 211 | } | 213 | } |
| 214 | static DEVICE_ATTR_RO(manage_start_stop); | ||
| 212 | 215 | ||
| 213 | static ssize_t | 216 | static ssize_t |
| 214 | manage_start_stop_store(struct device *dev, struct device_attribute *attr, | 217 | manage_system_start_stop_show(struct device *dev, |
| 215 | const char *buf, size_t count) | 218 | struct device_attribute *attr, char *buf) |
| 219 | { | ||
| 220 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 221 | struct scsi_device *sdp = sdkp->device; | ||
| 222 | |||
| 223 | return sysfs_emit(buf, "%u\n", sdp->manage_system_start_stop); | ||
| 224 | } | ||
| 225 | |||
| 226 | static ssize_t | ||
| 227 | manage_system_start_stop_store(struct device *dev, | ||
| 228 | struct device_attribute *attr, | ||
| 229 | const char *buf, size_t count) | ||
| 216 | { | 230 | { |
| 217 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 231 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
| 218 | struct scsi_device *sdp = sdkp->device; | 232 | struct scsi_device *sdp = sdkp->device; |
| @@ -224,11 +238,42 @@ manage_start_stop_store(struct device *dev, struct device_attribute *attr, · 5 unmodified lines | |||
| 224 | if (kstrtobool(buf, &v)) | 238 | if (kstrtobool(buf, &v)) |
| 225 | return -EINVAL; | 239 | return -EINVAL; |
| 226 | 240 | ||
| 227 | sdp->manage_start_stop = v; | 241 | sdp->manage_system_start_stop = v; |
| 228 | 242 | ||
| 229 | return count; | 243 | return count; |
| 230 | } | 244 | } |
| 231 | static DEVICE_ATTR_RW(manage_start_stop); | 245 | static DEVICE_ATTR_RW(manage_system_start_stop); |
| 246 | |||
| 247 | static ssize_t | ||
| 248 | manage_runtime_start_stop_show(struct device *dev, | ||
| 249 | struct device_attribute *attr, char *buf) | ||
| 250 | { | ||
| 251 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 252 | struct scsi_device *sdp = sdkp->device; | ||
| 253 | |||
| 254 | return sysfs_emit(buf, "%u\n", sdp->manage_runtime_start_stop); | ||
| 255 | } | ||
| 256 | |||
| 257 | static ssize_t | ||
| 258 | manage_runtime_start_stop_store(struct device *dev, | ||
| 259 | struct device_attribute *attr, | ||
| 260 | const char *buf, size_t count) | ||
| 261 | { | ||
| 262 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 263 | struct scsi_device *sdp = sdkp->device; | ||
| 264 | bool v; | ||
| 265 | |||
| 266 | if (!capable(CAP_SYS_ADMIN)) | ||
| 267 | return -EACCES; | ||
| 268 | |||
| 269 | if (kstrtobool(buf, &v)) | ||
| 270 | return -EINVAL; | ||
| 271 | |||
| 272 | sdp->manage_runtime_start_stop = v; | ||
| 273 | |||
| 274 | return count; | ||
| 275 | } | ||
| 276 | static DEVICE_ATTR_RW(manage_runtime_start_stop); | ||
| 232 | 277 | ||
| 233 | static ssize_t | 278 | static ssize_t |
| 234 | allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) | 279 | allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) |
| @@ -560,6 +605,8 @@ static struct attribute *sd_disk_attrs[] = { · 325 unmodified lines | |||
| 560 | &dev_attr_FUA.attr, | 605 | &dev_attr_FUA.attr, |
| 561 | &dev_attr_allow_restart.attr, | 606 | &dev_attr_allow_restart.attr, |
| 562 | &dev_attr_manage_start_stop.attr, | 607 | &dev_attr_manage_start_stop.attr, |
| 608 | &dev_attr_manage_system_start_stop.attr, | ||
| 609 | &dev_attr_manage_runtime_start_stop.attr, | ||
| 563 | &dev_attr_protection_type.attr, | 610 | &dev_attr_protection_type.attr, |
| 564 | &dev_attr_protection_mode.attr, | 611 | &dev_attr_protection_mode.attr, |
| 565 | &dev_attr_app_tag_own.attr, | 612 | &dev_attr_app_tag_own.attr, |
| @@ -3694,7 +3741,8 @@ static int sd_remove(struct device *dev) · 3128 unmodified lines | |||
| 3694 | 3741 | ||
| 3695 | device_del(&sdkp->disk_dev); | 3742 | device_del(&sdkp->disk_dev); |
| 3696 | del_gendisk(sdkp->disk); | 3743 | del_gendisk(sdkp->disk); |
| 3697 | sd_shutdown(dev); | 3744 | if (!sdkp->suspended) |
| 3745 | sd_shutdown(dev); | ||
| 3698 | 3746 | ||
| 3699 | put_disk(sdkp->disk); | 3747 | put_disk(sdkp->disk); |
| 3700 | return 0; | 3748 | return 0; |
| @@ -3771,13 +3819,20 @@ static void sd_shutdown(struct device *dev) · 70 unmodified lines | |||
| 3771 | sd_sync_cache(sdkp, NULL); | 3819 | sd_sync_cache(sdkp, NULL); |
| 3772 | } | 3820 | } |
| 3773 | 3821 | ||
| 3774 | if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { | 3822 | if (system_state != SYSTEM_RESTART && |
| 3823 | sdkp->device->manage_system_start_stop) { | ||
| 3775 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); | 3824 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); |
| 3776 | sd_start_stop_device(sdkp, 0); | 3825 | sd_start_stop_device(sdkp, 0); |
| 3777 | } | 3826 | } |
| 3778 | } | 3827 | } |
| 3779 | 3828 | ||
| 3780 | static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) | 3829 | static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime) |
| 3830 | { | ||
| 3831 | return (sdev->manage_system_start_stop && !runtime) || | ||
| 3832 | (sdev->manage_runtime_start_stop && runtime); | ||
| 3833 | } | ||
| 3834 | |||
| 3835 | static int sd_suspend_common(struct device *dev, bool runtime) | ||
| 3781 | { | 3836 | { |
| 3782 | struct scsi_disk *sdkp = dev_get_drvdata(dev); | 3837 | struct scsi_disk *sdkp = dev_get_drvdata(dev); |
| 3783 | struct scsi_sense_hdr sshdr; | 3838 | struct scsi_sense_hdr sshdr; |
| @@ -3809,15 +3864,18 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) · 25 unmodified lines | |||
| 3809 | } | 3864 | } |
| 3810 | } | 3865 | } |
| 3811 | 3866 | ||
| 3812 | if (sdkp->device->manage_start_stop) { | 3867 | if (sd_do_start_stop(sdkp->device, runtime)) { |
| 3813 | if (!sdkp->device->silence_suspend) | 3868 | if (!sdkp->device->silence_suspend) |
| 3814 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); | 3869 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); |
| 3815 | /* an error is not worth aborting a system sleep */ | 3870 | /* an error is not worth aborting a system sleep */ |
| 3816 | ret = sd_start_stop_device(sdkp, 0); | 3871 | ret = sd_start_stop_device(sdkp, 0); |
| 3817 | if (ignore_stop_errors) | 3872 | if (!runtime) |
| 3818 | ret = 0; | 3873 | ret = 0; |
| 3819 | } | 3874 | } |
| 3820 | 3875 | ||
| 3876 | if (!ret) | ||
| 3877 | sdkp->suspended = true; | ||
| 3878 | |||
| 3821 | return ret; | 3879 | return ret; |
| 3822 | } | 3880 | } |
| 3823 | 3881 | ||
| @@ -3826,15 +3884,15 @@ static int sd_suspend_system(struct device *dev) · 2 unmodified lines | |||
| 3826 | if (pm_runtime_suspended(dev)) | 3884 | if (pm_runtime_suspended(dev)) |
| 3827 | return 0; | 3885 | return 0; |
| 3828 | 3886 | ||
| 3829 | return sd_suspend_common(dev, true); | 3887 | return sd_suspend_common(dev, false); |
| 3830 | } | 3888 | } |
| 3831 | 3889 | ||
| 3832 | static int sd_suspend_runtime(struct device *dev) | 3890 | static int sd_suspend_runtime(struct device *dev) |
| 3833 | { | 3891 | { |
| 3834 | return sd_suspend_common(dev, false); | 3892 | return sd_suspend_common(dev, true); |
| 3835 | } | 3893 | } |
| 3836 | 3894 | ||
| 3837 | static int sd_resume(struct device *dev) | 3895 | static int sd_resume(struct device *dev, bool runtime) |
| 3838 | { | 3896 | { |
| 3839 | struct scsi_disk *sdkp = dev_get_drvdata(dev); | 3897 | struct scsi_disk *sdkp = dev_get_drvdata(dev); |
| 3840 | int ret = 0; | 3898 | int ret = 0; |
| @@ -3842,16 +3900,21 @@ static int sd_resume(struct device *dev) · 1 unmodified line | |||
| 3842 | if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ | 3900 | if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ |
| 3843 | return 0; | 3901 | return 0; |
| 3844 | 3902 | ||
| 3845 | if (!sdkp->device->manage_start_stop) | 3903 | if (!sd_do_start_stop(sdkp->device, runtime)) { |
| 3904 | sdkp->suspended = false; | ||
| 3846 | return 0; | 3905 | return 0; |
| 3906 | } | ||
| 3847 | 3907 | ||
| 3848 | if (!sdkp->device->no_start_on_resume) { | 3908 | if (!sdkp->device->no_start_on_resume) { |
| 3849 | sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); | 3909 | sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); |
| 3850 | ret = sd_start_stop_device(sdkp, 1); | 3910 | ret = sd_start_stop_device(sdkp, 1); |
| 3851 | } | 3911 | } |
| 3852 | 3912 | ||
| 3853 | if (!ret) | 3913 | if (!ret) { |
| 3854 | opal_unlock_from_suspend(sdkp->opal_dev); | 3914 | opal_unlock_from_suspend(sdkp->opal_dev); |
| 3915 | sdkp->suspended = false; | ||
| 3916 | } | ||
| 3917 | |||
| 3855 | return ret; | 3918 | return ret; |
| 3856 | } | 3919 | } |
| 3857 | 3920 | ||
| @@ -3860,7 +3923,7 @@ static int sd_resume_system(struct device *dev) · 2 unmodified lines | |||
| 3860 | if (pm_runtime_suspended(dev)) | 3923 | if (pm_runtime_suspended(dev)) |
| 3861 | return 0; | 3924 | return 0; |
| 3862 | 3925 | ||
| 3863 | return sd_resume(dev); | 3926 | return sd_resume(dev, false); |
| 3864 | } | 3927 | } |
| 3865 | 3928 | ||
| 3866 | static int sd_resume_runtime(struct device *dev) | 3929 | static int sd_resume_runtime(struct device *dev) |
| @@ -3887,7 +3950,7 @@ static int sd_resume_runtime(struct device *dev) · 20 unmodified lines | |||
| 3887 | "Failed to clear sense data\n"); | 3950 | "Failed to clear sense data\n"); |
| 3888 | } | 3951 | } |
| 3889 | 3952 | ||
| 3890 | return sd_resume(dev); | 3953 | return sd_resume(dev, true); |
| 3891 | } | 3954 | } |
| 3892 | 3955 | ||
| 3893 | static const struct dev_pm_ops sd_pm_ops = { | 3956 | static const struct dev_pm_ops sd_pm_ops = { |
| @@ -131,6 +131,7 @@ struct scsi_disk { · 130 unmodified lines | |||
| 131 | u8 provisioning_mode; | 131 | u8 provisioning_mode; |
| 132 | u8 zeroing_mode; | 132 | u8 zeroing_mode; |
| 133 | u8 nr_actuators; /* Number of actuators */ | 133 | u8 nr_actuators; /* Number of actuators */ |
| 134 | bool suspended; /* Disk is suspended (stopped) */ | ||
| 134 | unsigned ATO : 1; /* state of disk ATO bit */ | 135 | unsigned ATO : 1; /* state of disk ATO bit */ |
| 135 | unsigned cache_override : 1; /* temp override of WCE,RCD */ | 136 | unsigned cache_override : 1; /* temp override of WCE,RCD */ |
| 136 | unsigned WCE : 1; /* state of disk WCE bit */ | 137 | unsigned WCE : 1; /* state of disk WCE bit */ |
| @@ -100,6 +100,7 @@ static void __init imx8mm_soc_uid(void) · 99 unmodified lines | |||
| 100 | { | 100 | { |
| 101 | void __iomem *ocotp_base; | 101 | void __iomem *ocotp_base; |
| 102 | struct device_node *np; | 102 | struct device_node *np; |
| 103 | struct clk *clk; | ||
| 103 | u32 offset = of_machine_is_compatible("fsl,imx8mp") ? | 104 | u32 offset = of_machine_is_compatible("fsl,imx8mp") ? |
| 104 | IMX8MP_OCOTP_UID_OFFSET : 0; | 105 | IMX8MP_OCOTP_UID_OFFSET : 0; |
| 105 | 106 | ||
| @@ -109,11 +110,20 @@ static void __init imx8mm_soc_uid(void) · 3 unmodified lines | |||
| 109 | 110 | ||
| 110 | ocotp_base = of_iomap(np, 0); | 111 | ocotp_base = of_iomap(np, 0); |
| 111 | WARN_ON(!ocotp_base); | 112 | WARN_ON(!ocotp_base); |
| 113 | clk = of_clk_get_by_name(np, NULL); | ||
| 114 | if (IS_ERR(clk)) { | ||
| 115 | WARN_ON(IS_ERR(clk)); | ||
| 116 | return; | ||
| 117 | } | ||
| 118 | |||
| 119 | clk_prepare_enable(clk); | ||
| 112 | 120 | ||
| 113 | soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); | 121 | soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); |
| 114 | soc_uid <<= 32; | 122 | soc_uid <<= 32; |
| 115 | soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); | 123 | soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); |
| 116 | 124 | ||
| 125 | clk_disable_unprepare(clk); | ||
| 126 | clk_put(clk); | ||
| 117 | iounmap(ocotp_base); | 127 | iounmap(ocotp_base); |
| 118 | of_node_put(np); | 128 | of_node_put(np); |
| 119 | } | 129 | } |
| @@ -20,6 +20,7 @@ config LOONGSON2_GUTS · 19 unmodified lines | |||
| 20 | config LOONGSON2_PM | 20 | config LOONGSON2_PM |
| 21 | bool "Loongson-2 SoC Power Management Controller Driver" | 21 | bool "Loongson-2 SoC Power Management Controller Driver" |
| 22 | depends on LOONGARCH && OF | 22 | depends on LOONGARCH && OF |
| 23 | depends on INPUT=y | ||
| 23 | help | 24 | help |
| 24 | The Loongson-2's power management controller was ACPI, supports ACPI | 25 | The Loongson-2's power management controller was ACPI, supports ACPI |
| 25 | S2Idle (Suspend To Idle), ACPI S3 (Suspend To RAM), ACPI S4 (Suspend To | 26 | S2Idle (Suspend To Idle), ACPI S3 (Suspend To RAM), ACPI S4 (Suspend To |
| @@ -70,7 +70,7 @@ static const struct loongson2_soc_die_attr *loongson2_soc_die_match( · 69 unmodified lines | |||
| 70 | if (matches->svr == (svr & matches->mask)) | 70 | if (matches->svr == (svr & matches->mask)) |
| 71 | return matches; | 71 | return matches; |
| 72 | matches++; | 72 | matches++; |
| 73 | }; | 73 | } |
| 74 | 74 | ||
| 75 | return NULL; | 75 | return NULL; |
| 76 | } | 76 | } |
| @@ -94,7 +94,6 @@ static int loongson2_guts_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 94 | { | 94 | { |
| 95 | struct device_node *root, *np = pdev->dev.of_node; | 95 | struct device_node *root, *np = pdev->dev.of_node; |
| 96 | struct device *dev = &pdev->dev; | 96 | struct device *dev = &pdev->dev; |
| 97 | struct resource *res; | ||
| 98 | const struct loongson2_soc_die_attr *soc_die; | 97 | const struct loongson2_soc_die_attr *soc_die; |
| 99 | const char *machine; | 98 | const char *machine; |
| 100 | u32 svr; | 99 | u32 svr; |
| @@ -106,8 +105,7 @@ static int loongson2_guts_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 106 | 105 | ||
| 107 | guts->little_endian = of_property_read_bool(np, "little-endian"); | 106 | guts->little_endian = of_property_read_bool(np, "little-endian"); |
| 108 | 107 | ||
| 109 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 108 | guts->regs = devm_platform_ioremap_resource(pdev, 0); |
| 110 | guts->regs = ioremap(res->start, res->end - res->start + 1); | ||
| 111 | if (IS_ERR(guts->regs)) | 109 | if (IS_ERR(guts->regs)) |
| 112 | return PTR_ERR(guts->regs); | 110 | return PTR_ERR(guts->regs); |
| 113 | 111 | ||
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/input.h> | 11 | #include <linux/input.h> |
| 12 | #include <linux/suspend.h> | 12 | #include <linux/suspend.h> |
| 13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
| 14 | #include <linux/of_platform.h> | ||
| 14 | #include <linux/pm_wakeirq.h> | 15 | #include <linux/pm_wakeirq.h> |
| 15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 16 | #include <asm/bootinfo.h> | 17 | #include <asm/bootinfo.h> |
| @@ -192,12 +193,16 @@ static int loongson2_pm_probe(struct platform_device *pdev) · 175 unmodified lines | |||
| 192 | if (loongson_sysconf.suspend_addr) | 193 | if (loongson_sysconf.suspend_addr) |
| 193 | suspend_set_ops(&loongson2_suspend_ops); | 194 | suspend_set_ops(&loongson2_suspend_ops); |
| 194 | 195 | ||
| 196 | /* Populate children */ | ||
| 197 | retval = devm_of_platform_populate(dev); | ||
| 198 | if (retval) | ||
| 199 | dev_err(dev, "Error populating children, reboot and poweroff might not work properly\n"); | ||
| 200 | |||
| 195 | return 0; | 201 | return 0; |
| 196 | } | 202 | } |
| 197 | 203 | ||
| 198 | static const struct of_device_id loongson2_pm_match[] = { | 204 | static const struct of_device_id loongson2_pm_match[] = { |
| 199 | { .compatible = "loongson,ls2k0500-pmc", }, | 205 | { .compatible = "loongson,ls2k0500-pmc", }, |
| 200 | { .compatible = "loongson,ls2k1000-pmc", }, | ||
| 201 | {}, | 206 | {}, |
| 202 | }; | 207 | }; |
| 203 | 208 | ||
| @@ -256,7 +256,6 @@ static int cs42l43_spi_probe(struct platform_device *pdev) · 255 unmodified lines | |||
| 256 | 256 | ||
| 257 | ret = devm_spi_register_controller(priv->dev, priv->ctlr); | 257 | ret = devm_spi_register_controller(priv->dev, priv->ctlr); |
| 258 | if (ret) { | 258 | if (ret) { |
| 259 | pm_runtime_disable(priv->dev); | ||
| 260 | dev_err(priv->dev, "Failed to register SPI controller: %d\n", ret); | 259 | dev_err(priv->dev, "Failed to register SPI controller: %d\n", ret); |
| 261 | } | 260 | } |
| 262 | 261 | ||
| @@ -194,7 +194,7 @@ static ssize_t gxp_spi_write(struct gxp_spi_chip *chip, const struct spi_mem_op · 193 unmodified lines | |||
| 194 | return ret; | 194 | return ret; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | return write_len; | 197 | return 0; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) | 200 | static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) |
| @@ -843,7 +843,6 @@ sector_t target_to_linux_sector(struct se_device *dev, sector_t lb) · 842 unmodified lines | |||
| 843 | EXPORT_SYMBOL(target_to_linux_sector); | 843 | EXPORT_SYMBOL(target_to_linux_sector); |
| 844 | 844 | ||
| 845 | struct devices_idr_iter { | 845 | struct devices_idr_iter { |
| 846 | struct config_item *prev_item; | ||
| 847 | int (*fn)(struct se_device *dev, void *data); | 846 | int (*fn)(struct se_device *dev, void *data); |
| 848 | void *data; | 847 | void *data; |
| 849 | }; | 848 | }; |
| @@ -853,11 +852,9 @@ static int target_devices_idr_iter(int id, void *p, void *data) · 3 unmodified lines | |||
| 853 | { | 852 | { |
| 854 | struct devices_idr_iter *iter = data; | 853 | struct devices_idr_iter *iter = data; |
| 855 | struct se_device *dev = p; | 854 | struct se_device *dev = p; |
| 855 | struct config_item *item; | ||
| 856 | int ret; | 856 | int ret; |
| 857 | 857 | ||
| 858 | config_item_put(iter->prev_item); | ||
| 859 | iter->prev_item = NULL; | ||
| 860 | |||
| 861 | /* | 858 | /* |
| 862 | * We add the device early to the idr, so it can be used | 859 | * We add the device early to the idr, so it can be used |
| 863 | * by backend modules during configuration. We do not want | 860 | * by backend modules during configuration. We do not want |
| @@ -867,12 +864,13 @@ static int target_devices_idr_iter(int id, void *p, void *data) · 3 unmodified lines | |||
| 867 | if (!target_dev_configured(dev)) | 864 | if (!target_dev_configured(dev)) |
| 868 | return 0; | 865 | return 0; |
| 869 | 866 | ||
| 870 | iter->prev_item = config_item_get_unless_zero(&dev->dev_group.cg_item); | 867 | item = config_item_get_unless_zero(&dev->dev_group.cg_item); |
| 871 | if (!iter->prev_item) | 868 | if (!item) |
| 872 | return 0; | 869 | return 0; |
| 873 | mutex_unlock(&device_mutex); | 870 | mutex_unlock(&device_mutex); |
| 874 | 871 | ||
| 875 | ret = iter->fn(dev, iter->data); | 872 | ret = iter->fn(dev, iter->data); |
| 873 | config_item_put(item); | ||
| 876 | 874 | ||
| 877 | mutex_lock(&device_mutex); | 875 | mutex_lock(&device_mutex); |
| 878 | return ret; | 876 | return ret; |
| @@ -895,7 +893,6 @@ int target_for_each_device(int (*fn)(struct se_device *dev, void *data), · 16 unmodified lines | |||
| 895 | mutex_lock(&device_mutex); | 893 | mutex_lock(&device_mutex); |
| 896 | ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter); | 894 | ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter); |
| 897 | mutex_unlock(&device_mutex); | 895 | mutex_unlock(&device_mutex); |
| 898 | config_item_put(iter.prev_item); | ||
| 899 | return ret; | 896 | return ret; |
| 900 | } | 897 | } |
| 901 | 898 | ||
| @@ -238,8 +238,6 @@ int optee_notif_send(struct optee *optee, u_int key); · 237 unmodified lines | |||
| 238 | u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, | 238 | u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, |
| 239 | struct tee_param *param); | 239 | struct tee_param *param); |
| 240 | 240 | ||
| 241 | int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len); | ||
| 242 | int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len); | ||
| 243 | void optee_supp_init(struct optee_supp *supp); | 241 | void optee_supp_init(struct optee_supp *supp); |
| 244 | void optee_supp_uninit(struct optee_supp *supp); | 242 | void optee_supp_uninit(struct optee_supp *supp); |
| 245 | void optee_supp_release(struct optee_supp *supp); | 243 | void optee_supp_release(struct optee_supp *supp); |
| @@ -47,8 +47,6 @@ struct tee_device { · 46 unmodified lines | |||
| 47 | struct tee_shm_pool *pool; | 47 | struct tee_shm_pool *pool; |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | int tee_shm_init(void); | ||
| 51 | |||
| 52 | int tee_shm_get_fd(struct tee_shm *shm); | 50 | int tee_shm_get_fd(struct tee_shm *shm); |
| 53 | 51 | ||
| 54 | bool tee_device_get(struct tee_device *teedev); | 52 | bool tee_device_get(struct tee_device *teedev); |
| @@ -185,9 +185,6 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, · 184 unmodified lines | |||
| 185 | if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) | 185 | if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) |
| 186 | return -EINVAL; | 186 | return -EINVAL; |
| 187 | 187 | ||
| 188 | if (kstrtoint(buf, 10, &trip.hysteresis)) | ||
| 189 | return -EINVAL; | ||
| 190 | |||
| 191 | mutex_lock(&tz->lock); | 188 | mutex_lock(&tz->lock); |
| 192 | 189 | ||
| 193 | if (!device_is_registered(dev)) { | 190 | if (!device_is_registered(dev)) { |
| @@ -198,7 +195,11 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, · 4 unmodified lines | |||
| 198 | ret = __thermal_zone_get_trip(tz, trip_id, &trip); | 195 | ret = __thermal_zone_get_trip(tz, trip_id, &trip); |
| 199 | if (ret) | 196 | if (ret) |
| 200 | goto unlock; | 197 | goto unlock; |
| 201 | 198 | ||
| 199 | ret = kstrtoint(buf, 10, &trip.hysteresis); | ||
| 200 | if (ret) | ||
| 201 | goto unlock; | ||
| 202 | |||
| 202 | ret = thermal_zone_set_trip(tz, trip_id, &trip); | 203 | ret = thermal_zone_set_trip(tz, trip_id, &trip); |
| 203 | unlock: | 204 | unlock: |
| 204 | mutex_unlock(&tz->lock); | 205 | mutex_unlock(&tz->lock); |
| @@ -3097,10 +3097,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) · 3096 unmodified lines | |||
| 3097 | gsm->has_devices = false; | 3097 | gsm->has_devices = false; |
| 3098 | } | 3098 | } |
| 3099 | for (i = NUM_DLCI - 1; i >= 0; i--) | 3099 | for (i = NUM_DLCI - 1; i >= 0; i--) |
| 3100 | if (gsm->dlci[i]) { | 3100 | if (gsm->dlci[i]) |
| 3101 | gsm_dlci_release(gsm->dlci[i]); | 3101 | gsm_dlci_release(gsm->dlci[i]); |
| 3102 | gsm->dlci[i] = NULL; | ||
| 3103 | } | ||
| 3104 | mutex_unlock(&gsm->mutex); | 3102 | mutex_unlock(&gsm->mutex); |
| 3105 | /* Now wipe the queues */ | 3103 | /* Now wipe the queues */ |
| 3106 | tty_ldisc_flush(gsm->tty); | 3104 | tty_ldisc_flush(gsm->tty); |
| @@ -1936,7 +1936,10 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) · 1935 unmodified lines | |||
| 1936 | skip_rx = true; | 1936 | skip_rx = true; |
| 1937 | 1937 | ||
| 1938 | if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { | 1938 | if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { |
| 1939 | if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) | 1939 | struct irq_data *d; |
| 1940 | |||
| 1941 | d = irq_get_irq_data(port->irq); | ||
| 1942 | if (d && irqd_is_wakeup_set(d)) | ||
| 1940 | pm_wakeup_event(tport->tty->dev, 0); | 1943 | pm_wakeup_event(tport->tty->dev, 0); |
| 1941 | if (!up->dma || handle_rx_dma(up, iir)) | 1944 | if (!up->dma || handle_rx_dma(up, iir)) |
| 1942 | status = serial8250_rx_chars(up, status); | 1945 | status = serial8250_rx_chars(up, status); |
| @@ -233,7 +233,8 @@ int parent_create_sysfs_files(struct mdev_parent *parent) · 232 unmodified lines | |||
| 233 | out_err: | 233 | out_err: |
| 234 | while (--i >= 0) | 234 | while (--i >= 0) |
| 235 | mdev_type_remove(parent->types[i]); | 235 | mdev_type_remove(parent->types[i]); |
| 236 | return 0; | 236 | kset_unregister(parent->mdev_types_kset); |
| 237 | return ret; | ||
| 237 | } | 238 | } |
| 238 | 239 | ||
| 239 | static ssize_t remove_store(struct device *dev, struct device_attribute *attr, | 240 | static ssize_t remove_store(struct device *dev, struct device_attribute *attr, |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | config PDS_VFIO_PCI | 4 | config PDS_VFIO_PCI |
| 5 | tristate "VFIO support for PDS PCI devices" | 5 | tristate "VFIO support for PDS PCI devices" |
| 6 | depends on PDS_CORE | 6 | depends on PDS_CORE && PCI_IOV |
| 7 | select VFIO_PCI_CORE | 7 | select VFIO_PCI_CORE |
| 8 | help | 8 | help |
| 9 | This provides generic PCI support for PDS devices using the VFIO | 9 | This provides generic PCI support for PDS devices using the VFIO |
| @@ -162,7 +162,7 @@ static int pds_vfio_init_device(struct vfio_device *vdev) · 161 unmodified lines | |||
| 162 | pci_id = PCI_DEVID(pdev->bus->number, pdev->devfn); | 162 | pci_id = PCI_DEVID(pdev->bus->number, pdev->devfn); |
| 163 | dev_dbg(&pdev->dev, | 163 | dev_dbg(&pdev->dev, |
| 164 | "%s: PF %#04x VF %#04x vf_id %d domain %d pds_vfio %p\n", | 164 | "%s: PF %#04x VF %#04x vf_id %d domain %d pds_vfio %p\n", |
| 165 | __func__, pci_dev_id(pdev->physfn), pci_id, vf_id, | 165 | __func__, pci_dev_id(pci_physfn(pdev)), pci_id, vf_id, |
| 166 | pci_domain_nr(pdev->bus), pds_vfio); | 166 | pci_domain_nr(pdev->bus), pds_vfio); |
| 167 | 167 | ||
| 168 | return 0; | 168 | return 0; |
| @@ -123,8 +123,18 @@ static inline ssize_t vringh_iov_xfer(struct vringh *vrh, · 122 unmodified lines | |||
| 123 | done += partlen; | 123 | done += partlen; |
| 124 | len -= partlen; | 124 | len -= partlen; |
| 125 | ptr += partlen; | 125 | ptr += partlen; |
| 126 | iov->consumed += partlen; | ||
| 127 | iov->iov[iov->i].iov_len -= partlen; | ||
| 128 | iov->iov[iov->i].iov_base += partlen; | ||
| 126 | 129 | ||
| 127 | vringh_kiov_advance(iov, partlen); | 130 | if (!iov->iov[iov->i].iov_len) { |
| 131 | /* Fix up old iov element then increment. */ | ||
| 132 | iov->iov[iov->i].iov_len = iov->consumed; | ||
| 133 | iov->iov[iov->i].iov_base -= iov->consumed; | ||
| 134 | |||
| 135 | iov->consumed = 0; | ||
| 136 | iov->i++; | ||
| 137 | } | ||
| 128 | } | 138 | } |
| 129 | return done; | 139 | return done; |
| 130 | } | 140 | } |
| @@ -73,6 +73,7 @@ config DUMMY_CONSOLE_ROWS · 72 unmodified lines | |||
| 73 | config FRAMEBUFFER_CONSOLE | 73 | config FRAMEBUFFER_CONSOLE |
| 74 | bool "Framebuffer Console support" | 74 | bool "Framebuffer Console support" |
| 75 | depends on FB_CORE && !UML | 75 | depends on FB_CORE && !UML |
| 76 | default DRM_FBDEV_EMULATION | ||
| 76 | select VT_HW_CONSOLE_BINDING | 77 | select VT_HW_CONSOLE_BINDING |
| 77 | select CRC32 | 78 | select CRC32 |
| 78 | select FONT_SUPPORT | 79 | select FONT_SUPPORT |
| @@ -1762,7 +1762,7 @@ config FB_COBALT · 1761 unmodified lines | |||
| 1762 | 1762 | ||
| 1763 | config FB_SH7760 | 1763 | config FB_SH7760 |
| 1764 | bool "SH7760/SH7763/SH7720/SH7721 LCDC support" | 1764 | bool "SH7760/SH7763/SH7720/SH7721 LCDC support" |
| 1765 | depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ | 1765 | depends on FB=y && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ |
| 1766 | || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) | 1766 | || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) |
| 1767 | select FB_IOMEM_HELPERS | 1767 | select FB_IOMEM_HELPERS |
| 1768 | help | 1768 | help |
| @@ -28,7 +28,7 @@ config FIRMWARE_EDID · 27 unmodified lines | |||
| 28 | config FB_DEVICE | 28 | config FB_DEVICE |
| 29 | bool "Provide legacy /dev/fb* device" | 29 | bool "Provide legacy /dev/fb* device" |
| 30 | depends on FB_CORE | 30 | depends on FB_CORE |
| 31 | default y | 31 | default FB |
| 32 | help | 32 | help |
| 33 | Say Y here if you want the legacy /dev/fb* device file and | 33 | Say Y here if you want the legacy /dev/fb* device file and |
| 34 | interfaces within sysfs anc procfs. It is only required if you | 34 | interfaces within sysfs anc procfs. It is only required if you |
| @@ -80,7 +80,7 @@ struct aio_ring { · 79 unmodified lines | |||
| 80 | struct kioctx_table { | 80 | struct kioctx_table { |
| 81 | struct rcu_head rcu; | 81 | struct rcu_head rcu; |
| 82 | unsigned nr; | 82 | unsigned nr; |
| 83 | struct kioctx __rcu *table[]; | 83 | struct kioctx __rcu *table[] __counted_by(nr); |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | struct kioctx_cpu { | 86 | struct kioctx_cpu { |
| @@ -345,10 +345,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) · 344 unmodified lines | |||
| 345 | /* there's now no turning back... the old userspace image is dead, | 345 | /* there's now no turning back... the old userspace image is dead, |
| 346 | * defunct, deceased, etc. | 346 | * defunct, deceased, etc. |
| 347 | */ | 347 | */ |
| 348 | SET_PERSONALITY(exec_params.hdr); | ||
| 348 | if (elf_check_fdpic(&exec_params.hdr)) | 349 | if (elf_check_fdpic(&exec_params.hdr)) |
| 349 | set_personality(PER_LINUX_FDPIC); | 350 | current->personality |= PER_LINUX_FDPIC; |
| 350 | else | ||
| 351 | set_personality(PER_LINUX); | ||
| 352 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) | 351 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) |
| 353 | current->personality |= READ_IMPLIES_EXEC; | 352 | current->personality |= READ_IMPLIES_EXEC; |
| 354 | 353 | ||
| @@ -103,24 +103,17 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans) · 102 unmodified lines | |||
| 103 | * Transfer bytes to our delayed refs rsv. | 103 | * Transfer bytes to our delayed refs rsv. |
| 104 | * | 104 | * |
| 105 | * @fs_info: the filesystem | 105 | * @fs_info: the filesystem |
| 106 | * @src: source block rsv to transfer from | ||
| 107 | * @num_bytes: number of bytes to transfer | 106 | * @num_bytes: number of bytes to transfer |
| 108 | * | 107 | * |
| 109 | * This transfers up to the num_bytes amount from the src rsv to the | 108 | * This transfers up to the num_bytes amount, previously reserved, to the |
| 110 | * delayed_refs_rsv. Any extra bytes are returned to the space info. | 109 | * delayed_refs_rsv. Any extra bytes are returned to the space info. |
| 111 | */ | 110 | */ |
| 112 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, | 111 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, |
| 113 | struct btrfs_block_rsv *src, | ||
| 114 | u64 num_bytes) | 112 | u64 num_bytes) |
| 115 | { | 113 | { |
| 116 | struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; | 114 | struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; |
| 117 | u64 to_free = 0; | 115 | u64 to_free = 0; |
| 118 | 116 | ||
| 119 | spin_lock(&src->lock); | ||
| 120 | src->reserved -= num_bytes; | ||
| 121 | src->size -= num_bytes; | ||
| 122 | spin_unlock(&src->lock); | ||
| 123 | |||
| 124 | spin_lock(&delayed_refs_rsv->lock); | 117 | spin_lock(&delayed_refs_rsv->lock); |
| 125 | if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { | 118 | if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { |
| 126 | u64 delta = delayed_refs_rsv->size - | 119 | u64 delta = delayed_refs_rsv->size - |
| @@ -163,6 +156,8 @@ int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, · 36 unmodified lines | |||
| 163 | struct btrfs_block_rsv *block_rsv = &fs_info->delayed_refs_rsv; | 156 | struct btrfs_block_rsv *block_rsv = &fs_info->delayed_refs_rsv; |
| 164 | u64 limit = btrfs_calc_delayed_ref_bytes(fs_info, 1); | 157 | u64 limit = btrfs_calc_delayed_ref_bytes(fs_info, 1); |
| 165 | u64 num_bytes = 0; | 158 | u64 num_bytes = 0; |
| 159 | u64 refilled_bytes; | ||
| 160 | u64 to_free; | ||
| 166 | int ret = -ENOSPC; | 161 | int ret = -ENOSPC; |
| 167 | 162 | ||
| 168 | spin_lock(&block_rsv->lock); | 163 | spin_lock(&block_rsv->lock); |
| @@ -178,9 +173,38 @@ int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, · 9 unmodified lines | |||
| 178 | ret = btrfs_reserve_metadata_bytes(fs_info, block_rsv, num_bytes, flush); | 173 | ret = btrfs_reserve_metadata_bytes(fs_info, block_rsv, num_bytes, flush); |
| 179 | if (ret) | 174 | if (ret) |
| 180 | return ret; | 175 | return ret; |
| 181 | btrfs_block_rsv_add_bytes(block_rsv, num_bytes, false); | 176 | |
| 182 | trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv", | 177 | /* |
| 183 | 0, num_bytes, 1); | 178 | * We may have raced with someone else, so check again if we the block |
| 179 | * reserve is still not full and release any excess space. | ||
| 180 | */ | ||
| 181 | spin_lock(&block_rsv->lock); | ||
| 182 | if (block_rsv->reserved < block_rsv->size) { | ||
| 183 | u64 needed = block_rsv->size - block_rsv->reserved; | ||
| 184 | |||
| 185 | if (num_bytes >= needed) { | ||
| 186 | block_rsv->reserved += needed; | ||
| 187 | block_rsv->full = true; | ||
| 188 | to_free = num_bytes - needed; | ||
| 189 | refilled_bytes = needed; | ||
| 190 | } else { | ||
| 191 | block_rsv->reserved += num_bytes; | ||
| 192 | to_free = 0; | ||
| 193 | refilled_bytes = num_bytes; | ||
| 194 | } | ||
| 195 | } else { | ||
| 196 | to_free = num_bytes; | ||
| 197 | refilled_bytes = 0; | ||
| 198 | } | ||
| 199 | spin_unlock(&block_rsv->lock); | ||
| 200 | |||
| 201 | if (to_free > 0) | ||
| 202 | btrfs_space_info_free_bytes_may_use(fs_info, block_rsv->space_info, | ||
| 203 | to_free); | ||
| 204 | |||
| 205 | if (refilled_bytes > 0) | ||
| 206 | trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv", 0, | ||
| 207 | refilled_bytes, 1); | ||
| 184 | return 0; | 208 | return 0; |
| 185 | } | 209 | } |
| 186 | 210 | ||
| @@ -407,7 +407,6 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans); · 406 unmodified lines | |||
| 407 | int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, | 407 | int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, |
| 408 | enum btrfs_reserve_flush_enum flush); | 408 | enum btrfs_reserve_flush_enum flush); |
| 409 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, | 409 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, |
| 410 | struct btrfs_block_rsv *src, | ||
| 411 | u64 num_bytes); | 410 | u64 num_bytes); |
| 412 | bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); | 411 | bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); |
| 413 | 412 | ||
| @@ -1514,15 +1514,14 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, · 1513 unmodified lines | |||
| 1514 | btrfs_release_path(path); | 1514 | btrfs_release_path(path); |
| 1515 | 1515 | ||
| 1516 | /* now insert the actual backref */ | 1516 | /* now insert the actual backref */ |
| 1517 | if (owner < BTRFS_FIRST_FREE_OBJECTID) { | 1517 | if (owner < BTRFS_FIRST_FREE_OBJECTID) |
| 1518 | BUG_ON(refs_to_add != 1); | ||
| 1519 | ret = insert_tree_block_ref(trans, path, bytenr, parent, | 1518 | ret = insert_tree_block_ref(trans, path, bytenr, parent, |
| 1520 | root_objectid); | 1519 | root_objectid); |
| 1521 | } else { | 1520 | else |
| 1522 | ret = insert_extent_data_ref(trans, path, bytenr, parent, | 1521 | ret = insert_extent_data_ref(trans, path, bytenr, parent, |
| 1523 | root_objectid, owner, offset, | 1522 | root_objectid, owner, offset, |
| 1524 | refs_to_add); | 1523 | refs_to_add); |
| 1525 | } | 1524 | |
| 1526 | if (ret) | 1525 | if (ret) |
| 1527 | btrfs_abort_transaction(trans, ret); | 1526 | btrfs_abort_transaction(trans, ret); |
| 1528 | out: | 1527 | out: |
| @@ -1656,7 +1655,10 @@ again: · 127 unmodified lines | |||
| 1656 | goto again; | 1655 | goto again; |
| 1657 | } | 1656 | } |
| 1658 | } else { | 1657 | } else { |
| 1659 | err = -EIO; | 1658 | err = -EUCLEAN; |
| 1659 | btrfs_err(fs_info, | ||
| 1660 | "missing extent item for extent %llu num_bytes %llu level %d", | ||
| 1661 | head->bytenr, head->num_bytes, extent_op->level); | ||
| 1660 | goto out; | 1662 | goto out; |
| 1661 | } | 1663 | } |
| 1662 | } | 1664 | } |
| @@ -1699,12 +1701,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, · 36 unmodified lines | |||
| 1699 | parent = ref->parent; | 1701 | parent = ref->parent; |
| 1700 | ref_root = ref->root; | 1702 | ref_root = ref->root; |
| 1701 | 1703 | ||
| 1702 | if (node->ref_mod != 1) { | 1704 | if (unlikely(node->ref_mod != 1)) { |
| 1703 | btrfs_err(trans->fs_info, | 1705 | btrfs_err(trans->fs_info, |
| 1704 | "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", | 1706 | "btree block %llu has %d references rather than 1: action %d ref_root %llu parent %llu", |
| 1705 | node->bytenr, node->ref_mod, node->action, ref_root, | 1707 | node->bytenr, node->ref_mod, node->action, ref_root, |
| 1706 | parent); | 1708 | parent); |
| 1707 | return -EIO; | 1709 | return -EUCLEAN; |
| 1708 | } | 1710 | } |
| 1709 | if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { | 1711 | if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { |
| 1710 | BUG_ON(!extent_op || !extent_op->update_flags); | 1712 | BUG_ON(!extent_op || !extent_op->update_flags); |
| @@ -3995,8 +3995,14 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv, · 3994 unmodified lines | |||
| 3995 | char *dst = (char *)dstv; | 3995 | char *dst = (char *)dstv; |
| 3996 | unsigned long i = get_eb_page_index(start); | 3996 | unsigned long i = get_eb_page_index(start); |
| 3997 | 3997 | ||
| 3998 | if (check_eb_range(eb, start, len)) | 3998 | if (check_eb_range(eb, start, len)) { |
| 3999 | /* | ||
| 4000 | * Invalid range hit, reset the memory, so callers won't get | ||
| 4001 | * some random garbage for their uninitialzed memory. | ||
| 4002 | */ | ||
| 4003 | memset(dstv, 0, len); | ||
| 3999 | return; | 4004 | return; |
| 4005 | } | ||
| 4000 | 4006 | ||
| 4001 | offset = get_eb_offset_in_page(eb, start); | 4007 | offset = get_eb_offset_in_page(eb, start); |
| 4002 | 4008 | ||
| @@ -2117,7 +2117,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 2116 unmodified lines | |||
| 2117 | * calculated f_bavail. | 2117 | * calculated f_bavail. |
| 2118 | */ | 2118 | */ |
| 2119 | if (!mixed && block_rsv->space_info->full && | 2119 | if (!mixed && block_rsv->space_info->full && |
| 2120 | total_free_meta - thresh < block_rsv->size) | 2120 | (total_free_meta < thresh || total_free_meta - thresh < block_rsv->size)) |
| 2121 | buf->f_bavail = 0; | 2121 | buf->f_bavail = 0; |
| 2122 | 2122 | ||
| 2123 | buf->f_type = BTRFS_SUPER_MAGIC; | 2123 | buf->f_type = BTRFS_SUPER_MAGIC; |
| @@ -631,14 +631,14 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, · 630 unmodified lines | |||
| 631 | reloc_reserved = true; | 631 | reloc_reserved = true; |
| 632 | } | 632 | } |
| 633 | 633 | ||
| 634 | ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes, flush); | 634 | ret = btrfs_reserve_metadata_bytes(fs_info, rsv, num_bytes, flush); |
| 635 | if (ret) | 635 | if (ret) |
| 636 | goto reserve_fail; | 636 | goto reserve_fail; |
| 637 | if (delayed_refs_bytes) { | 637 | if (delayed_refs_bytes) { |
| 638 | btrfs_migrate_to_delayed_refs_rsv(fs_info, rsv, | 638 | btrfs_migrate_to_delayed_refs_rsv(fs_info, delayed_refs_bytes); |
| 639 | delayed_refs_bytes); | ||
| 640 | num_bytes -= delayed_refs_bytes; | 639 | num_bytes -= delayed_refs_bytes; |
| 641 | } | 640 | } |
| 641 | btrfs_block_rsv_add_bytes(rsv, num_bytes, true); | ||
| 642 | 642 | ||
| 643 | if (rsv->space_info->force_alloc) | 643 | if (rsv->space_info->force_alloc) |
| 644 | do_chunk_alloc = true; | 644 | do_chunk_alloc = true; |
| @@ -4722,7 +4722,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 4721 unmodified lines | |||
| 4722 | struct extent_buffer *leaf; | 4722 | struct extent_buffer *leaf; |
| 4723 | int slot; | 4723 | int slot; |
| 4724 | int ins_nr = 0; | 4724 | int ins_nr = 0; |
| 4725 | int start_slot; | 4725 | int start_slot = 0; |
| 4726 | int ret; | 4726 | int ret; |
| 4727 | 4727 | ||
| 4728 | if (!(inode->flags & BTRFS_INODE_PREALLOC)) | 4728 | if (!(inode->flags & BTRFS_INODE_PREALLOC)) |
| @@ -1594,7 +1594,7 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, · 1593 unmodified lines | |||
| 1594 | u64 search_start; | 1594 | u64 search_start; |
| 1595 | u64 hole_size; | 1595 | u64 hole_size; |
| 1596 | u64 max_hole_start; | 1596 | u64 max_hole_start; |
| 1597 | u64 max_hole_size; | 1597 | u64 max_hole_size = 0; |
| 1598 | u64 extent_end; | 1598 | u64 extent_end; |
| 1599 | u64 search_end = device->total_bytes; | 1599 | u64 search_end = device->total_bytes; |
| 1600 | int ret; | 1600 | int ret; |
| @@ -1602,17 +1602,16 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, · 1 unmodified line | |||
| 1602 | struct extent_buffer *l; | 1602 | struct extent_buffer *l; |
| 1603 | 1603 | ||
| 1604 | search_start = dev_extent_search_start(device); | 1604 | search_start = dev_extent_search_start(device); |
| 1605 | max_hole_start = search_start; | ||
| 1605 | 1606 | ||
| 1606 | WARN_ON(device->zone_info && | 1607 | WARN_ON(device->zone_info && |
| 1607 | !IS_ALIGNED(num_bytes, device->zone_info->zone_size)); | 1608 | !IS_ALIGNED(num_bytes, device->zone_info->zone_size)); |
| 1608 | 1609 | ||
| 1609 | path = btrfs_alloc_path(); | 1610 | path = btrfs_alloc_path(); |
| 1610 | if (!path) | 1611 | if (!path) { |
| 1611 | return -ENOMEM; | 1612 | ret = -ENOMEM; |
| 1612 | 1613 | goto out; | |
| 1613 | max_hole_start = search_start; | 1614 | } |
| 1614 | max_hole_size = 0; | ||
| 1615 | |||
| 1616 | again: | 1615 | again: |
| 1617 | if (search_start >= search_end || | 1616 | if (search_start >= search_end || |
| 1618 | test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) { | 1617 | test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) { |
| @@ -2011,7 +2011,7 @@ void folio_zero_new_buffers(struct folio *folio, size_t from, size_t to) · 2010 unmodified lines | |||
| 2011 | } | 2011 | } |
| 2012 | EXPORT_SYMBOL(folio_zero_new_buffers); | 2012 | EXPORT_SYMBOL(folio_zero_new_buffers); |
| 2013 | 2013 | ||
| 2014 | static void | 2014 | static int |
| 2015 | iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, | 2015 | iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, |
| 2016 | const struct iomap *iomap) | 2016 | const struct iomap *iomap) |
| 2017 | { | 2017 | { |
| @@ -2025,7 +2025,8 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 7 unmodified lines | |||
| 2025 | * current block, then do not map the buffer and let the caller | 2025 | * current block, then do not map the buffer and let the caller |
| 2026 | * handle it. | 2026 | * handle it. |
| 2027 | */ | 2027 | */ |
| 2028 | BUG_ON(offset >= iomap->offset + iomap->length); | 2028 | if (offset >= iomap->offset + iomap->length) |
| 2029 | return -EIO; | ||
| 2029 | 2030 | ||
| 2030 | switch (iomap->type) { | 2031 | switch (iomap->type) { |
| 2031 | case IOMAP_HOLE: | 2032 | case IOMAP_HOLE: |
| @@ -2037,7 +2038,7 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 5 unmodified lines | |||
| 2037 | if (!buffer_uptodate(bh) || | 2038 | if (!buffer_uptodate(bh) || |
| 2038 | (offset >= i_size_read(inode))) | 2039 | (offset >= i_size_read(inode))) |
| 2039 | set_buffer_new(bh); | 2040 | set_buffer_new(bh); |
| 2040 | break; | 2041 | return 0; |
| 2041 | case IOMAP_DELALLOC: | 2042 | case IOMAP_DELALLOC: |
| 2042 | if (!buffer_uptodate(bh) || | 2043 | if (!buffer_uptodate(bh) || |
| 2043 | (offset >= i_size_read(inode))) | 2044 | (offset >= i_size_read(inode))) |
| @@ -2045,7 +2046,7 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 1 unmodified line | |||
| 2045 | set_buffer_uptodate(bh); | 2046 | set_buffer_uptodate(bh); |
| 2046 | set_buffer_mapped(bh); | 2047 | set_buffer_mapped(bh); |
| 2047 | set_buffer_delay(bh); | 2048 | set_buffer_delay(bh); |
| 2048 | break; | 2049 | return 0; |
| 2049 | case IOMAP_UNWRITTEN: | 2050 | case IOMAP_UNWRITTEN: |
| 2050 | /* | 2051 | /* |
| 2051 | * For unwritten regions, we always need to ensure that regions | 2052 | * For unwritten regions, we always need to ensure that regions |
| @@ -2057,12 +2058,24 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 5 unmodified lines | |||
| 2057 | fallthrough; | 2058 | fallthrough; |
| 2058 | case IOMAP_MAPPED: | 2059 | case IOMAP_MAPPED: |
| 2059 | if ((iomap->flags & IOMAP_F_NEW) || | 2060 | if ((iomap->flags & IOMAP_F_NEW) || |
| 2060 | offset >= i_size_read(inode)) | 2061 | offset >= i_size_read(inode)) { |
| 2062 | /* | ||
| 2063 | * This can happen if truncating the block device races | ||
| 2064 | * with the check in the caller as i_size updates on | ||
| 2065 | * block devices aren't synchronized by i_rwsem for | ||
| 2066 | * block devices. | ||
| 2067 | */ | ||
| 2068 | if (S_ISBLK(inode->i_mode)) | ||
| 2069 | return -EIO; | ||
| 2061 | set_buffer_new(bh); | 2070 | set_buffer_new(bh); |
| 2071 | } | ||
| 2062 | bh->b_blocknr = (iomap->addr + offset - iomap->offset) >> | 2072 | bh->b_blocknr = (iomap->addr + offset - iomap->offset) >> |
| 2063 | inode->i_blkbits; | 2073 | inode->i_blkbits; |
| 2064 | set_buffer_mapped(bh); | 2074 | set_buffer_mapped(bh); |
| 2065 | break; | 2075 | return 0; |
| 2076 | default: | ||
| 2077 | WARN_ON_ONCE(1); | ||
| 2078 | return -EIO; | ||
| 2066 | } | 2079 | } |
| 2067 | } | 2080 | } |
| 2068 | 2081 | ||
| @@ -2103,13 +2116,12 @@ int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len, · 34 unmodified lines | |||
| 2103 | clear_buffer_new(bh); | 2116 | clear_buffer_new(bh); |
| 2104 | if (!buffer_mapped(bh)) { | 2117 | if (!buffer_mapped(bh)) { |
| 2105 | WARN_ON(bh->b_size != blocksize); | 2118 | WARN_ON(bh->b_size != blocksize); |
| 2106 | if (get_block) { | 2119 | if (get_block) |
| 2107 | err = get_block(inode, block, bh, 1); | 2120 | err = get_block(inode, block, bh, 1); |
| 2108 | if (err) | 2121 | else |
| 2109 | break; | 2122 | err = iomap_to_bh(inode, block, bh, iomap); |
| 2110 | } else { | 2123 | if (err) |
| 2111 | iomap_to_bh(inode, block, bh, iomap); | 2124 | break; |
| 2112 | } | ||
| 2113 | 2125 | ||
| 2114 | if (buffer_new(bh)) { | 2126 | if (buffer_new(bh)) { |
| 2115 | clean_bdev_bh_alias(bh); | 2127 | clean_bdev_bh_alias(bh); |
| @@ -249,11 +249,9 @@ static struct inode *parse_longname(const struct inode *parent, · 248 unmodified lines | |||
| 249 | if (!dir) { | 249 | if (!dir) { |
| 250 | /* This can happen if we're not mounting cephfs on the root */ | 250 | /* This can happen if we're not mounting cephfs on the root */ |
| 251 | dir = ceph_get_inode(parent->i_sb, vino, NULL); | 251 | dir = ceph_get_inode(parent->i_sb, vino, NULL); |
| 252 | if (!dir) | 252 | if (IS_ERR(dir)) |
| 253 | dir = ERR_PTR(-ENOENT); | 253 | dout("Can't find inode %s (%s)\n", inode_number, name); |
| 254 | } | 254 | } |
| 255 | if (IS_ERR(dir)) | ||
| 256 | dout("Can't find inode %s (%s)\n", inode_number, name); | ||
| 257 | 255 | ||
| 258 | out: | 256 | out: |
| 259 | kfree(inode_number); | 257 | kfree(inode_number); |
| @@ -1535,10 +1535,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb, · 1534 unmodified lines | |||
| 1535 | 1535 | ||
| 1536 | if (wbc->pages_skipped) { | 1536 | if (wbc->pages_skipped) { |
| 1537 | /* | 1537 | /* |
| 1538 | * writeback is not making progress due to locked | 1538 | * Writeback is not making progress due to locked buffers. |
| 1539 | * buffers. Skip this inode for now. | 1539 | * Skip this inode for now. Although having skipped pages |
| 1540 | * is odd for clean inodes, it can happen for some | ||
| 1541 | * filesystems so handle that gracefully. | ||
| 1540 | */ | 1542 | */ |
| 1541 | redirty_tail_locked(inode, wb); | 1543 | if (inode->i_state & I_DIRTY_ALL) |
| 1544 | redirty_tail_locked(inode, wb); | ||
| 1545 | else | ||
| 1546 | inode_cgwb_move_to_attached(inode, wb); | ||
| 1542 | return; | 1547 | return; |
| 1543 | } | 1548 | } |
| 1544 | 1549 | ||
| @@ -640,11 +640,13 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos, · 639 unmodified lines | |||
| 640 | size_t poff, plen; | 640 | size_t poff, plen; |
| 641 | 641 | ||
| 642 | /* | 642 | /* |
| 643 | * If the write completely overlaps the current folio, then | 643 | * If the write or zeroing completely overlaps the current folio, then |
| 644 | * entire folio will be dirtied so there is no need for | 644 | * entire folio will be dirtied so there is no need for |
| 645 | * per-block state tracking structures to be attached to this folio. | 645 | * per-block state tracking structures to be attached to this folio. |
| 646 | * For the unshare case, we must read in the ondisk contents because we | ||
| 647 | * are not changing pagecache contents. | ||
| 646 | */ | 648 | */ |
| 647 | if (pos <= folio_pos(folio) && | 649 | if (!(iter->flags & IOMAP_UNSHARE) && pos <= folio_pos(folio) && |
| 648 | pos + len >= folio_pos(folio) + folio_size(folio)) | 650 | pos + len >= folio_pos(folio) + folio_size(folio)) |
| 649 | return 0; | 651 | return 0; |
| 650 | 652 | ||
| @@ -1047,7 +1049,7 @@ static int iomap_write_delalloc_punch(struct inode *inode, struct folio *folio, · 396 unmodified lines | |||
| 1047 | 1049 | ||
| 1048 | /* | 1050 | /* |
| 1049 | * Scan the data range passed to us for dirty page cache folios. If we find a | 1051 | * Scan the data range passed to us for dirty page cache folios. If we find a |
| 1050 | * dirty folio, punch out the preceeding range and update the offset from which | 1052 | * dirty folio, punch out the preceding range and update the offset from which |
| 1051 | * the next punch will start from. | 1053 | * the next punch will start from. |
| 1052 | * | 1054 | * |
| 1053 | * We can punch out storage reservations under clean pages because they either | 1055 | * We can punch out storage reservations under clean pages because they either |
| @@ -1261,7 +1263,6 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) · 207 unmodified lines | |||
| 1261 | const struct iomap *srcmap = iomap_iter_srcmap(iter); | 1263 | const struct iomap *srcmap = iomap_iter_srcmap(iter); |
| 1262 | loff_t pos = iter->pos; | 1264 | loff_t pos = iter->pos; |
| 1263 | loff_t length = iomap_length(iter); | 1265 | loff_t length = iomap_length(iter); |
| 1264 | long status = 0; | ||
| 1265 | loff_t written = 0; | 1266 | loff_t written = 0; |
| 1266 | 1267 | ||
| 1267 | /* don't bother with blocks that are not shared to start with */ | 1268 | /* don't bother with blocks that are not shared to start with */ |
| @@ -1272,28 +1273,33 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) · 4 unmodified lines | |||
| 1272 | return length; | 1273 | return length; |
| 1273 | 1274 | ||
| 1274 | do { | 1275 | do { |
| 1275 | unsigned long offset = offset_in_page(pos); | ||
| 1276 | unsigned long bytes = min_t(loff_t, PAGE_SIZE - offset, length); | ||
| 1277 | struct folio *folio; | 1276 | struct folio *folio; |
| 1277 | int status; | ||
| 1278 | size_t offset; | ||
| 1279 | size_t bytes = min_t(u64, SIZE_MAX, length); | ||
| 1278 | 1280 | ||
| 1279 | status = iomap_write_begin(iter, pos, bytes, &folio); | 1281 | status = iomap_write_begin(iter, pos, bytes, &folio); |
| 1280 | if (unlikely(status)) | 1282 | if (unlikely(status)) |
| 1281 | return status; | 1283 | return status; |
| 1282 | if (iter->iomap.flags & IOMAP_F_STALE) | 1284 | if (iomap->flags & IOMAP_F_STALE) |
| 1283 | break; | 1285 | break; |
| 1284 | 1286 | ||
| 1285 | status = iomap_write_end(iter, pos, bytes, bytes, folio); | 1287 | offset = offset_in_folio(folio, pos); |
| 1286 | if (WARN_ON_ONCE(status == 0)) | 1288 | if (bytes > folio_size(folio) - offset) |
| 1289 | bytes = folio_size(folio) - offset; | ||
| 1290 | |||
| 1291 | bytes = iomap_write_end(iter, pos, bytes, bytes, folio); | ||
| 1292 | if (WARN_ON_ONCE(bytes == 0)) | ||
| 1287 | return -EIO; | 1293 | return -EIO; |
| 1288 | 1294 | ||
| 1289 | cond_resched(); | 1295 | cond_resched(); |
| 1290 | 1296 | ||
| 1291 | pos += status; | 1297 | pos += bytes; |
| 1292 | written += status; | 1298 | written += bytes; |
| 1293 | length -= status; | 1299 | length -= bytes; |
| 1294 | 1300 | ||
| 1295 | balance_dirty_pages_ratelimited(iter->inode->i_mapping); | 1301 | balance_dirty_pages_ratelimited(iter->inode->i_mapping); |
| 1296 | } while (length); | 1302 | } while (length > 0); |
| 1297 | 1303 | ||
| 1298 | return written; | 1304 | return written; |
| 1299 | } | 1305 | } |
| @@ -1903,6 +1903,7 @@ ssize_t direct_write_fallback(struct kiocb *iocb, struct iov_iter *iter, · 1902 unmodified lines | |||
| 1903 | * We don't know how much we wrote, so just return the number of | 1903 | * We don't know how much we wrote, so just return the number of |
| 1904 | * bytes which were direct-written | 1904 | * bytes which were direct-written |
| 1905 | */ | 1905 | */ |
| 1906 | iocb->ki_pos -= buffered_written; | ||
| 1906 | if (direct_written) | 1907 | if (direct_written) |
| 1907 | return direct_written; | 1908 | return direct_written; |
| 1908 | return err; | 1909 | return err; |
| @@ -10622,7 +10622,9 @@ static void nfs4_disable_swap(struct inode *inode) · 10621 unmodified lines | |||
| 10622 | */ | 10622 | */ |
| 10623 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; | 10623 | struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; |
| 10624 | 10624 | ||
| 10625 | nfs4_schedule_state_manager(clp); | 10625 | set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); |
| 10626 | clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); | ||
| 10627 | wake_up_var(&clp->cl_state); | ||
| 10626 | } | 10628 | } |
| 10627 | 10629 | ||
| 10628 | static const struct inode_operations nfs4_dir_inode_operations = { | 10630 | static const struct inode_operations nfs4_dir_inode_operations = { |
| @@ -1209,16 +1209,26 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) · 1208 unmodified lines | |||
| 1209 | { | 1209 | { |
| 1210 | struct task_struct *task; | 1210 | struct task_struct *task; |
| 1211 | char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; | 1211 | char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; |
| 1212 | struct rpc_clnt *clnt = clp->cl_rpcclient; | ||
| 1213 | bool swapon = false; | ||
| 1212 | 1214 | ||
| 1213 | if (clp->cl_rpcclient->cl_shutdown) | 1215 | if (clnt->cl_shutdown) |
| 1214 | return; | 1216 | return; |
| 1215 | 1217 | ||
| 1216 | set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); | 1218 | set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); |
| 1217 | if (test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) != 0) { | 1219 | |
| 1218 | wake_up_var(&clp->cl_state); | 1220 | if (atomic_read(&clnt->cl_swapper)) { |
| 1219 | return; | 1221 | swapon = !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, |
| 1222 | &clp->cl_state); | ||
| 1223 | if (!swapon) { | ||
| 1224 | wake_up_var(&clp->cl_state); | ||
| 1225 | return; | ||
| 1226 | } | ||
| 1220 | } | 1227 | } |
| 1221 | set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); | 1228 | |
| 1229 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) | ||
| 1230 | return; | ||
| 1231 | |||
| 1222 | __module_get(THIS_MODULE); | 1232 | __module_get(THIS_MODULE); |
| 1223 | refcount_inc(&clp->cl_count); | 1233 | refcount_inc(&clp->cl_count); |
| 1224 | 1234 | ||
| @@ -1235,8 +1245,9 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) · 10 unmodified lines | |||
| 1235 | __func__, PTR_ERR(task)); | 1245 | __func__, PTR_ERR(task)); |
| 1236 | if (!nfs_client_init_is_complete(clp)) | 1246 | if (!nfs_client_init_is_complete(clp)) |
| 1237 | nfs_mark_client_ready(clp, PTR_ERR(task)); | 1247 | nfs_mark_client_ready(clp, PTR_ERR(task)); |
| 1248 | if (swapon) | ||
| 1249 | clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); | ||
| 1238 | nfs4_clear_state_manager_bit(clp); | 1250 | nfs4_clear_state_manager_bit(clp); |
| 1239 | clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); | ||
| 1240 | nfs_put_client(clp); | 1251 | nfs_put_client(clp); |
| 1241 | module_put(THIS_MODULE); | 1252 | module_put(THIS_MODULE); |
| 1242 | } | 1253 | } |
| @@ -2703,6 +2714,13 @@ static void nfs4_state_manager(struct nfs_client *clp) · 1460 unmodified lines | |||
| 2703 | nfs4_end_drain_session(clp); | 2714 | nfs4_end_drain_session(clp); |
| 2704 | nfs4_clear_state_manager_bit(clp); | 2715 | nfs4_clear_state_manager_bit(clp); |
| 2705 | 2716 | ||
| 2717 | if (test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && | ||
| 2718 | !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, | ||
| 2719 | &clp->cl_state)) { | ||
| 2720 | memflags = memalloc_nofs_save(); | ||
| 2721 | continue; | ||
| 2722 | } | ||
| 2723 | |||
| 2706 | if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) { | 2724 | if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) { |
| 2707 | if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { | 2725 | if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { |
| 2708 | nfs_client_return_marked_delegations(clp); | 2726 | nfs_client_return_marked_delegations(clp); |
| @@ -2741,22 +2759,25 @@ static int nfs4_run_state_manager(void *ptr) · 32 unmodified lines | |||
| 2741 | 2759 | ||
| 2742 | allow_signal(SIGKILL); | 2760 | allow_signal(SIGKILL); |
| 2743 | again: | 2761 | again: |
| 2744 | set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); | ||
| 2745 | nfs4_state_manager(clp); | 2762 | nfs4_state_manager(clp); |
| 2746 | if (atomic_read(&cl->cl_swapper)) { | 2763 | |
| 2764 | if (test_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) && | ||
| 2765 | !test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) { | ||
| 2747 | wait_var_event_interruptible(&clp->cl_state, | 2766 | wait_var_event_interruptible(&clp->cl_state, |
| 2748 | test_bit(NFS4CLNT_RUN_MANAGER, | 2767 | test_bit(NFS4CLNT_RUN_MANAGER, |
| 2749 | &clp->cl_state)); | 2768 | &clp->cl_state)); |
| 2750 | if (atomic_read(&cl->cl_swapper) && | 2769 | if (!atomic_read(&cl->cl_swapper)) |
| 2751 | test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state)) | 2770 | clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); |
| 2771 | if (refcount_read(&clp->cl_count) > 1 && !signalled() && | ||
| 2772 | !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) | ||
| 2752 | goto again; | 2773 | goto again; |
| 2753 | /* Either no longer a swapper, or were signalled */ | 2774 | /* Either no longer a swapper, or were signalled */ |
| 2775 | clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); | ||
| 2754 | } | 2776 | } |
| 2755 | clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); | ||
| 2756 | 2777 | ||
| 2757 | if (refcount_read(&clp->cl_count) > 1 && !signalled() && | 2778 | if (refcount_read(&clp->cl_count) > 1 && !signalled() && |
| 2758 | test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && | 2779 | test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && |
| 2759 | !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state)) | 2780 | !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) |
| 2760 | goto again; | 2781 | goto again; |
| 2761 | 2782 | ||
| 2762 | nfs_put_client(clp); | 2783 | nfs_put_client(clp); |
| @@ -802,8 +802,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) · 801 unmodified lines | |||
| 802 | } | 802 | } |
| 803 | 803 | ||
| 804 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { | 804 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { |
| 805 | nfs_release_request(req); | ||
| 806 | atomic_long_dec(&NFS_I(nfs_page_to_inode(req))->nrequests); | 805 | atomic_long_dec(&NFS_I(nfs_page_to_inode(req))->nrequests); |
| 806 | nfs_release_request(req); | ||
| 807 | } | 807 | } |
| 808 | } | 808 | } |
| 809 | 809 | ||
| @@ -4113,6 +4113,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, · 4112 unmodified lines | |||
| 4113 | struct file *file, unsigned long maxcount) | 4113 | struct file *file, unsigned long maxcount) |
| 4114 | { | 4114 | { |
| 4115 | struct xdr_stream *xdr = resp->xdr; | 4115 | struct xdr_stream *xdr = resp->xdr; |
| 4116 | unsigned int base = xdr->buf->page_len & ~PAGE_MASK; | ||
| 4116 | unsigned int starting_len = xdr->buf->len; | 4117 | unsigned int starting_len = xdr->buf->len; |
| 4117 | __be32 zero = xdr_zero; | 4118 | __be32 zero = xdr_zero; |
| 4118 | __be32 nfserr; | 4119 | __be32 nfserr; |
| @@ -4121,8 +4122,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, · 2 unmodified lines | |||
| 4121 | return nfserr_resource; | 4122 | return nfserr_resource; |
| 4122 | 4123 | ||
| 4123 | nfserr = nfsd_iter_read(resp->rqstp, read->rd_fhp, file, | 4124 | nfserr = nfsd_iter_read(resp->rqstp, read->rd_fhp, file, |
| 4124 | read->rd_offset, &maxcount, | 4125 | read->rd_offset, &maxcount, base, |
| 4125 | xdr->buf->page_len & ~PAGE_MASK, | ||
| 4126 | &read->rd_eof); | 4126 | &read->rd_eof); |
| 4127 | read->rd_length = maxcount; | 4127 | read->rd_length = maxcount; |
| 4128 | if (nfserr) | 4128 | if (nfserr) |
| @@ -73,10 +73,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, · 72 unmodified lines | |||
| 73 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | 73 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
| 74 | 74 | ||
| 75 | err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); | 75 | err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); |
| 76 | if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */ | 76 | if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */ |
| 77 | brelse(bh); | ||
| 78 | goto failed; | 77 | goto failed; |
| 79 | } | ||
| 80 | } | 78 | } |
| 81 | 79 | ||
| 82 | lock_buffer(bh); | 80 | lock_buffer(bh); |
| @@ -102,6 +100,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, · 19 unmodified lines | |||
| 102 | failed: | 100 | failed: |
| 103 | unlock_page(bh->b_page); | 101 | unlock_page(bh->b_page); |
| 104 | put_page(bh->b_page); | 102 | put_page(bh->b_page); |
| 103 | if (unlikely(err)) | ||
| 104 | brelse(bh); | ||
| 105 | return err; | 105 | return err; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| @@ -1562,6 +1562,7 @@ load_root: · 1561 unmodified lines | |||
| 1562 | put_inode_out: | 1562 | put_inode_out: |
| 1563 | iput(inode); | 1563 | iput(inode); |
| 1564 | out: | 1564 | out: |
| 1565 | ntfs3_put_sbi(sbi); | ||
| 1565 | kfree(boot2); | 1566 | kfree(boot2); |
| 1566 | return err; | 1567 | return err; |
| 1567 | } | 1568 | } |
| @@ -337,7 +337,7 @@ static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry, · 336 unmodified lines | |||
| 337 | { | 337 | { |
| 338 | struct iattr attr = { | 338 | struct iattr attr = { |
| 339 | .ia_valid = | 339 | .ia_valid = |
| 340 | ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, | 340 | ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME, |
| 341 | .ia_atime = stat->atime, | 341 | .ia_atime = stat->atime, |
| 342 | .ia_mtime = stat->mtime, | 342 | .ia_mtime = stat->mtime, |
| 343 | }; | 343 | }; |
| @@ -188,7 +188,7 @@ static int ovl_check_encode_origin(struct dentry *dentry) · 187 unmodified lines | |||
| 188 | 188 | ||
| 189 | /* Lower file handle for non-upper non-decodable */ | 189 | /* Lower file handle for non-upper non-decodable */ |
| 190 | if (!ovl_dentry_upper(dentry) && !decodable) | 190 | if (!ovl_dentry_upper(dentry) && !decodable) |
| 191 | return 0; | 191 | return 1; |
| 192 | 192 | ||
| 193 | /* Upper file handle for pure upper */ | 193 | /* Upper file handle for pure upper */ |
| 194 | if (!ovl_dentry_lower(dentry)) | 194 | if (!ovl_dentry_lower(dentry)) |
| @@ -341,7 +341,6 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter) · 340 unmodified lines | |||
| 341 | if (!aio_req) | 341 | if (!aio_req) |
| 342 | goto out; | 342 | goto out; |
| 343 | 343 | ||
| 344 | real.flags = 0; | ||
| 345 | aio_req->orig_iocb = iocb; | 344 | aio_req->orig_iocb = iocb; |
| 346 | kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); | 345 | kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); |
| 347 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; | 346 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; |
| @@ -391,6 +390,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) · 43 unmodified lines | |||
| 391 | if (!ovl_should_sync(OVL_FS(inode->i_sb))) | 390 | if (!ovl_should_sync(OVL_FS(inode->i_sb))) |
| 392 | ifl &= ~(IOCB_DSYNC | IOCB_SYNC); | 391 | ifl &= ~(IOCB_DSYNC | IOCB_SYNC); |
| 393 | 392 | ||
| 393 | /* | ||
| 394 | * Overlayfs doesn't support deferred completions, don't copy | ||
| 395 | * this property in case it is set by the issuer. | ||
| 396 | */ | ||
| 397 | ifl &= ~IOCB_DIO_CALLER_COMP; | ||
| 398 | |||
| 394 | old_cred = ovl_override_creds(file_inode(file)->i_sb); | 399 | old_cred = ovl_override_creds(file_inode(file)->i_sb); |
| 395 | if (is_sync_kiocb(iocb)) { | 400 | if (is_sync_kiocb(iocb)) { |
| 396 | file_start_write(real.file); | 401 | file_start_write(real.file); |
| @@ -407,7 +412,6 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) · 10 unmodified lines | |||
| 407 | if (!aio_req) | 412 | if (!aio_req) |
| 408 | goto out; | 413 | goto out; |
| 409 | 414 | ||
| 410 | real.flags = 0; | ||
| 411 | aio_req->orig_iocb = iocb; | 415 | aio_req->orig_iocb = iocb; |
| 412 | kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); | 416 | kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); |
| 413 | aio_req->iocb.ki_flags = ifl; | 417 | aio_req->iocb.ki_flags = ifl; |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | struct ovl_config { | 8 | struct ovl_config { |
| 9 | char *upperdir; | 9 | char *upperdir; |
| 10 | char *workdir; | 10 | char *workdir; |
| 11 | char **lowerdirs; | ||
| 11 | bool default_permissions; | 12 | bool default_permissions; |
| 12 | int redirect_mode; | 13 | int redirect_mode; |
| 13 | int verity_mode; | 14 | int verity_mode; |
| @@ -39,17 +40,8 @@ struct ovl_layer { · 25 unmodified lines | |||
| 39 | int idx; | 40 | int idx; |
| 40 | /* One fsid per unique underlying sb (upper fsid == 0) */ | 41 | /* One fsid per unique underlying sb (upper fsid == 0) */ |
| 41 | int fsid; | 42 | int fsid; |
| 42 | char *name; | ||
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | /* | ||
| 46 | * ovl_free_fs() relies on @mnt being the first member when unmounting | ||
| 47 | * the private mounts created for each layer. Let's check both the | ||
| 48 | * offset and type. | ||
| 49 | */ | ||
| 50 | static_assert(offsetof(struct ovl_layer, mnt) == 0); | ||
| 51 | static_assert(__same_type(typeof_member(struct ovl_layer, mnt), struct vfsmount *)); | ||
| 52 | |||
| 53 | struct ovl_path { | 45 | struct ovl_path { |
| 54 | const struct ovl_layer *layer; | 46 | const struct ovl_layer *layer; |
| 55 | struct dentry *dentry; | 47 | struct dentry *dentry; |
| @@ -752,12 +752,12 @@ void ovl_free_fs(struct ovl_fs *ofs) · 751 unmodified lines | |||
| 752 | if (ofs->upperdir_locked) | 752 | if (ofs->upperdir_locked) |
| 753 | ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root); | 753 | ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root); |
| 754 | 754 | ||
| 755 | /* Hack! Reuse ofs->layers as a vfsmount array before freeing it */ | 755 | /* Reuse ofs->config.lowerdirs as a vfsmount array before freeing it */ |
| 756 | mounts = (struct vfsmount **) ofs->layers; | 756 | mounts = (struct vfsmount **) ofs->config.lowerdirs; |
| 757 | for (i = 0; i < ofs->numlayer; i++) { | 757 | for (i = 0; i < ofs->numlayer; i++) { |
| 758 | iput(ofs->layers[i].trap); | 758 | iput(ofs->layers[i].trap); |
| 759 | kfree(ofs->config.lowerdirs[i]); | ||
| 759 | mounts[i] = ofs->layers[i].mnt; | 760 | mounts[i] = ofs->layers[i].mnt; |
| 760 | kfree(ofs->layers[i].name); | ||
| 761 | } | 761 | } |
| 762 | kern_unmount_array(mounts, ofs->numlayer); | 762 | kern_unmount_array(mounts, ofs->numlayer); |
| 763 | kfree(ofs->layers); | 763 | kfree(ofs->layers); |
| @@ -765,6 +765,7 @@ void ovl_free_fs(struct ovl_fs *ofs) · 1 unmodified line | |||
| 765 | free_anon_bdev(ofs->fs[i].pseudo_dev); | 765 | free_anon_bdev(ofs->fs[i].pseudo_dev); |
| 766 | kfree(ofs->fs); | 766 | kfree(ofs->fs); |
| 767 | 767 | ||
| 768 | kfree(ofs->config.lowerdirs); | ||
| 768 | kfree(ofs->config.upperdir); | 769 | kfree(ofs->config.upperdir); |
| 769 | kfree(ofs->config.workdir); | 770 | kfree(ofs->config.workdir); |
| 770 | if (ofs->creator_cred) | 771 | if (ofs->creator_cred) |
| @@ -949,16 +950,16 @@ int ovl_show_options(struct seq_file *m, struct dentry *dentry) · 178 unmodified lines | |||
| 949 | struct super_block *sb = dentry->d_sb; | 950 | struct super_block *sb = dentry->d_sb; |
| 950 | struct ovl_fs *ofs = OVL_FS(sb); | 951 | struct ovl_fs *ofs = OVL_FS(sb); |
| 951 | size_t nr, nr_merged_lower = ofs->numlayer - ofs->numdatalayer; | 952 | size_t nr, nr_merged_lower = ofs->numlayer - ofs->numdatalayer; |
| 952 | const struct ovl_layer *data_layers = &ofs->layers[nr_merged_lower]; | 953 | char **lowerdatadirs = &ofs->config.lowerdirs[nr_merged_lower]; |
| 953 | 954 | ||
| 954 | /* ofs->layers[0] is the upper layer */ | 955 | /* lowerdirs[] starts from offset 1 */ |
| 955 | seq_printf(m, ",lowerdir=%s", ofs->layers[1].name); | 956 | seq_printf(m, ",lowerdir=%s", ofs->config.lowerdirs[1]); |
| 956 | /* dump regular lower layers */ | 957 | /* dump regular lower layers */ |
| 957 | for (nr = 2; nr < nr_merged_lower; nr++) | 958 | for (nr = 2; nr < nr_merged_lower; nr++) |
| 958 | seq_printf(m, ":%s", ofs->layers[nr].name); | 959 | seq_printf(m, ":%s", ofs->config.lowerdirs[nr]); |
| 959 | /* dump data lower layers */ | 960 | /* dump data lower layers */ |
| 960 | for (nr = 0; nr < ofs->numdatalayer; nr++) | 961 | for (nr = 0; nr < ofs->numdatalayer; nr++) |
| 961 | seq_printf(m, "::%s", data_layers[nr].name); | 962 | seq_printf(m, "::%s", lowerdatadirs[nr]); |
| 962 | if (ofs->config.upperdir) { | 963 | if (ofs->config.upperdir) { |
| 963 | seq_show_option(m, "upperdir", ofs->config.upperdir); | 964 | seq_show_option(m, "upperdir", ofs->config.upperdir); |
| 964 | seq_show_option(m, "workdir", ofs->config.workdir); | 965 | seq_show_option(m, "workdir", ofs->config.workdir); |
| @@ -104,8 +104,8 @@ static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak) · 103 unmodified lines | |||
| 104 | static int ovl_dentry_revalidate_common(struct dentry *dentry, | 104 | static int ovl_dentry_revalidate_common(struct dentry *dentry, |
| 105 | unsigned int flags, bool weak) | 105 | unsigned int flags, bool weak) |
| 106 | { | 106 | { |
| 107 | struct ovl_entry *oe = OVL_E(dentry); | 107 | struct ovl_entry *oe; |
| 108 | struct ovl_path *lowerstack = ovl_lowerstack(oe); | 108 | struct ovl_path *lowerstack; |
| 109 | struct inode *inode = d_inode_rcu(dentry); | 109 | struct inode *inode = d_inode_rcu(dentry); |
| 110 | struct dentry *upper; | 110 | struct dentry *upper; |
| 111 | unsigned int i; | 111 | unsigned int i; |
| @@ -115,6 +115,8 @@ static int ovl_dentry_revalidate_common(struct dentry *dentry, · 3 unmodified lines | |||
| 115 | if (!inode) | 115 | if (!inode) |
| 116 | return -ECHILD; | 116 | return -ECHILD; |
| 117 | 117 | ||
| 118 | oe = OVL_I_E(inode); | ||
| 119 | lowerstack = ovl_lowerstack(oe); | ||
| 118 | upper = ovl_i_dentry_upper(inode); | 120 | upper = ovl_i_dentry_upper(inode); |
| 119 | if (upper) | 121 | if (upper) |
| 120 | ret = ovl_revalidate_real(upper, flags, weak); | 122 | ret = ovl_revalidate_real(upper, flags, weak); |
| @@ -167,6 +169,7 @@ static void ovl_free_inode(struct inode *inode) · 46 unmodified lines | |||
| 167 | struct ovl_inode *oi = OVL_I(inode); | 169 | struct ovl_inode *oi = OVL_I(inode); |
| 168 | 170 | ||
| 169 | kfree(oi->redirect); | 171 | kfree(oi->redirect); |
| 172 | kfree(oi->oe); | ||
| 170 | mutex_destroy(&oi->lock); | 173 | mutex_destroy(&oi->lock); |
| 171 | kmem_cache_free(ovl_inode_cachep, oi); | 174 | kmem_cache_free(ovl_inode_cachep, oi); |
| 172 | } | 175 | } |
| @@ -176,7 +179,7 @@ static void ovl_destroy_inode(struct inode *inode) · 3 unmodified lines | |||
| 176 | struct ovl_inode *oi = OVL_I(inode); | 179 | struct ovl_inode *oi = OVL_I(inode); |
| 177 | 180 | ||
| 178 | dput(oi->__upperdentry); | 181 | dput(oi->__upperdentry); |
| 179 | ovl_free_entry(oi->oe); | 182 | ovl_stack_put(ovl_lowerstack(oi->oe), ovl_numlower(oi->oe)); |
| 180 | if (S_ISDIR(inode->i_mode)) | 183 | if (S_ISDIR(inode->i_mode)) |
| 181 | ovl_dir_cache_free(inode); | 184 | ovl_dir_cache_free(inode); |
| 182 | else | 185 | else |
| @@ -569,11 +572,6 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs, · 386 unmodified lines | |||
| 569 | upper_layer->idx = 0; | 572 | upper_layer->idx = 0; |
| 570 | upper_layer->fsid = 0; | 573 | upper_layer->fsid = 0; |
| 571 | 574 | ||
| 572 | err = -ENOMEM; | ||
| 573 | upper_layer->name = kstrdup(ofs->config.upperdir, GFP_KERNEL); | ||
| 574 | if (!upper_layer->name) | ||
| 575 | goto out; | ||
| 576 | |||
| 577 | /* | 575 | /* |
| 578 | * Inherit SB_NOSEC flag from upperdir. | 576 | * Inherit SB_NOSEC flag from upperdir. |
| 579 | * | 577 | * |
| @@ -1122,7 +1120,8 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs, · 542 unmodified lines | |||
| 1122 | layers[ofs->numlayer].idx = ofs->numlayer; | 1120 | layers[ofs->numlayer].idx = ofs->numlayer; |
| 1123 | layers[ofs->numlayer].fsid = fsid; | 1121 | layers[ofs->numlayer].fsid = fsid; |
| 1124 | layers[ofs->numlayer].fs = &ofs->fs[fsid]; | 1122 | layers[ofs->numlayer].fs = &ofs->fs[fsid]; |
| 1125 | layers[ofs->numlayer].name = l->name; | 1123 | /* Store for printing lowerdir=... in ovl_show_options() */ |
| 1124 | ofs->config.lowerdirs[ofs->numlayer] = l->name; | ||
| 1126 | l->name = NULL; | 1125 | l->name = NULL; |
| 1127 | ofs->numlayer++; | 1126 | ofs->numlayer++; |
| 1128 | ofs->fs[fsid].is_lower = true; | 1127 | ofs->fs[fsid].is_lower = true; |
| @@ -1367,8 +1366,16 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc) · 238 unmodified lines | |||
| 1367 | if (!layers) | 1366 | if (!layers) |
| 1368 | goto out_err; | 1367 | goto out_err; |
| 1369 | 1368 | ||
| 1369 | ofs->config.lowerdirs = kcalloc(ctx->nr + 1, sizeof(char *), GFP_KERNEL); | ||
| 1370 | if (!ofs->config.lowerdirs) { | ||
| 1371 | kfree(layers); | ||
| 1372 | goto out_err; | ||
| 1373 | } | ||
| 1370 | ofs->layers = layers; | 1374 | ofs->layers = layers; |
| 1371 | /* Layer 0 is reserved for upper even if there's no upper */ | 1375 | /* |
| 1376 | * Layer 0 is reserved for upper even if there's no upper. | ||
| 1377 | * For consistency, config.lowerdirs[0] is NULL. | ||
| 1378 | */ | ||
| 1372 | ofs->numlayer = 1; | 1379 | ofs->numlayer = 1; |
| 1373 | 1380 | ||
| 1374 | sb->s_stack_depth = 0; | 1381 | sb->s_stack_depth = 0; |
| @@ -537,7 +537,6 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) · 536 unmodified lines | |||
| 537 | break; | 537 | break; |
| 538 | } | 538 | } |
| 539 | ret += copied; | 539 | ret += copied; |
| 540 | buf->offset = 0; | ||
| 541 | buf->len = copied; | 540 | buf->len = copied; |
| 542 | 541 | ||
| 543 | if (!iov_iter_count(from)) | 542 | if (!iov_iter_count(from)) |
| @@ -289,9 +289,7 @@ struct proc_maps_private { · 288 unmodified lines | |||
| 289 | struct inode *inode; | 289 | struct inode *inode; |
| 290 | struct task_struct *task; | 290 | struct task_struct *task; |
| 291 | struct mm_struct *mm; | 291 | struct mm_struct *mm; |
| 292 | #ifdef CONFIG_MMU | ||
| 293 | struct vma_iterator iter; | 292 | struct vma_iterator iter; |
| 294 | #endif | ||
| 295 | #ifdef CONFIG_NUMA | 293 | #ifdef CONFIG_NUMA |
| 296 | struct mempolicy *task_mempolicy; | 294 | struct mempolicy *task_mempolicy; |
| 297 | #endif | 295 | #endif |
| @@ -175,15 +175,28 @@ static int show_map(struct seq_file *m, void *_p) · 174 unmodified lines | |||
| 175 | return nommu_vma_show(m, _p); | 175 | return nommu_vma_show(m, _p); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static void *m_start(struct seq_file *m, loff_t *pos) | 178 | static struct vm_area_struct *proc_get_vma(struct proc_maps_private *priv, |
| 179 | loff_t *ppos) | ||
| 180 | { | ||
| 181 | struct vm_area_struct *vma = vma_next(&priv->iter); | ||
| 182 | |||
| 183 | if (vma) { | ||
| 184 | *ppos = vma->vm_start; | ||
| 185 | } else { | ||
| 186 | *ppos = -1UL; | ||
| 187 | } | ||
| 188 | |||
| 189 | return vma; | ||
| 190 | } | ||
| 191 | |||
| 192 | static void *m_start(struct seq_file *m, loff_t *ppos) | ||
| 179 | { | 193 | { |
| 180 | struct proc_maps_private *priv = m->private; | 194 | struct proc_maps_private *priv = m->private; |
| 195 | unsigned long last_addr = *ppos; | ||
| 181 | struct mm_struct *mm; | 196 | struct mm_struct *mm; |
| 182 | struct vm_area_struct *vma; | ||
| 183 | unsigned long addr = *pos; | ||
| 184 | 197 | ||
| 185 | /* See m_next(). Zero at the start or after lseek. */ | 198 | /* See proc_get_vma(). Zero at the start or after lseek. */ |
| 186 | if (addr == -1UL) | 199 | if (last_addr == -1UL) |
| 187 | return NULL; | 200 | return NULL; |
| 188 | 201 | ||
| 189 | /* pin the task and mm whilst we play with them */ | 202 | /* pin the task and mm whilst we play with them */ |
| @@ -192,44 +205,41 @@ static void *m_start(struct seq_file *m, loff_t *pos) · 2 unmodified lines | |||
| 192 | return ERR_PTR(-ESRCH); | 205 | return ERR_PTR(-ESRCH); |
| 193 | 206 | ||
| 194 | mm = priv->mm; | 207 | mm = priv->mm; |
| 195 | if (!mm || !mmget_not_zero(mm)) | 208 | if (!mm || !mmget_not_zero(mm)) { |
| 209 | put_task_struct(priv->task); | ||
| 210 | priv->task = NULL; | ||
| 196 | return NULL; | 211 | return NULL; |
| 212 | } | ||
| 197 | 213 | ||
| 198 | if (mmap_read_lock_killable(mm)) { | 214 | if (mmap_read_lock_killable(mm)) { |
| 199 | mmput(mm); | 215 | mmput(mm); |
| 216 | put_task_struct(priv->task); | ||
| 217 | priv->task = NULL; | ||
| 200 | return ERR_PTR(-EINTR); | 218 | return ERR_PTR(-EINTR); |
| 201 | } | 219 | } |
| 202 | 220 | ||
| 203 | /* start the next element from addr */ | 221 | vma_iter_init(&priv->iter, mm, last_addr); |
| 204 | vma = find_vma(mm, addr); | ||
| 205 | if (vma) | ||
| 206 | return vma; | ||
| 207 | 222 | ||
| 208 | mmap_read_unlock(mm); | 223 | return proc_get_vma(priv, ppos); |
| 209 | mmput(mm); | ||
| 210 | return NULL; | ||
| 211 | } | 224 | } |
| 212 | 225 | ||
| 213 | static void m_stop(struct seq_file *m, void *_vml) | 226 | static void m_stop(struct seq_file *m, void *v) |
| 214 | { | 227 | { |
| 215 | struct proc_maps_private *priv = m->private; | 228 | struct proc_maps_private *priv = m->private; |
| 229 | struct mm_struct *mm = priv->mm; | ||
| 216 | 230 | ||
| 217 | if (!IS_ERR_OR_NULL(_vml)) { | 231 | if (!priv->task) |
| 218 | mmap_read_unlock(priv->mm); | 232 | return; |
| 219 | mmput(priv->mm); | 233 | |
| 220 | } | 234 | mmap_read_unlock(mm); |
| 221 | if (priv->task) { | 235 | mmput(mm); |
| 222 | put_task_struct(priv->task); | 236 | put_task_struct(priv->task); |
| 223 | priv->task = NULL; | 237 | priv->task = NULL; |
| 224 | } | ||
| 225 | } | 238 | } |
| 226 | 239 | ||
| 227 | static void *m_next(struct seq_file *m, void *_p, loff_t *pos) | 240 | static void *m_next(struct seq_file *m, void *_p, loff_t *ppos) |
| 228 | { | 241 | { |
| 229 | struct vm_area_struct *vma = _p; | 242 | return proc_get_vma(m->private, ppos); |
| 230 | |||
| 231 | *pos = vma->vm_end; | ||
| 232 | return find_vma(vma->vm_mm, vma->vm_end); | ||
| 233 | } | 243 | } |
| 234 | 244 | ||
| 235 | static const struct seq_operations proc_pid_maps_ops = { | 245 | static const struct seq_operations proc_pid_maps_ops = { |
| @@ -2699,7 +2699,7 @@ struct reiserfs_iget_args { · 2698 unmodified lines | |||
| 2699 | #define get_journal_desc_magic(bh) (bh->b_data + bh->b_size - 12) | 2699 | #define get_journal_desc_magic(bh) (bh->b_data + bh->b_size - 12) |
| 2700 | 2700 | ||
| 2701 | #define journal_trans_half(blocksize) \ | 2701 | #define journal_trans_half(blocksize) \ |
| 2702 | ((blocksize - sizeof (struct reiserfs_journal_desc) + sizeof (__u32) - 12) / sizeof (__u32)) | 2702 | ((blocksize - sizeof(struct reiserfs_journal_desc) - 12) / sizeof(__u32)) |
| 2703 | 2703 | ||
| 2704 | /* journal.c see journal.c for all the comments here */ | 2704 | /* journal.c see journal.c for all the comments here */ |
| 2705 | 2705 | ||
| @@ -2711,7 +2711,7 @@ struct reiserfs_journal_desc { · 5 unmodified lines | |||
| 2711 | __le32 j_len; | 2711 | __le32 j_len; |
| 2712 | 2712 | ||
| 2713 | __le32 j_mount_id; /* mount id of this trans */ | 2713 | __le32 j_mount_id; /* mount id of this trans */ |
| 2714 | __le32 j_realblock[1]; /* real locations for each block */ | 2714 | __le32 j_realblock[]; /* real locations for each block */ |
| 2715 | }; | 2715 | }; |
| 2716 | 2716 | ||
| 2717 | #define get_desc_trans_id(d) le32_to_cpu((d)->j_trans_id) | 2717 | #define get_desc_trans_id(d) le32_to_cpu((d)->j_trans_id) |
| @@ -2726,7 +2726,7 @@ struct reiserfs_journal_desc { · 8 unmodified lines | |||
| 2726 | struct reiserfs_journal_commit { | 2726 | struct reiserfs_journal_commit { |
| 2727 | __le32 j_trans_id; /* must match j_trans_id from the desc block */ | 2727 | __le32 j_trans_id; /* must match j_trans_id from the desc block */ |
| 2728 | __le32 j_len; /* ditto */ | 2728 | __le32 j_len; /* ditto */ |
| 2729 | __le32 j_realblock[1]; /* real locations for each block */ | 2729 | __le32 j_realblock[]; /* real locations for each block */ |
| 2730 | }; | 2730 | }; |
| 2731 | 2731 | ||
| 2732 | #define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id) | 2732 | #define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id) |
| @@ -452,6 +452,9 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) · 451 unmodified lines | |||
| 452 | struct cached_fid *cfid, *q; | 452 | struct cached_fid *cfid, *q; |
| 453 | LIST_HEAD(entry); | 453 | LIST_HEAD(entry); |
| 454 | 454 | ||
| 455 | if (cfids == NULL) | ||
| 456 | return; | ||
| 457 | |||
| 455 | spin_lock(&cfids->cfid_list_lock); | 458 | spin_lock(&cfids->cfid_list_lock); |
| 456 | list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { | 459 | list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { |
| 457 | list_move(&cfid->entry, &entry); | 460 | list_move(&cfid->entry, &entry); |
| @@ -651,6 +654,9 @@ void free_cached_dirs(struct cached_fids *cfids) · 193 unmodified lines | |||
| 651 | struct cached_fid *cfid, *q; | 654 | struct cached_fid *cfid, *q; |
| 652 | LIST_HEAD(entry); | 655 | LIST_HEAD(entry); |
| 653 | 656 | ||
| 657 | if (cfids == NULL) | ||
| 658 | return; | ||
| 659 | |||
| 654 | if (cfids->laundromat) { | 660 | if (cfids->laundromat) { |
| 655 | kthread_stop(cfids->laundromat); | 661 | kthread_stop(cfids->laundromat); |
| 656 | cfids->laundromat = NULL; | 662 | cfids->laundromat = NULL; |
| @@ -1807,6 +1807,7 @@ static inline bool is_retryable_error(int error) · 1806 unmodified lines | |||
| 1807 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ | 1807 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ |
| 1808 | #define MID_RESPONSE_MALFORMED 0x10 | 1808 | #define MID_RESPONSE_MALFORMED 0x10 |
| 1809 | #define MID_SHUTDOWN 0x20 | 1809 | #define MID_SHUTDOWN 0x20 |
| 1810 | #define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */ | ||
| 1810 | 1811 | ||
| 1811 | /* Flags */ | 1812 | /* Flags */ |
| 1812 | #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ | 1813 | #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ |
| @@ -1943,7 +1944,7 @@ require use of the stronger protocol */ · 130 unmodified lines | |||
| 1943 | * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once | 1944 | * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once |
| 1944 | * ->can_cache_brlcks | 1945 | * ->can_cache_brlcks |
| 1945 | * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc | 1946 | * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc |
| 1946 | * cached_fid->fid_mutex cifs_tcon->crfid tconInfoAlloc | 1947 | * cached_fid->fid_mutex cifs_tcon->crfid tcon_info_alloc |
| 1947 | * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo | 1948 | * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo |
| 1948 | * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo | 1949 | * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo |
| 1949 | * ->invalidHandle initiate_cifs_search | 1950 | * ->invalidHandle initiate_cifs_search |
| @@ -512,7 +512,7 @@ extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses); · 511 unmodified lines | |||
| 512 | 512 | ||
| 513 | extern struct cifs_ses *sesInfoAlloc(void); | 513 | extern struct cifs_ses *sesInfoAlloc(void); |
| 514 | extern void sesInfoFree(struct cifs_ses *); | 514 | extern void sesInfoFree(struct cifs_ses *); |
| 515 | extern struct cifs_tcon *tconInfoAlloc(void); | 515 | extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled); |
| 516 | extern void tconInfoFree(struct cifs_tcon *); | 516 | extern void tconInfoFree(struct cifs_tcon *); |
| 517 | 517 | ||
| 518 | extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server, | 518 | extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server, |
| @@ -1882,7 +1882,8 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx) · 1881 unmodified lines | |||
| 1882 | } | 1882 | } |
| 1883 | } | 1883 | } |
| 1884 | 1884 | ||
| 1885 | tcon = tconInfoAlloc(); | 1885 | /* no need to setup directory caching on IPC share, so pass in false */ |
| 1886 | tcon = tcon_info_alloc(false); | ||
| 1886 | if (tcon == NULL) | 1887 | if (tcon == NULL) |
| 1887 | return -ENOMEM; | 1888 | return -ENOMEM; |
| 1888 | 1889 | ||
| @@ -2492,7 +2493,10 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) · 603 unmodified lines | |||
| 2492 | goto out_fail; | 2493 | goto out_fail; |
| 2493 | } | 2494 | } |
| 2494 | 2495 | ||
| 2495 | tcon = tconInfoAlloc(); | 2496 | if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) |
| 2497 | tcon = tcon_info_alloc(true); | ||
| 2498 | else | ||
| 2499 | tcon = tcon_info_alloc(false); | ||
| 2496 | if (tcon == NULL) { | 2500 | if (tcon == NULL) { |
| 2497 | rc = -ENOMEM; | 2501 | rc = -ENOMEM; |
| 2498 | goto out_fail; | 2502 | goto out_fail; |
| @@ -1541,6 +1541,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, · 1540 unmodified lines | |||
| 1541 | 1541 | ||
| 1542 | cifs_parse_mount_err: | 1542 | cifs_parse_mount_err: |
| 1543 | kfree_sensitive(ctx->password); | 1543 | kfree_sensitive(ctx->password); |
| 1544 | ctx->password = NULL; | ||
| 1544 | return -EINVAL; | 1545 | return -EINVAL; |
| 1545 | } | 1546 | } |
| 1546 | 1547 | ||
| @@ -113,18 +113,22 @@ sesInfoFree(struct cifs_ses *buf_to_free) · 112 unmodified lines | |||
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | struct cifs_tcon * | 115 | struct cifs_tcon * |
| 116 | tconInfoAlloc(void) | 116 | tcon_info_alloc(bool dir_leases_enabled) |
| 117 | { | 117 | { |
| 118 | struct cifs_tcon *ret_buf; | 118 | struct cifs_tcon *ret_buf; |
| 119 | 119 | ||
| 120 | ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL); | 120 | ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL); |
| 121 | if (!ret_buf) | 121 | if (!ret_buf) |
| 122 | return NULL; | 122 | return NULL; |
| 123 | ret_buf->cfids = init_cached_dirs(); | 123 | |
| 124 | if (!ret_buf->cfids) { | 124 | if (dir_leases_enabled == true) { |
| 125 | kfree(ret_buf); | 125 | ret_buf->cfids = init_cached_dirs(); |
| 126 | return NULL; | 126 | if (!ret_buf->cfids) { |
| 127 | kfree(ret_buf); | ||
| 128 | return NULL; | ||
| 129 | } | ||
| 127 | } | 130 | } |
| 131 | /* else ret_buf->cfids is already set to NULL above */ | ||
| 128 | 132 | ||
| 129 | atomic_inc(&tconInfoAllocCount); | 133 | atomic_inc(&tconInfoAllocCount); |
| 130 | ret_buf->status = TID_NEW; | 134 | ret_buf->status = TID_NEW; |
| @@ -539,6 +539,9 @@ static int parse_create_response(struct cifs_open_info_data *data, · 538 unmodified lines | |||
| 539 | int rc = 0; | 539 | int rc = 0; |
| 540 | 540 | ||
| 541 | switch (rsp->hdr.Status) { | 541 | switch (rsp->hdr.Status) { |
| 542 | case STATUS_IO_REPARSE_TAG_NOT_HANDLED: | ||
| 543 | reparse_point = true; | ||
| 544 | break; | ||
| 542 | case STATUS_STOPPED_ON_SYMLINK: | 545 | case STATUS_STOPPED_ON_SYMLINK: |
| 543 | rc = smb2_parse_symlink_response(cifs_sb, iov, | 546 | rc = smb2_parse_symlink_response(cifs_sb, iov, |
| 544 | &data->symlink_target); | 547 | &data->symlink_target); |
| @@ -877,8 +877,6 @@ static const struct status_to_posix_error smb2_error_map_table[] = { · 876 unmodified lines | |||
| 877 | "STATUS_IO_REPARSE_TAG_MISMATCH"}, | 877 | "STATUS_IO_REPARSE_TAG_MISMATCH"}, |
| 878 | {STATUS_IO_REPARSE_DATA_INVALID, -EIO, | 878 | {STATUS_IO_REPARSE_DATA_INVALID, -EIO, |
| 879 | "STATUS_IO_REPARSE_DATA_INVALID"}, | 879 | "STATUS_IO_REPARSE_DATA_INVALID"}, |
| 880 | {STATUS_IO_REPARSE_TAG_NOT_HANDLED, -EIO, | ||
| 881 | "STATUS_IO_REPARSE_TAG_NOT_HANDLED"}, | ||
| 882 | {STATUS_REPARSE_POINT_NOT_RESOLVED, -EIO, | 880 | {STATUS_REPARSE_POINT_NOT_RESOLVED, -EIO, |
| 883 | "STATUS_REPARSE_POINT_NOT_RESOLVED"}, | 881 | "STATUS_REPARSE_POINT_NOT_RESOLVED"}, |
| 884 | {STATUS_DIRECTORY_IS_A_REPARSE_POINT, -EIO, | 882 | {STATUS_DIRECTORY_IS_A_REPARSE_POINT, -EIO, |
| @@ -848,7 +848,7 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) · 847 unmodified lines | |||
| 848 | 848 | ||
| 849 | iov[num].iov_base = create_posix_buf(mode); | 849 | iov[num].iov_base = create_posix_buf(mode); |
| 850 | if (mode == ACL_NO_MODE) | 850 | if (mode == ACL_NO_MODE) |
| 851 | cifs_dbg(FYI, "Invalid mode\n"); | 851 | cifs_dbg(FYI, "%s: no mode\n", __func__); |
| 852 | if (iov[num].iov_base == NULL) | 852 | if (iov[num].iov_base == NULL) |
| 853 | return -ENOMEM; | 853 | return -ENOMEM; |
| 854 | iov[num].iov_len = sizeof(struct create_posix); | 854 | iov[num].iov_len = sizeof(struct create_posix); |
| @@ -3878,7 +3878,7 @@ void smb2_reconnect_server(struct work_struct *work) · 3023 unmodified lines | |||
| 3878 | goto done; | 3878 | goto done; |
| 3879 | 3879 | ||
| 3880 | /* allocate a dummy tcon struct used for reconnect */ | 3880 | /* allocate a dummy tcon struct used for reconnect */ |
| 3881 | tcon = tconInfoAlloc(); | 3881 | tcon = tcon_info_alloc(false); |
| 3882 | if (!tcon) { | 3882 | if (!tcon) { |
| 3883 | resched = true; | 3883 | resched = true; |
| 3884 | list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) { | 3884 | list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) { |
| @@ -1401,10 +1401,13 @@ create_conn: · 1400 unmodified lines | |||
| 1401 | server->smbd_conn = smbd_get_connection( | 1401 | server->smbd_conn = smbd_get_connection( |
| 1402 | server, (struct sockaddr *) &server->dstaddr); | 1402 | server, (struct sockaddr *) &server->dstaddr); |
| 1403 | 1403 | ||
| 1404 | if (server->smbd_conn) | 1404 | if (server->smbd_conn) { |
| 1405 | cifs_dbg(VFS, "RDMA transport re-established\n"); | 1405 | cifs_dbg(VFS, "RDMA transport re-established\n"); |
| 1406 | 1406 | trace_smb3_smbd_connect_done(server->hostname, server->conn_id, &server->dstaddr); | |
| 1407 | return server->smbd_conn ? 0 : -ENOENT; | 1407 | return 0; |
| 1408 | } | ||
| 1409 | trace_smb3_smbd_connect_err(server->hostname, server->conn_id, &server->dstaddr); | ||
| 1410 | return -ENOENT; | ||
| 1408 | } | 1411 | } |
| 1409 | 1412 | ||
| 1410 | static void destroy_caches_and_workqueue(struct smbd_connection *info) | 1413 | static void destroy_caches_and_workqueue(struct smbd_connection *info) |
| @@ -935,6 +935,8 @@ DEFINE_EVENT(smb3_connect_class, smb3_##name, \ · 934 unmodified lines | |||
| 935 | TP_ARGS(hostname, conn_id, addr)) | 935 | TP_ARGS(hostname, conn_id, addr)) |
| 936 | 936 | ||
| 937 | DEFINE_SMB3_CONNECT_EVENT(connect_done); | 937 | DEFINE_SMB3_CONNECT_EVENT(connect_done); |
| 938 | DEFINE_SMB3_CONNECT_EVENT(smbd_connect_done); | ||
| 939 | DEFINE_SMB3_CONNECT_EVENT(smbd_connect_err); | ||
| 938 | 940 | ||
| 939 | DECLARE_EVENT_CLASS(smb3_connect_err_class, | 941 | DECLARE_EVENT_CLASS(smb3_connect_err_class, |
| 940 | TP_PROTO(char *hostname, __u64 conn_id, | 942 | TP_PROTO(char *hostname, __u64 conn_id, |
| @@ -35,6 +35,8 @@ · 34 unmodified lines | |||
| 35 | void | 35 | void |
| 36 | cifs_wake_up_task(struct mid_q_entry *mid) | 36 | cifs_wake_up_task(struct mid_q_entry *mid) |
| 37 | { | 37 | { |
| 38 | if (mid->mid_state == MID_RESPONSE_RECEIVED) | ||
| 39 | mid->mid_state = MID_RESPONSE_READY; | ||
| 38 | wake_up_process(mid->callback_data); | 40 | wake_up_process(mid->callback_data); |
| 39 | } | 41 | } |
| 40 | 42 | ||
| @@ -87,7 +89,8 @@ static void __release_mid(struct kref *refcount) · 46 unmodified lines | |||
| 87 | struct TCP_Server_Info *server = midEntry->server; | 89 | struct TCP_Server_Info *server = midEntry->server; |
| 88 | 90 | ||
| 89 | if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && | 91 | if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && |
| 90 | midEntry->mid_state == MID_RESPONSE_RECEIVED && | 92 | (midEntry->mid_state == MID_RESPONSE_RECEIVED || |
| 93 | midEntry->mid_state == MID_RESPONSE_READY) && | ||
| 91 | server->ops->handle_cancelled_mid) | 94 | server->ops->handle_cancelled_mid) |
| 92 | server->ops->handle_cancelled_mid(midEntry, server); | 95 | server->ops->handle_cancelled_mid(midEntry, server); |
| 93 | 96 | ||
| @@ -737,7 +740,8 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) · 643 unmodified lines | |||
| 737 | int error; | 740 | int error; |
| 738 | 741 | ||
| 739 | error = wait_event_state(server->response_q, | 742 | error = wait_event_state(server->response_q, |
| 740 | midQ->mid_state != MID_REQUEST_SUBMITTED, | 743 | midQ->mid_state != MID_REQUEST_SUBMITTED && |
| 744 | midQ->mid_state != MID_RESPONSE_RECEIVED, | ||
| 741 | (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); | 745 | (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); |
| 742 | if (error < 0) | 746 | if (error < 0) |
| 743 | return -ERESTARTSYS; | 747 | return -ERESTARTSYS; |
| @@ -890,7 +894,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) · 146 unmodified lines | |||
| 890 | 894 | ||
| 891 | spin_lock(&server->mid_lock); | 895 | spin_lock(&server->mid_lock); |
| 892 | switch (mid->mid_state) { | 896 | switch (mid->mid_state) { |
| 893 | case MID_RESPONSE_RECEIVED: | 897 | case MID_RESPONSE_READY: |
| 894 | spin_unlock(&server->mid_lock); | 898 | spin_unlock(&server->mid_lock); |
| 895 | return rc; | 899 | return rc; |
| 896 | case MID_RETRY_NEEDED: | 900 | case MID_RETRY_NEEDED: |
| @@ -989,6 +993,9 @@ cifs_compound_callback(struct mid_q_entry *mid) · 92 unmodified lines | |||
| 989 | credits.instance = server->reconnect_instance; | 993 | credits.instance = server->reconnect_instance; |
| 990 | 994 | ||
| 991 | add_credits(server, &credits, mid->optype); | 995 | add_credits(server, &credits, mid->optype); |
| 996 | |||
| 997 | if (mid->mid_state == MID_RESPONSE_RECEIVED) | ||
| 998 | mid->mid_state = MID_RESPONSE_READY; | ||
| 992 | } | 999 | } |
| 993 | 1000 | ||
| 994 | static void | 1001 | static void |
| @@ -1209,7 +1216,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 214 unmodified lines | |||
| 1209 | send_cancel(server, &rqst[i], midQ[i]); | 1216 | send_cancel(server, &rqst[i], midQ[i]); |
| 1210 | spin_lock(&server->mid_lock); | 1217 | spin_lock(&server->mid_lock); |
| 1211 | midQ[i]->mid_flags |= MID_WAIT_CANCELLED; | 1218 | midQ[i]->mid_flags |= MID_WAIT_CANCELLED; |
| 1212 | if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { | 1219 | if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED || |
| 1220 | midQ[i]->mid_state == MID_RESPONSE_RECEIVED) { | ||
| 1213 | midQ[i]->callback = cifs_cancelled_callback; | 1221 | midQ[i]->callback = cifs_cancelled_callback; |
| 1214 | cancelled_mid[i] = true; | 1222 | cancelled_mid[i] = true; |
| 1215 | credits[i].value = 0; | 1223 | credits[i].value = 0; |
| @@ -1230,7 +1238,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 14 unmodified lines | |||
| 1230 | } | 1238 | } |
| 1231 | 1239 | ||
| 1232 | if (!midQ[i]->resp_buf || | 1240 | if (!midQ[i]->resp_buf || |
| 1233 | midQ[i]->mid_state != MID_RESPONSE_RECEIVED) { | 1241 | midQ[i]->mid_state != MID_RESPONSE_READY) { |
| 1234 | rc = -EIO; | 1242 | rc = -EIO; |
| 1235 | cifs_dbg(FYI, "Bad MID state?\n"); | 1243 | cifs_dbg(FYI, "Bad MID state?\n"); |
| 1236 | goto out; | 1244 | goto out; |
| @@ -1417,7 +1425,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 180 unmodified lines | |||
| 1417 | if (rc != 0) { | 1425 | if (rc != 0) { |
| 1418 | send_cancel(server, &rqst, midQ); | 1426 | send_cancel(server, &rqst, midQ); |
| 1419 | spin_lock(&server->mid_lock); | 1427 | spin_lock(&server->mid_lock); |
| 1420 | if (midQ->mid_state == MID_REQUEST_SUBMITTED) { | 1428 | if (midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1429 | midQ->mid_state == MID_RESPONSE_RECEIVED) { | ||
| 1421 | /* no longer considered to be "in-flight" */ | 1430 | /* no longer considered to be "in-flight" */ |
| 1422 | midQ->callback = release_mid; | 1431 | midQ->callback = release_mid; |
| 1423 | spin_unlock(&server->mid_lock); | 1432 | spin_unlock(&server->mid_lock); |
| @@ -1434,7 +1443,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 10 unmodified lines | |||
| 1434 | } | 1443 | } |
| 1435 | 1444 | ||
| 1436 | if (!midQ->resp_buf || !out_buf || | 1445 | if (!midQ->resp_buf || !out_buf || |
| 1437 | midQ->mid_state != MID_RESPONSE_RECEIVED) { | 1446 | midQ->mid_state != MID_RESPONSE_READY) { |
| 1438 | rc = -EIO; | 1447 | rc = -EIO; |
| 1439 | cifs_server_dbg(VFS, "Bad MID state?\n"); | 1448 | cifs_server_dbg(VFS, "Bad MID state?\n"); |
| 1440 | goto out; | 1449 | goto out; |
| @@ -1558,14 +1567,16 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 117 unmodified lines | |||
| 1558 | 1567 | ||
| 1559 | /* Wait for a reply - allow signals to interrupt. */ | 1568 | /* Wait for a reply - allow signals to interrupt. */ |
| 1560 | rc = wait_event_interruptible(server->response_q, | 1569 | rc = wait_event_interruptible(server->response_q, |
| 1561 | (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || | 1570 | (!(midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1571 | midQ->mid_state == MID_RESPONSE_RECEIVED)) || | ||
| 1562 | ((server->tcpStatus != CifsGood) && | 1572 | ((server->tcpStatus != CifsGood) && |
| 1563 | (server->tcpStatus != CifsNew))); | 1573 | (server->tcpStatus != CifsNew))); |
| 1564 | 1574 | ||
| 1565 | /* Were we interrupted by a signal ? */ | 1575 | /* Were we interrupted by a signal ? */ |
| 1566 | spin_lock(&server->srv_lock); | 1576 | spin_lock(&server->srv_lock); |
| 1567 | if ((rc == -ERESTARTSYS) && | 1577 | if ((rc == -ERESTARTSYS) && |
| 1568 | (midQ->mid_state == MID_REQUEST_SUBMITTED) && | 1578 | (midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1579 | midQ->mid_state == MID_RESPONSE_RECEIVED) && | ||
| 1569 | ((server->tcpStatus == CifsGood) || | 1580 | ((server->tcpStatus == CifsGood) || |
| 1570 | (server->tcpStatus == CifsNew))) { | 1581 | (server->tcpStatus == CifsNew))) { |
| 1571 | spin_unlock(&server->srv_lock); | 1582 | spin_unlock(&server->srv_lock); |
| @@ -1596,7 +1607,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 24 unmodified lines | |||
| 1596 | if (rc) { | 1607 | if (rc) { |
| 1597 | send_cancel(server, &rqst, midQ); | 1608 | send_cancel(server, &rqst, midQ); |
| 1598 | spin_lock(&server->mid_lock); | 1609 | spin_lock(&server->mid_lock); |
| 1599 | if (midQ->mid_state == MID_REQUEST_SUBMITTED) { | 1610 | if (midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1611 | midQ->mid_state == MID_RESPONSE_RECEIVED) { | ||
| 1600 | /* no longer considered to be "in-flight" */ | 1612 | /* no longer considered to be "in-flight" */ |
| 1601 | midQ->callback = release_mid; | 1613 | midQ->callback = release_mid; |
| 1602 | spin_unlock(&server->mid_lock); | 1614 | spin_unlock(&server->mid_lock); |
| @@ -1616,7 +1628,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 13 unmodified lines | |||
| 1616 | return rc; | 1628 | return rc; |
| 1617 | 1629 | ||
| 1618 | /* rcvd frame is ok */ | 1630 | /* rcvd frame is ok */ |
| 1619 | if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { | 1631 | if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) { |
| 1620 | rc = -EIO; | 1632 | rc = -EIO; |
| 1621 | cifs_tcon_dbg(VFS, "Bad MID state?\n"); | 1633 | cifs_tcon_dbg(VFS, "Bad MID state?\n"); |
| 1622 | goto out; | 1634 | goto out; |
| @@ -197,6 +197,9 @@ int ksmbd_conn_write(struct ksmbd_work *work) · 196 unmodified lines | |||
| 197 | if (work->send_no_response) | 197 | if (work->send_no_response) |
| 198 | return 0; | 198 | return 0; |
| 199 | 199 | ||
| 200 | if (!work->iov_idx) | ||
| 201 | return -EINVAL; | ||
| 202 | |||
| 200 | ksmbd_conn_lock(conn); | 203 | ksmbd_conn_lock(conn); |
| 201 | sent = conn->transport->ops->writev(conn->transport, work->iov, | 204 | sent = conn->transport->ops->writev(conn->transport, work->iov, |
| 202 | work->iov_cnt, | 205 | work->iov_cnt, |
| @@ -115,8 +115,10 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, · 114 unmodified lines | |||
| 115 | if (check_conn_state(work)) | 115 | if (check_conn_state(work)) |
| 116 | return SERVER_HANDLER_CONTINUE; | 116 | return SERVER_HANDLER_CONTINUE; |
| 117 | 117 | ||
| 118 | if (ksmbd_verify_smb_message(work)) | 118 | if (ksmbd_verify_smb_message(work)) { |
| 119 | conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); | ||
| 119 | return SERVER_HANDLER_ABORT; | 120 | return SERVER_HANDLER_ABORT; |
| 121 | } | ||
| 120 | 122 | ||
| 121 | command = conn->ops->get_cmd_val(work); | 123 | command = conn->ops->get_cmd_val(work); |
| 122 | *cmd = command; | 124 | *cmd = command; |
| @@ -440,10 +440,8 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) · 439 unmodified lines | |||
| 440 | 440 | ||
| 441 | validate_credit: | 441 | validate_credit: |
| 442 | if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && | 442 | if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && |
| 443 | smb2_validate_credit_charge(work->conn, hdr)) { | 443 | smb2_validate_credit_charge(work->conn, hdr)) |
| 444 | work->conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); | ||
| 445 | return 1; | 444 | return 1; |
| 446 | } | ||
| 447 | 445 | ||
| 448 | return 0; | 446 | return 0; |
| 449 | } | 447 | } |
| @@ -70,6 +70,7 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, · 69 unmodified lines | |||
| 70 | struct dentry *dentry, | 70 | struct dentry *dentry, |
| 71 | unsigned int flags); | 71 | unsigned int flags); |
| 72 | static int dcache_dir_open_wrapper(struct inode *inode, struct file *file); | 72 | static int dcache_dir_open_wrapper(struct inode *inode, struct file *file); |
| 73 | static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx); | ||
| 73 | static int eventfs_release(struct inode *inode, struct file *file); | 74 | static int eventfs_release(struct inode *inode, struct file *file); |
| 74 | 75 | ||
| 75 | static const struct inode_operations eventfs_root_dir_inode_operations = { | 76 | static const struct inode_operations eventfs_root_dir_inode_operations = { |
| @@ -79,7 +80,7 @@ static const struct inode_operations eventfs_root_dir_inode_operations = { · 3 unmodified lines | |||
| 79 | static const struct file_operations eventfs_file_operations = { | 80 | static const struct file_operations eventfs_file_operations = { |
| 80 | .open = dcache_dir_open_wrapper, | 81 | .open = dcache_dir_open_wrapper, |
| 81 | .read = generic_read_dir, | 82 | .read = generic_read_dir, |
| 82 | .iterate_shared = dcache_readdir, | 83 | .iterate_shared = dcache_readdir_wrapper, |
| 83 | .llseek = generic_file_llseek, | 84 | .llseek = generic_file_llseek, |
| 84 | .release = eventfs_release, | 85 | .release = eventfs_release, |
| 85 | }; | 86 | }; |
| @@ -396,6 +397,11 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, · 310 unmodified lines | |||
| 396 | return ret; | 397 | return ret; |
| 397 | } | 398 | } |
| 398 | 399 | ||
| 400 | struct dentry_list { | ||
| 401 | void *cursor; | ||
| 402 | struct dentry **dentries; | ||
| 403 | }; | ||
| 404 | |||
| 399 | /** | 405 | /** |
| 400 | * eventfs_release - called to release eventfs file/dir | 406 | * eventfs_release - called to release eventfs file/dir |
| 401 | * @inode: inode to be released | 407 | * @inode: inode to be released |
| @@ -404,26 +410,25 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, · 2 unmodified lines | |||
| 404 | static int eventfs_release(struct inode *inode, struct file *file) | 410 | static int eventfs_release(struct inode *inode, struct file *file) |
| 405 | { | 411 | { |
| 406 | struct tracefs_inode *ti; | 412 | struct tracefs_inode *ti; |
| 407 | struct eventfs_inode *ei; | 413 | struct dentry_list *dlist = file->private_data; |
| 408 | struct eventfs_file *ef; | 414 | void *cursor; |
| 409 | struct dentry *dentry; | 415 | int i; |
| 410 | int idx; | ||
| 411 | 416 | ||
| 412 | ti = get_tracefs(inode); | 417 | ti = get_tracefs(inode); |
| 413 | if (!(ti->flags & TRACEFS_EVENT_INODE)) | 418 | if (!(ti->flags & TRACEFS_EVENT_INODE)) |
| 414 | return -EINVAL; | 419 | return -EINVAL; |
| 415 | 420 | ||
| 416 | ei = ti->private; | 421 | if (WARN_ON_ONCE(!dlist)) |
| 417 | idx = srcu_read_lock(&eventfs_srcu); | 422 | return -EINVAL; |
| 418 | list_for_each_entry_srcu(ef, &ei->e_top_files, list, | 423 | |
| 419 | srcu_read_lock_held(&eventfs_srcu)) { | 424 | for (i = 0; dlist->dentries && dlist->dentries[i]; i++) { |
| 420 | mutex_lock(&eventfs_mutex); | 425 | dput(dlist->dentries[i]); |
| 421 | dentry = ef->dentry; | ||
| 422 | mutex_unlock(&eventfs_mutex); | ||
| 423 | if (dentry) | ||
| 424 | dput(dentry); | ||
| 425 | } | 426 | } |
| 426 | srcu_read_unlock(&eventfs_srcu, idx); | 427 | |
| 428 | cursor = dlist->cursor; | ||
| 429 | kfree(dlist->dentries); | ||
| 430 | kfree(dlist); | ||
| 431 | file->private_data = cursor; | ||
| 427 | return dcache_dir_close(inode, file); | 432 | return dcache_dir_close(inode, file); |
| 428 | } | 433 | } |
| 429 | 434 | ||
| @@ -442,22 +447,70 @@ static int dcache_dir_open_wrapper(struct inode *inode, struct file *file) · 12 unmodified lines | |||
| 442 | struct tracefs_inode *ti; | 447 | struct tracefs_inode *ti; |
| 443 | struct eventfs_inode *ei; | 448 | struct eventfs_inode *ei; |
| 444 | struct eventfs_file *ef; | 449 | struct eventfs_file *ef; |
| 450 | struct dentry_list *dlist; | ||
| 451 | struct dentry **dentries = NULL; | ||
| 445 | struct dentry *dentry = file_dentry(file); | 452 | struct dentry *dentry = file_dentry(file); |
| 453 | struct dentry *d; | ||
| 446 | struct inode *f_inode = file_inode(file); | 454 | struct inode *f_inode = file_inode(file); |
| 455 | int cnt = 0; | ||
| 447 | int idx; | 456 | int idx; |
| 457 | int ret; | ||
| 448 | 458 | ||
| 449 | ti = get_tracefs(f_inode); | 459 | ti = get_tracefs(f_inode); |
| 450 | if (!(ti->flags & TRACEFS_EVENT_INODE)) | 460 | if (!(ti->flags & TRACEFS_EVENT_INODE)) |
| 451 | return -EINVAL; | 461 | return -EINVAL; |
| 452 | 462 | ||
| 463 | if (WARN_ON_ONCE(file->private_data)) | ||
| 464 | return -EINVAL; | ||
| 465 | |||
| 466 | dlist = kmalloc(sizeof(*dlist), GFP_KERNEL); | ||
| 467 | if (!dlist) | ||
| 468 | return -ENOMEM; | ||
| 469 | |||
| 453 | ei = ti->private; | 470 | ei = ti->private; |
| 454 | idx = srcu_read_lock(&eventfs_srcu); | 471 | idx = srcu_read_lock(&eventfs_srcu); |
| 455 | list_for_each_entry_srcu(ef, &ei->e_top_files, list, | 472 | list_for_each_entry_srcu(ef, &ei->e_top_files, list, |
| 456 | srcu_read_lock_held(&eventfs_srcu)) { | 473 | srcu_read_lock_held(&eventfs_srcu)) { |
| 457 | create_dentry(ef, dentry, false); | 474 | d = create_dentry(ef, dentry, false); |
| 475 | if (d) { | ||
| 476 | struct dentry **tmp; | ||
| 477 | |||
| 478 | tmp = krealloc(dentries, sizeof(d) * (cnt + 2), GFP_KERNEL); | ||
| 479 | if (!tmp) | ||
| 480 | break; | ||
| 481 | tmp[cnt] = d; | ||
| 482 | tmp[cnt + 1] = NULL; | ||
| 483 | cnt++; | ||
| 484 | dentries = tmp; | ||
| 485 | } | ||
| 458 | } | 486 | } |
| 459 | srcu_read_unlock(&eventfs_srcu, idx); | 487 | srcu_read_unlock(&eventfs_srcu, idx); |
| 460 | return dcache_dir_open(inode, file); | 488 | ret = dcache_dir_open(inode, file); |
| 489 | |||
| 490 | /* | ||
| 491 | * dcache_dir_open() sets file->private_data to a dentry cursor. | ||
| 492 | * Need to save that but also save all the dentries that were | ||
| 493 | * opened by this function. | ||
| 494 | */ | ||
| 495 | dlist->cursor = file->private_data; | ||
| 496 | dlist->dentries = dentries; | ||
| 497 | file->private_data = dlist; | ||
| 498 | return ret; | ||
| 499 | } | ||
| 500 | |||
| 501 | /* | ||
| 502 | * This just sets the file->private_data back to the cursor and back. | ||
| 503 | */ | ||
| 504 | static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx) | ||
| 505 | { | ||
| 506 | struct dentry_list *dlist = file->private_data; | ||
| 507 | int ret; | ||
| 508 | |||
| 509 | file->private_data = dlist->cursor; | ||
| 510 | ret = dcache_readdir(file, ctx); | ||
| 511 | dlist->cursor = file->private_data; | ||
| 512 | file->private_data = dlist; | ||
| 513 | return ret; | ||
| 461 | } | 514 | } |
| 462 | 515 | ||
| 463 | /** | 516 | /** |
| @@ -147,7 +147,7 @@ config XFS_ONLINE_SCRUB_STATS · 146 unmodified lines | |||
| 147 | bool "XFS online metadata check usage data collection" | 147 | bool "XFS online metadata check usage data collection" |
| 148 | default y | 148 | default y |
| 149 | depends on XFS_ONLINE_SCRUB | 149 | depends on XFS_ONLINE_SCRUB |
| 150 | select FS_DEBUG | 150 | select XFS_DEBUG |
| 151 | help | 151 | help |
| 152 | If you say Y here, the kernel will gather usage data about | 152 | If you say Y here, the kernel will gather usage data about |
| 153 | the online metadata check subsystem. This includes the number | 153 | the online metadata check subsystem. This includes the number |
| @@ -131,4 +131,26 @@ void xlog_check_buf_cancel_table(struct xlog *log); · 130 unmodified lines | |||
| 131 | #define xlog_check_buf_cancel_table(log) do { } while (0) | 131 | #define xlog_check_buf_cancel_table(log) do { } while (0) |
| 132 | #endif | 132 | #endif |
| 133 | 133 | ||
| 134 | /* | ||
| 135 | * Transform a regular reservation into one suitable for recovery of a log | ||
| 136 | * intent item. | ||
| 137 | * | ||
| 138 | * Intent recovery only runs a single step of the transaction chain and defers | ||
| 139 | * the rest to a separate transaction. Therefore, we reduce logcount to 1 here | ||
| 140 | * to avoid livelocks if the log grant space is nearly exhausted due to the | ||
| 141 | * recovered intent pinning the tail. Keep the same logflags to avoid tripping | ||
| 142 | * asserts elsewhere. Struct copies abound below. | ||
| 143 | */ | ||
| 144 | static inline struct xfs_trans_res | ||
| 145 | xlog_recover_resv(const struct xfs_trans_res *r) | ||
| 146 | { | ||
| 147 | struct xfs_trans_res ret = { | ||
| 148 | .tr_logres = r->tr_logres, | ||
| 149 | .tr_logcount = 1, | ||
| 150 | .tr_logflags = r->tr_logflags, | ||
| 151 | }; | ||
| 152 | |||
| 153 | return ret; | ||
| 154 | } | ||
| 155 | |||
| 134 | #endif /* __XFS_LOG_RECOVER_H__ */ | 156 | #endif /* __XFS_LOG_RECOVER_H__ */ |
| @@ -266,7 +266,8 @@ xfs_validate_sb_write( · 265 unmodified lines | |||
| 266 | return -EFSCORRUPTED; | 266 | return -EFSCORRUPTED; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | if (xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { | 269 | if (!xfs_is_readonly(mp) && |
| 270 | xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { | ||
| 270 | xfs_alert(mp, | 271 | xfs_alert(mp, |
| 271 | "Corruption detected in superblock read-only compatible features (0x%x)!", | 272 | "Corruption detected in superblock read-only compatible features (0x%x)!", |
| 272 | (sbp->sb_features_ro_compat & | 273 | (sbp->sb_features_ro_compat & |
| @@ -588,6 +588,8 @@ out_nofix: · 587 unmodified lines | |||
| 588 | out_teardown: | 588 | out_teardown: |
| 589 | error = xchk_teardown(sc, error); | 589 | error = xchk_teardown(sc, error); |
| 590 | out_sc: | 590 | out_sc: |
| 591 | if (error != -ENOENT) | ||
| 592 | xchk_stats_merge(mp, sm, &run); | ||
| 591 | kfree(sc); | 593 | kfree(sc); |
| 592 | out: | 594 | out: |
| 593 | trace_xchk_done(XFS_I(file_inode(file)), sm, error); | 595 | trace_xchk_done(XFS_I(file_inode(file)), sm, error); |
| @@ -595,8 +597,6 @@ out: · 1 unmodified line | |||
| 595 | sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; | 597 | sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; |
| 596 | error = 0; | 598 | error = 0; |
| 597 | } | 599 | } |
| 598 | if (error != -ENOENT) | ||
| 599 | xchk_stats_merge(mp, sm, &run); | ||
| 600 | return error; | 600 | return error; |
| 601 | need_drain: | 601 | need_drain: |
| 602 | error = xchk_teardown(sc, 0); | 602 | error = xchk_teardown(sc, 0); |
| @@ -185,7 +185,10 @@ xchk_stats_merge_one( · 184 unmodified lines | |||
| 185 | { | 185 | { |
| 186 | struct xchk_scrub_stats *css; | 186 | struct xchk_scrub_stats *css; |
| 187 | 187 | ||
| 188 | ASSERT(sm->sm_type < XFS_SCRUB_TYPE_NR); | 188 | if (sm->sm_type >= XFS_SCRUB_TYPE_NR) { |
| 189 | ASSERT(sm->sm_type < XFS_SCRUB_TYPE_NR); | ||
| 190 | return; | ||
| 191 | } | ||
| 189 | 192 | ||
| 190 | css = &cs->cs_stats[sm->sm_type]; | 193 | css = &cs->cs_stats[sm->sm_type]; |
| 191 | spin_lock(&css->css_lock); | 194 | spin_lock(&css->css_lock); |
| @@ -333,7 +333,6 @@ xfs_attr_inactive( · 332 unmodified lines | |||
| 333 | int error = 0; | 333 | int error = 0; |
| 334 | 334 | ||
| 335 | mp = dp->i_mount; | 335 | mp = dp->i_mount; |
| 336 | ASSERT(! XFS_NOT_DQATTACHED(mp, dp)); | ||
| 337 | 336 | ||
| 338 | xfs_ilock(dp, lock_mode); | 337 | xfs_ilock(dp, lock_mode); |
| 339 | if (!xfs_inode_has_attr_fork(dp)) | 338 | if (!xfs_inode_has_attr_fork(dp)) |
| @@ -547,7 +547,7 @@ xfs_attri_item_recover( · 546 unmodified lines | |||
| 547 | struct xfs_inode *ip; | 547 | struct xfs_inode *ip; |
| 548 | struct xfs_da_args *args; | 548 | struct xfs_da_args *args; |
| 549 | struct xfs_trans *tp; | 549 | struct xfs_trans *tp; |
| 550 | struct xfs_trans_res tres; | 550 | struct xfs_trans_res resv; |
| 551 | struct xfs_attri_log_format *attrp; | 551 | struct xfs_attri_log_format *attrp; |
| 552 | struct xfs_attri_log_nameval *nv = attrip->attri_nameval; | 552 | struct xfs_attri_log_nameval *nv = attrip->attri_nameval; |
| 553 | int error; | 553 | int error; |
| @@ -618,8 +618,9 @@ xfs_attri_item_recover( · 64 unmodified lines | |||
| 618 | goto out; | 618 | goto out; |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | xfs_init_attr_trans(args, &tres, &total); | 621 | xfs_init_attr_trans(args, &resv, &total); |
| 622 | error = xfs_trans_alloc(mp, &tres, total, 0, XFS_TRANS_RESERVE, &tp); | 622 | resv = xlog_recover_resv(&resv); |
| 623 | error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp); | ||
| 623 | if (error) | 624 | if (error) |
| 624 | goto out; | 625 | goto out; |
| 625 | 626 | ||
| @@ -490,6 +490,7 @@ xfs_bui_item_recover( · 489 unmodified lines | |||
| 490 | struct list_head *capture_list) | 490 | struct list_head *capture_list) |
| 491 | { | 491 | { |
| 492 | struct xfs_bmap_intent fake = { }; | 492 | struct xfs_bmap_intent fake = { }; |
| 493 | struct xfs_trans_res resv; | ||
| 493 | struct xfs_bui_log_item *buip = BUI_ITEM(lip); | 494 | struct xfs_bui_log_item *buip = BUI_ITEM(lip); |
| 494 | struct xfs_trans *tp; | 495 | struct xfs_trans *tp; |
| 495 | struct xfs_inode *ip = NULL; | 496 | struct xfs_inode *ip = NULL; |
| @@ -515,7 +516,8 @@ xfs_bui_item_recover( · 19 unmodified lines | |||
| 515 | return error; | 516 | return error; |
| 516 | 517 | ||
| 517 | /* Allocate transaction and do the work. */ | 518 | /* Allocate transaction and do the work. */ |
| 518 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, | 519 | resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); |
| 520 | error = xfs_trans_alloc(mp, &resv, | ||
| 519 | XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); | 521 | XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); |
| 520 | if (error) | 522 | if (error) |
| 521 | goto err_rele; | 523 | goto err_rele; |
| @@ -146,6 +146,20 @@ xfs_nfs_get_inode( · 145 unmodified lines | |||
| 146 | return ERR_PTR(error); | 146 | return ERR_PTR(error); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | /* | ||
| 150 | * Reload the incore unlinked list to avoid failure in inodegc. | ||
| 151 | * Use an unlocked check here because unrecovered unlinked inodes | ||
| 152 | * should be somewhat rare. | ||
| 153 | */ | ||
| 154 | if (xfs_inode_unlinked_incomplete(ip)) { | ||
| 155 | error = xfs_inode_reload_unlinked(ip); | ||
| 156 | if (error) { | ||
| 157 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
| 158 | xfs_irele(ip); | ||
| 159 | return ERR_PTR(error); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 149 | if (VFS_I(ip)->i_generation != generation) { | 163 | if (VFS_I(ip)->i_generation != generation) { |
| 150 | xfs_irele(ip); | 164 | xfs_irele(ip); |
| 151 | return ERR_PTR(-ESTALE); | 165 | return ERR_PTR(-ESTALE); |
| @@ -660,6 +660,7 @@ xfs_efi_item_recover( · 659 unmodified lines | |||
| 660 | struct xfs_log_item *lip, | 660 | struct xfs_log_item *lip, |
| 661 | struct list_head *capture_list) | 661 | struct list_head *capture_list) |
| 662 | { | 662 | { |
| 663 | struct xfs_trans_res resv; | ||
| 663 | struct xfs_efi_log_item *efip = EFI_ITEM(lip); | 664 | struct xfs_efi_log_item *efip = EFI_ITEM(lip); |
| 664 | struct xfs_mount *mp = lip->li_log->l_mp; | 665 | struct xfs_mount *mp = lip->li_log->l_mp; |
| 665 | struct xfs_efd_log_item *efdp; | 666 | struct xfs_efd_log_item *efdp; |
| @@ -683,7 +684,8 @@ xfs_efi_item_recover( · 17 unmodified lines | |||
| 683 | } | 684 | } |
| 684 | } | 685 | } |
| 685 | 686 | ||
| 686 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); | 687 | resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); |
| 688 | error = xfs_trans_alloc(mp, &resv, 0, 0, 0, &tp); | ||
| 687 | if (error) | 689 | if (error) |
| 688 | return error; | 690 | return error; |
| 689 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); | 691 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); |
| @@ -565,6 +565,19 @@ err: · 564 unmodified lines | |||
| 565 | } | 565 | } |
| 566 | #endif /* CONFIG_XFS_RT */ | 566 | #endif /* CONFIG_XFS_RT */ |
| 567 | 567 | ||
| 568 | static inline bool | ||
| 569 | rmap_not_shareable(struct xfs_mount *mp, const struct xfs_rmap_irec *r) | ||
| 570 | { | ||
| 571 | if (!xfs_has_reflink(mp)) | ||
| 572 | return true; | ||
| 573 | if (XFS_RMAP_NON_INODE_OWNER(r->rm_owner)) | ||
| 574 | return true; | ||
| 575 | if (r->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK | | ||
| 576 | XFS_RMAP_UNWRITTEN)) | ||
| 577 | return true; | ||
| 578 | return false; | ||
| 579 | } | ||
| 580 | |||
| 568 | /* Execute a getfsmap query against the regular data device. */ | 581 | /* Execute a getfsmap query against the regular data device. */ |
| 569 | STATIC int | 582 | STATIC int |
| 570 | __xfs_getfsmap_datadev( | 583 | __xfs_getfsmap_datadev( |
| @@ -598,7 +611,6 @@ __xfs_getfsmap_datadev( · 27 unmodified lines | |||
| 598 | * low to the fsmap low key and max out the high key to the end | 611 | * low to the fsmap low key and max out the high key to the end |
| 599 | * of the AG. | 612 | * of the AG. |
| 600 | */ | 613 | */ |
| 601 | info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb); | ||
| 602 | info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); | 614 | info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); |
| 603 | error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); | 615 | error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); |
| 604 | if (error) | 616 | if (error) |
| @@ -608,12 +620,9 @@ __xfs_getfsmap_datadev( · 3 unmodified lines | |||
| 608 | 620 | ||
| 609 | /* Adjust the low key if we are continuing from where we left off. */ | 621 | /* Adjust the low key if we are continuing from where we left off. */ |
| 610 | if (info->low.rm_blockcount == 0) { | 622 | if (info->low.rm_blockcount == 0) { |
| 611 | /* empty */ | 623 | /* No previous record from which to continue */ |
| 612 | } else if (XFS_RMAP_NON_INODE_OWNER(info->low.rm_owner) || | 624 | } else if (rmap_not_shareable(mp, &info->low)) { |
| 613 | (info->low.rm_flags & (XFS_RMAP_ATTR_FORK | | 625 | /* Last record seen was an unshareable extent */ |
| 614 | XFS_RMAP_BMBT_BLOCK | | ||
| 615 | XFS_RMAP_UNWRITTEN))) { | ||
| 616 | info->low.rm_startblock += info->low.rm_blockcount; | ||
| 617 | info->low.rm_owner = 0; | 626 | info->low.rm_owner = 0; |
| 618 | info->low.rm_offset = 0; | 627 | info->low.rm_offset = 0; |
| 619 | 628 | ||
| @@ -621,8 +630,10 @@ __xfs_getfsmap_datadev( · 1 unmodified line | |||
| 621 | if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs) | 630 | if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs) |
| 622 | return 0; | 631 | return 0; |
| 623 | } else { | 632 | } else { |
| 633 | /* Last record seen was a shareable file data extent */ | ||
| 624 | info->low.rm_offset += info->low.rm_blockcount; | 634 | info->low.rm_offset += info->low.rm_blockcount; |
| 625 | } | 635 | } |
| 636 | info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb); | ||
| 626 | 637 | ||
| 627 | info->high.rm_startblock = -1U; | 638 | info->high.rm_startblock = -1U; |
| 628 | info->high.rm_owner = ULLONG_MAX; | 639 | info->high.rm_owner = ULLONG_MAX; |
| @@ -113,7 +113,7 @@ xfs_inode_alloc( · 112 unmodified lines | |||
| 113 | INIT_LIST_HEAD(&ip->i_ioend_list); | 113 | INIT_LIST_HEAD(&ip->i_ioend_list); |
| 114 | spin_lock_init(&ip->i_ioend_lock); | 114 | spin_lock_init(&ip->i_ioend_lock); |
| 115 | ip->i_next_unlinked = NULLAGINO; | 115 | ip->i_next_unlinked = NULLAGINO; |
| 116 | ip->i_prev_unlinked = NULLAGINO; | 116 | ip->i_prev_unlinked = 0; |
| 117 | 117 | ||
| 118 | return ip; | 118 | return ip; |
| 119 | } | 119 | } |
| @@ -443,7 +443,7 @@ xfs_inodegc_queue_all( · 323 unmodified lines | |||
| 443 | int cpu; | 443 | int cpu; |
| 444 | bool ret = false; | 444 | bool ret = false; |
| 445 | 445 | ||
| 446 | for_each_online_cpu(cpu) { | 446 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 447 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 447 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| 448 | if (!llist_empty(&gc->list)) { | 448 | if (!llist_empty(&gc->list)) { |
| 449 | mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); | 449 | mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); |
| @@ -463,7 +463,7 @@ xfs_inodegc_wait_all( · 13 unmodified lines | |||
| 463 | int error = 0; | 463 | int error = 0; |
| 464 | 464 | ||
| 465 | flush_workqueue(mp->m_inodegc_wq); | 465 | flush_workqueue(mp->m_inodegc_wq); |
| 466 | for_each_online_cpu(cpu) { | 466 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 467 | struct xfs_inodegc *gc; | 467 | struct xfs_inodegc *gc; |
| 468 | 468 | ||
| 469 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 469 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| @@ -1845,9 +1845,17 @@ xfs_inodegc_worker( · 1375 unmodified lines | |||
| 1845 | struct xfs_inodegc, work); | 1845 | struct xfs_inodegc, work); |
| 1846 | struct llist_node *node = llist_del_all(&gc->list); | 1846 | struct llist_node *node = llist_del_all(&gc->list); |
| 1847 | struct xfs_inode *ip, *n; | 1847 | struct xfs_inode *ip, *n; |
| 1848 | struct xfs_mount *mp = gc->mp; | ||
| 1848 | unsigned int nofs_flag; | 1849 | unsigned int nofs_flag; |
| 1849 | 1850 | ||
| 1850 | ASSERT(gc->cpu == smp_processor_id()); | 1851 | /* |
| 1852 | * Clear the cpu mask bit and ensure that we have seen the latest | ||
| 1853 | * update of the gc structure associated with this CPU. This matches | ||
| 1854 | * with the release semantics used when setting the cpumask bit in | ||
| 1855 | * xfs_inodegc_queue. | ||
| 1856 | */ | ||
| 1857 | cpumask_clear_cpu(gc->cpu, &mp->m_inodegc_cpumask); | ||
| 1858 | smp_mb__after_atomic(); | ||
| 1851 | 1859 | ||
| 1852 | WRITE_ONCE(gc->items, 0); | 1860 | WRITE_ONCE(gc->items, 0); |
| 1853 | 1861 | ||
| @@ -1862,7 +1870,7 @@ xfs_inodegc_worker( · 8 unmodified lines | |||
| 1862 | nofs_flag = memalloc_nofs_save(); | 1870 | nofs_flag = memalloc_nofs_save(); |
| 1863 | 1871 | ||
| 1864 | ip = llist_entry(node, struct xfs_inode, i_gclist); | 1872 | ip = llist_entry(node, struct xfs_inode, i_gclist); |
| 1865 | trace_xfs_inodegc_worker(ip->i_mount, READ_ONCE(gc->shrinker_hits)); | 1873 | trace_xfs_inodegc_worker(mp, READ_ONCE(gc->shrinker_hits)); |
| 1866 | 1874 | ||
| 1867 | WRITE_ONCE(gc->shrinker_hits, 0); | 1875 | WRITE_ONCE(gc->shrinker_hits, 0); |
| 1868 | llist_for_each_entry_safe(ip, n, node, i_gclist) { | 1876 | llist_for_each_entry_safe(ip, n, node, i_gclist) { |
| @@ -2057,6 +2065,7 @@ xfs_inodegc_queue( · 188 unmodified lines | |||
| 2057 | struct xfs_inodegc *gc; | 2065 | struct xfs_inodegc *gc; |
| 2058 | int items; | 2066 | int items; |
| 2059 | unsigned int shrinker_hits; | 2067 | unsigned int shrinker_hits; |
| 2068 | unsigned int cpu_nr; | ||
| 2060 | unsigned long queue_delay = 1; | 2069 | unsigned long queue_delay = 1; |
| 2061 | 2070 | ||
| 2062 | trace_xfs_inode_set_need_inactive(ip); | 2071 | trace_xfs_inode_set_need_inactive(ip); |
| @@ -2064,18 +2073,28 @@ xfs_inodegc_queue( · 1 unmodified line | |||
| 2064 | ip->i_flags |= XFS_NEED_INACTIVE; | 2073 | ip->i_flags |= XFS_NEED_INACTIVE; |
| 2065 | spin_unlock(&ip->i_flags_lock); | 2074 | spin_unlock(&ip->i_flags_lock); |
| 2066 | 2075 | ||
| 2067 | gc = get_cpu_ptr(mp->m_inodegc); | 2076 | cpu_nr = get_cpu(); |
| 2077 | gc = this_cpu_ptr(mp->m_inodegc); | ||
| 2068 | llist_add(&ip->i_gclist, &gc->list); | 2078 | llist_add(&ip->i_gclist, &gc->list); |
| 2069 | items = READ_ONCE(gc->items); | 2079 | items = READ_ONCE(gc->items); |
| 2070 | WRITE_ONCE(gc->items, items + 1); | 2080 | WRITE_ONCE(gc->items, items + 1); |
| 2071 | shrinker_hits = READ_ONCE(gc->shrinker_hits); | 2081 | shrinker_hits = READ_ONCE(gc->shrinker_hits); |
| 2072 | 2082 | ||
| 2083 | /* | ||
| 2084 | * Ensure the list add is always seen by anyone who finds the cpumask | ||
| 2085 | * bit set. This effectively gives the cpumask bit set operation | ||
| 2086 | * release ordering semantics. | ||
| 2087 | */ | ||
| 2088 | smp_mb__before_atomic(); | ||
| 2089 | if (!cpumask_test_cpu(cpu_nr, &mp->m_inodegc_cpumask)) | ||
| 2090 | cpumask_test_and_set_cpu(cpu_nr, &mp->m_inodegc_cpumask); | ||
| 2091 | |||
| 2073 | /* | 2092 | /* |
| 2074 | * We queue the work while holding the current CPU so that the work | 2093 | * We queue the work while holding the current CPU so that the work |
| 2075 | * is scheduled to run on this CPU. | 2094 | * is scheduled to run on this CPU. |
| 2076 | */ | 2095 | */ |
| 2077 | if (!xfs_is_inodegc_enabled(mp)) { | 2096 | if (!xfs_is_inodegc_enabled(mp)) { |
| 2078 | put_cpu_ptr(gc); | 2097 | put_cpu(); |
| 2079 | return; | 2098 | return; |
| 2080 | } | 2099 | } |
| 2081 | 2100 | ||
| @@ -2085,7 +2104,7 @@ xfs_inodegc_queue( · 3 unmodified lines | |||
| 2085 | trace_xfs_inodegc_queue(mp, __return_address); | 2104 | trace_xfs_inodegc_queue(mp, __return_address); |
| 2086 | mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, | 2105 | mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, |
| 2087 | queue_delay); | 2106 | queue_delay); |
| 2088 | put_cpu_ptr(gc); | 2107 | put_cpu(); |
| 2089 | 2108 | ||
| 2090 | if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) { | 2109 | if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) { |
| 2091 | trace_xfs_inodegc_throttle(mp, __return_address); | 2110 | trace_xfs_inodegc_throttle(mp, __return_address); |
| @@ -2093,47 +2112,6 @@ xfs_inodegc_queue( · 1 unmodified line | |||
| 2093 | } | 2112 | } |
| 2094 | } | 2113 | } |
| 2095 | 2114 | ||
| 2096 | /* | ||
| 2097 | * Fold the dead CPU inodegc queue into the current CPUs queue. | ||
| 2098 | */ | ||
| 2099 | void | ||
| 2100 | xfs_inodegc_cpu_dead( | ||
| 2101 | struct xfs_mount *mp, | ||
| 2102 | unsigned int dead_cpu) | ||
| 2103 | { | ||
| 2104 | struct xfs_inodegc *dead_gc, *gc; | ||
| 2105 | struct llist_node *first, *last; | ||
| 2106 | unsigned int count = 0; | ||
| 2107 | |||
| 2108 | dead_gc = per_cpu_ptr(mp->m_inodegc, dead_cpu); | ||
| 2109 | cancel_delayed_work_sync(&dead_gc->work); | ||
| 2110 | |||
| 2111 | if (llist_empty(&dead_gc->list)) | ||
| 2112 | return; | ||
| 2113 | |||
| 2114 | first = dead_gc->list.first; | ||
| 2115 | last = first; | ||
| 2116 | while (last->next) { | ||
| 2117 | last = last->next; | ||
| 2118 | count++; | ||
| 2119 | } | ||
| 2120 | dead_gc->list.first = NULL; | ||
| 2121 | dead_gc->items = 0; | ||
| 2122 | |||
| 2123 | /* Add pending work to current CPU */ | ||
| 2124 | gc = get_cpu_ptr(mp->m_inodegc); | ||
| 2125 | llist_add_batch(first, last, &gc->list); | ||
| 2126 | count += READ_ONCE(gc->items); | ||
| 2127 | WRITE_ONCE(gc->items, count); | ||
| 2128 | |||
| 2129 | if (xfs_is_inodegc_enabled(mp)) { | ||
| 2130 | trace_xfs_inodegc_queue(mp, __return_address); | ||
| 2131 | mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, | ||
| 2132 | 0); | ||
| 2133 | } | ||
| 2134 | put_cpu_ptr(gc); | ||
| 2135 | } | ||
| 2136 | |||
| 2137 | /* | 2115 | /* |
| 2138 | * We set the inode flag atomically with the radix tree tag. Once we get tag | 2116 | * We set the inode flag atomically with the radix tree tag. Once we get tag |
| 2139 | * lookups on the radix tree, this inode flag can go away. | 2117 | * lookups on the radix tree, this inode flag can go away. |
| @@ -2195,7 +2173,7 @@ xfs_inodegc_shrinker_count( · 55 unmodified lines | |||
| 2195 | if (!xfs_is_inodegc_enabled(mp)) | 2173 | if (!xfs_is_inodegc_enabled(mp)) |
| 2196 | return 0; | 2174 | return 0; |
| 2197 | 2175 | ||
| 2198 | for_each_online_cpu(cpu) { | 2176 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 2199 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 2177 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| 2200 | if (!llist_empty(&gc->list)) | 2178 | if (!llist_empty(&gc->list)) |
| 2201 | return XFS_INODEGC_SHRINKER_COUNT; | 2179 | return XFS_INODEGC_SHRINKER_COUNT; |
| @@ -2220,7 +2198,7 @@ xfs_inodegc_shrinker_scan( · 18 unmodified lines | |||
| 2220 | 2198 | ||
| 2221 | trace_xfs_inodegc_shrinker_scan(mp, sc, __return_address); | 2199 | trace_xfs_inodegc_shrinker_scan(mp, sc, __return_address); |
| 2222 | 2200 | ||
| 2223 | for_each_online_cpu(cpu) { | 2201 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 2224 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 2202 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| 2225 | if (!llist_empty(&gc->list)) { | 2203 | if (!llist_empty(&gc->list)) { |
| 2226 | unsigned int h = READ_ONCE(gc->shrinker_hits); | 2204 | unsigned int h = READ_ONCE(gc->shrinker_hits); |
| @@ -79,7 +79,6 @@ void xfs_inodegc_push(struct xfs_mount *mp); · 78 unmodified lines | |||
| 79 | int xfs_inodegc_flush(struct xfs_mount *mp); | 79 | int xfs_inodegc_flush(struct xfs_mount *mp); |
| 80 | void xfs_inodegc_stop(struct xfs_mount *mp); | 80 | void xfs_inodegc_stop(struct xfs_mount *mp); |
| 81 | void xfs_inodegc_start(struct xfs_mount *mp); | 81 | void xfs_inodegc_start(struct xfs_mount *mp); |
| 82 | void xfs_inodegc_cpu_dead(struct xfs_mount *mp, unsigned int cpu); | ||
| 83 | int xfs_inodegc_register_shrinker(struct xfs_mount *mp); | 82 | int xfs_inodegc_register_shrinker(struct xfs_mount *mp); |
| 84 | 83 | ||
| 85 | #endif | 84 | #endif |
| @@ -1642,8 +1642,11 @@ xfs_inode_needs_inactive( · 1641 unmodified lines | |||
| 1642 | if (VFS_I(ip)->i_mode == 0) | 1642 | if (VFS_I(ip)->i_mode == 0) |
| 1643 | return false; | 1643 | return false; |
| 1644 | 1644 | ||
| 1645 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1645 | /* |
| 1646 | if (xfs_is_readonly(mp)) | 1646 | * If this is a read-only mount, don't do this (would generate I/O) |
| 1647 | * unless we're in log recovery and cleaning the iunlinked list. | ||
| 1648 | */ | ||
| 1649 | if (xfs_is_readonly(mp) && !xlog_recovery_needed(mp->m_log)) | ||
| 1647 | return false; | 1650 | return false; |
| 1648 | 1651 | ||
| 1649 | /* If the log isn't running, push inodes straight to reclaim. */ | 1652 | /* If the log isn't running, push inodes straight to reclaim. */ |
| @@ -1703,8 +1706,11 @@ xfs_inactive( · 53 unmodified lines | |||
| 1703 | mp = ip->i_mount; | 1706 | mp = ip->i_mount; |
| 1704 | ASSERT(!xfs_iflags_test(ip, XFS_IRECOVERY)); | 1707 | ASSERT(!xfs_iflags_test(ip, XFS_IRECOVERY)); |
| 1705 | 1708 | ||
| 1706 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1709 | /* |
| 1707 | if (xfs_is_readonly(mp)) | 1710 | * If this is a read-only mount, don't do this (would generate I/O) |
| 1711 | * unless we're in log recovery and cleaning the iunlinked list. | ||
| 1712 | */ | ||
| 1713 | if (xfs_is_readonly(mp) && !xlog_recovery_needed(mp->m_log)) | ||
| 1708 | goto out; | 1714 | goto out; |
| 1709 | 1715 | ||
| 1710 | /* Metadata inodes require explicit resource cleanup. */ | 1716 | /* Metadata inodes require explicit resource cleanup. */ |
| @@ -1736,9 +1742,21 @@ xfs_inactive( · 25 unmodified lines | |||
| 1736 | ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) | 1742 | ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) |
| 1737 | truncate = 1; | 1743 | truncate = 1; |
| 1738 | 1744 | ||
| 1739 | error = xfs_qm_dqattach(ip); | 1745 | if (xfs_iflags_test(ip, XFS_IQUOTAUNCHECKED)) { |
| 1740 | if (error) | 1746 | /* |
| 1741 | goto out; | 1747 | * If this inode is being inactivated during a quotacheck and |
| 1748 | * has not yet been scanned by quotacheck, we /must/ remove | ||
| 1749 | * the dquots from the inode before inactivation changes the | ||
| 1750 | * block and inode counts. Most probably this is a result of | ||
| 1751 | * reloading the incore iunlinked list to purge unrecovered | ||
| 1752 | * unlinked inodes. | ||
| 1753 | */ | ||
| 1754 | xfs_qm_dqdetach(ip); | ||
| 1755 | } else { | ||
| 1756 | error = xfs_qm_dqattach(ip); | ||
| 1757 | if (error) | ||
| 1758 | goto out; | ||
| 1759 | } | ||
| 1742 | 1760 | ||
| 1743 | if (S_ISLNK(VFS_I(ip)->i_mode)) | 1761 | if (S_ISLNK(VFS_I(ip)->i_mode)) |
| 1744 | error = xfs_inactive_symlink(ip); | 1762 | error = xfs_inactive_symlink(ip); |
| @@ -1822,12 +1840,17 @@ xfs_iunlink_lookup( · 77 unmodified lines | |||
| 1822 | 1840 | ||
| 1823 | rcu_read_lock(); | 1841 | rcu_read_lock(); |
| 1824 | ip = radix_tree_lookup(&pag->pag_ici_root, agino); | 1842 | ip = radix_tree_lookup(&pag->pag_ici_root, agino); |
| 1843 | if (!ip) { | ||
| 1844 | /* Caller can handle inode not being in memory. */ | ||
| 1845 | rcu_read_unlock(); | ||
| 1846 | return NULL; | ||
| 1847 | } | ||
| 1825 | 1848 | ||
| 1826 | /* | 1849 | /* |
| 1827 | * Inode not in memory or in RCU freeing limbo should not happen. | 1850 | * Inode in RCU freeing limbo should not happen. Warn about this and |
| 1828 | * Warn about this and let the caller handle the failure. | 1851 | * let the caller handle the failure. |
| 1829 | */ | 1852 | */ |
| 1830 | if (WARN_ON_ONCE(!ip || !ip->i_ino)) { | 1853 | if (WARN_ON_ONCE(!ip->i_ino)) { |
| 1831 | rcu_read_unlock(); | 1854 | rcu_read_unlock(); |
| 1832 | return NULL; | 1855 | return NULL; |
| 1833 | } | 1856 | } |
| @@ -1836,7 +1859,10 @@ xfs_iunlink_lookup( · 2 unmodified lines | |||
| 1836 | return ip; | 1859 | return ip; |
| 1837 | } | 1860 | } |
| 1838 | 1861 | ||
| 1839 | /* Update the prev pointer of the next agino. */ | 1862 | /* |
| 1863 | * Update the prev pointer of the next agino. Returns -ENOLINK if the inode | ||
| 1864 | * is not in cache. | ||
| 1865 | */ | ||
| 1840 | static int | 1866 | static int |
| 1841 | xfs_iunlink_update_backref( | 1867 | xfs_iunlink_update_backref( |
| 1842 | struct xfs_perag *pag, | 1868 | struct xfs_perag *pag, |
| @@ -1851,7 +1877,8 @@ xfs_iunlink_update_backref( · 8 unmodified lines | |||
| 1851 | 1877 | ||
| 1852 | ip = xfs_iunlink_lookup(pag, next_agino); | 1878 | ip = xfs_iunlink_lookup(pag, next_agino); |
| 1853 | if (!ip) | 1879 | if (!ip) |
| 1854 | return -EFSCORRUPTED; | 1880 | return -ENOLINK; |
| 1881 | |||
| 1855 | ip->i_prev_unlinked = prev_agino; | 1882 | ip->i_prev_unlinked = prev_agino; |
| 1856 | return 0; | 1883 | return 0; |
| 1857 | } | 1884 | } |
| @@ -1895,6 +1922,64 @@ xfs_iunlink_update_bucket( · 37 unmodified lines | |||
| 1895 | return 0; | 1922 | return 0; |
| 1896 | } | 1923 | } |
| 1897 | 1924 | ||
| 1925 | /* | ||
| 1926 | * Load the inode @next_agino into the cache and set its prev_unlinked pointer | ||
| 1927 | * to @prev_agino. Caller must hold the AGI to synchronize with other changes | ||
| 1928 | * to the unlinked list. | ||
| 1929 | */ | ||
| 1930 | STATIC int | ||
| 1931 | xfs_iunlink_reload_next( | ||
| 1932 | struct xfs_trans *tp, | ||
| 1933 | struct xfs_buf *agibp, | ||
| 1934 | xfs_agino_t prev_agino, | ||
| 1935 | xfs_agino_t next_agino) | ||
| 1936 | { | ||
| 1937 | struct xfs_perag *pag = agibp->b_pag; | ||
| 1938 | struct xfs_mount *mp = pag->pag_mount; | ||
| 1939 | struct xfs_inode *next_ip = NULL; | ||
| 1940 | xfs_ino_t ino; | ||
| 1941 | int error; | ||
| 1942 | |||
| 1943 | ASSERT(next_agino != NULLAGINO); | ||
| 1944 | |||
| 1945 | #ifdef DEBUG | ||
| 1946 | rcu_read_lock(); | ||
| 1947 | next_ip = radix_tree_lookup(&pag->pag_ici_root, next_agino); | ||
| 1948 | ASSERT(next_ip == NULL); | ||
| 1949 | rcu_read_unlock(); | ||
| 1950 | #endif | ||
| 1951 | |||
| 1952 | xfs_info_ratelimited(mp, | ||
| 1953 | "Found unrecovered unlinked inode 0x%x in AG 0x%x. Initiating recovery.", | ||
| 1954 | next_agino, pag->pag_agno); | ||
| 1955 | |||
| 1956 | /* | ||
| 1957 | * Use an untrusted lookup just to be cautious in case the AGI has been | ||
| 1958 | * corrupted and now points at a free inode. That shouldn't happen, | ||
| 1959 | * but we'd rather shut down now since we're already running in a weird | ||
| 1960 | * situation. | ||
| 1961 | */ | ||
| 1962 | ino = XFS_AGINO_TO_INO(mp, pag->pag_agno, next_agino); | ||
| 1963 | error = xfs_iget(mp, tp, ino, XFS_IGET_UNTRUSTED, 0, &next_ip); | ||
| 1964 | if (error) | ||
| 1965 | return error; | ||
| 1966 | |||
| 1967 | /* If this is not an unlinked inode, something is very wrong. */ | ||
| 1968 | if (VFS_I(next_ip)->i_nlink != 0) { | ||
| 1969 | error = -EFSCORRUPTED; | ||
| 1970 | goto rele; | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | next_ip->i_prev_unlinked = prev_agino; | ||
| 1974 | trace_xfs_iunlink_reload_next(next_ip); | ||
| 1975 | rele: | ||
| 1976 | ASSERT(!(VFS_I(next_ip)->i_state & I_DONTCACHE)); | ||
| 1977 | if (xfs_is_quotacheck_running(mp) && next_ip) | ||
| 1978 | xfs_iflags_set(next_ip, XFS_IQUOTAUNCHECKED); | ||
| 1979 | xfs_irele(next_ip); | ||
| 1980 | return error; | ||
| 1981 | } | ||
| 1982 | |||
| 1898 | static int | 1983 | static int |
| 1899 | xfs_iunlink_insert_inode( | 1984 | xfs_iunlink_insert_inode( |
| 1900 | struct xfs_trans *tp, | 1985 | struct xfs_trans *tp, |
| @@ -1926,6 +2011,8 @@ xfs_iunlink_insert_inode( · 25 unmodified lines | |||
| 1926 | * inode. | 2011 | * inode. |
| 1927 | */ | 2012 | */ |
| 1928 | error = xfs_iunlink_update_backref(pag, agino, next_agino); | 2013 | error = xfs_iunlink_update_backref(pag, agino, next_agino); |
| 2014 | if (error == -ENOLINK) | ||
| 2015 | error = xfs_iunlink_reload_next(tp, agibp, agino, next_agino); | ||
| 1929 | if (error) | 2016 | if (error) |
| 1930 | return error; | 2017 | return error; |
| 1931 | 2018 | ||
| @@ -1941,6 +2028,7 @@ xfs_iunlink_insert_inode( · 9 unmodified lines | |||
| 1941 | } | 2028 | } |
| 1942 | 2029 | ||
| 1943 | /* Point the head of the list to point to this inode. */ | 2030 | /* Point the head of the list to point to this inode. */ |
| 2031 | ip->i_prev_unlinked = NULLAGINO; | ||
| 1944 | return xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, agino); | 2032 | return xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, agino); |
| 1945 | } | 2033 | } |
| 1946 | 2034 | ||
| @@ -2020,6 +2108,9 @@ xfs_iunlink_remove_inode( · 73 unmodified lines | |||
| 2020 | */ | 2108 | */ |
| 2021 | error = xfs_iunlink_update_backref(pag, ip->i_prev_unlinked, | 2109 | error = xfs_iunlink_update_backref(pag, ip->i_prev_unlinked, |
| 2022 | ip->i_next_unlinked); | 2110 | ip->i_next_unlinked); |
| 2111 | if (error == -ENOLINK) | ||
| 2112 | error = xfs_iunlink_reload_next(tp, agibp, ip->i_prev_unlinked, | ||
| 2113 | ip->i_next_unlinked); | ||
| 2023 | if (error) | 2114 | if (error) |
| 2024 | return error; | 2115 | return error; |
| 2025 | 2116 | ||
| @@ -2040,7 +2131,7 @@ xfs_iunlink_remove_inode( · 14 unmodified lines | |||
| 2040 | } | 2131 | } |
| 2041 | 2132 | ||
| 2042 | ip->i_next_unlinked = NULLAGINO; | 2133 | ip->i_next_unlinked = NULLAGINO; |
| 2043 | ip->i_prev_unlinked = NULLAGINO; | 2134 | ip->i_prev_unlinked = 0; |
| 2044 | return error; | 2135 | return error; |
| 2045 | } | 2136 | } |
| 2046 | 2137 | ||
| @@ -3529,3 +3620,117 @@ xfs_iunlock2_io_mmap( · 1482 unmodified lines | |||
| 3529 | if (ip1 != ip2) | 3620 | if (ip1 != ip2) |
| 3530 | inode_unlock(VFS_I(ip1)); | 3621 | inode_unlock(VFS_I(ip1)); |
| 3531 | } | 3622 | } |
| 3623 | |||
| 3624 | /* | ||
| 3625 | * Reload the incore inode list for this inode. Caller should ensure that | ||
| 3626 | * the link count cannot change, either by taking ILOCK_SHARED or otherwise | ||
| 3627 | * preventing other threads from executing. | ||
| 3628 | */ | ||
| 3629 | int | ||
| 3630 | xfs_inode_reload_unlinked_bucket( | ||
| 3631 | struct xfs_trans *tp, | ||
| 3632 | struct xfs_inode *ip) | ||
| 3633 | { | ||
| 3634 | struct xfs_mount *mp = tp->t_mountp; | ||
| 3635 | struct xfs_buf *agibp; | ||
| 3636 | struct xfs_agi *agi; | ||
| 3637 | struct xfs_perag *pag; | ||
| 3638 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ip->i_ino); | ||
| 3639 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); | ||
| 3640 | xfs_agino_t prev_agino, next_agino; | ||
| 3641 | unsigned int bucket; | ||
| 3642 | bool foundit = false; | ||
| 3643 | int error; | ||
| 3644 | |||
| 3645 | /* Grab the first inode in the list */ | ||
| 3646 | pag = xfs_perag_get(mp, agno); | ||
| 3647 | error = xfs_ialloc_read_agi(pag, tp, &agibp); | ||
| 3648 | xfs_perag_put(pag); | ||
| 3649 | if (error) | ||
| 3650 | return error; | ||
| 3651 | |||
| 3652 | /* | ||
| 3653 | * We've taken ILOCK_SHARED and the AGI buffer lock to stabilize the | ||
| 3654 | * incore unlinked list pointers for this inode. Check once more to | ||
| 3655 | * see if we raced with anyone else to reload the unlinked list. | ||
| 3656 | */ | ||
| 3657 | if (!xfs_inode_unlinked_incomplete(ip)) { | ||
| 3658 | foundit = true; | ||
| 3659 | goto out_agibp; | ||
| 3660 | } | ||
| 3661 | |||
| 3662 | bucket = agino % XFS_AGI_UNLINKED_BUCKETS; | ||
| 3663 | agi = agibp->b_addr; | ||
| 3664 | |||
| 3665 | trace_xfs_inode_reload_unlinked_bucket(ip); | ||
| 3666 | |||
| 3667 | xfs_info_ratelimited(mp, | ||
| 3668 | "Found unrecovered unlinked inode 0x%x in AG 0x%x. Initiating list recovery.", | ||
| 3669 | agino, agno); | ||
| 3670 | |||
| 3671 | prev_agino = NULLAGINO; | ||
| 3672 | next_agino = be32_to_cpu(agi->agi_unlinked[bucket]); | ||
| 3673 | while (next_agino != NULLAGINO) { | ||
| 3674 | struct xfs_inode *next_ip = NULL; | ||
| 3675 | |||
| 3676 | /* Found this caller's inode, set its backlink. */ | ||
| 3677 | if (next_agino == agino) { | ||
| 3678 | next_ip = ip; | ||
| 3679 | next_ip->i_prev_unlinked = prev_agino; | ||
| 3680 | foundit = true; | ||
| 3681 | goto next_inode; | ||
| 3682 | } | ||
| 3683 | |||
| 3684 | /* Try in-memory lookup first. */ | ||
| 3685 | next_ip = xfs_iunlink_lookup(pag, next_agino); | ||
| 3686 | if (next_ip) | ||
| 3687 | goto next_inode; | ||
| 3688 | |||
| 3689 | /* Inode not in memory, try reloading it. */ | ||
| 3690 | error = xfs_iunlink_reload_next(tp, agibp, prev_agino, | ||
| 3691 | next_agino); | ||
| 3692 | if (error) | ||
| 3693 | break; | ||
| 3694 | |||
| 3695 | /* Grab the reloaded inode. */ | ||
| 3696 | next_ip = xfs_iunlink_lookup(pag, next_agino); | ||
| 3697 | if (!next_ip) { | ||
| 3698 | /* No incore inode at all? We reloaded it... */ | ||
| 3699 | ASSERT(next_ip != NULL); | ||
| 3700 | error = -EFSCORRUPTED; | ||
| 3701 | break; | ||
| 3702 | } | ||
| 3703 | |||
| 3704 | next_inode: | ||
| 3705 | prev_agino = next_agino; | ||
| 3706 | next_agino = next_ip->i_next_unlinked; | ||
| 3707 | } | ||
| 3708 | |||
| 3709 | out_agibp: | ||
| 3710 | xfs_trans_brelse(tp, agibp); | ||
| 3711 | /* Should have found this inode somewhere in the iunlinked bucket. */ | ||
| 3712 | if (!error && !foundit) | ||
| 3713 | error = -EFSCORRUPTED; | ||
| 3714 | return error; | ||
| 3715 | } | ||
| 3716 | |||
| 3717 | /* Decide if this inode is missing its unlinked list and reload it. */ | ||
| 3718 | int | ||
| 3719 | xfs_inode_reload_unlinked( | ||
| 3720 | struct xfs_inode *ip) | ||
| 3721 | { | ||
| 3722 | struct xfs_trans *tp; | ||
| 3723 | int error; | ||
| 3724 | |||
| 3725 | error = xfs_trans_alloc_empty(ip->i_mount, &tp); | ||
| 3726 | if (error) | ||
| 3727 | return error; | ||
| 3728 | |||
| 3729 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
| 3730 | if (xfs_inode_unlinked_incomplete(ip)) | ||
| 3731 | error = xfs_inode_reload_unlinked_bucket(tp, ip); | ||
| 3732 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 3733 | xfs_trans_cancel(tp); | ||
| 3734 | |||
| 3735 | return error; | ||
| 3736 | } | ||
| @@ -68,8 +68,21 @@ typedef struct xfs_inode { · 67 unmodified lines | |||
| 68 | uint64_t i_diflags2; /* XFS_DIFLAG2_... */ | 68 | uint64_t i_diflags2; /* XFS_DIFLAG2_... */ |
| 69 | struct timespec64 i_crtime; /* time created */ | 69 | struct timespec64 i_crtime; /* time created */ |
| 70 | 70 | ||
| 71 | /* unlinked list pointers */ | 71 | /* |
| 72 | * Unlinked list pointers. These point to the next and previous inodes | ||
| 73 | * in the AGI unlinked bucket list, respectively. These fields can | ||
| 74 | * only be updated with the AGI locked. | ||
| 75 | * | ||
| 76 | * i_next_unlinked caches di_next_unlinked. | ||
| 77 | */ | ||
| 72 | xfs_agino_t i_next_unlinked; | 78 | xfs_agino_t i_next_unlinked; |
| 79 | |||
| 80 | /* | ||
| 81 | * If the inode is not on an unlinked list, this field is zero. If the | ||
| 82 | * inode is the first element in an unlinked list, this field is | ||
| 83 | * NULLAGINO. Otherwise, i_prev_unlinked points to the previous inode | ||
| 84 | * in the unlinked list. | ||
| 85 | */ | ||
| 73 | xfs_agino_t i_prev_unlinked; | 86 | xfs_agino_t i_prev_unlinked; |
| 74 | 87 | ||
| 75 | /* VFS inode */ | 88 | /* VFS inode */ |
| @@ -81,6 +94,11 @@ typedef struct xfs_inode { · 5 unmodified lines | |||
| 81 | struct list_head i_ioend_list; | 94 | struct list_head i_ioend_list; |
| 82 | } xfs_inode_t; | 95 | } xfs_inode_t; |
| 83 | 96 | ||
| 97 | static inline bool xfs_inode_on_unlinked_list(const struct xfs_inode *ip) | ||
| 98 | { | ||
| 99 | return ip->i_prev_unlinked != 0; | ||
| 100 | } | ||
| 101 | |||
| 84 | static inline bool xfs_inode_has_attr_fork(struct xfs_inode *ip) | 102 | static inline bool xfs_inode_has_attr_fork(struct xfs_inode *ip) |
| 85 | { | 103 | { |
| 86 | return ip->i_forkoff > 0; | 104 | return ip->i_forkoff > 0; |
| @@ -326,6 +344,9 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip) · 239 unmodified lines | |||
| 326 | */ | 344 | */ |
| 327 | #define XFS_INACTIVATING (1 << 13) | 345 | #define XFS_INACTIVATING (1 << 13) |
| 328 | 346 | ||
| 347 | /* Quotacheck is running but inode has not been added to quota counts. */ | ||
| 348 | #define XFS_IQUOTAUNCHECKED (1 << 14) | ||
| 349 | |||
| 329 | /* All inode state flags related to inode reclaim. */ | 350 | /* All inode state flags related to inode reclaim. */ |
| 330 | #define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \ | 351 | #define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \ |
| 331 | XFS_IRECLAIM | \ | 352 | XFS_IRECLAIM | \ |
| @@ -340,7 +361,7 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip) · 8 unmodified lines | |||
| 340 | #define XFS_IRECLAIM_RESET_FLAGS \ | 361 | #define XFS_IRECLAIM_RESET_FLAGS \ |
| 341 | (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ | 362 | (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ |
| 342 | XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | XFS_NEED_INACTIVE | \ | 363 | XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | XFS_NEED_INACTIVE | \ |
| 343 | XFS_INACTIVATING) | 364 | XFS_INACTIVATING | XFS_IQUOTAUNCHECKED) |
| 344 | 365 | ||
| 345 | /* | 366 | /* |
| 346 | * Flags for inode locking. | 367 | * Flags for inode locking. |
| @@ -575,4 +596,13 @@ void xfs_end_io(struct work_struct *work); · 228 unmodified lines | |||
| 575 | int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); | 596 | int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); |
| 576 | void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); | 597 | void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); |
| 577 | 598 | ||
| 599 | static inline bool | ||
| 600 | xfs_inode_unlinked_incomplete( | ||
| 601 | struct xfs_inode *ip) | ||
| 602 | { | ||
| 603 | return VFS_I(ip)->i_nlink == 0 && !xfs_inode_on_unlinked_list(ip); | ||
| 604 | } | ||
| 605 | int xfs_inode_reload_unlinked_bucket(struct xfs_trans *tp, struct xfs_inode *ip); | ||
| 606 | int xfs_inode_reload_unlinked(struct xfs_inode *ip); | ||
| 607 | |||
| 578 | #endif /* __XFS_INODE_H__ */ | 608 | #endif /* __XFS_INODE_H__ */ |
| @@ -80,6 +80,17 @@ xfs_bulkstat_one_int( · 79 unmodified lines | |||
| 80 | if (error) | 80 | if (error) |
| 81 | goto out; | 81 | goto out; |
| 82 | 82 | ||
| 83 | /* Reload the incore unlinked list to avoid failure in inodegc. */ | ||
| 84 | if (xfs_inode_unlinked_incomplete(ip)) { | ||
| 85 | error = xfs_inode_reload_unlinked_bucket(tp, ip); | ||
| 86 | if (error) { | ||
| 87 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 88 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
| 89 | xfs_irele(ip); | ||
| 90 | return error; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 83 | ASSERT(ip != NULL); | 94 | ASSERT(ip != NULL); |
| 84 | ASSERT(ip->i_imap.im_blkno != 0); | 95 | ASSERT(ip->i_imap.im_blkno != 0); |
| 85 | inode = VFS_I(ip); | 96 | inode = VFS_I(ip); |
| @@ -715,15 +715,7 @@ xfs_log_mount( · 714 unmodified lines | |||
| 715 | * just worked. | 715 | * just worked. |
| 716 | */ | 716 | */ |
| 717 | if (!xfs_has_norecovery(mp)) { | 717 | if (!xfs_has_norecovery(mp)) { |
| 718 | /* | ||
| 719 | * log recovery ignores readonly state and so we need to clear | ||
| 720 | * mount-based read only state so it can write to disk. | ||
| 721 | */ | ||
| 722 | bool readonly = test_and_clear_bit(XFS_OPSTATE_READONLY, | ||
| 723 | &mp->m_opstate); | ||
| 724 | error = xlog_recover(log); | 718 | error = xlog_recover(log); |
| 725 | if (readonly) | ||
| 726 | set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); | ||
| 727 | if (error) { | 719 | if (error) { |
| 728 | xfs_warn(mp, "log mount/recovery failed: error %d", | 720 | xfs_warn(mp, "log mount/recovery failed: error %d", |
| 729 | error); | 721 | error); |
| @@ -772,7 +764,6 @@ xfs_log_mount_finish( · 42 unmodified lines | |||
| 772 | struct xfs_mount *mp) | 764 | struct xfs_mount *mp) |
| 773 | { | 765 | { |
| 774 | struct xlog *log = mp->m_log; | 766 | struct xlog *log = mp->m_log; |
| 775 | bool readonly; | ||
| 776 | int error = 0; | 767 | int error = 0; |
| 777 | 768 | ||
| 778 | if (xfs_has_norecovery(mp)) { | 769 | if (xfs_has_norecovery(mp)) { |
| @@ -780,12 +771,6 @@ xfs_log_mount_finish( · 1 unmodified line | |||
| 780 | return 0; | 771 | return 0; |
| 781 | } | 772 | } |
| 782 | 773 | ||
| 783 | /* | ||
| 784 | * log recovery ignores readonly state and so we need to clear | ||
| 785 | * mount-based read only state so it can write to disk. | ||
| 786 | */ | ||
| 787 | readonly = test_and_clear_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); | ||
| 788 | |||
| 789 | /* | 774 | /* |
| 790 | * During the second phase of log recovery, we need iget and | 775 | * During the second phase of log recovery, we need iget and |
| 791 | * iput to behave like they do for an active filesystem. | 776 | * iput to behave like they do for an active filesystem. |
| @@ -835,8 +820,6 @@ xfs_log_mount_finish( · 43 unmodified lines | |||
| 835 | xfs_buftarg_drain(mp->m_ddev_targp); | 820 | xfs_buftarg_drain(mp->m_ddev_targp); |
| 836 | 821 | ||
| 837 | clear_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate); | 822 | clear_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate); |
| 838 | if (readonly) | ||
| 839 | set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); | ||
| 840 | 823 | ||
| 841 | /* Make sure the log is dead if we're returning failure. */ | 824 | /* Make sure the log is dead if we're returning failure. */ |
| 842 | ASSERT(!error || xlog_is_shutdown(log)); | 825 | ASSERT(!error || xlog_is_shutdown(log)); |
| @@ -124,7 +124,7 @@ xlog_cil_push_pcp_aggregate( · 123 unmodified lines | |||
| 124 | struct xlog_cil_pcp *cilpcp; | 124 | struct xlog_cil_pcp *cilpcp; |
| 125 | int cpu; | 125 | int cpu; |
| 126 | 126 | ||
| 127 | for_each_online_cpu(cpu) { | 127 | for_each_cpu(cpu, &ctx->cil_pcpmask) { |
| 128 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); | 128 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); |
| 129 | 129 | ||
| 130 | ctx->ticket->t_curr_res += cilpcp->space_reserved; | 130 | ctx->ticket->t_curr_res += cilpcp->space_reserved; |
| @@ -165,7 +165,13 @@ xlog_cil_insert_pcp_aggregate( · 34 unmodified lines | |||
| 165 | if (!test_and_clear_bit(XLOG_CIL_PCP_SPACE, &cil->xc_flags)) | 165 | if (!test_and_clear_bit(XLOG_CIL_PCP_SPACE, &cil->xc_flags)) |
| 166 | return; | 166 | return; |
| 167 | 167 | ||
| 168 | for_each_online_cpu(cpu) { | 168 | /* |
| 169 | * We can race with other cpus setting cil_pcpmask. However, we've | ||
| 170 | * atomically cleared PCP_SPACE which forces other threads to add to | ||
| 171 | * the global space used count. cil_pcpmask is a superset of cilpcp | ||
| 172 | * structures that could have a nonzero space_used. | ||
| 173 | */ | ||
| 174 | for_each_cpu(cpu, &ctx->cil_pcpmask) { | ||
| 169 | int old, prev; | 175 | int old, prev; |
| 170 | 176 | ||
| 171 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); | 177 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); |
| @@ -554,6 +560,7 @@ xlog_cil_insert_items( · 382 unmodified lines | |||
| 554 | int iovhdr_res = 0, split_res = 0, ctx_res = 0; | 560 | int iovhdr_res = 0, split_res = 0, ctx_res = 0; |
| 555 | int space_used; | 561 | int space_used; |
| 556 | int order; | 562 | int order; |
| 563 | unsigned int cpu_nr; | ||
| 557 | struct xlog_cil_pcp *cilpcp; | 564 | struct xlog_cil_pcp *cilpcp; |
| 558 | 565 | ||
| 559 | ASSERT(tp); | 566 | ASSERT(tp); |
| @@ -577,7 +584,12 @@ xlog_cil_insert_items( · 17 unmodified lines | |||
| 577 | * can't be scheduled away between split sample/update operations that | 584 | * can't be scheduled away between split sample/update operations that |
| 578 | * are done without outside locking to serialise them. | 585 | * are done without outside locking to serialise them. |
| 579 | */ | 586 | */ |
| 580 | cilpcp = get_cpu_ptr(cil->xc_pcp); | 587 | cpu_nr = get_cpu(); |
| 588 | cilpcp = this_cpu_ptr(cil->xc_pcp); | ||
| 589 | |||
| 590 | /* Tell the future push that there was work added by this CPU. */ | ||
| 591 | if (!cpumask_test_cpu(cpu_nr, &ctx->cil_pcpmask)) | ||
| 592 | cpumask_test_and_set_cpu(cpu_nr, &ctx->cil_pcpmask); | ||
| 581 | 593 | ||
| 582 | /* | 594 | /* |
| 583 | * We need to take the CIL checkpoint unit reservation on the first | 595 | * We need to take the CIL checkpoint unit reservation on the first |
| @@ -663,7 +675,7 @@ xlog_cil_insert_items( · 79 unmodified lines | |||
| 663 | continue; | 675 | continue; |
| 664 | list_add_tail(&lip->li_cil, &cilpcp->log_items); | 676 | list_add_tail(&lip->li_cil, &cilpcp->log_items); |
| 665 | } | 677 | } |
| 666 | put_cpu_ptr(cilpcp); | 678 | put_cpu(); |
| 667 | 679 | ||
| 668 | /* | 680 | /* |
| 669 | * If we've overrun the reservation, dump the tx details before we move | 681 | * If we've overrun the reservation, dump the tx details before we move |
| @@ -1790,38 +1802,6 @@ out_shutdown: · 1120 unmodified lines | |||
| 1790 | return 0; | 1802 | return 0; |
| 1791 | } | 1803 | } |
| 1792 | 1804 | ||
| 1793 | /* | ||
| 1794 | * Move dead percpu state to the relevant CIL context structures. | ||
| 1795 | * | ||
| 1796 | * We have to lock the CIL context here to ensure that nothing is modifying | ||
| 1797 | * the percpu state, either addition or removal. Both of these are done under | ||
| 1798 | * the CIL context lock, so grabbing that exclusively here will ensure we can | ||
| 1799 | * safely drain the cilpcp for the CPU that is dying. | ||
| 1800 | */ | ||
| 1801 | void | ||
| 1802 | xlog_cil_pcp_dead( | ||
| 1803 | struct xlog *log, | ||
| 1804 | unsigned int cpu) | ||
| 1805 | { | ||
| 1806 | struct xfs_cil *cil = log->l_cilp; | ||
| 1807 | struct xlog_cil_pcp *cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); | ||
| 1808 | struct xfs_cil_ctx *ctx; | ||
| 1809 | |||
| 1810 | down_write(&cil->xc_ctx_lock); | ||
| 1811 | ctx = cil->xc_ctx; | ||
| 1812 | if (ctx->ticket) | ||
| 1813 | ctx->ticket->t_curr_res += cilpcp->space_reserved; | ||
| 1814 | cilpcp->space_reserved = 0; | ||
| 1815 | |||
| 1816 | if (!list_empty(&cilpcp->log_items)) | ||
| 1817 | list_splice_init(&cilpcp->log_items, &ctx->log_items); | ||
| 1818 | if (!list_empty(&cilpcp->busy_extents)) | ||
| 1819 | list_splice_init(&cilpcp->busy_extents, &ctx->busy_extents); | ||
| 1820 | atomic_add(cilpcp->space_used, &ctx->space_used); | ||
| 1821 | cilpcp->space_used = 0; | ||
| 1822 | up_write(&cil->xc_ctx_lock); | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | /* | 1805 | /* |
| 1826 | * Perform initial CIL structure initialisation. | 1806 | * Perform initial CIL structure initialisation. |
| 1827 | */ | 1807 | */ |
| @@ -231,6 +231,12 @@ struct xfs_cil_ctx { · 230 unmodified lines | |||
| 231 | struct work_struct discard_endio_work; | 231 | struct work_struct discard_endio_work; |
| 232 | struct work_struct push_work; | 232 | struct work_struct push_work; |
| 233 | atomic_t order_id; | 233 | atomic_t order_id; |
| 234 | |||
| 235 | /* | ||
| 236 | * CPUs that could have added items to the percpu CIL data. Access is | ||
| 237 | * coordinated with xc_ctx_lock. | ||
| 238 | */ | ||
| 239 | struct cpumask cil_pcpmask; | ||
| 234 | }; | 240 | }; |
| 235 | 241 | ||
| 236 | /* | 242 | /* |
| @@ -278,9 +284,6 @@ struct xfs_cil { · 41 unmodified lines | |||
| 278 | wait_queue_head_t xc_push_wait; /* background push throttle */ | 284 | wait_queue_head_t xc_push_wait; /* background push throttle */ |
| 279 | 285 | ||
| 280 | void __percpu *xc_pcp; /* percpu CIL structures */ | 286 | void __percpu *xc_pcp; /* percpu CIL structures */ |
| 281 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 282 | struct list_head xc_pcp_list; | ||
| 283 | #endif | ||
| 284 | } ____cacheline_aligned_in_smp; | 287 | } ____cacheline_aligned_in_smp; |
| 285 | 288 | ||
| 286 | /* xc_flags bit values */ | 289 | /* xc_flags bit values */ |
| @@ -705,9 +708,4 @@ xlog_kvmalloc( · 418 unmodified lines | |||
| 705 | return p; | 708 | return p; |
| 706 | } | 709 | } |
| 707 | 710 | ||
| 708 | /* | ||
| 709 | * CIL CPU dead notifier | ||
| 710 | */ | ||
| 711 | void xlog_cil_pcp_dead(struct xlog *log, unsigned int cpu); | ||
| 712 | |||
| 713 | #endif /* __XFS_LOG_PRIV_H__ */ | 711 | #endif /* __XFS_LOG_PRIV_H__ */ |
| @@ -329,7 +329,7 @@ xlog_find_verify_cycle( · 328 unmodified lines | |||
| 329 | * try a smaller size. We need to be able to read at least | 329 | * try a smaller size. We need to be able to read at least |
| 330 | * a log sector, or we're out of luck. | 330 | * a log sector, or we're out of luck. |
| 331 | */ | 331 | */ |
| 332 | bufblks = 1 << ffs(nbblks); | 332 | bufblks = roundup_pow_of_two(nbblks); |
| 333 | while (bufblks > log->l_logBBsize) | 333 | while (bufblks > log->l_logBBsize) |
| 334 | bufblks >>= 1; | 334 | bufblks >>= 1; |
| 335 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { | 335 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { |
| @@ -1528,7 +1528,7 @@ xlog_write_log_records( · 1192 unmodified lines | |||
| 1528 | * a smaller size. We need to be able to write at least a | 1528 | * a smaller size. We need to be able to write at least a |
| 1529 | * log sector, or we're out of luck. | 1529 | * log sector, or we're out of luck. |
| 1530 | */ | 1530 | */ |
| 1531 | bufblks = 1 << ffs(blocks); | 1531 | bufblks = roundup_pow_of_two(blocks); |
| 1532 | while (bufblks > log->l_logBBsize) | 1532 | while (bufblks > log->l_logBBsize) |
| 1533 | bufblks >>= 1; | 1533 | bufblks >>= 1; |
| 1534 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { | 1534 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { |
| @@ -60,6 +60,7 @@ struct xfs_error_cfg { · 59 unmodified lines | |||
| 60 | * Per-cpu deferred inode inactivation GC lists. | 60 | * Per-cpu deferred inode inactivation GC lists. |
| 61 | */ | 61 | */ |
| 62 | struct xfs_inodegc { | 62 | struct xfs_inodegc { |
| 63 | struct xfs_mount *mp; | ||
| 63 | struct llist_head list; | 64 | struct llist_head list; |
| 64 | struct delayed_work work; | 65 | struct delayed_work work; |
| 65 | int error; | 66 | int error; |
| @@ -67,9 +68,7 @@ struct xfs_inodegc { · 1 unmodified line | |||
| 67 | /* approximate count of inodes in the list */ | 68 | /* approximate count of inodes in the list */ |
| 68 | unsigned int items; | 69 | unsigned int items; |
| 69 | unsigned int shrinker_hits; | 70 | unsigned int shrinker_hits; |
| 70 | #if defined(DEBUG) || defined(XFS_WARN) | ||
| 71 | unsigned int cpu; | 71 | unsigned int cpu; |
| 72 | #endif | ||
| 73 | }; | 72 | }; |
| 74 | 73 | ||
| 75 | /* | 74 | /* |
| @@ -98,7 +97,6 @@ typedef struct xfs_mount { · 22 unmodified lines | |||
| 98 | xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ | 97 | xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ |
| 99 | xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ | 98 | xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ |
| 100 | xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ | 99 | xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ |
| 101 | struct list_head m_mount_list; /* global mount list */ | ||
| 102 | void __percpu *m_inodegc; /* percpu inodegc structures */ | 100 | void __percpu *m_inodegc; /* percpu inodegc structures */ |
| 103 | 101 | ||
| 104 | /* | 102 | /* |
| @@ -249,6 +247,9 @@ typedef struct xfs_mount { · 144 unmodified lines | |||
| 249 | unsigned int *m_errortag; | 247 | unsigned int *m_errortag; |
| 250 | struct xfs_kobj m_errortag_kobj; | 248 | struct xfs_kobj m_errortag_kobj; |
| 251 | #endif | 249 | #endif |
| 250 | |||
| 251 | /* cpus that have inodes queued for inactivation */ | ||
| 252 | struct cpumask m_inodegc_cpumask; | ||
| 252 | } xfs_mount_t; | 253 | } xfs_mount_t; |
| 253 | 254 | ||
| 254 | #define M_IGEO(mp) (&(mp)->m_ino_geo) | 255 | #define M_IGEO(mp) (&(mp)->m_ino_geo) |
| @@ -404,6 +405,8 @@ __XFS_HAS_FEAT(nouuid, NOUUID) · 149 unmodified lines | |||
| 404 | #define XFS_OPSTATE_WARNED_SHRINK 8 | 405 | #define XFS_OPSTATE_WARNED_SHRINK 8 |
| 405 | /* Kernel has logged a warning about logged xattr updates being used. */ | 406 | /* Kernel has logged a warning about logged xattr updates being used. */ |
| 406 | #define XFS_OPSTATE_WARNED_LARP 9 | 407 | #define XFS_OPSTATE_WARNED_LARP 9 |
| 408 | /* Mount time quotacheck is running */ | ||
| 409 | #define XFS_OPSTATE_QUOTACHECK_RUNNING 10 | ||
| 407 | 410 | ||
| 408 | #define __XFS_IS_OPSTATE(name, NAME) \ | 411 | #define __XFS_IS_OPSTATE(name, NAME) \ |
| 409 | static inline bool xfs_is_ ## name (struct xfs_mount *mp) \ | 412 | static inline bool xfs_is_ ## name (struct xfs_mount *mp) \ |
| @@ -426,6 +429,11 @@ __XFS_IS_OPSTATE(inode32, INODE32) · 16 unmodified lines | |||
| 426 | __XFS_IS_OPSTATE(readonly, READONLY) | 429 | __XFS_IS_OPSTATE(readonly, READONLY) |
| 427 | __XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED) | 430 | __XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED) |
| 428 | __XFS_IS_OPSTATE(blockgc_enabled, BLOCKGC_ENABLED) | 431 | __XFS_IS_OPSTATE(blockgc_enabled, BLOCKGC_ENABLED) |
| 432 | #ifdef CONFIG_XFS_QUOTA | ||
| 433 | __XFS_IS_OPSTATE(quotacheck_running, QUOTACHECK_RUNNING) | ||
| 434 | #else | ||
| 435 | # define xfs_is_quotacheck_running(mp) (false) | ||
| 436 | #endif | ||
| 429 | 437 | ||
| 430 | static inline bool | 438 | static inline bool |
| 431 | xfs_should_warn(struct xfs_mount *mp, long nr) | 439 | xfs_should_warn(struct xfs_mount *mp, long nr) |
| @@ -443,7 +451,8 @@ xfs_should_warn(struct xfs_mount *mp, long nr) · 11 unmodified lines | |||
| 443 | { (1UL << XFS_OPSTATE_BLOCKGC_ENABLED), "blockgc" }, \ | 451 | { (1UL << XFS_OPSTATE_BLOCKGC_ENABLED), "blockgc" }, \ |
| 444 | { (1UL << XFS_OPSTATE_WARNED_SCRUB), "wscrub" }, \ | 452 | { (1UL << XFS_OPSTATE_WARNED_SCRUB), "wscrub" }, \ |
| 445 | { (1UL << XFS_OPSTATE_WARNED_SHRINK), "wshrink" }, \ | 453 | { (1UL << XFS_OPSTATE_WARNED_SHRINK), "wshrink" }, \ |
| 446 | { (1UL << XFS_OPSTATE_WARNED_LARP), "wlarp" } | 454 | { (1UL << XFS_OPSTATE_WARNED_LARP), "wlarp" }, \ |
| 455 | { (1UL << XFS_OPSTATE_QUOTACHECK_RUNNING), "quotacheck" } | ||
| 447 | 456 | ||
| 448 | /* | 457 | /* |
| 449 | * Max and min values for mount-option defined I/O | 458 | * Max and min values for mount-option defined I/O |
| @@ -1160,6 +1160,19 @@ xfs_qm_dqusage_adjust( · 1159 unmodified lines | |||
| 1160 | if (error) | 1160 | if (error) |
| 1161 | return error; | 1161 | return error; |
| 1162 | 1162 | ||
| 1163 | /* | ||
| 1164 | * Reload the incore unlinked list to avoid failure in inodegc. | ||
| 1165 | * Use an unlocked check here because unrecovered unlinked inodes | ||
| 1166 | * should be somewhat rare. | ||
| 1167 | */ | ||
| 1168 | if (xfs_inode_unlinked_incomplete(ip)) { | ||
| 1169 | error = xfs_inode_reload_unlinked(ip); | ||
| 1170 | if (error) { | ||
| 1171 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
| 1172 | goto error0; | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | |||
| 1163 | ASSERT(ip->i_delayed_blks == 0); | 1176 | ASSERT(ip->i_delayed_blks == 0); |
| 1164 | 1177 | ||
| 1165 | if (XFS_IS_REALTIME_INODE(ip)) { | 1178 | if (XFS_IS_REALTIME_INODE(ip)) { |
| @@ -1173,6 +1186,7 @@ xfs_qm_dqusage_adjust( · 7 unmodified lines | |||
| 1173 | } | 1186 | } |
| 1174 | 1187 | ||
| 1175 | nblks = (xfs_qcnt_t)ip->i_nblocks - rtblks; | 1188 | nblks = (xfs_qcnt_t)ip->i_nblocks - rtblks; |
| 1189 | xfs_iflags_clear(ip, XFS_IQUOTAUNCHECKED); | ||
| 1176 | 1190 | ||
| 1177 | /* | 1191 | /* |
| 1178 | * Add the (disk blocks and inode) resources occupied by this | 1192 | * Add the (disk blocks and inode) resources occupied by this |
| @@ -1319,8 +1333,10 @@ xfs_qm_quotacheck( · 140 unmodified lines | |||
| 1319 | flags |= XFS_PQUOTA_CHKD; | 1333 | flags |= XFS_PQUOTA_CHKD; |
| 1320 | } | 1334 | } |
| 1321 | 1335 | ||
| 1336 | xfs_set_quotacheck_running(mp); | ||
| 1322 | error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true, | 1337 | error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true, |
| 1323 | NULL); | 1338 | NULL); |
| 1339 | xfs_clear_quotacheck_running(mp); | ||
| 1324 | 1340 | ||
| 1325 | /* | 1341 | /* |
| 1326 | * On error, the inode walk may have partially populated the dquot | 1342 | * On error, the inode walk may have partially populated the dquot |
| @@ -477,6 +477,7 @@ xfs_cui_item_recover( · 476 unmodified lines | |||
| 477 | struct xfs_log_item *lip, | 477 | struct xfs_log_item *lip, |
| 478 | struct list_head *capture_list) | 478 | struct list_head *capture_list) |
| 479 | { | 479 | { |
| 480 | struct xfs_trans_res resv; | ||
| 480 | struct xfs_cui_log_item *cuip = CUI_ITEM(lip); | 481 | struct xfs_cui_log_item *cuip = CUI_ITEM(lip); |
| 481 | struct xfs_cud_log_item *cudp; | 482 | struct xfs_cud_log_item *cudp; |
| 482 | struct xfs_trans *tp; | 483 | struct xfs_trans *tp; |
| @@ -514,8 +515,9 @@ xfs_cui_item_recover( · 31 unmodified lines | |||
| 514 | * doesn't fit. We need to reserve enough blocks to handle a | 515 | * doesn't fit. We need to reserve enough blocks to handle a |
| 515 | * full btree split on either end of the refcount range. | 516 | * full btree split on either end of the refcount range. |
| 516 | */ | 517 | */ |
| 517 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, | 518 | resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); |
| 518 | mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp); | 519 | error = xfs_trans_alloc(mp, &resv, mp->m_refc_maxlevels * 2, 0, |
| 520 | XFS_TRANS_RESERVE, &tp); | ||
| 519 | if (error) | 521 | if (error) |
| 520 | return error; | 522 | return error; |
| 521 | 523 | ||
| @@ -507,6 +507,7 @@ xfs_rui_item_recover( · 506 unmodified lines | |||
| 507 | struct xfs_log_item *lip, | 507 | struct xfs_log_item *lip, |
| 508 | struct list_head *capture_list) | 508 | struct list_head *capture_list) |
| 509 | { | 509 | { |
| 510 | struct xfs_trans_res resv; | ||
| 510 | struct xfs_rui_log_item *ruip = RUI_ITEM(lip); | 511 | struct xfs_rui_log_item *ruip = RUI_ITEM(lip); |
| 511 | struct xfs_rud_log_item *rudp; | 512 | struct xfs_rud_log_item *rudp; |
| 512 | struct xfs_trans *tp; | 513 | struct xfs_trans *tp; |
| @@ -530,8 +531,9 @@ xfs_rui_item_recover( · 17 unmodified lines | |||
| 530 | } | 531 | } |
| 531 | } | 532 | } |
| 532 | 533 | ||
| 533 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, | 534 | resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); |
| 534 | mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp); | 535 | error = xfs_trans_alloc(mp, &resv, mp->m_rmap_maxlevels, 0, |
| 536 | XFS_TRANS_RESERVE, &tp); | ||
| 535 | if (error) | 537 | if (error) |
| 536 | return error; | 538 | return error; |
| 537 | rudp = xfs_trans_get_rud(tp, ruip); | 539 | rudp = xfs_trans_get_rud(tp, ruip); |
| @@ -56,28 +56,6 @@ static struct kset *xfs_kset; /* top-level xfs sysfs dir */ · 55 unmodified lines | |||
| 56 | static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ | 56 | static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ |
| 57 | #endif | 57 | #endif |
| 58 | 58 | ||
| 59 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 60 | static LIST_HEAD(xfs_mount_list); | ||
| 61 | static DEFINE_SPINLOCK(xfs_mount_list_lock); | ||
| 62 | |||
| 63 | static inline void xfs_mount_list_add(struct xfs_mount *mp) | ||
| 64 | { | ||
| 65 | spin_lock(&xfs_mount_list_lock); | ||
| 66 | list_add(&mp->m_mount_list, &xfs_mount_list); | ||
| 67 | spin_unlock(&xfs_mount_list_lock); | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline void xfs_mount_list_del(struct xfs_mount *mp) | ||
| 71 | { | ||
| 72 | spin_lock(&xfs_mount_list_lock); | ||
| 73 | list_del(&mp->m_mount_list); | ||
| 74 | spin_unlock(&xfs_mount_list_lock); | ||
| 75 | } | ||
| 76 | #else /* !CONFIG_HOTPLUG_CPU */ | ||
| 77 | static inline void xfs_mount_list_add(struct xfs_mount *mp) {} | ||
| 78 | static inline void xfs_mount_list_del(struct xfs_mount *mp) {} | ||
| 79 | #endif | ||
| 80 | |||
| 81 | enum xfs_dax_mode { | 59 | enum xfs_dax_mode { |
| 82 | XFS_DAX_INODE = 0, | 60 | XFS_DAX_INODE = 0, |
| 83 | XFS_DAX_ALWAYS = 1, | 61 | XFS_DAX_ALWAYS = 1, |
| @@ -1135,9 +1113,8 @@ xfs_inodegc_init_percpu( · 1051 unmodified lines | |||
| 1135 | 1113 | ||
| 1136 | for_each_possible_cpu(cpu) { | 1114 | for_each_possible_cpu(cpu) { |
| 1137 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 1115 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| 1138 | #if defined(DEBUG) || defined(XFS_WARN) | ||
| 1139 | gc->cpu = cpu; | 1116 | gc->cpu = cpu; |
| 1140 | #endif | 1117 | gc->mp = mp; |
| 1141 | init_llist_head(&gc->list); | 1118 | init_llist_head(&gc->list); |
| 1142 | gc->items = 0; | 1119 | gc->items = 0; |
| 1143 | gc->error = 0; | 1120 | gc->error = 0; |
| @@ -1168,7 +1145,6 @@ xfs_fs_put_super( · 24 unmodified lines | |||
| 1168 | xfs_freesb(mp); | 1145 | xfs_freesb(mp); |
| 1169 | xchk_mount_stats_free(mp); | 1146 | xchk_mount_stats_free(mp); |
| 1170 | free_percpu(mp->m_stats.xs_stats); | 1147 | free_percpu(mp->m_stats.xs_stats); |
| 1171 | xfs_mount_list_del(mp); | ||
| 1172 | xfs_inodegc_free_percpu(mp); | 1148 | xfs_inodegc_free_percpu(mp); |
| 1173 | xfs_destroy_percpu_counters(mp); | 1149 | xfs_destroy_percpu_counters(mp); |
| 1174 | xfs_destroy_mount_workqueues(mp); | 1150 | xfs_destroy_mount_workqueues(mp); |
| @@ -1577,13 +1553,6 @@ xfs_fs_fill_super( · 402 unmodified lines | |||
| 1577 | if (error) | 1553 | if (error) |
| 1578 | goto out_destroy_counters; | 1554 | goto out_destroy_counters; |
| 1579 | 1555 | ||
| 1580 | /* | ||
| 1581 | * All percpu data structures requiring cleanup when a cpu goes offline | ||
| 1582 | * must be allocated before adding this @mp to the cpu-dead handler's | ||
| 1583 | * mount list. | ||
| 1584 | */ | ||
| 1585 | xfs_mount_list_add(mp); | ||
| 1586 | |||
| 1587 | /* Allocate stats memory before we do operations that might use it */ | 1556 | /* Allocate stats memory before we do operations that might use it */ |
| 1588 | mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); | 1557 | mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); |
| 1589 | if (!mp->m_stats.xs_stats) { | 1558 | if (!mp->m_stats.xs_stats) { |
| @@ -1781,7 +1750,6 @@ xfs_fs_fill_super( · 191 unmodified lines | |||
| 1781 | out_free_stats: | 1750 | out_free_stats: |
| 1782 | free_percpu(mp->m_stats.xs_stats); | 1751 | free_percpu(mp->m_stats.xs_stats); |
| 1783 | out_destroy_inodegc: | 1752 | out_destroy_inodegc: |
| 1784 | xfs_mount_list_del(mp); | ||
| 1785 | xfs_inodegc_free_percpu(mp); | 1753 | xfs_inodegc_free_percpu(mp); |
| 1786 | out_destroy_counters: | 1754 | out_destroy_counters: |
| 1787 | xfs_destroy_percpu_counters(mp); | 1755 | xfs_destroy_percpu_counters(mp); |
| @@ -2326,49 +2294,6 @@ xfs_destroy_workqueues(void) · 538 unmodified lines | |||
| 2326 | destroy_workqueue(xfs_alloc_wq); | 2294 | destroy_workqueue(xfs_alloc_wq); |
| 2327 | } | 2295 | } |
| 2328 | 2296 | ||
| 2329 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 2330 | static int | ||
| 2331 | xfs_cpu_dead( | ||
| 2332 | unsigned int cpu) | ||
| 2333 | { | ||
| 2334 | struct xfs_mount *mp, *n; | ||
| 2335 | |||
| 2336 | spin_lock(&xfs_mount_list_lock); | ||
| 2337 | list_for_each_entry_safe(mp, n, &xfs_mount_list, m_mount_list) { | ||
| 2338 | spin_unlock(&xfs_mount_list_lock); | ||
| 2339 | xfs_inodegc_cpu_dead(mp, cpu); | ||
| 2340 | xlog_cil_pcp_dead(mp->m_log, cpu); | ||
| 2341 | spin_lock(&xfs_mount_list_lock); | ||
| 2342 | } | ||
| 2343 | spin_unlock(&xfs_mount_list_lock); | ||
| 2344 | return 0; | ||
| 2345 | } | ||
| 2346 | |||
| 2347 | static int __init | ||
| 2348 | xfs_cpu_hotplug_init(void) | ||
| 2349 | { | ||
| 2350 | int error; | ||
| 2351 | |||
| 2352 | error = cpuhp_setup_state_nocalls(CPUHP_XFS_DEAD, "xfs:dead", NULL, | ||
| 2353 | xfs_cpu_dead); | ||
| 2354 | if (error < 0) | ||
| 2355 | xfs_alert(NULL, | ||
| 2356 | "Failed to initialise CPU hotplug, error %d. XFS is non-functional.", | ||
| 2357 | error); | ||
| 2358 | return error; | ||
| 2359 | } | ||
| 2360 | |||
| 2361 | static void | ||
| 2362 | xfs_cpu_hotplug_destroy(void) | ||
| 2363 | { | ||
| 2364 | cpuhp_remove_state_nocalls(CPUHP_XFS_DEAD); | ||
| 2365 | } | ||
| 2366 | |||
| 2367 | #else /* !CONFIG_HOTPLUG_CPU */ | ||
| 2368 | static inline int xfs_cpu_hotplug_init(void) { return 0; } | ||
| 2369 | static inline void xfs_cpu_hotplug_destroy(void) {} | ||
| 2370 | #endif | ||
| 2371 | |||
| 2372 | STATIC int __init | 2297 | STATIC int __init |
| 2373 | init_xfs_fs(void) | 2298 | init_xfs_fs(void) |
| 2374 | { | 2299 | { |
| @@ -2385,13 +2310,9 @@ init_xfs_fs(void) · 10 unmodified lines | |||
| 2385 | 2310 | ||
| 2386 | xfs_dir_startup(); | 2311 | xfs_dir_startup(); |
| 2387 | 2312 | ||
| 2388 | error = xfs_cpu_hotplug_init(); | ||
| 2389 | if (error) | ||
| 2390 | goto out; | ||
| 2391 | |||
| 2392 | error = xfs_init_caches(); | 2313 | error = xfs_init_caches(); |
| 2393 | if (error) | 2314 | if (error) |
| 2394 | goto out_destroy_hp; | 2315 | goto out; |
| 2395 | 2316 | ||
| 2396 | error = xfs_init_workqueues(); | 2317 | error = xfs_init_workqueues(); |
| 2397 | if (error) | 2318 | if (error) |
| @@ -2475,8 +2396,6 @@ init_xfs_fs(void) · 77 unmodified lines | |||
| 2475 | xfs_destroy_workqueues(); | 2396 | xfs_destroy_workqueues(); |
| 2476 | out_destroy_caches: | 2397 | out_destroy_caches: |
| 2477 | xfs_destroy_caches(); | 2398 | xfs_destroy_caches(); |
| 2478 | out_destroy_hp: | ||
| 2479 | xfs_cpu_hotplug_destroy(); | ||
| 2480 | out: | 2399 | out: |
| 2481 | return error; | 2400 | return error; |
| 2482 | } | 2401 | } |
| @@ -2500,7 +2419,6 @@ exit_xfs_fs(void) · 17 unmodified lines | |||
| 2500 | xfs_destroy_workqueues(); | 2419 | xfs_destroy_workqueues(); |
| 2501 | xfs_destroy_caches(); | 2420 | xfs_destroy_caches(); |
| 2502 | xfs_uuid_table_free(); | 2421 | xfs_uuid_table_free(); |
| 2503 | xfs_cpu_hotplug_destroy(); | ||
| 2504 | } | 2422 | } |
| 2505 | 2423 | ||
| 2506 | module_init(init_xfs_fs); | 2424 | module_init(init_xfs_fs); |
| @@ -3824,6 +3824,51 @@ TRACE_EVENT(xfs_iunlink_update_dinode, · 3823 unmodified lines | |||
| 3824 | __entry->new_ptr) | 3824 | __entry->new_ptr) |
| 3825 | ); | 3825 | ); |
| 3826 | 3826 | ||
| 3827 | TRACE_EVENT(xfs_iunlink_reload_next, | ||
| 3828 | TP_PROTO(struct xfs_inode *ip), | ||
| 3829 | TP_ARGS(ip), | ||
| 3830 | TP_STRUCT__entry( | ||
| 3831 | __field(dev_t, dev) | ||
| 3832 | __field(xfs_agnumber_t, agno) | ||
| 3833 | __field(xfs_agino_t, agino) | ||
| 3834 | __field(xfs_agino_t, prev_agino) | ||
| 3835 | __field(xfs_agino_t, next_agino) | ||
| 3836 | ), | ||
| 3837 | TP_fast_assign( | ||
| 3838 | __entry->dev = ip->i_mount->m_super->s_dev; | ||
| 3839 | __entry->agno = XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino); | ||
| 3840 | __entry->agino = XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino); | ||
| 3841 | __entry->prev_agino = ip->i_prev_unlinked; | ||
| 3842 | __entry->next_agino = ip->i_next_unlinked; | ||
| 3843 | ), | ||
| 3844 | TP_printk("dev %d:%d agno 0x%x agino 0x%x prev_unlinked 0x%x next_unlinked 0x%x", | ||
| 3845 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
| 3846 | __entry->agno, | ||
| 3847 | __entry->agino, | ||
| 3848 | __entry->prev_agino, | ||
| 3849 | __entry->next_agino) | ||
| 3850 | ); | ||
| 3851 | |||
| 3852 | TRACE_EVENT(xfs_inode_reload_unlinked_bucket, | ||
| 3853 | TP_PROTO(struct xfs_inode *ip), | ||
| 3854 | TP_ARGS(ip), | ||
| 3855 | TP_STRUCT__entry( | ||
| 3856 | __field(dev_t, dev) | ||
| 3857 | __field(xfs_agnumber_t, agno) | ||
| 3858 | __field(xfs_agino_t, agino) | ||
| 3859 | ), | ||
| 3860 | TP_fast_assign( | ||
| 3861 | __entry->dev = ip->i_mount->m_super->s_dev; | ||
| 3862 | __entry->agno = XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino); | ||
| 3863 | __entry->agino = XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino); | ||
| 3864 | ), | ||
| 3865 | TP_printk("dev %d:%d agno 0x%x agino 0x%x bucket %u", | ||
| 3866 | MAJOR(__entry->dev), MINOR(__entry->dev), | ||
| 3867 | __entry->agno, | ||
| 3868 | __entry->agino, | ||
| 3869 | __entry->agino % XFS_AGI_UNLINKED_BUCKETS) | ||
| 3870 | ); | ||
| 3871 | |||
| 3827 | DECLARE_EVENT_CLASS(xfs_ag_inode_class, | 3872 | DECLARE_EVENT_CLASS(xfs_ag_inode_class, |
| 3828 | TP_PROTO(struct xfs_inode *ip), | 3873 | TP_PROTO(struct xfs_inode *ip), |
| 3829 | TP_ARGS(ip), | 3874 | TP_ARGS(ip), |
| @@ -46,6 +46,17 @@ xfs_attr_grab_log_assist( · 45 unmodified lines | |||
| 46 | if (xfs_sb_version_haslogxattrs(&mp->m_sb)) | 46 | if (xfs_sb_version_haslogxattrs(&mp->m_sb)) |
| 47 | return 0; | 47 | return 0; |
| 48 | 48 | ||
| 49 | /* | ||
| 50 | * Check if the filesystem featureset is new enough to set this log | ||
| 51 | * incompat feature bit. Strictly speaking, the minimum requirement is | ||
| 52 | * a V5 filesystem for the superblock field, but we'll require rmap | ||
| 53 | * or reflink to avoid having to deal with really old kernels. | ||
| 54 | */ | ||
| 55 | if (!xfs_has_reflink(mp) && !xfs_has_rmapbt(mp)) { | ||
| 56 | error = -EOPNOTSUPP; | ||
| 57 | goto drop_incompat; | ||
| 58 | } | ||
| 59 | |||
| 49 | /* Enable log-assisted xattrs. */ | 60 | /* Enable log-assisted xattrs. */ |
| 50 | error = xfs_add_incompat_log_feature(mp, | 61 | error = xfs_add_incompat_log_feature(mp, |
| 51 | XFS_SB_FEAT_INCOMPAT_LOG_XATTRS); | 62 | XFS_SB_FEAT_INCOMPAT_LOG_XATTRS); |
| @@ -76,7 +76,7 @@ static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb, · 75 unmodified lines | |||
| 76 | 76 | ||
| 77 | #ifndef __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 77 | #ifndef __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 78 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 78 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 79 | pte_t *ptep, pte_t pte) | 79 | pte_t *ptep, pte_t pte, unsigned long sz) |
| 80 | { | 80 | { |
| 81 | set_pte_at(mm, addr, ptep, pte); | 81 | set_pte_at(mm, addr, ptep, pte); |
| 82 | } | 82 | } |
| @@ -138,13 +138,6 @@ · 137 unmodified lines | |||
| 138 | * are handled as text/data or they can be discarded (which | 138 | * are handled as text/data or they can be discarded (which |
| 139 | * often happens at runtime) | 139 | * often happens at runtime) |
| 140 | */ | 140 | */ |
| 141 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 142 | #define CPU_KEEP(sec) *(.cpu##sec) | ||
| 143 | #define CPU_DISCARD(sec) | ||
| 144 | #else | ||
| 145 | #define CPU_KEEP(sec) | ||
| 146 | #define CPU_DISCARD(sec) *(.cpu##sec) | ||
| 147 | #endif | ||
| 148 | 141 | ||
| 149 | #if defined(CONFIG_MEMORY_HOTPLUG) | 142 | #if defined(CONFIG_MEMORY_HOTPLUG) |
| 150 | #define MEM_KEEP(sec) *(.mem##sec) | 143 | #define MEM_KEEP(sec) *(.mem##sec) |
| @@ -42,11 +42,13 @@ struct aer_capability_regs { · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | #if defined(CONFIG_PCIEAER) | 43 | #if defined(CONFIG_PCIEAER) |
| 44 | int pci_aer_clear_nonfatal_status(struct pci_dev *dev); | 44 | int pci_aer_clear_nonfatal_status(struct pci_dev *dev); |
| 45 | int pcie_aer_is_native(struct pci_dev *dev); | ||
| 45 | #else | 46 | #else |
| 46 | static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev) | 47 | static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev) |
| 47 | { | 48 | { |
| 48 | return -EINVAL; | 49 | return -EINVAL; |
| 49 | } | 50 | } |
| 51 | static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; } | ||
| 50 | #endif | 52 | #endif |
| 51 | 53 | ||
| 52 | void cper_print_aer(struct pci_dev *dev, int aer_severity, | 54 | void cper_print_aer(struct pci_dev *dev, int aer_severity, |
| @@ -67,6 +67,8 @@ · 66 unmodified lines | |||
| 67 | #define ARM_SMCCC_VERSION_1_3 0x10003 | 67 | #define ARM_SMCCC_VERSION_1_3 0x10003 |
| 68 | 68 | ||
| 69 | #define ARM_SMCCC_1_3_SVE_HINT 0x10000 | 69 | #define ARM_SMCCC_1_3_SVE_HINT 0x10000 |
| 70 | #define ARM_SMCCC_CALL_HINTS ARM_SMCCC_1_3_SVE_HINT | ||
| 71 | |||
| 70 | 72 | ||
| 71 | #define ARM_SMCCC_VERSION_FUNC_ID \ | 73 | #define ARM_SMCCC_VERSION_FUNC_ID \ |
| 72 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | 74 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ |
| @@ -459,8 +459,6 @@ raw_atomic_read_acquire(const atomic_t *v) · 458 unmodified lines | |||
| 459 | { | 459 | { |
| 460 | #if defined(arch_atomic_read_acquire) | 460 | #if defined(arch_atomic_read_acquire) |
| 461 | return arch_atomic_read_acquire(v); | 461 | return arch_atomic_read_acquire(v); |
| 462 | #elif defined(arch_atomic_read) | ||
| 463 | return arch_atomic_read(v); | ||
| 464 | #else | 462 | #else |
| 465 | int ret; | 463 | int ret; |
| 466 | 464 | ||
| @@ -508,8 +506,6 @@ raw_atomic_set_release(atomic_t *v, int i) · 41 unmodified lines | |||
| 508 | { | 506 | { |
| 509 | #if defined(arch_atomic_set_release) | 507 | #if defined(arch_atomic_set_release) |
| 510 | arch_atomic_set_release(v, i); | 508 | arch_atomic_set_release(v, i); |
| 511 | #elif defined(arch_atomic_set) | ||
| 512 | arch_atomic_set(v, i); | ||
| 513 | #else | 509 | #else |
| 514 | if (__native_word(atomic_t)) { | 510 | if (__native_word(atomic_t)) { |
| 515 | smp_store_release(&(v)->counter, i); | 511 | smp_store_release(&(v)->counter, i); |
| @@ -2575,8 +2571,6 @@ raw_atomic64_read_acquire(const atomic64_t *v) · 2059 unmodified lines | |||
| 2575 | { | 2571 | { |
| 2576 | #if defined(arch_atomic64_read_acquire) | 2572 | #if defined(arch_atomic64_read_acquire) |
| 2577 | return arch_atomic64_read_acquire(v); | 2573 | return arch_atomic64_read_acquire(v); |
| 2578 | #elif defined(arch_atomic64_read) | ||
| 2579 | return arch_atomic64_read(v); | ||
| 2580 | #else | 2574 | #else |
| 2581 | s64 ret; | 2575 | s64 ret; |
| 2582 | 2576 | ||
| @@ -2624,8 +2618,6 @@ raw_atomic64_set_release(atomic64_t *v, s64 i) · 41 unmodified lines | |||
| 2624 | { | 2618 | { |
| 2625 | #if defined(arch_atomic64_set_release) | 2619 | #if defined(arch_atomic64_set_release) |
| 2626 | arch_atomic64_set_release(v, i); | 2620 | arch_atomic64_set_release(v, i); |
| 2627 | #elif defined(arch_atomic64_set) | ||
| 2628 | arch_atomic64_set(v, i); | ||
| 2629 | #else | 2621 | #else |
| 2630 | if (__native_word(atomic64_t)) { | 2622 | if (__native_word(atomic64_t)) { |
| 2631 | smp_store_release(&(v)->counter, i); | 2623 | smp_store_release(&(v)->counter, i); |
| @@ -4657,4 +4649,4 @@ raw_atomic64_dec_if_positive(atomic64_t *v) · 2025 unmodified lines | |||
| 4657 | } | 4649 | } |
| 4658 | 4650 | ||
| 4659 | #endif /* _LINUX_ATOMIC_FALLBACK_H */ | 4651 | #endif /* _LINUX_ATOMIC_FALLBACK_H */ |
| 4660 | // 202b45c7db600ce36198eb1f1fc2c2d5268ace2d | 4652 | // 2fdd6702823fa842f9cea57a002e6e4476ae780c |
| @@ -1318,7 +1318,7 @@ static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, · 1317 unmodified lines | |||
| 1318 | static inline struct bpf_trampoline *bpf_trampoline_get(u64 key, | 1318 | static inline struct bpf_trampoline *bpf_trampoline_get(u64 key, |
| 1319 | struct bpf_attach_target_info *tgt_info) | 1319 | struct bpf_attach_target_info *tgt_info) |
| 1320 | { | 1320 | { |
| 1321 | return ERR_PTR(-EOPNOTSUPP); | 1321 | return NULL; |
| 1322 | } | 1322 | } |
| 1323 | static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {} | 1323 | static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {} |
| 1324 | #define DEFINE_BPF_DISPATCHER(name) | 1324 | #define DEFINE_BPF_DISPATCHER(name) |
| @@ -467,19 +467,17 @@ union ceph_mds_request_args { · 466 unmodified lines | |||
| 467 | } __attribute__ ((packed)); | 467 | } __attribute__ ((packed)); |
| 468 | 468 | ||
| 469 | union ceph_mds_request_args_ext { | 469 | union ceph_mds_request_args_ext { |
| 470 | union { | 470 | union ceph_mds_request_args old; |
| 471 | union ceph_mds_request_args old; | 471 | struct { |
| 472 | struct { | 472 | __le32 mode; |
| 473 | __le32 mode; | 473 | __le32 uid; |
| 474 | __le32 uid; | 474 | __le32 gid; |
| 475 | __le32 gid; | 475 | struct ceph_timespec mtime; |
| 476 | struct ceph_timespec mtime; | 476 | struct ceph_timespec atime; |
| 477 | struct ceph_timespec atime; | 477 | __le64 size, old_size; /* old_size needed by truncate */ |
| 478 | __le64 size, old_size; /* old_size needed by truncate */ | 478 | __le32 mask; /* CEPH_SETATTR_* */ |
| 479 | __le32 mask; /* CEPH_SETATTR_* */ | 479 | struct ceph_timespec btime; |
| 480 | struct ceph_timespec btime; | 480 | } __attribute__ ((packed)) setattr_ext; |
| 481 | } __attribute__ ((packed)) setattr_ext; | ||
| 482 | }; | ||
| 483 | }; | 481 | }; |
| 484 | 482 | ||
| 485 | #define CEPH_MDS_FLAG_REPLAY 1 /* this is a replayed op */ | 483 | #define CEPH_MDS_FLAG_REPLAY 1 /* this is a replayed op */ |
| @@ -90,7 +90,6 @@ enum cpuhp_state { · 89 unmodified lines | |||
| 90 | CPUHP_FS_BUFF_DEAD, | 90 | CPUHP_FS_BUFF_DEAD, |
| 91 | CPUHP_PRINTK_DEAD, | 91 | CPUHP_PRINTK_DEAD, |
| 92 | CPUHP_MM_MEMCQ_DEAD, | 92 | CPUHP_MM_MEMCQ_DEAD, |
| 93 | CPUHP_XFS_DEAD, | ||
| 94 | CPUHP_PERCPU_CNT_DEAD, | 93 | CPUHP_PERCPU_CNT_DEAD, |
| 95 | CPUHP_RADIX_DEAD, | 94 | CPUHP_RADIX_DEAD, |
| 96 | CPUHP_PAGE_ALLOC, | 95 | CPUHP_PAGE_ALLOC, |
| @@ -984,7 +984,9 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, · 983 unmodified lines | |||
| 984 | unsigned long addr, pte_t *ptep, | 984 | unsigned long addr, pte_t *ptep, |
| 985 | pte_t old_pte, pte_t pte) | 985 | pte_t old_pte, pte_t pte) |
| 986 | { | 986 | { |
| 987 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 987 | unsigned long psize = huge_page_size(hstate_vma(vma)); |
| 988 | |||
| 989 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize); | ||
| 988 | } | 990 | } |
| 989 | #endif | 991 | #endif |
| 990 | 992 | ||
| @@ -1173,7 +1175,7 @@ static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, · 182 unmodified lines | |||
| 1173 | } | 1175 | } |
| 1174 | 1176 | ||
| 1175 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 1177 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 1176 | pte_t *ptep, pte_t pte) | 1178 | pte_t *ptep, pte_t pte, unsigned long sz) |
| 1177 | { | 1179 | { |
| 1178 | } | 1180 | } |
| 1179 | 1181 | ||
| @@ -569,8 +569,12 @@ enum · 568 unmodified lines | |||
| 569 | * 2) rcu_report_dead() reports the final quiescent states. | 569 | * 2) rcu_report_dead() reports the final quiescent states. |
| 570 | * | 570 | * |
| 571 | * _ IRQ_POLL: irq_poll_cpu_dead() migrates the queue | 571 | * _ IRQ_POLL: irq_poll_cpu_dead() migrates the queue |
| 572 | * | ||
| 573 | * _ (HR)TIMER_SOFTIRQ: (hr)timers_dead_cpu() migrates the queue | ||
| 572 | */ | 574 | */ |
| 573 | #define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(RCU_SOFTIRQ) | BIT(IRQ_POLL_SOFTIRQ)) | 575 | #define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(TIMER_SOFTIRQ) | BIT(IRQ_POLL_SOFTIRQ) |\ |
| 576 | BIT(HRTIMER_SOFTIRQ) | BIT(RCU_SOFTIRQ)) | ||
| 577 | |||
| 574 | 578 | ||
| 575 | /* map softirq index to softirq name. update 'softirq_to_name' in | 579 | /* map softirq index to softirq name. update 'softirq_to_name' in |
| 576 | * kernel/softirq.c when adding a new softirq. | 580 | * kernel/softirq.c when adding a new softirq. |
| @@ -54,7 +54,7 @@ extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; · 53 unmodified lines | |||
| 54 | int kasan_populate_early_shadow(const void *shadow_start, | 54 | int kasan_populate_early_shadow(const void *shadow_start, |
| 55 | const void *shadow_end); | 55 | const void *shadow_end); |
| 56 | 56 | ||
| 57 | #ifndef __HAVE_ARCH_SHADOW_MAP | 57 | #ifndef kasan_mem_to_shadow |
| 58 | static inline void *kasan_mem_to_shadow(const void *addr) | 58 | static inline void *kasan_mem_to_shadow(const void *addr) |
| 59 | { | 59 | { |
| 60 | return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) | 60 | return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) |
| @@ -192,6 +192,7 @@ enum { · 191 unmodified lines | |||
| 192 | ATA_PFLAG_UNLOADING = (1 << 9), /* driver is being unloaded */ | 192 | ATA_PFLAG_UNLOADING = (1 << 9), /* driver is being unloaded */ |
| 193 | ATA_PFLAG_UNLOADED = (1 << 10), /* driver is unloaded */ | 193 | ATA_PFLAG_UNLOADED = (1 << 10), /* driver is unloaded */ |
| 194 | 194 | ||
| 195 | ATA_PFLAG_RESUMING = (1 << 16), /* port is being resumed */ | ||
| 195 | ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ | 196 | ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ |
| 196 | ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ | 197 | ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ |
| 197 | ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */ | 198 | ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */ |
| @@ -259,7 +260,7 @@ enum { · 61 unmodified lines | |||
| 259 | * advised to wait only for the following duration before | 260 | * advised to wait only for the following duration before |
| 260 | * doing SRST. | 261 | * doing SRST. |
| 261 | */ | 262 | */ |
| 262 | ATA_TMOUT_PMP_SRST_WAIT = 5000, | 263 | ATA_TMOUT_PMP_SRST_WAIT = 10000, |
| 263 | 264 | ||
| 264 | /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might | 265 | /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might |
| 265 | * be a spurious PHY event, so ignore the first PHY event that | 266 | * be a spurious PHY event, so ignore the first PHY event that |
| @@ -318,9 +319,10 @@ enum { · 52 unmodified lines | |||
| 318 | ATA_EH_ENABLE_LINK = (1 << 3), | 319 | ATA_EH_ENABLE_LINK = (1 << 3), |
| 319 | ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */ | 320 | ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */ |
| 320 | ATA_EH_GET_SUCCESS_SENSE = (1 << 6), /* Get sense data for successful cmd */ | 321 | ATA_EH_GET_SUCCESS_SENSE = (1 << 6), /* Get sense data for successful cmd */ |
| 322 | ATA_EH_SET_ACTIVE = (1 << 7), /* Set a device to active power mode */ | ||
| 321 | 323 | ||
| 322 | ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK | | 324 | ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK | |
| 323 | ATA_EH_GET_SUCCESS_SENSE, | 325 | ATA_EH_GET_SUCCESS_SENSE | ATA_EH_SET_ACTIVE, |
| 324 | ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | | 326 | ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | |
| 325 | ATA_EH_ENABLE_LINK, | 327 | ATA_EH_ENABLE_LINK, |
| 326 | 328 | ||
| @@ -357,7 +359,7 @@ enum { · 30 unmodified lines | |||
| 357 | /* This should match the actual table size of | 359 | /* This should match the actual table size of |
| 358 | * ata_eh_cmd_timeout_table in libata-eh.c. | 360 | * ata_eh_cmd_timeout_table in libata-eh.c. |
| 359 | */ | 361 | */ |
| 360 | ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 7, | 362 | ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 8, |
| 361 | 363 | ||
| 362 | /* Horkage types. May be set by libata or controller on drives | 364 | /* Horkage types. May be set by libata or controller on drives |
| 363 | (some horkage may be drive/controller pair dependent */ | 365 | (some horkage may be drive/controller pair dependent */ |
| @@ -1148,6 +1150,7 @@ extern int ata_std_bios_param(struct scsi_device *sdev, · 784 unmodified lines | |||
| 1148 | struct block_device *bdev, | 1150 | struct block_device *bdev, |
| 1149 | sector_t capacity, int geom[]); | 1151 | sector_t capacity, int geom[]); |
| 1150 | extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); | 1152 | extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); |
| 1153 | extern int ata_scsi_slave_alloc(struct scsi_device *sdev); | ||
| 1151 | extern int ata_scsi_slave_config(struct scsi_device *sdev); | 1154 | extern int ata_scsi_slave_config(struct scsi_device *sdev); |
| 1152 | extern void ata_scsi_slave_destroy(struct scsi_device *sdev); | 1155 | extern void ata_scsi_slave_destroy(struct scsi_device *sdev); |
| 1153 | extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, | 1156 | extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, |
| @@ -1396,6 +1399,7 @@ extern const struct attribute_group *ata_common_sdev_groups[]; · 242 unmodified lines | |||
| 1396 | .this_id = ATA_SHT_THIS_ID, \ | 1399 | .this_id = ATA_SHT_THIS_ID, \ |
| 1397 | .emulated = ATA_SHT_EMULATED, \ | 1400 | .emulated = ATA_SHT_EMULATED, \ |
| 1398 | .proc_name = drv_name, \ | 1401 | .proc_name = drv_name, \ |
| 1402 | .slave_alloc = ata_scsi_slave_alloc, \ | ||
| 1399 | .slave_destroy = ata_scsi_slave_destroy, \ | 1403 | .slave_destroy = ata_scsi_slave_destroy, \ |
| 1400 | .bios_param = ata_std_bios_param, \ | 1404 | .bios_param = ata_std_bios_param, \ |
| 1401 | .unlock_native_capacity = ata_scsi_unlock_native_capacity,\ | 1405 | .unlock_native_capacity = ata_scsi_unlock_native_capacity,\ |
| @@ -428,6 +428,8 @@ struct ma_wr_state { · 427 unmodified lines | |||
| 428 | #define MAS_ROOT ((struct maple_enode *)5UL) | 428 | #define MAS_ROOT ((struct maple_enode *)5UL) |
| 429 | #define MAS_NONE ((struct maple_enode *)9UL) | 429 | #define MAS_NONE ((struct maple_enode *)9UL) |
| 430 | #define MAS_PAUSE ((struct maple_enode *)17UL) | 430 | #define MAS_PAUSE ((struct maple_enode *)17UL) |
| 431 | #define MAS_OVERFLOW ((struct maple_enode *)33UL) | ||
| 432 | #define MAS_UNDERFLOW ((struct maple_enode *)65UL) | ||
| 431 | #define MA_ERROR(err) \ | 433 | #define MA_ERROR(err) \ |
| 432 | ((struct maple_enode *)(((unsigned long)err << 2) | 2UL)) | 434 | ((struct maple_enode *)(((unsigned long)err << 2) | 2UL)) |
| 433 | 435 | ||
| @@ -511,6 +513,15 @@ static inline bool mas_is_paused(const struct ma_state *mas) · 77 unmodified lines | |||
| 511 | return mas->node == MAS_PAUSE; | 513 | return mas->node == MAS_PAUSE; |
| 512 | } | 514 | } |
| 513 | 515 | ||
| 516 | /* Check if the mas is pointing to a node or not */ | ||
| 517 | static inline bool mas_is_active(struct ma_state *mas) | ||
| 518 | { | ||
| 519 | if ((unsigned long)mas->node >= MAPLE_RESERVED_RANGE) | ||
| 520 | return true; | ||
| 521 | |||
| 522 | return false; | ||
| 523 | } | ||
| 524 | |||
| 514 | /** | 525 | /** |
| 515 | * mas_reset() - Reset a Maple Tree operation state. | 526 | * mas_reset() - Reset a Maple Tree operation state. |
| 516 | * @mas: Maple Tree operation state. | 527 | * @mas: Maple Tree operation state. |
| @@ -920,7 +920,7 @@ unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec, · 919 unmodified lines | |||
| 920 | return READ_ONCE(mz->lru_zone_size[zone_idx][lru]); | 920 | return READ_ONCE(mz->lru_zone_size[zone_idx][lru]); |
| 921 | } | 921 | } |
| 922 | 922 | ||
| 923 | void mem_cgroup_handle_over_high(void); | 923 | void mem_cgroup_handle_over_high(gfp_t gfp_mask); |
| 924 | 924 | ||
| 925 | unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); | 925 | unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); |
| 926 | 926 | ||
| @@ -1458,7 +1458,7 @@ static inline void mem_cgroup_unlock_pages(void) · 531 unmodified lines | |||
| 1458 | rcu_read_unlock(); | 1458 | rcu_read_unlock(); |
| 1459 | } | 1459 | } |
| 1460 | 1460 | ||
| 1461 | static inline void mem_cgroup_handle_over_high(void) | 1461 | static inline void mem_cgroup_handle_over_high(gfp_t gfp_mask) |
| 1462 | { | 1462 | { |
| 1463 | } | 1463 | } |
| 1464 | 1464 | ||
| @@ -9,6 +9,7 @@ struct ip_ct_sctp { · 8 unmodified lines | |||
| 9 | enum sctp_conntrack state; | 9 | enum sctp_conntrack state; |
| 10 | 10 | ||
| 11 | __be32 vtag[IP_CT_DIR_MAX]; | 11 | __be32 vtag[IP_CT_DIR_MAX]; |
| 12 | u8 init[IP_CT_DIR_MAX]; | ||
| 12 | u8 last_dir; | 13 | u8 last_dir; |
| 13 | u8 flags; | 14 | u8 flags; |
| 14 | }; | 15 | }; |
| @@ -206,6 +206,14 @@ static inline int pmd_young(pmd_t pmd) · 205 unmodified lines | |||
| 206 | #endif | 206 | #endif |
| 207 | 207 | ||
| 208 | #ifndef set_ptes | 208 | #ifndef set_ptes |
| 209 | |||
| 210 | #ifndef pte_next_pfn | ||
| 211 | static inline pte_t pte_next_pfn(pte_t pte) | ||
| 212 | { | ||
| 213 | return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT)); | ||
| 214 | } | ||
| 215 | #endif | ||
| 216 | |||
| 209 | /** | 217 | /** |
| 210 | * set_ptes - Map consecutive pages to a contiguous range of addresses. | 218 | * set_ptes - Map consecutive pages to a contiguous range of addresses. |
| 211 | * @mm: Address space to map the pages into. | 219 | * @mm: Address space to map the pages into. |
| @@ -231,7 +239,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr, · 19 unmodified lines | |||
| 231 | if (--nr == 0) | 239 | if (--nr == 0) |
| 232 | break; | 240 | break; |
| 233 | ptep++; | 241 | ptep++; |
| 234 | pte = __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT)); | 242 | pte = pte_next_pfn(pte); |
| 235 | } | 243 | } |
| 236 | arch_leave_lazy_mmu_mode(); | 244 | arch_leave_lazy_mmu_mode(); |
| 237 | } | 245 | } |
| @@ -55,7 +55,7 @@ static inline void resume_user_mode_work(struct pt_regs *regs) · 54 unmodified lines | |||
| 55 | } | 55 | } |
| 56 | #endif | 56 | #endif |
| 57 | 57 | ||
| 58 | mem_cgroup_handle_over_high(); | 58 | mem_cgroup_handle_over_high(GFP_KERNEL); |
| 59 | blkcg_maybe_throttle_current(); | 59 | blkcg_maybe_throttle_current(); |
| 60 | 60 | ||
| 61 | rseq_handle_notify_resume(NULL, regs); | 61 | rseq_handle_notify_resume(NULL, regs); |
| @@ -512,8 +512,8 @@ do { \ · 511 unmodified lines | |||
| 512 | 512 | ||
| 513 | static inline void do_write_seqcount_begin_nested(seqcount_t *s, int subclass) | 513 | static inline void do_write_seqcount_begin_nested(seqcount_t *s, int subclass) |
| 514 | { | 514 | { |
| 515 | do_raw_write_seqcount_begin(s); | ||
| 516 | seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_); | 515 | seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_); |
| 516 | do_raw_write_seqcount_begin(s); | ||
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | /** | 519 | /** |
| @@ -172,14 +172,23 @@ static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) · 171 unmodified lines | |||
| 172 | if (!mem) | 172 | if (!mem) |
| 173 | return false; | 173 | return false; |
| 174 | 174 | ||
| 175 | if (IS_ENABLED(CONFIG_SWIOTLB_DYNAMIC)) { | 175 | #ifdef CONFIG_SWIOTLB_DYNAMIC |
| 176 | /* Pairs with smp_wmb() in swiotlb_find_slots() and | 176 | /* |
| 177 | * swiotlb_dyn_alloc(), which modify the RCU lists. | 177 | * All SWIOTLB buffer addresses must have been returned by |
| 178 | */ | 178 | * swiotlb_tbl_map_single() and passed to a device driver. |
| 179 | smp_rmb(); | 179 | * If a SWIOTLB address is checked on another CPU, then it was |
| 180 | return swiotlb_find_pool(dev, paddr); | 180 | * presumably loaded by the device driver from an unspecified private |
| 181 | } | 181 | * data structure. Make sure that this load is ordered before reading |
| 182 | * dev->dma_uses_io_tlb here and mem->pools in swiotlb_find_pool(). | ||
| 183 | * | ||
| 184 | * This barrier pairs with smp_mb() in swiotlb_find_slots(). | ||
| 185 | */ | ||
| 186 | smp_rmb(); | ||
| 187 | return READ_ONCE(dev->dma_uses_io_tlb) && | ||
| 188 | swiotlb_find_pool(dev, paddr); | ||
| 189 | #else | ||
| 182 | return paddr >= mem->defpool.start && paddr < mem->defpool.end; | 190 | return paddr >= mem->defpool.start && paddr < mem->defpool.end; |
| 191 | #endif | ||
| 183 | } | 192 | } |
| 184 | 193 | ||
| 185 | static inline bool is_swiotlb_force_bounce(struct device *dev) | 194 | static inline bool is_swiotlb_force_bounce(struct device *dev) |
| @@ -350,7 +350,7 @@ struct hci_dev { · 349 unmodified lines | |||
| 350 | struct list_head list; | 350 | struct list_head list; |
| 351 | struct mutex lock; | 351 | struct mutex lock; |
| 352 | 352 | ||
| 353 | char name[8]; | 353 | const char *name; |
| 354 | unsigned long flags; | 354 | unsigned long flags; |
| 355 | __u16 id; | 355 | __u16 id; |
| 356 | __u8 bus; | 356 | __u8 bus; |
| @@ -5941,6 +5941,7 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy, · 5940 unmodified lines | |||
| 5941 | * @event_lock: (private) lock for event list | 5941 | * @event_lock: (private) lock for event list |
| 5942 | * @owner_nlportid: (private) owner socket port ID | 5942 | * @owner_nlportid: (private) owner socket port ID |
| 5943 | * @nl_owner_dead: (private) owner socket went away | 5943 | * @nl_owner_dead: (private) owner socket went away |
| 5944 | * @cqm_rssi_work: (private) CQM RSSI reporting work | ||
| 5944 | * @cqm_config: (private) nl80211 RSSI monitor state | 5945 | * @cqm_config: (private) nl80211 RSSI monitor state |
| 5945 | * @pmsr_list: (private) peer measurement requests | 5946 | * @pmsr_list: (private) peer measurement requests |
| 5946 | * @pmsr_lock: (private) peer measurements requests/results lock | 5947 | * @pmsr_lock: (private) peer measurements requests/results lock |
| @@ -6013,7 +6014,8 @@ struct wireless_dev { · 66 unmodified lines | |||
| 6013 | } wext; | 6014 | } wext; |
| 6014 | #endif | 6015 | #endif |
| 6015 | 6016 | ||
| 6016 | struct cfg80211_cqm_config *cqm_config; | 6017 | struct wiphy_work cqm_rssi_work; |
| 6018 | struct cfg80211_cqm_config __rcu *cqm_config; | ||
| 6017 | 6019 | ||
| 6018 | struct list_head pmsr_list; | 6020 | struct list_head pmsr_list; |
| 6019 | spinlock_t pmsr_lock; | 6021 | spinlock_t pmsr_lock; |
| @@ -7231,7 +7233,7 @@ struct cfg80211_rx_assoc_resp { · 1211 unmodified lines | |||
| 7231 | int uapsd_queues; | 7233 | int uapsd_queues; |
| 7232 | const u8 *ap_mld_addr; | 7234 | const u8 *ap_mld_addr; |
| 7233 | struct { | 7235 | struct { |
| 7234 | const u8 *addr; | 7236 | u8 addr[ETH_ALEN] __aligned(2); |
| 7235 | struct cfg80211_bss *bss; | 7237 | struct cfg80211_bss *bss; |
| 7236 | u16 status; | 7238 | u16 status; |
| 7237 | } links[IEEE80211_MLD_MAX_NUM_LINKS]; | 7239 | } links[IEEE80211_MLD_MAX_NUM_LINKS]; |
| @@ -154,6 +154,7 @@ struct fib_info { · 153 unmodified lines | |||
| 154 | int fib_nhs; | 154 | int fib_nhs; |
| 155 | bool fib_nh_is_v6; | 155 | bool fib_nh_is_v6; |
| 156 | bool nh_updated; | 156 | bool nh_updated; |
| 157 | bool pfsrc_removed; | ||
| 157 | struct nexthop *nh; | 158 | struct nexthop *nh; |
| 158 | struct rcu_head rcu; | 159 | struct rcu_head rcu; |
| 159 | struct fib_nh fib_nh[] __counted_by(fib_nhs); | 160 | struct fib_nh fib_nh[] __counted_by(fib_nhs); |
| @@ -103,9 +103,10 @@ struct mana_txq { · 102 unmodified lines | |||
| 103 | 103 | ||
| 104 | /* skb data and frags dma mappings */ | 104 | /* skb data and frags dma mappings */ |
| 105 | struct mana_skb_head { | 105 | struct mana_skb_head { |
| 106 | dma_addr_t dma_handle[MAX_SKB_FRAGS + 1]; | 106 | /* GSO pkts may have 2 SGEs for the linear part*/ |
| 107 | dma_addr_t dma_handle[MAX_SKB_FRAGS + 2]; | ||
| 107 | 108 | ||
| 108 | u32 size[MAX_SKB_FRAGS + 1]; | 109 | u32 size[MAX_SKB_FRAGS + 2]; |
| 109 | }; | 110 | }; |
| 110 | 111 | ||
| 111 | #define MANA_HEADROOM sizeof(struct mana_skb_head) | 112 | #define MANA_HEADROOM sizeof(struct mana_skb_head) |
| @@ -539,7 +539,7 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb, · 538 unmodified lines | |||
| 539 | READ_ONCE(hh->hh_len)) | 539 | READ_ONCE(hh->hh_len)) |
| 540 | return neigh_hh_output(hh, skb); | 540 | return neigh_hh_output(hh, skb); |
| 541 | 541 | ||
| 542 | return n->output(n, skb); | 542 | return READ_ONCE(n->output)(n, skb); |
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | static inline struct neighbour * | 545 | static inline struct neighbour * |
| @@ -16,13 +16,13 @@ · 15 unmodified lines | |||
| 16 | * page_pool_alloc_pages() call. Drivers should use | 16 | * page_pool_alloc_pages() call. Drivers should use |
| 17 | * page_pool_dev_alloc_pages() replacing dev_alloc_pages(). | 17 | * page_pool_dev_alloc_pages() replacing dev_alloc_pages(). |
| 18 | * | 18 | * |
| 19 | * API keeps track of in-flight pages, in order to let API user know | 19 | * The API keeps track of in-flight pages, in order to let API users know |
| 20 | * when it is safe to free a page_pool object. Thus, API users | 20 | * when it is safe to free a page_pool object. Thus, API users |
| 21 | * must call page_pool_put_page() to free the page, or attach | 21 | * must call page_pool_put_page() to free the page, or attach |
| 22 | * the page to a page_pool-aware objects like skbs marked with | 22 | * the page to a page_pool-aware object like skbs marked with |
| 23 | * skb_mark_for_recycle(). | 23 | * skb_mark_for_recycle(). |
| 24 | * | 24 | * |
| 25 | * API user must call page_pool_put_page() once on a page, as it | 25 | * API users must call page_pool_put_page() once on a page, as it |
| 26 | * will either recycle the page, or in case of refcnt > 1, it will | 26 | * will either recycle the page, or in case of refcnt > 1, it will |
| 27 | * release the DMA mapping and in-flight state accounting. | 27 | * release the DMA mapping and in-flight state accounting. |
| 28 | */ | 28 | */ |
| @@ -348,12 +348,14 @@ ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, · 347 unmodified lines | |||
| 348 | struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, gfp_t gfp, | 348 | struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, gfp_t gfp, |
| 349 | bool force_schedule); | 349 | bool force_schedule); |
| 350 | 350 | ||
| 351 | static inline void tcp_dec_quickack_mode(struct sock *sk, | 351 | static inline void tcp_dec_quickack_mode(struct sock *sk) |
| 352 | const unsigned int pkts) | ||
| 353 | { | 352 | { |
| 354 | struct inet_connection_sock *icsk = inet_csk(sk); | 353 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 355 | 354 | ||
| 356 | if (icsk->icsk_ack.quick) { | 355 | if (icsk->icsk_ack.quick) { |
| 356 | /* How many ACKs S/ACKing new data have we sent? */ | ||
| 357 | const unsigned int pkts = inet_csk_ack_scheduled(sk) ? 1 : 0; | ||
| 358 | |||
| 357 | if (pkts >= icsk->icsk_ack.quick) { | 359 | if (pkts >= icsk->icsk_ack.quick) { |
| 358 | icsk->icsk_ack.quick = 0; | 360 | icsk->icsk_ack.quick = 0; |
| 359 | /* Leaving quickack mode we deflate ATO. */ | 361 | /* Leaving quickack mode we deflate ATO. */ |
| @@ -157,6 +157,9 @@ enum scsi_disposition { · 156 unmodified lines | |||
| 157 | #define SCSI_3 4 /* SPC */ | 157 | #define SCSI_3 4 /* SPC */ |
| 158 | #define SCSI_SPC_2 5 | 158 | #define SCSI_SPC_2 5 |
| 159 | #define SCSI_SPC_3 6 | 159 | #define SCSI_SPC_3 6 |
| 160 | #define SCSI_SPC_4 7 | ||
| 161 | #define SCSI_SPC_5 8 | ||
| 162 | #define SCSI_SPC_6 14 | ||
| 160 | 163 | ||
| 161 | /* | 164 | /* |
| 162 | * INQ PERIPHERAL QUALIFIERS | 165 | * INQ PERIPHERAL QUALIFIERS |
| @@ -161,6 +161,10 @@ struct scsi_device { · 160 unmodified lines | |||
| 161 | * pass settings from slave_alloc to scsi | 161 | * pass settings from slave_alloc to scsi |
| 162 | * core. */ | 162 | * core. */ |
| 163 | unsigned int eh_timeout; /* Error handling timeout */ | 163 | unsigned int eh_timeout; /* Error handling timeout */ |
| 164 | |||
| 165 | bool manage_system_start_stop; /* Let HLD (sd) manage system start/stop */ | ||
| 166 | bool manage_runtime_start_stop; /* Let HLD (sd) manage runtime start/stop */ | ||
| 167 | |||
| 164 | unsigned removable:1; | 168 | unsigned removable:1; |
| 165 | unsigned changed:1; /* Data invalid due to media change */ | 169 | unsigned changed:1; /* Data invalid due to media change */ |
| 166 | unsigned busy:1; /* Used to prevent races */ | 170 | unsigned busy:1; /* Used to prevent races */ |
| @@ -193,7 +197,6 @@ struct scsi_device { · 26 unmodified lines | |||
| 193 | unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ | 197 | unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ |
| 194 | unsigned no_start_on_add:1; /* do not issue start on add */ | 198 | unsigned no_start_on_add:1; /* do not issue start on add */ |
| 195 | unsigned allow_restart:1; /* issue START_UNIT in error handler */ | 199 | unsigned allow_restart:1; /* issue START_UNIT in error handler */ |
| 196 | unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ | ||
| 197 | unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */ | 200 | unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */ |
| 198 | unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ | 201 | unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ |
| 199 | unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ | 202 | unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ |
| @@ -764,7 +764,7 @@ scsi_template_proc_dir(const struct scsi_host_template *sht); · 763 unmodified lines | |||
| 764 | #define scsi_template_proc_dir(sht) NULL | 764 | #define scsi_template_proc_dir(sht) NULL |
| 765 | #endif | 765 | #endif |
| 766 | extern void scsi_scan_host(struct Scsi_Host *); | 766 | extern void scsi_scan_host(struct Scsi_Host *); |
| 767 | extern void scsi_rescan_device(struct scsi_device *); | 767 | extern int scsi_rescan_device(struct scsi_device *sdev); |
| 768 | extern void scsi_remove_host(struct Scsi_Host *); | 768 | extern void scsi_remove_host(struct Scsi_Host *); |
| 769 | extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); | 769 | extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); |
| 770 | extern int scsi_host_busy(struct Scsi_Host *shost); | 770 | extern int scsi_host_busy(struct Scsi_Host *shost); |
| @@ -29,6 +29,11 @@ · 28 unmodified lines | |||
| 29 | struct TAG { MEMBERS } ATTRS NAME; \ | 29 | struct TAG { MEMBERS } ATTRS NAME; \ |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | #ifdef __cplusplus | ||
| 33 | /* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ | ||
| 34 | #define __DECLARE_FLEX_ARRAY(T, member) \ | ||
| 35 | T member[0] | ||
| 36 | #else | ||
| 32 | /** | 37 | /** |
| 33 | * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union | 38 | * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union |
| 34 | * | 39 | * |
| @@ -49,3 +54,5 @@ · 14 unmodified lines | |||
| 49 | #ifndef __counted_by | 54 | #ifndef __counted_by |
| 50 | #define __counted_by(m) | 55 | #define __counted_by(m) |
| 51 | #endif | 56 | #endif |
| 57 | |||
| 58 | #endif /* _UAPI_LINUX_STDDEF_H */ | ||
| @@ -243,7 +243,7 @@ int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 242 unmodified lines | |||
| 243 | struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link); | 243 | struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link); |
| 244 | const char __user *oldf, *newf; | 244 | const char __user *oldf, *newf; |
| 245 | 245 | ||
| 246 | if (sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in) | 246 | if (sqe->buf_index || sqe->splice_fd_in) |
| 247 | return -EINVAL; | 247 | return -EINVAL; |
| 248 | if (unlikely(req->flags & REQ_F_FIXED_FILE)) | 248 | if (unlikely(req->flags & REQ_F_FIXED_FILE)) |
| 249 | return -EBADF; | 249 | return -EBADF; |
| @@ -973,37 +973,31 @@ void notrace *bpf_mem_cache_alloc_flags(struct bpf_mem_alloc *ma, gfp_t flags) · 972 unmodified lines | |||
| 973 | return !ret ? NULL : ret + LLIST_NODE_SZ; | 973 | return !ret ? NULL : ret + LLIST_NODE_SZ; |
| 974 | } | 974 | } |
| 975 | 975 | ||
| 976 | /* Most of the logic is taken from setup_kmalloc_cache_index_table() */ | ||
| 977 | static __init int bpf_mem_cache_adjust_size(void) | 976 | static __init int bpf_mem_cache_adjust_size(void) |
| 978 | { | 977 | { |
| 979 | unsigned int size, index; | 978 | unsigned int size; |
| 980 | 979 | ||
| 981 | /* Normally KMALLOC_MIN_SIZE is 8-bytes, but it can be | 980 | /* Adjusting the indexes in size_index() according to the object_size |
| 982 | * up-to 256-bytes. | 981 | * of underlying slab cache, so bpf_mem_alloc() will select a |
| 982 | * bpf_mem_cache with unit_size equal to the object_size of | ||
| 983 | * the underlying slab cache. | ||
| 984 | * | ||
| 985 | * The maximal value of KMALLOC_MIN_SIZE and __kmalloc_minalign() is | ||
| 986 | * 256-bytes, so only do adjustment for [8-bytes, 192-bytes]. | ||
| 983 | */ | 987 | */ |
| 984 | size = KMALLOC_MIN_SIZE; | 988 | for (size = 192; size >= 8; size -= 8) { |
| 985 | if (size <= 192) | 989 | unsigned int kmalloc_size, index; |
| 986 | index = size_index[(size - 1) / 8]; | ||
| 987 | else | ||
| 988 | index = fls(size - 1) - 1; | ||
| 989 | for (size = 8; size < KMALLOC_MIN_SIZE && size <= 192; size += 8) | ||
| 990 | size_index[(size - 1) / 8] = index; | ||
| 991 | 990 | ||
| 992 | /* The minimal alignment is 64-bytes, so disable 96-bytes cache and | 991 | kmalloc_size = kmalloc_size_roundup(size); |
| 993 | * use 128-bytes cache instead. | 992 | if (kmalloc_size == size) |
| 994 | */ | 993 | continue; |
| 995 | if (KMALLOC_MIN_SIZE >= 64) { | ||
| 996 | index = size_index[(128 - 1) / 8]; | ||
| 997 | for (size = 64 + 8; size <= 96; size += 8) | ||
| 998 | size_index[(size - 1) / 8] = index; | ||
| 999 | } | ||
| 1000 | 994 | ||
| 1001 | /* The minimal alignment is 128-bytes, so disable 192-bytes cache and | 995 | if (kmalloc_size <= 192) |
| 1002 | * use 256-bytes cache instead. | 996 | index = size_index[(kmalloc_size - 1) / 8]; |
| 1003 | */ | 997 | else |
| 1004 | if (KMALLOC_MIN_SIZE >= 128) { | 998 | index = fls(kmalloc_size - 1) - 1; |
| 1005 | index = fls(256 - 1) - 1; | 999 | /* Only overwrite if necessary */ |
| 1006 | for (size = 128 + 8; size <= 192; size += 8) | 1000 | if (size_index[(size - 1) / 8] != index) |
| 1007 | size_index[(size - 1) / 8] = index; | 1001 | size_index[(size - 1) / 8] = index; |
| 1008 | } | 1002 | } |
| 1009 | 1003 | ||
| @@ -253,6 +253,9 @@ int bpf_mprog_attach(struct bpf_mprog_entry *entry, · 252 unmodified lines | |||
| 253 | goto out; | 253 | goto out; |
| 254 | } | 254 | } |
| 255 | idx = tidx; | 255 | idx = tidx; |
| 256 | } else if (bpf_mprog_total(entry) == bpf_mprog_max()) { | ||
| 257 | ret = -ERANGE; | ||
| 258 | goto out; | ||
| 256 | } | 259 | } |
| 257 | if (flags & BPF_F_BEFORE) { | 260 | if (flags & BPF_F_BEFORE) { |
| 258 | tidx = bpf_mprog_pos_before(entry, &rtuple); | 261 | tidx = bpf_mprog_pos_before(entry, &rtuple); |
| @@ -4132,11 +4132,9 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno) · 4131 unmodified lines | |||
| 4132 | bitmap_from_u64(mask, bt_reg_mask(bt)); | 4132 | bitmap_from_u64(mask, bt_reg_mask(bt)); |
| 4133 | for_each_set_bit(i, mask, 32) { | 4133 | for_each_set_bit(i, mask, 32) { |
| 4134 | reg = &st->frame[0]->regs[i]; | 4134 | reg = &st->frame[0]->regs[i]; |
| 4135 | if (reg->type != SCALAR_VALUE) { | 4135 | bt_clear_reg(bt, i); |
| 4136 | bt_clear_reg(bt, i); | 4136 | if (reg->type == SCALAR_VALUE) |
| 4137 | continue; | 4137 | reg->precise = true; |
| 4138 | } | ||
| 4139 | reg->precise = true; | ||
| 4140 | } | 4138 | } |
| 4141 | return 0; | 4139 | return 0; |
| 4142 | } | 4140 | } |
| @@ -739,6 +739,17 @@ subsys_initcall(crash_notes_memory_init); · 738 unmodified lines | |||
| 739 | #undef pr_fmt | 739 | #undef pr_fmt |
| 740 | #define pr_fmt(fmt) "crash hp: " fmt | 740 | #define pr_fmt(fmt) "crash hp: " fmt |
| 741 | 741 | ||
| 742 | /* | ||
| 743 | * Different than kexec/kdump loading/unloading/jumping/shrinking which | ||
| 744 | * usually rarely happen, there will be many crash hotplug events notified | ||
| 745 | * during one short period, e.g one memory board is hot added and memory | ||
| 746 | * regions are online. So mutex lock __crash_hotplug_lock is used to | ||
| 747 | * serialize the crash hotplug handling specifically. | ||
| 748 | */ | ||
| 749 | DEFINE_MUTEX(__crash_hotplug_lock); | ||
| 750 | #define crash_hotplug_lock() mutex_lock(&__crash_hotplug_lock) | ||
| 751 | #define crash_hotplug_unlock() mutex_unlock(&__crash_hotplug_lock) | ||
| 752 | |||
| 742 | /* | 753 | /* |
| 743 | * This routine utilized when the crash_hotplug sysfs node is read. | 754 | * This routine utilized when the crash_hotplug sysfs node is read. |
| 744 | * It reflects the kernel's ability/permission to update the crash | 755 | * It reflects the kernel's ability/permission to update the crash |
| @@ -748,9 +759,11 @@ int crash_check_update_elfcorehdr(void) · 3 unmodified lines | |||
| 748 | { | 759 | { |
| 749 | int rc = 0; | 760 | int rc = 0; |
| 750 | 761 | ||
| 762 | crash_hotplug_lock(); | ||
| 751 | /* Obtain lock while reading crash information */ | 763 | /* Obtain lock while reading crash information */ |
| 752 | if (!kexec_trylock()) { | 764 | if (!kexec_trylock()) { |
| 753 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); | 765 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); |
| 766 | crash_hotplug_unlock(); | ||
| 754 | return 0; | 767 | return 0; |
| 755 | } | 768 | } |
| 756 | if (kexec_crash_image) { | 769 | if (kexec_crash_image) { |
| @@ -761,6 +774,7 @@ int crash_check_update_elfcorehdr(void) · 4 unmodified lines | |||
| 761 | } | 774 | } |
| 762 | /* Release lock now that update complete */ | 775 | /* Release lock now that update complete */ |
| 763 | kexec_unlock(); | 776 | kexec_unlock(); |
| 777 | crash_hotplug_unlock(); | ||
| 764 | 778 | ||
| 765 | return rc; | 779 | return rc; |
| 766 | } | 780 | } |
| @@ -783,9 +797,11 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) · 16 unmodified lines | |||
| 783 | { | 797 | { |
| 784 | struct kimage *image; | 798 | struct kimage *image; |
| 785 | 799 | ||
| 800 | crash_hotplug_lock(); | ||
| 786 | /* Obtain lock while changing crash information */ | 801 | /* Obtain lock while changing crash information */ |
| 787 | if (!kexec_trylock()) { | 802 | if (!kexec_trylock()) { |
| 788 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); | 803 | pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); |
| 804 | crash_hotplug_unlock(); | ||
| 789 | return; | 805 | return; |
| 790 | } | 806 | } |
| 791 | 807 | ||
| @@ -852,6 +868,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) · 60 unmodified lines | |||
| 852 | out: | 868 | out: |
| 853 | /* Release lock now that update complete */ | 869 | /* Release lock now that update complete */ |
| 854 | kexec_unlock(); | 870 | kexec_unlock(); |
| 871 | crash_hotplug_unlock(); | ||
| 855 | } | 872 | } |
| 856 | 873 | ||
| 857 | static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v) | 874 | static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v) |
| @@ -399,14 +399,13 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags, · 398 unmodified lines | |||
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | mem->areas = memblock_alloc(array_size(sizeof(struct io_tlb_area), | 401 | mem->areas = memblock_alloc(array_size(sizeof(struct io_tlb_area), |
| 402 | default_nareas), SMP_CACHE_BYTES); | 402 | nareas), SMP_CACHE_BYTES); |
| 403 | if (!mem->areas) { | 403 | if (!mem->areas) { |
| 404 | pr_warn("%s: Failed to allocate mem->areas.\n", __func__); | 404 | pr_warn("%s: Failed to allocate mem->areas.\n", __func__); |
| 405 | return; | 405 | return; |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | swiotlb_init_io_tlb_pool(mem, __pa(tlb), nslabs, false, | 408 | swiotlb_init_io_tlb_pool(mem, __pa(tlb), nslabs, false, nareas); |
| 409 | default_nareas); | ||
| 410 | add_mem_pool(&io_tlb_default_mem, mem); | 409 | add_mem_pool(&io_tlb_default_mem, mem); |
| 411 | 410 | ||
| 412 | if (flags & SWIOTLB_VERBOSE) | 411 | if (flags & SWIOTLB_VERBOSE) |
| @@ -729,9 +728,6 @@ static void swiotlb_dyn_alloc(struct work_struct *work) · 316 unmodified lines | |||
| 729 | } | 728 | } |
| 730 | 729 | ||
| 731 | add_mem_pool(mem, pool); | 730 | add_mem_pool(mem, pool); |
| 732 | |||
| 733 | /* Pairs with smp_rmb() in is_swiotlb_buffer(). */ | ||
| 734 | smp_wmb(); | ||
| 735 | } | 731 | } |
| 736 | 732 | ||
| 737 | /** | 733 | /** |
| @@ -1152,9 +1148,26 @@ static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr, · 414 unmodified lines | |||
| 1152 | spin_unlock_irqrestore(&dev->dma_io_tlb_lock, flags); | 1148 | spin_unlock_irqrestore(&dev->dma_io_tlb_lock, flags); |
| 1153 | 1149 | ||
| 1154 | found: | 1150 | found: |
| 1155 | dev->dma_uses_io_tlb = true; | 1151 | WRITE_ONCE(dev->dma_uses_io_tlb, true); |
| 1156 | /* Pairs with smp_rmb() in is_swiotlb_buffer() */ | 1152 | |
| 1157 | smp_wmb(); | 1153 | /* |
| 1154 | * The general barrier orders reads and writes against a presumed store | ||
| 1155 | * of the SWIOTLB buffer address by a device driver (to a driver private | ||
| 1156 | * data structure). It serves two purposes. | ||
| 1157 | * | ||
| 1158 | * First, the store to dev->dma_uses_io_tlb must be ordered before the | ||
| 1159 | * presumed store. This guarantees that the returned buffer address | ||
| 1160 | * cannot be passed to another CPU before updating dev->dma_uses_io_tlb. | ||
| 1161 | * | ||
| 1162 | * Second, the load from mem->pools must be ordered before the same | ||
| 1163 | * presumed store. This guarantees that the returned buffer address | ||
| 1164 | * cannot be observed by another CPU before an update of the RCU list | ||
| 1165 | * that was made by swiotlb_dyn_alloc() on a third CPU (cf. multicopy | ||
| 1166 | * atomicity). | ||
| 1167 | * | ||
| 1168 | * See also the comment in is_swiotlb_buffer(). | ||
| 1169 | */ | ||
| 1170 | smp_mb(); | ||
| 1158 | 1171 | ||
| 1159 | *retpool = pool; | 1172 | *retpool = pool; |
| 1160 | return index; | 1173 | return index; |
| @@ -609,7 +609,7 @@ int pidfd_create(struct pid *pid, unsigned int flags) · 608 unmodified lines | |||
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | /** | 611 | /** |
| 612 | * pidfd_open() - Open new pid file descriptor. | 612 | * sys_pidfd_open() - Open new pid file descriptor. |
| 613 | * | 613 | * |
| 614 | * @pid: pid for which to retrieve a pidfd | 614 | * @pid: pid for which to retrieve a pidfd |
| 615 | * @flags: flags to pass | 615 | * @flags: flags to pass |
| @@ -9269,7 +9269,7 @@ void __init init_idle(struct task_struct *idle, int cpu) · 9268 unmodified lines | |||
| 9269 | * PF_KTHREAD should already be set at this point; regardless, make it | 9269 | * PF_KTHREAD should already be set at this point; regardless, make it |
| 9270 | * look like a proper per-CPU kthread. | 9270 | * look like a proper per-CPU kthread. |
| 9271 | */ | 9271 | */ |
| 9272 | idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY; | 9272 | idle->flags |= PF_KTHREAD | PF_NO_SETAFFINITY; |
| 9273 | kthread_set_per_cpu(idle, cpu); | 9273 | kthread_set_per_cpu(idle, cpu); |
| 9274 | 9274 | ||
| 9275 | #ifdef CONFIG_SMP | 9275 | #ifdef CONFIG_SMP |
| @@ -101,6 +101,7 @@ static inline int __cpupri_find(struct cpupri *cp, struct task_struct *p, · 100 unmodified lines | |||
| 101 | 101 | ||
| 102 | if (lowest_mask) { | 102 | if (lowest_mask) { |
| 103 | cpumask_and(lowest_mask, &p->cpus_mask, vec->mask); | 103 | cpumask_and(lowest_mask, &p->cpus_mask, vec->mask); |
| 104 | cpumask_and(lowest_mask, lowest_mask, cpu_active_mask); | ||
| 104 | 105 | ||
| 105 | /* | 106 | /* |
| 106 | * We have to ensure that we have at least one bit | 107 | * We have to ensure that we have at least one bit |
| @@ -373,6 +373,7 @@ EXPORT_SYMBOL_GPL(play_idle_precise); · 372 unmodified lines | |||
| 373 | 373 | ||
| 374 | void cpu_startup_entry(enum cpuhp_state state) | 374 | void cpu_startup_entry(enum cpuhp_state state) |
| 375 | { | 375 | { |
| 376 | current->flags |= PF_IDLE; | ||
| 376 | arch_cpu_idle_prepare(); | 377 | arch_cpu_idle_prepare(); |
| 377 | cpuhp_online_idle(state); | 378 | cpuhp_online_idle(state); |
| 378 | while (1) | 379 | while (1) |
| @@ -78,6 +78,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, · 77 unmodified lines | |||
| 78 | * task_work_cancel_match - cancel a pending work added by task_work_add() | 78 | * task_work_cancel_match - cancel a pending work added by task_work_add() |
| 79 | * @task: the task which should execute the work | 79 | * @task: the task which should execute the work |
| 80 | * @match: match function to call | 80 | * @match: match function to call |
| 81 | * @data: data to be passed in to match function | ||
| 81 | * | 82 | * |
| 82 | * RETURNS: | 83 | * RETURNS: |
| 83 | * The found work or NULL if not found. | 84 | * The found work or NULL if not found. |
| @@ -354,6 +354,11 @@ static void rb_init_page(struct buffer_data_page *bpage) · 353 unmodified lines | |||
| 354 | local_set(&bpage->commit, 0); | 354 | local_set(&bpage->commit, 0); |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | static __always_inline unsigned int rb_page_commit(struct buffer_page *bpage) | ||
| 358 | { | ||
| 359 | return local_read(&bpage->page->commit); | ||
| 360 | } | ||
| 361 | |||
| 357 | static void free_buffer_page(struct buffer_page *bpage) | 362 | static void free_buffer_page(struct buffer_page *bpage) |
| 358 | { | 363 | { |
| 359 | free_page((unsigned long)bpage->page); | 364 | free_page((unsigned long)bpage->page); |
| @@ -1132,6 +1137,9 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu, · 772 unmodified lines | |||
| 1132 | if (full) { | 1137 | if (full) { |
| 1133 | poll_wait(filp, &work->full_waiters, poll_table); | 1138 | poll_wait(filp, &work->full_waiters, poll_table); |
| 1134 | work->full_waiters_pending = true; | 1139 | work->full_waiters_pending = true; |
| 1140 | if (!cpu_buffer->shortest_full || | ||
| 1141 | cpu_buffer->shortest_full > full) | ||
| 1142 | cpu_buffer->shortest_full = full; | ||
| 1135 | } else { | 1143 | } else { |
| 1136 | poll_wait(filp, &work->waiters, poll_table); | 1144 | poll_wait(filp, &work->waiters, poll_table); |
| 1137 | work->waiters_pending = true; | 1145 | work->waiters_pending = true; |
| @@ -2003,7 +2011,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) · 865 unmodified lines | |||
| 2003 | * Increment overrun to account for the lost events. | 2011 | * Increment overrun to account for the lost events. |
| 2004 | */ | 2012 | */ |
| 2005 | local_add(page_entries, &cpu_buffer->overrun); | 2013 | local_add(page_entries, &cpu_buffer->overrun); |
| 2006 | local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); | 2014 | local_sub(rb_page_commit(to_remove_page), &cpu_buffer->entries_bytes); |
| 2007 | local_inc(&cpu_buffer->pages_lost); | 2015 | local_inc(&cpu_buffer->pages_lost); |
| 2008 | } | 2016 | } |
| 2009 | 2017 | ||
| @@ -2367,11 +2375,6 @@ rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer) · 357 unmodified lines | |||
| 2367 | cpu_buffer->reader_page->read); | 2375 | cpu_buffer->reader_page->read); |
| 2368 | } | 2376 | } |
| 2369 | 2377 | ||
| 2370 | static __always_inline unsigned rb_page_commit(struct buffer_page *bpage) | ||
| 2371 | { | ||
| 2372 | return local_read(&bpage->page->commit); | ||
| 2373 | } | ||
| 2374 | |||
| 2375 | static struct ring_buffer_event * | 2378 | static struct ring_buffer_event * |
| 2376 | rb_iter_head_event(struct ring_buffer_iter *iter) | 2379 | rb_iter_head_event(struct ring_buffer_iter *iter) |
| 2377 | { | 2380 | { |
| @@ -2517,7 +2520,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer, · 139 unmodified lines | |||
| 2517 | * the counters. | 2520 | * the counters. |
| 2518 | */ | 2521 | */ |
| 2519 | local_add(entries, &cpu_buffer->overrun); | 2522 | local_add(entries, &cpu_buffer->overrun); |
| 2520 | local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); | 2523 | local_sub(rb_page_commit(next_page), &cpu_buffer->entries_bytes); |
| 2521 | local_inc(&cpu_buffer->pages_lost); | 2524 | local_inc(&cpu_buffer->pages_lost); |
| 2522 | 2525 | ||
| 2523 | /* | 2526 | /* |
| @@ -2660,9 +2663,6 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, · 136 unmodified lines | |||
| 2660 | 2663 | ||
| 2661 | event = __rb_page_index(tail_page, tail); | 2664 | event = __rb_page_index(tail_page, tail); |
| 2662 | 2665 | ||
| 2663 | /* account for padding bytes */ | ||
| 2664 | local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); | ||
| 2665 | |||
| 2666 | /* | 2666 | /* |
| 2667 | * Save the original length to the meta data. | 2667 | * Save the original length to the meta data. |
| 2668 | * This will be used by the reader to add lost event | 2668 | * This will be used by the reader to add lost event |
| @@ -2676,7 +2676,8 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, · 7 unmodified lines | |||
| 2676 | * write counter enough to allow another writer to slip | 2676 | * write counter enough to allow another writer to slip |
| 2677 | * in on this page. | 2677 | * in on this page. |
| 2678 | * We put in a discarded commit instead, to make sure | 2678 | * We put in a discarded commit instead, to make sure |
| 2679 | * that this space is not used again. | 2679 | * that this space is not used again, and this space will |
| 2680 | * not be accounted into 'entries_bytes'. | ||
| 2680 | * | 2681 | * |
| 2681 | * If we are less than the minimum size, we don't need to | 2682 | * If we are less than the minimum size, we don't need to |
| 2682 | * worry about it. | 2683 | * worry about it. |
| @@ -2701,6 +2702,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, · 18 unmodified lines | |||
| 2701 | /* time delta must be non zero */ | 2702 | /* time delta must be non zero */ |
| 2702 | event->time_delta = 1; | 2703 | event->time_delta = 1; |
| 2703 | 2704 | ||
| 2705 | /* account for padding bytes */ | ||
| 2706 | local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); | ||
| 2707 | |||
| 2704 | /* Make sure the padding is visible before the tail_page->write update */ | 2708 | /* Make sure the padding is visible before the tail_page->write update */ |
| 2705 | smp_wmb(); | 2709 | smp_wmb(); |
| 2706 | 2710 | ||
| @@ -4215,7 +4219,7 @@ u64 ring_buffer_oldest_event_ts(struct trace_buffer *buffer, int cpu) · 1508 unmodified lines | |||
| 4215 | EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts); | 4219 | EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts); |
| 4216 | 4220 | ||
| 4217 | /** | 4221 | /** |
| 4218 | * ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer | 4222 | * ring_buffer_bytes_cpu - get the number of bytes unconsumed in a cpu buffer |
| 4219 | * @buffer: The ring buffer | 4223 | * @buffer: The ring buffer |
| 4220 | * @cpu: The per CPU buffer to read from. | 4224 | * @cpu: The per CPU buffer to read from. |
| 4221 | */ | 4225 | */ |
| @@ -4723,6 +4727,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) · 501 unmodified lines | |||
| 4723 | 4727 | ||
| 4724 | length = rb_event_length(event); | 4728 | length = rb_event_length(event); |
| 4725 | cpu_buffer->reader_page->read += length; | 4729 | cpu_buffer->reader_page->read += length; |
| 4730 | cpu_buffer->read_bytes += length; | ||
| 4726 | } | 4731 | } |
| 4727 | 4732 | ||
| 4728 | static void rb_advance_iter(struct ring_buffer_iter *iter) | 4733 | static void rb_advance_iter(struct ring_buffer_iter *iter) |
| @@ -5816,7 +5821,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer, · 1087 unmodified lines | |||
| 5816 | } else { | 5821 | } else { |
| 5817 | /* update the entry counter */ | 5822 | /* update the entry counter */ |
| 5818 | cpu_buffer->read += rb_page_entries(reader); | 5823 | cpu_buffer->read += rb_page_entries(reader); |
| 5819 | cpu_buffer->read_bytes += BUF_PAGE_SIZE; | 5824 | cpu_buffer->read_bytes += rb_page_commit(reader); |
| 5820 | 5825 | ||
| 5821 | /* swap the pages */ | 5826 | /* swap the pages */ |
| 5822 | rb_init_page(bpage); | 5827 | rb_init_page(bpage); |
| @@ -2770,6 +2770,7 @@ void trace_event_eval_update(struct trace_eval_map **map, int len) · 2769 unmodified lines | |||
| 2770 | update_event_fields(call, map[i]); | 2770 | update_event_fields(call, map[i]); |
| 2771 | } | 2771 | } |
| 2772 | } | 2772 | } |
| 2773 | cond_resched(); | ||
| 2773 | } | 2774 | } |
| 2774 | up_write(&trace_event_sem); | 2775 | up_write(&trace_event_sem); |
| 2775 | } | 2776 | } |
| @@ -127,8 +127,13 @@ struct user_event_enabler { · 126 unmodified lines | |||
| 127 | /* Bit 7 is for freeing status of enablement */ | 127 | /* Bit 7 is for freeing status of enablement */ |
| 128 | #define ENABLE_VAL_FREEING_BIT 7 | 128 | #define ENABLE_VAL_FREEING_BIT 7 |
| 129 | 129 | ||
| 130 | /* Only duplicate the bit value */ | 130 | /* Bit 8 is for marking 32-bit on 64-bit */ |
| 131 | #define ENABLE_VAL_DUP_MASK ENABLE_VAL_BIT_MASK | 131 | #define ENABLE_VAL_32_ON_64_BIT 8 |
| 132 | |||
| 133 | #define ENABLE_VAL_COMPAT_MASK (1 << ENABLE_VAL_32_ON_64_BIT) | ||
| 134 | |||
| 135 | /* Only duplicate the bit and compat values */ | ||
| 136 | #define ENABLE_VAL_DUP_MASK (ENABLE_VAL_BIT_MASK | ENABLE_VAL_COMPAT_MASK) | ||
| 132 | 137 | ||
| 133 | #define ENABLE_BITOPS(e) (&(e)->values) | 138 | #define ENABLE_BITOPS(e) (&(e)->values) |
| 134 | 139 | ||
| @@ -174,6 +179,30 @@ struct user_event_validator { · 39 unmodified lines | |||
| 174 | int flags; | 179 | int flags; |
| 175 | }; | 180 | }; |
| 176 | 181 | ||
| 182 | static inline void align_addr_bit(unsigned long *addr, int *bit, | ||
| 183 | unsigned long *flags) | ||
| 184 | { | ||
| 185 | if (IS_ALIGNED(*addr, sizeof(long))) { | ||
| 186 | #ifdef __BIG_ENDIAN | ||
| 187 | /* 32 bit on BE 64 bit requires a 32 bit offset when aligned. */ | ||
| 188 | if (test_bit(ENABLE_VAL_32_ON_64_BIT, flags)) | ||
| 189 | *bit += 32; | ||
| 190 | #endif | ||
| 191 | return; | ||
| 192 | } | ||
| 193 | |||
| 194 | *addr = ALIGN_DOWN(*addr, sizeof(long)); | ||
| 195 | |||
| 196 | /* | ||
| 197 | * We only support 32 and 64 bit values. The only time we need | ||
| 198 | * to align is a 32 bit value on a 64 bit kernel, which on LE | ||
| 199 | * is always 32 bits, and on BE requires no change when unaligned. | ||
| 200 | */ | ||
| 201 | #ifdef __LITTLE_ENDIAN | ||
| 202 | *bit += 32; | ||
| 203 | #endif | ||
| 204 | } | ||
| 205 | |||
| 177 | typedef void (*user_event_func_t) (struct user_event *user, struct iov_iter *i, | 206 | typedef void (*user_event_func_t) (struct user_event *user, struct iov_iter *i, |
| 178 | void *tpdata, bool *faulted); | 207 | void *tpdata, bool *faulted); |
| 179 | 208 | ||
| @@ -482,6 +511,7 @@ static int user_event_enabler_write(struct user_event_mm *mm, · 302 unmodified lines | |||
| 482 | unsigned long *ptr; | 511 | unsigned long *ptr; |
| 483 | struct page *page; | 512 | struct page *page; |
| 484 | void *kaddr; | 513 | void *kaddr; |
| 514 | int bit = ENABLE_BIT(enabler); | ||
| 485 | int ret; | 515 | int ret; |
| 486 | 516 | ||
| 487 | lockdep_assert_held(&event_mutex); | 517 | lockdep_assert_held(&event_mutex); |
| @@ -497,6 +527,8 @@ static int user_event_enabler_write(struct user_event_mm *mm, · 9 unmodified lines | |||
| 497 | test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler)))) | 527 | test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler)))) |
| 498 | return -EBUSY; | 528 | return -EBUSY; |
| 499 | 529 | ||
| 530 | align_addr_bit(&uaddr, &bit, ENABLE_BITOPS(enabler)); | ||
| 531 | |||
| 500 | ret = pin_user_pages_remote(mm->mm, uaddr, 1, FOLL_WRITE | FOLL_NOFAULT, | 532 | ret = pin_user_pages_remote(mm->mm, uaddr, 1, FOLL_WRITE | FOLL_NOFAULT, |
| 501 | &page, NULL); | 533 | &page, NULL); |
| 502 | 534 | ||
| @@ -515,9 +547,9 @@ static int user_event_enabler_write(struct user_event_mm *mm, · 12 unmodified lines | |||
| 515 | 547 | ||
| 516 | /* Update bit atomically, user tracers must be atomic as well */ | 548 | /* Update bit atomically, user tracers must be atomic as well */ |
| 517 | if (enabler->event && enabler->event->status) | 549 | if (enabler->event && enabler->event->status) |
| 518 | set_bit(ENABLE_BIT(enabler), ptr); | 550 | set_bit(bit, ptr); |
| 519 | else | 551 | else |
| 520 | clear_bit(ENABLE_BIT(enabler), ptr); | 552 | clear_bit(bit, ptr); |
| 521 | 553 | ||
| 522 | kunmap_local(kaddr); | 554 | kunmap_local(kaddr); |
| 523 | unpin_user_pages_dirty_lock(&page, 1, true); | 555 | unpin_user_pages_dirty_lock(&page, 1, true); |
| @@ -849,6 +881,12 @@ static struct user_event_enabler · 325 unmodified lines | |||
| 849 | enabler->event = user; | 881 | enabler->event = user; |
| 850 | enabler->addr = uaddr; | 882 | enabler->addr = uaddr; |
| 851 | enabler->values = reg->enable_bit; | 883 | enabler->values = reg->enable_bit; |
| 884 | |||
| 885 | #if BITS_PER_LONG >= 64 | ||
| 886 | if (reg->enable_size == 4) | ||
| 887 | set_bit(ENABLE_VAL_32_ON_64_BIT, ENABLE_BITOPS(enabler)); | ||
| 888 | #endif | ||
| 889 | |||
| 852 | retry: | 890 | retry: |
| 853 | /* Prevents state changes from racing with new enablers */ | 891 | /* Prevents state changes from racing with new enablers */ |
| 854 | mutex_lock(&event_mutex); | 892 | mutex_lock(&event_mutex); |
| @@ -2377,7 +2415,8 @@ static long user_unreg_get(struct user_unreg __user *ureg, · 1522 unmodified lines | |||
| 2377 | } | 2415 | } |
| 2378 | 2416 | ||
| 2379 | static int user_event_mm_clear_bit(struct user_event_mm *user_mm, | 2417 | static int user_event_mm_clear_bit(struct user_event_mm *user_mm, |
| 2380 | unsigned long uaddr, unsigned char bit) | 2418 | unsigned long uaddr, unsigned char bit, |
| 2419 | unsigned long flags) | ||
| 2381 | { | 2420 | { |
| 2382 | struct user_event_enabler enabler; | 2421 | struct user_event_enabler enabler; |
| 2383 | int result; | 2422 | int result; |
| @@ -2385,7 +2424,7 @@ static int user_event_mm_clear_bit(struct user_event_mm *user_mm, · 1 unmodified line | |||
| 2385 | 2424 | ||
| 2386 | memset(&enabler, 0, sizeof(enabler)); | 2425 | memset(&enabler, 0, sizeof(enabler)); |
| 2387 | enabler.addr = uaddr; | 2426 | enabler.addr = uaddr; |
| 2388 | enabler.values = bit; | 2427 | enabler.values = bit | flags; |
| 2389 | retry: | 2428 | retry: |
| 2390 | /* Prevents state changes from racing with new enablers */ | 2429 | /* Prevents state changes from racing with new enablers */ |
| 2391 | mutex_lock(&event_mutex); | 2430 | mutex_lock(&event_mutex); |
| @@ -2415,6 +2454,7 @@ static long user_events_ioctl_unreg(unsigned long uarg) · 23 unmodified lines | |||
| 2415 | struct user_event_mm *mm = current->user_event_mm; | 2454 | struct user_event_mm *mm = current->user_event_mm; |
| 2416 | struct user_event_enabler *enabler, *next; | 2455 | struct user_event_enabler *enabler, *next; |
| 2417 | struct user_unreg reg; | 2456 | struct user_unreg reg; |
| 2457 | unsigned long flags; | ||
| 2418 | long ret; | 2458 | long ret; |
| 2419 | 2459 | ||
| 2420 | ret = user_unreg_get(ureg, ®); | 2460 | ret = user_unreg_get(ureg, ®); |
| @@ -2425,6 +2465,7 @@ static long user_events_ioctl_unreg(unsigned long uarg) · 4 unmodified lines | |||
| 2425 | if (!mm) | 2465 | if (!mm) |
| 2426 | return -ENOENT; | 2466 | return -ENOENT; |
| 2427 | 2467 | ||
| 2468 | flags = 0; | ||
| 2428 | ret = -ENOENT; | 2469 | ret = -ENOENT; |
| 2429 | 2470 | ||
| 2430 | /* | 2471 | /* |
| @@ -2441,6 +2482,9 @@ static long user_events_ioctl_unreg(unsigned long uarg) · 10 unmodified lines | |||
| 2441 | ENABLE_BIT(enabler) == reg.disable_bit) { | 2482 | ENABLE_BIT(enabler) == reg.disable_bit) { |
| 2442 | set_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler)); | 2483 | set_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler)); |
| 2443 | 2484 | ||
| 2485 | /* We must keep compat flags for the clear */ | ||
| 2486 | flags |= enabler->values & ENABLE_VAL_COMPAT_MASK; | ||
| 2487 | |||
| 2444 | if (!test_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler))) | 2488 | if (!test_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler))) |
| 2445 | user_event_enabler_destroy(enabler, true); | 2489 | user_event_enabler_destroy(enabler, true); |
| 2446 | 2490 | ||
| @@ -2454,7 +2498,7 @@ static long user_events_ioctl_unreg(unsigned long uarg) · 7 unmodified lines | |||
| 2454 | /* Ensure bit is now cleared for user, regardless of event status */ | 2498 | /* Ensure bit is now cleared for user, regardless of event status */ |
| 2455 | if (!ret) | 2499 | if (!ret) |
| 2456 | ret = user_event_mm_clear_bit(mm, reg.disable_addr, | 2500 | ret = user_event_mm_clear_bit(mm, reg.disable_addr, |
| 2457 | reg.disable_bit); | 2501 | reg.disable_bit, flags); |
| 2458 | 2502 | ||
| 2459 | return ret; | 2503 | return ret; |
| 2460 | } | 2504 | } |
| @@ -6535,9 +6535,6 @@ void __init workqueue_init_early(void) · 6534 unmodified lines | |||
| 6535 | 6535 | ||
| 6536 | BUG_ON(!zalloc_cpumask_var_node(&pt->pod_cpus[0], GFP_KERNEL, NUMA_NO_NODE)); | 6536 | BUG_ON(!zalloc_cpumask_var_node(&pt->pod_cpus[0], GFP_KERNEL, NUMA_NO_NODE)); |
| 6537 | 6537 | ||
| 6538 | wq_update_pod_attrs_buf = alloc_workqueue_attrs(); | ||
| 6539 | BUG_ON(!wq_update_pod_attrs_buf); | ||
| 6540 | |||
| 6541 | pt->nr_pods = 1; | 6538 | pt->nr_pods = 1; |
| 6542 | cpumask_copy(pt->pod_cpus[0], cpu_possible_mask); | 6539 | cpumask_copy(pt->pod_cpus[0], cpu_possible_mask); |
| 6543 | pt->pod_node[0] = NUMA_NO_NODE; | 6540 | pt->pod_node[0] = NUMA_NO_NODE; |
| @@ -6605,13 +6602,13 @@ static void __init wq_cpu_intensive_thresh_init(void) · 61 unmodified lines | |||
| 6605 | unsigned long thresh; | 6602 | unsigned long thresh; |
| 6606 | unsigned long bogo; | 6603 | unsigned long bogo; |
| 6607 | 6604 | ||
| 6605 | pwq_release_worker = kthread_create_worker(0, "pool_workqueue_release"); | ||
| 6606 | BUG_ON(IS_ERR(pwq_release_worker)); | ||
| 6607 | |||
| 6608 | /* if the user set it to a specific value, keep it */ | 6608 | /* if the user set it to a specific value, keep it */ |
| 6609 | if (wq_cpu_intensive_thresh_us != ULONG_MAX) | 6609 | if (wq_cpu_intensive_thresh_us != ULONG_MAX) |
| 6610 | return; | 6610 | return; |
| 6611 | 6611 | ||
| 6612 | pwq_release_worker = kthread_create_worker(0, "pool_workqueue_release"); | ||
| 6613 | BUG_ON(IS_ERR(pwq_release_worker)); | ||
| 6614 | |||
| 6615 | /* | 6612 | /* |
| 6616 | * The default of 10ms is derived from the fact that most modern (as of | 6613 | * The default of 10ms is derived from the fact that most modern (as of |
| 6617 | * 2023) processors can do a lot in 10ms and that it's just below what | 6614 | * 2023) processors can do a lot in 10ms and that it's just below what |
| @@ -28,7 +28,7 @@ static int count_argc(const char *str) · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | /** | 29 | /** |
| 30 | * argv_free - free an argv | 30 | * argv_free - free an argv |
| 31 | * @argv - the argument vector to be freed | 31 | * @argv: the argument vector to be freed |
| 32 | * | 32 | * |
| 33 | * Frees an argv and the strings it points to. | 33 | * Frees an argv and the strings it points to. |
| 34 | */ | 34 | */ |
| @@ -46,7 +46,7 @@ EXPORT_SYMBOL(argv_free); · 11 unmodified lines | |||
| 46 | * @str: the string to be split | 46 | * @str: the string to be split |
| 47 | * @argcp: returned argument count | 47 | * @argcp: returned argument count |
| 48 | * | 48 | * |
| 49 | * Returns an array of pointers to strings which are split out from | 49 | * Returns: an array of pointers to strings which are split out from |
| 50 | * @str. This is performed by strictly splitting on white-space; no | 50 | * @str. This is performed by strictly splitting on white-space; no |
| 51 | * quote processing is performed. Multiple whitespace characters are | 51 | * quote processing is performed. Multiple whitespace characters are |
| 52 | * considered to be a single argument separator. The returned array | 52 | * considered to be a single argument separator. The returned array |
| @@ -256,6 +256,22 @@ bool mas_is_err(struct ma_state *mas) · 255 unmodified lines | |||
| 256 | return xa_is_err(mas->node); | 256 | return xa_is_err(mas->node); |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | static __always_inline bool mas_is_overflow(struct ma_state *mas) | ||
| 260 | { | ||
| 261 | if (unlikely(mas->node == MAS_OVERFLOW)) | ||
| 262 | return true; | ||
| 263 | |||
| 264 | return false; | ||
| 265 | } | ||
| 266 | |||
| 267 | static __always_inline bool mas_is_underflow(struct ma_state *mas) | ||
| 268 | { | ||
| 269 | if (unlikely(mas->node == MAS_UNDERFLOW)) | ||
| 270 | return true; | ||
| 271 | |||
| 272 | return false; | ||
| 273 | } | ||
| 274 | |||
| 259 | static inline bool mas_searchable(struct ma_state *mas) | 275 | static inline bool mas_searchable(struct ma_state *mas) |
| 260 | { | 276 | { |
| 261 | if (mas_is_none(mas)) | 277 | if (mas_is_none(mas)) |
| @@ -4415,10 +4431,13 @@ no_entry: · 4153 unmodified lines | |||
| 4415 | * | 4431 | * |
| 4416 | * @mas: The maple state | 4432 | * @mas: The maple state |
| 4417 | * @max: The minimum starting range | 4433 | * @max: The minimum starting range |
| 4434 | * @empty: Can be empty | ||
| 4435 | * @set_underflow: Set the @mas->node to underflow state on limit. | ||
| 4418 | * | 4436 | * |
| 4419 | * Return: The entry in the previous slot which is possibly NULL | 4437 | * Return: The entry in the previous slot which is possibly NULL |
| 4420 | */ | 4438 | */ |
| 4421 | static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty) | 4439 | static void *mas_prev_slot(struct ma_state *mas, unsigned long min, bool empty, |
| 4440 | bool set_underflow) | ||
| 4422 | { | 4441 | { |
| 4423 | void *entry; | 4442 | void *entry; |
| 4424 | void __rcu **slots; | 4443 | void __rcu **slots; |
| @@ -4435,7 +4454,6 @@ retry: · 10 unmodified lines | |||
| 4435 | if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) | 4454 | if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) |
| 4436 | goto retry; | 4455 | goto retry; |
| 4437 | 4456 | ||
| 4438 | again: | ||
| 4439 | if (mas->min <= min) { | 4457 | if (mas->min <= min) { |
| 4440 | pivot = mas_safe_min(mas, pivots, mas->offset); | 4458 | pivot = mas_safe_min(mas, pivots, mas->offset); |
| 4441 | 4459 | ||
| @@ -4443,9 +4461,10 @@ again: · 1 unmodified line | |||
| 4443 | goto retry; | 4461 | goto retry; |
| 4444 | 4462 | ||
| 4445 | if (pivot <= min) | 4463 | if (pivot <= min) |
| 4446 | return NULL; | 4464 | goto underflow; |
| 4447 | } | 4465 | } |
| 4448 | 4466 | ||
| 4467 | again: | ||
| 4449 | if (likely(mas->offset)) { | 4468 | if (likely(mas->offset)) { |
| 4450 | mas->offset--; | 4469 | mas->offset--; |
| 4451 | mas->last = mas->index - 1; | 4470 | mas->last = mas->index - 1; |
| @@ -4457,7 +4476,7 @@ again: · 5 unmodified lines | |||
| 4457 | } | 4476 | } |
| 4458 | 4477 | ||
| 4459 | if (mas_is_none(mas)) | 4478 | if (mas_is_none(mas)) |
| 4460 | return NULL; | 4479 | goto underflow; |
| 4461 | 4480 | ||
| 4462 | mas->last = mas->max; | 4481 | mas->last = mas->max; |
| 4463 | node = mas_mn(mas); | 4482 | node = mas_mn(mas); |
| @@ -4474,10 +4493,19 @@ again: · 10 unmodified lines | |||
| 4474 | if (likely(entry)) | 4493 | if (likely(entry)) |
| 4475 | return entry; | 4494 | return entry; |
| 4476 | 4495 | ||
| 4477 | if (!empty) | 4496 | if (!empty) { |
| 4497 | if (mas->index <= min) | ||
| 4498 | goto underflow; | ||
| 4499 | |||
| 4478 | goto again; | 4500 | goto again; |
| 4501 | } | ||
| 4479 | 4502 | ||
| 4480 | return entry; | 4503 | return entry; |
| 4504 | |||
| 4505 | underflow: | ||
| 4506 | if (set_underflow) | ||
| 4507 | mas->node = MAS_UNDERFLOW; | ||
| 4508 | return NULL; | ||
| 4481 | } | 4509 | } |
| 4482 | 4510 | ||
| 4483 | /* | 4511 | /* |
| @@ -4567,10 +4595,13 @@ no_entry: · 83 unmodified lines | |||
| 4567 | * @mas: The maple state | 4595 | * @mas: The maple state |
| 4568 | * @max: The maximum starting range | 4596 | * @max: The maximum starting range |
| 4569 | * @empty: Can be empty | 4597 | * @empty: Can be empty |
| 4598 | * @set_overflow: Should @mas->node be set to overflow when the limit is | ||
| 4599 | * reached. | ||
| 4570 | * | 4600 | * |
| 4571 | * Return: The entry in the next slot which is possibly NULL | 4601 | * Return: The entry in the next slot which is possibly NULL |
| 4572 | */ | 4602 | */ |
| 4573 | static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty) | 4603 | static void *mas_next_slot(struct ma_state *mas, unsigned long max, bool empty, |
| 4604 | bool set_overflow) | ||
| 4574 | { | 4605 | { |
| 4575 | void __rcu **slots; | 4606 | void __rcu **slots; |
| 4576 | unsigned long *pivots; | 4607 | unsigned long *pivots; |
| @@ -4589,22 +4620,22 @@ retry: · 12 unmodified lines | |||
| 4589 | if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) | 4620 | if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) |
| 4590 | goto retry; | 4621 | goto retry; |
| 4591 | 4622 | ||
| 4592 | again: | ||
| 4593 | if (mas->max >= max) { | 4623 | if (mas->max >= max) { |
| 4594 | if (likely(mas->offset < data_end)) | 4624 | if (likely(mas->offset < data_end)) |
| 4595 | pivot = pivots[mas->offset]; | 4625 | pivot = pivots[mas->offset]; |
| 4596 | else | 4626 | else |
| 4597 | return NULL; /* must be mas->max */ | 4627 | goto overflow; |
| 4598 | 4628 | ||
| 4599 | if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) | 4629 | if (unlikely(mas_rewalk_if_dead(mas, node, save_point))) |
| 4600 | goto retry; | 4630 | goto retry; |
| 4601 | 4631 | ||
| 4602 | if (pivot >= max) | 4632 | if (pivot >= max) |
| 4603 | return NULL; | 4633 | goto overflow; |
| 4604 | } | 4634 | } |
| 4605 | 4635 | ||
| 4606 | if (likely(mas->offset < data_end)) { | 4636 | if (likely(mas->offset < data_end)) { |
| 4607 | mas->index = pivots[mas->offset] + 1; | 4637 | mas->index = pivots[mas->offset] + 1; |
| 4638 | again: | ||
| 4608 | mas->offset++; | 4639 | mas->offset++; |
| 4609 | if (likely(mas->offset < data_end)) | 4640 | if (likely(mas->offset < data_end)) |
| 4610 | mas->last = pivots[mas->offset]; | 4641 | mas->last = pivots[mas->offset]; |
| @@ -4616,8 +4647,11 @@ again: · 5 unmodified lines | |||
| 4616 | goto retry; | 4647 | goto retry; |
| 4617 | } | 4648 | } |
| 4618 | 4649 | ||
| 4619 | if (mas_is_none(mas)) | 4650 | if (WARN_ON_ONCE(mas_is_none(mas))) { |
| 4651 | mas->node = MAS_OVERFLOW; | ||
| 4620 | return NULL; | 4652 | return NULL; |
| 4653 | goto overflow; | ||
| 4654 | } | ||
| 4621 | 4655 | ||
| 4622 | mas->offset = 0; | 4656 | mas->offset = 0; |
| 4623 | mas->index = mas->min; | 4657 | mas->index = mas->min; |
| @@ -4636,12 +4670,20 @@ again: · 12 unmodified lines | |||
| 4636 | return entry; | 4670 | return entry; |
| 4637 | 4671 | ||
| 4638 | if (!empty) { | 4672 | if (!empty) { |
| 4639 | if (!mas->offset) | 4673 | if (mas->last >= max) |
| 4640 | data_end = 2; | 4674 | goto overflow; |
| 4675 | |||
| 4676 | mas->index = mas->last + 1; | ||
| 4677 | /* Node cannot end on NULL, so it's safe to short-cut here */ | ||
| 4641 | goto again; | 4678 | goto again; |
| 4642 | } | 4679 | } |
| 4643 | 4680 | ||
| 4644 | return entry; | 4681 | return entry; |
| 4682 | |||
| 4683 | overflow: | ||
| 4684 | if (set_overflow) | ||
| 4685 | mas->node = MAS_OVERFLOW; | ||
| 4686 | return NULL; | ||
| 4645 | } | 4687 | } |
| 4646 | 4688 | ||
| 4647 | /* | 4689 | /* |
| @@ -4651,17 +4693,20 @@ again: · 3 unmodified lines | |||
| 4651 | * | 4693 | * |
| 4652 | * Set the @mas->node to the next entry and the range_start to | 4694 | * Set the @mas->node to the next entry and the range_start to |
| 4653 | * the beginning value for the entry. Does not check beyond @limit. | 4695 | * the beginning value for the entry. Does not check beyond @limit. |
| 4654 | * Sets @mas->index and @mas->last to the limit if it is hit. | 4696 | * Sets @mas->index and @mas->last to the range, Does not update @mas->index and |
| 4697 | * @mas->last on overflow. | ||
| 4655 | * Restarts on dead nodes. | 4698 | * Restarts on dead nodes. |
| 4656 | * | 4699 | * |
| 4657 | * Return: the next entry or %NULL. | 4700 | * Return: the next entry or %NULL. |
| 4658 | */ | 4701 | */ |
| 4659 | static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit) | 4702 | static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit) |
| 4660 | { | 4703 | { |
| 4661 | if (mas->last >= limit) | 4704 | if (mas->last >= limit) { |
| 4705 | mas->node = MAS_OVERFLOW; | ||
| 4662 | return NULL; | 4706 | return NULL; |
| 4707 | } | ||
| 4663 | 4708 | ||
| 4664 | return mas_next_slot(mas, limit, false); | 4709 | return mas_next_slot(mas, limit, false, true); |
| 4665 | } | 4710 | } |
| 4666 | 4711 | ||
| 4667 | /* | 4712 | /* |
| @@ -4837,7 +4882,7 @@ void *mas_walk(struct ma_state *mas) · 169 unmodified lines | |||
| 4837 | { | 4882 | { |
| 4838 | void *entry; | 4883 | void *entry; |
| 4839 | 4884 | ||
| 4840 | if (mas_is_none(mas) || mas_is_paused(mas) || mas_is_ptr(mas)) | 4885 | if (!mas_is_active(mas) || !mas_is_start(mas)) |
| 4841 | mas->node = MAS_START; | 4886 | mas->node = MAS_START; |
| 4842 | retry: | 4887 | retry: |
| 4843 | entry = mas_state_walk(mas); | 4888 | entry = mas_state_walk(mas); |
| @@ -5294,14 +5339,22 @@ static inline void mte_destroy_walk(struct maple_enode *enode, · 450 unmodified lines | |||
| 5294 | 5339 | ||
| 5295 | static void mas_wr_store_setup(struct ma_wr_state *wr_mas) | 5340 | static void mas_wr_store_setup(struct ma_wr_state *wr_mas) |
| 5296 | { | 5341 | { |
| 5297 | if (mas_is_start(wr_mas->mas)) | 5342 | if (!mas_is_active(wr_mas->mas)) { |
| 5298 | return; | 5343 | if (mas_is_start(wr_mas->mas)) |
| 5344 | return; | ||
| 5299 | 5345 | ||
| 5300 | if (unlikely(mas_is_paused(wr_mas->mas))) | 5346 | if (unlikely(mas_is_paused(wr_mas->mas))) |
| 5301 | goto reset; | 5347 | goto reset; |
| 5302 | 5348 | ||
| 5303 | if (unlikely(mas_is_none(wr_mas->mas))) | 5349 | if (unlikely(mas_is_none(wr_mas->mas))) |
| 5304 | goto reset; | 5350 | goto reset; |
| 5351 | |||
| 5352 | if (unlikely(mas_is_overflow(wr_mas->mas))) | ||
| 5353 | goto reset; | ||
| 5354 | |||
| 5355 | if (unlikely(mas_is_underflow(wr_mas->mas))) | ||
| 5356 | goto reset; | ||
| 5357 | } | ||
| 5305 | 5358 | ||
| 5306 | /* | 5359 | /* |
| 5307 | * A less strict version of mas_is_span_wr() where we allow spanning | 5360 | * A less strict version of mas_is_span_wr() where we allow spanning |
| @@ -5595,8 +5648,25 @@ static inline bool mas_next_setup(struct ma_state *mas, unsigned long max, · 287 unmodified lines | |||
| 5595 | { | 5648 | { |
| 5596 | bool was_none = mas_is_none(mas); | 5649 | bool was_none = mas_is_none(mas); |
| 5597 | 5650 | ||
| 5598 | if (mas_is_none(mas) || mas_is_paused(mas)) | 5651 | if (unlikely(mas->last >= max)) { |
| 5652 | mas->node = MAS_OVERFLOW; | ||
| 5653 | return true; | ||
| 5654 | } | ||
| 5655 | |||
| 5656 | if (mas_is_active(mas)) | ||
| 5657 | return false; | ||
| 5658 | |||
| 5659 | if (mas_is_none(mas) || mas_is_paused(mas)) { | ||
| 5660 | mas->node = MAS_START; | ||
| 5661 | } else if (mas_is_overflow(mas)) { | ||
| 5662 | /* Overflowed before, but the max changed */ | ||
| 5599 | mas->node = MAS_START; | 5663 | mas->node = MAS_START; |
| 5664 | } else if (mas_is_underflow(mas)) { | ||
| 5665 | mas->node = MAS_START; | ||
| 5666 | *entry = mas_walk(mas); | ||
| 5667 | if (*entry) | ||
| 5668 | return true; | ||
| 5669 | } | ||
| 5600 | 5670 | ||
| 5601 | if (mas_is_start(mas)) | 5671 | if (mas_is_start(mas)) |
| 5602 | *entry = mas_walk(mas); /* Retries on dead nodes handled by mas_walk */ | 5672 | *entry = mas_walk(mas); /* Retries on dead nodes handled by mas_walk */ |
| @@ -5615,6 +5685,7 @@ static inline bool mas_next_setup(struct ma_state *mas, unsigned long max, · 12 unmodified lines | |||
| 5615 | 5685 | ||
| 5616 | if (mas_is_none(mas)) | 5686 | if (mas_is_none(mas)) |
| 5617 | return true; | 5687 | return true; |
| 5688 | |||
| 5618 | return false; | 5689 | return false; |
| 5619 | } | 5690 | } |
| 5620 | 5691 | ||
| @@ -5637,7 +5708,7 @@ void *mas_next(struct ma_state *mas, unsigned long max) · 16 unmodified lines | |||
| 5637 | return entry; | 5708 | return entry; |
| 5638 | 5709 | ||
| 5639 | /* Retries on dead nodes handled by mas_next_slot */ | 5710 | /* Retries on dead nodes handled by mas_next_slot */ |
| 5640 | return mas_next_slot(mas, max, false); | 5711 | return mas_next_slot(mas, max, false, true); |
| 5641 | } | 5712 | } |
| 5642 | EXPORT_SYMBOL_GPL(mas_next); | 5713 | EXPORT_SYMBOL_GPL(mas_next); |
| 5643 | 5714 | ||
| @@ -5660,7 +5731,7 @@ void *mas_next_range(struct ma_state *mas, unsigned long max) · 16 unmodified lines | |||
| 5660 | return entry; | 5731 | return entry; |
| 5661 | 5732 | ||
| 5662 | /* Retries on dead nodes handled by mas_next_slot */ | 5733 | /* Retries on dead nodes handled by mas_next_slot */ |
| 5663 | return mas_next_slot(mas, max, true); | 5734 | return mas_next_slot(mas, max, true, true); |
| 5664 | } | 5735 | } |
| 5665 | EXPORT_SYMBOL_GPL(mas_next_range); | 5736 | EXPORT_SYMBOL_GPL(mas_next_range); |
| 5666 | 5737 | ||
| @@ -5691,18 +5762,31 @@ EXPORT_SYMBOL_GPL(mt_next); · 24 unmodified lines | |||
| 5691 | static inline bool mas_prev_setup(struct ma_state *mas, unsigned long min, | 5762 | static inline bool mas_prev_setup(struct ma_state *mas, unsigned long min, |
| 5692 | void **entry) | 5763 | void **entry) |
| 5693 | { | 5764 | { |
| 5694 | if (mas->index <= min) | 5765 | if (unlikely(mas->index <= min)) { |
| 5695 | goto none; | 5766 | mas->node = MAS_UNDERFLOW; |
| 5767 | return true; | ||
| 5768 | } | ||
| 5696 | 5769 | ||
| 5697 | if (mas_is_none(mas) || mas_is_paused(mas)) | 5770 | if (mas_is_active(mas)) |
| 5771 | return false; | ||
| 5772 | |||
| 5773 | if (mas_is_overflow(mas)) { | ||
| 5698 | mas->node = MAS_START; | 5774 | mas->node = MAS_START; |
| 5775 | *entry = mas_walk(mas); | ||
| 5776 | if (*entry) | ||
| 5777 | return true; | ||
| 5778 | } | ||
| 5699 | 5779 | ||
| 5700 | if (mas_is_start(mas)) { | 5780 | if (mas_is_none(mas) || mas_is_paused(mas)) { |
| 5701 | mas_walk(mas); | 5781 | mas->node = MAS_START; |
| 5702 | if (!mas->index) | 5782 | } else if (mas_is_underflow(mas)) { |
| 5703 | goto none; | 5783 | /* underflowed before but the min changed */ |
| 5784 | mas->node = MAS_START; | ||
| 5704 | } | 5785 | } |
| 5705 | 5786 | ||
| 5787 | if (mas_is_start(mas)) | ||
| 5788 | mas_walk(mas); | ||
| 5789 | |||
| 5706 | if (unlikely(mas_is_ptr(mas))) { | 5790 | if (unlikely(mas_is_ptr(mas))) { |
| 5707 | if (!mas->index) | 5791 | if (!mas->index) |
| 5708 | goto none; | 5792 | goto none; |
| @@ -5747,7 +5831,7 @@ void *mas_prev(struct ma_state *mas, unsigned long min) · 38 unmodified lines | |||
| 5747 | if (mas_prev_setup(mas, min, &entry)) | 5831 | if (mas_prev_setup(mas, min, &entry)) |
| 5748 | return entry; | 5832 | return entry; |
| 5749 | 5833 | ||
| 5750 | return mas_prev_slot(mas, min, false); | 5834 | return mas_prev_slot(mas, min, false, true); |
| 5751 | } | 5835 | } |
| 5752 | EXPORT_SYMBOL_GPL(mas_prev); | 5836 | EXPORT_SYMBOL_GPL(mas_prev); |
| 5753 | 5837 | ||
| @@ -5770,7 +5854,7 @@ void *mas_prev_range(struct ma_state *mas, unsigned long min) · 16 unmodified lines | |||
| 5770 | if (mas_prev_setup(mas, min, &entry)) | 5854 | if (mas_prev_setup(mas, min, &entry)) |
| 5771 | return entry; | 5855 | return entry; |
| 5772 | 5856 | ||
| 5773 | return mas_prev_slot(mas, min, true); | 5857 | return mas_prev_slot(mas, min, true, true); |
| 5774 | } | 5858 | } |
| 5775 | EXPORT_SYMBOL_GPL(mas_prev_range); | 5859 | EXPORT_SYMBOL_GPL(mas_prev_range); |
| 5776 | 5860 | ||
| @@ -5828,24 +5912,35 @@ EXPORT_SYMBOL_GPL(mas_pause); · 51 unmodified lines | |||
| 5828 | static inline bool mas_find_setup(struct ma_state *mas, unsigned long max, | 5912 | static inline bool mas_find_setup(struct ma_state *mas, unsigned long max, |
| 5829 | void **entry) | 5913 | void **entry) |
| 5830 | { | 5914 | { |
| 5831 | *entry = NULL; | 5915 | if (mas_is_active(mas)) { |
| 5916 | if (mas->last < max) | ||
| 5917 | return false; | ||
| 5832 | 5918 | ||
| 5833 | if (unlikely(mas_is_none(mas))) { | 5919 | return true; |
| 5920 | } | ||
| 5921 | |||
| 5922 | if (mas_is_paused(mas)) { | ||
| 5834 | if (unlikely(mas->last >= max)) | 5923 | if (unlikely(mas->last >= max)) |
| 5835 | return true; | 5924 | return true; |
| 5836 | 5925 | ||
| 5837 | mas->index = mas->last; | 5926 | mas->index = ++mas->last; |
| 5838 | mas->node = MAS_START; | 5927 | mas->node = MAS_START; |
| 5839 | } else if (unlikely(mas_is_paused(mas))) { | 5928 | } else if (mas_is_none(mas)) { |
| 5840 | if (unlikely(mas->last >= max)) | 5929 | if (unlikely(mas->last >= max)) |
| 5841 | return true; | 5930 | return true; |
| 5842 | 5931 | ||
| 5932 | mas->index = mas->last; | ||
| 5843 | mas->node = MAS_START; | 5933 | mas->node = MAS_START; |
| 5844 | mas->index = ++mas->last; | 5934 | } else if (mas_is_overflow(mas) || mas_is_underflow(mas)) { |
| 5845 | } else if (unlikely(mas_is_ptr(mas))) | 5935 | if (mas->index > max) { |
| 5846 | goto ptr_out_of_range; | 5936 | mas->node = MAS_OVERFLOW; |
| 5937 | return true; | ||
| 5938 | } | ||
| 5939 | |||
| 5940 | mas->node = MAS_START; | ||
| 5941 | } | ||
| 5847 | 5942 | ||
| 5848 | if (unlikely(mas_is_start(mas))) { | 5943 | if (mas_is_start(mas)) { |
| 5849 | /* First run or continue */ | 5944 | /* First run or continue */ |
| 5850 | if (mas->index > max) | 5945 | if (mas->index > max) |
| 5851 | return true; | 5946 | return true; |
| @@ -5895,7 +5990,7 @@ void *mas_find(struct ma_state *mas, unsigned long max) · 43 unmodified lines | |||
| 5895 | return entry; | 5990 | return entry; |
| 5896 | 5991 | ||
| 5897 | /* Retries on dead nodes handled by mas_next_slot */ | 5992 | /* Retries on dead nodes handled by mas_next_slot */ |
| 5898 | return mas_next_slot(mas, max, false); | 5993 | return mas_next_slot(mas, max, false, false); |
| 5899 | } | 5994 | } |
| 5900 | EXPORT_SYMBOL_GPL(mas_find); | 5995 | EXPORT_SYMBOL_GPL(mas_find); |
| 5901 | 5996 | ||
| @@ -5913,13 +6008,13 @@ EXPORT_SYMBOL_GPL(mas_find); · 11 unmodified lines | |||
| 5913 | */ | 6008 | */ |
| 5914 | void *mas_find_range(struct ma_state *mas, unsigned long max) | 6009 | void *mas_find_range(struct ma_state *mas, unsigned long max) |
| 5915 | { | 6010 | { |
| 5916 | void *entry; | 6011 | void *entry = NULL; |
| 5917 | 6012 | ||
| 5918 | if (mas_find_setup(mas, max, &entry)) | 6013 | if (mas_find_setup(mas, max, &entry)) |
| 5919 | return entry; | 6014 | return entry; |
| 5920 | 6015 | ||
| 5921 | /* Retries on dead nodes handled by mas_next_slot */ | 6016 | /* Retries on dead nodes handled by mas_next_slot */ |
| 5922 | return mas_next_slot(mas, max, true); | 6017 | return mas_next_slot(mas, max, true, false); |
| 5923 | } | 6018 | } |
| 5924 | EXPORT_SYMBOL_GPL(mas_find_range); | 6019 | EXPORT_SYMBOL_GPL(mas_find_range); |
| 5925 | 6020 | ||
| @@ -5934,26 +6029,36 @@ EXPORT_SYMBOL_GPL(mas_find_range); · 8 unmodified lines | |||
| 5934 | static inline bool mas_find_rev_setup(struct ma_state *mas, unsigned long min, | 6029 | static inline bool mas_find_rev_setup(struct ma_state *mas, unsigned long min, |
| 5935 | void **entry) | 6030 | void **entry) |
| 5936 | { | 6031 | { |
| 5937 | *entry = NULL; | 6032 | if (mas_is_active(mas)) { |
| 5938 | 6033 | if (mas->index > min) | |
| 5939 | if (unlikely(mas_is_none(mas))) { | 6034 | return false; |
| 5940 | if (mas->index <= min) | ||
| 5941 | goto none; | ||
| 5942 | 6035 | ||
| 5943 | mas->last = mas->index; | 6036 | return true; |
| 5944 | mas->node = MAS_START; | ||
| 5945 | } | 6037 | } |
| 5946 | 6038 | ||
| 5947 | if (unlikely(mas_is_paused(mas))) { | 6039 | if (mas_is_paused(mas)) { |
| 5948 | if (unlikely(mas->index <= min)) { | 6040 | if (unlikely(mas->index <= min)) { |
| 5949 | mas->node = MAS_NONE; | 6041 | mas->node = MAS_NONE; |
| 5950 | return true; | 6042 | return true; |
| 5951 | } | 6043 | } |
| 5952 | mas->node = MAS_START; | 6044 | mas->node = MAS_START; |
| 5953 | mas->last = --mas->index; | 6045 | mas->last = --mas->index; |
| 6046 | } else if (mas_is_none(mas)) { | ||
| 6047 | if (mas->index <= min) | ||
| 6048 | goto none; | ||
| 6049 | |||
| 6050 | mas->last = mas->index; | ||
| 6051 | mas->node = MAS_START; | ||
| 6052 | } else if (mas_is_underflow(mas) || mas_is_overflow(mas)) { | ||
| 6053 | if (mas->last <= min) { | ||
| 6054 | mas->node = MAS_UNDERFLOW; | ||
| 6055 | return true; | ||
| 6056 | } | ||
| 6057 | |||
| 6058 | mas->node = MAS_START; | ||
| 5954 | } | 6059 | } |
| 5955 | 6060 | ||
| 5956 | if (unlikely(mas_is_start(mas))) { | 6061 | if (mas_is_start(mas)) { |
| 5957 | /* First run or continue */ | 6062 | /* First run or continue */ |
| 5958 | if (mas->index < min) | 6063 | if (mas->index < min) |
| 5959 | return true; | 6064 | return true; |
| @@ -6004,13 +6109,13 @@ none: · 44 unmodified lines | |||
| 6004 | */ | 6109 | */ |
| 6005 | void *mas_find_rev(struct ma_state *mas, unsigned long min) | 6110 | void *mas_find_rev(struct ma_state *mas, unsigned long min) |
| 6006 | { | 6111 | { |
| 6007 | void *entry; | 6112 | void *entry = NULL; |
| 6008 | 6113 | ||
| 6009 | if (mas_find_rev_setup(mas, min, &entry)) | 6114 | if (mas_find_rev_setup(mas, min, &entry)) |
| 6010 | return entry; | 6115 | return entry; |
| 6011 | 6116 | ||
| 6012 | /* Retries on dead nodes handled by mas_prev_slot */ | 6117 | /* Retries on dead nodes handled by mas_prev_slot */ |
| 6013 | return mas_prev_slot(mas, min, false); | 6118 | return mas_prev_slot(mas, min, false, false); |
| 6014 | 6119 | ||
| 6015 | } | 6120 | } |
| 6016 | EXPORT_SYMBOL_GPL(mas_find_rev); | 6121 | EXPORT_SYMBOL_GPL(mas_find_rev); |
| @@ -6030,13 +6135,13 @@ EXPORT_SYMBOL_GPL(mas_find_rev); · 13 unmodified lines | |||
| 6030 | */ | 6135 | */ |
| 6031 | void *mas_find_range_rev(struct ma_state *mas, unsigned long min) | 6136 | void *mas_find_range_rev(struct ma_state *mas, unsigned long min) |
| 6032 | { | 6137 | { |
| 6033 | void *entry; | 6138 | void *entry = NULL; |
| 6034 | 6139 | ||
| 6035 | if (mas_find_rev_setup(mas, min, &entry)) | 6140 | if (mas_find_rev_setup(mas, min, &entry)) |
| 6036 | return entry; | 6141 | return entry; |
| 6037 | 6142 | ||
| 6038 | /* Retries on dead nodes handled by mas_prev_slot */ | 6143 | /* Retries on dead nodes handled by mas_prev_slot */ |
| 6039 | return mas_prev_slot(mas, min, true); | 6144 | return mas_prev_slot(mas, min, true, false); |
| 6040 | } | 6145 | } |
| 6041 | EXPORT_SYMBOL_GPL(mas_find_range_rev); | 6146 | EXPORT_SYMBOL_GPL(mas_find_range_rev); |
| 6042 | 6147 | ||
| @@ -265,7 +265,8 @@ EXPORT_SYMBOL(sg_free_table); · 264 unmodified lines | |||
| 265 | * @table: The sg table header to use | 265 | * @table: The sg table header to use |
| 266 | * @nents: Number of entries in sg list | 266 | * @nents: Number of entries in sg list |
| 267 | * @max_ents: The maximum number of entries the allocator returns per call | 267 | * @max_ents: The maximum number of entries the allocator returns per call |
| 268 | * @nents_first_chunk: Number of entries int the (preallocated) first | 268 | * @first_chunk: first SGL if preallocated (may be %NULL) |
| 269 | * @nents_first_chunk: Number of entries in the (preallocated) first | ||
| 269 | * scatterlist chunk, 0 means no such preallocated chunk provided by user | 270 | * scatterlist chunk, 0 means no such preallocated chunk provided by user |
| 270 | * @gfp_mask: GFP allocation mask | 271 | * @gfp_mask: GFP allocation mask |
| 271 | * @alloc_fn: Allocator to use | 272 | * @alloc_fn: Allocator to use |
| @@ -788,6 +789,7 @@ EXPORT_SYMBOL(__sg_page_iter_dma_next); · 516 unmodified lines | |||
| 788 | * @miter: sg mapping iter to be started | 789 | * @miter: sg mapping iter to be started |
| 789 | * @sgl: sg list to iterate over | 790 | * @sgl: sg list to iterate over |
| 790 | * @nents: number of sg entries | 791 | * @nents: number of sg entries |
| 792 | * @flags: sg iterator flags | ||
| 791 | * | 793 | * |
| 792 | * Description: | 794 | * Description: |
| 793 | * Starts mapping iterator @miter. | 795 | * Starts mapping iterator @miter. |
| @@ -2166,7 +2166,7 @@ static noinline void __init next_prev_test(struct maple_tree *mt) · 2165 unmodified lines | |||
| 2166 | MT_BUG_ON(mt, val != NULL); | 2166 | MT_BUG_ON(mt, val != NULL); |
| 2167 | MT_BUG_ON(mt, mas.index != 0); | 2167 | MT_BUG_ON(mt, mas.index != 0); |
| 2168 | MT_BUG_ON(mt, mas.last != 5); | 2168 | MT_BUG_ON(mt, mas.last != 5); |
| 2169 | MT_BUG_ON(mt, mas.node != MAS_NONE); | 2169 | MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW); |
| 2170 | 2170 | ||
| 2171 | mas.index = 0; | 2171 | mas.index = 0; |
| 2172 | mas.last = 5; | 2172 | mas.last = 5; |
| @@ -2917,6 +2917,7 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt) · 744 unmodified lines | |||
| 2917 | * exists MAS_NONE active range | 2917 | * exists MAS_NONE active range |
| 2918 | * exists active active range | 2918 | * exists active active range |
| 2919 | * DNE active active set to last range | 2919 | * DNE active active set to last range |
| 2920 | * ERANGE active MAS_OVERFLOW last range | ||
| 2920 | * | 2921 | * |
| 2921 | * Function ENTRY Start Result index & last | 2922 | * Function ENTRY Start Result index & last |
| 2922 | * mas_prev() | 2923 | * mas_prev() |
| @@ -2945,6 +2946,7 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt) · 22 unmodified lines | |||
| 2945 | * any MAS_ROOT MAS_NONE 0 | 2946 | * any MAS_ROOT MAS_NONE 0 |
| 2946 | * exists active active range | 2947 | * exists active active range |
| 2947 | * DNE active active last range | 2948 | * DNE active active last range |
| 2949 | * ERANGE active MAS_UNDERFLOW last range | ||
| 2948 | * | 2950 | * |
| 2949 | * Function ENTRY Start Result index & last | 2951 | * Function ENTRY Start Result index & last |
| 2950 | * mas_find() | 2952 | * mas_find() |
| @@ -2955,7 +2957,7 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt) · 4 unmodified lines | |||
| 2955 | * DNE MAS_START MAS_NONE 0 | 2957 | * DNE MAS_START MAS_NONE 0 |
| 2956 | * DNE MAS_PAUSE MAS_NONE 0 | 2958 | * DNE MAS_PAUSE MAS_NONE 0 |
| 2957 | * DNE MAS_ROOT MAS_NONE 0 | 2959 | * DNE MAS_ROOT MAS_NONE 0 |
| 2958 | * DNE MAS_NONE MAS_NONE 0 | 2960 | * DNE MAS_NONE MAS_NONE 1 |
| 2959 | * if index == 0 | 2961 | * if index == 0 |
| 2960 | * exists MAS_START MAS_ROOT 0 | 2962 | * exists MAS_START MAS_ROOT 0 |
| 2961 | * exists MAS_PAUSE MAS_ROOT 0 | 2963 | * exists MAS_PAUSE MAS_ROOT 0 |
| @@ -2967,7 +2969,7 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt) · 5 unmodified lines | |||
| 2967 | * DNE MAS_START active set to max | 2969 | * DNE MAS_START active set to max |
| 2968 | * exists MAS_PAUSE active range | 2970 | * exists MAS_PAUSE active range |
| 2969 | * DNE MAS_PAUSE active set to max | 2971 | * DNE MAS_PAUSE active set to max |
| 2970 | * exists MAS_NONE active range | 2972 | * exists MAS_NONE active range (start at last) |
| 2971 | * exists active active range | 2973 | * exists active active range |
| 2972 | * DNE active active last range (max < last) | 2974 | * DNE active active last range (max < last) |
| 2973 | * | 2975 | * |
| @@ -2992,7 +2994,7 @@ static noinline void __init check_empty_area_fill(struct maple_tree *mt) · 18 unmodified lines | |||
| 2992 | * DNE MAS_START active set to min | 2994 | * DNE MAS_START active set to min |
| 2993 | * exists MAS_PAUSE active range | 2995 | * exists MAS_PAUSE active range |
| 2994 | * DNE MAS_PAUSE active set to min | 2996 | * DNE MAS_PAUSE active set to min |
| 2995 | * exists MAS_NONE active range | 2997 | * exists MAS_NONE active range (start at index) |
| 2996 | * exists active active range | 2998 | * exists active active range |
| 2997 | * DNE active active last range (min > index) | 2999 | * DNE active active last range (min > index) |
| 2998 | * | 3000 | * |
| @@ -3039,10 +3041,10 @@ static noinline void __init check_state_handling(struct maple_tree *mt) · 40 unmodified lines | |||
| 3039 | mtree_store_range(mt, 0, 0, ptr, GFP_KERNEL); | 3041 | mtree_store_range(mt, 0, 0, ptr, GFP_KERNEL); |
| 3040 | 3042 | ||
| 3041 | mas_lock(&mas); | 3043 | mas_lock(&mas); |
| 3042 | /* prev: Start -> none */ | 3044 | /* prev: Start -> underflow*/ |
| 3043 | entry = mas_prev(&mas, 0); | 3045 | entry = mas_prev(&mas, 0); |
| 3044 | MT_BUG_ON(mt, entry != NULL); | 3046 | MT_BUG_ON(mt, entry != NULL); |
| 3045 | MT_BUG_ON(mt, mas.node != MAS_NONE); | 3047 | MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW); |
| 3046 | 3048 | ||
| 3047 | /* prev: Start -> root */ | 3049 | /* prev: Start -> root */ |
| 3048 | mas_set(&mas, 10); | 3050 | mas_set(&mas, 10); |
| @@ -3069,7 +3071,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) · 20 unmodified lines | |||
| 3069 | MT_BUG_ON(mt, entry != NULL); | 3071 | MT_BUG_ON(mt, entry != NULL); |
| 3070 | MT_BUG_ON(mt, mas.node != MAS_NONE); | 3072 | MT_BUG_ON(mt, mas.node != MAS_NONE); |
| 3071 | 3073 | ||
| 3072 | /* next: start -> none */ | 3074 | /* next: start -> none*/ |
| 3073 | mas_set(&mas, 10); | 3075 | mas_set(&mas, 10); |
| 3074 | entry = mas_next(&mas, ULONG_MAX); | 3076 | entry = mas_next(&mas, ULONG_MAX); |
| 3075 | MT_BUG_ON(mt, mas.index != 1); | 3077 | MT_BUG_ON(mt, mas.index != 1); |
| @@ -3268,25 +3270,46 @@ static noinline void __init check_state_handling(struct maple_tree *mt) · 192 unmodified lines | |||
| 3268 | MT_BUG_ON(mt, mas.last != 0x2500); | 3270 | MT_BUG_ON(mt, mas.last != 0x2500); |
| 3269 | MT_BUG_ON(mt, !mas_active(mas)); | 3271 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3270 | 3272 | ||
| 3271 | /* next:active -> active out of range*/ | 3273 | /* next:active -> active beyond data */ |
| 3272 | entry = mas_next(&mas, 0x2999); | 3274 | entry = mas_next(&mas, 0x2999); |
| 3273 | MT_BUG_ON(mt, entry != NULL); | 3275 | MT_BUG_ON(mt, entry != NULL); |
| 3274 | MT_BUG_ON(mt, mas.index != 0x2501); | 3276 | MT_BUG_ON(mt, mas.index != 0x2501); |
| 3275 | MT_BUG_ON(mt, mas.last != 0x2fff); | 3277 | MT_BUG_ON(mt, mas.last != 0x2fff); |
| 3276 | MT_BUG_ON(mt, !mas_active(mas)); | 3278 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3277 | 3279 | ||
| 3278 | /* Continue after out of range*/ | 3280 | /* Continue after last range ends after max */ |
| 3279 | entry = mas_next(&mas, ULONG_MAX); | 3281 | entry = mas_next(&mas, ULONG_MAX); |
| 3280 | MT_BUG_ON(mt, entry != ptr3); | 3282 | MT_BUG_ON(mt, entry != ptr3); |
| 3281 | MT_BUG_ON(mt, mas.index != 0x3000); | 3283 | MT_BUG_ON(mt, mas.index != 0x3000); |
| 3282 | MT_BUG_ON(mt, mas.last != 0x3500); | 3284 | MT_BUG_ON(mt, mas.last != 0x3500); |
| 3283 | MT_BUG_ON(mt, !mas_active(mas)); | 3285 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3284 | 3286 | ||
| 3285 | /* next:active -> active out of range*/ | 3287 | /* next:active -> active continued */ |
| 3288 | entry = mas_next(&mas, ULONG_MAX); | ||
| 3289 | MT_BUG_ON(mt, entry != NULL); | ||
| 3290 | MT_BUG_ON(mt, mas.index != 0x3501); | ||
| 3291 | MT_BUG_ON(mt, mas.last != ULONG_MAX); | ||
| 3292 | MT_BUG_ON(mt, !mas_active(mas)); | ||
| 3293 | |||
| 3294 | /* next:active -> overflow */ | ||
| 3286 | entry = mas_next(&mas, ULONG_MAX); | 3295 | entry = mas_next(&mas, ULONG_MAX); |
| 3287 | MT_BUG_ON(mt, entry != NULL); | 3296 | MT_BUG_ON(mt, entry != NULL); |
| 3288 | MT_BUG_ON(mt, mas.index != 0x3501); | 3297 | MT_BUG_ON(mt, mas.index != 0x3501); |
| 3289 | MT_BUG_ON(mt, mas.last != ULONG_MAX); | 3298 | MT_BUG_ON(mt, mas.last != ULONG_MAX); |
| 3299 | MT_BUG_ON(mt, mas.node != MAS_OVERFLOW); | ||
| 3300 | |||
| 3301 | /* next:overflow -> overflow */ | ||
| 3302 | entry = mas_next(&mas, ULONG_MAX); | ||
| 3303 | MT_BUG_ON(mt, entry != NULL); | ||
| 3304 | MT_BUG_ON(mt, mas.index != 0x3501); | ||
| 3305 | MT_BUG_ON(mt, mas.last != ULONG_MAX); | ||
| 3306 | MT_BUG_ON(mt, mas.node != MAS_OVERFLOW); | ||
| 3307 | |||
| 3308 | /* prev:overflow -> active */ | ||
| 3309 | entry = mas_prev(&mas, 0); | ||
| 3310 | MT_BUG_ON(mt, entry != ptr3); | ||
| 3311 | MT_BUG_ON(mt, mas.index != 0x3000); | ||
| 3312 | MT_BUG_ON(mt, mas.last != 0x3500); | ||
| 3290 | MT_BUG_ON(mt, !mas_active(mas)); | 3313 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3291 | 3314 | ||
| 3292 | /* next: none -> active, skip value at location */ | 3315 | /* next: none -> active, skip value at location */ |
| @@ -3307,11 +3330,46 @@ static noinline void __init check_state_handling(struct maple_tree *mt) · 14 unmodified lines | |||
| 3307 | MT_BUG_ON(mt, mas.last != 0x1500); | 3330 | MT_BUG_ON(mt, mas.last != 0x1500); |
| 3308 | MT_BUG_ON(mt, !mas_active(mas)); | 3331 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3309 | 3332 | ||
| 3310 | /* prev:active -> active out of range*/ | 3333 | /* prev:active -> active spanning end range */ |
| 3334 | entry = mas_prev(&mas, 0x0100); | ||
| 3335 | MT_BUG_ON(mt, entry != NULL); | ||
| 3336 | MT_BUG_ON(mt, mas.index != 0); | ||
| 3337 | MT_BUG_ON(mt, mas.last != 0x0FFF); | ||
| 3338 | MT_BUG_ON(mt, !mas_active(mas)); | ||
| 3339 | |||
| 3340 | /* prev:active -> underflow */ | ||
| 3341 | entry = mas_prev(&mas, 0); | ||
| 3342 | MT_BUG_ON(mt, entry != NULL); | ||
| 3343 | MT_BUG_ON(mt, mas.index != 0); | ||
| 3344 | MT_BUG_ON(mt, mas.last != 0x0FFF); | ||
| 3345 | MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW); | ||
| 3346 | |||
| 3347 | /* prev:underflow -> underflow */ | ||
| 3311 | entry = mas_prev(&mas, 0); | 3348 | entry = mas_prev(&mas, 0); |
| 3312 | MT_BUG_ON(mt, entry != NULL); | 3349 | MT_BUG_ON(mt, entry != NULL); |
| 3313 | MT_BUG_ON(mt, mas.index != 0); | 3350 | MT_BUG_ON(mt, mas.index != 0); |
| 3314 | MT_BUG_ON(mt, mas.last != 0x0FFF); | 3351 | MT_BUG_ON(mt, mas.last != 0x0FFF); |
| 3352 | MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW); | ||
| 3353 | |||
| 3354 | /* next:underflow -> active */ | ||
| 3355 | entry = mas_next(&mas, ULONG_MAX); | ||
| 3356 | MT_BUG_ON(mt, entry != ptr); | ||
| 3357 | MT_BUG_ON(mt, mas.index != 0x1000); | ||
| 3358 | MT_BUG_ON(mt, mas.last != 0x1500); | ||
| 3359 | MT_BUG_ON(mt, !mas_active(mas)); | ||
| 3360 | |||
| 3361 | /* prev:first value -> underflow */ | ||
| 3362 | entry = mas_prev(&mas, 0x1000); | ||
| 3363 | MT_BUG_ON(mt, entry != NULL); | ||
| 3364 | MT_BUG_ON(mt, mas.index != 0x1000); | ||
| 3365 | MT_BUG_ON(mt, mas.last != 0x1500); | ||
| 3366 | MT_BUG_ON(mt, mas.node != MAS_UNDERFLOW); | ||
| 3367 | |||
| 3368 | /* find:underflow -> first value */ | ||
| 3369 | entry = mas_find(&mas, ULONG_MAX); | ||
| 3370 | MT_BUG_ON(mt, entry != ptr); | ||
| 3371 | MT_BUG_ON(mt, mas.index != 0x1000); | ||
| 3372 | MT_BUG_ON(mt, mas.last != 0x1500); | ||
| 3315 | MT_BUG_ON(mt, !mas_active(mas)); | 3373 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3316 | 3374 | ||
| 3317 | /* prev: pause ->active */ | 3375 | /* prev: pause ->active */ |
| @@ -3325,14 +3383,14 @@ static noinline void __init check_state_handling(struct maple_tree *mt) · 7 unmodified lines | |||
| 3325 | MT_BUG_ON(mt, mas.last != 0x2500); | 3383 | MT_BUG_ON(mt, mas.last != 0x2500); |
| 3326 | MT_BUG_ON(mt, !mas_active(mas)); | 3384 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3327 | 3385 | ||
| 3328 | /* prev:active -> active out of range*/ | 3386 | /* prev:active -> active spanning min */ |
| 3329 | entry = mas_prev(&mas, 0x1600); | 3387 | entry = mas_prev(&mas, 0x1600); |
| 3330 | MT_BUG_ON(mt, entry != NULL); | 3388 | MT_BUG_ON(mt, entry != NULL); |
| 3331 | MT_BUG_ON(mt, mas.index != 0x1501); | 3389 | MT_BUG_ON(mt, mas.index != 0x1501); |
| 3332 | MT_BUG_ON(mt, mas.last != 0x1FFF); | 3390 | MT_BUG_ON(mt, mas.last != 0x1FFF); |
| 3333 | MT_BUG_ON(mt, !mas_active(mas)); | 3391 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3334 | 3392 | ||
| 3335 | /* prev: active ->active, continue*/ | 3393 | /* prev: active ->active, continue */ |
| 3336 | entry = mas_prev(&mas, 0); | 3394 | entry = mas_prev(&mas, 0); |
| 3337 | MT_BUG_ON(mt, entry != ptr); | 3395 | MT_BUG_ON(mt, entry != ptr); |
| 3338 | MT_BUG_ON(mt, mas.index != 0x1000); | 3396 | MT_BUG_ON(mt, mas.index != 0x1000); |
| @@ -3379,7 +3437,7 @@ static noinline void __init check_state_handling(struct maple_tree *mt) · 40 unmodified lines | |||
| 3379 | MT_BUG_ON(mt, mas.last != 0x2FFF); | 3437 | MT_BUG_ON(mt, mas.last != 0x2FFF); |
| 3380 | MT_BUG_ON(mt, !mas_active(mas)); | 3438 | MT_BUG_ON(mt, !mas_active(mas)); |
| 3381 | 3439 | ||
| 3382 | /* find: none ->active */ | 3440 | /* find: overflow ->active */ |
| 3383 | entry = mas_find(&mas, 0x5000); | 3441 | entry = mas_find(&mas, 0x5000); |
| 3384 | MT_BUG_ON(mt, entry != ptr3); | 3442 | MT_BUG_ON(mt, entry != ptr3); |
| 3385 | MT_BUG_ON(mt, mas.index != 0x3000); | 3443 | MT_BUG_ON(mt, mas.index != 0x3000); |
| @@ -3778,7 +3836,6 @@ static int __init maple_tree_seed(void) · 392 unmodified lines | |||
| 3778 | check_empty_area_fill(&tree); | 3836 | check_empty_area_fill(&tree); |
| 3779 | mtree_destroy(&tree); | 3837 | mtree_destroy(&tree); |
| 3780 | 3838 | ||
| 3781 | |||
| 3782 | mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); | 3839 | mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); |
| 3783 | check_state_handling(&tree); | 3840 | check_state_handling(&tree); |
| 3784 | mtree_destroy(&tree); | 3841 | mtree_destroy(&tree); |
| @@ -148,6 +148,8 @@ static void damon_do_test_apply_three_regions(struct kunit *test, · 147 unmodified lines | |||
| 148 | KUNIT_EXPECT_EQ(test, r->ar.start, expected[i * 2]); | 148 | KUNIT_EXPECT_EQ(test, r->ar.start, expected[i * 2]); |
| 149 | KUNIT_EXPECT_EQ(test, r->ar.end, expected[i * 2 + 1]); | 149 | KUNIT_EXPECT_EQ(test, r->ar.end, expected[i * 2 + 1]); |
| 150 | } | 150 | } |
| 151 | |||
| 152 | damon_destroy_target(t); | ||
| 151 | } | 153 | } |
| 152 | 154 | ||
| 153 | /* | 155 | /* |
| @@ -341,13 +341,14 @@ static void damon_hugetlb_mkold(pte_t *pte, struct mm_struct *mm, · 340 unmodified lines | |||
| 341 | bool referenced = false; | 341 | bool referenced = false; |
| 342 | pte_t entry = huge_ptep_get(pte); | 342 | pte_t entry = huge_ptep_get(pte); |
| 343 | struct folio *folio = pfn_folio(pte_pfn(entry)); | 343 | struct folio *folio = pfn_folio(pte_pfn(entry)); |
| 344 | unsigned long psize = huge_page_size(hstate_vma(vma)); | ||
| 344 | 345 | ||
| 345 | folio_get(folio); | 346 | folio_get(folio); |
| 346 | 347 | ||
| 347 | if (pte_young(entry)) { | 348 | if (pte_young(entry)) { |
| 348 | referenced = true; | 349 | referenced = true; |
| 349 | entry = pte_mkold(entry); | 350 | entry = pte_mkold(entry); |
| 350 | set_huge_pte_at(mm, addr, pte, entry); | 351 | set_huge_pte_at(mm, addr, pte, entry, psize); |
| 351 | } | 352 | } |
| 352 | 353 | ||
| 353 | #ifdef CONFIG_MMU_NOTIFIER | 354 | #ifdef CONFIG_MMU_NOTIFIER |
| @@ -3475,13 +3475,11 @@ skip: · 3474 unmodified lines | |||
| 3475 | */ | 3475 | */ |
| 3476 | static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf, | 3476 | static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf, |
| 3477 | struct folio *folio, unsigned long start, | 3477 | struct folio *folio, unsigned long start, |
| 3478 | unsigned long addr, unsigned int nr_pages) | 3478 | unsigned long addr, unsigned int nr_pages, |
| 3479 | unsigned int *mmap_miss) | ||
| 3479 | { | 3480 | { |
| 3480 | vm_fault_t ret = 0; | 3481 | vm_fault_t ret = 0; |
| 3481 | struct vm_area_struct *vma = vmf->vma; | ||
| 3482 | struct file *file = vma->vm_file; | ||
| 3483 | struct page *page = folio_page(folio, start); | 3482 | struct page *page = folio_page(folio, start); |
| 3484 | unsigned int mmap_miss = READ_ONCE(file->f_ra.mmap_miss); | ||
| 3485 | unsigned int count = 0; | 3483 | unsigned int count = 0; |
| 3486 | pte_t *old_ptep = vmf->pte; | 3484 | pte_t *old_ptep = vmf->pte; |
| 3487 | 3485 | ||
| @@ -3489,8 +3487,7 @@ static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf, · 1 unmodified line | |||
| 3489 | if (PageHWPoison(page + count)) | 3487 | if (PageHWPoison(page + count)) |
| 3490 | goto skip; | 3488 | goto skip; |
| 3491 | 3489 | ||
| 3492 | if (mmap_miss > 0) | 3490 | (*mmap_miss)++; |
| 3493 | mmap_miss--; | ||
| 3494 | 3491 | ||
| 3495 | /* | 3492 | /* |
| 3496 | * NOTE: If there're PTE markers, we'll leave them to be | 3493 | * NOTE: If there're PTE markers, we'll leave them to be |
| @@ -3506,7 +3503,7 @@ skip: · 9 unmodified lines | |||
| 3506 | if (count) { | 3503 | if (count) { |
| 3507 | set_pte_range(vmf, folio, page, count, addr); | 3504 | set_pte_range(vmf, folio, page, count, addr); |
| 3508 | folio_ref_add(folio, count); | 3505 | folio_ref_add(folio, count); |
| 3509 | if (in_range(vmf->address, addr, count)) | 3506 | if (in_range(vmf->address, addr, count * PAGE_SIZE)) |
| 3510 | ret = VM_FAULT_NOPAGE; | 3507 | ret = VM_FAULT_NOPAGE; |
| 3511 | } | 3508 | } |
| 3512 | 3509 | ||
| @@ -3520,12 +3517,40 @@ skip: · 7 unmodified lines | |||
| 3520 | if (count) { | 3517 | if (count) { |
| 3521 | set_pte_range(vmf, folio, page, count, addr); | 3518 | set_pte_range(vmf, folio, page, count, addr); |
| 3522 | folio_ref_add(folio, count); | 3519 | folio_ref_add(folio, count); |
| 3523 | if (in_range(vmf->address, addr, count)) | 3520 | if (in_range(vmf->address, addr, count * PAGE_SIZE)) |
| 3524 | ret = VM_FAULT_NOPAGE; | 3521 | ret = VM_FAULT_NOPAGE; |
| 3525 | } | 3522 | } |
| 3526 | 3523 | ||
| 3527 | vmf->pte = old_ptep; | 3524 | vmf->pte = old_ptep; |
| 3528 | WRITE_ONCE(file->f_ra.mmap_miss, mmap_miss); | 3525 | |
| 3526 | return ret; | ||
| 3527 | } | ||
| 3528 | |||
| 3529 | static vm_fault_t filemap_map_order0_folio(struct vm_fault *vmf, | ||
| 3530 | struct folio *folio, unsigned long addr, | ||
| 3531 | unsigned int *mmap_miss) | ||
| 3532 | { | ||
| 3533 | vm_fault_t ret = 0; | ||
| 3534 | struct page *page = &folio->page; | ||
| 3535 | |||
| 3536 | if (PageHWPoison(page)) | ||
| 3537 | return ret; | ||
| 3538 | |||
| 3539 | (*mmap_miss)++; | ||
| 3540 | |||
| 3541 | /* | ||
| 3542 | * NOTE: If there're PTE markers, we'll leave them to be | ||
| 3543 | * handled in the specific fault path, and it'll prohibit | ||
| 3544 | * the fault-around logic. | ||
| 3545 | */ | ||
| 3546 | if (!pte_none(ptep_get(vmf->pte))) | ||
| 3547 | return ret; | ||
| 3548 | |||
| 3549 | if (vmf->address == addr) | ||
| 3550 | ret = VM_FAULT_NOPAGE; | ||
| 3551 | |||
| 3552 | set_pte_range(vmf, folio, page, 1, addr); | ||
| 3553 | folio_ref_inc(folio); | ||
| 3529 | 3554 | ||
| 3530 | return ret; | 3555 | return ret; |
| 3531 | } | 3556 | } |
| @@ -3541,7 +3566,7 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, · 9 unmodified lines | |||
| 3541 | XA_STATE(xas, &mapping->i_pages, start_pgoff); | 3566 | XA_STATE(xas, &mapping->i_pages, start_pgoff); |
| 3542 | struct folio *folio; | 3567 | struct folio *folio; |
| 3543 | vm_fault_t ret = 0; | 3568 | vm_fault_t ret = 0; |
| 3544 | int nr_pages = 0; | 3569 | unsigned int nr_pages = 0, mmap_miss = 0, mmap_miss_saved; |
| 3545 | 3570 | ||
| 3546 | rcu_read_lock(); | 3571 | rcu_read_lock(); |
| 3547 | folio = next_uptodate_folio(&xas, mapping, end_pgoff); | 3572 | folio = next_uptodate_folio(&xas, mapping, end_pgoff); |
| @@ -3569,25 +3594,27 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, · 21 unmodified lines | |||
| 3569 | end = folio->index + folio_nr_pages(folio) - 1; | 3594 | end = folio->index + folio_nr_pages(folio) - 1; |
| 3570 | nr_pages = min(end, end_pgoff) - xas.xa_index + 1; | 3595 | nr_pages = min(end, end_pgoff) - xas.xa_index + 1; |
| 3571 | 3596 | ||
| 3572 | /* | 3597 | if (!folio_test_large(folio)) |
| 3573 | * NOTE: If there're PTE markers, we'll leave them to be | 3598 | ret |= filemap_map_order0_folio(vmf, |
| 3574 | * handled in the specific fault path, and it'll prohibit the | 3599 | folio, addr, &mmap_miss); |
| 3575 | * fault-around logic. | 3600 | else |
| 3576 | */ | 3601 | ret |= filemap_map_folio_range(vmf, folio, |
| 3577 | if (!pte_none(ptep_get(vmf->pte))) | 3602 | xas.xa_index - folio->index, addr, |
| 3578 | goto unlock; | 3603 | nr_pages, &mmap_miss); |
| 3579 | |||
| 3580 | ret |= filemap_map_folio_range(vmf, folio, | ||
| 3581 | xas.xa_index - folio->index, addr, nr_pages); | ||
| 3582 | 3604 | ||
| 3583 | unlock: | ||
| 3584 | folio_unlock(folio); | 3605 | folio_unlock(folio); |
| 3585 | folio_put(folio); | 3606 | folio_put(folio); |
| 3586 | folio = next_uptodate_folio(&xas, mapping, end_pgoff); | 3607 | } while ((folio = next_uptodate_folio(&xas, mapping, end_pgoff)) != NULL); |
| 3587 | } while (folio); | ||
| 3588 | pte_unmap_unlock(vmf->pte, vmf->ptl); | 3608 | pte_unmap_unlock(vmf->pte, vmf->ptl); |
| 3589 | out: | 3609 | out: |
| 3590 | rcu_read_unlock(); | 3610 | rcu_read_unlock(); |
| 3611 | |||
| 3612 | mmap_miss_saved = READ_ONCE(file->f_ra.mmap_miss); | ||
| 3613 | if (mmap_miss >= mmap_miss_saved) | ||
| 3614 | WRITE_ONCE(file->f_ra.mmap_miss, 0); | ||
| 3615 | else | ||
| 3616 | WRITE_ONCE(file->f_ra.mmap_miss, mmap_miss_saved - mmap_miss); | ||
| 3617 | |||
| 3591 | return ret; | 3618 | return ret; |
| 3592 | } | 3619 | } |
| 3593 | EXPORT_SYMBOL(filemap_map_pages); | 3620 | EXPORT_SYMBOL(filemap_map_pages); |
| @@ -4980,7 +4980,7 @@ static bool is_hugetlb_entry_hwpoisoned(pte_t pte) · 4979 unmodified lines | |||
| 4980 | 4980 | ||
| 4981 | static void | 4981 | static void |
| 4982 | hugetlb_install_folio(struct vm_area_struct *vma, pte_t *ptep, unsigned long addr, | 4982 | hugetlb_install_folio(struct vm_area_struct *vma, pte_t *ptep, unsigned long addr, |
| 4983 | struct folio *new_folio, pte_t old) | 4983 | struct folio *new_folio, pte_t old, unsigned long sz) |
| 4984 | { | 4984 | { |
| 4985 | pte_t newpte = make_huge_pte(vma, &new_folio->page, 1); | 4985 | pte_t newpte = make_huge_pte(vma, &new_folio->page, 1); |
| 4986 | 4986 | ||
| @@ -4988,7 +4988,7 @@ hugetlb_install_folio(struct vm_area_struct *vma, pte_t *ptep, unsigned long add · 1 unmodified line | |||
| 4988 | hugepage_add_new_anon_rmap(new_folio, vma, addr); | 4988 | hugepage_add_new_anon_rmap(new_folio, vma, addr); |
| 4989 | if (userfaultfd_wp(vma) && huge_pte_uffd_wp(old)) | 4989 | if (userfaultfd_wp(vma) && huge_pte_uffd_wp(old)) |
| 4990 | newpte = huge_pte_mkuffd_wp(newpte); | 4990 | newpte = huge_pte_mkuffd_wp(newpte); |
| 4991 | set_huge_pte_at(vma->vm_mm, addr, ptep, newpte); | 4991 | set_huge_pte_at(vma->vm_mm, addr, ptep, newpte, sz); |
| 4992 | hugetlb_count_add(pages_per_huge_page(hstate_vma(vma)), vma->vm_mm); | 4992 | hugetlb_count_add(pages_per_huge_page(hstate_vma(vma)), vma->vm_mm); |
| 4993 | folio_set_hugetlb_migratable(new_folio); | 4993 | folio_set_hugetlb_migratable(new_folio); |
| 4994 | } | 4994 | } |
| @@ -5065,7 +5065,7 @@ again: · 70 unmodified lines | |||
| 5065 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) { | 5065 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) { |
| 5066 | if (!userfaultfd_wp(dst_vma)) | 5066 | if (!userfaultfd_wp(dst_vma)) |
| 5067 | entry = huge_pte_clear_uffd_wp(entry); | 5067 | entry = huge_pte_clear_uffd_wp(entry); |
| 5068 | set_huge_pte_at(dst, addr, dst_pte, entry); | 5068 | set_huge_pte_at(dst, addr, dst_pte, entry, sz); |
| 5069 | } else if (unlikely(is_hugetlb_entry_migration(entry))) { | 5069 | } else if (unlikely(is_hugetlb_entry_migration(entry))) { |
| 5070 | swp_entry_t swp_entry = pte_to_swp_entry(entry); | 5070 | swp_entry_t swp_entry = pte_to_swp_entry(entry); |
| 5071 | bool uffd_wp = pte_swp_uffd_wp(entry); | 5071 | bool uffd_wp = pte_swp_uffd_wp(entry); |
| @@ -5080,18 +5080,18 @@ again: · 8 unmodified lines | |||
| 5080 | entry = swp_entry_to_pte(swp_entry); | 5080 | entry = swp_entry_to_pte(swp_entry); |
| 5081 | if (userfaultfd_wp(src_vma) && uffd_wp) | 5081 | if (userfaultfd_wp(src_vma) && uffd_wp) |
| 5082 | entry = pte_swp_mkuffd_wp(entry); | 5082 | entry = pte_swp_mkuffd_wp(entry); |
| 5083 | set_huge_pte_at(src, addr, src_pte, entry); | 5083 | set_huge_pte_at(src, addr, src_pte, entry, sz); |
| 5084 | } | 5084 | } |
| 5085 | if (!userfaultfd_wp(dst_vma)) | 5085 | if (!userfaultfd_wp(dst_vma)) |
| 5086 | entry = huge_pte_clear_uffd_wp(entry); | 5086 | entry = huge_pte_clear_uffd_wp(entry); |
| 5087 | set_huge_pte_at(dst, addr, dst_pte, entry); | 5087 | set_huge_pte_at(dst, addr, dst_pte, entry, sz); |
| 5088 | } else if (unlikely(is_pte_marker(entry))) { | 5088 | } else if (unlikely(is_pte_marker(entry))) { |
| 5089 | pte_marker marker = copy_pte_marker( | 5089 | pte_marker marker = copy_pte_marker( |
| 5090 | pte_to_swp_entry(entry), dst_vma); | 5090 | pte_to_swp_entry(entry), dst_vma); |
| 5091 | 5091 | ||
| 5092 | if (marker) | 5092 | if (marker) |
| 5093 | set_huge_pte_at(dst, addr, dst_pte, | 5093 | set_huge_pte_at(dst, addr, dst_pte, |
| 5094 | make_pte_marker(marker)); | 5094 | make_pte_marker(marker), sz); |
| 5095 | } else { | 5095 | } else { |
| 5096 | entry = huge_ptep_get(src_pte); | 5096 | entry = huge_ptep_get(src_pte); |
| 5097 | pte_folio = page_folio(pte_page(entry)); | 5097 | pte_folio = page_folio(pte_page(entry)); |
| @@ -5145,7 +5145,7 @@ again: · 47 unmodified lines | |||
| 5145 | goto again; | 5145 | goto again; |
| 5146 | } | 5146 | } |
| 5147 | hugetlb_install_folio(dst_vma, dst_pte, addr, | 5147 | hugetlb_install_folio(dst_vma, dst_pte, addr, |
| 5148 | new_folio, src_pte_old); | 5148 | new_folio, src_pte_old, sz); |
| 5149 | spin_unlock(src_ptl); | 5149 | spin_unlock(src_ptl); |
| 5150 | spin_unlock(dst_ptl); | 5150 | spin_unlock(dst_ptl); |
| 5151 | continue; | 5151 | continue; |
| @@ -5166,7 +5166,7 @@ again: · 14 unmodified lines | |||
| 5166 | if (!userfaultfd_wp(dst_vma)) | 5166 | if (!userfaultfd_wp(dst_vma)) |
| 5167 | entry = huge_pte_clear_uffd_wp(entry); | 5167 | entry = huge_pte_clear_uffd_wp(entry); |
| 5168 | 5168 | ||
| 5169 | set_huge_pte_at(dst, addr, dst_pte, entry); | 5169 | set_huge_pte_at(dst, addr, dst_pte, entry, sz); |
| 5170 | hugetlb_count_add(npages, dst); | 5170 | hugetlb_count_add(npages, dst); |
| 5171 | } | 5171 | } |
| 5172 | spin_unlock(src_ptl); | 5172 | spin_unlock(src_ptl); |
| @@ -5184,7 +5184,8 @@ again: · 11 unmodified lines | |||
| 5184 | } | 5184 | } |
| 5185 | 5185 | ||
| 5186 | static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr, | 5186 | static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr, |
| 5187 | unsigned long new_addr, pte_t *src_pte, pte_t *dst_pte) | 5187 | unsigned long new_addr, pte_t *src_pte, pte_t *dst_pte, |
| 5188 | unsigned long sz) | ||
| 5188 | { | 5189 | { |
| 5189 | struct hstate *h = hstate_vma(vma); | 5190 | struct hstate *h = hstate_vma(vma); |
| 5190 | struct mm_struct *mm = vma->vm_mm; | 5191 | struct mm_struct *mm = vma->vm_mm; |
| @@ -5202,7 +5203,7 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr, · 11 unmodified lines | |||
| 5202 | spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING); | 5203 | spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING); |
| 5203 | 5204 | ||
| 5204 | pte = huge_ptep_get_and_clear(mm, old_addr, src_pte); | 5205 | pte = huge_ptep_get_and_clear(mm, old_addr, src_pte); |
| 5205 | set_huge_pte_at(mm, new_addr, dst_pte, pte); | 5206 | set_huge_pte_at(mm, new_addr, dst_pte, pte, sz); |
| 5206 | 5207 | ||
| 5207 | if (src_ptl != dst_ptl) | 5208 | if (src_ptl != dst_ptl) |
| 5208 | spin_unlock(src_ptl); | 5209 | spin_unlock(src_ptl); |
| @@ -5259,7 +5260,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, · 50 unmodified lines | |||
| 5259 | if (!dst_pte) | 5260 | if (!dst_pte) |
| 5260 | break; | 5261 | break; |
| 5261 | 5262 | ||
| 5262 | move_huge_pte(vma, old_addr, new_addr, src_pte, dst_pte); | 5263 | move_huge_pte(vma, old_addr, new_addr, src_pte, dst_pte, sz); |
| 5263 | } | 5264 | } |
| 5264 | 5265 | ||
| 5265 | if (shared_pmd) | 5266 | if (shared_pmd) |
| @@ -5337,7 +5338,8 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct · 71 unmodified lines | |||
| 5337 | if (pte_swp_uffd_wp_any(pte) && | 5338 | if (pte_swp_uffd_wp_any(pte) && |
| 5338 | !(zap_flags & ZAP_FLAG_DROP_MARKER)) | 5339 | !(zap_flags & ZAP_FLAG_DROP_MARKER)) |
| 5339 | set_huge_pte_at(mm, address, ptep, | 5340 | set_huge_pte_at(mm, address, ptep, |
| 5340 | make_pte_marker(PTE_MARKER_UFFD_WP)); | 5341 | make_pte_marker(PTE_MARKER_UFFD_WP), |
| 5342 | sz); | ||
| 5341 | else | 5343 | else |
| 5342 | huge_pte_clear(mm, address, ptep, sz); | 5344 | huge_pte_clear(mm, address, ptep, sz); |
| 5343 | spin_unlock(ptl); | 5345 | spin_unlock(ptl); |
| @@ -5371,7 +5373,8 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct · 27 unmodified lines | |||
| 5371 | if (huge_pte_uffd_wp(pte) && | 5373 | if (huge_pte_uffd_wp(pte) && |
| 5372 | !(zap_flags & ZAP_FLAG_DROP_MARKER)) | 5374 | !(zap_flags & ZAP_FLAG_DROP_MARKER)) |
| 5373 | set_huge_pte_at(mm, address, ptep, | 5375 | set_huge_pte_at(mm, address, ptep, |
| 5374 | make_pte_marker(PTE_MARKER_UFFD_WP)); | 5376 | make_pte_marker(PTE_MARKER_UFFD_WP), |
| 5377 | sz); | ||
| 5375 | hugetlb_count_sub(pages_per_huge_page(h), mm); | 5378 | hugetlb_count_sub(pages_per_huge_page(h), mm); |
| 5376 | page_remove_rmap(page, vma, true); | 5379 | page_remove_rmap(page, vma, true); |
| 5377 | 5380 | ||
| @@ -5676,7 +5679,7 @@ retry_avoidcopy: · 298 unmodified lines | |||
| 5676 | hugepage_add_new_anon_rmap(new_folio, vma, haddr); | 5679 | hugepage_add_new_anon_rmap(new_folio, vma, haddr); |
| 5677 | if (huge_pte_uffd_wp(pte)) | 5680 | if (huge_pte_uffd_wp(pte)) |
| 5678 | newpte = huge_pte_mkuffd_wp(newpte); | 5681 | newpte = huge_pte_mkuffd_wp(newpte); |
| 5679 | set_huge_pte_at(mm, haddr, ptep, newpte); | 5682 | set_huge_pte_at(mm, haddr, ptep, newpte, huge_page_size(h)); |
| 5680 | folio_set_hugetlb_migratable(new_folio); | 5683 | folio_set_hugetlb_migratable(new_folio); |
| 5681 | /* Make the old page be freed below */ | 5684 | /* Make the old page be freed below */ |
| 5682 | new_folio = old_folio; | 5685 | new_folio = old_folio; |
| @@ -5972,7 +5975,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm, · 289 unmodified lines | |||
| 5972 | */ | 5975 | */ |
| 5973 | if (unlikely(pte_marker_uffd_wp(old_pte))) | 5976 | if (unlikely(pte_marker_uffd_wp(old_pte))) |
| 5974 | new_pte = huge_pte_mkuffd_wp(new_pte); | 5977 | new_pte = huge_pte_mkuffd_wp(new_pte); |
| 5975 | set_huge_pte_at(mm, haddr, ptep, new_pte); | 5978 | set_huge_pte_at(mm, haddr, ptep, new_pte, huge_page_size(h)); |
| 5976 | 5979 | ||
| 5977 | hugetlb_count_add(pages_per_huge_page(h), mm); | 5980 | hugetlb_count_add(pages_per_huge_page(h), mm); |
| 5978 | if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { | 5981 | if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { |
| @@ -6261,7 +6264,8 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, · 282 unmodified lines | |||
| 6261 | } | 6264 | } |
| 6262 | 6265 | ||
| 6263 | _dst_pte = make_pte_marker(PTE_MARKER_POISONED); | 6266 | _dst_pte = make_pte_marker(PTE_MARKER_POISONED); |
| 6264 | set_huge_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte); | 6267 | set_huge_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte, |
| 6268 | huge_page_size(h)); | ||
| 6265 | 6269 | ||
| 6266 | /* No need to invalidate - it was non-present before */ | 6270 | /* No need to invalidate - it was non-present before */ |
| 6267 | update_mmu_cache(dst_vma, dst_addr, dst_pte); | 6271 | update_mmu_cache(dst_vma, dst_addr, dst_pte); |
| @@ -6412,7 +6416,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, · 144 unmodified lines | |||
| 6412 | if (wp_enabled) | 6416 | if (wp_enabled) |
| 6413 | _dst_pte = huge_pte_mkuffd_wp(_dst_pte); | 6417 | _dst_pte = huge_pte_mkuffd_wp(_dst_pte); |
| 6414 | 6418 | ||
| 6415 | set_huge_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte); | 6419 | set_huge_pte_at(dst_mm, dst_addr, dst_pte, _dst_pte, huge_page_size(h)); |
| 6416 | 6420 | ||
| 6417 | hugetlb_count_add(pages_per_huge_page(h), dst_mm); | 6421 | hugetlb_count_add(pages_per_huge_page(h), dst_mm); |
| 6418 | 6422 | ||
| @@ -6598,7 +6602,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma, · 179 unmodified lines | |||
| 6598 | else if (uffd_wp_resolve) | 6602 | else if (uffd_wp_resolve) |
| 6599 | newpte = pte_swp_clear_uffd_wp(newpte); | 6603 | newpte = pte_swp_clear_uffd_wp(newpte); |
| 6600 | if (!pte_same(pte, newpte)) | 6604 | if (!pte_same(pte, newpte)) |
| 6601 | set_huge_pte_at(mm, address, ptep, newpte); | 6605 | set_huge_pte_at(mm, address, ptep, newpte, psize); |
| 6602 | } else if (unlikely(is_pte_marker(pte))) { | 6606 | } else if (unlikely(is_pte_marker(pte))) { |
| 6603 | /* No other markers apply for now. */ | 6607 | /* No other markers apply for now. */ |
| 6604 | WARN_ON_ONCE(!pte_marker_uffd_wp(pte)); | 6608 | WARN_ON_ONCE(!pte_marker_uffd_wp(pte)); |
| @@ -6623,7 +6627,8 @@ long hugetlb_change_protection(struct vm_area_struct *vma, · 18 unmodified lines | |||
| 6623 | if (unlikely(uffd_wp)) | 6627 | if (unlikely(uffd_wp)) |
| 6624 | /* Safe to modify directly (none->non-present). */ | 6628 | /* Safe to modify directly (none->non-present). */ |
| 6625 | set_huge_pte_at(mm, address, ptep, | 6629 | set_huge_pte_at(mm, address, ptep, |
| 6626 | make_pte_marker(PTE_MARKER_UFFD_WP)); | 6630 | make_pte_marker(PTE_MARKER_UFFD_WP), |
| 6631 | psize); | ||
| 6627 | } | 6632 | } |
| 6628 | spin_unlock(ptl); | 6633 | spin_unlock(ptl); |
| 6629 | } | 6634 | } |
| @@ -291,7 +291,7 @@ struct kasan_stack_ring { · 290 unmodified lines | |||
| 291 | 291 | ||
| 292 | #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) | 292 | #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) |
| 293 | 293 | ||
| 294 | #ifndef __HAVE_ARCH_SHADOW_MAP | 294 | #ifndef kasan_shadow_to_mem |
| 295 | static inline const void *kasan_shadow_to_mem(const void *shadow_addr) | 295 | static inline const void *kasan_shadow_to_mem(const void *shadow_addr) |
| 296 | { | 296 | { |
| 297 | return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET) | 297 | return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET) |
| @@ -299,15 +299,13 @@ static inline const void *kasan_shadow_to_mem(const void *shadow_addr) · 1 unmodified line | |||
| 299 | } | 299 | } |
| 300 | #endif | 300 | #endif |
| 301 | 301 | ||
| 302 | #ifndef addr_has_metadata | ||
| 302 | static __always_inline bool addr_has_metadata(const void *addr) | 303 | static __always_inline bool addr_has_metadata(const void *addr) |
| 303 | { | 304 | { |
| 304 | #ifdef __HAVE_ARCH_SHADOW_MAP | ||
| 305 | return (kasan_mem_to_shadow((void *)addr) != NULL); | ||
| 306 | #else | ||
| 307 | return (kasan_reset_tag(addr) >= | 305 | return (kasan_reset_tag(addr) >= |
| 308 | kasan_shadow_to_mem((void *)KASAN_SHADOW_START)); | 306 | kasan_shadow_to_mem((void *)KASAN_SHADOW_START)); |
| 309 | #endif | ||
| 310 | } | 307 | } |
| 308 | #endif | ||
| 311 | 309 | ||
| 312 | /** | 310 | /** |
| 313 | * kasan_check_range - Check memory region, and report if invalid access. | 311 | * kasan_check_range - Check memory region, and report if invalid access. |
| @@ -2555,7 +2555,7 @@ static unsigned long calculate_high_delay(struct mem_cgroup *memcg, · 2554 unmodified lines | |||
| 2555 | * Scheduled by try_charge() to be executed from the userland return path | 2555 | * Scheduled by try_charge() to be executed from the userland return path |
| 2556 | * and reclaims memory over the high limit. | 2556 | * and reclaims memory over the high limit. |
| 2557 | */ | 2557 | */ |
| 2558 | void mem_cgroup_handle_over_high(void) | 2558 | void mem_cgroup_handle_over_high(gfp_t gfp_mask) |
| 2559 | { | 2559 | { |
| 2560 | unsigned long penalty_jiffies; | 2560 | unsigned long penalty_jiffies; |
| 2561 | unsigned long pflags; | 2561 | unsigned long pflags; |
| @@ -2583,7 +2583,7 @@ retry_reclaim: · 21 unmodified lines | |||
| 2583 | */ | 2583 | */ |
| 2584 | nr_reclaimed = reclaim_high(memcg, | 2584 | nr_reclaimed = reclaim_high(memcg, |
| 2585 | in_retry ? SWAP_CLUSTER_MAX : nr_pages, | 2585 | in_retry ? SWAP_CLUSTER_MAX : nr_pages, |
| 2586 | GFP_KERNEL); | 2586 | gfp_mask); |
| 2587 | 2587 | ||
| 2588 | /* | 2588 | /* |
| 2589 | * memory.high is breached and reclaim is unable to keep up. Throttle | 2589 | * memory.high is breached and reclaim is unable to keep up. Throttle |
| @@ -2819,7 +2819,7 @@ done_restock: · 229 unmodified lines | |||
| 2819 | if (current->memcg_nr_pages_over_high > MEMCG_CHARGE_BATCH && | 2819 | if (current->memcg_nr_pages_over_high > MEMCG_CHARGE_BATCH && |
| 2820 | !(current->flags & PF_MEMALLOC) && | 2820 | !(current->flags & PF_MEMALLOC) && |
| 2821 | gfpflags_allow_blocking(gfp_mask)) { | 2821 | gfpflags_allow_blocking(gfp_mask)) { |
| 2822 | mem_cgroup_handle_over_high(); | 2822 | mem_cgroup_handle_over_high(gfp_mask); |
| 2823 | } | 2823 | } |
| 2824 | return 0; | 2824 | return 0; |
| 2825 | } | 2825 | } |
| @@ -3867,6 +3867,13 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of, · 1041 unmodified lines | |||
| 3867 | case _MEMSWAP: | 3867 | case _MEMSWAP: |
| 3868 | ret = mem_cgroup_resize_max(memcg, nr_pages, true); | 3868 | ret = mem_cgroup_resize_max(memcg, nr_pages, true); |
| 3869 | break; | 3869 | break; |
| 3870 | case _KMEM: | ||
| 3871 | pr_warn_once("kmem.limit_in_bytes is deprecated and will be removed. " | ||
| 3872 | "Writing any value to this file has no effect. " | ||
| 3873 | "Please report your usecase to linux-mm@kvack.org if you " | ||
| 3874 | "depend on this functionality.\n"); | ||
| 3875 | ret = 0; | ||
| 3876 | break; | ||
| 3870 | case _TCP: | 3877 | case _TCP: |
| 3871 | ret = memcg_update_tcp_max(memcg, nr_pages); | 3878 | ret = memcg_update_tcp_max(memcg, nr_pages); |
| 3872 | break; | 3879 | break; |
| @@ -5077,6 +5084,12 @@ static struct cftype mem_cgroup_legacy_files[] = { · 1204 unmodified lines | |||
| 5077 | .seq_show = memcg_numa_stat_show, | 5084 | .seq_show = memcg_numa_stat_show, |
| 5078 | }, | 5085 | }, |
| 5079 | #endif | 5086 | #endif |
| 5087 | { | ||
| 5088 | .name = "kmem.limit_in_bytes", | ||
| 5089 | .private = MEMFILE_PRIVATE(_KMEM, RES_LIMIT), | ||
| 5090 | .write = mem_cgroup_write, | ||
| 5091 | .read_u64 = mem_cgroup_read_u64, | ||
| 5092 | }, | ||
| 5080 | { | 5093 | { |
| 5081 | .name = "kmem.usage_in_bytes", | 5094 | .name = "kmem.usage_in_bytes", |
| 5082 | .private = MEMFILE_PRIVATE(_KMEM, RES_USAGE), | 5095 | .private = MEMFILE_PRIVATE(_KMEM, RES_USAGE), |
| @@ -426,6 +426,7 @@ struct queue_pages { · 425 unmodified lines | |||
| 426 | unsigned long start; | 426 | unsigned long start; |
| 427 | unsigned long end; | 427 | unsigned long end; |
| 428 | struct vm_area_struct *first; | 428 | struct vm_area_struct *first; |
| 429 | bool has_unmovable; | ||
| 429 | }; | 430 | }; |
| 430 | 431 | ||
| 431 | /* | 432 | /* |
| @@ -446,9 +447,8 @@ static inline bool queue_folio_required(struct folio *folio, · 14 unmodified lines | |||
| 446 | /* | 447 | /* |
| 447 | * queue_folios_pmd() has three possible return values: | 448 | * queue_folios_pmd() has three possible return values: |
| 448 | * 0 - folios are placed on the right node or queued successfully, or | 449 | * 0 - folios are placed on the right node or queued successfully, or |
| 449 | * special page is met, i.e. huge zero page. | 450 | * special page is met, i.e. zero page, or unmovable page is found |
| 450 | * 1 - there is unmovable folio, and MPOL_MF_MOVE* & MPOL_MF_STRICT were | 451 | * but continue walking (indicated by queue_pages.has_unmovable). |
| 451 | * specified. | ||
| 452 | * -EIO - is migration entry or only MPOL_MF_STRICT was specified and an | 452 | * -EIO - is migration entry or only MPOL_MF_STRICT was specified and an |
| 453 | * existing folio was already on a node that does not follow the | 453 | * existing folio was already on a node that does not follow the |
| 454 | * policy. | 454 | * policy. |
| @@ -479,7 +479,7 @@ static int queue_folios_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, · 24 unmodified lines | |||
| 479 | if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { | 479 | if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { |
| 480 | if (!vma_migratable(walk->vma) || | 480 | if (!vma_migratable(walk->vma) || |
| 481 | migrate_folio_add(folio, qp->pagelist, flags)) { | 481 | migrate_folio_add(folio, qp->pagelist, flags)) { |
| 482 | ret = 1; | 482 | qp->has_unmovable = true; |
| 483 | goto unlock; | 483 | goto unlock; |
| 484 | } | 484 | } |
| 485 | } else | 485 | } else |
| @@ -495,9 +495,8 @@ unlock: · 9 unmodified lines | |||
| 495 | * | 495 | * |
| 496 | * queue_folios_pte_range() has three possible return values: | 496 | * queue_folios_pte_range() has three possible return values: |
| 497 | * 0 - folios are placed on the right node or queued successfully, or | 497 | * 0 - folios are placed on the right node or queued successfully, or |
| 498 | * special page is met, i.e. zero page. | 498 | * special page is met, i.e. zero page, or unmovable page is found |
| 499 | * 1 - there is unmovable folio, and MPOL_MF_MOVE* & MPOL_MF_STRICT were | 499 | * but continue walking (indicated by queue_pages.has_unmovable). |
| 500 | * specified. | ||
| 501 | * -EIO - only MPOL_MF_STRICT was specified and an existing folio was already | 500 | * -EIO - only MPOL_MF_STRICT was specified and an existing folio was already |
| 502 | * on a node that does not follow the policy. | 501 | * on a node that does not follow the policy. |
| 503 | */ | 502 | */ |
| @@ -508,7 +507,6 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr, · 4 unmodified lines | |||
| 508 | struct folio *folio; | 507 | struct folio *folio; |
| 509 | struct queue_pages *qp = walk->private; | 508 | struct queue_pages *qp = walk->private; |
| 510 | unsigned long flags = qp->flags; | 509 | unsigned long flags = qp->flags; |
| 511 | bool has_unmovable = false; | ||
| 512 | pte_t *pte, *mapped_pte; | 510 | pte_t *pte, *mapped_pte; |
| 513 | pte_t ptent; | 511 | pte_t ptent; |
| 514 | spinlock_t *ptl; | 512 | spinlock_t *ptl; |
| @@ -538,11 +536,12 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr, · 23 unmodified lines | |||
| 538 | if (!queue_folio_required(folio, qp)) | 536 | if (!queue_folio_required(folio, qp)) |
| 539 | continue; | 537 | continue; |
| 540 | if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { | 538 | if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { |
| 541 | /* MPOL_MF_STRICT must be specified if we get here */ | 539 | /* |
| 542 | if (!vma_migratable(vma)) { | 540 | * MPOL_MF_STRICT must be specified if we get here. |
| 543 | has_unmovable = true; | 541 | * Continue walking vmas due to MPOL_MF_MOVE* flags. |
| 544 | break; | 542 | */ |
| 545 | } | 543 | if (!vma_migratable(vma)) |
| 544 | qp->has_unmovable = true; | ||
| 546 | 545 | ||
| 547 | /* | 546 | /* |
| 548 | * Do not abort immediately since there may be | 547 | * Do not abort immediately since there may be |
| @@ -550,16 +549,13 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr, · 1 unmodified line | |||
| 550 | * need migrate other LRU pages. | 549 | * need migrate other LRU pages. |
| 551 | */ | 550 | */ |
| 552 | if (migrate_folio_add(folio, qp->pagelist, flags)) | 551 | if (migrate_folio_add(folio, qp->pagelist, flags)) |
| 553 | has_unmovable = true; | 552 | qp->has_unmovable = true; |
| 554 | } else | 553 | } else |
| 555 | break; | 554 | break; |
| 556 | } | 555 | } |
| 557 | pte_unmap_unlock(mapped_pte, ptl); | 556 | pte_unmap_unlock(mapped_pte, ptl); |
| 558 | cond_resched(); | 557 | cond_resched(); |
| 559 | 558 | ||
| 560 | if (has_unmovable) | ||
| 561 | return 1; | ||
| 562 | |||
| 563 | return addr != end ? -EIO : 0; | 559 | return addr != end ? -EIO : 0; |
| 564 | } | 560 | } |
| 565 | 561 | ||
| @@ -599,7 +595,7 @@ static int queue_folios_hugetlb(pte_t *pte, unsigned long hmask, · 33 unmodified lines | |||
| 599 | * Detecting misplaced folio but allow migrating folios which | 595 | * Detecting misplaced folio but allow migrating folios which |
| 600 | * have been queued. | 596 | * have been queued. |
| 601 | */ | 597 | */ |
| 602 | ret = 1; | 598 | qp->has_unmovable = true; |
| 603 | goto unlock; | 599 | goto unlock; |
| 604 | } | 600 | } |
| 605 | 601 | ||
| @@ -620,7 +616,7 @@ static int queue_folios_hugetlb(pte_t *pte, unsigned long hmask, · 14 unmodified lines | |||
| 620 | * Failed to isolate folio but allow migrating pages | 616 | * Failed to isolate folio but allow migrating pages |
| 621 | * which have been queued. | 617 | * which have been queued. |
| 622 | */ | 618 | */ |
| 623 | ret = 1; | 619 | qp->has_unmovable = true; |
| 624 | } | 620 | } |
| 625 | unlock: | 621 | unlock: |
| 626 | spin_unlock(ptl); | 622 | spin_unlock(ptl); |
| @@ -756,12 +752,15 @@ queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end, · 129 unmodified lines | |||
| 756 | .start = start, | 752 | .start = start, |
| 757 | .end = end, | 753 | .end = end, |
| 758 | .first = NULL, | 754 | .first = NULL, |
| 755 | .has_unmovable = false, | ||
| 759 | }; | 756 | }; |
| 760 | const struct mm_walk_ops *ops = lock_vma ? | 757 | const struct mm_walk_ops *ops = lock_vma ? |
| 761 | &queue_pages_lock_vma_walk_ops : &queue_pages_walk_ops; | 758 | &queue_pages_lock_vma_walk_ops : &queue_pages_walk_ops; |
| 762 | 759 | ||
| 763 | err = walk_page_range(mm, start, end, ops, &qp); | 760 | err = walk_page_range(mm, start, end, ops, &qp); |
| 764 | 761 | ||
| 762 | if (qp.has_unmovable) | ||
| 763 | err = 1; | ||
| 765 | if (!qp.first) | 764 | if (!qp.first) |
| 766 | /* whole range in hole */ | 765 | /* whole range in hole */ |
| 767 | err = -EFAULT; | 766 | err = -EFAULT; |
| @@ -1358,7 +1357,7 @@ static long do_mbind(unsigned long start, unsigned long len, · 590 unmodified lines | |||
| 1358 | putback_movable_pages(&pagelist); | 1357 | putback_movable_pages(&pagelist); |
| 1359 | } | 1358 | } |
| 1360 | 1359 | ||
| 1361 | if ((ret > 0) || (nr_failed && (flags & MPOL_MF_STRICT))) | 1360 | if (((ret > 0) || nr_failed) && (flags & MPOL_MF_STRICT)) |
| 1362 | err = -EIO; | 1361 | err = -EIO; |
| 1363 | } else { | 1362 | } else { |
| 1364 | up_out: | 1363 | up_out: |
| @@ -243,7 +243,9 @@ static bool remove_migration_pte(struct folio *folio, · 242 unmodified lines | |||
| 243 | 243 | ||
| 244 | #ifdef CONFIG_HUGETLB_PAGE | 244 | #ifdef CONFIG_HUGETLB_PAGE |
| 245 | if (folio_test_hugetlb(folio)) { | 245 | if (folio_test_hugetlb(folio)) { |
| 246 | unsigned int shift = huge_page_shift(hstate_vma(vma)); | 246 | struct hstate *h = hstate_vma(vma); |
| 247 | unsigned int shift = huge_page_shift(h); | ||
| 248 | unsigned long psize = huge_page_size(h); | ||
| 247 | 249 | ||
| 248 | pte = arch_make_huge_pte(pte, shift, vma->vm_flags); | 250 | pte = arch_make_huge_pte(pte, shift, vma->vm_flags); |
| 249 | if (folio_test_anon(folio)) | 251 | if (folio_test_anon(folio)) |
| @@ -251,7 +253,8 @@ static bool remove_migration_pte(struct folio *folio, · 1 unmodified line | |||
| 251 | rmap_flags); | 253 | rmap_flags); |
| 252 | else | 254 | else |
| 253 | page_dup_file_rmap(new, true); | 255 | page_dup_file_rmap(new, true); |
| 254 | set_huge_pte_at(vma->vm_mm, pvmw.address, pvmw.pte, pte); | 256 | set_huge_pte_at(vma->vm_mm, pvmw.address, pvmw.pte, pte, |
| 257 | psize); | ||
| 255 | } else | 258 | } else |
| 256 | #endif | 259 | #endif |
| 257 | { | 260 | { |
| @@ -2400,7 +2400,7 @@ void free_unref_page(struct page *page, unsigned int order) · 2399 unmodified lines | |||
| 2400 | struct per_cpu_pages *pcp; | 2400 | struct per_cpu_pages *pcp; |
| 2401 | struct zone *zone; | 2401 | struct zone *zone; |
| 2402 | unsigned long pfn = page_to_pfn(page); | 2402 | unsigned long pfn = page_to_pfn(page); |
| 2403 | int migratetype; | 2403 | int migratetype, pcpmigratetype; |
| 2404 | 2404 | ||
| 2405 | if (!free_unref_page_prepare(page, pfn, order)) | 2405 | if (!free_unref_page_prepare(page, pfn, order)) |
| 2406 | return; | 2406 | return; |
| @@ -2408,24 +2408,24 @@ void free_unref_page(struct page *page, unsigned int order) · 1 unmodified line | |||
| 2408 | /* | 2408 | /* |
| 2409 | * We only track unmovable, reclaimable and movable on pcp lists. | 2409 | * We only track unmovable, reclaimable and movable on pcp lists. |
| 2410 | * Place ISOLATE pages on the isolated list because they are being | 2410 | * Place ISOLATE pages on the isolated list because they are being |
| 2411 | * offlined but treat HIGHATOMIC as movable pages so we can get those | 2411 | * offlined but treat HIGHATOMIC and CMA as movable pages so we can |
| 2412 | * areas back if necessary. Otherwise, we may have to free | 2412 | * get those areas back if necessary. Otherwise, we may have to free |
| 2413 | * excessively into the page allocator | 2413 | * excessively into the page allocator |
| 2414 | */ | 2414 | */ |
| 2415 | migratetype = get_pcppage_migratetype(page); | 2415 | migratetype = pcpmigratetype = get_pcppage_migratetype(page); |
| 2416 | if (unlikely(migratetype >= MIGRATE_PCPTYPES)) { | 2416 | if (unlikely(migratetype >= MIGRATE_PCPTYPES)) { |
| 2417 | if (unlikely(is_migrate_isolate(migratetype))) { | 2417 | if (unlikely(is_migrate_isolate(migratetype))) { |
| 2418 | free_one_page(page_zone(page), page, pfn, order, migratetype, FPI_NONE); | 2418 | free_one_page(page_zone(page), page, pfn, order, migratetype, FPI_NONE); |
| 2419 | return; | 2419 | return; |
| 2420 | } | 2420 | } |
| 2421 | migratetype = MIGRATE_MOVABLE; | 2421 | pcpmigratetype = MIGRATE_MOVABLE; |
| 2422 | } | 2422 | } |
| 2423 | 2423 | ||
| 2424 | zone = page_zone(page); | 2424 | zone = page_zone(page); |
| 2425 | pcp_trylock_prepare(UP_flags); | 2425 | pcp_trylock_prepare(UP_flags); |
| 2426 | pcp = pcp_spin_trylock(zone->per_cpu_pageset); | 2426 | pcp = pcp_spin_trylock(zone->per_cpu_pageset); |
| 2427 | if (pcp) { | 2427 | if (pcp) { |
| 2428 | free_unref_page_commit(zone, pcp, page, migratetype, order); | 2428 | free_unref_page_commit(zone, pcp, page, pcpmigratetype, order); |
| 2429 | pcp_spin_unlock(pcp); | 2429 | pcp_spin_unlock(pcp); |
| 2430 | } else { | 2430 | } else { |
| 2431 | free_one_page(zone, page, pfn, order, migratetype, FPI_NONE); | 2431 | free_one_page(zone, page, pfn, order, migratetype, FPI_NONE); |
| @@ -1480,6 +1480,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, · 1479 unmodified lines | |||
| 1480 | struct mmu_notifier_range range; | 1480 | struct mmu_notifier_range range; |
| 1481 | enum ttu_flags flags = (enum ttu_flags)(long)arg; | 1481 | enum ttu_flags flags = (enum ttu_flags)(long)arg; |
| 1482 | unsigned long pfn; | 1482 | unsigned long pfn; |
| 1483 | unsigned long hsz = 0; | ||
| 1483 | 1484 | ||
| 1484 | /* | 1485 | /* |
| 1485 | * When racing against e.g. zap_pte_range() on another cpu, | 1486 | * When racing against e.g. zap_pte_range() on another cpu, |
| @@ -1511,6 +1512,9 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, · 25 unmodified lines | |||
| 1511 | */ | 1512 | */ |
| 1512 | adjust_range_if_pmd_sharing_possible(vma, &range.start, | 1513 | adjust_range_if_pmd_sharing_possible(vma, &range.start, |
| 1513 | &range.end); | 1514 | &range.end); |
| 1515 | |||
| 1516 | /* We need the huge page size for set_huge_pte_at() */ | ||
| 1517 | hsz = huge_page_size(hstate_vma(vma)); | ||
| 1514 | } | 1518 | } |
| 1515 | mmu_notifier_invalidate_range_start(&range); | 1519 | mmu_notifier_invalidate_range_start(&range); |
| 1516 | 1520 | ||
| @@ -1628,7 +1632,8 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, · 111 unmodified lines | |||
| 1628 | pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); | 1632 | pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); |
| 1629 | if (folio_test_hugetlb(folio)) { | 1633 | if (folio_test_hugetlb(folio)) { |
| 1630 | hugetlb_count_sub(folio_nr_pages(folio), mm); | 1634 | hugetlb_count_sub(folio_nr_pages(folio), mm); |
| 1631 | set_huge_pte_at(mm, address, pvmw.pte, pteval); | 1635 | set_huge_pte_at(mm, address, pvmw.pte, pteval, |
| 1636 | hsz); | ||
| 1632 | } else { | 1637 | } else { |
| 1633 | dec_mm_counter(mm, mm_counter(&folio->page)); | 1638 | dec_mm_counter(mm, mm_counter(&folio->page)); |
| 1634 | set_pte_at(mm, address, pvmw.pte, pteval); | 1639 | set_pte_at(mm, address, pvmw.pte, pteval); |
| @@ -1820,6 +1825,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, · 185 unmodified lines | |||
| 1820 | struct mmu_notifier_range range; | 1825 | struct mmu_notifier_range range; |
| 1821 | enum ttu_flags flags = (enum ttu_flags)(long)arg; | 1826 | enum ttu_flags flags = (enum ttu_flags)(long)arg; |
| 1822 | unsigned long pfn; | 1827 | unsigned long pfn; |
| 1828 | unsigned long hsz = 0; | ||
| 1823 | 1829 | ||
| 1824 | /* | 1830 | /* |
| 1825 | * When racing against e.g. zap_pte_range() on another cpu, | 1831 | * When racing against e.g. zap_pte_range() on another cpu, |
| @@ -1855,6 +1861,9 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, · 29 unmodified lines | |||
| 1855 | */ | 1861 | */ |
| 1856 | adjust_range_if_pmd_sharing_possible(vma, &range.start, | 1862 | adjust_range_if_pmd_sharing_possible(vma, &range.start, |
| 1857 | &range.end); | 1863 | &range.end); |
| 1864 | |||
| 1865 | /* We need the huge page size for set_huge_pte_at() */ | ||
| 1866 | hsz = huge_page_size(hstate_vma(vma)); | ||
| 1858 | } | 1867 | } |
| 1859 | mmu_notifier_invalidate_range_start(&range); | 1868 | mmu_notifier_invalidate_range_start(&range); |
| 1860 | 1869 | ||
| @@ -2020,7 +2029,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, · 159 unmodified lines | |||
| 2020 | pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); | 2029 | pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); |
| 2021 | if (folio_test_hugetlb(folio)) { | 2030 | if (folio_test_hugetlb(folio)) { |
| 2022 | hugetlb_count_sub(folio_nr_pages(folio), mm); | 2031 | hugetlb_count_sub(folio_nr_pages(folio), mm); |
| 2023 | set_huge_pte_at(mm, address, pvmw.pte, pteval); | 2032 | set_huge_pte_at(mm, address, pvmw.pte, pteval, |
| 2033 | hsz); | ||
| 2024 | } else { | 2034 | } else { |
| 2025 | dec_mm_counter(mm, mm_counter(&folio->page)); | 2035 | dec_mm_counter(mm, mm_counter(&folio->page)); |
| 2026 | set_pte_at(mm, address, pvmw.pte, pteval); | 2036 | set_pte_at(mm, address, pvmw.pte, pteval); |
| @@ -2044,7 +2054,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, · 17 unmodified lines | |||
| 2044 | 2054 | ||
| 2045 | if (arch_unmap_one(mm, vma, address, pteval) < 0) { | 2055 | if (arch_unmap_one(mm, vma, address, pteval) < 0) { |
| 2046 | if (folio_test_hugetlb(folio)) | 2056 | if (folio_test_hugetlb(folio)) |
| 2047 | set_huge_pte_at(mm, address, pvmw.pte, pteval); | 2057 | set_huge_pte_at(mm, address, pvmw.pte, |
| 2058 | pteval, hsz); | ||
| 2048 | else | 2059 | else |
| 2049 | set_pte_at(mm, address, pvmw.pte, pteval); | 2060 | set_pte_at(mm, address, pvmw.pte, pteval); |
| 2050 | ret = false; | 2061 | ret = false; |
| @@ -2058,7 +2069,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, · 7 unmodified lines | |||
| 2058 | if (anon_exclusive && | 2069 | if (anon_exclusive && |
| 2059 | page_try_share_anon_rmap(subpage)) { | 2070 | page_try_share_anon_rmap(subpage)) { |
| 2060 | if (folio_test_hugetlb(folio)) | 2071 | if (folio_test_hugetlb(folio)) |
| 2061 | set_huge_pte_at(mm, address, pvmw.pte, pteval); | 2072 | set_huge_pte_at(mm, address, pvmw.pte, |
| 2073 | pteval, hsz); | ||
| 2062 | else | 2074 | else |
| 2063 | set_pte_at(mm, address, pvmw.pte, pteval); | 2075 | set_pte_at(mm, address, pvmw.pte, pteval); |
| 2064 | ret = false; | 2076 | ret = false; |
| @@ -2090,7 +2102,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, · 25 unmodified lines | |||
| 2090 | if (pte_uffd_wp(pteval)) | 2102 | if (pte_uffd_wp(pteval)) |
| 2091 | swp_pte = pte_swp_mkuffd_wp(swp_pte); | 2103 | swp_pte = pte_swp_mkuffd_wp(swp_pte); |
| 2092 | if (folio_test_hugetlb(folio)) | 2104 | if (folio_test_hugetlb(folio)) |
| 2093 | set_huge_pte_at(mm, address, pvmw.pte, swp_pte); | 2105 | set_huge_pte_at(mm, address, pvmw.pte, swp_pte, |
| 2106 | hsz); | ||
| 2094 | else | 2107 | else |
| 2095 | set_pte_at(mm, address, pvmw.pte, swp_pte); | 2108 | set_pte_at(mm, address, pvmw.pte, swp_pte); |
| 2096 | trace_set_migration_pte(address, pte_val(swp_pte), | 2109 | trace_set_migration_pte(address, pte_val(swp_pte), |
| @@ -479,7 +479,7 @@ void slab_kmem_cache_release(struct kmem_cache *s) · 478 unmodified lines | |||
| 479 | 479 | ||
| 480 | void kmem_cache_destroy(struct kmem_cache *s) | 480 | void kmem_cache_destroy(struct kmem_cache *s) |
| 481 | { | 481 | { |
| 482 | int refcnt; | 482 | int err = -EBUSY; |
| 483 | bool rcu_set; | 483 | bool rcu_set; |
| 484 | 484 | ||
| 485 | if (unlikely(!s) || !kasan_check_byte(s)) | 485 | if (unlikely(!s) || !kasan_check_byte(s)) |
| @@ -490,17 +490,17 @@ void kmem_cache_destroy(struct kmem_cache *s) · 4 unmodified lines | |||
| 490 | 490 | ||
| 491 | rcu_set = s->flags & SLAB_TYPESAFE_BY_RCU; | 491 | rcu_set = s->flags & SLAB_TYPESAFE_BY_RCU; |
| 492 | 492 | ||
| 493 | refcnt = --s->refcount; | 493 | s->refcount--; |
| 494 | if (refcnt) | 494 | if (s->refcount) |
| 495 | goto out_unlock; | 495 | goto out_unlock; |
| 496 | 496 | ||
| 497 | WARN(shutdown_cache(s), | 497 | err = shutdown_cache(s); |
| 498 | "%s %s: Slab cache still has objects when called from %pS", | 498 | WARN(err, "%s %s: Slab cache still has objects when called from %pS", |
| 499 | __func__, s->name, (void *)_RET_IP_); | 499 | __func__, s->name, (void *)_RET_IP_); |
| 500 | out_unlock: | 500 | out_unlock: |
| 501 | mutex_unlock(&slab_mutex); | 501 | mutex_unlock(&slab_mutex); |
| 502 | cpus_read_unlock(); | 502 | cpus_read_unlock(); |
| 503 | if (!refcnt && !rcu_set) | 503 | if (!err && !rcu_set) |
| 504 | kmem_cache_release(s); | 504 | kmem_cache_release(s); |
| 505 | } | 505 | } |
| 506 | EXPORT_SYMBOL(kmem_cache_destroy); | 506 | EXPORT_SYMBOL(kmem_cache_destroy); |
| @@ -745,24 +745,24 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags, unsigned long caller) · 238 unmodified lines | |||
| 745 | 745 | ||
| 746 | size_t kmalloc_size_roundup(size_t size) | 746 | size_t kmalloc_size_roundup(size_t size) |
| 747 | { | 747 | { |
| 748 | struct kmem_cache *c; | 748 | if (size && size <= KMALLOC_MAX_CACHE_SIZE) { |
| 749 | /* | ||
| 750 | * The flags don't matter since size_index is common to all. | ||
| 751 | * Neither does the caller for just getting ->object_size. | ||
| 752 | */ | ||
| 753 | return kmalloc_slab(size, GFP_KERNEL, 0)->object_size; | ||
| 754 | } | ||
| 749 | 755 | ||
| 750 | /* Short-circuit the 0 size case. */ | ||
| 751 | if (unlikely(size == 0)) | ||
| 752 | return 0; | ||
| 753 | /* Short-circuit saturated "too-large" case. */ | ||
| 754 | if (unlikely(size == SIZE_MAX)) | ||
| 755 | return SIZE_MAX; | ||
| 756 | /* Above the smaller buckets, size is a multiple of page size. */ | 756 | /* Above the smaller buckets, size is a multiple of page size. */ |
| 757 | if (size > KMALLOC_MAX_CACHE_SIZE) | 757 | if (size && size <= KMALLOC_MAX_SIZE) |
| 758 | return PAGE_SIZE << get_order(size); | 758 | return PAGE_SIZE << get_order(size); |
| 759 | 759 | ||
| 760 | /* | 760 | /* |
| 761 | * The flags don't matter since size_index is common to all. | 761 | * Return 'size' for 0 - kmalloc() returns ZERO_SIZE_PTR |
| 762 | * Neither does the caller for just getting ->object_size. | 762 | * and very large size - kmalloc() may fail. |
| 763 | */ | 763 | */ |
| 764 | c = kmalloc_slab(size, GFP_KERNEL, 0); | 764 | return size; |
| 765 | return c ? c->object_size : 0; | 765 | |
| 766 | } | 766 | } |
| 767 | EXPORT_SYMBOL(kmalloc_size_roundup); | 767 | EXPORT_SYMBOL(kmalloc_size_roundup); |
| 768 | 768 | ||
| @@ -111,7 +111,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, · 110 unmodified lines | |||
| 111 | pte_t entry = pfn_pte(pfn, prot); | 111 | pte_t entry = pfn_pte(pfn, prot); |
| 112 | 112 | ||
| 113 | entry = arch_make_huge_pte(entry, ilog2(size), 0); | 113 | entry = arch_make_huge_pte(entry, ilog2(size), 0); |
| 114 | set_huge_pte_at(&init_mm, addr, pte, entry); | 114 | set_huge_pte_at(&init_mm, addr, pte, entry, size); |
| 115 | pfn += PFN_DOWN(size); | 115 | pfn += PFN_DOWN(size); |
| 116 | continue; | 116 | continue; |
| 117 | } | 117 | } |
| @@ -1218,6 +1218,19 @@ bool zswap_store(struct folio *folio) · 1217 unmodified lines | |||
| 1218 | if (!zswap_enabled || !tree) | 1218 | if (!zswap_enabled || !tree) |
| 1219 | return false; | 1219 | return false; |
| 1220 | 1220 | ||
| 1221 | /* | ||
| 1222 | * If this is a duplicate, it must be removed before attempting to store | ||
| 1223 | * it, otherwise, if the store fails the old page won't be removed from | ||
| 1224 | * the tree, and it might be written back overriding the new data. | ||
| 1225 | */ | ||
| 1226 | spin_lock(&tree->lock); | ||
| 1227 | dupentry = zswap_rb_search(&tree->rbroot, offset); | ||
| 1228 | if (dupentry) { | ||
| 1229 | zswap_duplicate_entry++; | ||
| 1230 | zswap_invalidate_entry(tree, dupentry); | ||
| 1231 | } | ||
| 1232 | spin_unlock(&tree->lock); | ||
| 1233 | |||
| 1221 | /* | 1234 | /* |
| 1222 | * XXX: zswap reclaim does not work with cgroups yet. Without a | 1235 | * XXX: zswap reclaim does not work with cgroups yet. Without a |
| 1223 | * cgroup-aware entry LRU, we will push out entries system-wide based on | 1236 | * cgroup-aware entry LRU, we will push out entries system-wide based on |
| @@ -1333,7 +1346,14 @@ insert_entry: · 109 unmodified lines | |||
| 1333 | 1346 | ||
| 1334 | /* map */ | 1347 | /* map */ |
| 1335 | spin_lock(&tree->lock); | 1348 | spin_lock(&tree->lock); |
| 1349 | /* | ||
| 1350 | * A duplicate entry should have been removed at the beginning of this | ||
| 1351 | * function. Since the swap entry should be pinned, if a duplicate is | ||
| 1352 | * found again here it means that something went wrong in the swap | ||
| 1353 | * cache. | ||
| 1354 | */ | ||
| 1336 | while (zswap_rb_insert(&tree->rbroot, entry, &dupentry) == -EEXIST) { | 1355 | while (zswap_rb_insert(&tree->rbroot, entry, &dupentry) == -EEXIST) { |
| 1356 | WARN_ON(1); | ||
| 1337 | zswap_duplicate_entry++; | 1357 | zswap_duplicate_entry++; |
| 1338 | zswap_invalidate_entry(tree, dupentry); | 1358 | zswap_invalidate_entry(tree, dupentry); |
| 1339 | } | 1359 | } |
| @@ -2413,34 +2413,41 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, · 2412 unmodified lines | |||
| 2413 | if (!test_bit(HCI_CONN_AUTH, &conn->flags)) | 2413 | if (!test_bit(HCI_CONN_AUTH, &conn->flags)) |
| 2414 | goto auth; | 2414 | goto auth; |
| 2415 | 2415 | ||
| 2416 | /* An authenticated FIPS approved combination key has sufficient | 2416 | switch (conn->key_type) { |
| 2417 | * security for security level 4. */ | 2417 | case HCI_LK_AUTH_COMBINATION_P256: |
| 2418 | if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 && | 2418 | /* An authenticated FIPS approved combination key has |
| 2419 | sec_level == BT_SECURITY_FIPS) | 2419 | * sufficient security for security level 4 or lower. |
| 2420 | goto encrypt; | 2420 | */ |
| 2421 | 2421 | if (sec_level <= BT_SECURITY_FIPS) | |
| 2422 | /* An authenticated combination key has sufficient security for | 2422 | goto encrypt; |
| 2423 | security level 3. */ | 2423 | break; |
| 2424 | if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 || | 2424 | case HCI_LK_AUTH_COMBINATION_P192: |
| 2425 | conn->key_type == HCI_LK_AUTH_COMBINATION_P256) && | 2425 | /* An authenticated combination key has sufficient security for |
| 2426 | sec_level == BT_SECURITY_HIGH) | 2426 | * security level 3 or lower. |
| 2427 | goto encrypt; | 2427 | */ |
| 2428 | 2428 | if (sec_level <= BT_SECURITY_HIGH) | |
| 2429 | /* An unauthenticated combination key has sufficient security for | 2429 | goto encrypt; |
| 2430 | security level 1 and 2. */ | 2430 | break; |
| 2431 | if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 || | 2431 | case HCI_LK_UNAUTH_COMBINATION_P192: |
| 2432 | conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) && | 2432 | case HCI_LK_UNAUTH_COMBINATION_P256: |
| 2433 | (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) | 2433 | /* An unauthenticated combination key has sufficient security |
| 2434 | goto encrypt; | 2434 | * for security level 2 or lower. |
| 2435 | 2435 | */ | |
| 2436 | /* A combination key has always sufficient security for the security | 2436 | if (sec_level <= BT_SECURITY_MEDIUM) |
| 2437 | levels 1 or 2. High security level requires the combination key | 2437 | goto encrypt; |
| 2438 | is generated using maximum PIN code length (16). | 2438 | break; |
| 2439 | For pre 2.1 units. */ | 2439 | case HCI_LK_COMBINATION: |
| 2440 | if (conn->key_type == HCI_LK_COMBINATION && | 2440 | /* A combination key has always sufficient security for the |
| 2441 | (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW || | 2441 | * security levels 2 or lower. High security level requires the |
| 2442 | conn->pin_length == 16)) | 2442 | * combination key is generated using maximum PIN code length |
| 2443 | goto encrypt; | 2443 | * (16). For pre 2.1 units. |
| 2444 | */ | ||
| 2445 | if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16) | ||
| 2446 | goto encrypt; | ||
| 2447 | break; | ||
| 2448 | default: | ||
| 2449 | break; | ||
| 2450 | } | ||
| 2444 | 2451 | ||
| 2445 | auth: | 2452 | auth: |
| 2446 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) | 2453 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) |
| @@ -2617,7 +2617,11 @@ int hci_register_dev(struct hci_dev *hdev) · 2616 unmodified lines | |||
| 2617 | if (id < 0) | 2617 | if (id < 0) |
| 2618 | return id; | 2618 | return id; |
| 2619 | 2619 | ||
| 2620 | snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); | 2620 | error = dev_set_name(&hdev->dev, "hci%u", id); |
| 2621 | if (error) | ||
| 2622 | return error; | ||
| 2623 | |||
| 2624 | hdev->name = dev_name(&hdev->dev); | ||
| 2621 | hdev->id = id; | 2625 | hdev->id = id; |
| 2622 | 2626 | ||
| 2623 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 2627 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
| @@ -2639,8 +2643,6 @@ int hci_register_dev(struct hci_dev *hdev) · 15 unmodified lines | |||
| 2639 | if (!IS_ERR_OR_NULL(bt_debugfs)) | 2643 | if (!IS_ERR_OR_NULL(bt_debugfs)) |
| 2640 | hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); | 2644 | hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); |
| 2641 | 2645 | ||
| 2642 | dev_set_name(&hdev->dev, "%s", hdev->name); | ||
| 2643 | |||
| 2644 | error = device_add(&hdev->dev); | 2646 | error = device_add(&hdev->dev); |
| 2645 | if (error < 0) | 2647 | if (error < 0) |
| 2646 | goto err_wqueue; | 2648 | goto err_wqueue; |
| @@ -2784,6 +2786,7 @@ void hci_release_dev(struct hci_dev *hdev) · 137 unmodified lines | |||
| 2784 | hci_conn_params_clear_all(hdev); | 2786 | hci_conn_params_clear_all(hdev); |
| 2785 | hci_discovery_filter_clear(hdev); | 2787 | hci_discovery_filter_clear(hdev); |
| 2786 | hci_blocked_keys_clear(hdev); | 2788 | hci_blocked_keys_clear(hdev); |
| 2789 | hci_codec_list_clear(&hdev->local_codecs); | ||
| 2787 | hci_dev_unlock(hdev); | 2790 | hci_dev_unlock(hdev); |
| 2788 | 2791 | ||
| 2789 | ida_simple_remove(&hci_index_ida, hdev->id); | 2792 | ida_simple_remove(&hci_index_ida, hdev->id); |
| @@ -3418,7 +3421,12 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) · 628 unmodified lines | |||
| 3418 | if (c->type == type && c->sent) { | 3421 | if (c->type == type && c->sent) { |
| 3419 | bt_dev_err(hdev, "killing stalled connection %pMR", | 3422 | bt_dev_err(hdev, "killing stalled connection %pMR", |
| 3420 | &c->dst); | 3423 | &c->dst); |
| 3424 | /* hci_disconnect might sleep, so, we have to release | ||
| 3425 | * the RCU read lock before calling it. | ||
| 3426 | */ | ||
| 3427 | rcu_read_unlock(); | ||
| 3421 | hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); | 3428 | hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM); |
| 3429 | rcu_read_lock(); | ||
| 3422 | } | 3430 | } |
| 3423 | } | 3431 | } |
| 3424 | 3432 | ||
| @@ -33,6 +33,7 @@ · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | #include "hci_request.h" | 34 | #include "hci_request.h" |
| 35 | #include "hci_debugfs.h" | 35 | #include "hci_debugfs.h" |
| 36 | #include "hci_codec.h" | ||
| 36 | #include "a2mp.h" | 37 | #include "a2mp.h" |
| 37 | #include "amp.h" | 38 | #include "amp.h" |
| 38 | #include "smp.h" | 39 | #include "smp.h" |
| @@ -71,7 +71,5 @@ struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, · 70 unmodified lines | |||
| 71 | void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn); | 71 | void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn); |
| 72 | void hci_req_add_le_passive_scan(struct hci_request *req); | 72 | void hci_req_add_le_passive_scan(struct hci_request *req); |
| 73 | 73 | ||
| 74 | void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next); | ||
| 75 | |||
| 76 | void hci_request_setup(struct hci_dev *hdev); | 74 | void hci_request_setup(struct hci_dev *hdev); |
| 77 | void hci_request_cancel_all(struct hci_dev *hdev); | 75 | void hci_request_cancel_all(struct hci_dev *hdev); |
| @@ -413,11 +413,6 @@ static int hci_le_scan_restart_sync(struct hci_dev *hdev) · 412 unmodified lines | |||
| 413 | LE_SCAN_FILTER_DUP_ENABLE); | 413 | LE_SCAN_FILTER_DUP_ENABLE); |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | static int le_scan_restart_sync(struct hci_dev *hdev, void *data) | ||
| 417 | { | ||
| 418 | return hci_le_scan_restart_sync(hdev); | ||
| 419 | } | ||
| 420 | |||
| 421 | static void le_scan_restart(struct work_struct *work) | 416 | static void le_scan_restart(struct work_struct *work) |
| 422 | { | 417 | { |
| 423 | struct hci_dev *hdev = container_of(work, struct hci_dev, | 418 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
| @@ -427,15 +422,15 @@ static void le_scan_restart(struct work_struct *work) · 3 unmodified lines | |||
| 427 | 422 | ||
| 428 | bt_dev_dbg(hdev, ""); | 423 | bt_dev_dbg(hdev, ""); |
| 429 | 424 | ||
| 430 | hci_dev_lock(hdev); | 425 | status = hci_le_scan_restart_sync(hdev); |
| 431 | |||
| 432 | status = hci_cmd_sync_queue(hdev, le_scan_restart_sync, NULL, NULL); | ||
| 433 | if (status) { | 426 | if (status) { |
| 434 | bt_dev_err(hdev, "failed to restart LE scan: status %d", | 427 | bt_dev_err(hdev, "failed to restart LE scan: status %d", |
| 435 | status); | 428 | status); |
| 436 | goto unlock; | 429 | return; |
| 437 | } | 430 | } |
| 438 | 431 | ||
| 432 | hci_dev_lock(hdev); | ||
| 433 | |||
| 439 | if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) || | 434 | if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) || |
| 440 | !hdev->discovery.scan_start) | 435 | !hdev->discovery.scan_start) |
| 441 | goto unlock; | 436 | goto unlock; |
| @@ -5079,6 +5074,7 @@ int hci_dev_close_sync(struct hci_dev *hdev) · 4637 unmodified lines | |||
| 5079 | memset(hdev->eir, 0, sizeof(hdev->eir)); | 5074 | memset(hdev->eir, 0, sizeof(hdev->eir)); |
| 5080 | memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); | 5075 | memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); |
| 5081 | bacpy(&hdev->random_addr, BDADDR_ANY); | 5076 | bacpy(&hdev->random_addr, BDADDR_ANY); |
| 5077 | hci_codec_list_clear(&hdev->local_codecs); | ||
| 5082 | 5078 | ||
| 5083 | hci_dev_put(hdev); | 5079 | hci_dev_put(hdev); |
| 5084 | return err; | 5080 | return err; |
| @@ -502,7 +502,7 @@ drop: · 501 unmodified lines | |||
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | /* -------- Socket interface ---------- */ | 504 | /* -------- Socket interface ---------- */ |
| 505 | static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *ba) | 505 | static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst) |
| 506 | { | 506 | { |
| 507 | struct sock *sk; | 507 | struct sock *sk; |
| 508 | 508 | ||
| @@ -510,7 +510,10 @@ static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *ba) · 1 unmodified line | |||
| 510 | if (sk->sk_state != BT_LISTEN) | 510 | if (sk->sk_state != BT_LISTEN) |
| 511 | continue; | 511 | continue; |
| 512 | 512 | ||
| 513 | if (!bacmp(&iso_pi(sk)->src, ba)) | 513 | if (bacmp(&iso_pi(sk)->dst, dst)) |
| 514 | continue; | ||
| 515 | |||
| 516 | if (!bacmp(&iso_pi(sk)->src, src)) | ||
| 514 | return sk; | 517 | return sk; |
| 515 | } | 518 | } |
| 516 | 519 | ||
| @@ -952,7 +955,7 @@ static int iso_listen_cis(struct sock *sk) · 435 unmodified lines | |||
| 952 | 955 | ||
| 953 | write_lock(&iso_sk_list.lock); | 956 | write_lock(&iso_sk_list.lock); |
| 954 | 957 | ||
| 955 | if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src)) | 958 | if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst)) |
| 956 | err = -EADDRINUSE; | 959 | err = -EADDRINUSE; |
| 957 | 960 | ||
| 958 | write_unlock(&iso_sk_list.lock); | 961 | write_unlock(&iso_sk_list.lock); |
| @@ -294,7 +294,7 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_ · 293 unmodified lines | |||
| 294 | /* tell br_dev_xmit to continue with forwarding */ | 294 | /* tell br_dev_xmit to continue with forwarding */ |
| 295 | nf_bridge->bridged_dnat = 1; | 295 | nf_bridge->bridged_dnat = 1; |
| 296 | /* FIXME Need to refragment */ | 296 | /* FIXME Need to refragment */ |
| 297 | ret = neigh->output(neigh, skb); | 297 | ret = READ_ONCE(neigh->output)(neigh, skb); |
| 298 | } | 298 | } |
| 299 | neigh_release(neigh); | 299 | neigh_release(neigh); |
| 300 | return ret; | 300 | return ret; |
| @@ -410,7 +410,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev, · 409 unmodified lines | |||
| 410 | */ | 410 | */ |
| 411 | __skb_queue_purge(&n->arp_queue); | 411 | __skb_queue_purge(&n->arp_queue); |
| 412 | n->arp_queue_len_bytes = 0; | 412 | n->arp_queue_len_bytes = 0; |
| 413 | n->output = neigh_blackhole; | 413 | WRITE_ONCE(n->output, neigh_blackhole); |
| 414 | if (n->nud_state & NUD_VALID) | 414 | if (n->nud_state & NUD_VALID) |
| 415 | n->nud_state = NUD_NOARP; | 415 | n->nud_state = NUD_NOARP; |
| 416 | else | 416 | else |
| @@ -920,7 +920,7 @@ static void neigh_suspect(struct neighbour *neigh) · 503 unmodified lines | |||
| 920 | { | 920 | { |
| 921 | neigh_dbg(2, "neigh %p is suspected\n", neigh); | 921 | neigh_dbg(2, "neigh %p is suspected\n", neigh); |
| 922 | 922 | ||
| 923 | neigh->output = neigh->ops->output; | 923 | WRITE_ONCE(neigh->output, neigh->ops->output); |
| 924 | } | 924 | } |
| 925 | 925 | ||
| 926 | /* Neighbour state is OK; | 926 | /* Neighbour state is OK; |
| @@ -932,7 +932,7 @@ static void neigh_connect(struct neighbour *neigh) · 5 unmodified lines | |||
| 932 | { | 932 | { |
| 933 | neigh_dbg(2, "neigh %p is connected\n", neigh); | 933 | neigh_dbg(2, "neigh %p is connected\n", neigh); |
| 934 | 934 | ||
| 935 | neigh->output = neigh->ops->connected_output; | 935 | WRITE_ONCE(neigh->output, neigh->ops->connected_output); |
| 936 | } | 936 | } |
| 937 | 937 | ||
| 938 | static void neigh_periodic_work(struct work_struct *work) | 938 | static void neigh_periodic_work(struct work_struct *work) |
| @@ -988,7 +988,9 @@ static void neigh_periodic_work(struct work_struct *work) · 49 unmodified lines | |||
| 988 | (state == NUD_FAILED || | 988 | (state == NUD_FAILED || |
| 989 | !time_in_range_open(jiffies, n->used, | 989 | !time_in_range_open(jiffies, n->used, |
| 990 | n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { | 990 | n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { |
| 991 | *np = n->next; | 991 | rcu_assign_pointer(*np, |
| 992 | rcu_dereference_protected(n->next, | ||
| 993 | lockdep_is_held(&tbl->lock))); | ||
| 992 | neigh_mark_dead(n); | 994 | neigh_mark_dead(n); |
| 993 | write_unlock(&n->lock); | 995 | write_unlock(&n->lock); |
| 994 | neigh_cleanup_and_release(n); | 996 | neigh_cleanup_and_release(n); |
| @@ -1447,7 +1449,7 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, · 452 unmodified lines | |||
| 1447 | if (n2) | 1449 | if (n2) |
| 1448 | n1 = n2; | 1450 | n1 = n2; |
| 1449 | } | 1451 | } |
| 1450 | n1->output(n1, skb); | 1452 | READ_ONCE(n1->output)(n1, skb); |
| 1451 | if (n2) | 1453 | if (n2) |
| 1452 | neigh_release(n2); | 1454 | neigh_release(n2); |
| 1453 | rcu_read_unlock(); | 1455 | rcu_read_unlock(); |
| @@ -3153,7 +3155,7 @@ int neigh_xmit(int index, struct net_device *dev, · 1699 unmodified lines | |||
| 3153 | rcu_read_unlock(); | 3155 | rcu_read_unlock(); |
| 3154 | goto out_kfree_skb; | 3156 | goto out_kfree_skb; |
| 3155 | } | 3157 | } |
| 3156 | err = neigh->output(neigh, skb); | 3158 | err = READ_ONCE(neigh->output)(neigh, skb); |
| 3157 | rcu_read_unlock(); | 3159 | rcu_read_unlock(); |
| 3158 | } | 3160 | } |
| 3159 | else if (index == NEIGH_LINK_TABLE) { | 3161 | else if (index == NEIGH_LINK_TABLE) { |
| @@ -668,6 +668,8 @@ BPF_CALL_4(bpf_msg_redirect_map, struct sk_msg *, msg, · 667 unmodified lines | |||
| 668 | sk = __sock_map_lookup_elem(map, key); | 668 | sk = __sock_map_lookup_elem(map, key); |
| 669 | if (unlikely(!sk || !sock_map_redirect_allowed(sk))) | 669 | if (unlikely(!sk || !sock_map_redirect_allowed(sk))) |
| 670 | return SK_DROP; | 670 | return SK_DROP; |
| 671 | if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk)) | ||
| 672 | return SK_DROP; | ||
| 671 | 673 | ||
| 672 | msg->flags = flags; | 674 | msg->flags = flags; |
| 673 | msg->sk_redir = sk; | 675 | msg->sk_redir = sk; |
| @@ -1267,6 +1269,8 @@ BPF_CALL_4(bpf_msg_redirect_hash, struct sk_msg *, msg, · 593 unmodified lines | |||
| 1267 | sk = __sock_hash_lookup_elem(map, key); | 1269 | sk = __sock_hash_lookup_elem(map, key); |
| 1268 | if (unlikely(!sk || !sock_map_redirect_allowed(sk))) | 1270 | if (unlikely(!sk || !sock_map_redirect_allowed(sk))) |
| 1269 | return SK_DROP; | 1271 | return SK_DROP; |
| 1272 | if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk)) | ||
| 1273 | return SK_DROP; | ||
| 1270 | 1274 | ||
| 1271 | msg->flags = flags; | 1275 | msg->flags = flags; |
| 1272 | msg->sk_redir = sk; | 1276 | msg->sk_redir = sk; |
| @@ -21,16 +21,6 @@ struct plca_reply_data { · 20 unmodified lines | |||
| 21 | #define PLCA_REPDATA(__reply_base) \ | 21 | #define PLCA_REPDATA(__reply_base) \ |
| 22 | container_of(__reply_base, struct plca_reply_data, base) | 22 | container_of(__reply_base, struct plca_reply_data, base) |
| 23 | 23 | ||
| 24 | static void plca_update_sint(int *dst, const struct nlattr *attr, | ||
| 25 | bool *mod) | ||
| 26 | { | ||
| 27 | if (!attr) | ||
| 28 | return; | ||
| 29 | |||
| 30 | *dst = nla_get_u32(attr); | ||
| 31 | *mod = true; | ||
| 32 | } | ||
| 33 | |||
| 34 | // PLCA get configuration message ------------------------------------------- // | 24 | // PLCA get configuration message ------------------------------------------- // |
| 35 | 25 | ||
| 36 | const struct nla_policy ethnl_plca_get_cfg_policy[] = { | 26 | const struct nla_policy ethnl_plca_get_cfg_policy[] = { |
| @@ -38,6 +28,29 @@ const struct nla_policy ethnl_plca_get_cfg_policy[] = { · 1 unmodified line | |||
| 38 | NLA_POLICY_NESTED(ethnl_header_policy), | 28 | NLA_POLICY_NESTED(ethnl_header_policy), |
| 39 | }; | 29 | }; |
| 40 | 30 | ||
| 31 | static void plca_update_sint(int *dst, struct nlattr **tb, u32 attrid, | ||
| 32 | bool *mod) | ||
| 33 | { | ||
| 34 | const struct nlattr *attr = tb[attrid]; | ||
| 35 | |||
| 36 | if (!attr || | ||
| 37 | WARN_ON_ONCE(attrid >= ARRAY_SIZE(ethnl_plca_set_cfg_policy))) | ||
| 38 | return; | ||
| 39 | |||
| 40 | switch (ethnl_plca_set_cfg_policy[attrid].type) { | ||
| 41 | case NLA_U8: | ||
| 42 | *dst = nla_get_u8(attr); | ||
| 43 | break; | ||
| 44 | case NLA_U32: | ||
| 45 | *dst = nla_get_u32(attr); | ||
| 46 | break; | ||
| 47 | default: | ||
| 48 | WARN_ON_ONCE(1); | ||
| 49 | } | ||
| 50 | |||
| 51 | *mod = true; | ||
| 52 | } | ||
| 53 | |||
| 41 | static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base, | 54 | static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base, |
| 42 | struct ethnl_reply_data *reply_base, | 55 | struct ethnl_reply_data *reply_base, |
| 43 | const struct genl_info *info) | 56 | const struct genl_info *info) |
| @@ -144,13 +157,13 @@ ethnl_set_plca(struct ethnl_req_info *req_info, struct genl_info *info) · 100 unmodified lines | |||
| 144 | return -EOPNOTSUPP; | 157 | return -EOPNOTSUPP; |
| 145 | 158 | ||
| 146 | memset(&plca_cfg, 0xff, sizeof(plca_cfg)); | 159 | memset(&plca_cfg, 0xff, sizeof(plca_cfg)); |
| 147 | plca_update_sint(&plca_cfg.enabled, tb[ETHTOOL_A_PLCA_ENABLED], &mod); | 160 | plca_update_sint(&plca_cfg.enabled, tb, ETHTOOL_A_PLCA_ENABLED, &mod); |
| 148 | plca_update_sint(&plca_cfg.node_id, tb[ETHTOOL_A_PLCA_NODE_ID], &mod); | 161 | plca_update_sint(&plca_cfg.node_id, tb, ETHTOOL_A_PLCA_NODE_ID, &mod); |
| 149 | plca_update_sint(&plca_cfg.node_cnt, tb[ETHTOOL_A_PLCA_NODE_CNT], &mod); | 162 | plca_update_sint(&plca_cfg.node_cnt, tb, ETHTOOL_A_PLCA_NODE_CNT, &mod); |
| 150 | plca_update_sint(&plca_cfg.to_tmr, tb[ETHTOOL_A_PLCA_TO_TMR], &mod); | 163 | plca_update_sint(&plca_cfg.to_tmr, tb, ETHTOOL_A_PLCA_TO_TMR, &mod); |
| 151 | plca_update_sint(&plca_cfg.burst_cnt, tb[ETHTOOL_A_PLCA_BURST_CNT], | 164 | plca_update_sint(&plca_cfg.burst_cnt, tb, ETHTOOL_A_PLCA_BURST_CNT, |
| 152 | &mod); | 165 | &mod); |
| 153 | plca_update_sint(&plca_cfg.burst_tmr, tb[ETHTOOL_A_PLCA_BURST_TMR], | 166 | plca_update_sint(&plca_cfg.burst_tmr, tb, ETHTOOL_A_PLCA_BURST_TMR, |
| 154 | &mod); | 167 | &mod); |
| 155 | if (!mod) | 168 | if (!mod) |
| 156 | return 0; | 169 | return 0; |
| @@ -1887,6 +1887,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local) · 1886 unmodified lines | |||
| 1887 | continue; | 1887 | continue; |
| 1888 | if (fi->fib_prefsrc == local) { | 1888 | if (fi->fib_prefsrc == local) { |
| 1889 | fi->fib_flags |= RTNH_F_DEAD; | 1889 | fi->fib_flags |= RTNH_F_DEAD; |
| 1890 | fi->pfsrc_removed = true; | ||
| 1890 | ret++; | 1891 | ret++; |
| 1891 | } | 1892 | } |
| 1892 | } | 1893 | } |
| @@ -2027,6 +2027,7 @@ void fib_table_flush_external(struct fib_table *tb) · 2026 unmodified lines | |||
| 2027 | int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) | 2027 | int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) |
| 2028 | { | 2028 | { |
| 2029 | struct trie *t = (struct trie *)tb->tb_data; | 2029 | struct trie *t = (struct trie *)tb->tb_data; |
| 2030 | struct nl_info info = { .nl_net = net }; | ||
| 2030 | struct key_vector *pn = t->kv; | 2031 | struct key_vector *pn = t->kv; |
| 2031 | unsigned long cindex = 1; | 2032 | unsigned long cindex = 1; |
| 2032 | struct hlist_node *tmp; | 2033 | struct hlist_node *tmp; |
| @@ -2089,6 +2090,9 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) · 56 unmodified lines | |||
| 2089 | 2090 | ||
| 2090 | fib_notify_alias_delete(net, n->key, &n->leaf, fa, | 2091 | fib_notify_alias_delete(net, n->key, &n->leaf, fa, |
| 2091 | NULL); | 2092 | NULL); |
| 2093 | if (fi->pfsrc_removed) | ||
| 2094 | rtmsg_fib(RTM_DELROUTE, htonl(n->key), fa, | ||
| 2095 | KEYLENGTH - fa->fa_slen, tb->tb_id, &info, 0); | ||
| 2092 | hlist_del_rcu(&fa->fa_list); | 2096 | hlist_del_rcu(&fa->fa_list); |
| 2093 | fib_release_info(fa->fa_info); | 2097 | fib_release_info(fa->fa_info); |
| 2094 | alias_free_mem_rcu(fa); | 2098 | alias_free_mem_rcu(fa); |
| @@ -3417,6 +3417,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, · 3416 unmodified lines | |||
| 3417 | fa->fa_type == fri.type) { | 3417 | fa->fa_type == fri.type) { |
| 3418 | fri.offload = READ_ONCE(fa->offload); | 3418 | fri.offload = READ_ONCE(fa->offload); |
| 3419 | fri.trap = READ_ONCE(fa->trap); | 3419 | fri.trap = READ_ONCE(fa->trap); |
| 3420 | fri.offload_failed = | ||
| 3421 | READ_ONCE(fa->offload_failed); | ||
| 3420 | break; | 3422 | break; |
| 3421 | } | 3423 | } |
| 3422 | } | 3424 | } |
| @@ -1621,16 +1621,13 @@ EXPORT_SYMBOL(tcp_read_sock); · 1620 unmodified lines | |||
| 1621 | 1621 | ||
| 1622 | int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) | 1622 | int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) |
| 1623 | { | 1623 | { |
| 1624 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 1625 | u32 seq = tp->copied_seq; | ||
| 1626 | struct sk_buff *skb; | 1624 | struct sk_buff *skb; |
| 1627 | int copied = 0; | 1625 | int copied = 0; |
| 1628 | u32 offset; | ||
| 1629 | 1626 | ||
| 1630 | if (sk->sk_state == TCP_LISTEN) | 1627 | if (sk->sk_state == TCP_LISTEN) |
| 1631 | return -ENOTCONN; | 1628 | return -ENOTCONN; |
| 1632 | 1629 | ||
| 1633 | while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { | 1630 | while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) { |
| 1634 | u8 tcp_flags; | 1631 | u8 tcp_flags; |
| 1635 | int used; | 1632 | int used; |
| 1636 | 1633 | ||
| @@ -1643,13 +1640,10 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) · 6 unmodified lines | |||
| 1643 | copied = used; | 1640 | copied = used; |
| 1644 | break; | 1641 | break; |
| 1645 | } | 1642 | } |
| 1646 | seq += used; | ||
| 1647 | copied += used; | 1643 | copied += used; |
| 1648 | 1644 | ||
| 1649 | if (tcp_flags & TCPHDR_FIN) { | 1645 | if (tcp_flags & TCPHDR_FIN) |
| 1650 | ++seq; | ||
| 1651 | break; | 1646 | break; |
| 1652 | } | ||
| 1653 | } | 1647 | } |
| 1654 | return copied; | 1648 | return copied; |
| 1655 | } | 1649 | } |
| @@ -222,6 +222,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk, · 221 unmodified lines | |||
| 222 | int *addr_len) | 222 | int *addr_len) |
| 223 | { | 223 | { |
| 224 | struct tcp_sock *tcp = tcp_sk(sk); | 224 | struct tcp_sock *tcp = tcp_sk(sk); |
| 225 | int peek = flags & MSG_PEEK; | ||
| 225 | u32 seq = tcp->copied_seq; | 226 | u32 seq = tcp->copied_seq; |
| 226 | struct sk_psock *psock; | 227 | struct sk_psock *psock; |
| 227 | int copied = 0; | 228 | int copied = 0; |
| @@ -311,7 +312,8 @@ msg_bytes_ready: · 83 unmodified lines | |||
| 311 | copied = -EAGAIN; | 312 | copied = -EAGAIN; |
| 312 | } | 313 | } |
| 313 | out: | 314 | out: |
| 314 | WRITE_ONCE(tcp->copied_seq, seq); | 315 | if (!peek) |
| 316 | WRITE_ONCE(tcp->copied_seq, seq); | ||
| 315 | tcp_rcv_space_adjust(sk); | 317 | tcp_rcv_space_adjust(sk); |
| 316 | if (copied > 0) | 318 | if (copied > 0) |
| 317 | __tcp_cleanup_rbuf(sk, copied); | 319 | __tcp_cleanup_rbuf(sk, copied); |
| @@ -253,6 +253,19 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb) · 252 unmodified lines | |||
| 253 | if (unlikely(len > icsk->icsk_ack.rcv_mss + | 253 | if (unlikely(len > icsk->icsk_ack.rcv_mss + |
| 254 | MAX_TCP_OPTION_SPACE)) | 254 | MAX_TCP_OPTION_SPACE)) |
| 255 | tcp_gro_dev_warn(sk, skb, len); | 255 | tcp_gro_dev_warn(sk, skb, len); |
| 256 | /* If the skb has a len of exactly 1*MSS and has the PSH bit | ||
| 257 | * set then it is likely the end of an application write. So | ||
| 258 | * more data may not be arriving soon, and yet the data sender | ||
| 259 | * may be waiting for an ACK if cwnd-bound or using TX zero | ||
| 260 | * copy. So we set ICSK_ACK_PUSHED here so that | ||
| 261 | * tcp_cleanup_rbuf() will send an ACK immediately if the app | ||
| 262 | * reads all of the data and is not ping-pong. If len > MSS | ||
| 263 | * then this logic does not matter (and does not hurt) because | ||
| 264 | * tcp_cleanup_rbuf() will always ACK immediately if the app | ||
| 265 | * reads data and there is more than an MSS of unACKed data. | ||
| 266 | */ | ||
| 267 | if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_PSH) | ||
| 268 | icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; | ||
| 256 | } else { | 269 | } else { |
| 257 | /* Otherwise, we make more careful check taking into account, | 270 | /* Otherwise, we make more careful check taking into account, |
| 258 | * that SACKs block is variable. | 271 | * that SACKs block is variable. |
| @@ -177,8 +177,7 @@ static void tcp_event_data_sent(struct tcp_sock *tp, · 176 unmodified lines | |||
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | /* Account for an ACK we sent. */ | 179 | /* Account for an ACK we sent. */ |
| 180 | static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts, | 180 | static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt) |
| 181 | u32 rcv_nxt) | ||
| 182 | { | 181 | { |
| 183 | struct tcp_sock *tp = tcp_sk(sk); | 182 | struct tcp_sock *tp = tcp_sk(sk); |
| 184 | 183 | ||
| @@ -192,7 +191,7 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts, · 7 unmodified lines | |||
| 192 | 191 | ||
| 193 | if (unlikely(rcv_nxt != tp->rcv_nxt)) | 192 | if (unlikely(rcv_nxt != tp->rcv_nxt)) |
| 194 | return; /* Special ACK sent by DCTCP to reflect ECN */ | 193 | return; /* Special ACK sent by DCTCP to reflect ECN */ |
| 195 | tcp_dec_quickack_mode(sk, pkts); | 194 | tcp_dec_quickack_mode(sk); |
| 196 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); | 195 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); |
| 197 | } | 196 | } |
| 198 | 197 | ||
| @@ -1380,7 +1379,7 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, · 1181 unmodified lines | |||
| 1380 | sk, skb); | 1379 | sk, skb); |
| 1381 | 1380 | ||
| 1382 | if (likely(tcb->tcp_flags & TCPHDR_ACK)) | 1381 | if (likely(tcb->tcp_flags & TCPHDR_ACK)) |
| 1383 | tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt); | 1382 | tcp_event_ack_sent(sk, rcv_nxt); |
| 1384 | 1383 | ||
| 1385 | if (skb->len != tcp_header_size) { | 1384 | if (skb->len != tcp_header_size) { |
| 1386 | tcp_event_data_sent(tp, sk); | 1385 | tcp_event_data_sent(tp, sk); |
| @@ -1639,9 +1639,12 @@ process: · 1638 unmodified lines | |||
| 1639 | struct sock *nsk; | 1639 | struct sock *nsk; |
| 1640 | 1640 | ||
| 1641 | sk = req->rsk_listener; | 1641 | sk = req->rsk_listener; |
| 1642 | drop_reason = tcp_inbound_md5_hash(sk, skb, | 1642 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
| 1643 | &hdr->saddr, &hdr->daddr, | 1643 | drop_reason = SKB_DROP_REASON_XFRM_POLICY; |
| 1644 | AF_INET6, dif, sdif); | 1644 | else |
| 1645 | drop_reason = tcp_inbound_md5_hash(sk, skb, | ||
| 1646 | &hdr->saddr, &hdr->daddr, | ||
| 1647 | AF_INET6, dif, sdif); | ||
| 1645 | if (drop_reason) { | 1648 | if (drop_reason) { |
| 1646 | sk_drops_add(sk, skb); | 1649 | sk_drops_add(sk, skb); |
| 1647 | reqsk_put(req); | 1650 | reqsk_put(req); |
| @@ -1688,6 +1691,7 @@ process: · 40 unmodified lines | |||
| 1688 | } | 1691 | } |
| 1689 | goto discard_and_relse; | 1692 | goto discard_and_relse; |
| 1690 | } | 1693 | } |
| 1694 | nf_reset_ct(skb); | ||
| 1691 | if (nsk == sk) { | 1695 | if (nsk == sk) { |
| 1692 | reqsk_put(req); | 1696 | reqsk_put(req); |
| 1693 | tcp_v6_restore_cb(skb); | 1697 | tcp_v6_restore_cb(skb); |
| @@ -507,7 +507,6 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) · 506 unmodified lines | |||
| 507 | */ | 507 | */ |
| 508 | if (len > INT_MAX - transhdrlen) | 508 | if (len > INT_MAX - transhdrlen) |
| 509 | return -EMSGSIZE; | 509 | return -EMSGSIZE; |
| 510 | ulen = len + transhdrlen; | ||
| 511 | 510 | ||
| 512 | /* Mirror BSD error message compatibility */ | 511 | /* Mirror BSD error message compatibility */ |
| 513 | if (msg->msg_flags & MSG_OOB) | 512 | if (msg->msg_flags & MSG_OOB) |
| @@ -628,6 +627,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) · 114 unmodified lines | |||
| 628 | 627 | ||
| 629 | back_from_confirm: | 628 | back_from_confirm: |
| 630 | lock_sock(sk); | 629 | lock_sock(sk); |
| 630 | ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; | ||
| 631 | err = ip6_append_data(sk, ip_generic_getfrag, msg, | 631 | err = ip6_append_data(sk, ip_generic_getfrag, msg, |
| 632 | ulen, transhdrlen, &ipc6, | 632 | ulen, transhdrlen, &ipc6, |
| 633 | &fl6, (struct rt6_info *)dst, | 633 | &fl6, (struct rt6_info *)dst, |
| @@ -566,6 +566,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, · 565 unmodified lines | |||
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | err = ieee80211_key_link(key, link, sta); | 568 | err = ieee80211_key_link(key, link, sta); |
| 569 | /* KRACK protection, shouldn't happen but just silently accept key */ | ||
| 570 | if (err == -EALREADY) | ||
| 571 | err = 0; | ||
| 569 | 572 | ||
| 570 | out_unlock: | 573 | out_unlock: |
| 571 | mutex_unlock(&local->sta_mtx); | 574 | mutex_unlock(&local->sta_mtx); |
| @@ -1857,7 +1860,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local, · 1285 unmodified lines | |||
| 1857 | /* VHT can override some HT caps such as the A-MSDU max length */ | 1860 | /* VHT can override some HT caps such as the A-MSDU max length */ |
| 1858 | if (params->vht_capa) | 1861 | if (params->vht_capa) |
| 1859 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | 1862 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, |
| 1860 | params->vht_capa, link_sta); | 1863 | params->vht_capa, NULL, |
| 1864 | link_sta); | ||
| 1861 | 1865 | ||
| 1862 | if (params->he_capa) | 1866 | if (params->he_capa) |
| 1863 | ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, | 1867 | ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, |
| @@ -1072,7 +1072,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, · 1071 unmodified lines | |||
| 1072 | &chandef); | 1072 | &chandef); |
| 1073 | memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); | 1073 | memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); |
| 1074 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | 1074 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, |
| 1075 | &cap_ie, | 1075 | &cap_ie, NULL, |
| 1076 | &sta->deflink); | 1076 | &sta->deflink); |
| 1077 | if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap))) | 1077 | if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap))) |
| 1078 | rates_updated |= true; | 1078 | rates_updated |= true; |
| @@ -676,7 +676,7 @@ struct ieee80211_if_mesh { · 675 unmodified lines | |||
| 676 | struct timer_list mesh_path_root_timer; | 676 | struct timer_list mesh_path_root_timer; |
| 677 | 677 | ||
| 678 | unsigned long wrkq_flags; | 678 | unsigned long wrkq_flags; |
| 679 | unsigned long mbss_changed; | 679 | unsigned long mbss_changed[64 / BITS_PER_LONG]; |
| 680 | 680 | ||
| 681 | bool userspace_handles_dfs; | 681 | bool userspace_handles_dfs; |
| 682 | 682 | ||
| @@ -2141,6 +2141,7 @@ void · 1458 unmodified lines | |||
| 2141 | ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | 2141 | ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, |
| 2142 | struct ieee80211_supported_band *sband, | 2142 | struct ieee80211_supported_band *sband, |
| 2143 | const struct ieee80211_vht_cap *vht_cap_ie, | 2143 | const struct ieee80211_vht_cap *vht_cap_ie, |
| 2144 | const struct ieee80211_vht_cap *vht_cap_ie2, | ||
| 2144 | struct link_sta_info *link_sta); | 2145 | struct link_sta_info *link_sta); |
| 2145 | enum ieee80211_sta_rx_bandwidth | 2146 | enum ieee80211_sta_rx_bandwidth |
| 2146 | ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta); | 2147 | ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta); |
| @@ -802,6 +802,9 @@ static void ieee80211_key_destroy(struct ieee80211_key *key, · 801 unmodified lines | |||
| 802 | 802 | ||
| 803 | void ieee80211_key_free_unused(struct ieee80211_key *key) | 803 | void ieee80211_key_free_unused(struct ieee80211_key *key) |
| 804 | { | 804 | { |
| 805 | if (!key) | ||
| 806 | return; | ||
| 807 | |||
| 805 | WARN_ON(key->sdata || key->local); | 808 | WARN_ON(key->sdata || key->local); |
| 806 | ieee80211_key_free_common(key); | 809 | ieee80211_key_free_common(key); |
| 807 | } | 810 | } |
| @@ -854,7 +857,7 @@ int ieee80211_key_link(struct ieee80211_key *key, · 46 unmodified lines | |||
| 854 | * can cause warnings to appear. | 857 | * can cause warnings to appear. |
| 855 | */ | 858 | */ |
| 856 | bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; | 859 | bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; |
| 857 | int ret = -EOPNOTSUPP; | 860 | int ret; |
| 858 | 861 | ||
| 859 | mutex_lock(&sdata->local->key_mtx); | 862 | mutex_lock(&sdata->local->key_mtx); |
| 860 | 863 | ||
| @@ -868,8 +871,10 @@ int ieee80211_key_link(struct ieee80211_key *key, · 7 unmodified lines | |||
| 868 | * the same cipher. Enforce the assumption for pairwise keys. | 871 | * the same cipher. Enforce the assumption for pairwise keys. |
| 869 | */ | 872 | */ |
| 870 | if ((alt_key && alt_key->conf.cipher != key->conf.cipher) || | 873 | if ((alt_key && alt_key->conf.cipher != key->conf.cipher) || |
| 871 | (old_key && old_key->conf.cipher != key->conf.cipher)) | 874 | (old_key && old_key->conf.cipher != key->conf.cipher)) { |
| 875 | ret = -EOPNOTSUPP; | ||
| 872 | goto out; | 876 | goto out; |
| 877 | } | ||
| 873 | } else if (sta) { | 878 | } else if (sta) { |
| 874 | struct link_sta_info *link_sta = &sta->deflink; | 879 | struct link_sta_info *link_sta = &sta->deflink; |
| 875 | int link_id = key->conf.link_id; | 880 | int link_id = key->conf.link_id; |
| @@ -895,8 +900,10 @@ int ieee80211_key_link(struct ieee80211_key *key, · 19 unmodified lines | |||
| 895 | 900 | ||
| 896 | /* Non-pairwise keys must also not switch the cipher on rekey */ | 901 | /* Non-pairwise keys must also not switch the cipher on rekey */ |
| 897 | if (!pairwise) { | 902 | if (!pairwise) { |
| 898 | if (old_key && old_key->conf.cipher != key->conf.cipher) | 903 | if (old_key && old_key->conf.cipher != key->conf.cipher) { |
| 904 | ret = -EOPNOTSUPP; | ||
| 899 | goto out; | 905 | goto out; |
| 906 | } | ||
| 900 | } | 907 | } |
| 901 | 908 | ||
| 902 | /* | 909 | /* |
| @@ -904,9 +911,8 @@ int ieee80211_key_link(struct ieee80211_key *key, · 1 unmodified line | |||
| 904 | * new version of the key to avoid nonce reuse or replay issues. | 911 | * new version of the key to avoid nonce reuse or replay issues. |
| 905 | */ | 912 | */ |
| 906 | if (ieee80211_key_identical(sdata, old_key, key)) { | 913 | if (ieee80211_key_identical(sdata, old_key, key)) { |
| 907 | ieee80211_key_free_unused(key); | 914 | ret = -EALREADY; |
| 908 | ret = 0; | 915 | goto unlock; |
| 909 | goto out; | ||
| 910 | } | 916 | } |
| 911 | 917 | ||
| 912 | key->local = sdata->local; | 918 | key->local = sdata->local; |
| @@ -930,7 +936,11 @@ int ieee80211_key_link(struct ieee80211_key *key, · 17 unmodified lines | |||
| 930 | ieee80211_key_free(key, delay_tailroom); | 936 | ieee80211_key_free(key, delay_tailroom); |
| 931 | } | 937 | } |
| 932 | 938 | ||
| 939 | key = NULL; | ||
| 940 | |||
| 933 | out: | 941 | out: |
| 942 | ieee80211_key_free_unused(key); | ||
| 943 | unlock: | ||
| 934 | mutex_unlock(&sdata->local->key_mtx); | 944 | mutex_unlock(&sdata->local->key_mtx); |
| 935 | 945 | ||
| 936 | return ret; | 946 | return ret; |
| @@ -1175,7 +1175,7 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, · 1174 unmodified lines | |||
| 1175 | 1175 | ||
| 1176 | /* if we race with running work, worst case this work becomes a noop */ | 1176 | /* if we race with running work, worst case this work becomes a noop */ |
| 1177 | for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE) | 1177 | for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE) |
| 1178 | set_bit(bit, &ifmsh->mbss_changed); | 1178 | set_bit(bit, ifmsh->mbss_changed); |
| 1179 | set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags); | 1179 | set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags); |
| 1180 | wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); | 1180 | wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); |
| 1181 | } | 1181 | } |
| @@ -1257,7 +1257,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) · 75 unmodified lines | |||
| 1257 | 1257 | ||
| 1258 | /* clear any mesh work (for next join) we may have accrued */ | 1258 | /* clear any mesh work (for next join) we may have accrued */ |
| 1259 | ifmsh->wrkq_flags = 0; | 1259 | ifmsh->wrkq_flags = 0; |
| 1260 | ifmsh->mbss_changed = 0; | 1260 | memset(ifmsh->mbss_changed, 0, sizeof(ifmsh->mbss_changed)); |
| 1261 | 1261 | ||
| 1262 | local->fif_other_bss--; | 1262 | local->fif_other_bss--; |
| 1263 | atomic_dec(&local->iff_allmultis); | 1263 | atomic_dec(&local->iff_allmultis); |
| @@ -1724,9 +1724,9 @@ static void mesh_bss_info_changed(struct ieee80211_sub_if_data *sdata) · 460 unmodified lines | |||
| 1724 | u32 bit; | 1724 | u32 bit; |
| 1725 | u64 changed = 0; | 1725 | u64 changed = 0; |
| 1726 | 1726 | ||
| 1727 | for_each_set_bit(bit, &ifmsh->mbss_changed, | 1727 | for_each_set_bit(bit, ifmsh->mbss_changed, |
| 1728 | sizeof(changed) * BITS_PER_BYTE) { | 1728 | sizeof(changed) * BITS_PER_BYTE) { |
| 1729 | clear_bit(bit, &ifmsh->mbss_changed); | 1729 | clear_bit(bit, ifmsh->mbss_changed); |
| 1730 | changed |= BIT(bit); | 1730 | changed |= BIT(bit); |
| 1731 | } | 1731 | } |
| 1732 | 1732 | ||
| @@ -451,7 +451,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, · 450 unmodified lines | |||
| 451 | changed |= IEEE80211_RC_BW_CHANGED; | 451 | changed |= IEEE80211_RC_BW_CHANGED; |
| 452 | 452 | ||
| 453 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | 453 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, |
| 454 | elems->vht_cap_elem, | 454 | elems->vht_cap_elem, NULL, |
| 455 | &sta->deflink); | 455 | &sta->deflink); |
| 456 | 456 | ||
| 457 | ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap, | 457 | ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap, |
| @@ -4202,10 +4202,33 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link, · 4201 unmodified lines | |||
| 4202 | elems->ht_cap_elem, | 4202 | elems->ht_cap_elem, |
| 4203 | link_sta); | 4203 | link_sta); |
| 4204 | 4204 | ||
| 4205 | if (elems->vht_cap_elem && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) | 4205 | if (elems->vht_cap_elem && |
| 4206 | !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) { | ||
| 4207 | const struct ieee80211_vht_cap *bss_vht_cap = NULL; | ||
| 4208 | const struct cfg80211_bss_ies *ies; | ||
| 4209 | |||
| 4210 | /* | ||
| 4211 | * Cisco AP module 9115 with FW 17.3 has a bug and sends a | ||
| 4212 | * too large maximum MPDU length in the association response | ||
| 4213 | * (indicating 12k) that it cannot actually process ... | ||
| 4214 | * Work around that. | ||
| 4215 | */ | ||
| 4216 | rcu_read_lock(); | ||
| 4217 | ies = rcu_dereference(cbss->ies); | ||
| 4218 | if (ies) { | ||
| 4219 | const struct element *elem; | ||
| 4220 | |||
| 4221 | elem = cfg80211_find_elem(WLAN_EID_VHT_CAPABILITY, | ||
| 4222 | ies->data, ies->len); | ||
| 4223 | if (elem && elem->datalen >= sizeof(*bss_vht_cap)) | ||
| 4224 | bss_vht_cap = (const void *)elem->data; | ||
| 4225 | } | ||
| 4226 | |||
| 4206 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | 4227 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, |
| 4207 | elems->vht_cap_elem, | 4228 | elems->vht_cap_elem, |
| 4208 | link_sta); | 4229 | bss_vht_cap, link_sta); |
| 4230 | rcu_read_unlock(); | ||
| 4231 | } | ||
| 4209 | 4232 | ||
| 4210 | if (elems->he_operation && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) && | 4233 | if (elems->he_operation && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) && |
| 4211 | elems->he_cap) { | 4234 | elems->he_cap) { |
| @@ -5107,9 +5130,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, · 895 unmodified lines | |||
| 5107 | continue; | 5130 | continue; |
| 5108 | 5131 | ||
| 5109 | valid_links |= BIT(link_id); | 5132 | valid_links |= BIT(link_id); |
| 5110 | if (assoc_data->link[link_id].disabled) { | 5133 | if (assoc_data->link[link_id].disabled) |
| 5111 | dormant_links |= BIT(link_id); | 5134 | dormant_links |= BIT(link_id); |
| 5112 | } else if (link_id != assoc_data->assoc_link_id) { | 5135 | |
| 5136 | if (link_id != assoc_data->assoc_link_id) { | ||
| 5113 | err = ieee80211_sta_allocate_link(sta, link_id); | 5137 | err = ieee80211_sta_allocate_link(sta, link_id); |
| 5114 | if (err) | 5138 | if (err) |
| 5115 | goto out_err; | 5139 | goto out_err; |
| @@ -5124,7 +5148,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, · 8 unmodified lines | |||
| 5124 | struct ieee80211_link_data *link; | 5148 | struct ieee80211_link_data *link; |
| 5125 | struct link_sta_info *link_sta; | 5149 | struct link_sta_info *link_sta; |
| 5126 | 5150 | ||
| 5127 | if (!cbss || assoc_data->link[link_id].disabled) | 5151 | if (!cbss) |
| 5128 | continue; | 5152 | continue; |
| 5129 | 5153 | ||
| 5130 | link = sdata_dereference(sdata->link[link_id], sdata); | 5154 | link = sdata_dereference(sdata->link[link_id], sdata); |
| @@ -5429,17 +5453,18 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, · 298 unmodified lines | |||
| 5429 | for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) { | 5453 | for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) { |
| 5430 | struct ieee80211_link_data *link; | 5454 | struct ieee80211_link_data *link; |
| 5431 | 5455 | ||
| 5432 | link = sdata_dereference(sdata->link[link_id], sdata); | ||
| 5433 | if (!link) | ||
| 5434 | continue; | ||
| 5435 | |||
| 5436 | if (!assoc_data->link[link_id].bss) | 5456 | if (!assoc_data->link[link_id].bss) |
| 5437 | continue; | 5457 | continue; |
| 5438 | 5458 | ||
| 5439 | resp.links[link_id].bss = assoc_data->link[link_id].bss; | 5459 | resp.links[link_id].bss = assoc_data->link[link_id].bss; |
| 5440 | resp.links[link_id].addr = link->conf->addr; | 5460 | ether_addr_copy(resp.links[link_id].addr, |
| 5461 | assoc_data->link[link_id].addr); | ||
| 5441 | resp.links[link_id].status = assoc_data->link[link_id].status; | 5462 | resp.links[link_id].status = assoc_data->link[link_id].status; |
| 5442 | 5463 | ||
| 5464 | link = sdata_dereference(sdata->link[link_id], sdata); | ||
| 5465 | if (!link) | ||
| 5466 | continue; | ||
| 5467 | |||
| 5443 | /* get uapsd queues configuration - same for all links */ | 5468 | /* get uapsd queues configuration - same for all links */ |
| 5444 | resp.uapsd_queues = 0; | 5469 | resp.uapsd_queues = 0; |
| 5445 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 5470 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
| @@ -665,7 +665,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) · 664 unmodified lines | |||
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED && | 667 | if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED && |
| 668 | !ieee80211_is_deauth(hdr->frame_control))) | 668 | !ieee80211_is_deauth(hdr->frame_control)) && |
| 669 | tx->skb->protocol != tx->sdata->control_port_protocol) | ||
| 669 | return TX_DROP; | 670 | return TX_DROP; |
| 670 | 671 | ||
| 671 | if (!skip_hw && tx->key && | 672 | if (!skip_hw && tx->key && |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | * | 4 | * |
| 5 | * Portions of this file | 5 | * Portions of this file |
| 6 | * Copyright(c) 2015 - 2016 Intel Deutschland GmbH | 6 | * Copyright(c) 2015 - 2016 Intel Deutschland GmbH |
| 7 | * Copyright (C) 2018 - 2022 Intel Corporation | 7 | * Copyright (C) 2018 - 2023 Intel Corporation |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/ieee80211.h> | 10 | #include <linux/ieee80211.h> |
| @@ -116,12 +116,14 @@ void · 105 unmodified lines | |||
| 116 | ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | 116 | ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, |
| 117 | struct ieee80211_supported_band *sband, | 117 | struct ieee80211_supported_band *sband, |
| 118 | const struct ieee80211_vht_cap *vht_cap_ie, | 118 | const struct ieee80211_vht_cap *vht_cap_ie, |
| 119 | const struct ieee80211_vht_cap *vht_cap_ie2, | ||
| 119 | struct link_sta_info *link_sta) | 120 | struct link_sta_info *link_sta) |
| 120 | { | 121 | { |
| 121 | struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap; | 122 | struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap; |
| 122 | struct ieee80211_sta_vht_cap own_cap; | 123 | struct ieee80211_sta_vht_cap own_cap; |
| 123 | u32 cap_info, i; | 124 | u32 cap_info, i; |
| 124 | bool have_80mhz; | 125 | bool have_80mhz; |
| 126 | u32 mpdu_len; | ||
| 125 | 127 | ||
| 126 | memset(vht_cap, 0, sizeof(*vht_cap)); | 128 | memset(vht_cap, 0, sizeof(*vht_cap)); |
| 127 | 129 | ||
| @@ -317,11 +319,21 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, · 189 unmodified lines | |||
| 317 | 319 | ||
| 318 | link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta); | 320 | link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta); |
| 319 | 321 | ||
| 322 | /* | ||
| 323 | * Work around the Cisco 9115 FW 17.3 bug by taking the min of | ||
| 324 | * both reported MPDU lengths. | ||
| 325 | */ | ||
| 326 | mpdu_len = vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK; | ||
| 327 | if (vht_cap_ie2) | ||
| 328 | mpdu_len = min_t(u32, mpdu_len, | ||
| 329 | le32_get_bits(vht_cap_ie2->vht_cap_info, | ||
| 330 | IEEE80211_VHT_CAP_MAX_MPDU_MASK)); | ||
| 331 | |||
| 320 | /* | 332 | /* |
| 321 | * FIXME - should the amsdu len be per link? store per link | 333 | * FIXME - should the amsdu len be per link? store per link |
| 322 | * and maintain a minimum? | 334 | * and maintain a minimum? |
| 323 | */ | 335 | */ |
| 324 | switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) { | 336 | switch (mpdu_len) { |
| 325 | case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: | 337 | case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454: |
| 326 | link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454; | 338 | link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454; |
| 327 | break; | 339 | break; |
| @@ -307,12 +307,6 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info) · 306 unmodified lines | |||
| 307 | goto create_err; | 307 | goto create_err; |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | if (addr_l.id == 0) { | ||
| 311 | NL_SET_ERR_MSG_ATTR(info->extack, laddr, "missing local addr id"); | ||
| 312 | err = -EINVAL; | ||
| 313 | goto create_err; | ||
| 314 | } | ||
| 315 | |||
| 316 | err = mptcp_pm_parse_addr(raddr, info, &addr_r); | 310 | err = mptcp_pm_parse_addr(raddr, info, &addr_r); |
| 317 | if (err < 0) { | 311 | if (err < 0) { |
| 318 | NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr"); | 312 | NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr"); |
| @@ -3425,24 +3425,21 @@ static void schedule_3rdack_retransmission(struct sock *ssk) · 3424 unmodified lines | |||
| 3425 | sk_reset_timer(ssk, &icsk->icsk_delack_timer, timeout); | 3425 | sk_reset_timer(ssk, &icsk->icsk_delack_timer, timeout); |
| 3426 | } | 3426 | } |
| 3427 | 3427 | ||
| 3428 | void mptcp_subflow_process_delegated(struct sock *ssk) | 3428 | void mptcp_subflow_process_delegated(struct sock *ssk, long status) |
| 3429 | { | 3429 | { |
| 3430 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); | 3430 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); |
| 3431 | struct sock *sk = subflow->conn; | 3431 | struct sock *sk = subflow->conn; |
| 3432 | 3432 | ||
| 3433 | if (test_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status)) { | 3433 | if (status & BIT(MPTCP_DELEGATE_SEND)) { |
| 3434 | mptcp_data_lock(sk); | 3434 | mptcp_data_lock(sk); |
| 3435 | if (!sock_owned_by_user(sk)) | 3435 | if (!sock_owned_by_user(sk)) |
| 3436 | __mptcp_subflow_push_pending(sk, ssk, true); | 3436 | __mptcp_subflow_push_pending(sk, ssk, true); |
| 3437 | else | 3437 | else |
| 3438 | __set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->cb_flags); | 3438 | __set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->cb_flags); |
| 3439 | mptcp_data_unlock(sk); | 3439 | mptcp_data_unlock(sk); |
| 3440 | mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_SEND); | ||
| 3441 | } | 3440 | } |
| 3442 | if (test_bit(MPTCP_DELEGATE_ACK, &subflow->delegated_status)) { | 3441 | if (status & BIT(MPTCP_DELEGATE_ACK)) |
| 3443 | schedule_3rdack_retransmission(ssk); | 3442 | schedule_3rdack_retransmission(ssk); |
| 3444 | mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_ACK); | ||
| 3445 | } | ||
| 3446 | } | 3443 | } |
| 3447 | 3444 | ||
| 3448 | static int mptcp_hash(struct sock *sk) | 3445 | static int mptcp_hash(struct sock *sk) |
| @@ -3968,14 +3965,17 @@ static int mptcp_napi_poll(struct napi_struct *napi, int budget) · 519 unmodified lines | |||
| 3968 | struct sock *ssk = mptcp_subflow_tcp_sock(subflow); | 3965 | struct sock *ssk = mptcp_subflow_tcp_sock(subflow); |
| 3969 | 3966 | ||
| 3970 | bh_lock_sock_nested(ssk); | 3967 | bh_lock_sock_nested(ssk); |
| 3971 | if (!sock_owned_by_user(ssk) && | 3968 | if (!sock_owned_by_user(ssk)) { |
| 3972 | mptcp_subflow_has_delegated_action(subflow)) | 3969 | mptcp_subflow_process_delegated(ssk, xchg(&subflow->delegated_status, 0)); |
| 3973 | mptcp_subflow_process_delegated(ssk); | 3970 | } else { |
| 3974 | /* ... elsewhere tcp_release_cb_override already processed | 3971 | /* tcp_release_cb_override already processed |
| 3975 | * the action or will do at next release_sock(). | 3972 | * the action or will do at next release_sock(). |
| 3976 | * In both case must dequeue the subflow here - on the same | 3973 | * In both case must dequeue the subflow here - on the same |
| 3977 | * CPU that scheduled it. | 3974 | * CPU that scheduled it. |
| 3978 | */ | 3975 | */ |
| 3976 | smp_wmb(); | ||
| 3977 | clear_bit(MPTCP_DELEGATE_SCHEDULED, &subflow->delegated_status); | ||
| 3978 | } | ||
| 3979 | bh_unlock_sock(ssk); | 3979 | bh_unlock_sock(ssk); |
| 3980 | sock_put(ssk); | 3980 | sock_put(ssk); |
| 3981 | 3981 | ||
| @@ -444,9 +444,11 @@ struct mptcp_delegated_action { · 443 unmodified lines | |||
| 444 | 444 | ||
| 445 | DECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); | 445 | DECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); |
| 446 | 446 | ||
| 447 | #define MPTCP_DELEGATE_SEND 0 | 447 | #define MPTCP_DELEGATE_SCHEDULED 0 |
| 448 | #define MPTCP_DELEGATE_ACK 1 | 448 | #define MPTCP_DELEGATE_SEND 1 |
| 449 | #define MPTCP_DELEGATE_ACK 2 | ||
| 449 | 450 | ||
| 451 | #define MPTCP_DELEGATE_ACTIONS_MASK (~BIT(MPTCP_DELEGATE_SCHEDULED)) | ||
| 450 | /* MPTCP subflow context */ | 452 | /* MPTCP subflow context */ |
| 451 | struct mptcp_subflow_context { | 453 | struct mptcp_subflow_context { |
| 452 | struct list_head node;/* conn_list of subflows */ | 454 | struct list_head node;/* conn_list of subflows */ |
| @@ -564,23 +566,24 @@ mptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow) · 111 unmodified lines | |||
| 564 | return subflow->map_seq + mptcp_subflow_get_map_offset(subflow); | 566 | return subflow->map_seq + mptcp_subflow_get_map_offset(subflow); |
| 565 | } | 567 | } |
| 566 | 568 | ||
| 567 | void mptcp_subflow_process_delegated(struct sock *ssk); | 569 | void mptcp_subflow_process_delegated(struct sock *ssk, long actions); |
| 568 | 570 | ||
| 569 | static inline void mptcp_subflow_delegate(struct mptcp_subflow_context *subflow, int action) | 571 | static inline void mptcp_subflow_delegate(struct mptcp_subflow_context *subflow, int action) |
| 570 | { | 572 | { |
| 573 | long old, set_bits = BIT(MPTCP_DELEGATE_SCHEDULED) | BIT(action); | ||
| 571 | struct mptcp_delegated_action *delegated; | 574 | struct mptcp_delegated_action *delegated; |
| 572 | bool schedule; | 575 | bool schedule; |
| 573 | 576 | ||
| 574 | /* the caller held the subflow bh socket lock */ | 577 | /* the caller held the subflow bh socket lock */ |
| 575 | lockdep_assert_in_softirq(); | 578 | lockdep_assert_in_softirq(); |
| 576 | 579 | ||
| 577 | /* The implied barrier pairs with mptcp_subflow_delegated_done(), and | 580 | /* The implied barrier pairs with tcp_release_cb_override() |
| 578 | * ensures the below list check sees list updates done prior to status | 581 | * mptcp_napi_poll(), and ensures the below list check sees list |
| 579 | * bit changes | 582 | * updates done prior to delegated status bits changes |
| 580 | */ | 583 | */ |
| 581 | if (!test_and_set_bit(action, &subflow->delegated_status)) { | 584 | old = set_mask_bits(&subflow->delegated_status, 0, set_bits); |
| 582 | /* still on delegated list from previous scheduling */ | 585 | if (!(old & BIT(MPTCP_DELEGATE_SCHEDULED))) { |
| 583 | if (!list_empty(&subflow->delegated_node)) | 586 | if (WARN_ON_ONCE(!list_empty(&subflow->delegated_node))) |
| 584 | return; | 587 | return; |
| 585 | 588 | ||
| 586 | delegated = this_cpu_ptr(&mptcp_delegated_actions); | 589 | delegated = this_cpu_ptr(&mptcp_delegated_actions); |
| @@ -605,20 +608,6 @@ mptcp_subflow_delegated_next(struct mptcp_delegated_action *delegated) · 18 unmodified lines | |||
| 605 | return ret; | 608 | return ret; |
| 606 | } | 609 | } |
| 607 | 610 | ||
| 608 | static inline bool mptcp_subflow_has_delegated_action(const struct mptcp_subflow_context *subflow) | ||
| 609 | { | ||
| 610 | return !!READ_ONCE(subflow->delegated_status); | ||
| 611 | } | ||
| 612 | |||
| 613 | static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *subflow, int action) | ||
| 614 | { | ||
| 615 | /* pairs with mptcp_subflow_delegate, ensures delegate_node is updated before | ||
| 616 | * touching the status bit | ||
| 617 | */ | ||
| 618 | smp_wmb(); | ||
| 619 | clear_bit(action, &subflow->delegated_status); | ||
| 620 | } | ||
| 621 | |||
| 622 | int mptcp_is_enabled(const struct net *net); | 611 | int mptcp_is_enabled(const struct net *net); |
| 623 | unsigned int mptcp_get_add_addr_timeout(const struct net *net); | 612 | unsigned int mptcp_get_add_addr_timeout(const struct net *net); |
| 624 | int mptcp_is_checksum_enabled(const struct net *net); | 613 | int mptcp_is_checksum_enabled(const struct net *net); |
| @@ -1956,9 +1956,15 @@ static void subflow_ulp_clone(const struct request_sock *req, · 1955 unmodified lines | |||
| 1956 | static void tcp_release_cb_override(struct sock *ssk) | 1956 | static void tcp_release_cb_override(struct sock *ssk) |
| 1957 | { | 1957 | { |
| 1958 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); | 1958 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); |
| 1959 | long status; | ||
| 1959 | 1960 | ||
| 1960 | if (mptcp_subflow_has_delegated_action(subflow)) | 1961 | /* process and clear all the pending actions, but leave the subflow into |
| 1961 | mptcp_subflow_process_delegated(ssk); | 1962 | * the napi queue. To respect locking, only the same CPU that originated |
| 1963 | * the action can touch the list. mptcp_napi_poll will take care of it. | ||
| 1964 | */ | ||
| 1965 | status = set_mask_bits(&subflow->delegated_status, MPTCP_DELEGATE_ACTIONS_MASK, 0); | ||
| 1966 | if (status) | ||
| 1967 | mptcp_subflow_process_delegated(ssk, status); | ||
| 1962 | 1968 | ||
| 1963 | tcp_release_cb(ssk); | 1969 | tcp_release_cb(ssk); |
| 1964 | } | 1970 | } |
| @@ -1435,7 +1435,7 @@ static int bind_mcastif_addr(struct socket *sock, struct net_device *dev) · 1434 unmodified lines | |||
| 1435 | sin.sin_addr.s_addr = addr; | 1435 | sin.sin_addr.s_addr = addr; |
| 1436 | sin.sin_port = 0; | 1436 | sin.sin_port = 0; |
| 1437 | 1437 | ||
| 1438 | return sock->ops->bind(sock, (struct sockaddr*)&sin, sizeof(sin)); | 1438 | return kernel_bind(sock, (struct sockaddr *)&sin, sizeof(sin)); |
| 1439 | } | 1439 | } |
| 1440 | 1440 | ||
| 1441 | static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen, | 1441 | static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen, |
| @@ -1501,8 +1501,8 @@ static int make_send_sock(struct netns_ipvs *ipvs, int id, · 59 unmodified lines | |||
| 1501 | } | 1501 | } |
| 1502 | 1502 | ||
| 1503 | get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->mcfg, id); | 1503 | get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->mcfg, id); |
| 1504 | result = sock->ops->connect(sock, (struct sockaddr *) &mcast_addr, | 1504 | result = kernel_connect(sock, (struct sockaddr *)&mcast_addr, |
| 1505 | salen, 0); | 1505 | salen, 0); |
| 1506 | if (result < 0) { | 1506 | if (result < 0) { |
| 1507 | pr_err("Error connecting to the multicast addr\n"); | 1507 | pr_err("Error connecting to the multicast addr\n"); |
| 1508 | goto error; | 1508 | goto error; |
| @@ -1542,7 +1542,7 @@ static int make_receive_sock(struct netns_ipvs *ipvs, int id, · 33 unmodified lines | |||
| 1542 | 1542 | ||
| 1543 | get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id); | 1543 | get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id); |
| 1544 | sock->sk->sk_bound_dev_if = dev->ifindex; | 1544 | sock->sk->sk_bound_dev_if = dev->ifindex; |
| 1545 | result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen); | 1545 | result = kernel_bind(sock, (struct sockaddr *)&mcast_addr, salen); |
| 1546 | if (result < 0) { | 1546 | if (result < 0) { |
| 1547 | pr_err("Error binding to the multicast addr\n"); | 1547 | pr_err("Error binding to the multicast addr\n"); |
| 1548 | goto error; | 1548 | goto error; |
| @@ -112,7 +112,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { · 111 unmodified lines | |||
| 112 | /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA}, | 112 | /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA}, |
| 113 | /* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/ | 113 | /* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/ |
| 114 | /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */ | 114 | /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */ |
| 115 | /* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ | 115 | /* cookie_ack */ {sCL, sCL, sCW, sES, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ |
| 116 | /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL}, | 116 | /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL}, |
| 117 | /* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, | 117 | /* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, |
| 118 | /* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, | 118 | /* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, |
| @@ -126,7 +126,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { · 7 unmodified lines | |||
| 126 | /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV}, | 126 | /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV}, |
| 127 | /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV}, | 127 | /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV}, |
| 128 | /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV}, | 128 | /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV}, |
| 129 | /* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ | 129 | /* cookie_echo */ {sIV, sCL, sCE, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ |
| 130 | /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV}, | 130 | /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV}, |
| 131 | /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV}, | 131 | /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV}, |
| 132 | /* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, | 132 | /* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, |
| @@ -412,6 +412,9 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, · 279 unmodified lines | |||
| 412 | /* (D) vtag must be same as init_vtag as found in INIT_ACK */ | 412 | /* (D) vtag must be same as init_vtag as found in INIT_ACK */ |
| 413 | if (sh->vtag != ct->proto.sctp.vtag[dir]) | 413 | if (sh->vtag != ct->proto.sctp.vtag[dir]) |
| 414 | goto out_unlock; | 414 | goto out_unlock; |
| 415 | } else if (sch->type == SCTP_CID_COOKIE_ACK) { | ||
| 416 | ct->proto.sctp.init[dir] = 0; | ||
| 417 | ct->proto.sctp.init[!dir] = 0; | ||
| 415 | } else if (sch->type == SCTP_CID_HEARTBEAT) { | 418 | } else if (sch->type == SCTP_CID_HEARTBEAT) { |
| 416 | if (ct->proto.sctp.vtag[dir] == 0) { | 419 | if (ct->proto.sctp.vtag[dir] == 0) { |
| 417 | pr_debug("Setting %d vtag %x for dir %d\n", sch->type, sh->vtag, dir); | 420 | pr_debug("Setting %d vtag %x for dir %d\n", sch->type, sh->vtag, dir); |
| @@ -461,16 +464,18 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, · 43 unmodified lines | |||
| 461 | } | 464 | } |
| 462 | 465 | ||
| 463 | /* If it is an INIT or an INIT ACK note down the vtag */ | 466 | /* If it is an INIT or an INIT ACK note down the vtag */ |
| 464 | if (sch->type == SCTP_CID_INIT || | 467 | if (sch->type == SCTP_CID_INIT) { |
| 465 | sch->type == SCTP_CID_INIT_ACK) { | 468 | struct sctp_inithdr _ih, *ih; |
| 466 | struct sctp_inithdr _inithdr, *ih; | ||
| 467 | 469 | ||
| 468 | ih = skb_header_pointer(skb, offset + sizeof(_sch), | 470 | ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); |
| 469 | sizeof(_inithdr), &_inithdr); | 471 | if (!ih) |
| 470 | if (ih == NULL) | ||
| 471 | goto out_unlock; | 472 | goto out_unlock; |
| 472 | pr_debug("Setting vtag %x for dir %d\n", | 473 | |
| 473 | ih->init_tag, !dir); | 474 | if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir]) |
| 475 | ct->proto.sctp.init[!dir] = 0; | ||
| 476 | ct->proto.sctp.init[dir] = 1; | ||
| 477 | |||
| 478 | pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); | ||
| 474 | ct->proto.sctp.vtag[!dir] = ih->init_tag; | 479 | ct->proto.sctp.vtag[!dir] = ih->init_tag; |
| 475 | 480 | ||
| 476 | /* don't renew timeout on init retransmit so | 481 | /* don't renew timeout on init retransmit so |
| @@ -481,6 +486,24 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, · 4 unmodified lines | |||
| 481 | old_state == SCTP_CONNTRACK_CLOSED && | 486 | old_state == SCTP_CONNTRACK_CLOSED && |
| 482 | nf_ct_is_confirmed(ct)) | 487 | nf_ct_is_confirmed(ct)) |
| 483 | ignore = true; | 488 | ignore = true; |
| 489 | } else if (sch->type == SCTP_CID_INIT_ACK) { | ||
| 490 | struct sctp_inithdr _ih, *ih; | ||
| 491 | __be32 vtag; | ||
| 492 | |||
| 493 | ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); | ||
| 494 | if (!ih) | ||
| 495 | goto out_unlock; | ||
| 496 | |||
| 497 | vtag = ct->proto.sctp.vtag[!dir]; | ||
| 498 | if (!ct->proto.sctp.init[!dir] && vtag && vtag != ih->init_tag) | ||
| 499 | goto out_unlock; | ||
| 500 | /* collision */ | ||
| 501 | if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir] && | ||
| 502 | vtag != ih->init_tag) | ||
| 503 | goto out_unlock; | ||
| 504 | |||
| 505 | pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); | ||
| 506 | ct->proto.sctp.vtag[!dir] = ih->init_tag; | ||
| 484 | } | 507 | } |
| 485 | 508 | ||
| 486 | ct->proto.sctp.state = new_state; | 509 | ct->proto.sctp.state = new_state; |
| @@ -7879,24 +7879,14 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info, · 7878 unmodified lines | |||
| 7879 | return nft_delobj(&ctx, obj); | 7879 | return nft_delobj(&ctx, obj); |
| 7880 | } | 7880 | } |
| 7881 | 7881 | ||
| 7882 | void nft_obj_notify(struct net *net, const struct nft_table *table, | 7882 | static void |
| 7883 | struct nft_object *obj, u32 portid, u32 seq, int event, | 7883 | __nft_obj_notify(struct net *net, const struct nft_table *table, |
| 7884 | u16 flags, int family, int report, gfp_t gfp) | 7884 | struct nft_object *obj, u32 portid, u32 seq, int event, |
| 7885 | u16 flags, int family, int report, gfp_t gfp) | ||
| 7885 | { | 7886 | { |
| 7886 | struct nftables_pernet *nft_net = nft_pernet(net); | 7887 | struct nftables_pernet *nft_net = nft_pernet(net); |
| 7887 | struct sk_buff *skb; | 7888 | struct sk_buff *skb; |
| 7888 | int err; | 7889 | int err; |
| 7889 | char *buf = kasprintf(gfp, "%s:%u", | ||
| 7890 | table->name, nft_net->base_seq); | ||
| 7891 | |||
| 7892 | audit_log_nfcfg(buf, | ||
| 7893 | family, | ||
| 7894 | obj->handle, | ||
| 7895 | event == NFT_MSG_NEWOBJ ? | ||
| 7896 | AUDIT_NFT_OP_OBJ_REGISTER : | ||
| 7897 | AUDIT_NFT_OP_OBJ_UNREGISTER, | ||
| 7898 | gfp); | ||
| 7899 | kfree(buf); | ||
| 7900 | 7890 | ||
| 7901 | if (!report && | 7891 | if (!report && |
| 7902 | !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) | 7892 | !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) |
| @@ -7919,13 +7909,35 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, · 16 unmodified lines | |||
| 7919 | err: | 7909 | err: |
| 7920 | nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS); | 7910 | nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS); |
| 7921 | } | 7911 | } |
| 7912 | |||
| 7913 | void nft_obj_notify(struct net *net, const struct nft_table *table, | ||
| 7914 | struct nft_object *obj, u32 portid, u32 seq, int event, | ||
| 7915 | u16 flags, int family, int report, gfp_t gfp) | ||
| 7916 | { | ||
| 7917 | struct nftables_pernet *nft_net = nft_pernet(net); | ||
| 7918 | char *buf = kasprintf(gfp, "%s:%u", | ||
| 7919 | table->name, nft_net->base_seq); | ||
| 7920 | |||
| 7921 | audit_log_nfcfg(buf, | ||
| 7922 | family, | ||
| 7923 | obj->handle, | ||
| 7924 | event == NFT_MSG_NEWOBJ ? | ||
| 7925 | AUDIT_NFT_OP_OBJ_REGISTER : | ||
| 7926 | AUDIT_NFT_OP_OBJ_UNREGISTER, | ||
| 7927 | gfp); | ||
| 7928 | kfree(buf); | ||
| 7929 | |||
| 7930 | __nft_obj_notify(net, table, obj, portid, seq, event, | ||
| 7931 | flags, family, report, gfp); | ||
| 7932 | } | ||
| 7922 | EXPORT_SYMBOL_GPL(nft_obj_notify); | 7933 | EXPORT_SYMBOL_GPL(nft_obj_notify); |
| 7923 | 7934 | ||
| 7924 | static void nf_tables_obj_notify(const struct nft_ctx *ctx, | 7935 | static void nf_tables_obj_notify(const struct nft_ctx *ctx, |
| 7925 | struct nft_object *obj, int event) | 7936 | struct nft_object *obj, int event) |
| 7926 | { | 7937 | { |
| 7927 | nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, | 7938 | __nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, |
| 7928 | ctx->flags, ctx->family, ctx->report, GFP_KERNEL); | 7939 | ctx->seq, event, ctx->flags, ctx->family, |
| 7940 | ctx->report, GFP_KERNEL); | ||
| 7929 | } | 7941 | } |
| 7930 | 7942 | ||
| 7931 | /* | 7943 | /* |
| @@ -154,6 +154,17 @@ int nft_payload_inner_offset(const struct nft_pktinfo *pkt) · 153 unmodified lines | |||
| 154 | return pkt->inneroff; | 154 | return pkt->inneroff; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static bool nft_payload_need_vlan_copy(const struct nft_payload *priv) | ||
| 158 | { | ||
| 159 | unsigned int len = priv->offset + priv->len; | ||
| 160 | |||
| 161 | /* data past ether src/dst requested, copy needed */ | ||
| 162 | if (len > offsetof(struct ethhdr, h_proto)) | ||
| 163 | return true; | ||
| 164 | |||
| 165 | return false; | ||
| 166 | } | ||
| 167 | |||
| 157 | void nft_payload_eval(const struct nft_expr *expr, | 168 | void nft_payload_eval(const struct nft_expr *expr, |
| 158 | struct nft_regs *regs, | 169 | struct nft_regs *regs, |
| 159 | const struct nft_pktinfo *pkt) | 170 | const struct nft_pktinfo *pkt) |
| @@ -172,7 +183,7 @@ void nft_payload_eval(const struct nft_expr *expr, · 12 unmodified lines | |||
| 172 | goto err; | 183 | goto err; |
| 173 | 184 | ||
| 174 | if (skb_vlan_tag_present(skb) && | 185 | if (skb_vlan_tag_present(skb) && |
| 175 | priv->offset >= offsetof(struct ethhdr, h_proto)) { | 186 | nft_payload_need_vlan_copy(priv)) { |
| 176 | if (!nft_payload_copy_vlan(dest, skb, | 187 | if (!nft_payload_copy_vlan(dest, skb, |
| 177 | priv->offset, priv->len)) | 188 | priv->offset, priv->len)) |
| 178 | goto err; | 189 | goto err; |
| @@ -233,10 +233,9 @@ static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set, · 232 unmodified lines | |||
| 233 | rb_erase(&rbe->node, &priv->root); | 233 | rb_erase(&rbe->node, &priv->root); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | static int nft_rbtree_gc_elem(const struct nft_set *__set, | 236 | static const struct nft_rbtree_elem * |
| 237 | struct nft_rbtree *priv, | 237 | nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv, |
| 238 | struct nft_rbtree_elem *rbe, | 238 | struct nft_rbtree_elem *rbe, u8 genmask) |
| 239 | u8 genmask) | ||
| 240 | { | 239 | { |
| 241 | struct nft_set *set = (struct nft_set *)__set; | 240 | struct nft_set *set = (struct nft_set *)__set; |
| 242 | struct rb_node *prev = rb_prev(&rbe->node); | 241 | struct rb_node *prev = rb_prev(&rbe->node); |
| @@ -246,7 +245,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, · 3 unmodified lines | |||
| 246 | 245 | ||
| 247 | gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC); | 246 | gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC); |
| 248 | if (!gc) | 247 | if (!gc) |
| 249 | return -ENOMEM; | 248 | return ERR_PTR(-ENOMEM); |
| 250 | 249 | ||
| 251 | /* search for end interval coming before this element. | 250 | /* search for end interval coming before this element. |
| 252 | * end intervals don't carry a timeout extension, they | 251 | * end intervals don't carry a timeout extension, they |
| @@ -261,6 +260,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, · 8 unmodified lines | |||
| 261 | prev = rb_prev(prev); | 260 | prev = rb_prev(prev); |
| 262 | } | 261 | } |
| 263 | 262 | ||
| 263 | rbe_prev = NULL; | ||
| 264 | if (prev) { | 264 | if (prev) { |
| 265 | rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); | 265 | rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); |
| 266 | nft_rbtree_gc_remove(net, set, priv, rbe_prev); | 266 | nft_rbtree_gc_remove(net, set, priv, rbe_prev); |
| @@ -272,7 +272,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, · 5 unmodified lines | |||
| 272 | */ | 272 | */ |
| 273 | gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); | 273 | gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); |
| 274 | if (WARN_ON_ONCE(!gc)) | 274 | if (WARN_ON_ONCE(!gc)) |
| 275 | return -ENOMEM; | 275 | return ERR_PTR(-ENOMEM); |
| 276 | 276 | ||
| 277 | nft_trans_gc_elem_add(gc, rbe_prev); | 277 | nft_trans_gc_elem_add(gc, rbe_prev); |
| 278 | } | 278 | } |
| @@ -280,13 +280,13 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set, · 1 unmodified line | |||
| 280 | nft_rbtree_gc_remove(net, set, priv, rbe); | 280 | nft_rbtree_gc_remove(net, set, priv, rbe); |
| 281 | gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); | 281 | gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); |
| 282 | if (WARN_ON_ONCE(!gc)) | 282 | if (WARN_ON_ONCE(!gc)) |
| 283 | return -ENOMEM; | 283 | return ERR_PTR(-ENOMEM); |
| 284 | 284 | ||
| 285 | nft_trans_gc_elem_add(gc, rbe); | 285 | nft_trans_gc_elem_add(gc, rbe); |
| 286 | 286 | ||
| 287 | nft_trans_gc_queue_sync_done(gc); | 287 | nft_trans_gc_queue_sync_done(gc); |
| 288 | 288 | ||
| 289 | return 0; | 289 | return rbe_prev; |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | static bool nft_rbtree_update_first(const struct nft_set *set, | 292 | static bool nft_rbtree_update_first(const struct nft_set *set, |
| @@ -314,7 +314,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, · 21 unmodified lines | |||
| 314 | struct nft_rbtree *priv = nft_set_priv(set); | 314 | struct nft_rbtree *priv = nft_set_priv(set); |
| 315 | u8 cur_genmask = nft_genmask_cur(net); | 315 | u8 cur_genmask = nft_genmask_cur(net); |
| 316 | u8 genmask = nft_genmask_next(net); | 316 | u8 genmask = nft_genmask_next(net); |
| 317 | int d, err; | 317 | int d; |
| 318 | 318 | ||
| 319 | /* Descend the tree to search for an existing element greater than the | 319 | /* Descend the tree to search for an existing element greater than the |
| 320 | * key value to insert that is greater than the new element. This is the | 320 | * key value to insert that is greater than the new element. This is the |
| @@ -363,9 +363,14 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, · 42 unmodified lines | |||
| 363 | */ | 363 | */ |
| 364 | if (nft_set_elem_expired(&rbe->ext) && | 364 | if (nft_set_elem_expired(&rbe->ext) && |
| 365 | nft_set_elem_active(&rbe->ext, cur_genmask)) { | 365 | nft_set_elem_active(&rbe->ext, cur_genmask)) { |
| 366 | err = nft_rbtree_gc_elem(set, priv, rbe, genmask); | 366 | const struct nft_rbtree_elem *removed_end; |
| 367 | if (err < 0) | 367 | |
| 368 | return err; | 368 | removed_end = nft_rbtree_gc_elem(set, priv, rbe, genmask); |
| 369 | if (IS_ERR(removed_end)) | ||
| 370 | return PTR_ERR(removed_end); | ||
| 371 | |||
| 372 | if (removed_end == rbe_le || removed_end == rbe_ge) | ||
| 373 | return -EAGAIN; | ||
| 369 | 374 | ||
| 370 | continue; | 375 | continue; |
| 371 | } | 376 | } |
| @@ -486,11 +491,18 @@ static int nft_rbtree_insert(const struct net *net, const struct nft_set *set, · 114 unmodified lines | |||
| 486 | struct nft_rbtree_elem *rbe = elem->priv; | 491 | struct nft_rbtree_elem *rbe = elem->priv; |
| 487 | int err; | 492 | int err; |
| 488 | 493 | ||
| 489 | write_lock_bh(&priv->lock); | 494 | do { |
| 490 | write_seqcount_begin(&priv->count); | 495 | if (fatal_signal_pending(current)) |
| 491 | err = __nft_rbtree_insert(net, set, rbe, ext); | 496 | return -EINTR; |
| 492 | write_seqcount_end(&priv->count); | 497 | |
| 493 | write_unlock_bh(&priv->lock); | 498 | cond_resched(); |
| 499 | |||
| 500 | write_lock_bh(&priv->lock); | ||
| 501 | write_seqcount_begin(&priv->count); | ||
| 502 | err = __nft_rbtree_insert(net, set, rbe, ext); | ||
| 503 | write_seqcount_end(&priv->count); | ||
| 504 | write_unlock_bh(&priv->lock); | ||
| 505 | } while (err == -EAGAIN); | ||
| 494 | 506 | ||
| 495 | return err; | 507 | return err; |
| 496 | } | 508 | } |
| @@ -352,7 +352,7 @@ static void netlink_overrun(struct sock *sk) · 351 unmodified lines | |||
| 352 | if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) { | 352 | if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) { |
| 353 | if (!test_and_set_bit(NETLINK_S_CONGESTED, | 353 | if (!test_and_set_bit(NETLINK_S_CONGESTED, |
| 354 | &nlk_sk(sk)->state)) { | 354 | &nlk_sk(sk)->state)) { |
| 355 | sk->sk_err = ENOBUFS; | 355 | WRITE_ONCE(sk->sk_err, ENOBUFS); |
| 356 | sk_error_report(sk); | 356 | sk_error_report(sk); |
| 357 | } | 357 | } |
| 358 | } | 358 | } |
| @@ -1605,7 +1605,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) · 1246 unmodified lines | |||
| 1605 | goto out; | 1605 | goto out; |
| 1606 | } | 1606 | } |
| 1607 | 1607 | ||
| 1608 | sk->sk_err = p->code; | 1608 | WRITE_ONCE(sk->sk_err, p->code); |
| 1609 | sk_error_report(sk); | 1609 | sk_error_report(sk); |
| 1610 | out: | 1610 | out: |
| 1611 | return ret; | 1611 | return ret; |
| @@ -1991,7 +1991,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, · 379 unmodified lines | |||
| 1991 | atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { | 1991 | atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { |
| 1992 | ret = netlink_dump(sk); | 1992 | ret = netlink_dump(sk); |
| 1993 | if (ret) { | 1993 | if (ret) { |
| 1994 | sk->sk_err = -ret; | 1994 | WRITE_ONCE(sk->sk_err, -ret); |
| 1995 | sk_error_report(sk); | 1995 | sk_error_report(sk); |
| 1996 | } | 1996 | } |
| 1997 | } | 1997 | } |
| @@ -2511,7 +2511,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, · 513 unmodified lines | |||
| 2511 | err_bad_put: | 2511 | err_bad_put: |
| 2512 | nlmsg_free(skb); | 2512 | nlmsg_free(skb); |
| 2513 | err_skb: | 2513 | err_skb: |
| 2514 | NETLINK_CB(in_skb).sk->sk_err = ENOBUFS; | 2514 | WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS); |
| 2515 | sk_error_report(NETLINK_CB(in_skb).sk); | 2515 | sk_error_report(NETLINK_CB(in_skb).sk); |
| 2516 | } | 2516 | } |
| 2517 | EXPORT_SYMBOL(netlink_ack); | 2517 | EXPORT_SYMBOL(netlink_ack); |
| @@ -1636,7 +1636,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) · 1635 unmodified lines | |||
| 1636 | timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0); | 1636 | timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0); |
| 1637 | INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work); | 1637 | INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work); |
| 1638 | 1638 | ||
| 1639 | spin_lock(&llcp_devices_lock); | ||
| 1639 | list_add(&local->list, &llcp_devices); | 1640 | list_add(&local->list, &llcp_devices); |
| 1641 | spin_unlock(&llcp_devices_lock); | ||
| 1640 | 1642 | ||
| 1641 | return 0; | 1643 | return 0; |
| 1642 | } | 1644 | } |
| @@ -145,7 +145,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp) · 144 unmodified lines | |||
| 145 | addrlen = sizeof(sin); | 145 | addrlen = sizeof(sin); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | ret = sock->ops->bind(sock, addr, addrlen); | 148 | ret = kernel_bind(sock, addr, addrlen); |
| 149 | if (ret) { | 149 | if (ret) { |
| 150 | rdsdebug("bind failed with %d at address %pI6c\n", | 150 | rdsdebug("bind failed with %d at address %pI6c\n", |
| 151 | ret, &conn->c_laddr); | 151 | ret, &conn->c_laddr); |
| @@ -173,7 +173,7 @@ int rds_tcp_conn_path_connect(struct rds_conn_path *cp) · 21 unmodified lines | |||
| 173 | * own the socket | 173 | * own the socket |
| 174 | */ | 174 | */ |
| 175 | rds_tcp_set_callbacks(sock, cp); | 175 | rds_tcp_set_callbacks(sock, cp); |
| 176 | ret = sock->ops->connect(sock, addr, addrlen, O_NONBLOCK); | 176 | ret = kernel_connect(sock, addr, addrlen, O_NONBLOCK); |
| 177 | 177 | ||
| 178 | rdsdebug("connect to address %pI6c returned %d\n", &conn->c_faddr, ret); | 178 | rdsdebug("connect to address %pI6c returned %d\n", &conn->c_faddr, ret); |
| 179 | if (ret == -EINPROGRESS) | 179 | if (ret == -EINPROGRESS) |
| @@ -306,7 +306,7 @@ struct socket *rds_tcp_listen_init(struct net *net, bool isv6) · 305 unmodified lines | |||
| 306 | addr_len = sizeof(*sin); | 306 | addr_len = sizeof(*sin); |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | ret = sock->ops->bind(sock, (struct sockaddr *)&ss, addr_len); | 309 | ret = kernel_bind(sock, (struct sockaddr *)&ss, addr_len); |
| 310 | if (ret < 0) { | 310 | if (ret < 0) { |
| 311 | rdsdebug("could not bind %s listener socket: %d\n", | 311 | rdsdebug("could not bind %s listener socket: %d\n", |
| 312 | isv6 ? "IPv6" : "IPv4", ret); | 312 | isv6 ? "IPv6" : "IPv4", ret); |
| @@ -48,6 +48,7 @@ struct rfkill { · 47 unmodified lines | |||
| 48 | bool persistent; | 48 | bool persistent; |
| 49 | bool polling_paused; | 49 | bool polling_paused; |
| 50 | bool suspended; | 50 | bool suspended; |
| 51 | bool need_sync; | ||
| 51 | 52 | ||
| 52 | const struct rfkill_ops *ops; | 53 | const struct rfkill_ops *ops; |
| 53 | void *data; | 54 | void *data; |
| @@ -368,6 +369,17 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked) · 314 unmodified lines | |||
| 368 | rfkill_event(rfkill); | 369 | rfkill_event(rfkill); |
| 369 | } | 370 | } |
| 370 | 371 | ||
| 372 | static void rfkill_sync(struct rfkill *rfkill) | ||
| 373 | { | ||
| 374 | lockdep_assert_held(&rfkill_global_mutex); | ||
| 375 | |||
| 376 | if (!rfkill->need_sync) | ||
| 377 | return; | ||
| 378 | |||
| 379 | rfkill_set_block(rfkill, rfkill_global_states[rfkill->type].cur); | ||
| 380 | rfkill->need_sync = false; | ||
| 381 | } | ||
| 382 | |||
| 371 | static void rfkill_update_global_state(enum rfkill_type type, bool blocked) | 383 | static void rfkill_update_global_state(enum rfkill_type type, bool blocked) |
| 372 | { | 384 | { |
| 373 | int i; | 385 | int i; |
| @@ -730,6 +742,10 @@ static ssize_t soft_show(struct device *dev, struct device_attribute *attr, · 356 unmodified lines | |||
| 730 | { | 742 | { |
| 731 | struct rfkill *rfkill = to_rfkill(dev); | 743 | struct rfkill *rfkill = to_rfkill(dev); |
| 732 | 744 | ||
| 745 | mutex_lock(&rfkill_global_mutex); | ||
| 746 | rfkill_sync(rfkill); | ||
| 747 | mutex_unlock(&rfkill_global_mutex); | ||
| 748 | |||
| 733 | return sysfs_emit(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0); | 749 | return sysfs_emit(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0); |
| 734 | } | 750 | } |
| 735 | 751 | ||
| @@ -751,6 +767,7 @@ static ssize_t soft_store(struct device *dev, struct device_attribute *attr, · 15 unmodified lines | |||
| 751 | return -EINVAL; | 767 | return -EINVAL; |
| 752 | 768 | ||
| 753 | mutex_lock(&rfkill_global_mutex); | 769 | mutex_lock(&rfkill_global_mutex); |
| 770 | rfkill_sync(rfkill); | ||
| 754 | rfkill_set_block(rfkill, state); | 771 | rfkill_set_block(rfkill, state); |
| 755 | mutex_unlock(&rfkill_global_mutex); | 772 | mutex_unlock(&rfkill_global_mutex); |
| 756 | 773 | ||
| @@ -783,6 +800,10 @@ static ssize_t state_show(struct device *dev, struct device_attribute *attr, · 26 unmodified lines | |||
| 783 | { | 800 | { |
| 784 | struct rfkill *rfkill = to_rfkill(dev); | 801 | struct rfkill *rfkill = to_rfkill(dev); |
| 785 | 802 | ||
| 803 | mutex_lock(&rfkill_global_mutex); | ||
| 804 | rfkill_sync(rfkill); | ||
| 805 | mutex_unlock(&rfkill_global_mutex); | ||
| 806 | |||
| 786 | return sysfs_emit(buf, "%d\n", user_state_from_blocked(rfkill->state)); | 807 | return sysfs_emit(buf, "%d\n", user_state_from_blocked(rfkill->state)); |
| 787 | } | 808 | } |
| 788 | 809 | ||
| @@ -805,6 +826,7 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, · 16 unmodified lines | |||
| 805 | return -EINVAL; | 826 | return -EINVAL; |
| 806 | 827 | ||
| 807 | mutex_lock(&rfkill_global_mutex); | 828 | mutex_lock(&rfkill_global_mutex); |
| 829 | rfkill_sync(rfkill); | ||
| 808 | rfkill_set_block(rfkill, state == RFKILL_USER_STATE_SOFT_BLOCKED); | 830 | rfkill_set_block(rfkill, state == RFKILL_USER_STATE_SOFT_BLOCKED); |
| 809 | mutex_unlock(&rfkill_global_mutex); | 831 | mutex_unlock(&rfkill_global_mutex); |
| 810 | 832 | ||
| @@ -1032,14 +1054,10 @@ static void rfkill_uevent_work(struct work_struct *work) · 221 unmodified lines | |||
| 1032 | 1054 | ||
| 1033 | static void rfkill_sync_work(struct work_struct *work) | 1055 | static void rfkill_sync_work(struct work_struct *work) |
| 1034 | { | 1056 | { |
| 1035 | struct rfkill *rfkill; | 1057 | struct rfkill *rfkill = container_of(work, struct rfkill, sync_work); |
| 1036 | bool cur; | ||
| 1037 | |||
| 1038 | rfkill = container_of(work, struct rfkill, sync_work); | ||
| 1039 | 1058 | ||
| 1040 | mutex_lock(&rfkill_global_mutex); | 1059 | mutex_lock(&rfkill_global_mutex); |
| 1041 | cur = rfkill_global_states[rfkill->type].cur; | 1060 | rfkill_sync(rfkill); |
| 1042 | rfkill_set_block(rfkill, cur); | ||
| 1043 | mutex_unlock(&rfkill_global_mutex); | 1061 | mutex_unlock(&rfkill_global_mutex); |
| 1044 | } | 1062 | } |
| 1045 | 1063 | ||
| @@ -1087,6 +1105,7 @@ int __must_check rfkill_register(struct rfkill *rfkill) · 41 unmodified lines | |||
| 1087 | round_jiffies_relative(POLL_INTERVAL)); | 1105 | round_jiffies_relative(POLL_INTERVAL)); |
| 1088 | 1106 | ||
| 1089 | if (!rfkill->persistent || rfkill_epo_lock_active) { | 1107 | if (!rfkill->persistent || rfkill_epo_lock_active) { |
| 1108 | rfkill->need_sync = true; | ||
| 1090 | schedule_work(&rfkill->sync_work); | 1109 | schedule_work(&rfkill->sync_work); |
| 1091 | } else { | 1110 | } else { |
| 1092 | #ifdef CONFIG_RFKILL_INPUT | 1111 | #ifdef CONFIG_RFKILL_INPUT |
| @@ -1171,6 +1190,7 @@ static int rfkill_fop_open(struct inode *inode, struct file *file) · 78 unmodified lines | |||
| 1171 | ev = kzalloc(sizeof(*ev), GFP_KERNEL); | 1190 | ev = kzalloc(sizeof(*ev), GFP_KERNEL); |
| 1172 | if (!ev) | 1191 | if (!ev) |
| 1173 | goto free; | 1192 | goto free; |
| 1193 | rfkill_sync(rfkill); | ||
| 1174 | rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD); | 1194 | rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD); |
| 1175 | list_add_tail(&ev->list, &data->events); | 1195 | list_add_tail(&ev->list, &data->events); |
| 1176 | } | 1196 | } |
| @@ -1159,8 +1159,7 @@ int sctp_assoc_update(struct sctp_association *asoc, · 1158 unmodified lines | |||
| 1159 | /* Add any peer addresses from the new association. */ | 1159 | /* Add any peer addresses from the new association. */ |
| 1160 | list_for_each_entry(trans, &new->peer.transport_addr_list, | 1160 | list_for_each_entry(trans, &new->peer.transport_addr_list, |
| 1161 | transports) | 1161 | transports) |
| 1162 | if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr) && | 1162 | if (!sctp_assoc_add_peer(asoc, &trans->ipaddr, |
| 1163 | !sctp_assoc_add_peer(asoc, &trans->ipaddr, | ||
| 1164 | GFP_ATOMIC, trans->state)) | 1163 | GFP_ATOMIC, trans->state)) |
| 1165 | return -ENOMEM; | 1164 | return -ENOMEM; |
| 1166 | 1165 | ||
| @@ -2450,6 +2450,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, · 2449 unmodified lines | |||
| 2450 | if (trans) { | 2450 | if (trans) { |
| 2451 | trans->hbinterval = | 2451 | trans->hbinterval = |
| 2452 | msecs_to_jiffies(params->spp_hbinterval); | 2452 | msecs_to_jiffies(params->spp_hbinterval); |
| 2453 | sctp_transport_reset_hb_timer(trans); | ||
| 2453 | } else if (asoc) { | 2454 | } else if (asoc) { |
| 2454 | asoc->hbinterval = | 2455 | asoc->hbinterval = |
| 2455 | msecs_to_jiffies(params->spp_hbinterval); | 2456 | msecs_to_jiffies(params->spp_hbinterval); |
| @@ -737,6 +737,14 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) · 736 unmodified lines | |||
| 737 | return ret; | 737 | return ret; |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | static int __sock_sendmsg(struct socket *sock, struct msghdr *msg) | ||
| 741 | { | ||
| 742 | int err = security_socket_sendmsg(sock, msg, | ||
| 743 | msg_data_left(msg)); | ||
| 744 | |||
| 745 | return err ?: sock_sendmsg_nosec(sock, msg); | ||
| 746 | } | ||
| 747 | |||
| 740 | /** | 748 | /** |
| 741 | * sock_sendmsg - send a message through @sock | 749 | * sock_sendmsg - send a message through @sock |
| 742 | * @sock: socket | 750 | * @sock: socket |
| @@ -747,10 +755,19 @@ static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) · 4 unmodified lines | |||
| 747 | */ | 755 | */ |
| 748 | int sock_sendmsg(struct socket *sock, struct msghdr *msg) | 756 | int sock_sendmsg(struct socket *sock, struct msghdr *msg) |
| 749 | { | 757 | { |
| 750 | int err = security_socket_sendmsg(sock, msg, | 758 | struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name; |
| 751 | msg_data_left(msg)); | 759 | struct sockaddr_storage address; |
| 760 | int ret; | ||
| 752 | 761 | ||
| 753 | return err ?: sock_sendmsg_nosec(sock, msg); | 762 | if (msg->msg_name) { |
| 763 | memcpy(&address, msg->msg_name, msg->msg_namelen); | ||
| 764 | msg->msg_name = &address; | ||
| 765 | } | ||
| 766 | |||
| 767 | ret = __sock_sendmsg(sock, msg); | ||
| 768 | msg->msg_name = save_addr; | ||
| 769 | |||
| 770 | return ret; | ||
| 754 | } | 771 | } |
| 755 | EXPORT_SYMBOL(sock_sendmsg); | 772 | EXPORT_SYMBOL(sock_sendmsg); |
| 756 | 773 | ||
| @@ -1138,7 +1155,7 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from) · 381 unmodified lines | |||
| 1138 | if (sock->type == SOCK_SEQPACKET) | 1155 | if (sock->type == SOCK_SEQPACKET) |
| 1139 | msg.msg_flags |= MSG_EOR; | 1156 | msg.msg_flags |= MSG_EOR; |
| 1140 | 1157 | ||
| 1141 | res = sock_sendmsg(sock, &msg); | 1158 | res = __sock_sendmsg(sock, &msg); |
| 1142 | *from = msg.msg_iter; | 1159 | *from = msg.msg_iter; |
| 1143 | return res; | 1160 | return res; |
| 1144 | } | 1161 | } |
| @@ -2174,7 +2191,7 @@ int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, · 1029 unmodified lines | |||
| 2174 | if (sock->file->f_flags & O_NONBLOCK) | 2191 | if (sock->file->f_flags & O_NONBLOCK) |
| 2175 | flags |= MSG_DONTWAIT; | 2192 | flags |= MSG_DONTWAIT; |
| 2176 | msg.msg_flags = flags; | 2193 | msg.msg_flags = flags; |
| 2177 | err = sock_sendmsg(sock, &msg); | 2194 | err = __sock_sendmsg(sock, &msg); |
| 2178 | 2195 | ||
| 2179 | out_put: | 2196 | out_put: |
| 2180 | fput_light(sock->file, fput_needed); | 2197 | fput_light(sock->file, fput_needed); |
| @@ -2538,7 +2555,7 @@ static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys, · 357 unmodified lines | |||
| 2538 | err = sock_sendmsg_nosec(sock, msg_sys); | 2555 | err = sock_sendmsg_nosec(sock, msg_sys); |
| 2539 | goto out_freectl; | 2556 | goto out_freectl; |
| 2540 | } | 2557 | } |
| 2541 | err = sock_sendmsg(sock, msg_sys); | 2558 | err = __sock_sendmsg(sock, msg_sys); |
| 2542 | /* | 2559 | /* |
| 2543 | * If this is sendmmsg() and sending to current destination address was | 2560 | * If this is sendmmsg() and sending to current destination address was |
| 2544 | * successful, remember it. | 2561 | * successful, remember it. |
| @@ -3499,7 +3516,12 @@ static long compat_sock_ioctl(struct file *file, unsigned int cmd, · 954 unmodified lines | |||
| 3499 | 3516 | ||
| 3500 | int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen) | 3517 | int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen) |
| 3501 | { | 3518 | { |
| 3502 | return READ_ONCE(sock->ops)->bind(sock, addr, addrlen); | 3519 | struct sockaddr_storage address; |
| 3520 | |||
| 3521 | memcpy(&address, addr, addrlen); | ||
| 3522 | |||
| 3523 | return READ_ONCE(sock->ops)->bind(sock, (struct sockaddr *)&address, | ||
| 3524 | addrlen); | ||
| 3503 | } | 3525 | } |
| 3504 | EXPORT_SYMBOL(kernel_bind); | 3526 | EXPORT_SYMBOL(kernel_bind); |
| 3505 | 3527 | ||
| @@ -769,9 +769,14 @@ int rpcauth_wrap_req(struct rpc_task *task, struct xdr_stream *xdr) · 768 unmodified lines | |||
| 769 | * @task: controlling RPC task | 769 | * @task: controlling RPC task |
| 770 | * @xdr: xdr_stream containing RPC Reply header | 770 | * @xdr: xdr_stream containing RPC Reply header |
| 771 | * | 771 | * |
| 772 | * On success, @xdr is updated to point past the verifier and | 772 | * Return values: |
| 773 | * zero is returned. Otherwise, @xdr is in an undefined state | 773 | * %0: Verifier is valid. @xdr now points past the verifier. |
| 774 | * and a negative errno is returned. | 774 | * %-EIO: Verifier is corrupted or message ended early. |
| 775 | * %-EACCES: Verifier is intact but not valid. | ||
| 776 | * %-EPROTONOSUPPORT: Server does not support the requested auth type. | ||
| 777 | * | ||
| 778 | * When a negative errno is returned, @xdr is left in an undefined | ||
| 779 | * state. | ||
| 775 | */ | 780 | */ |
| 776 | int | 781 | int |
| 777 | rpcauth_checkverf(struct rpc_task *task, struct xdr_stream *xdr) | 782 | rpcauth_checkverf(struct rpc_task *task, struct xdr_stream *xdr) |
| @@ -129,9 +129,9 @@ static int tls_validate(struct rpc_task *task, struct xdr_stream *xdr) · 128 unmodified lines | |||
| 129 | if (*p != rpc_auth_null) | 129 | if (*p != rpc_auth_null) |
| 130 | return -EIO; | 130 | return -EIO; |
| 131 | if (xdr_stream_decode_opaque_inline(xdr, &str, starttls_len) != starttls_len) | 131 | if (xdr_stream_decode_opaque_inline(xdr, &str, starttls_len) != starttls_len) |
| 132 | return -EIO; | 132 | return -EPROTONOSUPPORT; |
| 133 | if (memcmp(str, starttls_token, starttls_len)) | 133 | if (memcmp(str, starttls_token, starttls_len)) |
| 134 | return -EIO; | 134 | return -EPROTONOSUPPORT; |
| 135 | return 0; | 135 | return 0; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| @@ -2476,8 +2476,7 @@ call_status(struct rpc_task *task) · 2475 unmodified lines | |||
| 2476 | goto out_exit; | 2476 | goto out_exit; |
| 2477 | } | 2477 | } |
| 2478 | task->tk_action = call_encode; | 2478 | task->tk_action = call_encode; |
| 2479 | if (status != -ECONNRESET && status != -ECONNABORTED) | 2479 | rpc_check_timeout(task); |
| 2480 | rpc_check_timeout(task); | ||
| 2481 | return; | 2480 | return; |
| 2482 | out_exit: | 2481 | out_exit: |
| 2483 | rpc_call_rpcerror(task, status); | 2482 | rpc_call_rpcerror(task, status); |
| @@ -2725,7 +2724,15 @@ out_unparsable: · 241 unmodified lines | |||
| 2725 | 2724 | ||
| 2726 | out_verifier: | 2725 | out_verifier: |
| 2727 | trace_rpc_bad_verifier(task); | 2726 | trace_rpc_bad_verifier(task); |
| 2728 | goto out_garbage; | 2727 | switch (error) { |
| 2728 | case -EPROTONOSUPPORT: | ||
| 2729 | goto out_err; | ||
| 2730 | case -EACCES: | ||
| 2731 | /* Re-encode with a fresh cred */ | ||
| 2732 | fallthrough; | ||
| 2733 | default: | ||
| 2734 | goto out_garbage; | ||
| 2735 | } | ||
| 2729 | 2736 | ||
| 2730 | out_msg_denied: | 2737 | out_msg_denied: |
| 2731 | error = -EACCES; | 2738 | error = -EACCES; |
| @@ -2672,6 +2672,10 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work) · 2671 unmodified lines | |||
| 2672 | rcu_read_lock(); | 2672 | rcu_read_lock(); |
| 2673 | lower_xprt = rcu_dereference(lower_clnt->cl_xprt); | 2673 | lower_xprt = rcu_dereference(lower_clnt->cl_xprt); |
| 2674 | rcu_read_unlock(); | 2674 | rcu_read_unlock(); |
| 2675 | |||
| 2676 | if (wait_on_bit_lock(&lower_xprt->state, XPRT_LOCKED, TASK_KILLABLE)) | ||
| 2677 | goto out_unlock; | ||
| 2678 | |||
| 2675 | status = xs_tls_handshake_sync(lower_xprt, &upper_xprt->xprtsec); | 2679 | status = xs_tls_handshake_sync(lower_xprt, &upper_xprt->xprtsec); |
| 2676 | if (status) { | 2680 | if (status) { |
| 2677 | trace_rpc_tls_not_started(upper_clnt, upper_xprt); | 2681 | trace_rpc_tls_not_started(upper_clnt, upper_xprt); |
| @@ -2681,6 +2685,7 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work) · 3 unmodified lines | |||
| 2681 | status = xs_tcp_tls_finish_connecting(lower_xprt, upper_transport); | 2685 | status = xs_tcp_tls_finish_connecting(lower_xprt, upper_transport); |
| 2682 | if (status) | 2686 | if (status) |
| 2683 | goto out_close; | 2687 | goto out_close; |
| 2688 | xprt_release_write(lower_xprt, NULL); | ||
| 2684 | 2689 | ||
| 2685 | trace_rpc_socket_connect(upper_xprt, upper_transport->sock, 0); | 2690 | trace_rpc_socket_connect(upper_xprt, upper_transport->sock, 0); |
| 2686 | if (!xprt_test_and_set_connected(upper_xprt)) { | 2691 | if (!xprt_test_and_set_connected(upper_xprt)) { |
| @@ -2702,6 +2707,7 @@ out_unlock: · 15 unmodified lines | |||
| 2702 | return; | 2707 | return; |
| 2703 | 2708 | ||
| 2704 | out_close: | 2709 | out_close: |
| 2710 | xprt_release_write(lower_xprt, NULL); | ||
| 2705 | rpc_shutdown_client(lower_clnt); | 2711 | rpc_shutdown_client(lower_clnt); |
| 2706 | 2712 | ||
| 2707 | /* xprt_force_disconnect() wakes tasks with a fixed tk_status code. | 2713 | /* xprt_force_disconnect() wakes tasks with a fixed tk_status code. |
| @@ -1441,14 +1441,14 @@ static int tipc_crypto_key_revoke(struct net *net, u8 tx_key) · 1440 unmodified lines | |||
| 1441 | struct tipc_crypto *tx = tipc_net(net)->crypto_tx; | 1441 | struct tipc_crypto *tx = tipc_net(net)->crypto_tx; |
| 1442 | struct tipc_key key; | 1442 | struct tipc_key key; |
| 1443 | 1443 | ||
| 1444 | spin_lock(&tx->lock); | 1444 | spin_lock_bh(&tx->lock); |
| 1445 | key = tx->key; | 1445 | key = tx->key; |
| 1446 | WARN_ON(!key.active || tx_key != key.active); | 1446 | WARN_ON(!key.active || tx_key != key.active); |
| 1447 | 1447 | ||
| 1448 | /* Free the active key */ | 1448 | /* Free the active key */ |
| 1449 | tipc_crypto_key_set_state(tx, key.passive, 0, key.pending); | 1449 | tipc_crypto_key_set_state(tx, key.passive, 0, key.pending); |
| 1450 | tipc_crypto_key_detach(tx->aead[key.active], &tx->lock); | 1450 | tipc_crypto_key_detach(tx->aead[key.active], &tx->lock); |
| 1451 | spin_unlock(&tx->lock); | 1451 | spin_unlock_bh(&tx->lock); |
| 1452 | 1452 | ||
| 1453 | pr_warn("%s: key is revoked\n", tx->name); | 1453 | pr_warn("%s: key is revoked\n", tx->name); |
| 1454 | return -EKEYREVOKED; | 1454 | return -EKEYREVOKED; |
| @@ -1181,16 +1181,11 @@ void wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy, bool blocked, · 1180 unmodified lines | |||
| 1181 | } | 1181 | } |
| 1182 | EXPORT_SYMBOL(wiphy_rfkill_set_hw_state_reason); | 1182 | EXPORT_SYMBOL(wiphy_rfkill_set_hw_state_reason); |
| 1183 | 1183 | ||
| 1184 | void cfg80211_cqm_config_free(struct wireless_dev *wdev) | ||
| 1185 | { | ||
| 1186 | kfree(wdev->cqm_config); | ||
| 1187 | wdev->cqm_config = NULL; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, | 1184 | static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, |
| 1191 | bool unregister_netdev) | 1185 | bool unregister_netdev) |
| 1192 | { | 1186 | { |
| 1193 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 1187 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
| 1188 | struct cfg80211_cqm_config *cqm_config; | ||
| 1194 | unsigned int link_id; | 1189 | unsigned int link_id; |
| 1195 | 1190 | ||
| 1196 | ASSERT_RTNL(); | 1191 | ASSERT_RTNL(); |
| @@ -1227,7 +1222,10 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, · 30 unmodified lines | |||
| 1227 | kfree_sensitive(wdev->wext.keys); | 1222 | kfree_sensitive(wdev->wext.keys); |
| 1228 | wdev->wext.keys = NULL; | 1223 | wdev->wext.keys = NULL; |
| 1229 | #endif | 1224 | #endif |
| 1230 | cfg80211_cqm_config_free(wdev); | 1225 | wiphy_work_cancel(wdev->wiphy, &wdev->cqm_rssi_work); |
| 1226 | /* deleted from the list, so can't be found from nl80211 any more */ | ||
| 1227 | cqm_config = rcu_access_pointer(wdev->cqm_config); | ||
| 1228 | kfree_rcu(cqm_config, rcu_head); | ||
| 1231 | 1229 | ||
| 1232 | /* | 1230 | /* |
| 1233 | * Ensure that all events have been processed and | 1231 | * Ensure that all events have been processed and |
| @@ -1379,6 +1377,8 @@ void cfg80211_init_wdev(struct wireless_dev *wdev) · 145 unmodified lines | |||
| 1379 | wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; | 1377 | wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; |
| 1380 | #endif | 1378 | #endif |
| 1381 | 1379 | ||
| 1380 | wiphy_work_init(&wdev->cqm_rssi_work, cfg80211_cqm_rssi_notify_work); | ||
| 1381 | |||
| 1382 | if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT) | 1382 | if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT) |
| 1383 | wdev->ps = true; | 1383 | wdev->ps = true; |
| 1384 | else | 1384 | else |
| @@ -295,12 +295,17 @@ struct cfg80211_beacon_registration { · 294 unmodified lines | |||
| 295 | }; | 295 | }; |
| 296 | 296 | ||
| 297 | struct cfg80211_cqm_config { | 297 | struct cfg80211_cqm_config { |
| 298 | struct rcu_head rcu_head; | ||
| 298 | u32 rssi_hyst; | 299 | u32 rssi_hyst; |
| 299 | s32 last_rssi_event_value; | 300 | s32 last_rssi_event_value; |
| 301 | enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; | ||
| 300 | int n_rssi_thresholds; | 302 | int n_rssi_thresholds; |
| 301 | s32 rssi_thresholds[] __counted_by(n_rssi_thresholds); | 303 | s32 rssi_thresholds[] __counted_by(n_rssi_thresholds); |
| 302 | }; | 304 | }; |
| 303 | 305 | ||
| 306 | void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, | ||
| 307 | struct wiphy_work *work); | ||
| 308 | |||
| 304 | void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev); | 309 | void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev); |
| 305 | 310 | ||
| 306 | /* free object */ | 311 | /* free object */ |
| @@ -566,8 +571,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, · 259 unmodified lines | |||
| 566 | #define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; }) | 571 | #define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; }) |
| 567 | #endif | 572 | #endif |
| 568 | 573 | ||
| 569 | void cfg80211_cqm_config_free(struct wireless_dev *wdev); | ||
| 570 | |||
| 571 | void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid); | 574 | void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid); |
| 572 | void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev); | 575 | void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev); |
| 573 | void cfg80211_pmsr_free_wk(struct work_struct *work); | 576 | void cfg80211_pmsr_free_wk(struct work_struct *work); |
| @@ -52,7 +52,8 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, · 51 unmodified lines | |||
| 52 | cr.links[link_id].bssid = data->links[link_id].bss->bssid; | 52 | cr.links[link_id].bssid = data->links[link_id].bss->bssid; |
| 53 | cr.links[link_id].addr = data->links[link_id].addr; | 53 | cr.links[link_id].addr = data->links[link_id].addr; |
| 54 | /* need to have local link addresses for MLO connections */ | 54 | /* need to have local link addresses for MLO connections */ |
| 55 | WARN_ON(cr.ap_mld_addr && !cr.links[link_id].addr); | 55 | WARN_ON(cr.ap_mld_addr && |
| 56 | !is_valid_ether_addr(cr.links[link_id].addr)); | ||
| 56 | 57 | ||
| 57 | BUG_ON(!cr.links[link_id].bss->channel); | 58 | BUG_ON(!cr.links[link_id].bss->channel); |
| 58 | 59 | ||
| @@ -5909,6 +5909,21 @@ out: · 5908 unmodified lines | |||
| 5909 | nlmsg_free(msg); | 5909 | nlmsg_free(msg); |
| 5910 | } | 5910 | } |
| 5911 | 5911 | ||
| 5912 | static int nl80211_validate_ap_phy_operation(struct cfg80211_ap_settings *params) | ||
| 5913 | { | ||
| 5914 | struct ieee80211_channel *channel = params->chandef.chan; | ||
| 5915 | |||
| 5916 | if ((params->he_cap || params->he_oper) && | ||
| 5917 | (channel->flags & IEEE80211_CHAN_NO_HE)) | ||
| 5918 | return -EOPNOTSUPP; | ||
| 5919 | |||
| 5920 | if ((params->eht_cap || params->eht_oper) && | ||
| 5921 | (channel->flags & IEEE80211_CHAN_NO_EHT)) | ||
| 5922 | return -EOPNOTSUPP; | ||
| 5923 | |||
| 5924 | return 0; | ||
| 5925 | } | ||
| 5926 | |||
| 5912 | static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | 5927 | static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) |
| 5913 | { | 5928 | { |
| 5914 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5929 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| @@ -6178,6 +6193,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) · 263 unmodified lines | |||
| 6178 | if (err) | 6193 | if (err) |
| 6179 | goto out_unlock; | 6194 | goto out_unlock; |
| 6180 | 6195 | ||
| 6196 | err = nl80211_validate_ap_phy_operation(params); | ||
| 6197 | if (err) | ||
| 6198 | goto out_unlock; | ||
| 6199 | |||
| 6181 | if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]) | 6200 | if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]) |
| 6182 | params->flags = nla_get_u32( | 6201 | params->flags = nla_get_u32( |
| 6183 | info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]); | 6202 | info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]); |
| @@ -8482,7 +8501,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, · 2298 unmodified lines | |||
| 8482 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 8501 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| 8483 | struct net_device *dev = info->user_ptr[1]; | 8502 | struct net_device *dev = info->user_ptr[1]; |
| 8484 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 8503 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
| 8485 | struct mesh_config cfg; | 8504 | struct mesh_config cfg = {}; |
| 8486 | u32 mask; | 8505 | u32 mask; |
| 8487 | int err; | 8506 | int err; |
| 8488 | 8507 | ||
| @@ -12796,7 +12815,8 @@ static int nl80211_set_cqm_txe(struct genl_info *info, · 4307 unmodified lines | |||
| 12796 | } | 12815 | } |
| 12797 | 12816 | ||
| 12798 | static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, | 12817 | static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, |
| 12799 | struct net_device *dev) | 12818 | struct net_device *dev, |
| 12819 | struct cfg80211_cqm_config *cqm_config) | ||
| 12800 | { | 12820 | { |
| 12801 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 12821 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
| 12802 | s32 last, low, high; | 12822 | s32 last, low, high; |
| @@ -12805,7 +12825,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, · 2 unmodified lines | |||
| 12805 | int err; | 12825 | int err; |
| 12806 | 12826 | ||
| 12807 | /* RSSI reporting disabled? */ | 12827 | /* RSSI reporting disabled? */ |
| 12808 | if (!wdev->cqm_config) | 12828 | if (!cqm_config) |
| 12809 | return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); | 12829 | return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); |
| 12810 | 12830 | ||
| 12811 | /* | 12831 | /* |
| @@ -12814,7 +12834,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, · 2 unmodified lines | |||
| 12814 | * connection is established and enough beacons received to calculate | 12834 | * connection is established and enough beacons received to calculate |
| 12815 | * the average. | 12835 | * the average. |
| 12816 | */ | 12836 | */ |
| 12817 | if (!wdev->cqm_config->last_rssi_event_value && | 12837 | if (!cqm_config->last_rssi_event_value && |
| 12818 | wdev->links[0].client.current_bss && | 12838 | wdev->links[0].client.current_bss && |
| 12819 | rdev->ops->get_station) { | 12839 | rdev->ops->get_station) { |
| 12820 | struct station_info sinfo = {}; | 12840 | struct station_info sinfo = {}; |
| @@ -12828,30 +12848,30 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, · 7 unmodified lines | |||
| 12828 | 12848 | ||
| 12829 | cfg80211_sinfo_release_content(&sinfo); | 12849 | cfg80211_sinfo_release_content(&sinfo); |
| 12830 | if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG)) | 12850 | if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG)) |
| 12831 | wdev->cqm_config->last_rssi_event_value = | 12851 | cqm_config->last_rssi_event_value = |
| 12832 | (s8) sinfo.rx_beacon_signal_avg; | 12852 | (s8) sinfo.rx_beacon_signal_avg; |
| 12833 | } | 12853 | } |
| 12834 | 12854 | ||
| 12835 | last = wdev->cqm_config->last_rssi_event_value; | 12855 | last = cqm_config->last_rssi_event_value; |
| 12836 | hyst = wdev->cqm_config->rssi_hyst; | 12856 | hyst = cqm_config->rssi_hyst; |
| 12837 | n = wdev->cqm_config->n_rssi_thresholds; | 12857 | n = cqm_config->n_rssi_thresholds; |
| 12838 | 12858 | ||
| 12839 | for (i = 0; i < n; i++) { | 12859 | for (i = 0; i < n; i++) { |
| 12840 | i = array_index_nospec(i, n); | 12860 | i = array_index_nospec(i, n); |
| 12841 | if (last < wdev->cqm_config->rssi_thresholds[i]) | 12861 | if (last < cqm_config->rssi_thresholds[i]) |
| 12842 | break; | 12862 | break; |
| 12843 | } | 12863 | } |
| 12844 | 12864 | ||
| 12845 | low_index = i - 1; | 12865 | low_index = i - 1; |
| 12846 | if (low_index >= 0) { | 12866 | if (low_index >= 0) { |
| 12847 | low_index = array_index_nospec(low_index, n); | 12867 | low_index = array_index_nospec(low_index, n); |
| 12848 | low = wdev->cqm_config->rssi_thresholds[low_index] - hyst; | 12868 | low = cqm_config->rssi_thresholds[low_index] - hyst; |
| 12849 | } else { | 12869 | } else { |
| 12850 | low = S32_MIN; | 12870 | low = S32_MIN; |
| 12851 | } | 12871 | } |
| 12852 | if (i < n) { | 12872 | if (i < n) { |
| 12853 | i = array_index_nospec(i, n); | 12873 | i = array_index_nospec(i, n); |
| 12854 | high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1; | 12874 | high = cqm_config->rssi_thresholds[i] + hyst - 1; |
| 12855 | } else { | 12875 | } else { |
| 12856 | high = S32_MAX; | 12876 | high = S32_MAX; |
| 12857 | } | 12877 | } |
| @@ -12864,6 +12884,7 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, · 6 unmodified lines | |||
| 12864 | u32 hysteresis) | 12884 | u32 hysteresis) |
| 12865 | { | 12885 | { |
| 12866 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 12886 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| 12887 | struct cfg80211_cqm_config *cqm_config = NULL, *old; | ||
| 12867 | struct net_device *dev = info->user_ptr[1]; | 12888 | struct net_device *dev = info->user_ptr[1]; |
| 12868 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 12889 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
| 12869 | int i, err; | 12890 | int i, err; |
| @@ -12881,10 +12902,6 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, · 11 unmodified lines | |||
| 12881 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) | 12902 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) |
| 12882 | return -EOPNOTSUPP; | 12903 | return -EOPNOTSUPP; |
| 12883 | 12904 | ||
| 12884 | wdev_lock(wdev); | ||
| 12885 | cfg80211_cqm_config_free(wdev); | ||
| 12886 | wdev_unlock(wdev); | ||
| 12887 | |||
| 12888 | if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { | 12905 | if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { |
| 12889 | if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ | 12906 | if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ |
| 12890 | return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); | 12907 | return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); |
| @@ -12901,9 +12918,10 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, · 10 unmodified lines | |||
| 12901 | n_thresholds = 0; | 12918 | n_thresholds = 0; |
| 12902 | 12919 | ||
| 12903 | wdev_lock(wdev); | 12920 | wdev_lock(wdev); |
| 12904 | if (n_thresholds) { | 12921 | old = rcu_dereference_protected(wdev->cqm_config, |
| 12905 | struct cfg80211_cqm_config *cqm_config; | 12922 | lockdep_is_held(&wdev->mtx)); |
| 12906 | 12923 | ||
| 12924 | if (n_thresholds) { | ||
| 12907 | cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, | 12925 | cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, |
| 12908 | n_thresholds), | 12926 | n_thresholds), |
| 12909 | GFP_KERNEL); | 12927 | GFP_KERNEL); |
| @@ -12918,11 +12936,18 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, · 8 unmodified lines | |||
| 12918 | flex_array_size(cqm_config, rssi_thresholds, | 12936 | flex_array_size(cqm_config, rssi_thresholds, |
| 12919 | n_thresholds)); | 12937 | n_thresholds)); |
| 12920 | 12938 | ||
| 12921 | wdev->cqm_config = cqm_config; | 12939 | rcu_assign_pointer(wdev->cqm_config, cqm_config); |
| 12940 | } else { | ||
| 12941 | RCU_INIT_POINTER(wdev->cqm_config, NULL); | ||
| 12922 | } | 12942 | } |
| 12923 | 12943 | ||
| 12924 | err = cfg80211_cqm_rssi_update(rdev, dev); | 12944 | err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); |
| 12925 | 12945 | if (err) { | |
| 12946 | rcu_assign_pointer(wdev->cqm_config, old); | ||
| 12947 | kfree_rcu(cqm_config, rcu_head); | ||
| 12948 | } else { | ||
| 12949 | kfree_rcu(old, rcu_head); | ||
| 12950 | } | ||
| 12926 | unlock: | 12951 | unlock: |
| 12927 | wdev_unlock(wdev); | 12952 | wdev_unlock(wdev); |
| 12928 | 12953 | ||
| @@ -19073,9 +19098,8 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, · 6144 unmodified lines | |||
| 19073 | enum nl80211_cqm_rssi_threshold_event rssi_event, | 19098 | enum nl80211_cqm_rssi_threshold_event rssi_event, |
| 19074 | s32 rssi_level, gfp_t gfp) | 19099 | s32 rssi_level, gfp_t gfp) |
| 19075 | { | 19100 | { |
| 19076 | struct sk_buff *msg; | ||
| 19077 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 19101 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
| 19078 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 19102 | struct cfg80211_cqm_config *cqm_config; |
| 19079 | 19103 | ||
| 19080 | trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level); | 19104 | trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level); |
| 19081 | 19105 | ||
| @@ -19083,18 +19107,41 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, · 1 unmodified line | |||
| 19083 | rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)) | 19107 | rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)) |
| 19084 | return; | 19108 | return; |
| 19085 | 19109 | ||
| 19086 | if (wdev->cqm_config) { | 19110 | rcu_read_lock(); |
| 19087 | wdev->cqm_config->last_rssi_event_value = rssi_level; | 19111 | cqm_config = rcu_dereference(wdev->cqm_config); |
| 19112 | if (cqm_config) { | ||
| 19113 | cqm_config->last_rssi_event_value = rssi_level; | ||
| 19114 | cqm_config->last_rssi_event_type = rssi_event; | ||
| 19115 | wiphy_work_queue(wdev->wiphy, &wdev->cqm_rssi_work); | ||
| 19116 | } | ||
| 19117 | rcu_read_unlock(); | ||
| 19118 | } | ||
| 19119 | EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); | ||
| 19088 | 19120 | ||
| 19089 | cfg80211_cqm_rssi_update(rdev, dev); | 19121 | void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work) |
| 19122 | { | ||
| 19123 | struct wireless_dev *wdev = container_of(work, struct wireless_dev, | ||
| 19124 | cqm_rssi_work); | ||
| 19125 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | ||
| 19126 | enum nl80211_cqm_rssi_threshold_event rssi_event; | ||
| 19127 | struct cfg80211_cqm_config *cqm_config; | ||
| 19128 | struct sk_buff *msg; | ||
| 19129 | s32 rssi_level; | ||
| 19090 | 19130 | ||
| 19091 | if (rssi_level == 0) | 19131 | wdev_lock(wdev); |
| 19092 | rssi_level = wdev->cqm_config->last_rssi_event_value; | 19132 | cqm_config = rcu_dereference_protected(wdev->cqm_config, |
| 19093 | } | 19133 | lockdep_is_held(&wdev->mtx)); |
| 19134 | if (!wdev->cqm_config) | ||
| 19135 | goto unlock; | ||
| 19094 | 19136 | ||
| 19095 | msg = cfg80211_prepare_cqm(dev, NULL, gfp); | 19137 | cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); |
| 19138 | |||
| 19139 | rssi_level = cqm_config->last_rssi_event_value; | ||
| 19140 | rssi_event = cqm_config->last_rssi_event_type; | ||
| 19141 | |||
| 19142 | msg = cfg80211_prepare_cqm(wdev->netdev, NULL, GFP_KERNEL); | ||
| 19096 | if (!msg) | 19143 | if (!msg) |
| 19097 | return; | 19144 | goto unlock; |
| 19098 | 19145 | ||
| 19099 | if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, | 19146 | if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, |
| 19100 | rssi_event)) | 19147 | rssi_event)) |
| @@ -19104,14 +19151,15 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, · 3 unmodified lines | |||
| 19104 | rssi_level)) | 19151 | rssi_level)) |
| 19105 | goto nla_put_failure; | 19152 | goto nla_put_failure; |
| 19106 | 19153 | ||
| 19107 | cfg80211_send_cqm(msg, gfp); | 19154 | cfg80211_send_cqm(msg, GFP_KERNEL); |
| 19108 | 19155 | ||
| 19109 | return; | 19156 | goto unlock; |
| 19110 | 19157 | ||
| 19111 | nla_put_failure: | 19158 | nla_put_failure: |
| 19112 | nlmsg_free(msg); | 19159 | nlmsg_free(msg); |
| 19160 | unlock: | ||
| 19161 | wdev_unlock(wdev); | ||
| 19113 | } | 19162 | } |
| 19114 | EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); | ||
| 19115 | 19163 | ||
| 19116 | void cfg80211_cqm_txe_notify(struct net_device *dev, | 19164 | void cfg80211_cqm_txe_notify(struct net_device *dev, |
| 19117 | const u8 *peer, u32 num_packets, | 19165 | const u8 *peer, u32 num_packets, |
| @@ -908,6 +908,10 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev) · 907 unmodified lines | |||
| 908 | !cfg80211_find_ssid_match(ap, request)) | 908 | !cfg80211_find_ssid_match(ap, request)) |
| 909 | continue; | 909 | continue; |
| 910 | 910 | ||
| 911 | if (!is_broadcast_ether_addr(request->bssid) && | ||
| 912 | !ether_addr_equal(request->bssid, ap->bssid)) | ||
| 913 | continue; | ||
| 914 | |||
| 911 | if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid) | 915 | if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid) |
| 912 | continue; | 916 | continue; |
| 913 | 917 | ||
| @@ -144,7 +144,7 @@ endif · 143 unmodified lines | |||
| 144 | quiet_cmd_gzip = GZIP $@ | 144 | quiet_cmd_gzip = GZIP $@ |
| 145 | cmd_gzip = $(KGZIP) -n -f $< | 145 | cmd_gzip = $(KGZIP) -n -f $< |
| 146 | quiet_cmd_xz = XZ $@ | 146 | quiet_cmd_xz = XZ $@ |
| 147 | cmd_xz = $(XZ) --lzma2=dict=2MiB -f $< | 147 | cmd_xz = $(XZ) --check=crc32 --lzma2=dict=1MiB -f $< |
| 148 | quiet_cmd_zstd = ZSTD $@ | 148 | quiet_cmd_zstd = ZSTD $@ |
| 149 | cmd_zstd = $(ZSTD) -T0 --rm -f -q $< | 149 | cmd_zstd = $(ZSTD) -T0 --rm -f -q $< |
| 150 | 150 | ||
| @@ -102,7 +102,7 @@ gen_proto_order_variant() · 101 unmodified lines | |||
| 102 | fi | 102 | fi |
| 103 | 103 | ||
| 104 | # Allow ACQUIRE/RELEASE/RELAXED ops to be defined in terms of FULL ops | 104 | # Allow ACQUIRE/RELEASE/RELAXED ops to be defined in terms of FULL ops |
| 105 | if [ ! -z "${order}" ]; then | 105 | if [ ! -z "${order}" ] && ! meta_is_implicitly_relaxed "${meta}"; then |
| 106 | printf "#elif defined(arch_${basename})\n" | 106 | printf "#elif defined(arch_${basename})\n" |
| 107 | printf "\t${retstmt}arch_${basename}(${args});\n" | 107 | printf "\t${retstmt}arch_${basename}(${args});\n" |
| 108 | fi | 108 | fi |
| @@ -111,12 +111,11 @@ lx-symbols command.""" · 110 unmodified lines | |||
| 111 | return "{textaddr} {sections}".format( | 111 | return "{textaddr} {sections}".format( |
| 112 | textaddr=textaddr, sections="".join(args)) | 112 | textaddr=textaddr, sections="".join(args)) |
| 113 | 113 | ||
| 114 | def load_module_symbols(self, module, module_file=None): | 114 | def load_module_symbols(self, module): |
| 115 | module_name = module['name'].string() | 115 | module_name = module['name'].string() |
| 116 | module_addr = str(module['mem'][constants.LX_MOD_TEXT]['base']).split()[0] | 116 | module_addr = str(module['mem'][constants.LX_MOD_TEXT]['base']).split()[0] |
| 117 | 117 | ||
| 118 | if not module_file: | 118 | module_file = self._get_module_file(module_name) |
| 119 | module_file = self._get_module_file(module_name) | ||
| 120 | if not module_file and not self.module_files_updated: | 119 | if not module_file and not self.module_files_updated: |
| 121 | self._update_module_files() | 120 | self._update_module_files() |
| 122 | module_file = self._get_module_file(module_name) | 121 | module_file = self._get_module_file(module_name) |
| @@ -139,19 +138,6 @@ lx-symbols command.""" · 16 unmodified lines | |||
| 139 | else: | 138 | else: |
| 140 | gdb.write("no module object found for '{0}'\n".format(module_name)) | 139 | gdb.write("no module object found for '{0}'\n".format(module_name)) |
| 141 | 140 | ||
| 142 | def load_ko_symbols(self, mod_path): | ||
| 143 | self.loaded_modules = [] | ||
| 144 | module_list = modules.module_list() | ||
| 145 | |||
| 146 | for module in module_list: | ||
| 147 | module_name = module['name'].string() | ||
| 148 | module_pattern = ".*/{0}\.ko(?:.debug)?$".format( | ||
| 149 | module_name.replace("_", r"[_\-]")) | ||
| 150 | if re.match(module_pattern, mod_path) and os.path.exists(mod_path): | ||
| 151 | self.load_module_symbols(module, mod_path) | ||
| 152 | return | ||
| 153 | raise gdb.GdbError("%s is not a valid .ko\n" % mod_path) | ||
| 154 | |||
| 155 | def load_all_symbols(self): | 141 | def load_all_symbols(self): |
| 156 | gdb.write("loading vmlinux\n") | 142 | gdb.write("loading vmlinux\n") |
| 157 | 143 | ||
| @@ -190,11 +176,6 @@ lx-symbols command.""" · 32 unmodified lines | |||
| 190 | self.module_files = [] | 176 | self.module_files = [] |
| 191 | self.module_files_updated = False | 177 | self.module_files_updated = False |
| 192 | 178 | ||
| 193 | argv = gdb.string_to_argv(arg) | ||
| 194 | if len(argv) == 1: | ||
| 195 | self.load_ko_symbols(argv[0]) | ||
| 196 | return | ||
| 197 | |||
| 198 | self.load_all_symbols() | 179 | self.load_all_symbols() |
| 199 | 180 | ||
| 200 | if hasattr(gdb, 'Breakpoint'): | 181 | if hasattr(gdb, 'Breakpoint'): |
| @@ -1604,7 +1604,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, · 1603 unmodified lines | |||
| 1604 | /* First handle the "special" cases */ | 1604 | /* First handle the "special" cases */ |
| 1605 | if (sym_is(name, namelen, "usb")) | 1605 | if (sym_is(name, namelen, "usb")) |
| 1606 | do_usb_table(symval, sym->st_size, mod); | 1606 | do_usb_table(symval, sym->st_size, mod); |
| 1607 | if (sym_is(name, namelen, "of")) | 1607 | else if (sym_is(name, namelen, "of")) |
| 1608 | do_of_table(symval, sym->st_size, mod); | 1608 | do_of_table(symval, sym->st_size, mod); |
| 1609 | else if (sym_is(name, namelen, "pnp")) | 1609 | else if (sym_is(name, namelen, "pnp")) |
| 1610 | do_pnp_device_entry(symval, sym->st_size, mod); | 1610 | do_pnp_device_entry(symval, sym->st_size, mod); |
| @@ -1015,9 +1015,20 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, · 1014 unmodified lines | |||
| 1015 | "*_console"))) | 1015 | "*_console"))) |
| 1016 | return 0; | 1016 | return 0; |
| 1017 | 1017 | ||
| 1018 | /* symbols in data sections that may refer to meminit/exit sections */ | 1018 | /* symbols in data sections that may refer to meminit sections */ |
| 1019 | if (match(fromsec, PATTERNS(DATA_SECTIONS)) && | 1019 | if (match(fromsec, PATTERNS(DATA_SECTIONS)) && |
| 1020 | match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS, ALL_EXIT_SECTIONS)) && | 1020 | match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS, ALL_XXXEXIT_SECTIONS)) && |
| 1021 | match(fromsym, PATTERNS("*driver"))) | ||
| 1022 | return 0; | ||
| 1023 | |||
| 1024 | /* | ||
| 1025 | * symbols in data sections must not refer to .exit.*, but there are | ||
| 1026 | * quite a few offenders, so hide these unless for W=1 builds until | ||
| 1027 | * these are fixed. | ||
| 1028 | */ | ||
| 1029 | if (!extra_warn && | ||
| 1030 | match(fromsec, PATTERNS(DATA_SECTIONS)) && | ||
| 1031 | match(tosec, PATTERNS(EXIT_SECTIONS)) && | ||
| 1021 | match(fromsym, PATTERNS("*driver"))) | 1032 | match(fromsym, PATTERNS("*driver"))) |
| 1022 | return 0; | 1033 | return 0; |
| 1023 | 1034 | ||
| @@ -64,7 +64,6 @@ install_linux_image () { · 63 unmodified lines | |||
| 64 | 64 | ||
| 65 | ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install | 65 | ${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install |
| 66 | rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build" | 66 | rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build" |
| 67 | rm -f "${pdir}/lib/modules/${KERNELRELEASE}/source" | ||
| 68 | 67 | ||
| 69 | # Install the kernel | 68 | # Install the kernel |
| 70 | if [ "${ARCH}" = um ] ; then | 69 | if [ "${ARCH}" = um ] ; then |
| @@ -68,7 +68,6 @@ cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/vmlinuz-%{KERNELRELEA · 67 unmodified lines | |||
| 68 | cp System.map %{buildroot}/boot/System.map-%{KERNELRELEASE} | 68 | cp System.map %{buildroot}/boot/System.map-%{KERNELRELEASE} |
| 69 | cp .config %{buildroot}/boot/config-%{KERNELRELEASE} | 69 | cp .config %{buildroot}/boot/config-%{KERNELRELEASE} |
| 70 | ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEASE}/build | 70 | ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEASE}/build |
| 71 | ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEASE}/source | ||
| 72 | %if %{with_devel} | 71 | %if %{with_devel} |
| 73 | %{make} %{makeflags} run-command KBUILD_RUN_COMMAND='${srctree}/scripts/package/install-extmod-build %{buildroot}/usr/src/kernels/%{KERNELRELEASE}' | 72 | %{make} %{makeflags} run-command KBUILD_RUN_COMMAND='${srctree}/scripts/package/install-extmod-build %{buildroot}/usr/src/kernels/%{KERNELRELEASE}' |
| 74 | %endif | 73 | %endif |
| @@ -101,7 +100,6 @@ fi · 26 unmodified lines | |||
| 101 | %defattr (-, root, root) | 100 | %defattr (-, root, root) |
| 102 | /lib/modules/%{KERNELRELEASE} | 101 | /lib/modules/%{KERNELRELEASE} |
| 103 | %exclude /lib/modules/%{KERNELRELEASE}/build | 102 | %exclude /lib/modules/%{KERNELRELEASE}/build |
| 104 | %exclude /lib/modules/%{KERNELRELEASE}/source | ||
| 105 | /boot/* | 103 | /boot/* |
| 106 | 104 | ||
| 107 | %files headers | 105 | %files headers |
| @@ -113,5 +111,4 @@ fi · 5 unmodified lines | |||
| 113 | %defattr (-, root, root) | 111 | %defattr (-, root, root) |
| 114 | /usr/src/kernels/%{KERNELRELEASE} | 112 | /usr/src/kernels/%{KERNELRELEASE} |
| 115 | /lib/modules/%{KERNELRELEASE}/build | 113 | /lib/modules/%{KERNELRELEASE}/build |
| 116 | /lib/modules/%{KERNELRELEASE}/source | ||
| 117 | %endif | 114 | %endif |
| @@ -29,9 +29,11 @@ config IMA · 28 unmodified lines | |||
| 29 | to learn more about IMA. | 29 | to learn more about IMA. |
| 30 | If unsure, say N. | 30 | If unsure, say N. |
| 31 | 31 | ||
| 32 | if IMA | ||
| 33 | |||
| 32 | config IMA_KEXEC | 34 | config IMA_KEXEC |
| 33 | bool "Enable carrying the IMA measurement list across a soft boot" | 35 | bool "Enable carrying the IMA measurement list across a soft boot" |
| 34 | depends on IMA && TCG_TPM && HAVE_IMA_KEXEC | 36 | depends on TCG_TPM && HAVE_IMA_KEXEC |
| 35 | default n | 37 | default n |
| 36 | help | 38 | help |
| 37 | TPM PCRs are only reset on a hard reboot. In order to validate | 39 | TPM PCRs are only reset on a hard reboot. In order to validate |
| @@ -43,7 +45,6 @@ config IMA_KEXEC · 5 unmodified lines | |||
| 43 | 45 | ||
| 44 | config IMA_MEASURE_PCR_IDX | 46 | config IMA_MEASURE_PCR_IDX |
| 45 | int | 47 | int |
| 46 | depends on IMA | ||
| 47 | range 8 14 | 48 | range 8 14 |
| 48 | default 10 | 49 | default 10 |
| 49 | help | 50 | help |
| @@ -53,7 +54,7 @@ config IMA_MEASURE_PCR_IDX · 3 unmodified lines | |||
| 53 | 54 | ||
| 54 | config IMA_LSM_RULES | 55 | config IMA_LSM_RULES |
| 55 | bool | 56 | bool |
| 56 | depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR) | 57 | depends on AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR) |
| 57 | default y | 58 | default y |
| 58 | help | 59 | help |
| 59 | Disabling this option will disregard LSM based policy rules. | 60 | Disabling this option will disregard LSM based policy rules. |
| @@ -61,7 +62,6 @@ config IMA_LSM_RULES · 1 unmodified line | |||
| 61 | choice | 62 | choice |
| 62 | prompt "Default template" | 63 | prompt "Default template" |
| 63 | default IMA_NG_TEMPLATE | 64 | default IMA_NG_TEMPLATE |
| 64 | depends on IMA | ||
| 65 | help | 65 | help |
| 66 | Select the default IMA measurement template. | 66 | Select the default IMA measurement template. |
| 67 | 67 | ||
| @@ -80,14 +80,12 @@ endchoice · 12 unmodified lines | |||
| 80 | 80 | ||
| 81 | config IMA_DEFAULT_TEMPLATE | 81 | config IMA_DEFAULT_TEMPLATE |
| 82 | string | 82 | string |
| 83 | depends on IMA | ||
| 84 | default "ima-ng" if IMA_NG_TEMPLATE | 83 | default "ima-ng" if IMA_NG_TEMPLATE |
| 85 | default "ima-sig" if IMA_SIG_TEMPLATE | 84 | default "ima-sig" if IMA_SIG_TEMPLATE |
| 86 | 85 | ||
| 87 | choice | 86 | choice |
| 88 | prompt "Default integrity hash algorithm" | 87 | prompt "Default integrity hash algorithm" |
| 89 | default IMA_DEFAULT_HASH_SHA1 | 88 | default IMA_DEFAULT_HASH_SHA1 |
| 90 | depends on IMA | ||
| 91 | help | 89 | help |
| 92 | Select the default hash algorithm used for the measurement | 90 | Select the default hash algorithm used for the measurement |
| 93 | list, integrity appraisal and audit log. The compiled default | 91 | list, integrity appraisal and audit log. The compiled default |
| @@ -117,7 +115,6 @@ endchoice · 23 unmodified lines | |||
| 117 | 115 | ||
| 118 | config IMA_DEFAULT_HASH | 116 | config IMA_DEFAULT_HASH |
| 119 | string | 117 | string |
| 120 | depends on IMA | ||
| 121 | default "sha1" if IMA_DEFAULT_HASH_SHA1 | 118 | default "sha1" if IMA_DEFAULT_HASH_SHA1 |
| 122 | default "sha256" if IMA_DEFAULT_HASH_SHA256 | 119 | default "sha256" if IMA_DEFAULT_HASH_SHA256 |
| 123 | default "sha512" if IMA_DEFAULT_HASH_SHA512 | 120 | default "sha512" if IMA_DEFAULT_HASH_SHA512 |
| @@ -126,7 +123,6 @@ config IMA_DEFAULT_HASH · 2 unmodified lines | |||
| 126 | 123 | ||
| 127 | config IMA_WRITE_POLICY | 124 | config IMA_WRITE_POLICY |
| 128 | bool "Enable multiple writes to the IMA policy" | 125 | bool "Enable multiple writes to the IMA policy" |
| 129 | depends on IMA | ||
| 130 | default n | 126 | default n |
| 131 | help | 127 | help |
| 132 | IMA policy can now be updated multiple times. The new rules get | 128 | IMA policy can now be updated multiple times. The new rules get |
| @@ -137,7 +133,6 @@ config IMA_WRITE_POLICY · 4 unmodified lines | |||
| 137 | 133 | ||
| 138 | config IMA_READ_POLICY | 134 | config IMA_READ_POLICY |
| 139 | bool "Enable reading back the current IMA policy" | 135 | bool "Enable reading back the current IMA policy" |
| 140 | depends on IMA | ||
| 141 | default y if IMA_WRITE_POLICY | 136 | default y if IMA_WRITE_POLICY |
| 142 | default n if !IMA_WRITE_POLICY | 137 | default n if !IMA_WRITE_POLICY |
| 143 | help | 138 | help |
| @@ -147,7 +142,6 @@ config IMA_READ_POLICY · 3 unmodified lines | |||
| 147 | 142 | ||
| 148 | config IMA_APPRAISE | 143 | config IMA_APPRAISE |
| 149 | bool "Appraise integrity measurements" | 144 | bool "Appraise integrity measurements" |
| 150 | depends on IMA | ||
| 151 | default n | 145 | default n |
| 152 | help | 146 | help |
| 153 | This option enables local measurement integrity appraisal. | 147 | This option enables local measurement integrity appraisal. |
| @@ -269,7 +263,7 @@ config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY · 115 unmodified lines | |||
| 269 | config IMA_BLACKLIST_KEYRING | 263 | config IMA_BLACKLIST_KEYRING |
| 270 | bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)" | 264 | bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)" |
| 271 | depends on SYSTEM_TRUSTED_KEYRING | 265 | depends on SYSTEM_TRUSTED_KEYRING |
| 272 | depends on IMA_TRUSTED_KEYRING | 266 | depends on INTEGRITY_TRUSTED_KEYRING |
| 273 | default n | 267 | default n |
| 274 | help | 268 | help |
| 275 | This option creates an IMA blacklist keyring, which contains all | 269 | This option creates an IMA blacklist keyring, which contains all |
| @@ -279,7 +273,7 @@ config IMA_BLACKLIST_KEYRING · 3 unmodified lines | |||
| 279 | 273 | ||
| 280 | config IMA_LOAD_X509 | 274 | config IMA_LOAD_X509 |
| 281 | bool "Load X509 certificate onto the '.ima' trusted keyring" | 275 | bool "Load X509 certificate onto the '.ima' trusted keyring" |
| 282 | depends on IMA_TRUSTED_KEYRING | 276 | depends on INTEGRITY_TRUSTED_KEYRING |
| 283 | default n | 277 | default n |
| 284 | help | 278 | help |
| 285 | File signature verification is based on the public keys | 279 | File signature verification is based on the public keys |
| @@ -304,7 +298,6 @@ config IMA_APPRAISE_SIGNED_INIT · 18 unmodified lines | |||
| 304 | 298 | ||
| 305 | config IMA_MEASURE_ASYMMETRIC_KEYS | 299 | config IMA_MEASURE_ASYMMETRIC_KEYS |
| 306 | bool | 300 | bool |
| 307 | depends on IMA | ||
| 308 | depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y | 301 | depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y |
| 309 | default y | 302 | default y |
| 310 | 303 | ||
| @@ -323,7 +316,8 @@ config IMA_SECURE_AND_OR_TRUSTED_BOOT · 12 unmodified lines | |||
| 323 | 316 | ||
| 324 | config IMA_DISABLE_HTABLE | 317 | config IMA_DISABLE_HTABLE |
| 325 | bool "Disable htable to allow measurement of duplicate records" | 318 | bool "Disable htable to allow measurement of duplicate records" |
| 326 | depends on IMA | ||
| 327 | default n | 319 | default n |
| 328 | help | 320 | help |
| 329 | This option disables htable to allow measurement of duplicate records. | 321 | This option disables htable to allow measurement of duplicate records. |
| 322 | |||
| 323 | endif | ||
| @@ -57,6 +57,7 @@ · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ | 58 | #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ |
| 59 | #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ | 59 | #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ |
| 60 | #define PRED_CMD_SBPB BIT(7) /* Selective Branch Prediction Barrier */ | ||
| 60 | 61 | ||
| 61 | #define MSR_PPIN_CTL 0x0000004e | 62 | #define MSR_PPIN_CTL 0x0000004e |
| 62 | #define MSR_PPIN 0x0000004f | 63 | #define MSR_PPIN 0x0000004f |
| @@ -155,6 +156,15 @@ · 92 unmodified lines | |||
| 155 | * Not susceptible to Post-Barrier | 156 | * Not susceptible to Post-Barrier |
| 156 | * Return Stack Buffer Predictions. | 157 | * Return Stack Buffer Predictions. |
| 157 | */ | 158 | */ |
| 159 | #define ARCH_CAP_GDS_CTRL BIT(25) /* | ||
| 160 | * CPU is vulnerable to Gather | ||
| 161 | * Data Sampling (GDS) and | ||
| 162 | * has controls for mitigation. | ||
| 163 | */ | ||
| 164 | #define ARCH_CAP_GDS_NO BIT(26) /* | ||
| 165 | * CPU is not vulnerable to Gather | ||
| 166 | * Data Sampling (GDS). | ||
| 167 | */ | ||
| 158 | 168 | ||
| 159 | #define ARCH_CAP_XAPIC_DISABLE BIT(21) /* | 169 | #define ARCH_CAP_XAPIC_DISABLE BIT(21) /* |
| 160 | * IA32_XAPIC_DISABLE_STATUS MSR | 170 | * IA32_XAPIC_DISABLE_STATUS MSR |
| @@ -178,6 +188,8 @@ · 17 unmodified lines | |||
| 178 | #define RNGDS_MITG_DIS BIT(0) /* SRBDS support */ | 188 | #define RNGDS_MITG_DIS BIT(0) /* SRBDS support */ |
| 179 | #define RTM_ALLOW BIT(1) /* TSX development mode */ | 189 | #define RTM_ALLOW BIT(1) /* TSX development mode */ |
| 180 | #define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ | 190 | #define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ |
| 191 | #define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */ | ||
| 192 | #define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */ | ||
| 181 | 193 | ||
| 182 | #define MSR_IA32_SYSENTER_CS 0x00000174 | 194 | #define MSR_IA32_SYSENTER_CS 0x00000174 |
| 183 | #define MSR_IA32_SYSENTER_ESP 0x00000175 | 195 | #define MSR_IA32_SYSENTER_ESP 0x00000175 |
| @@ -820,8 +820,11 @@ __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node) · 819 unmodified lines | |||
| 820 | #define __NR_cachestat 451 | 820 | #define __NR_cachestat 451 |
| 821 | __SYSCALL(__NR_cachestat, sys_cachestat) | 821 | __SYSCALL(__NR_cachestat, sys_cachestat) |
| 822 | 822 | ||
| 823 | #define __NR_fchmodat2 452 | ||
| 824 | __SYSCALL(__NR_fchmodat2, sys_fchmodat2) | ||
| 825 | |||
| 823 | #undef __NR_syscalls | 826 | #undef __NR_syscalls |
| 824 | #define __NR_syscalls 452 | 827 | #define __NR_syscalls 453 |
| 825 | 828 | ||
| 826 | /* | 829 | /* |
| 827 | * 32 bit systems traditionally used different | 830 | * 32 bit systems traditionally used different |
| @@ -673,8 +673,11 @@ struct drm_gem_open { · 672 unmodified lines | |||
| 673 | * Bitfield of supported PRIME sharing capabilities. See &DRM_PRIME_CAP_IMPORT | 673 | * Bitfield of supported PRIME sharing capabilities. See &DRM_PRIME_CAP_IMPORT |
| 674 | * and &DRM_PRIME_CAP_EXPORT. | 674 | * and &DRM_PRIME_CAP_EXPORT. |
| 675 | * | 675 | * |
| 676 | * PRIME buffers are exposed as dma-buf file descriptors. See | 676 | * Starting from kernel version 6.6, both &DRM_PRIME_CAP_IMPORT and |
| 677 | * Documentation/gpu/drm-mm.rst, section "PRIME Buffer Sharing". | 677 | * &DRM_PRIME_CAP_EXPORT are always advertised. |
| 678 | * | ||
| 679 | * PRIME buffers are exposed as dma-buf file descriptors. | ||
| 680 | * See :ref:`prime_buffer_sharing`. | ||
| 678 | */ | 681 | */ |
| 679 | #define DRM_CAP_PRIME 0x5 | 682 | #define DRM_CAP_PRIME 0x5 |
| 680 | /** | 683 | /** |
| @@ -682,6 +685,8 @@ struct drm_gem_open { · 1 unmodified line | |||
| 682 | * | 685 | * |
| 683 | * If this bit is set in &DRM_CAP_PRIME, the driver supports importing PRIME | 686 | * If this bit is set in &DRM_CAP_PRIME, the driver supports importing PRIME |
| 684 | * buffers via the &DRM_IOCTL_PRIME_FD_TO_HANDLE ioctl. | 687 | * buffers via the &DRM_IOCTL_PRIME_FD_TO_HANDLE ioctl. |
| 688 | * | ||
| 689 | * Starting from kernel version 6.6, this bit is always set in &DRM_CAP_PRIME. | ||
| 685 | */ | 690 | */ |
| 686 | #define DRM_PRIME_CAP_IMPORT 0x1 | 691 | #define DRM_PRIME_CAP_IMPORT 0x1 |
| 687 | /** | 692 | /** |
| @@ -689,6 +694,8 @@ struct drm_gem_open { · 1 unmodified line | |||
| 689 | * | 694 | * |
| 690 | * If this bit is set in &DRM_CAP_PRIME, the driver supports exporting PRIME | 695 | * If this bit is set in &DRM_CAP_PRIME, the driver supports exporting PRIME |
| 691 | * buffers via the &DRM_IOCTL_PRIME_HANDLE_TO_FD ioctl. | 696 | * buffers via the &DRM_IOCTL_PRIME_HANDLE_TO_FD ioctl. |
| 697 | * | ||
| 698 | * Starting from kernel version 6.6, this bit is always set in &DRM_CAP_PRIME. | ||
| 692 | */ | 699 | */ |
| 693 | #define DRM_PRIME_CAP_EXPORT 0x2 | 700 | #define DRM_PRIME_CAP_EXPORT 0x2 |
| 694 | /** | 701 | /** |
| @@ -756,15 +763,14 @@ struct drm_gem_open { · 61 unmodified lines | |||
| 756 | /** | 763 | /** |
| 757 | * DRM_CAP_SYNCOBJ | 764 | * DRM_CAP_SYNCOBJ |
| 758 | * | 765 | * |
| 759 | * If set to 1, the driver supports sync objects. See | 766 | * If set to 1, the driver supports sync objects. See :ref:`drm_sync_objects`. |
| 760 | * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". | ||
| 761 | */ | 767 | */ |
| 762 | #define DRM_CAP_SYNCOBJ 0x13 | 768 | #define DRM_CAP_SYNCOBJ 0x13 |
| 763 | /** | 769 | /** |
| 764 | * DRM_CAP_SYNCOBJ_TIMELINE | 770 | * DRM_CAP_SYNCOBJ_TIMELINE |
| 765 | * | 771 | * |
| 766 | * If set to 1, the driver supports timeline operations on sync objects. See | 772 | * If set to 1, the driver supports timeline operations on sync objects. See |
| 767 | * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". | 773 | * :ref:`drm_sync_objects`. |
| 768 | */ | 774 | */ |
| 769 | #define DRM_CAP_SYNCOBJ_TIMELINE 0x14 | 775 | #define DRM_CAP_SYNCOBJ_TIMELINE 0x14 |
| 770 | 776 | ||
| @@ -909,6 +915,27 @@ struct drm_syncobj_timeline_wait { · 138 unmodified lines | |||
| 909 | __u32 pad; | 915 | __u32 pad; |
| 910 | }; | 916 | }; |
| 911 | 917 | ||
| 918 | /** | ||
| 919 | * struct drm_syncobj_eventfd | ||
| 920 | * @handle: syncobj handle. | ||
| 921 | * @flags: Zero to wait for the point to be signalled, or | ||
| 922 | * &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE to wait for a fence to be | ||
| 923 | * available for the point. | ||
| 924 | * @point: syncobj timeline point (set to zero for binary syncobjs). | ||
| 925 | * @fd: Existing eventfd to sent events to. | ||
| 926 | * @pad: Must be zero. | ||
| 927 | * | ||
| 928 | * Register an eventfd to be signalled by a syncobj. The eventfd counter will | ||
| 929 | * be incremented by one. | ||
| 930 | */ | ||
| 931 | struct drm_syncobj_eventfd { | ||
| 932 | __u32 handle; | ||
| 933 | __u32 flags; | ||
| 934 | __u64 point; | ||
| 935 | __s32 fd; | ||
| 936 | __u32 pad; | ||
| 937 | }; | ||
| 938 | |||
| 912 | 939 | ||
| 913 | struct drm_syncobj_array { | 940 | struct drm_syncobj_array { |
| 914 | __u64 handles; | 941 | __u64 handles; |
| @@ -1169,6 +1196,8 @@ extern "C" { · 254 unmodified lines | |||
| 1169 | */ | 1196 | */ |
| 1170 | #define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) | 1197 | #define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) |
| 1171 | 1198 | ||
| 1199 | #define DRM_IOCTL_SYNCOBJ_EVENTFD DRM_IOWR(0xCF, struct drm_syncobj_eventfd) | ||
| 1200 | |||
| 1172 | /* | 1201 | /* |
| 1173 | * Device specific ioctls should only be in their respective headers | 1202 | * Device specific ioctls should only be in their respective headers |
| 1174 | * The device specific ioctl range is from 0x40 to 0x9f. | 1203 | * The device specific ioctl range is from 0x40 to 0x9f. |
| @@ -1180,25 +1209,50 @@ extern "C" { · 5 unmodified lines | |||
| 1180 | #define DRM_COMMAND_BASE 0x40 | 1209 | #define DRM_COMMAND_BASE 0x40 |
| 1181 | #define DRM_COMMAND_END 0xA0 | 1210 | #define DRM_COMMAND_END 0xA0 |
| 1182 | 1211 | ||
| 1183 | /* | 1212 | /** |
| 1184 | * Header for events written back to userspace on the drm fd. The | 1213 | * struct drm_event - Header for DRM events |
| 1185 | * type defines the type of event, the length specifies the total | 1214 | * @type: event type. |
| 1186 | * length of the event (including the header), and user_data is | 1215 | * @length: total number of payload bytes (including header). |
| 1187 | * typically a 64 bit value passed with the ioctl that triggered the | ||
| 1188 | * event. A read on the drm fd will always only return complete | ||
| 1189 | * events, that is, if for example the read buffer is 100 bytes, and | ||
| 1190 | * there are two 64 byte events pending, only one will be returned. | ||
| 1191 | * | 1216 | * |
| 1192 | * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and | 1217 | * This struct is a header for events written back to user-space on the DRM FD. |
| 1193 | * up are chipset specific. | 1218 | * A read on the DRM FD will always only return complete events: e.g. if the |
| 1219 | * read buffer is 100 bytes large and there are two 64 byte events pending, | ||
| 1220 | * only one will be returned. | ||
| 1221 | * | ||
| 1222 | * Event types 0 - 0x7fffffff are generic DRM events, 0x80000000 and | ||
| 1223 | * up are chipset specific. Generic DRM events include &DRM_EVENT_VBLANK, | ||
| 1224 | * &DRM_EVENT_FLIP_COMPLETE and &DRM_EVENT_CRTC_SEQUENCE. | ||
| 1194 | */ | 1225 | */ |
| 1195 | struct drm_event { | 1226 | struct drm_event { |
| 1196 | __u32 type; | 1227 | __u32 type; |
| 1197 | __u32 length; | 1228 | __u32 length; |
| 1198 | }; | 1229 | }; |
| 1199 | 1230 | ||
| 1231 | /** | ||
| 1232 | * DRM_EVENT_VBLANK - vertical blanking event | ||
| 1233 | * | ||
| 1234 | * This event is sent in response to &DRM_IOCTL_WAIT_VBLANK with the | ||
| 1235 | * &_DRM_VBLANK_EVENT flag set. | ||
| 1236 | * | ||
| 1237 | * The event payload is a struct drm_event_vblank. | ||
| 1238 | */ | ||
| 1200 | #define DRM_EVENT_VBLANK 0x01 | 1239 | #define DRM_EVENT_VBLANK 0x01 |
| 1240 | /** | ||
| 1241 | * DRM_EVENT_FLIP_COMPLETE - page-flip completion event | ||
| 1242 | * | ||
| 1243 | * This event is sent in response to an atomic commit or legacy page-flip with | ||
| 1244 | * the &DRM_MODE_PAGE_FLIP_EVENT flag set. | ||
| 1245 | * | ||
| 1246 | * The event payload is a struct drm_event_vblank. | ||
| 1247 | */ | ||
| 1201 | #define DRM_EVENT_FLIP_COMPLETE 0x02 | 1248 | #define DRM_EVENT_FLIP_COMPLETE 0x02 |
| 1249 | /** | ||
| 1250 | * DRM_EVENT_CRTC_SEQUENCE - CRTC sequence event | ||
| 1251 | * | ||
| 1252 | * This event is sent in response to &DRM_IOCTL_CRTC_QUEUE_SEQUENCE. | ||
| 1253 | * | ||
| 1254 | * The event payload is a struct drm_event_crtc_sequence. | ||
| 1255 | */ | ||
| 1202 | #define DRM_EVENT_CRTC_SEQUENCE 0x03 | 1256 | #define DRM_EVENT_CRTC_SEQUENCE 0x03 |
| 1203 | 1257 | ||
| 1204 | struct drm_event_vblank { | 1258 | struct drm_event_vblank { |
| @@ -0,0 +1,157 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
| 2 | #ifndef _UAPI_LINUX_SECCOMP_H | ||
| 3 | #define _UAPI_LINUX_SECCOMP_H | ||
| 4 | |||
| 5 | #include <linux/compiler.h> | ||
| 6 | #include <linux/types.h> | ||
| 7 | |||
| 8 | |||
| 9 | /* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */ | ||
| 10 | #define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */ | ||
| 11 | #define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */ | ||
| 12 | #define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ | ||
| 13 | |||
| 14 | /* Valid operations for seccomp syscall. */ | ||
| 15 | #define SECCOMP_SET_MODE_STRICT 0 | ||
| 16 | #define SECCOMP_SET_MODE_FILTER 1 | ||
| 17 | #define SECCOMP_GET_ACTION_AVAIL 2 | ||
| 18 | #define SECCOMP_GET_NOTIF_SIZES 3 | ||
| 19 | |||
| 20 | /* Valid flags for SECCOMP_SET_MODE_FILTER */ | ||
| 21 | #define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) | ||
| 22 | #define SECCOMP_FILTER_FLAG_LOG (1UL << 1) | ||
| 23 | #define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) | ||
| 24 | #define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3) | ||
| 25 | #define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4) | ||
| 26 | /* Received notifications wait in killable state (only respond to fatal signals) */ | ||
| 27 | #define SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (1UL << 5) | ||
| 28 | |||
| 29 | /* | ||
| 30 | * All BPF programs must return a 32-bit value. | ||
| 31 | * The bottom 16-bits are for optional return data. | ||
| 32 | * The upper 16-bits are ordered from least permissive values to most, | ||
| 33 | * as a signed value (so 0x8000000 is negative). | ||
| 34 | * | ||
| 35 | * The ordering ensures that a min_t() over composed return values always | ||
| 36 | * selects the least permissive choice. | ||
| 37 | */ | ||
| 38 | #define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process */ | ||
| 39 | #define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */ | ||
| 40 | #define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD | ||
| 41 | #define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ | ||
| 42 | #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ | ||
| 43 | #define SECCOMP_RET_USER_NOTIF 0x7fc00000U /* notifies userspace */ | ||
| 44 | #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ | ||
| 45 | #define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */ | ||
| 46 | #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ | ||
| 47 | |||
| 48 | /* Masks for the return value sections. */ | ||
| 49 | #define SECCOMP_RET_ACTION_FULL 0xffff0000U | ||
| 50 | #define SECCOMP_RET_ACTION 0x7fff0000U | ||
| 51 | #define SECCOMP_RET_DATA 0x0000ffffU | ||
| 52 | |||
| 53 | /** | ||
| 54 | * struct seccomp_data - the format the BPF program executes over. | ||
| 55 | * @nr: the system call number | ||
| 56 | * @arch: indicates system call convention as an AUDIT_ARCH_* value | ||
| 57 | * as defined in <linux/audit.h>. | ||
| 58 | * @instruction_pointer: at the time of the system call. | ||
| 59 | * @args: up to 6 system call arguments always stored as 64-bit values | ||
| 60 | * regardless of the architecture. | ||
| 61 | */ | ||
| 62 | struct seccomp_data { | ||
| 63 | int nr; | ||
| 64 | __u32 arch; | ||
| 65 | __u64 instruction_pointer; | ||
| 66 | __u64 args[6]; | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct seccomp_notif_sizes { | ||
| 70 | __u16 seccomp_notif; | ||
| 71 | __u16 seccomp_notif_resp; | ||
| 72 | __u16 seccomp_data; | ||
| 73 | }; | ||
| 74 | |||
| 75 | struct seccomp_notif { | ||
| 76 | __u64 id; | ||
| 77 | __u32 pid; | ||
| 78 | __u32 flags; | ||
| 79 | struct seccomp_data data; | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Valid flags for struct seccomp_notif_resp | ||
| 84 | * | ||
| 85 | * Note, the SECCOMP_USER_NOTIF_FLAG_CONTINUE flag must be used with caution! | ||
| 86 | * If set by the process supervising the syscalls of another process the | ||
| 87 | * syscall will continue. This is problematic because of an inherent TOCTOU. | ||
| 88 | * An attacker can exploit the time while the supervised process is waiting on | ||
| 89 | * a response from the supervising process to rewrite syscall arguments which | ||
| 90 | * are passed as pointers of the intercepted syscall. | ||
| 91 | * It should be absolutely clear that this means that the seccomp notifier | ||
| 92 | * _cannot_ be used to implement a security policy! It should only ever be used | ||
| 93 | * in scenarios where a more privileged process supervises the syscalls of a | ||
| 94 | * lesser privileged process to get around kernel-enforced security | ||
| 95 | * restrictions when the privileged process deems this safe. In other words, | ||
| 96 | * in order to continue a syscall the supervising process should be sure that | ||
| 97 | * another security mechanism or the kernel itself will sufficiently block | ||
| 98 | * syscalls if arguments are rewritten to something unsafe. | ||
| 99 | * | ||
| 100 | * Similar precautions should be applied when stacking SECCOMP_RET_USER_NOTIF | ||
| 101 | * or SECCOMP_RET_TRACE. For SECCOMP_RET_USER_NOTIF filters acting on the | ||
| 102 | * same syscall, the most recently added filter takes precedence. This means | ||
| 103 | * that the new SECCOMP_RET_USER_NOTIF filter can override any | ||
| 104 | * SECCOMP_IOCTL_NOTIF_SEND from earlier filters, essentially allowing all | ||
| 105 | * such filtered syscalls to be executed by sending the response | ||
| 106 | * SECCOMP_USER_NOTIF_FLAG_CONTINUE. Note that SECCOMP_RET_TRACE can equally | ||
| 107 | * be overriden by SECCOMP_USER_NOTIF_FLAG_CONTINUE. | ||
| 108 | */ | ||
| 109 | #define SECCOMP_USER_NOTIF_FLAG_CONTINUE (1UL << 0) | ||
| 110 | |||
| 111 | struct seccomp_notif_resp { | ||
| 112 | __u64 id; | ||
| 113 | __s64 val; | ||
| 114 | __s32 error; | ||
| 115 | __u32 flags; | ||
| 116 | }; | ||
| 117 | |||
| 118 | #define SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP (1UL << 0) | ||
| 119 | |||
| 120 | /* valid flags for seccomp_notif_addfd */ | ||
| 121 | #define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) /* Specify remote fd */ | ||
| 122 | #define SECCOMP_ADDFD_FLAG_SEND (1UL << 1) /* Addfd and return it, atomically */ | ||
| 123 | |||
| 124 | /** | ||
| 125 | * struct seccomp_notif_addfd | ||
| 126 | * @id: The ID of the seccomp notification | ||
| 127 | * @flags: SECCOMP_ADDFD_FLAG_* | ||
| 128 | * @srcfd: The local fd number | ||
| 129 | * @newfd: Optional remote FD number if SETFD option is set, otherwise 0. | ||
| 130 | * @newfd_flags: The O_* flags the remote FD should have applied | ||
| 131 | */ | ||
| 132 | struct seccomp_notif_addfd { | ||
| 133 | __u64 id; | ||
| 134 | __u32 flags; | ||
| 135 | __u32 srcfd; | ||
| 136 | __u32 newfd; | ||
| 137 | __u32 newfd_flags; | ||
| 138 | }; | ||
| 139 | |||
| 140 | #define SECCOMP_IOC_MAGIC '!' | ||
| 141 | #define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) | ||
| 142 | #define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) | ||
| 143 | #define SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type) | ||
| 144 | #define SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type) | ||
| 145 | |||
| 146 | /* Flags for seccomp notification fd ioctl. */ | ||
| 147 | #define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) | ||
| 148 | #define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, \ | ||
| 149 | struct seccomp_notif_resp) | ||
| 150 | #define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64) | ||
| 151 | /* On success, the return value is the remote process's added fd number */ | ||
| 152 | #define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, \ | ||
| 153 | struct seccomp_notif_addfd) | ||
| 154 | |||
| 155 | #define SECCOMP_IOCTL_NOTIF_SET_FLAGS SECCOMP_IOW(4, __u64) | ||
| 156 | |||
| 157 | #endif /* _UAPI_LINUX_SECCOMP_H */ | ||
| @@ -366,3 +366,4 @@ · 365 unmodified lines | |||
| 366 | 449 n64 futex_waitv sys_futex_waitv | 366 | 449 n64 futex_waitv sys_futex_waitv |
| 367 | 450 common set_mempolicy_home_node sys_set_mempolicy_home_node | 367 | 450 common set_mempolicy_home_node sys_set_mempolicy_home_node |
| 368 | 451 n64 cachestat sys_cachestat | 368 | 451 n64 cachestat sys_cachestat |
| 369 | 452 n64 fchmodat2 sys_fchmodat2 | ||
| @@ -538,3 +538,4 @@ · 537 unmodified lines | |||
| 538 | 449 common futex_waitv sys_futex_waitv | 538 | 449 common futex_waitv sys_futex_waitv |
| 539 | 450 nospu set_mempolicy_home_node sys_set_mempolicy_home_node | 539 | 450 nospu set_mempolicy_home_node sys_set_mempolicy_home_node |
| 540 | 451 common cachestat sys_cachestat | 540 | 451 common cachestat sys_cachestat |
| 541 | 452 common fchmodat2 sys_fchmodat2 | ||
| @@ -454,3 +454,4 @@ · 453 unmodified lines | |||
| 454 | 449 common futex_waitv sys_futex_waitv sys_futex_waitv | 454 | 449 common futex_waitv sys_futex_waitv sys_futex_waitv |
| 455 | 450 common set_mempolicy_home_node sys_set_mempolicy_home_node sys_set_mempolicy_home_node | 455 | 450 common set_mempolicy_home_node sys_set_mempolicy_home_node sys_set_mempolicy_home_node |
| 456 | 451 common cachestat sys_cachestat sys_cachestat | 456 | 451 common cachestat sys_cachestat sys_cachestat |
| 457 | 452 common fchmodat2 sys_fchmodat2 sys_fchmodat2 | ||
| @@ -373,6 +373,8 @@ · 372 unmodified lines | |||
| 373 | 449 common futex_waitv sys_futex_waitv | 373 | 449 common futex_waitv sys_futex_waitv |
| 374 | 450 common set_mempolicy_home_node sys_set_mempolicy_home_node | 374 | 450 common set_mempolicy_home_node sys_set_mempolicy_home_node |
| 375 | 451 common cachestat sys_cachestat | 375 | 451 common cachestat sys_cachestat |
| 376 | 452 common fchmodat2 sys_fchmodat2 | ||
| 377 | 453 64 map_shadow_stack sys_map_shadow_stack | ||
| 376 | 378 | ||
| 377 | # | 379 | # |
| 378 | # Due to a historical design error, certain syscalls are numbered differently | 380 | # Due to a historical design error, certain syscalls are numbered differently |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <sys/syscall.h> | 9 | #include <sys/syscall.h> |
| 10 | #include <sys/ioctl.h> | 10 | #include <sys/ioctl.h> |
| 11 | #include <linux/time64.h> | 11 | #include <linux/time64.h> |
| 12 | #include <linux/seccomp.h> | 12 | #include <uapi/linux/seccomp.h> |
| 13 | #include <sys/prctl.h> | 13 | #include <sys/prctl.h> |
| 14 | 14 | ||
| 15 | #include <unistd.h> | 15 | #include <unistd.h> |
| @@ -21,6 +21,7 @@ FILES=( · 20 unmodified lines | |||
| 21 | "include/uapi/linux/perf_event.h" | 21 | "include/uapi/linux/perf_event.h" |
| 22 | "include/uapi/linux/prctl.h" | 22 | "include/uapi/linux/prctl.h" |
| 23 | "include/uapi/linux/sched.h" | 23 | "include/uapi/linux/sched.h" |
| 24 | "include/uapi/linux/seccomp.h" | ||
| 24 | "include/uapi/linux/stat.h" | 25 | "include/uapi/linux/stat.h" |
| 25 | "include/uapi/linux/usbdevice_fs.h" | 26 | "include/uapi/linux/usbdevice_fs.h" |
| 26 | "include/uapi/linux/vhost.h" | 27 | "include/uapi/linux/vhost.h" |
| @@ -991,7 +991,7 @@ const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu) · 990 unmodified lines | |||
| 991 | } | 991 | } |
| 992 | } | 992 | } |
| 993 | free(cpuid); | 993 | free(cpuid); |
| 994 | if (!pmu) | 994 | if (!pmu || !table) |
| 995 | return table; | 995 | return table; |
| 996 | 996 | ||
| 997 | for (i = 0; i < table->num_pmus; i++) { | 997 | for (i = 0; i < table->num_pmus; i++) { |
| @@ -413,10 +413,10 @@ def has_event(event: Event) -> Function: · 412 unmodified lines | |||
| 413 | # pylint: disable=invalid-name | 413 | # pylint: disable=invalid-name |
| 414 | return Function('has_event', event) | 414 | return Function('has_event', event) |
| 415 | 415 | ||
| 416 | def strcmp_cpuid_str(event: str) -> Function: | 416 | def strcmp_cpuid_str(cpuid: Event) -> Function: |
| 417 | # pylint: disable=redefined-builtin | 417 | # pylint: disable=redefined-builtin |
| 418 | # pylint: disable=invalid-name | 418 | # pylint: disable=invalid-name |
| 419 | return Function('strcmp_cpuid_str', event) | 419 | return Function('strcmp_cpuid_str', cpuid) |
| 420 | 420 | ||
| 421 | class Metric: | 421 | class Metric: |
| 422 | """An individual metric that will specifiable on the perf command line.""" | 422 | """An individual metric that will specifiable on the perf command line.""" |
| @@ -1,508 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * bpf-prologue.c | ||
| 4 | * | ||
| 5 | * Copyright (C) 2015 He Kuang <hekuang@huawei.com> | ||
| 6 | * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> | ||
| 7 | * Copyright (C) 2015 Huawei Inc. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <bpf/libbpf.h> | ||
| 11 | #include "debug.h" | ||
| 12 | #include "bpf-loader.h" | ||
| 13 | #include "bpf-prologue.h" | ||
| 14 | #include "probe-finder.h" | ||
| 15 | #include <errno.h> | ||
| 16 | #include <stdlib.h> | ||
| 17 | #include <dwarf-regs.h> | ||
| 18 | #include <linux/filter.h> | ||
| 19 | |||
| 20 | #define BPF_REG_SIZE 8 | ||
| 21 | |||
| 22 | #define JMP_TO_ERROR_CODE -1 | ||
| 23 | #define JMP_TO_SUCCESS_CODE -2 | ||
| 24 | #define JMP_TO_USER_CODE -3 | ||
| 25 | |||
| 26 | struct bpf_insn_pos { | ||
| 27 | struct bpf_insn *begin; | ||
| 28 | struct bpf_insn *end; | ||
| 29 | struct bpf_insn *pos; | ||
| 30 | }; | ||
| 31 | |||
| 32 | static inline int | ||
| 33 | pos_get_cnt(struct bpf_insn_pos *pos) | ||
| 34 | { | ||
| 35 | return pos->pos - pos->begin; | ||
| 36 | } | ||
| 37 | |||
| 38 | static int | ||
| 39 | append_insn(struct bpf_insn new_insn, struct bpf_insn_pos *pos) | ||
| 40 | { | ||
| 41 | if (!pos->pos) | ||
| 42 | return -BPF_LOADER_ERRNO__PROLOGUE2BIG; | ||
| 43 | |||
| 44 | if (pos->pos + 1 >= pos->end) { | ||
| 45 | pr_err("bpf prologue: prologue too long\n"); | ||
| 46 | pos->pos = NULL; | ||
| 47 | return -BPF_LOADER_ERRNO__PROLOGUE2BIG; | ||
| 48 | } | ||
| 49 | |||
| 50 | *(pos->pos)++ = new_insn; | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | static int | ||
| 55 | check_pos(struct bpf_insn_pos *pos) | ||
| 56 | { | ||
| 57 | if (!pos->pos || pos->pos >= pos->end) | ||
| 58 | return -BPF_LOADER_ERRNO__PROLOGUE2BIG; | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | ||
| 63 | * Convert type string (u8/u16/u32/u64/s8/s16/s32/s64 ..., see | ||
| 64 | * Documentation/trace/kprobetrace.rst) to size field of BPF_LDX_MEM | ||
| 65 | * instruction (BPF_{B,H,W,DW}). | ||
| 66 | */ | ||
| 67 | static int | ||
| 68 | argtype_to_ldx_size(const char *type) | ||
| 69 | { | ||
| 70 | int arg_size = type ? atoi(&type[1]) : 64; | ||
| 71 | |||
| 72 | switch (arg_size) { | ||
| 73 | case 8: | ||
| 74 | return BPF_B; | ||
| 75 | case 16: | ||
| 76 | return BPF_H; | ||
| 77 | case 32: | ||
| 78 | return BPF_W; | ||
| 79 | case 64: | ||
| 80 | default: | ||
| 81 | return BPF_DW; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | static const char * | ||
| 86 | insn_sz_to_str(int insn_sz) | ||
| 87 | { | ||
| 88 | switch (insn_sz) { | ||
| 89 | case BPF_B: | ||
| 90 | return "BPF_B"; | ||
| 91 | case BPF_H: | ||
| 92 | return "BPF_H"; | ||
| 93 | case BPF_W: | ||
| 94 | return "BPF_W"; | ||
| 95 | case BPF_DW: | ||
| 96 | return "BPF_DW"; | ||
| 97 | default: | ||
| 98 | return "UNKNOWN"; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | /* Give it a shorter name */ | ||
| 103 | #define ins(i, p) append_insn((i), (p)) | ||
| 104 | |||
| 105 | /* | ||
| 106 | * Give a register name (in 'reg'), generate instruction to | ||
| 107 | * load register into an eBPF register rd: | ||
| 108 | * 'ldd target_reg, offset(ctx_reg)', where: | ||
| 109 | * ctx_reg is pre initialized to pointer of 'struct pt_regs'. | ||
| 110 | */ | ||
| 111 | static int | ||
| 112 | gen_ldx_reg_from_ctx(struct bpf_insn_pos *pos, int ctx_reg, | ||
| 113 | const char *reg, int target_reg) | ||
| 114 | { | ||
| 115 | int offset = regs_query_register_offset(reg); | ||
| 116 | |||
| 117 | if (offset < 0) { | ||
| 118 | pr_err("bpf: prologue: failed to get register %s\n", | ||
| 119 | reg); | ||
| 120 | return offset; | ||
| 121 | } | ||
| 122 | ins(BPF_LDX_MEM(BPF_DW, target_reg, ctx_reg, offset), pos); | ||
| 123 | |||
| 124 | return check_pos(pos); | ||
| 125 | } | ||
| 126 | |||
| 127 | /* | ||
| 128 | * Generate a BPF_FUNC_probe_read function call. | ||
| 129 | * | ||
| 130 | * src_base_addr_reg is a register holding base address, | ||
| 131 | * dst_addr_reg is a register holding dest address (on stack), | ||
| 132 | * result is: | ||
| 133 | * | ||
| 134 | * *[dst_addr_reg] = *([src_base_addr_reg] + offset) | ||
| 135 | * | ||
| 136 | * Arguments of BPF_FUNC_probe_read: | ||
| 137 | * ARG1: ptr to stack (dest) | ||
| 138 | * ARG2: size (8) | ||
| 139 | * ARG3: unsafe ptr (src) | ||
| 140 | */ | ||
| 141 | static int | ||
| 142 | gen_read_mem(struct bpf_insn_pos *pos, | ||
| 143 | int src_base_addr_reg, | ||
| 144 | int dst_addr_reg, | ||
| 145 | long offset, | ||
| 146 | int probeid) | ||
| 147 | { | ||
| 148 | /* mov arg3, src_base_addr_reg */ | ||
| 149 | if (src_base_addr_reg != BPF_REG_ARG3) | ||
| 150 | ins(BPF_MOV64_REG(BPF_REG_ARG3, src_base_addr_reg), pos); | ||
| 151 | /* add arg3, #offset */ | ||
| 152 | if (offset) | ||
| 153 | ins(BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG3, offset), pos); | ||
| 154 | |||
| 155 | /* mov arg2, #reg_size */ | ||
| 156 | ins(BPF_ALU64_IMM(BPF_MOV, BPF_REG_ARG2, BPF_REG_SIZE), pos); | ||
| 157 | |||
| 158 | /* mov arg1, dst_addr_reg */ | ||
| 159 | if (dst_addr_reg != BPF_REG_ARG1) | ||
| 160 | ins(BPF_MOV64_REG(BPF_REG_ARG1, dst_addr_reg), pos); | ||
| 161 | |||
| 162 | /* Call probe_read */ | ||
| 163 | ins(BPF_EMIT_CALL(probeid), pos); | ||
| 164 | /* | ||
| 165 | * Error processing: if read fail, goto error code, | ||
| 166 | * will be relocated. Target should be the start of | ||
| 167 | * error processing code. | ||
| 168 | */ | ||
| 169 | ins(BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, JMP_TO_ERROR_CODE), | ||
| 170 | pos); | ||
| 171 | |||
| 172 | return check_pos(pos); | ||
| 173 | } | ||
| 174 | |||
| 175 | /* | ||
| 176 | * Each arg should be bare register. Fetch and save them into argument | ||
| 177 | * registers (r3 - r5). | ||
| 178 | * | ||
| 179 | * BPF_REG_1 should have been initialized with pointer to | ||
| 180 | * 'struct pt_regs'. | ||
| 181 | */ | ||
| 182 | static int | ||
| 183 | gen_prologue_fastpath(struct bpf_insn_pos *pos, | ||
| 184 | struct probe_trace_arg *args, int nargs) | ||
| 185 | { | ||
| 186 | int i, err = 0; | ||
| 187 | |||
| 188 | for (i = 0; i < nargs; i++) { | ||
| 189 | err = gen_ldx_reg_from_ctx(pos, BPF_REG_1, args[i].value, | ||
| 190 | BPF_PROLOGUE_START_ARG_REG + i); | ||
| 191 | if (err) | ||
| 192 | goto errout; | ||
| 193 | } | ||
| 194 | |||
| 195 | return check_pos(pos); | ||
| 196 | errout: | ||
| 197 | return err; | ||
| 198 | } | ||
| 199 | |||
| 200 | /* | ||
| 201 | * Slow path: | ||
| 202 | * At least one argument has the form of 'offset($rx)'. | ||
| 203 | * | ||
| 204 | * Following code first stores them into stack, then loads all of then | ||
| 205 | * to r2 - r5. | ||
| 206 | * Before final loading, the final result should be: | ||
| 207 | * | ||
| 208 | * low address | ||
| 209 | * BPF_REG_FP - 24 ARG3 | ||
| 210 | * BPF_REG_FP - 16 ARG2 | ||
| 211 | * BPF_REG_FP - 8 ARG1 | ||
| 212 | * BPF_REG_FP | ||
| 213 | * high address | ||
| 214 | * | ||
| 215 | * For each argument (described as: offn(...off2(off1(reg)))), | ||
| 216 | * generates following code: | ||
| 217 | * | ||
| 218 | * r7 <- fp | ||
| 219 | * r7 <- r7 - stack_offset // Ideal code should initialize r7 using | ||
| 220 | * // fp before generating args. However, | ||
| 221 | * // eBPF won't regard r7 as stack pointer | ||
| 222 | * // if it is generated by minus 8 from | ||
| 223 | * // another stack pointer except fp. | ||
| 224 | * // This is why we have to set r7 | ||
| 225 | * // to fp for each variable. | ||
| 226 | * r3 <- value of 'reg'-> generated using gen_ldx_reg_from_ctx() | ||
| 227 | * (r7) <- r3 // skip following instructions for bare reg | ||
| 228 | * r3 <- r3 + off1 . // skip if off1 == 0 | ||
| 229 | * r2 <- 8 \ | ||
| 230 | * r1 <- r7 |-> generated by gen_read_mem() | ||
| 231 | * call probe_read / | ||
| 232 | * jnei r0, 0, err ./ | ||
| 233 | * r3 <- (r7) | ||
| 234 | * r3 <- r3 + off2 . // skip if off2 == 0 | ||
| 235 | * r2 <- 8 \ // r2 may be broken by probe_read, so set again | ||
| 236 | * r1 <- r7 |-> generated by gen_read_mem() | ||
| 237 | * call probe_read / | ||
| 238 | * jnei r0, 0, err ./ | ||
| 239 | * ... | ||
| 240 | */ | ||
| 241 | static int | ||
| 242 | gen_prologue_slowpath(struct bpf_insn_pos *pos, | ||
| 243 | struct probe_trace_arg *args, int nargs) | ||
| 244 | { | ||
| 245 | int err, i, probeid; | ||
| 246 | |||
| 247 | for (i = 0; i < nargs; i++) { | ||
| 248 | struct probe_trace_arg *arg = &args[i]; | ||
| 249 | const char *reg = arg->value; | ||
| 250 | struct probe_trace_arg_ref *ref = NULL; | ||
| 251 | int stack_offset = (i + 1) * -8; | ||
| 252 | |||
| 253 | pr_debug("prologue: fetch arg %d, base reg is %s\n", | ||
| 254 | i, reg); | ||
| 255 | |||
| 256 | /* value of base register is stored into ARG3 */ | ||
| 257 | err = gen_ldx_reg_from_ctx(pos, BPF_REG_CTX, reg, | ||
| 258 | BPF_REG_ARG3); | ||
| 259 | if (err) { | ||
| 260 | pr_err("prologue: failed to get offset of register %s\n", | ||
| 261 | reg); | ||
| 262 | goto errout; | ||
| 263 | } | ||
| 264 | |||
| 265 | /* Make r7 the stack pointer. */ | ||
| 266 | ins(BPF_MOV64_REG(BPF_REG_7, BPF_REG_FP), pos); | ||
| 267 | /* r7 += -8 */ | ||
| 268 | ins(BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, stack_offset), pos); | ||
| 269 | /* | ||
| 270 | * Store r3 (base register) onto stack | ||
| 271 | * Ensure fp[offset] is set. | ||
| 272 | * fp is the only valid base register when storing | ||
| 273 | * into stack. We are not allowed to use r7 as base | ||
| 274 | * register here. | ||
| 275 | */ | ||
| 276 | ins(BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_ARG3, | ||
| 277 | stack_offset), pos); | ||
| 278 | |||
| 279 | ref = arg->ref; | ||
| 280 | probeid = BPF_FUNC_probe_read_kernel; | ||
| 281 | while (ref) { | ||
| 282 | pr_debug("prologue: arg %d: offset %ld\n", | ||
| 283 | i, ref->offset); | ||
| 284 | |||
| 285 | if (ref->user_access) | ||
| 286 | probeid = BPF_FUNC_probe_read_user; | ||
| 287 | |||
| 288 | err = gen_read_mem(pos, BPF_REG_3, BPF_REG_7, | ||
| 289 | ref->offset, probeid); | ||
| 290 | if (err) { | ||
| 291 | pr_err("prologue: failed to generate probe_read function call\n"); | ||
| 292 | goto errout; | ||
| 293 | } | ||
| 294 | |||
| 295 | ref = ref->next; | ||
| 296 | /* | ||
| 297 | * Load previous result into ARG3. Use | ||
| 298 | * BPF_REG_FP instead of r7 because verifier | ||
| 299 | * allows FP based addressing only. | ||
| 300 | */ | ||
| 301 | if (ref) | ||
| 302 | ins(BPF_LDX_MEM(BPF_DW, BPF_REG_ARG3, | ||
| 303 | BPF_REG_FP, stack_offset), pos); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | /* Final pass: read to registers */ | ||
| 308 | for (i = 0; i < nargs; i++) { | ||
| 309 | int insn_sz = (args[i].ref) ? argtype_to_ldx_size(args[i].type) : BPF_DW; | ||
| 310 | |||
| 311 | pr_debug("prologue: load arg %d, insn_sz is %s\n", | ||
| 312 | i, insn_sz_to_str(insn_sz)); | ||
| 313 | ins(BPF_LDX_MEM(insn_sz, BPF_PROLOGUE_START_ARG_REG + i, | ||
| 314 | BPF_REG_FP, -BPF_REG_SIZE * (i + 1)), pos); | ||
| 315 | } | ||
| 316 | |||
| 317 | ins(BPF_JMP_IMM(BPF_JA, BPF_REG_0, 0, JMP_TO_SUCCESS_CODE), pos); | ||
| 318 | |||
| 319 | return check_pos(pos); | ||
| 320 | errout: | ||
| 321 | return err; | ||
| 322 | } | ||
| 323 | |||
| 324 | static int | ||
| 325 | prologue_relocate(struct bpf_insn_pos *pos, struct bpf_insn *error_code, | ||
| 326 | struct bpf_insn *success_code, struct bpf_insn *user_code) | ||
| 327 | { | ||
| 328 | struct bpf_insn *insn; | ||
| 329 | |||
| 330 | if (check_pos(pos)) | ||
| 331 | return -BPF_LOADER_ERRNO__PROLOGUE2BIG; | ||
| 332 | |||
| 333 | for (insn = pos->begin; insn < pos->pos; insn++) { | ||
| 334 | struct bpf_insn *target; | ||
| 335 | u8 class = BPF_CLASS(insn->code); | ||
| 336 | u8 opcode; | ||
| 337 | |||
| 338 | if (class != BPF_JMP) | ||
| 339 | continue; | ||
| 340 | opcode = BPF_OP(insn->code); | ||
| 341 | if (opcode == BPF_CALL) | ||
| 342 | continue; | ||
| 343 | |||
| 344 | switch (insn->off) { | ||
| 345 | case JMP_TO_ERROR_CODE: | ||
| 346 | target = error_code; | ||
| 347 | break; | ||
| 348 | case JMP_TO_SUCCESS_CODE: | ||
| 349 | target = success_code; | ||
| 350 | break; | ||
| 351 | case JMP_TO_USER_CODE: | ||
| 352 | target = user_code; | ||
| 353 | break; | ||
| 354 | default: | ||
| 355 | pr_err("bpf prologue: internal error: relocation failed\n"); | ||
| 356 | return -BPF_LOADER_ERRNO__PROLOGUE; | ||
| 357 | } | ||
| 358 | |||
| 359 | insn->off = target - (insn + 1); | ||
| 360 | } | ||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | |||
| 364 | int bpf__gen_prologue(struct probe_trace_arg *args, int nargs, | ||
| 365 | struct bpf_insn *new_prog, size_t *new_cnt, | ||
| 366 | size_t cnt_space) | ||
| 367 | { | ||
| 368 | struct bpf_insn *success_code = NULL; | ||
| 369 | struct bpf_insn *error_code = NULL; | ||
| 370 | struct bpf_insn *user_code = NULL; | ||
| 371 | struct bpf_insn_pos pos; | ||
| 372 | bool fastpath = true; | ||
| 373 | int err = 0, i; | ||
| 374 | |||
| 375 | if (!new_prog || !new_cnt) | ||
| 376 | return -EINVAL; | ||
| 377 | |||
| 378 | if (cnt_space > BPF_MAXINSNS) | ||
| 379 | cnt_space = BPF_MAXINSNS; | ||
| 380 | |||
| 381 | pos.begin = new_prog; | ||
| 382 | pos.end = new_prog + cnt_space; | ||
| 383 | pos.pos = new_prog; | ||
| 384 | |||
| 385 | if (!nargs) { | ||
| 386 | ins(BPF_ALU64_IMM(BPF_MOV, BPF_PROLOGUE_FETCH_RESULT_REG, 0), | ||
| 387 | &pos); | ||
| 388 | |||
| 389 | if (check_pos(&pos)) | ||
| 390 | goto errout; | ||
| 391 | |||
| 392 | *new_cnt = pos_get_cnt(&pos); | ||
| 393 | return 0; | ||
| 394 | } | ||
| 395 | |||
| 396 | if (nargs > BPF_PROLOGUE_MAX_ARGS) { | ||
| 397 | pr_warning("bpf: prologue: %d arguments are dropped\n", | ||
| 398 | nargs - BPF_PROLOGUE_MAX_ARGS); | ||
| 399 | nargs = BPF_PROLOGUE_MAX_ARGS; | ||
| 400 | } | ||
| 401 | |||
| 402 | /* First pass: validation */ | ||
| 403 | for (i = 0; i < nargs; i++) { | ||
| 404 | struct probe_trace_arg_ref *ref = args[i].ref; | ||
| 405 | |||
| 406 | if (args[i].value[0] == '@') { | ||
| 407 | /* TODO: fetch global variable */ | ||
| 408 | pr_err("bpf: prologue: global %s%+ld not support\n", | ||
| 409 | args[i].value, ref ? ref->offset : 0); | ||
| 410 | return -ENOTSUP; | ||
| 411 | } | ||
| 412 | |||
| 413 | while (ref) { | ||
| 414 | /* fastpath is true if all args has ref == NULL */ | ||
| 415 | fastpath = false; | ||
| 416 | |||
| 417 | /* | ||
| 418 | * Instruction encodes immediate value using | ||
| 419 | * s32, ref->offset is long. On systems which | ||
| 420 | * can't fill long in s32, refuse to process if | ||
| 421 | * ref->offset too large (or small). | ||
| 422 | */ | ||
| 423 | #ifdef __LP64__ | ||
| 424 | #define OFFSET_MAX ((1LL << 31) - 1) | ||
| 425 | #define OFFSET_MIN ((1LL << 31) * -1) | ||
| 426 | if (ref->offset > OFFSET_MAX || | ||
| 427 | ref->offset < OFFSET_MIN) { | ||
| 428 | pr_err("bpf: prologue: offset out of bound: %ld\n", | ||
| 429 | ref->offset); | ||
| 430 | return -BPF_LOADER_ERRNO__PROLOGUEOOB; | ||
| 431 | } | ||
| 432 | #endif | ||
| 433 | ref = ref->next; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | pr_debug("prologue: pass validation\n"); | ||
| 437 | |||
| 438 | if (fastpath) { | ||
| 439 | /* If all variables are registers... */ | ||
| 440 | pr_debug("prologue: fast path\n"); | ||
| 441 | err = gen_prologue_fastpath(&pos, args, nargs); | ||
| 442 | if (err) | ||
| 443 | goto errout; | ||
| 444 | } else { | ||
| 445 | pr_debug("prologue: slow path\n"); | ||
| 446 | |||
| 447 | /* Initialization: move ctx to a callee saved register. */ | ||
| 448 | ins(BPF_MOV64_REG(BPF_REG_CTX, BPF_REG_ARG1), &pos); | ||
| 449 | |||
| 450 | err = gen_prologue_slowpath(&pos, args, nargs); | ||
| 451 | if (err) | ||
| 452 | goto errout; | ||
| 453 | /* | ||
| 454 | * start of ERROR_CODE (only slow pass needs error code) | ||
| 455 | * mov r2 <- 1 // r2 is error number | ||
| 456 | * mov r3 <- 0 // r3, r4... should be touched or | ||
| 457 | * // verifier would complain | ||
| 458 | * mov r4 <- 0 | ||
| 459 | * ... | ||
| 460 | * goto usercode | ||
| 461 | */ | ||
| 462 | error_code = pos.pos; | ||
| 463 | ins(BPF_ALU64_IMM(BPF_MOV, BPF_PROLOGUE_FETCH_RESULT_REG, 1), | ||
| 464 | &pos); | ||
| 465 | |||
| 466 | for (i = 0; i < nargs; i++) | ||
| 467 | ins(BPF_ALU64_IMM(BPF_MOV, | ||
| 468 | BPF_PROLOGUE_START_ARG_REG + i, | ||
| 469 | 0), | ||
| 470 | &pos); | ||
| 471 | ins(BPF_JMP_IMM(BPF_JA, BPF_REG_0, 0, JMP_TO_USER_CODE), | ||
| 472 | &pos); | ||
| 473 | } | ||
| 474 | |||
| 475 | /* | ||
| 476 | * start of SUCCESS_CODE: | ||
| 477 | * mov r2 <- 0 | ||
| 478 | * goto usercode // skip | ||
| 479 | */ | ||
| 480 | success_code = pos.pos; | ||
| 481 | ins(BPF_ALU64_IMM(BPF_MOV, BPF_PROLOGUE_FETCH_RESULT_REG, 0), &pos); | ||
| 482 | |||
| 483 | /* | ||
| 484 | * start of USER_CODE: | ||
| 485 | * Restore ctx to r1 | ||
| 486 | */ | ||
| 487 | user_code = pos.pos; | ||
| 488 | if (!fastpath) { | ||
| 489 | /* | ||
| 490 | * Only slow path needs restoring of ctx. In fast path, | ||
| 491 | * register are loaded directly from r1. | ||
| 492 | */ | ||
| 493 | ins(BPF_MOV64_REG(BPF_REG_ARG1, BPF_REG_CTX), &pos); | ||
| 494 | err = prologue_relocate(&pos, error_code, success_code, | ||
| 495 | user_code); | ||
| 496 | if (err) | ||
| 497 | goto errout; | ||
| 498 | } | ||
| 499 | |||
| 500 | err = check_pos(&pos); | ||
| 501 | if (err) | ||
| 502 | goto errout; | ||
| 503 | |||
| 504 | *new_cnt = pos_get_cnt(&pos); | ||
| 505 | return 0; | ||
| 506 | errout: | ||
| 507 | return err; | ||
| 508 | } | ||
| @@ -23,7 +23,9 @@ · 22 unmodified lines | |||
| 23 | #define MAX_CPUS 4096 | 23 | #define MAX_CPUS 4096 |
| 24 | 24 | ||
| 25 | // FIXME: These should come from system headers | 25 | // FIXME: These should come from system headers |
| 26 | #ifndef bool | ||
| 26 | typedef char bool; | 27 | typedef char bool; |
| 28 | #endif | ||
| 27 | typedef int pid_t; | 29 | typedef int pid_t; |
| 28 | typedef long long int __s64; | 30 | typedef long long int __s64; |
| 29 | typedef __s64 time64_t; | 31 | typedef __s64 time64_t; |
| @@ -80,16 +80,6 @@ struct hashmap { · 79 unmodified lines | |||
| 80 | size_t sz; | 80 | size_t sz; |
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| 83 | #define HASHMAP_INIT(hash_fn, equal_fn, ctx) { \ | ||
| 84 | .hash_fn = (hash_fn), \ | ||
| 85 | .equal_fn = (equal_fn), \ | ||
| 86 | .ctx = (ctx), \ | ||
| 87 | .buckets = NULL, \ | ||
| 88 | .cap = 0, \ | ||
| 89 | .cap_bits = 0, \ | ||
| 90 | .sz = 0, \ | ||
| 91 | } | ||
| 92 | |||
| 93 | void hashmap__init(struct hashmap *map, hashmap_hash_fn hash_fn, | 83 | void hashmap__init(struct hashmap *map, hashmap_hash_fn hash_fn, |
| 94 | hashmap_equal_fn equal_fn, void *ctx); | 84 | hashmap_equal_fn equal_fn, void *ctx); |
| 95 | struct hashmap *hashmap__new(hashmap_hash_fn hash_fn, | 85 | struct hashmap *hashmap__new(hashmap_hash_fn hash_fn, |
| @@ -520,7 +520,7 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, const char *name, · 519 unmodified lines | |||
| 520 | pmu_name = pe->pmu; | 520 | pmu_name = pe->pmu; |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | alias = malloc(sizeof(*alias)); | 523 | alias = zalloc(sizeof(*alias)); |
| 524 | if (!alias) | 524 | if (!alias) |
| 525 | return -ENOMEM; | 525 | return -ENOMEM; |
| 526 | 526 | ||
| @@ -92,7 +92,7 @@ endif · 91 unmodified lines | |||
| 92 | TARGETS += tmpfs | 92 | TARGETS += tmpfs |
| 93 | TARGETS += tpm2 | 93 | TARGETS += tpm2 |
| 94 | TARGETS += tty | 94 | TARGETS += tty |
| 95 | TARGETS += uevents | 95 | TARGETS += uevent |
| 96 | TARGETS += user | 96 | TARGETS += user |
| 97 | TARGETS += user_events | 97 | TARGETS += user_events |
| 98 | TARGETS += vDSO | 98 | TARGETS += vDSO |
| @@ -185,6 +185,8 @@ static void test_cubic(void) · 184 unmodified lines | |||
| 185 | 185 | ||
| 186 | do_test("bpf_cubic", NULL); | 186 | do_test("bpf_cubic", NULL); |
| 187 | 187 | ||
| 188 | ASSERT_EQ(cubic_skel->bss->bpf_cubic_acked_called, 1, "pkts_acked called"); | ||
| 189 | |||
| 188 | bpf_link__destroy(link); | 190 | bpf_link__destroy(link); |
| 189 | bpf_cubic__destroy(cubic_skel); | 191 | bpf_cubic__destroy(cubic_skel); |
| 190 | } | 192 | } |
| @@ -475,6 +475,55 @@ out: · 474 unmodified lines | |||
| 475 | test_sockmap_drop_prog__destroy(drop); | 475 | test_sockmap_drop_prog__destroy(drop); |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | static void test_sockmap_skb_verdict_peek(void) | ||
| 479 | { | ||
| 480 | int err, map, verdict, s, c1, p1, zero = 0, sent, recvd, avail; | ||
| 481 | struct test_sockmap_pass_prog *pass; | ||
| 482 | char snd[256] = "0123456789"; | ||
| 483 | char rcv[256] = "0"; | ||
| 484 | |||
| 485 | pass = test_sockmap_pass_prog__open_and_load(); | ||
| 486 | if (!ASSERT_OK_PTR(pass, "open_and_load")) | ||
| 487 | return; | ||
| 488 | verdict = bpf_program__fd(pass->progs.prog_skb_verdict); | ||
| 489 | map = bpf_map__fd(pass->maps.sock_map_rx); | ||
| 490 | |||
| 491 | err = bpf_prog_attach(verdict, map, BPF_SK_SKB_STREAM_VERDICT, 0); | ||
| 492 | if (!ASSERT_OK(err, "bpf_prog_attach")) | ||
| 493 | goto out; | ||
| 494 | |||
| 495 | s = socket_loopback(AF_INET, SOCK_STREAM); | ||
| 496 | if (!ASSERT_GT(s, -1, "socket_loopback(s)")) | ||
| 497 | goto out; | ||
| 498 | |||
| 499 | err = create_pair(s, AF_INET, SOCK_STREAM, &c1, &p1); | ||
| 500 | if (!ASSERT_OK(err, "create_pairs(s)")) | ||
| 501 | goto out; | ||
| 502 | |||
| 503 | err = bpf_map_update_elem(map, &zero, &c1, BPF_NOEXIST); | ||
| 504 | if (!ASSERT_OK(err, "bpf_map_update_elem(c1)")) | ||
| 505 | goto out_close; | ||
| 506 | |||
| 507 | sent = xsend(p1, snd, sizeof(snd), 0); | ||
| 508 | ASSERT_EQ(sent, sizeof(snd), "xsend(p1)"); | ||
| 509 | recvd = recv(c1, rcv, sizeof(rcv), MSG_PEEK); | ||
| 510 | ASSERT_EQ(recvd, sizeof(rcv), "recv(c1)"); | ||
| 511 | err = ioctl(c1, FIONREAD, &avail); | ||
| 512 | ASSERT_OK(err, "ioctl(FIONREAD) error"); | ||
| 513 | ASSERT_EQ(avail, sizeof(snd), "after peek ioctl(FIONREAD)"); | ||
| 514 | recvd = recv(c1, rcv, sizeof(rcv), 0); | ||
| 515 | ASSERT_EQ(recvd, sizeof(rcv), "recv(p0)"); | ||
| 516 | err = ioctl(c1, FIONREAD, &avail); | ||
| 517 | ASSERT_OK(err, "ioctl(FIONREAD) error"); | ||
| 518 | ASSERT_EQ(avail, 0, "after read ioctl(FIONREAD)"); | ||
| 519 | |||
| 520 | out_close: | ||
| 521 | close(c1); | ||
| 522 | close(p1); | ||
| 523 | out: | ||
| 524 | test_sockmap_pass_prog__destroy(pass); | ||
| 525 | } | ||
| 526 | |||
| 478 | void test_sockmap_basic(void) | 527 | void test_sockmap_basic(void) |
| 479 | { | 528 | { |
| 480 | if (test__start_subtest("sockmap create_update_free")) | 529 | if (test__start_subtest("sockmap create_update_free")) |
| @@ -515,4 +564,6 @@ void test_sockmap_basic(void) · 34 unmodified lines | |||
| 515 | test_sockmap_skb_verdict_fionread(true); | 564 | test_sockmap_skb_verdict_fionread(true); |
| 516 | if (test__start_subtest("sockmap skb_verdict fionread on drop")) | 565 | if (test__start_subtest("sockmap skb_verdict fionread on drop")) |
| 517 | test_sockmap_skb_verdict_fionread(false); | 566 | test_sockmap_skb_verdict_fionread(false); |
| 567 | if (test__start_subtest("sockmap skb_verdict msg_f_peek")) | ||
| 568 | test_sockmap_skb_verdict_peek(); | ||
| 518 | } | 569 | } |
| @@ -2378,3 +2378,87 @@ void serial_test_tc_opts_chain_mixed(void) · 2377 unmodified lines | |||
| 2378 | test_tc_chain_mixed(BPF_TCX_INGRESS); | 2378 | test_tc_chain_mixed(BPF_TCX_INGRESS); |
| 2379 | test_tc_chain_mixed(BPF_TCX_EGRESS); | 2379 | test_tc_chain_mixed(BPF_TCX_EGRESS); |
| 2380 | } | 2380 | } |
| 2381 | |||
| 2382 | static int generate_dummy_prog(void) | ||
| 2383 | { | ||
| 2384 | const struct bpf_insn prog_insns[] = { | ||
| 2385 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 2386 | BPF_EXIT_INSN(), | ||
| 2387 | }; | ||
| 2388 | const size_t prog_insn_cnt = sizeof(prog_insns) / sizeof(struct bpf_insn); | ||
| 2389 | LIBBPF_OPTS(bpf_prog_load_opts, opts); | ||
| 2390 | const size_t log_buf_sz = 256; | ||
| 2391 | char *log_buf; | ||
| 2392 | int fd = -1; | ||
| 2393 | |||
| 2394 | log_buf = malloc(log_buf_sz); | ||
| 2395 | if (!ASSERT_OK_PTR(log_buf, "log_buf_alloc")) | ||
| 2396 | return fd; | ||
| 2397 | opts.log_buf = log_buf; | ||
| 2398 | opts.log_size = log_buf_sz; | ||
| 2399 | |||
| 2400 | log_buf[0] = '\0'; | ||
| 2401 | opts.log_level = 0; | ||
| 2402 | fd = bpf_prog_load(BPF_PROG_TYPE_SCHED_CLS, "tcx_prog", "GPL", | ||
| 2403 | prog_insns, prog_insn_cnt, &opts); | ||
| 2404 | ASSERT_STREQ(log_buf, "", "log_0"); | ||
| 2405 | ASSERT_GE(fd, 0, "prog_fd"); | ||
| 2406 | free(log_buf); | ||
| 2407 | return fd; | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | static void test_tc_opts_max_target(int target, int flags, bool relative) | ||
| 2411 | { | ||
| 2412 | int err, ifindex, i, prog_fd, last_fd = -1; | ||
| 2413 | LIBBPF_OPTS(bpf_prog_attach_opts, opta); | ||
| 2414 | const int max_progs = 63; | ||
| 2415 | |||
| 2416 | ASSERT_OK(system("ip link add dev tcx_opts1 type veth peer name tcx_opts2"), "add veth"); | ||
| 2417 | ifindex = if_nametoindex("tcx_opts1"); | ||
| 2418 | ASSERT_NEQ(ifindex, 0, "non_zero_ifindex"); | ||
| 2419 | |||
| 2420 | assert_mprog_count_ifindex(ifindex, target, 0); | ||
| 2421 | |||
| 2422 | for (i = 0; i < max_progs; i++) { | ||
| 2423 | prog_fd = generate_dummy_prog(); | ||
| 2424 | if (!ASSERT_GE(prog_fd, 0, "dummy_prog")) | ||
| 2425 | goto cleanup; | ||
| 2426 | err = bpf_prog_attach_opts(prog_fd, ifindex, target, &opta); | ||
| 2427 | if (!ASSERT_EQ(err, 0, "prog_attach")) | ||
| 2428 | goto cleanup; | ||
| 2429 | assert_mprog_count_ifindex(ifindex, target, i + 1); | ||
| 2430 | if (i == max_progs - 1 && relative) | ||
| 2431 | last_fd = prog_fd; | ||
| 2432 | else | ||
| 2433 | close(prog_fd); | ||
| 2434 | } | ||
| 2435 | |||
| 2436 | prog_fd = generate_dummy_prog(); | ||
| 2437 | if (!ASSERT_GE(prog_fd, 0, "dummy_prog")) | ||
| 2438 | goto cleanup; | ||
| 2439 | opta.flags = flags; | ||
| 2440 | if (last_fd > 0) | ||
| 2441 | opta.relative_fd = last_fd; | ||
| 2442 | err = bpf_prog_attach_opts(prog_fd, ifindex, target, &opta); | ||
| 2443 | ASSERT_EQ(err, -ERANGE, "prog_64_attach"); | ||
| 2444 | assert_mprog_count_ifindex(ifindex, target, max_progs); | ||
| 2445 | close(prog_fd); | ||
| 2446 | cleanup: | ||
| 2447 | if (last_fd > 0) | ||
| 2448 | close(last_fd); | ||
| 2449 | ASSERT_OK(system("ip link del dev tcx_opts1"), "del veth"); | ||
| 2450 | ASSERT_EQ(if_nametoindex("tcx_opts1"), 0, "dev1_removed"); | ||
| 2451 | ASSERT_EQ(if_nametoindex("tcx_opts2"), 0, "dev2_removed"); | ||
| 2452 | } | ||
| 2453 | |||
| 2454 | void serial_test_tc_opts_max(void) | ||
| 2455 | { | ||
| 2456 | test_tc_opts_max_target(BPF_TCX_INGRESS, 0, false); | ||
| 2457 | test_tc_opts_max_target(BPF_TCX_EGRESS, 0, false); | ||
| 2458 | |||
| 2459 | test_tc_opts_max_target(BPF_TCX_INGRESS, BPF_F_BEFORE, false); | ||
| 2460 | test_tc_opts_max_target(BPF_TCX_EGRESS, BPF_F_BEFORE, true); | ||
| 2461 | |||
| 2462 | test_tc_opts_max_target(BPF_TCX_INGRESS, BPF_F_AFTER, true); | ||
| 2463 | test_tc_opts_max_target(BPF_TCX_EGRESS, BPF_F_AFTER, false); | ||
| 2464 | } | ||
| @@ -490,6 +490,8 @@ static __always_inline void hystart_update(struct sock *sk, __u32 delay) · 489 unmodified lines | |||
| 490 | } | 490 | } |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | int bpf_cubic_acked_called = 0; | ||
| 494 | |||
| 493 | void BPF_STRUCT_OPS(bpf_cubic_acked, struct sock *sk, | 495 | void BPF_STRUCT_OPS(bpf_cubic_acked, struct sock *sk, |
| 494 | const struct ack_sample *sample) | 496 | const struct ack_sample *sample) |
| 495 | { | 497 | { |
| @@ -497,6 +499,7 @@ void BPF_STRUCT_OPS(bpf_cubic_acked, struct sock *sk, · 1 unmodified line | |||
| 497 | struct bictcp *ca = inet_csk_ca(sk); | 499 | struct bictcp *ca = inet_csk_ca(sk); |
| 498 | __u32 delay; | 500 | __u32 delay; |
| 499 | 501 | ||
| 502 | bpf_cubic_acked_called = 1; | ||
| 500 | /* Some calls are for duplicates without timetamps */ | 503 | /* Some calls are for duplicates without timetamps */ |
| 501 | if (sample->rtt_us < 0) | 504 | if (sample->rtt_us < 0) |
| 502 | return; | 505 | return; |
| @@ -1,6 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-or-later | 1 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | 2 | ||
| 3 | CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined $(KHDR_INCLUDES) | 3 | CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined -static-libasan $(KHDR_INCLUDES) |
| 4 | TEST_GEN_PROGS := fchmodat2_test | 4 | TEST_GEN_PROGS := fchmodat2_test |
| 5 | 5 | ||
| 6 | include ../lib.mk | 6 | include ../lib.mk |
| @@ -387,7 +387,7 @@ char *strdup_printf(const char *fmt, ...) · 386 unmodified lines | |||
| 387 | char *str; | 387 | char *str; |
| 388 | 388 | ||
| 389 | va_start(ap, fmt); | 389 | va_start(ap, fmt); |
| 390 | vasprintf(&str, fmt, ap); | 390 | TEST_ASSERT(vasprintf(&str, fmt, ap) >= 0, "vasprintf() failed"); |
| 391 | va_end(ap); | 391 | va_end(ap); |
| 392 | 392 | ||
| 393 | return str; | 393 | return str; |
| @@ -12,19 +12,37 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | #define REG_MASK (KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK) | 13 | #define REG_MASK (KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK) |
| 14 | 14 | ||
| 15 | static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX]; | ||
| 16 | |||
| 15 | bool filter_reg(__u64 reg) | 17 | bool filter_reg(__u64 reg) |
| 16 | { | 18 | { |
| 19 | switch (reg & ~REG_MASK) { | ||
| 17 | /* | 20 | /* |
| 18 | * Some ISA extensions are optional and not present on all host, | 21 | * Same set of ISA_EXT registers are not present on all host because |
| 19 | * but they can't be disabled through ISA_EXT registers when present. | 22 | * ISA_EXT registers are visible to the KVM user space based on the |
| 20 | * So, to make life easy, just filtering out these kind of registers. | 23 | * ISA extensions available on the host. Also, disabling an ISA |
| 24 | * extension using corresponding ISA_EXT register does not affect | ||
| 25 | * the visibility of the ISA_EXT register itself. | ||
| 26 | * | ||
| 27 | * Based on above, we should filter-out all ISA_EXT registers. | ||
| 21 | */ | 28 | */ |
| 22 | switch (reg & ~REG_MASK) { | 29 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_A: |
| 30 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_C: | ||
| 31 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_D: | ||
| 32 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_F: | ||
| 33 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_H: | ||
| 34 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_I: | ||
| 35 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_M: | ||
| 36 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVPBMT: | ||
| 23 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSTC: | 37 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSTC: |
| 24 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVINVAL: | 38 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVINVAL: |
| 25 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHINTPAUSE: | 39 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHINTPAUSE: |
| 40 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOM: | ||
| 41 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOZ: | ||
| 26 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBB: | 42 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBB: |
| 27 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA: | 43 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA: |
| 44 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_V: | ||
| 45 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVNAPOT: | ||
| 28 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBA: | 46 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBA: |
| 29 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBS: | 47 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBS: |
| 30 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICNTR: | 48 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICNTR: |
| @@ -32,6 +50,15 @@ bool filter_reg(__u64 reg) · 1 unmodified line | |||
| 32 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIFENCEI: | 50 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIFENCEI: |
| 33 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHPM: | 51 | case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHPM: |
| 34 | return true; | 52 | return true; |
| 53 | /* AIA registers are always available when Ssaia can't be disabled */ | ||
| 54 | case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(siselect): | ||
| 55 | case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1): | ||
| 56 | case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2): | ||
| 57 | case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(sieh): | ||
| 58 | case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(siph): | ||
| 59 | case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h): | ||
| 60 | case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h): | ||
| 61 | return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA]; | ||
| 35 | default: | 62 | default: |
| 36 | break; | 63 | break; |
| 37 | } | 64 | } |
| @@ -50,24 +77,27 @@ static inline bool vcpu_has_ext(struct kvm_vcpu *vcpu, int ext) · 12 unmodified lines | |||
| 50 | unsigned long value; | 77 | unsigned long value; |
| 51 | 78 | ||
| 52 | ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value); | 79 | ret = __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(ext), &value); |
| 53 | if (ret) { | 80 | return (ret) ? false : !!value; |
| 54 | printf("Failed to get ext %d", ext); | ||
| 55 | return false; | ||
| 56 | } | ||
| 57 | |||
| 58 | return !!value; | ||
| 59 | } | 81 | } |
| 60 | 82 | ||
| 61 | void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c) | 83 | void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c) |
| 62 | { | 84 | { |
| 85 | unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 }; | ||
| 63 | struct vcpu_reg_sublist *s; | 86 | struct vcpu_reg_sublist *s; |
| 87 | int rc; | ||
| 88 | |||
| 89 | for (int i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) | ||
| 90 | __vcpu_get_reg(vcpu, RISCV_ISA_EXT_REG(i), &isa_ext_state[i]); | ||
| 64 | 91 | ||
| 65 | /* | 92 | /* |
| 66 | * Disable all extensions which were enabled by default | 93 | * Disable all extensions which were enabled by default |
| 67 | * if they were available in the risc-v host. | 94 | * if they were available in the risc-v host. |
| 68 | */ | 95 | */ |
| 69 | for (int i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) | 96 | for (int i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) { |
| 70 | __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(i), 0); | 97 | rc = __vcpu_set_reg(vcpu, RISCV_ISA_EXT_REG(i), 0); |
| 98 | if (rc && isa_ext_state[i]) | ||
| 99 | isa_ext_cant_disable[i] = true; | ||
| 100 | } | ||
| 71 | 101 | ||
| 72 | for_each_sublist(c, s) { | 102 | for_each_sublist(c, s) { |
| 73 | if (!s->feature) | 103 | if (!s->feature) |
| @@ -506,10 +536,6 @@ static __u64 base_regs[] = { · 432 unmodified lines | |||
| 506 | KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(time), | 536 | KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(time), |
| 507 | KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(compare), | 537 | KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(compare), |
| 508 | KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(state), | 538 | KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(state), |
| 509 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_A, | ||
| 510 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_C, | ||
| 511 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_I, | ||
| 512 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_M, | ||
| 513 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_V01, | 539 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_V01, |
| 514 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_TIME, | 540 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_TIME, |
| 515 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_IPI, | 541 | KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_IPI, |
| @@ -25,7 +25,7 @@ if [[ "$1" == "-cgroup-v2" ]]; then · 24 unmodified lines | |||
| 25 | fi | 25 | fi |
| 26 | 26 | ||
| 27 | if [[ $cgroup2 ]]; then | 27 | if [[ $cgroup2 ]]; then |
| 28 | cgroup_path=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') | 28 | cgroup_path=$(mount -t cgroup2 | head -1 | awk '{print $3}') |
| 29 | if [[ -z "$cgroup_path" ]]; then | 29 | if [[ -z "$cgroup_path" ]]; then |
| 30 | cgroup_path=/dev/cgroup/memory | 30 | cgroup_path=/dev/cgroup/memory |
| 31 | mount -t cgroup2 none $cgroup_path | 31 | mount -t cgroup2 none $cgroup_path |
| @@ -33,7 +33,7 @@ if [[ $cgroup2 ]]; then · 1 unmodified line | |||
| 33 | fi | 33 | fi |
| 34 | echo "+hugetlb" >$cgroup_path/cgroup.subtree_control | 34 | echo "+hugetlb" >$cgroup_path/cgroup.subtree_control |
| 35 | else | 35 | else |
| 36 | cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') | 36 | cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') |
| 37 | if [[ -z "$cgroup_path" ]]; then | 37 | if [[ -z "$cgroup_path" ]]; then |
| 38 | cgroup_path=/dev/cgroup/memory | 38 | cgroup_path=/dev/cgroup/memory |
| 39 | mount -t cgroup memory,hugetlb $cgroup_path | 39 | mount -t cgroup memory,hugetlb $cgroup_path |
| @@ -20,7 +20,7 @@ fi · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | if [[ $cgroup2 ]]; then | 22 | if [[ $cgroup2 ]]; then |
| 23 | CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') | 23 | CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}') |
| 24 | if [[ -z "$CGROUP_ROOT" ]]; then | 24 | if [[ -z "$CGROUP_ROOT" ]]; then |
| 25 | CGROUP_ROOT=/dev/cgroup/memory | 25 | CGROUP_ROOT=/dev/cgroup/memory |
| 26 | mount -t cgroup2 none $CGROUP_ROOT | 26 | mount -t cgroup2 none $CGROUP_ROOT |
| @@ -28,7 +28,7 @@ if [[ $cgroup2 ]]; then · 1 unmodified line | |||
| 28 | fi | 28 | fi |
| 29 | echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control | 29 | echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control |
| 30 | else | 30 | else |
| 31 | CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') | 31 | CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') |
| 32 | if [[ -z "$CGROUP_ROOT" ]]; then | 32 | if [[ -z "$CGROUP_ROOT" ]]; then |
| 33 | CGROUP_ROOT=/dev/cgroup/memory | 33 | CGROUP_ROOT=/dev/cgroup/memory |
| 34 | mount -t cgroup memory,hugetlb $CGROUP_ROOT | 34 | mount -t cgroup memory,hugetlb $CGROUP_ROOT |
| @@ -6,13 +6,14 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \ · 5 unmodified lines | |||
| 6 | nft_concat_range.sh nft_conntrack_helper.sh \ | 6 | nft_concat_range.sh nft_conntrack_helper.sh \ |
| 7 | nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ | 7 | nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ |
| 8 | ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ | 8 | ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ |
| 9 | conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh | 9 | conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh \ |
| 10 | conntrack_sctp_collision.sh | ||
| 10 | 11 | ||
| 11 | HOSTPKG_CONFIG := pkg-config | 12 | HOSTPKG_CONFIG := pkg-config |
| 12 | 13 | ||
| 13 | CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null) | 14 | CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null) |
| 14 | LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) | 15 | LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) |
| 15 | 16 | ||
| 16 | TEST_GEN_FILES = nf-queue connect_close audit_logread | 17 | TEST_GEN_FILES = nf-queue connect_close audit_logread sctp_collision |
| 17 | 18 | ||
| 18 | include ../lib.mk | 19 | include ../lib.mk |
| @@ -0,0 +1,89 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # | ||
| 4 | # Testing For SCTP COLLISION SCENARIO as Below: | ||
| 5 | # | ||
| 6 | # 14:35:47.655279 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT] [init tag: 2017837359] | ||
| 7 | # 14:35:48.353250 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT] [init tag: 1187206187] | ||
| 8 | # 14:35:48.353275 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT ACK] [init tag: 2017837359] | ||
| 9 | # 14:35:48.353283 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [COOKIE ECHO] | ||
| 10 | # 14:35:48.353977 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [COOKIE ACK] | ||
| 11 | # 14:35:48.855335 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT ACK] [init tag: 164579970] | ||
| 12 | # | ||
| 13 | # TOPO: SERVER_NS (link0)<--->(link1) ROUTER_NS (link2)<--->(link3) CLIENT_NS | ||
| 14 | |||
| 15 | CLIENT_NS=$(mktemp -u client-XXXXXXXX) | ||
| 16 | CLIENT_IP="198.51.200.1" | ||
| 17 | CLIENT_PORT=1234 | ||
| 18 | |||
| 19 | SERVER_NS=$(mktemp -u server-XXXXXXXX) | ||
| 20 | SERVER_IP="198.51.100.1" | ||
| 21 | SERVER_PORT=1234 | ||
| 22 | |||
| 23 | ROUTER_NS=$(mktemp -u router-XXXXXXXX) | ||
| 24 | CLIENT_GW="198.51.200.2" | ||
| 25 | SERVER_GW="198.51.100.2" | ||
| 26 | |||
| 27 | # setup the topo | ||
| 28 | setup() { | ||
| 29 | ip net add $CLIENT_NS | ||
| 30 | ip net add $SERVER_NS | ||
| 31 | ip net add $ROUTER_NS | ||
| 32 | ip -n $SERVER_NS link add link0 type veth peer name link1 netns $ROUTER_NS | ||
| 33 | ip -n $CLIENT_NS link add link3 type veth peer name link2 netns $ROUTER_NS | ||
| 34 | |||
| 35 | ip -n $SERVER_NS link set link0 up | ||
| 36 | ip -n $SERVER_NS addr add $SERVER_IP/24 dev link0 | ||
| 37 | ip -n $SERVER_NS route add $CLIENT_IP dev link0 via $SERVER_GW | ||
| 38 | |||
| 39 | ip -n $ROUTER_NS link set link1 up | ||
| 40 | ip -n $ROUTER_NS link set link2 up | ||
| 41 | ip -n $ROUTER_NS addr add $SERVER_GW/24 dev link1 | ||
| 42 | ip -n $ROUTER_NS addr add $CLIENT_GW/24 dev link2 | ||
| 43 | ip net exec $ROUTER_NS sysctl -wq net.ipv4.ip_forward=1 | ||
| 44 | |||
| 45 | ip -n $CLIENT_NS link set link3 up | ||
| 46 | ip -n $CLIENT_NS addr add $CLIENT_IP/24 dev link3 | ||
| 47 | ip -n $CLIENT_NS route add $SERVER_IP dev link3 via $CLIENT_GW | ||
| 48 | |||
| 49 | # simulate the delay on OVS upcall by setting up a delay for INIT_ACK with | ||
| 50 | # tc on $SERVER_NS side | ||
| 51 | tc -n $SERVER_NS qdisc add dev link0 root handle 1: htb | ||
| 52 | tc -n $SERVER_NS class add dev link0 parent 1: classid 1:1 htb rate 100mbit | ||
| 53 | tc -n $SERVER_NS filter add dev link0 parent 1: protocol ip u32 match ip protocol 132 \ | ||
| 54 | 0xff match u8 2 0xff at 32 flowid 1:1 | ||
| 55 | tc -n $SERVER_NS qdisc add dev link0 parent 1:1 handle 10: netem delay 1200ms | ||
| 56 | |||
| 57 | # simulate the ctstate check on OVS nf_conntrack | ||
| 58 | ip net exec $ROUTER_NS iptables -A FORWARD -m state --state INVALID,UNTRACKED -j DROP | ||
| 59 | ip net exec $ROUTER_NS iptables -A INPUT -p sctp -j DROP | ||
| 60 | |||
| 61 | # use a smaller number for assoc's max_retrans to reproduce the issue | ||
| 62 | modprobe sctp | ||
| 63 | ip net exec $CLIENT_NS sysctl -wq net.sctp.association_max_retrans=3 | ||
| 64 | } | ||
| 65 | |||
| 66 | cleanup() { | ||
| 67 | ip net exec $CLIENT_NS pkill sctp_collision 2>&1 >/dev/null | ||
| 68 | ip net exec $SERVER_NS pkill sctp_collision 2>&1 >/dev/null | ||
| 69 | ip net del "$CLIENT_NS" | ||
| 70 | ip net del "$SERVER_NS" | ||
| 71 | ip net del "$ROUTER_NS" | ||
| 72 | } | ||
| 73 | |||
| 74 | do_test() { | ||
| 75 | ip net exec $SERVER_NS ./sctp_collision server \ | ||
| 76 | $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT & | ||
| 77 | ip net exec $CLIENT_NS ./sctp_collision client \ | ||
| 78 | $CLIENT_IP $CLIENT_PORT $SERVER_IP $SERVER_PORT | ||
| 79 | } | ||
| 80 | |||
| 81 | # NOTE: one way to work around the issue is set a smaller hb_interval | ||
| 82 | # ip net exec $CLIENT_NS sysctl -wq net.sctp.hb_interval=3500 | ||
| 83 | |||
| 84 | # run the test case | ||
| 85 | trap cleanup EXIT | ||
| 86 | setup && \ | ||
| 87 | echo "Test for SCTP Collision in nf_conntrack:" && \ | ||
| 88 | do_test && echo "PASS!" | ||
| 89 | exit $? | ||
| @@ -12,10 +12,11 @@ nft --version >/dev/null 2>&1 || { · 11 unmodified lines | |||
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | logfile=$(mktemp) | 14 | logfile=$(mktemp) |
| 15 | rulefile=$(mktemp) | ||
| 15 | echo "logging into $logfile" | 16 | echo "logging into $logfile" |
| 16 | ./audit_logread >"$logfile" & | 17 | ./audit_logread >"$logfile" & |
| 17 | logread_pid=$! | 18 | logread_pid=$! |
| 18 | trap 'kill $logread_pid; rm -f $logfile' EXIT | 19 | trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT |
| 19 | exec 3<"$logfile" | 20 | exec 3<"$logfile" |
| 20 | 21 | ||
| 21 | do_test() { # (cmd, log) | 22 | do_test() { # (cmd, log) |
| @@ -26,12 +27,14 @@ do_test() { # (cmd, log) · 4 unmodified lines | |||
| 26 | res=$(diff -a -u <(echo "$2") - <&3) | 27 | res=$(diff -a -u <(echo "$2") - <&3) |
| 27 | [ $? -eq 0 ] && { echo "OK"; return; } | 28 | [ $? -eq 0 ] && { echo "OK"; return; } |
| 28 | echo "FAIL" | 29 | echo "FAIL" |
| 29 | echo "$res" | 30 | grep -v '^\(---\|+++\|@@\)' <<< "$res" |
| 30 | ((RC++)) | 31 | ((RC--)) |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | nft flush ruleset | 34 | nft flush ruleset |
| 34 | 35 | ||
| 36 | # adding tables, chains and rules | ||
| 37 | |||
| 35 | for table in t1 t2; do | 38 | for table in t1 t2; do |
| 36 | do_test "nft add table $table" \ | 39 | do_test "nft add table $table" \ |
| 37 | "table=$table family=2 entries=1 op=nft_register_table" | 40 | "table=$table family=2 entries=1 op=nft_register_table" |
| @@ -62,6 +65,48 @@ for table in t1 t2; do · 24 unmodified lines | |||
| 62 | "table=$table family=2 entries=6 op=nft_register_rule" | 65 | "table=$table family=2 entries=6 op=nft_register_rule" |
| 63 | done | 66 | done |
| 64 | 67 | ||
| 68 | for ((i = 0; i < 500; i++)); do | ||
| 69 | echo "add rule t2 c3 counter accept comment \"rule $i\"" | ||
| 70 | done >$rulefile | ||
| 71 | do_test "nft -f $rulefile" \ | ||
| 72 | 'table=t2 family=2 entries=500 op=nft_register_rule' | ||
| 73 | |||
| 74 | # adding sets and elements | ||
| 75 | |||
| 76 | settype='type inet_service; counter' | ||
| 77 | setelem='{ 22, 80, 443 }' | ||
| 78 | setblock="{ $settype; elements = $setelem; }" | ||
| 79 | do_test "nft add set t1 s $setblock" \ | ||
| 80 | "table=t1 family=2 entries=4 op=nft_register_set" | ||
| 81 | |||
| 82 | do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \ | ||
| 83 | "table=t1 family=2 entries=5 op=nft_register_set" | ||
| 84 | |||
| 85 | do_test "nft add element t1 s3 $setelem" \ | ||
| 86 | "table=t1 family=2 entries=3 op=nft_register_setelem" | ||
| 87 | |||
| 88 | # adding counters | ||
| 89 | |||
| 90 | do_test 'nft add counter t1 c1' \ | ||
| 91 | 'table=t1 family=2 entries=1 op=nft_register_obj' | ||
| 92 | |||
| 93 | do_test 'nft add counter t2 c1; add counter t2 c2' \ | ||
| 94 | 'table=t2 family=2 entries=2 op=nft_register_obj' | ||
| 95 | |||
| 96 | # adding/updating quotas | ||
| 97 | |||
| 98 | do_test 'nft add quota t1 q1 { 10 bytes }' \ | ||
| 99 | 'table=t1 family=2 entries=1 op=nft_register_obj' | ||
| 100 | |||
| 101 | do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \ | ||
| 102 | 'table=t2 family=2 entries=2 op=nft_register_obj' | ||
| 103 | |||
| 104 | # changing the quota value triggers obj update path | ||
| 105 | do_test 'nft add quota t1 q1 { 20 bytes }' \ | ||
| 106 | 'table=t1 family=2 entries=1 op=nft_register_obj' | ||
| 107 | |||
| 108 | # resetting rules | ||
| 109 | |||
| 65 | do_test 'nft reset rules t1 c2' \ | 110 | do_test 'nft reset rules t1 c2' \ |
| 66 | 'table=t1 family=2 entries=3 op=nft_reset_rule' | 111 | 'table=t1 family=2 entries=3 op=nft_reset_rule' |
| 67 | 112 | ||
| @@ -70,19 +115,6 @@ do_test 'nft reset rules table t1' \ · 2 unmodified lines | |||
| 70 | table=t1 family=2 entries=3 op=nft_reset_rule | 115 | table=t1 family=2 entries=3 op=nft_reset_rule |
| 71 | table=t1 family=2 entries=3 op=nft_reset_rule' | 116 | table=t1 family=2 entries=3 op=nft_reset_rule' |
| 72 | 117 | ||
| 73 | do_test 'nft reset rules' \ | ||
| 74 | 'table=t1 family=2 entries=3 op=nft_reset_rule | ||
| 75 | table=t1 family=2 entries=3 op=nft_reset_rule | ||
| 76 | table=t1 family=2 entries=3 op=nft_reset_rule | ||
| 77 | table=t2 family=2 entries=3 op=nft_reset_rule | ||
| 78 | table=t2 family=2 entries=3 op=nft_reset_rule | ||
| 79 | table=t2 family=2 entries=3 op=nft_reset_rule' | ||
| 80 | |||
| 81 | for ((i = 0; i < 500; i++)); do | ||
| 82 | echo "add rule t2 c3 counter accept comment \"rule $i\"" | ||
| 83 | done | do_test 'nft -f -' \ | ||
| 84 | 'table=t2 family=2 entries=500 op=nft_register_rule' | ||
| 85 | |||
| 86 | do_test 'nft reset rules t2 c3' \ | 118 | do_test 'nft reset rules t2 c3' \ |
| 87 | 'table=t2 family=2 entries=189 op=nft_reset_rule | 119 | 'table=t2 family=2 entries=189 op=nft_reset_rule |
| 88 | table=t2 family=2 entries=188 op=nft_reset_rule | 120 | table=t2 family=2 entries=188 op=nft_reset_rule |
| @@ -105,4 +137,57 @@ table=t2 family=2 entries=180 op=nft_reset_rule · 16 unmodified lines | |||
| 105 | table=t2 family=2 entries=188 op=nft_reset_rule | 137 | table=t2 family=2 entries=188 op=nft_reset_rule |
| 106 | table=t2 family=2 entries=135 op=nft_reset_rule' | 138 | table=t2 family=2 entries=135 op=nft_reset_rule' |
| 107 | 139 | ||
| 140 | # resetting sets and elements | ||
| 141 | |||
| 142 | elem=(22 ,80 ,443) | ||
| 143 | relem="" | ||
| 144 | for i in {1..3}; do | ||
| 145 | relem+="${elem[((i - 1))]}" | ||
| 146 | do_test "nft reset element t1 s { $relem }" \ | ||
| 147 | "table=t1 family=2 entries=$i op=nft_reset_setelem" | ||
| 148 | done | ||
| 149 | |||
| 150 | do_test 'nft reset set t1 s' \ | ||
| 151 | 'table=t1 family=2 entries=3 op=nft_reset_setelem' | ||
| 152 | |||
| 153 | # deleting rules | ||
| 154 | |||
| 155 | readarray -t handles < <(nft -a list chain t1 c1 | \ | ||
| 156 | sed -n 's/.*counter.* handle \(.*\)$/\1/p') | ||
| 157 | |||
| 158 | do_test "nft delete rule t1 c1 handle ${handles[0]}" \ | ||
| 159 | 'table=t1 family=2 entries=1 op=nft_unregister_rule' | ||
| 160 | |||
| 161 | cmd='delete rule t1 c1 handle' | ||
| 162 | do_test "nft $cmd ${handles[1]}; $cmd ${handles[2]}" \ | ||
| 163 | 'table=t1 family=2 entries=2 op=nft_unregister_rule' | ||
| 164 | |||
| 165 | do_test 'nft flush chain t1 c2' \ | ||
| 166 | 'table=t1 family=2 entries=3 op=nft_unregister_rule' | ||
| 167 | |||
| 168 | do_test 'nft flush table t2' \ | ||
| 169 | 'table=t2 family=2 entries=509 op=nft_unregister_rule' | ||
| 170 | |||
| 171 | # deleting chains | ||
| 172 | |||
| 173 | do_test 'nft delete chain t2 c2' \ | ||
| 174 | 'table=t2 family=2 entries=1 op=nft_unregister_chain' | ||
| 175 | |||
| 176 | # deleting sets and elements | ||
| 177 | |||
| 178 | do_test 'nft delete element t1 s { 22 }' \ | ||
| 179 | 'table=t1 family=2 entries=1 op=nft_unregister_setelem' | ||
| 180 | |||
| 181 | do_test 'nft delete element t1 s { 80, 443 }' \ | ||
| 182 | 'table=t1 family=2 entries=2 op=nft_unregister_setelem' | ||
| 183 | |||
| 184 | do_test 'nft flush set t1 s2' \ | ||
| 185 | 'table=t1 family=2 entries=3 op=nft_unregister_setelem' | ||
| 186 | |||
| 187 | do_test 'nft delete set t1 s2' \ | ||
| 188 | 'table=t1 family=2 entries=1 op=nft_unregister_set' | ||
| 189 | |||
| 190 | do_test 'nft delete set t1 s3' \ | ||
| 191 | 'table=t1 family=2 entries=1 op=nft_unregister_set' | ||
| 192 | |||
| 108 | exit $RC | 193 | exit $RC |
| @@ -0,0 +1,99 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | #include <stdio.h> | ||
| 4 | #include <stdlib.h> | ||
| 5 | #include <string.h> | ||
| 6 | #include <unistd.h> | ||
| 7 | #include <arpa/inet.h> | ||
| 8 | |||
| 9 | int main(int argc, char *argv[]) | ||
| 10 | { | ||
| 11 | struct sockaddr_in saddr = {}, daddr = {}; | ||
| 12 | int sd, ret, len = sizeof(daddr); | ||
| 13 | struct timeval tv = {25, 0}; | ||
| 14 | char buf[] = "hello"; | ||
| 15 | |||
| 16 | if (argc != 6 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) { | ||
| 17 | printf("%s <server|client> <LOCAL_IP> <LOCAL_PORT> <REMOTE_IP> <REMOTE_PORT>\n", | ||
| 18 | argv[0]); | ||
| 19 | return -1; | ||
| 20 | } | ||
| 21 | |||
| 22 | sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); | ||
| 23 | if (sd < 0) { | ||
| 24 | printf("Failed to create sd\n"); | ||
| 25 | return -1; | ||
| 26 | } | ||
| 27 | |||
| 28 | saddr.sin_family = AF_INET; | ||
| 29 | saddr.sin_addr.s_addr = inet_addr(argv[2]); | ||
| 30 | saddr.sin_port = htons(atoi(argv[3])); | ||
| 31 | |||
| 32 | ret = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr)); | ||
| 33 | if (ret < 0) { | ||
| 34 | printf("Failed to bind to address\n"); | ||
| 35 | goto out; | ||
| 36 | } | ||
| 37 | |||
| 38 | ret = listen(sd, 5); | ||
| 39 | if (ret < 0) { | ||
| 40 | printf("Failed to listen on port\n"); | ||
| 41 | goto out; | ||
| 42 | } | ||
| 43 | |||
| 44 | daddr.sin_family = AF_INET; | ||
| 45 | daddr.sin_addr.s_addr = inet_addr(argv[4]); | ||
| 46 | daddr.sin_port = htons(atoi(argv[5])); | ||
| 47 | |||
| 48 | /* make test shorter than 25s */ | ||
| 49 | ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); | ||
| 50 | if (ret < 0) { | ||
| 51 | printf("Failed to setsockopt SO_RCVTIMEO\n"); | ||
| 52 | goto out; | ||
| 53 | } | ||
| 54 | |||
| 55 | if (!strcmp(argv[1], "server")) { | ||
| 56 | sleep(1); /* wait a bit for client's INIT */ | ||
| 57 | ret = connect(sd, (struct sockaddr *)&daddr, len); | ||
| 58 | if (ret < 0) { | ||
| 59 | printf("Failed to connect to peer\n"); | ||
| 60 | goto out; | ||
| 61 | } | ||
| 62 | ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); | ||
| 63 | if (ret < 0) { | ||
| 64 | printf("Failed to recv msg %d\n", ret); | ||
| 65 | goto out; | ||
| 66 | } | ||
| 67 | ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); | ||
| 68 | if (ret < 0) { | ||
| 69 | printf("Failed to send msg %d\n", ret); | ||
| 70 | goto out; | ||
| 71 | } | ||
| 72 | printf("Server: sent! %d\n", ret); | ||
| 73 | } | ||
| 74 | |||
| 75 | if (!strcmp(argv[1], "client")) { | ||
| 76 | usleep(300000); /* wait a bit for server's listening */ | ||
| 77 | ret = connect(sd, (struct sockaddr *)&daddr, len); | ||
| 78 | if (ret < 0) { | ||
| 79 | printf("Failed to connect to peer\n"); | ||
| 80 | goto out; | ||
| 81 | } | ||
| 82 | sleep(1); /* wait a bit for server's delayed INIT_ACK to reproduce the issue */ | ||
| 83 | ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); | ||
| 84 | if (ret < 0) { | ||
| 85 | printf("Failed to send msg %d\n", ret); | ||
| 86 | goto out; | ||
| 87 | } | ||
| 88 | ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); | ||
| 89 | if (ret < 0) { | ||
| 90 | printf("Failed to recv msg %d\n", ret); | ||
| 91 | goto out; | ||
| 92 | } | ||
| 93 | printf("Client: rcvd! %d\n", ret); | ||
| 94 | } | ||
| 95 | ret = 0; | ||
| 96 | out: | ||
| 97 | close(sd); | ||
| 98 | return ret; | ||
| 99 | } | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-or-later | 1 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | 2 | ||
| 3 | CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined | 3 | CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined -static-libasan |
| 4 | TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test | 4 | TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test |
| 5 | 5 | ||
| 6 | include ../lib.mk | 6 | include ../lib.mk |
| @@ -59,12 +59,11 @@ override define INSTALL_RULE · 58 unmodified lines | |||
| 59 | done; | 59 | done; |
| 60 | endef | 60 | endef |
| 61 | 61 | ||
| 62 | override define EMIT_TESTS | 62 | emit_tests: |
| 63 | +@for TARGET in $(SUB_DIRS); do \ | 63 | +@for TARGET in $(SUB_DIRS); do \ |
| 64 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ | 64 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
| 65 | $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ | 65 | $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET $@;\ |
| 66 | done; | 66 | done; |
| 67 | endef | ||
| 68 | 67 | ||
| 69 | override define CLEAN | 68 | override define CLEAN |
| 70 | +@for TARGET in $(SUB_DIRS); do \ | 69 | +@for TARGET in $(SUB_DIRS); do \ |
| @@ -77,4 +76,4 @@ endef · 6 unmodified lines | |||
| 77 | tags: | 76 | tags: |
| 78 | find . -name '*.c' -o -name '*.h' | xargs ctags | 77 | find . -name '*.c' -o -name '*.h' | xargs ctags |
| 79 | 78 | ||
| 80 | .PHONY: tags $(SUB_DIRS) | 79 | .PHONY: tags $(SUB_DIRS) emit_tests |
| @@ -30,13 +30,14 @@ override define RUN_TESTS · 29 unmodified lines | |||
| 30 | +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests | 30 | +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests |
| 31 | endef | 31 | endef |
| 32 | 32 | ||
| 33 | DEFAULT_EMIT_TESTS := $(EMIT_TESTS) | 33 | emit_tests: |
| 34 | override define EMIT_TESTS | 34 | for TEST in $(TEST_GEN_PROGS); do \ |
| 35 | $(DEFAULT_EMIT_TESTS) | 35 | BASENAME_TEST=`basename $$TEST`; \ |
| 36 | echo "$(COLLECTION):$$BASENAME_TEST"; \ | ||
| 37 | done | ||
| 36 | +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests | 38 | +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests |
| 37 | +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests | 39 | +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests |
| 38 | +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests | 40 | +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests |
| 39 | endef | ||
| 40 | 41 | ||
| 41 | DEFAULT_INSTALL_RULE := $(INSTALL_RULE) | 42 | DEFAULT_INSTALL_RULE := $(INSTALL_RULE) |
| 42 | override define INSTALL_RULE | 43 | override define INSTALL_RULE |
| @@ -64,4 +65,4 @@ sampling_tests: · 21 unmodified lines | |||
| 64 | event_code_tests: | 65 | event_code_tests: |
| 65 | TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all | 66 | TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all |
| 66 | 67 | ||
| 67 | .PHONY: all run_tests ebb sampling_tests event_code_tests | 68 | .PHONY: all run_tests ebb sampling_tests event_code_tests emit_tests |
| @@ -267,6 +267,7 @@ static const char g_smaps_rollup[] = · 266 unmodified lines | |||
| 267 | "Private_Dirty: 0 kB\n" | 267 | "Private_Dirty: 0 kB\n" |
| 268 | "Referenced: 0 kB\n" | 268 | "Referenced: 0 kB\n" |
| 269 | "Anonymous: 0 kB\n" | 269 | "Anonymous: 0 kB\n" |
| 270 | "KSM: 0 kB\n" | ||
| 270 | "LazyFree: 0 kB\n" | 271 | "LazyFree: 0 kB\n" |
| 271 | "AnonHugePages: 0 kB\n" | 272 | "AnonHugePages: 0 kB\n" |
| 272 | "ShmemPmdMapped: 0 kB\n" | 273 | "ShmemPmdMapped: 0 kB\n" |
| @@ -91,16 +91,18 @@ static int reg_disable(long *enable, int bit) · 90 unmodified lines | |||
| 91 | 91 | ||
| 92 | FIXTURE(user) { | 92 | FIXTURE(user) { |
| 93 | long check; | 93 | long check; |
| 94 | bool umount; | ||
| 94 | }; | 95 | }; |
| 95 | 96 | ||
| 96 | FIXTURE_SETUP(user) { | 97 | FIXTURE_SETUP(user) { |
| 97 | USER_EVENT_FIXTURE_SETUP(return); | 98 | USER_EVENT_FIXTURE_SETUP(return, self->umount); |
| 98 | 99 | ||
| 99 | change_event(false); | 100 | change_event(false); |
| 100 | self->check = 0; | 101 | self->check = 0; |
| 101 | } | 102 | } |
| 102 | 103 | ||
| 103 | FIXTURE_TEARDOWN(user) { | 104 | FIXTURE_TEARDOWN(user) { |
| 105 | USER_EVENT_FIXTURE_TEARDOWN(self->umount); | ||
| 104 | } | 106 | } |
| 105 | 107 | ||
| 106 | TEST_F(user, enablement) { | 108 | TEST_F(user, enablement) { |
| @@ -144,13 +144,16 @@ do { \ · 143 unmodified lines | |||
| 144 | 144 | ||
| 145 | FIXTURE(user) { | 145 | FIXTURE(user) { |
| 146 | int check; | 146 | int check; |
| 147 | bool umount; | ||
| 147 | }; | 148 | }; |
| 148 | 149 | ||
| 149 | FIXTURE_SETUP(user) { | 150 | FIXTURE_SETUP(user) { |
| 150 | USER_EVENT_FIXTURE_SETUP(return); | 151 | USER_EVENT_FIXTURE_SETUP(return, self->umount); |
| 151 | } | 152 | } |
| 152 | 153 | ||
| 153 | FIXTURE_TEARDOWN(user) { | 154 | FIXTURE_TEARDOWN(user) { |
| 155 | USER_EVENT_FIXTURE_TEARDOWN(self->umount); | ||
| 156 | |||
| 154 | wait_for_delete(); | 157 | wait_for_delete(); |
| 155 | } | 158 | } |
| 156 | 159 | ||
| @@ -204,10 +204,11 @@ FIXTURE(user) { · 203 unmodified lines | |||
| 204 | int data_fd; | 204 | int data_fd; |
| 205 | int enable_fd; | 205 | int enable_fd; |
| 206 | int check; | 206 | int check; |
| 207 | bool umount; | ||
| 207 | }; | 208 | }; |
| 208 | 209 | ||
| 209 | FIXTURE_SETUP(user) { | 210 | FIXTURE_SETUP(user) { |
| 210 | USER_EVENT_FIXTURE_SETUP(return); | 211 | USER_EVENT_FIXTURE_SETUP(return, self->umount); |
| 211 | 212 | ||
| 212 | self->status_fd = open(status_file, O_RDONLY); | 213 | self->status_fd = open(status_file, O_RDONLY); |
| 213 | ASSERT_NE(-1, self->status_fd); | 214 | ASSERT_NE(-1, self->status_fd); |
| @@ -219,6 +220,8 @@ FIXTURE_SETUP(user) { · 5 unmodified lines | |||
| 219 | } | 220 | } |
| 220 | 221 | ||
| 221 | FIXTURE_TEARDOWN(user) { | 222 | FIXTURE_TEARDOWN(user) { |
| 223 | USER_EVENT_FIXTURE_TEARDOWN(self->umount); | ||
| 224 | |||
| 222 | close(self->status_fd); | 225 | close(self->status_fd); |
| 223 | close(self->data_fd); | 226 | close(self->data_fd); |
| 224 | 227 | ||
| @@ -111,16 +111,19 @@ static int clear(int *check) · 110 unmodified lines | |||
| 111 | FIXTURE(user) { | 111 | FIXTURE(user) { |
| 112 | int data_fd; | 112 | int data_fd; |
| 113 | int check; | 113 | int check; |
| 114 | bool umount; | ||
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | FIXTURE_SETUP(user) { | 117 | FIXTURE_SETUP(user) { |
| 117 | USER_EVENT_FIXTURE_SETUP(return); | 118 | USER_EVENT_FIXTURE_SETUP(return, self->umount); |
| 118 | 119 | ||
| 119 | self->data_fd = open(data_file, O_RDWR); | 120 | self->data_fd = open(data_file, O_RDWR); |
| 120 | ASSERT_NE(-1, self->data_fd); | 121 | ASSERT_NE(-1, self->data_fd); |
| 121 | } | 122 | } |
| 122 | 123 | ||
| 123 | FIXTURE_TEARDOWN(user) { | 124 | FIXTURE_TEARDOWN(user) { |
| 125 | USER_EVENT_FIXTURE_TEARDOWN(self->umount); | ||
| 126 | |||
| 124 | close(self->data_fd); | 127 | close(self->data_fd); |
| 125 | 128 | ||
| 126 | if (clear(&self->check) != 0) | 129 | if (clear(&self->check) != 0) |
| @@ -11,13 +11,19 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #include "../kselftest.h" | 12 | #include "../kselftest.h" |
| 13 | 13 | ||
| 14 | static inline bool tracefs_enabled(char **message, bool *fail) | 14 | static inline void tracefs_unmount(void) |
| 15 | { | ||
| 16 | umount("/sys/kernel/tracing"); | ||
| 17 | } | ||
| 18 | |||
| 19 | static inline bool tracefs_enabled(char **message, bool *fail, bool *umount) | ||
| 15 | { | 20 | { |
| 16 | struct stat buf; | 21 | struct stat buf; |
| 17 | int ret; | 22 | int ret; |
| 18 | 23 | ||
| 19 | *message = ""; | 24 | *message = ""; |
| 20 | *fail = false; | 25 | *fail = false; |
| 26 | *umount = false; | ||
| 21 | 27 | ||
| 22 | /* Ensure tracefs is installed */ | 28 | /* Ensure tracefs is installed */ |
| 23 | ret = stat("/sys/kernel/tracing", &buf); | 29 | ret = stat("/sys/kernel/tracing", &buf); |
| @@ -37,6 +43,8 @@ static inline bool tracefs_enabled(char **message, bool *fail) · 13 unmodified lines | |||
| 37 | return false; | 43 | return false; |
| 38 | } | 44 | } |
| 39 | 45 | ||
| 46 | *umount = true; | ||
| 47 | |||
| 40 | ret = stat("/sys/kernel/tracing/README", &buf); | 48 | ret = stat("/sys/kernel/tracing/README", &buf); |
| 41 | } | 49 | } |
| 42 | 50 | ||
| @@ -49,13 +57,14 @@ static inline bool tracefs_enabled(char **message, bool *fail) · 6 unmodified lines | |||
| 49 | return true; | 57 | return true; |
| 50 | } | 58 | } |
| 51 | 59 | ||
| 52 | static inline bool user_events_enabled(char **message, bool *fail) | 60 | static inline bool user_events_enabled(char **message, bool *fail, bool *umount) |
| 53 | { | 61 | { |
| 54 | struct stat buf; | 62 | struct stat buf; |
| 55 | int ret; | 63 | int ret; |
| 56 | 64 | ||
| 57 | *message = ""; | 65 | *message = ""; |
| 58 | *fail = false; | 66 | *fail = false; |
| 67 | *umount = false; | ||
| 59 | 68 | ||
| 60 | if (getuid() != 0) { | 69 | if (getuid() != 0) { |
| 61 | *message = "Must be run as root"; | 70 | *message = "Must be run as root"; |
| @@ -63,7 +72,7 @@ static inline bool user_events_enabled(char **message, bool *fail) · 1 unmodified line | |||
| 63 | return false; | 72 | return false; |
| 64 | } | 73 | } |
| 65 | 74 | ||
| 66 | if (!tracefs_enabled(message, fail)) | 75 | if (!tracefs_enabled(message, fail, umount)) |
| 67 | return false; | 76 | return false; |
| 68 | 77 | ||
| 69 | /* Ensure user_events is installed */ | 78 | /* Ensure user_events is installed */ |
| @@ -85,10 +94,10 @@ static inline bool user_events_enabled(char **message, bool *fail) · 15 unmodified lines | |||
| 85 | return true; | 94 | return true; |
| 86 | } | 95 | } |
| 87 | 96 | ||
| 88 | #define USER_EVENT_FIXTURE_SETUP(statement) do { \ | 97 | #define USER_EVENT_FIXTURE_SETUP(statement, umount) do { \ |
| 89 | char *message; \ | 98 | char *message; \ |
| 90 | bool fail; \ | 99 | bool fail; \ |
| 91 | if (!user_events_enabled(&message, &fail)) { \ | 100 | if (!user_events_enabled(&message, &fail, &(umount))) { \ |
| 92 | if (fail) { \ | 101 | if (fail) { \ |
| 93 | TH_LOG("Setup failed due to: %s", message); \ | 102 | TH_LOG("Setup failed due to: %s", message); \ |
| 94 | ASSERT_FALSE(fail); \ | 103 | ASSERT_FALSE(fail); \ |
| @@ -97,4 +106,9 @@ static inline bool user_events_enabled(char **message, bool *fail) · 2 unmodified lines | |||
| 97 | } \ | 106 | } \ |
| 98 | } while (0) | 107 | } while (0) |
| 99 | 108 | ||
| 109 | #define USER_EVENT_FIXTURE_TEARDOWN(umount) do { \ | ||
| 110 | if ((umount)) \ | ||
| 111 | tracefs_unmount(); \ | ||
| 112 | } while (0) | ||
| 113 | |||
| 100 | #endif /* _USER_EVENTS_SELFTESTS_H */ | 114 | #endif /* _USER_EVENTS_SELFTESTS_H */ |
| @@ -159,6 +159,7 @@ static int timerlat_aa_irq_latency(struct timerlat_aa_data *taa_data, · 158 unmodified lines | |||
| 159 | taa_data->thread_nmi_sum = 0; | 159 | taa_data->thread_nmi_sum = 0; |
| 160 | taa_data->thread_irq_sum = 0; | 160 | taa_data->thread_irq_sum = 0; |
| 161 | taa_data->thread_softirq_sum = 0; | 161 | taa_data->thread_softirq_sum = 0; |
| 162 | taa_data->thread_thread_sum = 0; | ||
| 162 | taa_data->thread_blocking_duration = 0; | 163 | taa_data->thread_blocking_duration = 0; |
| 163 | taa_data->timer_irq_start_time = 0; | 164 | taa_data->timer_irq_start_time = 0; |
| 164 | taa_data->timer_irq_duration = 0; | 165 | taa_data->timer_irq_duration = 0; |
| @@ -337,7 +338,23 @@ static int timerlat_aa_irq_handler(struct trace_seq *s, struct tep_record *recor · 172 unmodified lines | |||
| 337 | taa_data->timer_irq_start_time = start; | 338 | taa_data->timer_irq_start_time = start; |
| 338 | taa_data->timer_irq_duration = duration; | 339 | taa_data->timer_irq_duration = duration; |
| 339 | 340 | ||
| 340 | taa_data->timer_irq_start_delay = taa_data->timer_irq_start_time - expected_start; | 341 | /* |
| 342 | * We are dealing with two different clock sources: the | ||
| 343 | * external clock source that timerlat uses as a reference | ||
| 344 | * and the clock used by the tracer. There are also two | ||
| 345 | * moments: the time reading the clock and the timer in | ||
| 346 | * which the event is placed in the buffer (the trace | ||
| 347 | * event timestamp). If the processor is slow or there | ||
| 348 | * is some hardware noise, the difference between the | ||
| 349 | * timestamp and the external clock read can be longer | ||
| 350 | * than the IRQ handler delay, resulting in a negative | ||
| 351 | * time. If so, set IRQ start delay as 0. In the end, | ||
| 352 | * it is less relevant than the noise. | ||
| 353 | */ | ||
| 354 | if (expected_start < taa_data->timer_irq_start_time) | ||
| 355 | taa_data->timer_irq_start_delay = taa_data->timer_irq_start_time - expected_start; | ||
| 356 | else | ||
| 357 | taa_data->timer_irq_start_delay = 0; | ||
| 341 | 358 | ||
| 342 | /* | 359 | /* |
| 343 | * not exit from idle. | 360 | * not exit from idle. |
| @@ -528,7 +545,7 @@ static int timerlat_aa_kworker_start_handler(struct trace_seq *s, struct tep_rec · 184 unmodified lines | |||
| 528 | static void timerlat_thread_analysis(struct timerlat_aa_data *taa_data, int cpu, | 545 | static void timerlat_thread_analysis(struct timerlat_aa_data *taa_data, int cpu, |
| 529 | int irq_thresh, int thread_thresh) | 546 | int irq_thresh, int thread_thresh) |
| 530 | { | 547 | { |
| 531 | unsigned long long exp_irq_ts; | 548 | long long exp_irq_ts; |
| 532 | int total; | 549 | int total; |
| 533 | int irq; | 550 | int irq; |
| 534 | 551 | ||
| @@ -545,12 +562,15 @@ static void timerlat_thread_analysis(struct timerlat_aa_data *taa_data, int cpu, · 10 unmodified lines | |||
| 545 | 562 | ||
| 546 | /* | 563 | /* |
| 547 | * Expected IRQ arrival time using the trace clock as the base. | 564 | * Expected IRQ arrival time using the trace clock as the base. |
| 565 | * | ||
| 566 | * TODO: Add a list of previous IRQ, and then run the list backwards. | ||
| 548 | */ | 567 | */ |
| 549 | exp_irq_ts = taa_data->timer_irq_start_time - taa_data->timer_irq_start_delay; | 568 | exp_irq_ts = taa_data->timer_irq_start_time - taa_data->timer_irq_start_delay; |
| 550 | 569 | if (exp_irq_ts < taa_data->prev_irq_timstamp + taa_data->prev_irq_duration) { | |
| 551 | if (exp_irq_ts < taa_data->prev_irq_timstamp + taa_data->prev_irq_duration) | 570 | if (taa_data->prev_irq_timstamp < taa_data->timer_irq_start_time) |
| 552 | printf(" Previous IRQ interference: \t\t up to %9.2f us\n", | 571 | printf(" Previous IRQ interference: \t\t up to %9.2f us\n", |
| 553 | ns_to_usf(taa_data->prev_irq_duration)); | 572 | ns_to_usf(taa_data->prev_irq_duration)); |
| 573 | } | ||
| 554 | 574 | ||
| 555 | /* | 575 | /* |
| 556 | * The delay that the IRQ suffered before starting. | 576 | * The delay that the IRQ suffered before starting. |
| @@ -45,7 +45,7 @@ static int timerlat_u_main(int cpu, struct timerlat_u_params *params) · 44 unmodified lines | |||
| 45 | 45 | ||
| 46 | retval = sched_setaffinity(gettid(), sizeof(set), &set); | 46 | retval = sched_setaffinity(gettid(), sizeof(set), &set); |
| 47 | if (retval == -1) { | 47 | if (retval == -1) { |
| 48 | err_msg("Error setting user thread affinity\n"); | 48 | debug_msg("Error setting user thread affinity %d, is the CPU online?\n", cpu); |
| 49 | exit(1); | 49 | exit(1); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| @@ -193,7 +193,9 @@ void *timerlat_u_dispatcher(void *data) · 141 unmodified lines | |||
| 193 | procs_count--; | 193 | procs_count--; |
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | break; | 196 | |
| 197 | if (!procs_count) | ||
| 198 | break; | ||
| 197 | } | 199 | } |
| 198 | 200 | ||
| 199 | sleep(1); | 201 | sleep(1); |