We need the char/misc fixes in here as well.
Unified · Split
| @@ -70,6 +70,7 @@ Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com> · 69 unmodified lines | ||
| 70 | 70 | Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com> |
| 71 | 71 | Brian Avery <b.avery@hp.com> |
| 72 | 72 | Brian King <brking@us.ibm.com> |
| 73 | +Brian Silverman <bsilver16384@gmail.com> <brian.silverman@bluerivertech.com> | |
| 73 | 74 | Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com> |
| 74 | 75 | Changbin Du <changbin.du@intel.com> <changbin.du@intel.com> |
| 75 | 76 | Chao Yu <chao@kernel.org> <chao2.yu@samsung.com> |
| @@ -92,7 +92,8 @@ Triggers can be set on more than one psi metric and more than one trigger · 91 unmodified lines | ||
| 92 | 92 | for the same psi metric can be specified. However for each trigger a separate |
| 93 | 93 | file descriptor is required to be able to poll it separately from others, |
| 94 | 94 | therefore for each trigger a separate open() syscall should be made even |
| 95 | −when opening the same psi interface file. | |
| 95 | +when opening the same psi interface file. Write operations to a file descriptor | |
| 96 | +with an already existing psi trigger will fail with EBUSY. | |
| 96 | 97 | |
| 97 | 98 | Monitors activate only when system enters stall state for the monitored |
| 98 | 99 | psi metric and deactivates upon exit from the stall state. While system is |
| @@ -10,6 +10,7 @@ gpio · 9 unmodified lines | ||
| 10 | 10 | gpio-aggregator |
| 11 | 11 | sysfs |
| 12 | 12 | gpio-mockup |
| 13 | + gpio-sim | |
| 13 | 14 | |
| 14 | 15 | .. only:: subproject and html |
| 15 | 16 | |
| @@ -266,10 +266,12 @@ Avanta family · 265 unmodified lines | ||
| 266 | 266 | ------------- |
| 267 | 267 | |
| 268 | 268 | Flavors: |
| 269 | + - 88F6500 | |
| 269 | 270 | - 88F6510 |
| 270 | 271 | - 88F6530P |
| 271 | 272 | - 88F6550 |
| 272 | 273 | - 88F6560 |
| 274 | + - 88F6601 | |
| 273 | 275 | |
| 274 | 276 | Homepage: |
| 275 | 277 | https://web.archive.org/web/20181005145041/http://www.marvell.com/broadband/ |
| @@ -52,6 +52,12 @@ stable kernels. · 51 unmodified lines | ||
| 52 | 52 | | Allwinner | A64/R18 | UNKNOWN1 | SUN50I_ERRATUM_UNKNOWN1 | |
| 53 | 53 | +----------------+-----------------+-----------------+-----------------------------+ |
| 54 | 54 | +----------------+-----------------+-----------------+-----------------------------+ |
| 55 | +| ARM | Cortex-A510 | #2064142 | ARM64_ERRATUM_2064142 | | |
| 56 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 57 | +| ARM | Cortex-A510 | #2038923 | ARM64_ERRATUM_2038923 | | |
| 58 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 59 | +| ARM | Cortex-A510 | #1902691 | ARM64_ERRATUM_1902691 | | |
| 60 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 55 | 61 | | ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | |
| 56 | 62 | +----------------+-----------------+-----------------+-----------------------------+ |
| 57 | 63 | | ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 | |
| @@ -92,12 +98,18 @@ stable kernels. · 34 unmodified lines | ||
| 92 | 98 | +----------------+-----------------+-----------------+-----------------------------+ |
| 93 | 99 | | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | |
| 94 | 100 | +----------------+-----------------+-----------------+-----------------------------+ |
| 101 | +| ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 | | |
| 102 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 95 | 103 | | ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 | |
| 96 | 104 | +----------------+-----------------+-----------------+-----------------------------+ |
| 97 | 105 | | ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 | |
| 98 | 106 | +----------------+-----------------+-----------------+-----------------------------+ |
| 99 | 107 | | ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 | |
| 100 | 108 | +----------------+-----------------+-----------------+-----------------------------+ |
| 109 | +| ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 | | |
| 110 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 111 | +| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 | | |
| 112 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 101 | 113 | | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | |
| 102 | 114 | +----------------+-----------------+-----------------+-----------------------------+ |
| 103 | 115 | | ARM | Neoverse-N1 | #1349291 | N/A | |
| @@ -36,6 +36,7 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | - renesas,intc-ex-r8a77980 # R-Car V3H |
| 37 | 37 | - renesas,intc-ex-r8a77990 # R-Car E3 |
| 38 | 38 | - renesas,intc-ex-r8a77995 # R-Car D3 |
| 39 | + - renesas,intc-ex-r8a779a0 # R-Car V3U | |
| 39 | 40 | - const: renesas,irqc |
| 40 | 41 | |
| 41 | 42 | '#interrupt-cells': |
| @@ -62,6 +62,7 @@ properties: · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | interrupts-extended: |
| 64 | 64 | minItems: 1 |
| 65 | + maxItems: 15872 | |
| 65 | 66 | description: |
| 66 | 67 | Specifies which contexts are connected to the PLIC, with "-1" specifying |
| 67 | 68 | that a context is not present. Each node pointed to should be a |
| @@ -90,12 +91,11 @@ examples: · 22 unmodified lines | ||
| 90 | 91 | #interrupt-cells = <1>; |
| 91 | 92 | compatible = "sifive,fu540-c000-plic", "sifive,plic-1.0.0"; |
| 92 | 93 | interrupt-controller; |
| 93 | − interrupts-extended = < | |
| 94 | − &cpu0_intc 11 | |
| 95 | − &cpu1_intc 11 &cpu1_intc 9 | |
| 96 | − &cpu2_intc 11 &cpu2_intc 9 | |
| 97 | − &cpu3_intc 11 &cpu3_intc 9 | |
| 98 | − &cpu4_intc 11 &cpu4_intc 9>; | |
| 94 | + interrupts-extended = <&cpu0_intc 11>, | |
| 95 | + <&cpu1_intc 11>, <&cpu1_intc 9>, | |
| 96 | + <&cpu2_intc 11>, <&cpu2_intc 9>, | |
| 97 | + <&cpu3_intc 11>, <&cpu3_intc 9>, | |
| 98 | + <&cpu4_intc 11>, <&cpu4_intc 9>; | |
| 99 | 99 | reg = <0xc000000 0x4000000>; |
| 100 | 100 | riscv,ndev = <10>; |
| 101 | 101 | }; |
| @@ -31,7 +31,7 @@ tcan4x5x: tcan4x5x@0 { · 30 unmodified lines | ||
| 31 | 31 | #address-cells = <1>; |
| 32 | 32 | #size-cells = <1>; |
| 33 | 33 | spi-max-frequency = <10000000>; |
| 34 | − bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>; | |
| 34 | + bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>; | |
| 35 | 35 | interrupt-parent = <&gpio1>; |
| 36 | 36 | interrupts = <14 IRQ_TYPE_LEVEL_LOW>; |
| 37 | 37 | device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; |
| @@ -166,6 +166,7 @@ to ReStructured Text format, or are simply too old. · 165 unmodified lines | ||
| 166 | 166 | .. toctree:: |
| 167 | 167 | :maxdepth: 2 |
| 168 | 168 | |
| 169 | + tools/index | |
| 169 | 170 | staging/index |
| 170 | 171 | watch_queue |
| 171 | 172 | |
| @@ -295,7 +295,7 @@ Pete Zaitcev gives the following summary: · 294 unmodified lines | ||
| 295 | 295 | |
| 296 | 296 | - If you are in a process context (any syscall) and want to lock other |
| 297 | 297 | process out, use a mutex. You can take a mutex and sleep |
| 298 | − (``copy_from_user*(`` or ``kmalloc(x,GFP_KERNEL)``). | |
| 298 | + (``copy_from_user()`` or ``kmalloc(x,GFP_KERNEL)``). | |
| 299 | 299 | |
| 300 | 300 | - Otherwise (== data can be touched in an interrupt), use |
| 301 | 301 | spin_lock_irqsave() and |
| @@ -0,0 +1,20 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +============ | |
| 4 | +Kernel tools | |
| 5 | +============ | |
| 6 | + | |
| 7 | +This book covers user-space tools that are shipped with the kernel source; | |
| 8 | +more additions are needed here: | |
| 9 | + | |
| 10 | +.. toctree:: | |
| 11 | + :maxdepth: 1 | |
| 12 | + | |
| 13 | + rtla/index | |
| 14 | + | |
| 15 | +.. only:: subproject and html | |
| 16 | + | |
| 17 | + Indices | |
| 18 | + ======= | |
| 19 | + | |
| 20 | + * :ref:`genindex` | |
| @@ -0,0 +1,26 @@ | ||
| 1 | +.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +================================ | |
| 4 | +The realtime Linux analysis tool | |
| 5 | +================================ | |
| 6 | + | |
| 7 | +RTLA provides a set of tools for the analysis of the kernel's realtime | |
| 8 | +behavior on specific hardware. | |
| 9 | + | |
| 10 | +.. toctree:: | |
| 11 | + :maxdepth: 1 | |
| 12 | + | |
| 13 | + rtla | |
| 14 | + rtla-osnoise | |
| 15 | + rtla-osnoise-hist | |
| 16 | + rtla-osnoise-top | |
| 17 | + rtla-timerlat | |
| 18 | + rtla-timerlat-hist | |
| 19 | + rtla-timerlat-top | |
| 20 | + | |
| 21 | +.. only:: subproject and html | |
| 22 | + | |
| 23 | + Indices | |
| 24 | + ======= | |
| 25 | + | |
| 26 | + * :ref:`genindex` | |
| @@ -3268,6 +3268,7 @@ number. · 3267 unmodified lines | ||
| 3268 | 3268 | |
| 3269 | 3269 | :Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device, |
| 3270 | 3270 | KVM_CAP_VCPU_ATTRIBUTES for vcpu device |
| 3271 | + KVM_CAP_SYS_ATTRIBUTES for system (/dev/kvm) device (no set) | |
| 3271 | 3272 | :Type: device ioctl, vm ioctl, vcpu ioctl |
| 3272 | 3273 | :Parameters: struct kvm_device_attr |
| 3273 | 3274 | :Returns: 0 on success, -1 on error |
| @@ -3302,7 +3303,8 @@ transferred is defined by the particular attribute. · 28 unmodified lines | ||
| 3302 | 3303 | ------------------------ |
| 3303 | 3304 | |
| 3304 | 3305 | :Capability: KVM_CAP_DEVICE_CTRL, KVM_CAP_VM_ATTRIBUTES for vm device, |
| 3305 | − KVM_CAP_VCPU_ATTRIBUTES for vcpu device | |
| 3306 | + KVM_CAP_VCPU_ATTRIBUTES for vcpu device | |
| 3307 | + KVM_CAP_SYS_ATTRIBUTES for system (/dev/kvm) device | |
| 3306 | 3308 | :Type: device ioctl, vm ioctl, vcpu ioctl |
| 3307 | 3309 | :Parameters: struct kvm_device_attr |
| 3308 | 3310 | :Returns: 0 on success, -1 on error |
| @@ -9,7 +9,7 @@ Page Table Check · 8 unmodified lines | ||
| 9 | 9 | Introduction |
| 10 | 10 | ============ |
| 11 | 11 | |
| 12 | −Page table check allows to hardern the kernel by ensuring that some types of | |
| 12 | +Page table check allows to harden the kernel by ensuring that some types of | |
| 13 | 13 | the memory corruptions are prevented. |
| 14 | 14 | |
| 15 | 15 | Page table check performs extra verifications at the time when new pages become |
| @@ -190,8 +190,9 @@ M: Johannes Berg <johannes@sipsolutions.net> · 189 unmodified lines | ||
| 190 | 190 | L: linux-wireless@vger.kernel.org |
| 191 | 191 | S: Maintained |
| 192 | 192 | W: https://wireless.wiki.kernel.org/ |
| 193 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git | |
| 194 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git | |
| 193 | +Q: https://patchwork.kernel.org/project/linux-wireless/list/ | |
| 194 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git | |
| 195 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git | |
| 195 | 196 | F: Documentation/driver-api/80211/cfg80211.rst |
| 196 | 197 | F: Documentation/networking/regulatory.rst |
| 197 | 198 | F: include/linux/ieee80211.h |
| @@ -7208,8 +7209,10 @@ F: drivers/net/mdio/of_mdio.c · 7010 unmodified lines | ||
| 7208 | 7209 | F: drivers/net/pcs/ |
| 7209 | 7210 | F: drivers/net/phy/ |
| 7210 | 7211 | F: include/dt-bindings/net/qca-ar803x.h |
| 7212 | +F: include/linux/linkmode.h | |
| 7211 | 7213 | F: include/linux/*mdio*.h |
| 7212 | 7214 | F: include/linux/mdio/*.h |
| 7215 | +F: include/linux/mii.h | |
| 7213 | 7216 | F: include/linux/of_net.h |
| 7214 | 7217 | F: include/linux/phy.h |
| 7215 | 7218 | F: include/linux/phy_fixed.h |
| @@ -11366,8 +11369,9 @@ M: Johannes Berg <johannes@sipsolutions.net> · 4150 unmodified lines | ||
| 11366 | 11369 | L: linux-wireless@vger.kernel.org |
| 11367 | 11370 | S: Maintained |
| 11368 | 11371 | W: https://wireless.wiki.kernel.org/ |
| 11369 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git | |
| 11370 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git | |
| 11372 | +Q: https://patchwork.kernel.org/project/linux-wireless/list/ | |
| 11373 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git | |
| 11374 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git | |
| 11371 | 11375 | F: Documentation/networking/mac80211-injection.rst |
| 11372 | 11376 | F: Documentation/networking/mac80211_hwsim/mac80211_hwsim.rst |
| 11373 | 11377 | F: drivers/net/wireless/mac80211_hwsim.[ch] |
| @@ -13374,9 +13378,10 @@ NETWORKING DRIVERS (WIRELESS) · 2000 unmodified lines | ||
| 13374 | 13378 | M: Kalle Valo <kvalo@kernel.org> |
| 13375 | 13379 | L: linux-wireless@vger.kernel.org |
| 13376 | 13380 | S: Maintained |
| 13377 | −Q: http://patchwork.kernel.org/project/linux-wireless/list/ | |
| 13378 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git | |
| 13379 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git | |
| 13381 | +W: https://wireless.wiki.kernel.org/ | |
| 13382 | +Q: https://patchwork.kernel.org/project/linux-wireless/list/ | |
| 13383 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git | |
| 13384 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git | |
| 13380 | 13385 | F: Documentation/devicetree/bindings/net/wireless/ |
| 13381 | 13386 | F: drivers/net/wireless/ |
| 13382 | 13387 | |
| @@ -13449,7 +13454,11 @@ L: netdev@vger.kernel.org · 66 unmodified lines | ||
| 13449 | 13454 | S: Maintained |
| 13450 | 13455 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 13451 | 13456 | F: arch/x86/net/* |
| 13457 | +F: include/linux/ip.h | |
| 13458 | +F: include/linux/ipv6* | |
| 13459 | +F: include/net/fib* | |
| 13452 | 13460 | F: include/net/ip* |
| 13461 | +F: include/net/route.h | |
| 13453 | 13462 | F: net/ipv4/ |
| 13454 | 13463 | F: net/ipv6/ |
| 13455 | 13464 | |
| @@ -13510,10 +13519,6 @@ F: include/net/tls.h · 54 unmodified lines | ||
| 13510 | 13519 | F: include/uapi/linux/tls.h |
| 13511 | 13520 | F: net/tls/* |
| 13512 | 13521 | |
| 13513 | −NETWORKING [WIRELESS] | |
| 13514 | −L: linux-wireless@vger.kernel.org | |
| 13515 | −Q: http://patchwork.kernel.org/project/linux-wireless/list/ | |
| 13516 | − | |
| 13517 | 13522 | NETXEN (1/10) GbE SUPPORT |
| 13518 | 13523 | M: Manish Chopra <manishc@marvell.com> |
| 13519 | 13524 | M: Rahul Verma <rahulv@marvell.com> |
| @@ -16532,8 +16537,9 @@ M: Johannes Berg <johannes@sipsolutions.net> · 3012 unmodified lines | ||
| 16532 | 16537 | L: linux-wireless@vger.kernel.org |
| 16533 | 16538 | S: Maintained |
| 16534 | 16539 | W: https://wireless.wiki.kernel.org/ |
| 16535 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git | |
| 16536 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git | |
| 16540 | +Q: https://patchwork.kernel.org/project/linux-wireless/list/ | |
| 16541 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git | |
| 16542 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git | |
| 16537 | 16543 | F: Documentation/ABI/stable/sysfs-class-rfkill |
| 16538 | 16544 | F: Documentation/driver-api/rfkill.rst |
| 16539 | 16545 | F: include/linux/rfkill.h |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 17 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 5 | +EXTRAVERSION = -rc2 | |
| 6 | 6 | NAME = Gobble Gobble |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -83,6 +83,7 @@ config ARM · 82 unmodified lines | ||
| 83 | 83 | select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32 |
| 84 | 84 | select HAVE_CONTEXT_TRACKING |
| 85 | 85 | select HAVE_C_RECORDMCOUNT |
| 86 | + select HAVE_BUILDTIME_MCOUNT_SORT | |
| 86 | 87 | select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL |
| 87 | 88 | select HAVE_DMA_CONTIGUOUS if MMU |
| 88 | 89 | select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU |
| @@ -288,6 +288,7 @@ · 287 unmodified lines | ||
| 288 | 288 | */ |
| 289 | 289 | #define ALT_UP(instr...) \ |
| 290 | 290 | .pushsection ".alt.smp.init", "a" ;\ |
| 291 | + .align 2 ;\ | |
| 291 | 292 | .long 9998b - . ;\ |
| 292 | 293 | 9997: instr ;\ |
| 293 | 294 | .if . - 9997b == 2 ;\ |
| @@ -299,6 +300,7 @@ · 5 unmodified lines | ||
| 299 | 300 | .popsection |
| 300 | 301 | #define ALT_UP_B(label) \ |
| 301 | 302 | .pushsection ".alt.smp.init", "a" ;\ |
| 303 | + .align 2 ;\ | |
| 302 | 304 | .long 9998b - . ;\ |
| 303 | 305 | W(b) . + (label - 9998b) ;\ |
| 304 | 306 | .popsection |
| @@ -96,6 +96,7 @@ unsigned long __get_wchan(struct task_struct *p); · 95 unmodified lines | ||
| 96 | 96 | #define __ALT_SMP_ASM(smp, up) \ |
| 97 | 97 | "9998: " smp "\n" \ |
| 98 | 98 | " .pushsection \".alt.smp.init\", \"a\"\n" \ |
| 99 | + " .align 2\n" \ | |
| 99 | 100 | " .long 9998b - .\n" \ |
| 100 | 101 | " " up "\n" \ |
| 101 | 102 | " .popsection\n" |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/string.h> |
| 12 | 12 | #include <asm/memory.h> |
| 13 | 13 | #include <asm/domain.h> |
| 14 | +#include <asm/unaligned.h> | |
| 14 | 15 | #include <asm/unified.h> |
| 15 | 16 | #include <asm/compiler.h> |
| 16 | 17 | |
| @@ -497,7 +498,10 @@ do { \ · 480 unmodified lines | ||
| 497 | 498 | } \ |
| 498 | 499 | default: __err = __get_user_bad(); break; \ |
| 499 | 500 | } \ |
| 500 | − *(type *)(dst) = __val; \ | |
| 501 | + if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) \ | |
| 502 | + put_unaligned(__val, (type *)(dst)); \ | |
| 503 | + else \ | |
| 504 | + *(type *)(dst) = __val; /* aligned by caller */ \ | |
| 501 | 505 | if (__err) \ |
| 502 | 506 | goto err_label; \ |
| 503 | 507 | } while (0) |
| @@ -507,7 +511,9 @@ do { \ · 3 unmodified lines | ||
| 507 | 511 | const type *__pk_ptr = (dst); \ |
| 508 | 512 | unsigned long __dst = (unsigned long)__pk_ptr; \ |
| 509 | 513 | int __err = 0; \ |
| 510 | − type __val = *(type *)src; \ | |
| 514 | + type __val = IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) \ | |
| 515 | + ? get_unaligned((type *)(src)) \ | |
| 516 | + : *(type *)(src); /* aligned by caller */ \ | |
| 511 | 517 | switch (sizeof(type)) { \ |
| 512 | 518 | case 1: __put_user_asm_byte(__val, __dst, __err, ""); break; \ |
| 513 | 519 | case 2: __put_user_asm_half(__val, __dst, __err, ""); break; \ |
| @@ -1,4 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | +KASAN_SANITIZE_actions-common.o := n | |
| 3 | +KASAN_SANITIZE_actions-arm.o := n | |
| 4 | +KASAN_SANITIZE_actions-thumb.o := n | |
| 2 | 5 | obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o |
| 3 | 6 | obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o |
| 4 | 7 | test-kprobes-objs := test-core.o |
| @@ -670,15 +670,25 @@ config ARM64_ERRATUM_1508412 · 669 unmodified lines | ||
| 670 | 670 | config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE |
| 671 | 671 | bool |
| 672 | 672 | |
| 673 | +config ARM64_ERRATUM_2051678 | |
| 674 | + bool "Cortex-A510: 2051678: disable Hardware Update of the page table dirty bit" | |
| 675 | + help | |
| 676 | + This options adds the workaround for ARM Cortex-A510 erratum ARM64_ERRATUM_2051678. | |
| 677 | + Affected Coretex-A510 might not respect the ordering rules for | |
| 678 | + hardware update of the page table's dirty bit. The workaround | |
| 679 | + is to not enable the feature on affected CPUs. | |
| 680 | + | |
| 681 | + If unsure, say Y. | |
| 682 | + | |
| 673 | 683 | config ARM64_ERRATUM_2119858 |
| 674 | − bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode" | |
| 684 | + bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode" | |
| 675 | 685 | default y |
| 676 | 686 | depends on CORESIGHT_TRBE |
| 677 | 687 | select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE |
| 678 | 688 | help |
| 679 | − This option adds the workaround for ARM Cortex-A710 erratum 2119858. | |
| 689 | + This option adds the workaround for ARM Cortex-A710/X2 erratum 2119858. | |
| 680 | 690 | |
| 681 | − Affected Cortex-A710 cores could overwrite up to 3 cache lines of trace | |
| 691 | + Affected Cortex-A710/X2 cores could overwrite up to 3 cache lines of trace | |
| 682 | 692 | data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in |
| 683 | 693 | the event of a WRAP event. |
| 684 | 694 | |
| @@ -761,14 +771,14 @@ config ARM64_ERRATUM_2253138 · 76 unmodified lines | ||
| 761 | 771 | If unsure, say Y. |
| 762 | 772 | |
| 763 | 773 | config ARM64_ERRATUM_2224489 |
| 764 | − bool "Cortex-A710: 2224489: workaround TRBE writing to address out-of-range" | |
| 774 | + bool "Cortex-A710/X2: 2224489: workaround TRBE writing to address out-of-range" | |
| 765 | 775 | depends on CORESIGHT_TRBE |
| 766 | 776 | default y |
| 767 | 777 | select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE |
| 768 | 778 | help |
| 769 | − This option adds the workaround for ARM Cortex-A710 erratum 2224489. | |
| 779 | + This option adds the workaround for ARM Cortex-A710/X2 erratum 2224489. | |
| 770 | 780 | |
| 771 | − Affected Cortex-A710 cores might write to an out-of-range address, not reserved | |
| 781 | + Affected Cortex-A710/X2 cores might write to an out-of-range address, not reserved | |
| 772 | 782 | for TRBE. Under some conditions, the TRBE might generate a write to the next |
| 773 | 783 | virtually addressed page following the last page of the TRBE address space |
| 774 | 784 | (i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base. |
| @@ -778,6 +788,65 @@ config ARM64_ERRATUM_2224489 · 3 unmodified lines | ||
| 778 | 788 | |
| 779 | 789 | If unsure, say Y. |
| 780 | 790 | |
| 791 | +config ARM64_ERRATUM_2064142 | |
| 792 | + bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled" | |
| 793 | + depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in | |
| 794 | + default y | |
| 795 | + help | |
| 796 | + This option adds the workaround for ARM Cortex-A510 erratum 2064142. | |
| 797 | + | |
| 798 | + Affected Cortex-A510 core might fail to write into system registers after the | |
| 799 | + TRBE has been disabled. Under some conditions after the TRBE has been disabled | |
| 800 | + writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1, | |
| 801 | + and TRBTRG_EL1 will be ignored and will not be effected. | |
| 802 | + | |
| 803 | + Work around this in the driver by executing TSB CSYNC and DSB after collection | |
| 804 | + is stopped and before performing a system register write to one of the affected | |
| 805 | + registers. | |
| 806 | + | |
| 807 | + If unsure, say Y. | |
| 808 | + | |
| 809 | +config ARM64_ERRATUM_2038923 | |
| 810 | + bool "Cortex-A510: 2038923: workaround TRBE corruption with enable" | |
| 811 | + depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in | |
| 812 | + default y | |
| 813 | + help | |
| 814 | + This option adds the workaround for ARM Cortex-A510 erratum 2038923. | |
| 815 | + | |
| 816 | + Affected Cortex-A510 core might cause an inconsistent view on whether trace is | |
| 817 | + prohibited within the CPU. As a result, the trace buffer or trace buffer state | |
| 818 | + might be corrupted. This happens after TRBE buffer has been enabled by setting | |
| 819 | + TRBLIMITR_EL1.E, followed by just a single context synchronization event before | |
| 820 | + execution changes from a context, in which trace is prohibited to one where it | |
| 821 | + isn't, or vice versa. In these mentioned conditions, the view of whether trace | |
| 822 | + is prohibited is inconsistent between parts of the CPU, and the trace buffer or | |
| 823 | + the trace buffer state might be corrupted. | |
| 824 | + | |
| 825 | + Work around this in the driver by preventing an inconsistent view of whether the | |
| 826 | + trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a | |
| 827 | + change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or | |
| 828 | + two ISB instructions if no ERET is to take place. | |
| 829 | + | |
| 830 | + If unsure, say Y. | |
| 831 | + | |
| 832 | +config ARM64_ERRATUM_1902691 | |
| 833 | + bool "Cortex-A510: 1902691: workaround TRBE trace corruption" | |
| 834 | + depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in | |
| 835 | + default y | |
| 836 | + help | |
| 837 | + This option adds the workaround for ARM Cortex-A510 erratum 1902691. | |
| 838 | + | |
| 839 | + Affected Cortex-A510 core might cause trace data corruption, when being written | |
| 840 | + into the memory. Effectively TRBE is broken and hence cannot be used to capture | |
| 841 | + trace data. | |
| 842 | + | |
| 843 | + Work around this problem in the driver by just preventing TRBE initialization on | |
| 844 | + affected cpus. The firmware must have disabled the access to TRBE for the kernel | |
| 845 | + on such implementations. This will cover the kernel for any firmware that doesn't | |
| 846 | + do this already. | |
| 847 | + | |
| 848 | + If unsure, say Y. | |
| 849 | + | |
| 781 | 850 | config CAVIUM_ERRATUM_22375 |
| 782 | 851 | bool "Cavium erratum 22375, 24313" |
| 783 | 852 | default y |
| @@ -73,7 +73,9 @@ · 72 unmodified lines | ||
| 73 | 73 | #define ARM_CPU_PART_CORTEX_A76 0xD0B |
| 74 | 74 | #define ARM_CPU_PART_NEOVERSE_N1 0xD0C |
| 75 | 75 | #define ARM_CPU_PART_CORTEX_A77 0xD0D |
| 76 | +#define ARM_CPU_PART_CORTEX_A510 0xD46 | |
| 76 | 77 | #define ARM_CPU_PART_CORTEX_A710 0xD47 |
| 78 | +#define ARM_CPU_PART_CORTEX_X2 0xD48 | |
| 77 | 79 | #define ARM_CPU_PART_NEOVERSE_N2 0xD49 |
| 78 | 80 | |
| 79 | 81 | #define APM_CPU_PART_POTENZA 0x000 |
| @@ -115,7 +117,9 @@ · 35 unmodified lines | ||
| 115 | 117 | #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) |
| 116 | 118 | #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) |
| 117 | 119 | #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) |
| 120 | +#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) | |
| 118 | 121 | #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) |
| 122 | +#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) | |
| 119 | 123 | #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) |
| 120 | 124 | #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) |
| 121 | 125 | #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) |
| @@ -347,6 +347,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = { · 346 unmodified lines | ||
| 347 | 347 | #endif |
| 348 | 348 | #ifdef CONFIG_ARM64_ERRATUM_2119858 |
| 349 | 349 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), |
| 350 | + MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0), | |
| 350 | 351 | #endif |
| 351 | 352 | {}, |
| 352 | 353 | }; |
| @@ -371,6 +372,7 @@ static struct midr_range trbe_write_out_of_range_cpus[] = { · 18 unmodified lines | ||
| 371 | 372 | #endif |
| 372 | 373 | #ifdef CONFIG_ARM64_ERRATUM_2224489 |
| 373 | 374 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), |
| 375 | + MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0), | |
| 374 | 376 | #endif |
| 375 | 377 | {}, |
| 376 | 378 | }; |
| @@ -597,6 +599,33 @@ const struct arm64_cpu_capabilities arm64_errata[] = { · 220 unmodified lines | ||
| 597 | 599 | .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, |
| 598 | 600 | CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus), |
| 599 | 601 | }, |
| 602 | +#endif | |
| 603 | +#ifdef CONFIG_ARM64_ERRATUM_2064142 | |
| 604 | + { | |
| 605 | + .desc = "ARM erratum 2064142", | |
| 606 | + .capability = ARM64_WORKAROUND_2064142, | |
| 607 | + | |
| 608 | + /* Cortex-A510 r0p0 - r0p2 */ | |
| 609 | + ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2) | |
| 610 | + }, | |
| 611 | +#endif | |
| 612 | +#ifdef CONFIG_ARM64_ERRATUM_2038923 | |
| 613 | + { | |
| 614 | + .desc = "ARM erratum 2038923", | |
| 615 | + .capability = ARM64_WORKAROUND_2038923, | |
| 616 | + | |
| 617 | + /* Cortex-A510 r0p0 - r0p2 */ | |
| 618 | + ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2) | |
| 619 | + }, | |
| 620 | +#endif | |
| 621 | +#ifdef CONFIG_ARM64_ERRATUM_1902691 | |
| 622 | + { | |
| 623 | + .desc = "ARM erratum 1902691", | |
| 624 | + .capability = ARM64_WORKAROUND_1902691, | |
| 625 | + | |
| 626 | + /* Cortex-A510 r0p0 - r0p1 */ | |
| 627 | + ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1) | |
| 628 | + }, | |
| 600 | 629 | #endif |
| 601 | 630 | { |
| 602 | 631 | } |
| @@ -1645,6 +1645,9 @@ static bool cpu_has_broken_dbm(void) · 1644 unmodified lines | ||
| 1645 | 1645 | MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), |
| 1646 | 1646 | /* Kryo4xx Silver (rdpe => r1p0) */ |
| 1647 | 1647 | MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe), |
| 1648 | +#endif | |
| 1649 | +#ifdef CONFIG_ARM64_ERRATUM_2051678 | |
| 1650 | + MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2), | |
| 1648 | 1651 | #endif |
| 1649 | 1652 | {}, |
| 1650 | 1653 | }; |
| @@ -33,8 +33,8 @@ · 32 unmodified lines | ||
| 33 | 33 | */ |
| 34 | 34 | |
| 35 | 35 | |
| 36 | −static void start_backtrace(struct stackframe *frame, unsigned long fp, | |
| 37 | − unsigned long pc) | |
| 36 | +static notrace void start_backtrace(struct stackframe *frame, unsigned long fp, | |
| 37 | + unsigned long pc) | |
| 38 | 38 | { |
| 39 | 39 | frame->fp = fp; |
| 40 | 40 | frame->pc = pc; |
| @@ -55,6 +55,7 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp, · 14 unmodified lines | ||
| 55 | 55 | frame->prev_fp = 0; |
| 56 | 56 | frame->prev_type = STACK_TYPE_UNKNOWN; |
| 57 | 57 | } |
| 58 | +NOKPROBE_SYMBOL(start_backtrace); | |
| 58 | 59 | |
| 59 | 60 | /* |
| 60 | 61 | * Unwind from one frame record (A) to the next frame record (B). |
| @@ -29,8 +29,11 @@ ldflags-y := -shared -soname=linux-vdso.so.1 --hash-style=sysv \ · 28 unmodified lines | ||
| 29 | 29 | ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 |
| 30 | 30 | ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO |
| 31 | 31 | |
| 32 | +# -Wmissing-prototypes and -Wmissing-declarations are removed from | |
| 33 | +# the CFLAGS of vgettimeofday.c to make possible to build the | |
| 34 | +# kernel with CONFIG_WERROR enabled. | |
| 32 | 35 | CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \ |
| 33 | − $(CC_FLAGS_LTO) | |
| 36 | + $(CC_FLAGS_LTO) -Wmissing-prototypes -Wmissing-declarations | |
| 34 | 37 | KASAN_SANITIZE := n |
| 35 | 38 | KCSAN_SANITIZE := n |
| 36 | 39 | UBSAN_SANITIZE := n |
| @@ -38,7 +38,10 @@ static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) · 37 unmodified lines | ||
| 38 | 38 | |
| 39 | 39 | static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val) |
| 40 | 40 | { |
| 41 | − write_sysreg_el1(val, SYS_SPSR); | |
| 41 | + if (has_vhe()) | |
| 42 | + write_sysreg_el1(val, SYS_SPSR); | |
| 43 | + else | |
| 44 | + __vcpu_sys_reg(vcpu, SPSR_EL1) = val; | |
| 42 | 45 | } |
| 43 | 46 | |
| 44 | 47 | static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val) |
| @@ -983,13 +983,9 @@ static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, · 982 unmodified lines | ||
| 983 | 983 | */ |
| 984 | 984 | stage2_put_pte(ptep, mmu, addr, level, mm_ops); |
| 985 | 985 | |
| 986 | − if (need_flush) { | |
| 987 | − kvm_pte_t *pte_follow = kvm_pte_follow(pte, mm_ops); | |
| 988 | − | |
| 989 | − dcache_clean_inval_poc((unsigned long)pte_follow, | |
| 990 | − (unsigned long)pte_follow + | |
| 991 | − kvm_granule_size(level)); | |
| 992 | − } | |
| 986 | + if (need_flush && mm_ops->dcache_clean_inval_poc) | |
| 987 | + mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops), | |
| 988 | + kvm_granule_size(level)); | |
| 993 | 989 | |
| 994 | 990 | if (childp) |
| 995 | 991 | mm_ops->put_page(childp); |
| @@ -1151,15 +1147,13 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, · 155 unmodified lines | ||
| 1151 | 1147 | struct kvm_pgtable *pgt = arg; |
| 1152 | 1148 | struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops; |
| 1153 | 1149 | kvm_pte_t pte = *ptep; |
| 1154 | − kvm_pte_t *pte_follow; | |
| 1155 | 1150 | |
| 1156 | 1151 | if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte)) |
| 1157 | 1152 | return 0; |
| 1158 | 1153 | |
| 1159 | − pte_follow = kvm_pte_follow(pte, mm_ops); | |
| 1160 | − dcache_clean_inval_poc((unsigned long)pte_follow, | |
| 1161 | − (unsigned long)pte_follow + | |
| 1162 | − kvm_granule_size(level)); | |
| 1154 | + if (mm_ops->dcache_clean_inval_poc) | |
| 1155 | + mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops), | |
| 1156 | + kvm_granule_size(level)); | |
| 1163 | 1157 | return 0; |
| 1164 | 1158 | } |
| 1165 | 1159 | |
| @@ -983,6 +983,9 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt) · 982 unmodified lines | ||
| 983 | 983 | val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT; |
| 984 | 984 | /* IDbits */ |
| 985 | 985 | val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT; |
| 986 | + /* SEIS */ | |
| 987 | + if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) | |
| 988 | + val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT); | |
| 986 | 989 | /* A3V */ |
| 987 | 990 | val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT; |
| 988 | 991 | /* EOImode */ |
| @@ -609,6 +609,18 @@ static int __init early_gicv4_enable(char *buf) · 608 unmodified lines | ||
| 609 | 609 | } |
| 610 | 610 | early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable); |
| 611 | 611 | |
| 612 | +static const struct midr_range broken_seis[] = { | |
| 613 | + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM), | |
| 614 | + MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM), | |
| 615 | + {}, | |
| 616 | +}; | |
| 617 | + | |
| 618 | +static bool vgic_v3_broken_seis(void) | |
| 619 | +{ | |
| 620 | + return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) && | |
| 621 | + is_midr_in_range_list(read_cpuid_id(), broken_seis)); | |
| 622 | +} | |
| 623 | + | |
| 612 | 624 | /** |
| 613 | 625 | * vgic_v3_probe - probe for a VGICv3 compatible interrupt controller |
| 614 | 626 | * @info: pointer to the GIC description |
| @@ -676,9 +688,10 @@ int vgic_v3_probe(const struct gic_kvm_info *info) · 61 unmodified lines | ||
| 676 | 688 | group1_trap = true; |
| 677 | 689 | } |
| 678 | 690 | |
| 679 | − if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) { | |
| 680 | − kvm_info("GICv3 with locally generated SEI\n"); | |
| 691 | + if (vgic_v3_broken_seis()) { | |
| 692 | + kvm_info("GICv3 with broken locally generated SEI\n"); | |
| 681 | 693 | |
| 694 | + kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_SEIS_MASK; | |
| 682 | 695 | group0_trap = true; |
| 683 | 696 | group1_trap = true; |
| 684 | 697 | if (ich_vtr_el2 & ICH_VTR_TDS_MASK) |
| @@ -40,8 +40,8 @@ static bool · 39 unmodified lines | ||
| 40 | 40 | ex_handler_load_unaligned_zeropad(const struct exception_table_entry *ex, |
| 41 | 41 | struct pt_regs *regs) |
| 42 | 42 | { |
| 43 | − int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->type); | |
| 44 | − int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->type); | |
| 43 | + int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->data); | |
| 44 | + int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->data); | |
| 45 | 45 | unsigned long data, addr, offset; |
| 46 | 46 | |
| 47 | 47 | addr = pt_regs_read_reg(regs, reg_addr); |
| @@ -55,6 +55,9 @@ WORKAROUND_1418040 · 54 unmodified lines | ||
| 55 | 55 | WORKAROUND_1463225 |
| 56 | 56 | WORKAROUND_1508412 |
| 57 | 57 | WORKAROUND_1542419 |
| 58 | +WORKAROUND_2064142 | |
| 59 | +WORKAROUND_2038923 | |
| 60 | +WORKAROUND_1902691 | |
| 58 | 61 | WORKAROUND_TRBE_OVERWRITE_FILL_MODE |
| 59 | 62 | WORKAROUND_TSB_FLUSH_FAILURE |
| 60 | 63 | WORKAROUND_TRBE_WRITE_OUT_OF_RANGE |
| @@ -318,7 +318,7 @@ config ARCH_PROC_KCORE_TEXT · 317 unmodified lines | ||
| 318 | 318 | depends on PROC_KCORE |
| 319 | 319 | |
| 320 | 320 | config IA64_MCA_RECOVERY |
| 321 | − tristate "MCA recovery from errors other than TLB." | |
| 321 | + bool "MCA recovery from errors other than TLB." | |
| 322 | 322 | |
| 323 | 323 | config IA64_PALINFO |
| 324 | 324 | tristate "/proc/pal support" |
| @@ -76,5 +76,5 @@ static void pci_fixup_video(struct pci_dev *pdev) · 75 unmodified lines | ||
| 76 | 76 | } |
| 77 | 77 | } |
| 78 | 78 | } |
| 79 | −DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, | |
| 80 | − PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); | |
| 79 | +DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, | |
| 80 | + PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); | |
| @@ -285,7 +285,7 @@ symbol = value · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | #define PTR_SCALESHIFT 2 |
| 287 | 287 | |
| 288 | −#define PTR .word | |
| 288 | +#define PTR_WD .word | |
| 289 | 289 | #define PTRSIZE 4 |
| 290 | 290 | #define PTRLOG 2 |
| 291 | 291 | #endif |
| @@ -310,7 +310,7 @@ symbol = value · 18 unmodified lines | ||
| 310 | 310 | |
| 311 | 311 | #define PTR_SCALESHIFT 3 |
| 312 | 312 | |
| 313 | −#define PTR .dword | |
| 313 | +#define PTR_WD .dword | |
| 314 | 314 | #define PTRSIZE 8 |
| 315 | 315 | #define PTRLOG 3 |
| 316 | 316 | #endif |
| @@ -32,7 +32,7 @@ do { \ · 31 unmodified lines | ||
| 32 | 32 | ".previous\n" \ |
| 33 | 33 | \ |
| 34 | 34 | ".section\t__ex_table,\"a\"\n\t" \ |
| 35 | − STR(PTR) "\t1b, 3b\n\t" \ | |
| 35 | + STR(PTR_WD) "\t1b, 3b\n\t" \ | |
| 36 | 36 | ".previous\n" \ |
| 37 | 37 | \ |
| 38 | 38 | : [tmp_dst] "=&r" (dst), [tmp_err] "=r" (error)\ |
| @@ -54,7 +54,7 @@ do { \ · 15 unmodified lines | ||
| 54 | 54 | ".previous\n" \ |
| 55 | 55 | \ |
| 56 | 56 | ".section\t__ex_table,\"a\"\n\t"\ |
| 57 | − STR(PTR) "\t1b, 3b\n\t" \ | |
| 57 | + STR(PTR_WD) "\t1b, 3b\n\t" \ | |
| 58 | 58 | ".previous\n" \ |
| 59 | 59 | \ |
| 60 | 60 | : [tmp_err] "=r" (error) \ |
| @@ -119,7 +119,7 @@ static inline void flush_scache_line(unsigned long addr) · 118 unmodified lines | ||
| 119 | 119 | " j 2b \n" \ |
| 120 | 120 | " .previous \n" \ |
| 121 | 121 | " .section __ex_table,\"a\" \n" \ |
| 122 | − " "STR(PTR)" 1b, 3b \n" \ | |
| 122 | + " "STR(PTR_WD)" 1b, 3b \n" \ | |
| 123 | 123 | " .previous" \ |
| 124 | 124 | : "+r" (__err) \ |
| 125 | 125 | : "i" (op), "r" (addr), "i" (-EFAULT)); \ |
| @@ -142,7 +142,7 @@ static inline void flush_scache_line(unsigned long addr) · 16 unmodified lines | ||
| 142 | 142 | " j 2b \n" \ |
| 143 | 143 | " .previous \n" \ |
| 144 | 144 | " .section __ex_table,\"a\" \n" \ |
| 145 | − " "STR(PTR)" 1b, 3b \n" \ | |
| 145 | + " "STR(PTR_WD)" 1b, 3b \n" \ | |
| 146 | 146 | " .previous" \ |
| 147 | 147 | : "+r" (__err) \ |
| 148 | 148 | : "i" (op), "r" (addr), "i" (-EFAULT)); \ |
| @@ -20,8 +20,8 @@ do { \ · 19 unmodified lines | ||
| 20 | 20 | "j\t3b\n\t" \ |
| 21 | 21 | ".previous\n\t" \ |
| 22 | 22 | ".section\t__ex_table,\"a\"\n\t" \ |
| 23 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 24 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 23 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 24 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 25 | 25 | ".previous" \ |
| 26 | 26 | : "=&r" (value), "=r" (res) \ |
| 27 | 27 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -41,8 +41,8 @@ do { \ · 13 unmodified lines | ||
| 41 | 41 | "j\t3b\n\t" \ |
| 42 | 42 | ".previous\n\t" \ |
| 43 | 43 | ".section\t__ex_table,\"a\"\n\t" \ |
| 44 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 45 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 44 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 45 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 46 | 46 | ".previous" \ |
| 47 | 47 | : "=&r" (value), "=r" (res) \ |
| 48 | 48 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -74,10 +74,10 @@ do { \ · 25 unmodified lines | ||
| 74 | 74 | "j\t10b\n\t" \ |
| 75 | 75 | ".previous\n\t" \ |
| 76 | 76 | ".section\t__ex_table,\"a\"\n\t" \ |
| 77 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 78 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 79 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 80 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 77 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 78 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 79 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 80 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 81 | 81 | ".previous" \ |
| 82 | 82 | : "=&r" (value), "=r" (res) \ |
| 83 | 83 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -102,8 +102,8 @@ do { \ · 18 unmodified lines | ||
| 102 | 102 | "j\t3b\n\t" \ |
| 103 | 103 | ".previous\n\t" \ |
| 104 | 104 | ".section\t__ex_table,\"a\"\n\t" \ |
| 105 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 106 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 105 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 106 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 107 | 107 | ".previous" \ |
| 108 | 108 | : "=&r" (value), "=r" (res) \ |
| 109 | 109 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -125,8 +125,8 @@ do { \ · 15 unmodified lines | ||
| 125 | 125 | "j\t3b\n\t" \ |
| 126 | 126 | ".previous\n\t" \ |
| 127 | 127 | ".section\t__ex_table,\"a\"\n\t" \ |
| 128 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 129 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 128 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 129 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 130 | 130 | ".previous" \ |
| 131 | 131 | : "=&r" (value), "=r" (res) \ |
| 132 | 132 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -145,8 +145,8 @@ do { \ · 12 unmodified lines | ||
| 145 | 145 | "j\t3b\n\t" \ |
| 146 | 146 | ".previous\n\t" \ |
| 147 | 147 | ".section\t__ex_table,\"a\"\n\t" \ |
| 148 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 149 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 148 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 149 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 150 | 150 | ".previous" \ |
| 151 | 151 | : "=&r" (value), "=r" (res) \ |
| 152 | 152 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -178,10 +178,10 @@ do { \ · 25 unmodified lines | ||
| 178 | 178 | "j\t10b\n\t" \ |
| 179 | 179 | ".previous\n\t" \ |
| 180 | 180 | ".section\t__ex_table,\"a\"\n\t" \ |
| 181 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 182 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 183 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 184 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 181 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 182 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 183 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 184 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 185 | 185 | ".previous" \ |
| 186 | 186 | : "=&r" (value), "=r" (res) \ |
| 187 | 187 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -223,14 +223,14 @@ do { \ · 35 unmodified lines | ||
| 223 | 223 | "j\t10b\n\t" \ |
| 224 | 224 | ".previous\n\t" \ |
| 225 | 225 | ".section\t__ex_table,\"a\"\n\t" \ |
| 226 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 227 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 228 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 229 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 230 | − STR(PTR)"\t5b, 11b\n\t" \ | |
| 231 | − STR(PTR)"\t6b, 11b\n\t" \ | |
| 232 | − STR(PTR)"\t7b, 11b\n\t" \ | |
| 233 | − STR(PTR)"\t8b, 11b\n\t" \ | |
| 226 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 227 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 228 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 229 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 230 | + STR(PTR_WD)"\t5b, 11b\n\t" \ | |
| 231 | + STR(PTR_WD)"\t6b, 11b\n\t" \ | |
| 232 | + STR(PTR_WD)"\t7b, 11b\n\t" \ | |
| 233 | + STR(PTR_WD)"\t8b, 11b\n\t" \ | |
| 234 | 234 | ".previous" \ |
| 235 | 235 | : "=&r" (value), "=r" (res) \ |
| 236 | 236 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -255,8 +255,8 @@ do { \ · 18 unmodified lines | ||
| 255 | 255 | "j\t3b\n\t" \ |
| 256 | 256 | ".previous\n\t" \ |
| 257 | 257 | ".section\t__ex_table,\"a\"\n\t" \ |
| 258 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 259 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 258 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 259 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 260 | 260 | ".previous" \ |
| 261 | 261 | : "=r" (res) \ |
| 262 | 262 | : "r" (value), "r" (addr), "i" (-EFAULT));\ |
| @@ -276,8 +276,8 @@ do { \ · 13 unmodified lines | ||
| 276 | 276 | "j\t3b\n\t" \ |
| 277 | 277 | ".previous\n\t" \ |
| 278 | 278 | ".section\t__ex_table,\"a\"\n\t" \ |
| 279 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 280 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 279 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 280 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 281 | 281 | ".previous" \ |
| 282 | 282 | : "=r" (res) \ |
| 283 | 283 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
| @@ -296,8 +296,8 @@ do { \ · 12 unmodified lines | ||
| 296 | 296 | "j\t3b\n\t" \ |
| 297 | 297 | ".previous\n\t" \ |
| 298 | 298 | ".section\t__ex_table,\"a\"\n\t" \ |
| 299 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 300 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 299 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 300 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 301 | 301 | ".previous" \ |
| 302 | 302 | : "=r" (res) \ |
| 303 | 303 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
| @@ -325,10 +325,10 @@ do { \ · 21 unmodified lines | ||
| 325 | 325 | "j\t10b\n\t" \ |
| 326 | 326 | ".previous\n\t" \ |
| 327 | 327 | ".section\t__ex_table,\"a\"\n\t" \ |
| 328 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 329 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 330 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 331 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 328 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 329 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 330 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 331 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 332 | 332 | ".previous" \ |
| 333 | 333 | : "=&r" (res) \ |
| 334 | 334 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
| @@ -365,14 +365,14 @@ do { \ · 30 unmodified lines | ||
| 365 | 365 | "j\t10b\n\t" \ |
| 366 | 366 | ".previous\n\t" \ |
| 367 | 367 | ".section\t__ex_table,\"a\"\n\t" \ |
| 368 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 369 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 370 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 371 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 372 | − STR(PTR)"\t5b, 11b\n\t" \ | |
| 373 | − STR(PTR)"\t6b, 11b\n\t" \ | |
| 374 | − STR(PTR)"\t7b, 11b\n\t" \ | |
| 375 | − STR(PTR)"\t8b, 11b\n\t" \ | |
| 368 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 369 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 370 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 371 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 372 | + STR(PTR_WD)"\t5b, 11b\n\t" \ | |
| 373 | + STR(PTR_WD)"\t6b, 11b\n\t" \ | |
| 374 | + STR(PTR_WD)"\t7b, 11b\n\t" \ | |
| 375 | + STR(PTR_WD)"\t8b, 11b\n\t" \ | |
| 376 | 376 | ".previous" \ |
| 377 | 377 | : "=&r" (res) \ |
| 378 | 378 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
| @@ -398,8 +398,8 @@ do { \ · 19 unmodified lines | ||
| 398 | 398 | "j\t3b\n\t" \ |
| 399 | 399 | ".previous\n\t" \ |
| 400 | 400 | ".section\t__ex_table,\"a\"\n\t" \ |
| 401 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 402 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 401 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 402 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 403 | 403 | ".previous" \ |
| 404 | 404 | : "=&r" (value), "=r" (res) \ |
| 405 | 405 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -419,8 +419,8 @@ do { \ · 13 unmodified lines | ||
| 419 | 419 | "j\t3b\n\t" \ |
| 420 | 420 | ".previous\n\t" \ |
| 421 | 421 | ".section\t__ex_table,\"a\"\n\t" \ |
| 422 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 423 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 422 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 423 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 424 | 424 | ".previous" \ |
| 425 | 425 | : "=&r" (value), "=r" (res) \ |
| 426 | 426 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -452,10 +452,10 @@ do { \ · 25 unmodified lines | ||
| 452 | 452 | "j\t10b\n\t" \ |
| 453 | 453 | ".previous\n\t" \ |
| 454 | 454 | ".section\t__ex_table,\"a\"\n\t" \ |
| 455 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 456 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 457 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 458 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 455 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 456 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 457 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 458 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 459 | 459 | ".previous" \ |
| 460 | 460 | : "=&r" (value), "=r" (res) \ |
| 461 | 461 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -481,8 +481,8 @@ do { \ · 19 unmodified lines | ||
| 481 | 481 | "j\t3b\n\t" \ |
| 482 | 482 | ".previous\n\t" \ |
| 483 | 483 | ".section\t__ex_table,\"a\"\n\t" \ |
| 484 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 485 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 484 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 485 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 486 | 486 | ".previous" \ |
| 487 | 487 | : "=&r" (value), "=r" (res) \ |
| 488 | 488 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -504,8 +504,8 @@ do { \ · 15 unmodified lines | ||
| 504 | 504 | "j\t3b\n\t" \ |
| 505 | 505 | ".previous\n\t" \ |
| 506 | 506 | ".section\t__ex_table,\"a\"\n\t" \ |
| 507 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 508 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 507 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 508 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 509 | 509 | ".previous" \ |
| 510 | 510 | : "=&r" (value), "=r" (res) \ |
| 511 | 511 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -524,8 +524,8 @@ do { \ · 12 unmodified lines | ||
| 524 | 524 | "j\t3b\n\t" \ |
| 525 | 525 | ".previous\n\t" \ |
| 526 | 526 | ".section\t__ex_table,\"a\"\n\t" \ |
| 527 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 528 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 527 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 528 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 529 | 529 | ".previous" \ |
| 530 | 530 | : "=&r" (value), "=r" (res) \ |
| 531 | 531 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -557,10 +557,10 @@ do { \ · 25 unmodified lines | ||
| 557 | 557 | "j\t10b\n\t" \ |
| 558 | 558 | ".previous\n\t" \ |
| 559 | 559 | ".section\t__ex_table,\"a\"\n\t" \ |
| 560 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 561 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 562 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 563 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 560 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 561 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 562 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 563 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 564 | 564 | ".previous" \ |
| 565 | 565 | : "=&r" (value), "=r" (res) \ |
| 566 | 566 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -602,14 +602,14 @@ do { \ · 35 unmodified lines | ||
| 602 | 602 | "j\t10b\n\t" \ |
| 603 | 603 | ".previous\n\t" \ |
| 604 | 604 | ".section\t__ex_table,\"a\"\n\t" \ |
| 605 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 606 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 607 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 608 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 609 | − STR(PTR)"\t5b, 11b\n\t" \ | |
| 610 | − STR(PTR)"\t6b, 11b\n\t" \ | |
| 611 | − STR(PTR)"\t7b, 11b\n\t" \ | |
| 612 | − STR(PTR)"\t8b, 11b\n\t" \ | |
| 605 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 606 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 607 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 608 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 609 | + STR(PTR_WD)"\t5b, 11b\n\t" \ | |
| 610 | + STR(PTR_WD)"\t6b, 11b\n\t" \ | |
| 611 | + STR(PTR_WD)"\t7b, 11b\n\t" \ | |
| 612 | + STR(PTR_WD)"\t8b, 11b\n\t" \ | |
| 613 | 613 | ".previous" \ |
| 614 | 614 | : "=&r" (value), "=r" (res) \ |
| 615 | 615 | : "r" (addr), "i" (-EFAULT)); \ |
| @@ -632,8 +632,8 @@ do { \ · 16 unmodified lines | ||
| 632 | 632 | "j\t3b\n\t" \ |
| 633 | 633 | ".previous\n\t" \ |
| 634 | 634 | ".section\t__ex_table,\"a\"\n\t" \ |
| 635 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 636 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 635 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 636 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 637 | 637 | ".previous" \ |
| 638 | 638 | : "=r" (res) \ |
| 639 | 639 | : "r" (value), "r" (addr), "i" (-EFAULT));\ |
| @@ -653,8 +653,8 @@ do { \ · 13 unmodified lines | ||
| 653 | 653 | "j\t3b\n\t" \ |
| 654 | 654 | ".previous\n\t" \ |
| 655 | 655 | ".section\t__ex_table,\"a\"\n\t" \ |
| 656 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 657 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 656 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 657 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 658 | 658 | ".previous" \ |
| 659 | 659 | : "=r" (res) \ |
| 660 | 660 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
| @@ -673,8 +673,8 @@ do { \ · 12 unmodified lines | ||
| 673 | 673 | "j\t3b\n\t" \ |
| 674 | 674 | ".previous\n\t" \ |
| 675 | 675 | ".section\t__ex_table,\"a\"\n\t" \ |
| 676 | − STR(PTR)"\t1b, 4b\n\t" \ | |
| 677 | − STR(PTR)"\t2b, 4b\n\t" \ | |
| 676 | + STR(PTR_WD)"\t1b, 4b\n\t" \ | |
| 677 | + STR(PTR_WD)"\t2b, 4b\n\t" \ | |
| 678 | 678 | ".previous" \ |
| 679 | 679 | : "=r" (res) \ |
| 680 | 680 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
| @@ -703,10 +703,10 @@ do { \ · 22 unmodified lines | ||
| 703 | 703 | "j\t10b\n\t" \ |
| 704 | 704 | ".previous\n\t" \ |
| 705 | 705 | ".section\t__ex_table,\"a\"\n\t" \ |
| 706 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 707 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 708 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 709 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 706 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 707 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 708 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 709 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 710 | 710 | ".previous" \ |
| 711 | 711 | : "=&r" (res) \ |
| 712 | 712 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
| @@ -743,14 +743,14 @@ do { \ · 30 unmodified lines | ||
| 743 | 743 | "j\t10b\n\t" \ |
| 744 | 744 | ".previous\n\t" \ |
| 745 | 745 | ".section\t__ex_table,\"a\"\n\t" \ |
| 746 | − STR(PTR)"\t1b, 11b\n\t" \ | |
| 747 | − STR(PTR)"\t2b, 11b\n\t" \ | |
| 748 | − STR(PTR)"\t3b, 11b\n\t" \ | |
| 749 | − STR(PTR)"\t4b, 11b\n\t" \ | |
| 750 | − STR(PTR)"\t5b, 11b\n\t" \ | |
| 751 | − STR(PTR)"\t6b, 11b\n\t" \ | |
| 752 | − STR(PTR)"\t7b, 11b\n\t" \ | |
| 753 | − STR(PTR)"\t8b, 11b\n\t" \ | |
| 746 | + STR(PTR_WD)"\t1b, 11b\n\t" \ | |
| 747 | + STR(PTR_WD)"\t2b, 11b\n\t" \ | |
| 748 | + STR(PTR_WD)"\t3b, 11b\n\t" \ | |
| 749 | + STR(PTR_WD)"\t4b, 11b\n\t" \ | |
| 750 | + STR(PTR_WD)"\t5b, 11b\n\t" \ | |
| 751 | + STR(PTR_WD)"\t6b, 11b\n\t" \ | |
| 752 | + STR(PTR_WD)"\t7b, 11b\n\t" \ | |
| 753 | + STR(PTR_WD)"\t8b, 11b\n\t" \ | |
| 754 | 754 | ".previous" \ |
| 755 | 755 | : "=&r" (res) \ |
| 756 | 756 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
| @@ -1258,10 +1258,10 @@ fpu_emul: · 1257 unmodified lines | ||
| 1258 | 1258 | " j 10b\n" |
| 1259 | 1259 | " .previous\n" |
| 1260 | 1260 | " .section __ex_table,\"a\"\n" |
| 1261 | − STR(PTR) " 1b,8b\n" | |
| 1262 | − STR(PTR) " 2b,8b\n" | |
| 1263 | − STR(PTR) " 3b,8b\n" | |
| 1264 | − STR(PTR) " 4b,8b\n" | |
| 1261 | + STR(PTR_WD) " 1b,8b\n" | |
| 1262 | + STR(PTR_WD) " 2b,8b\n" | |
| 1263 | + STR(PTR_WD) " 3b,8b\n" | |
| 1264 | + STR(PTR_WD) " 4b,8b\n" | |
| 1265 | 1265 | " .previous\n" |
| 1266 | 1266 | " .set pop\n" |
| 1267 | 1267 | : "+&r"(rt), "=&r"(rs), |
| @@ -1333,10 +1333,10 @@ fpu_emul: · 65 unmodified lines | ||
| 1333 | 1333 | " j 10b\n" |
| 1334 | 1334 | " .previous\n" |
| 1335 | 1335 | " .section __ex_table,\"a\"\n" |
| 1336 | − STR(PTR) " 1b,8b\n" | |
| 1337 | − STR(PTR) " 2b,8b\n" | |
| 1338 | − STR(PTR) " 3b,8b\n" | |
| 1339 | − STR(PTR) " 4b,8b\n" | |
| 1336 | + STR(PTR_WD) " 1b,8b\n" | |
| 1337 | + STR(PTR_WD) " 2b,8b\n" | |
| 1338 | + STR(PTR_WD) " 3b,8b\n" | |
| 1339 | + STR(PTR_WD) " 4b,8b\n" | |
| 1340 | 1340 | " .previous\n" |
| 1341 | 1341 | " .set pop\n" |
| 1342 | 1342 | : "+&r"(rt), "=&r"(rs), |
| @@ -1404,10 +1404,10 @@ fpu_emul: · 61 unmodified lines | ||
| 1404 | 1404 | " j 9b\n" |
| 1405 | 1405 | " .previous\n" |
| 1406 | 1406 | " .section __ex_table,\"a\"\n" |
| 1407 | − STR(PTR) " 1b,8b\n" | |
| 1408 | − STR(PTR) " 2b,8b\n" | |
| 1409 | − STR(PTR) " 3b,8b\n" | |
| 1410 | − STR(PTR) " 4b,8b\n" | |
| 1407 | + STR(PTR_WD) " 1b,8b\n" | |
| 1408 | + STR(PTR_WD) " 2b,8b\n" | |
| 1409 | + STR(PTR_WD) " 3b,8b\n" | |
| 1410 | + STR(PTR_WD) " 4b,8b\n" | |
| 1411 | 1411 | " .previous\n" |
| 1412 | 1412 | " .set pop\n" |
| 1413 | 1413 | : "+&r"(rt), "=&r"(rs), |
| @@ -1474,10 +1474,10 @@ fpu_emul: · 60 unmodified lines | ||
| 1474 | 1474 | " j 9b\n" |
| 1475 | 1475 | " .previous\n" |
| 1476 | 1476 | " .section __ex_table,\"a\"\n" |
| 1477 | − STR(PTR) " 1b,8b\n" | |
| 1478 | − STR(PTR) " 2b,8b\n" | |
| 1479 | − STR(PTR) " 3b,8b\n" | |
| 1480 | − STR(PTR) " 4b,8b\n" | |
| 1477 | + STR(PTR_WD) " 1b,8b\n" | |
| 1478 | + STR(PTR_WD) " 2b,8b\n" | |
| 1479 | + STR(PTR_WD) " 3b,8b\n" | |
| 1480 | + STR(PTR_WD) " 4b,8b\n" | |
| 1481 | 1481 | " .previous\n" |
| 1482 | 1482 | " .set pop\n" |
| 1483 | 1483 | : "+&r"(rt), "=&r"(rs), |
| @@ -1589,14 +1589,14 @@ fpu_emul: · 105 unmodified lines | ||
| 1589 | 1589 | " j 9b\n" |
| 1590 | 1590 | " .previous\n" |
| 1591 | 1591 | " .section __ex_table,\"a\"\n" |
| 1592 | − STR(PTR) " 1b,8b\n" | |
| 1593 | − STR(PTR) " 2b,8b\n" | |
| 1594 | − STR(PTR) " 3b,8b\n" | |
| 1595 | − STR(PTR) " 4b,8b\n" | |
| 1596 | − STR(PTR) " 5b,8b\n" | |
| 1597 | − STR(PTR) " 6b,8b\n" | |
| 1598 | − STR(PTR) " 7b,8b\n" | |
| 1599 | − STR(PTR) " 0b,8b\n" | |
| 1592 | + STR(PTR_WD) " 1b,8b\n" | |
| 1593 | + STR(PTR_WD) " 2b,8b\n" | |
| 1594 | + STR(PTR_WD) " 3b,8b\n" | |
| 1595 | + STR(PTR_WD) " 4b,8b\n" | |
| 1596 | + STR(PTR_WD) " 5b,8b\n" | |
| 1597 | + STR(PTR_WD) " 6b,8b\n" | |
| 1598 | + STR(PTR_WD) " 7b,8b\n" | |
| 1599 | + STR(PTR_WD) " 0b,8b\n" | |
| 1600 | 1600 | " .previous\n" |
| 1601 | 1601 | " .set pop\n" |
| 1602 | 1602 | : "+&r"(rt), "=&r"(rs), |
| @@ -1708,14 +1708,14 @@ fpu_emul: · 105 unmodified lines | ||
| 1708 | 1708 | " j 9b\n" |
| 1709 | 1709 | " .previous\n" |
| 1710 | 1710 | " .section __ex_table,\"a\"\n" |
| 1711 | − STR(PTR) " 1b,8b\n" | |
| 1712 | − STR(PTR) " 2b,8b\n" | |
| 1713 | − STR(PTR) " 3b,8b\n" | |
| 1714 | − STR(PTR) " 4b,8b\n" | |
| 1715 | − STR(PTR) " 5b,8b\n" | |
| 1716 | − STR(PTR) " 6b,8b\n" | |
| 1717 | − STR(PTR) " 7b,8b\n" | |
| 1718 | − STR(PTR) " 0b,8b\n" | |
| 1711 | + STR(PTR_WD) " 1b,8b\n" | |
| 1712 | + STR(PTR_WD) " 2b,8b\n" | |
| 1713 | + STR(PTR_WD) " 3b,8b\n" | |
| 1714 | + STR(PTR_WD) " 4b,8b\n" | |
| 1715 | + STR(PTR_WD) " 5b,8b\n" | |
| 1716 | + STR(PTR_WD) " 6b,8b\n" | |
| 1717 | + STR(PTR_WD) " 7b,8b\n" | |
| 1718 | + STR(PTR_WD) " 0b,8b\n" | |
| 1719 | 1719 | " .previous\n" |
| 1720 | 1720 | " .set pop\n" |
| 1721 | 1721 | : "+&r"(rt), "=&r"(rs), |
| @@ -1827,14 +1827,14 @@ fpu_emul: · 105 unmodified lines | ||
| 1827 | 1827 | " j 9b\n" |
| 1828 | 1828 | " .previous\n" |
| 1829 | 1829 | " .section __ex_table,\"a\"\n" |
| 1830 | − STR(PTR) " 1b,8b\n" | |
| 1831 | − STR(PTR) " 2b,8b\n" | |
| 1832 | − STR(PTR) " 3b,8b\n" | |
| 1833 | − STR(PTR) " 4b,8b\n" | |
| 1834 | − STR(PTR) " 5b,8b\n" | |
| 1835 | − STR(PTR) " 6b,8b\n" | |
| 1836 | − STR(PTR) " 7b,8b\n" | |
| 1837 | − STR(PTR) " 0b,8b\n" | |
| 1830 | + STR(PTR_WD) " 1b,8b\n" | |
| 1831 | + STR(PTR_WD) " 2b,8b\n" | |
| 1832 | + STR(PTR_WD) " 3b,8b\n" | |
| 1833 | + STR(PTR_WD) " 4b,8b\n" | |
| 1834 | + STR(PTR_WD) " 5b,8b\n" | |
| 1835 | + STR(PTR_WD) " 6b,8b\n" | |
| 1836 | + STR(PTR_WD) " 7b,8b\n" | |
| 1837 | + STR(PTR_WD) " 0b,8b\n" | |
| 1838 | 1838 | " .previous\n" |
| 1839 | 1839 | " .set pop\n" |
| 1840 | 1840 | : "+&r"(rt), "=&r"(rs), |
| @@ -1945,14 +1945,14 @@ fpu_emul: · 104 unmodified lines | ||
| 1945 | 1945 | " j 9b\n" |
| 1946 | 1946 | " .previous\n" |
| 1947 | 1947 | " .section __ex_table,\"a\"\n" |
| 1948 | − STR(PTR) " 1b,8b\n" | |
| 1949 | − STR(PTR) " 2b,8b\n" | |
| 1950 | − STR(PTR) " 3b,8b\n" | |
| 1951 | − STR(PTR) " 4b,8b\n" | |
| 1952 | − STR(PTR) " 5b,8b\n" | |
| 1953 | − STR(PTR) " 6b,8b\n" | |
| 1954 | − STR(PTR) " 7b,8b\n" | |
| 1955 | − STR(PTR) " 0b,8b\n" | |
| 1948 | + STR(PTR_WD) " 1b,8b\n" | |
| 1949 | + STR(PTR_WD) " 2b,8b\n" | |
| 1950 | + STR(PTR_WD) " 3b,8b\n" | |
| 1951 | + STR(PTR_WD) " 4b,8b\n" | |
| 1952 | + STR(PTR_WD) " 5b,8b\n" | |
| 1953 | + STR(PTR_WD) " 6b,8b\n" | |
| 1954 | + STR(PTR_WD) " 7b,8b\n" | |
| 1955 | + STR(PTR_WD) " 0b,8b\n" | |
| 1956 | 1956 | " .previous\n" |
| 1957 | 1957 | " .set pop\n" |
| 1958 | 1958 | : "+&r"(rt), "=&r"(rs), |
| @@ -2007,7 +2007,7 @@ fpu_emul: · 48 unmodified lines | ||
| 2007 | 2007 | "j 2b\n" |
| 2008 | 2008 | ".previous\n" |
| 2009 | 2009 | ".section __ex_table,\"a\"\n" |
| 2010 | − STR(PTR) " 1b,3b\n" | |
| 2010 | + STR(PTR_WD) " 1b,3b\n" | |
| 2011 | 2011 | ".previous\n" |
| 2012 | 2012 | : "=&r"(res), "+&r"(err) |
| 2013 | 2013 | : "r"(vaddr), "i"(SIGSEGV) |
| @@ -2065,7 +2065,7 @@ fpu_emul: · 51 unmodified lines | ||
| 2065 | 2065 | "j 2b\n" |
| 2066 | 2066 | ".previous\n" |
| 2067 | 2067 | ".section __ex_table,\"a\"\n" |
| 2068 | − STR(PTR) " 1b,3b\n" | |
| 2068 | + STR(PTR_WD) " 1b,3b\n" | |
| 2069 | 2069 | ".previous\n" |
| 2070 | 2070 | : "+&r"(res), "+&r"(err) |
| 2071 | 2071 | : "r"(vaddr), "i"(SIGSEGV)); |
| @@ -2126,7 +2126,7 @@ fpu_emul: · 54 unmodified lines | ||
| 2126 | 2126 | "j 2b\n" |
| 2127 | 2127 | ".previous\n" |
| 2128 | 2128 | ".section __ex_table,\"a\"\n" |
| 2129 | − STR(PTR) " 1b,3b\n" | |
| 2129 | + STR(PTR_WD) " 1b,3b\n" | |
| 2130 | 2130 | ".previous\n" |
| 2131 | 2131 | : "=&r"(res), "+&r"(err) |
| 2132 | 2132 | : "r"(vaddr), "i"(SIGSEGV) |
| @@ -2189,7 +2189,7 @@ fpu_emul: · 56 unmodified lines | ||
| 2189 | 2189 | "j 2b\n" |
| 2190 | 2190 | ".previous\n" |
| 2191 | 2191 | ".section __ex_table,\"a\"\n" |
| 2192 | − STR(PTR) " 1b,3b\n" | |
| 2192 | + STR(PTR_WD) " 1b,3b\n" | |
| 2193 | 2193 | ".previous\n" |
| 2194 | 2194 | : "+&r"(res), "+&r"(err) |
| 2195 | 2195 | : "r"(vaddr), "i"(SIGSEGV)); |
| @@ -23,14 +23,14 @@ · 22 unmodified lines | ||
| 23 | 23 | #define EX(a,b) \ |
| 24 | 24 | 9: a,##b; \ |
| 25 | 25 | .section __ex_table,"a"; \ |
| 26 | − PTR 9b,fault; \ | |
| 26 | + PTR_WD 9b,fault; \ | |
| 27 | 27 | .previous |
| 28 | 28 | |
| 29 | 29 | #define EX2(a,b) \ |
| 30 | 30 | 9: a,##b; \ |
| 31 | 31 | .section __ex_table,"a"; \ |
| 32 | − PTR 9b,fault; \ | |
| 33 | − PTR 9b+4,fault; \ | |
| 32 | + PTR_WD 9b,fault; \ | |
| 33 | + PTR_WD 9b+4,fault; \ | |
| 34 | 34 | .previous |
| 35 | 35 | |
| 36 | 36 | .set mips1 |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | .ex\@: \insn \reg, \src |
| 32 | 32 | .set pop |
| 33 | 33 | .section __ex_table,"a" |
| 34 | − PTR .ex\@, fault | |
| 34 | + PTR_WD .ex\@, fault | |
| 35 | 35 | .previous |
| 36 | 36 | .endm |
| 37 | 37 | |
| @@ -147,10 +147,10 @@ LEAF(kexec_smp_wait) · 146 unmodified lines | ||
| 147 | 147 | |
| 148 | 148 | kexec_args: |
| 149 | 149 | EXPORT(kexec_args) |
| 150 | −arg0: PTR 0x0 | |
| 151 | −arg1: PTR 0x0 | |
| 152 | −arg2: PTR 0x0 | |
| 153 | −arg3: PTR 0x0 | |
| 150 | +arg0: PTR_WD 0x0 | |
| 151 | +arg1: PTR_WD 0x0 | |
| 152 | +arg2: PTR_WD 0x0 | |
| 153 | +arg3: PTR_WD 0x0 | |
| 154 | 154 | .size kexec_args,PTRSIZE*4 |
| 155 | 155 | |
| 156 | 156 | #ifdef CONFIG_SMP |
| @@ -161,10 +161,10 @@ arg3: PTR 0x0 · 4 unmodified lines | ||
| 161 | 161 | */ |
| 162 | 162 | secondary_kexec_args: |
| 163 | 163 | EXPORT(secondary_kexec_args) |
| 164 | −s_arg0: PTR 0x0 | |
| 165 | −s_arg1: PTR 0x0 | |
| 166 | −s_arg2: PTR 0x0 | |
| 167 | −s_arg3: PTR 0x0 | |
| 164 | +s_arg0: PTR_WD 0x0 | |
| 165 | +s_arg1: PTR_WD 0x0 | |
| 166 | +s_arg2: PTR_WD 0x0 | |
| 167 | +s_arg3: PTR_WD 0x0 | |
| 168 | 168 | .size secondary_kexec_args,PTRSIZE*4 |
| 169 | 169 | kexec_flag: |
| 170 | 170 | LONG 0x1 |
| @@ -173,17 +173,17 @@ kexec_flag: · 2 unmodified lines | ||
| 173 | 173 | |
| 174 | 174 | kexec_start_address: |
| 175 | 175 | EXPORT(kexec_start_address) |
| 176 | − PTR 0x0 | |
| 176 | + PTR_WD 0x0 | |
| 177 | 177 | .size kexec_start_address, PTRSIZE |
| 178 | 178 | |
| 179 | 179 | kexec_indirection_page: |
| 180 | 180 | EXPORT(kexec_indirection_page) |
| 181 | − PTR 0 | |
| 181 | + PTR_WD 0 | |
| 182 | 182 | .size kexec_indirection_page, PTRSIZE |
| 183 | 183 | |
| 184 | 184 | relocate_new_kernel_end: |
| 185 | 185 | |
| 186 | 186 | relocate_new_kernel_size: |
| 187 | 187 | EXPORT(relocate_new_kernel_size) |
| 188 | − PTR relocate_new_kernel_end - relocate_new_kernel | |
| 188 | + PTR_WD relocate_new_kernel_end - relocate_new_kernel | |
| 189 | 189 | .size relocate_new_kernel_size, PTRSIZE |
| @@ -72,10 +72,10 @@ loads_done: · 71 unmodified lines | ||
| 72 | 72 | .set pop |
| 73 | 73 | |
| 74 | 74 | .section __ex_table,"a" |
| 75 | − PTR load_a4, bad_stack_a4 | |
| 76 | − PTR load_a5, bad_stack_a5 | |
| 77 | − PTR load_a6, bad_stack_a6 | |
| 78 | − PTR load_a7, bad_stack_a7 | |
| 75 | + PTR_WD load_a4, bad_stack_a4 | |
| 76 | + PTR_WD load_a5, bad_stack_a5 | |
| 77 | + PTR_WD load_a6, bad_stack_a6 | |
| 78 | + PTR_WD load_a7, bad_stack_a7 | |
| 79 | 79 | .previous |
| 80 | 80 | |
| 81 | 81 | lw t0, TI_FLAGS($28) # syscall tracing enabled? |
| @@ -216,7 +216,7 @@ einval: li v0, -ENOSYS · 134 unmodified lines | ||
| 216 | 216 | #endif /* CONFIG_MIPS_MT_FPAFF */ |
| 217 | 217 | |
| 218 | 218 | #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) |
| 219 | −#define __SYSCALL(nr, entry) PTR entry | |
| 219 | +#define __SYSCALL(nr, entry) PTR_WD entry | |
| 220 | 220 | .align 2 |
| 221 | 221 | .type sys_call_table, @object |
| 222 | 222 | EXPORT(sys_call_table) |
| @@ -101,7 +101,7 @@ not_n32_scall: · 100 unmodified lines | ||
| 101 | 101 | |
| 102 | 102 | END(handle_sysn32) |
| 103 | 103 | |
| 104 | −#define __SYSCALL(nr, entry) PTR entry | |
| 104 | +#define __SYSCALL(nr, entry) PTR_WD entry | |
| 105 | 105 | .type sysn32_call_table, @object |
| 106 | 106 | EXPORT(sysn32_call_table) |
| 107 | 107 | #include <asm/syscall_table_n32.h> |
| @@ -109,7 +109,7 @@ illegal_syscall: · 108 unmodified lines | ||
| 109 | 109 | j n64_syscall_exit |
| 110 | 110 | END(handle_sys64) |
| 111 | 111 | |
| 112 | −#define __SYSCALL(nr, entry) PTR entry | |
| 112 | +#define __SYSCALL(nr, entry) PTR_WD entry | |
| 113 | 113 | .align 3 |
| 114 | 114 | .type sys_call_table, @object |
| 115 | 115 | EXPORT(sys_call_table) |
| @@ -73,10 +73,10 @@ load_a7: lw a7, 28(t0) # argument #8 from usp · 72 unmodified lines | ||
| 73 | 73 | loads_done: |
| 74 | 74 | |
| 75 | 75 | .section __ex_table,"a" |
| 76 | − PTR load_a4, bad_stack_a4 | |
| 77 | − PTR load_a5, bad_stack_a5 | |
| 78 | − PTR load_a6, bad_stack_a6 | |
| 79 | − PTR load_a7, bad_stack_a7 | |
| 76 | + PTR_WD load_a4, bad_stack_a4 | |
| 77 | + PTR_WD load_a5, bad_stack_a5 | |
| 78 | + PTR_WD load_a6, bad_stack_a6 | |
| 79 | + PTR_WD load_a7, bad_stack_a7 | |
| 80 | 80 | .previous |
| 81 | 81 | |
| 82 | 82 | li t1, _TIF_WORK_SYSCALL_ENTRY |
| @@ -214,7 +214,7 @@ einval: li v0, -ENOSYS · 131 unmodified lines | ||
| 214 | 214 | END(sys32_syscall) |
| 215 | 215 | |
| 216 | 216 | #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat) |
| 217 | −#define __SYSCALL(nr, entry) PTR entry | |
| 217 | +#define __SYSCALL(nr, entry) PTR_WD entry | |
| 218 | 218 | .align 3 |
| 219 | 219 | .type sys32_call_table,@object |
| 220 | 220 | EXPORT(sys32_call_table) |
| @@ -122,8 +122,8 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) · 121 unmodified lines | ||
| 122 | 122 | " j 3b \n" |
| 123 | 123 | " .previous \n" |
| 124 | 124 | " .section __ex_table,\"a\" \n" |
| 125 | − " "STR(PTR)" 1b, 4b \n" | |
| 126 | − " "STR(PTR)" 2b, 4b \n" | |
| 125 | + " "STR(PTR_WD)" 1b, 4b \n" | |
| 126 | + " "STR(PTR_WD)" 2b, 4b \n" | |
| 127 | 127 | " .previous \n" |
| 128 | 128 | " .set pop \n" |
| 129 | 129 | : [old] "=&r" (old), |
| @@ -152,8 +152,8 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) · 22 unmodified lines | ||
| 152 | 152 | " j 3b \n" |
| 153 | 153 | " .previous \n" |
| 154 | 154 | " .section __ex_table,\"a\" \n" |
| 155 | − " "STR(PTR)" 1b, 5b \n" | |
| 156 | − " "STR(PTR)" 2b, 5b \n" | |
| 155 | + " "STR(PTR_WD)" 1b, 5b \n" | |
| 156 | + " "STR(PTR_WD)" 2b, 5b \n" | |
| 157 | 157 | " .previous \n" |
| 158 | 158 | " .set pop \n" |
| 159 | 159 | : [old] "=&r" (old), |
| @@ -347,7 +347,7 @@ EXPORT_SYMBOL(csum_partial) · 346 unmodified lines | ||
| 347 | 347 | .if \mode == LEGACY_MODE; \ |
| 348 | 348 | 9: insn reg, addr; \ |
| 349 | 349 | .section __ex_table,"a"; \ |
| 350 | − PTR 9b, .L_exc; \ | |
| 350 | + PTR_WD 9b, .L_exc; \ | |
| 351 | 351 | .previous; \ |
| 352 | 352 | /* This is enabled in EVA mode */ \ |
| 353 | 353 | .else; \ |
| @@ -356,7 +356,7 @@ EXPORT_SYMBOL(csum_partial) · 2 unmodified lines | ||
| 356 | 356 | ((\to == USEROP) && (type == ST_INSN)); \ |
| 357 | 357 | 9: __BUILD_EVA_INSN(insn##e, reg, addr); \ |
| 358 | 358 | .section __ex_table,"a"; \ |
| 359 | − PTR 9b, .L_exc; \ | |
| 359 | + PTR_WD 9b, .L_exc; \ | |
| 360 | 360 | .previous; \ |
| 361 | 361 | .else; \ |
| 362 | 362 | /* EVA without exception */ \ |
| @@ -116,7 +116,7 @@ · 115 unmodified lines | ||
| 116 | 116 | .if \mode == LEGACY_MODE; \ |
| 117 | 117 | 9: insn reg, addr; \ |
| 118 | 118 | .section __ex_table,"a"; \ |
| 119 | − PTR 9b, handler; \ | |
| 119 | + PTR_WD 9b, handler; \ | |
| 120 | 120 | .previous; \ |
| 121 | 121 | /* This is assembled in EVA mode */ \ |
| 122 | 122 | .else; \ |
| @@ -125,7 +125,7 @@ · 2 unmodified lines | ||
| 125 | 125 | ((\to == USEROP) && (type == ST_INSN)); \ |
| 126 | 126 | 9: __BUILD_EVA_INSN(insn##e, reg, addr); \ |
| 127 | 127 | .section __ex_table,"a"; \ |
| 128 | − PTR 9b, handler; \ | |
| 128 | + PTR_WD 9b, handler; \ | |
| 129 | 129 | .previous; \ |
| 130 | 130 | .else; \ |
| 131 | 131 | /* \ |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | 9: ___BUILD_EVA_INSN(insn, reg, addr); \ |
| 53 | 53 | .endif; \ |
| 54 | 54 | .section __ex_table,"a"; \ |
| 55 | − PTR 9b, handler; \ | |
| 55 | + PTR_WD 9b, handler; \ | |
| 56 | 56 | .previous |
| 57 | 57 | |
| 58 | 58 | .macro f_fill64 dst, offset, val, fixup, mode |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #define EX(insn,reg,addr,handler) \ |
| 16 | 16 | 9: insn reg, addr; \ |
| 17 | 17 | .section __ex_table,"a"; \ |
| 18 | − PTR 9b, handler; \ | |
| 18 | + PTR_WD 9b, handler; \ | |
| 19 | 19 | .previous |
| 20 | 20 | |
| 21 | 21 | /* |
| @@ -59,7 +59,7 @@ LEAF(__strncpy_from_user_asm) · 37 unmodified lines | ||
| 59 | 59 | jr ra |
| 60 | 60 | |
| 61 | 61 | .section __ex_table,"a" |
| 62 | − PTR 1b, .Lfault | |
| 62 | + PTR_WD 1b, .Lfault | |
| 63 | 63 | .previous |
| 64 | 64 | |
| 65 | 65 | EXPORT_SYMBOL(__strncpy_from_user_asm) |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #define EX(insn,reg,addr,handler) \ |
| 15 | 15 | 9: insn reg, addr; \ |
| 16 | 16 | .section __ex_table,"a"; \ |
| 17 | − PTR 9b, handler; \ | |
| 17 | + PTR_WD 9b, handler; \ | |
| 18 | 18 | .previous |
| 19 | 19 | |
| 20 | 20 | /* |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/pci.h> |
| 4 | 4 | #include <loongson.h> |
| 5 | 5 | |
| 6 | −static void pci_fixup_radeon(struct pci_dev *pdev) | |
| 6 | +static void pci_fixup_video(struct pci_dev *pdev) | |
| 7 | 7 | { |
| 8 | 8 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
| 9 | 9 | |
| @@ -22,8 +22,7 @@ static void pci_fixup_radeon(struct pci_dev *pdev) · 12 unmodified lines | ||
| 22 | 22 | res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW | |
| 23 | 23 | IORESOURCE_PCI_FIXED; |
| 24 | 24 | |
| 25 | − dev_info(&pdev->dev, "BAR %d: assigned %pR for Radeon ROM\n", | |
| 26 | − PCI_ROM_RESOURCE, res); | |
| 25 | + dev_info(&pdev->dev, "Video device with shadowed ROM at %pR\n", res); | |
| 27 | 26 | } |
| 28 | −DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, 0x9615, | |
| 29 | − PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_radeon); | |
| 27 | +DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_ATI, 0x9615, | |
| 28 | + PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); | |
| @@ -223,6 +223,8 @@ static __always_inline void update_user_segments(u32 val) · 222 unmodified lines | ||
| 223 | 223 | update_user_segment(15, val); |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | +int __init find_free_bat(void); | |
| 227 | +unsigned int bat_block_size(unsigned long base, unsigned long top); | |
| 226 | 228 | #endif /* !__ASSEMBLY__ */ |
| 227 | 229 | |
| 228 | 230 | /* We happily ignore the smaller BATs on 601, we don't actually use |
| @@ -178,6 +178,7 @@ static inline bool pte_user(pte_t pte) · 177 unmodified lines | ||
| 178 | 178 | #ifndef __ASSEMBLY__ |
| 179 | 179 | |
| 180 | 180 | int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); |
| 181 | +void unmap_kernel_page(unsigned long va); | |
| 181 | 182 | |
| 182 | 183 | #endif /* !__ASSEMBLY__ */ |
| 183 | 184 | |
| @@ -1082,6 +1082,8 @@ static inline int map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t p · 1081 unmodified lines | ||
| 1082 | 1082 | return hash__map_kernel_page(ea, pa, prot); |
| 1083 | 1083 | } |
| 1084 | 1084 | |
| 1085 | +void unmap_kernel_page(unsigned long va); | |
| 1086 | + | |
| 1085 | 1087 | static inline int __meminit vmemmap_create_mapping(unsigned long start, |
| 1086 | 1088 | unsigned long page_size, |
| 1087 | 1089 | unsigned long phys) |
| @@ -111,8 +111,10 @@ static inline void __set_fixmap(enum fixed_addresses idx, · 110 unmodified lines | ||
| 111 | 111 | BUILD_BUG_ON(idx >= __end_of_fixed_addresses); |
| 112 | 112 | else if (WARN_ON(idx >= __end_of_fixed_addresses)) |
| 113 | 113 | return; |
| 114 | − | |
| 115 | − map_kernel_page(__fix_to_virt(idx), phys, flags); | |
| 114 | + if (pgprot_val(flags)) | |
| 115 | + map_kernel_page(__fix_to_virt(idx), phys, flags); | |
| 116 | + else | |
| 117 | + unmap_kernel_page(__fix_to_virt(idx)); | |
| 116 | 118 | } |
| 117 | 119 | |
| 118 | 120 | #define __early_set_fixmap __set_fixmap |
| @@ -473,7 +473,7 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs) · 472 unmodified lines | ||
| 473 | 473 | return !(regs->msr & MSR_EE); |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | −static inline bool should_hard_irq_enable(void) | |
| 476 | +static __always_inline bool should_hard_irq_enable(void) | |
| 477 | 477 | { |
| 478 | 478 | return false; |
| 479 | 479 | } |
| @@ -39,7 +39,6 @@ struct kvm_nested_guest { · 38 unmodified lines | ||
| 39 | 39 | pgd_t *shadow_pgtable; /* our page table for this guest */ |
| 40 | 40 | u64 l1_gr_to_hr; /* L1's addr of part'n-scoped table */ |
| 41 | 41 | u64 process_table; /* process table entry for this guest */ |
| 42 | − u64 hfscr; /* HFSCR that the L1 requested for this nested guest */ | |
| 43 | 42 | long refcnt; /* number of pointers to this struct */ |
| 44 | 43 | struct mutex tlb_lock; /* serialize page faults and tlbies */ |
| 45 | 44 | struct kvm_nested_guest *next; |
| @@ -818,6 +818,7 @@ struct kvm_vcpu_arch { · 817 unmodified lines | ||
| 818 | 818 | |
| 819 | 819 | /* For support of nested guests */ |
| 820 | 820 | struct kvm_nested_guest *nested; |
| 821 | + u64 nested_hfscr; /* HFSCR that the L1 requested for the nested guest */ | |
| 821 | 822 | u32 nested_vcpu_id; |
| 822 | 823 | gpa_t nested_io_gpr; |
| 823 | 824 | #endif |
| @@ -64,6 +64,7 @@ extern int icache_44x_need_flush; · 63 unmodified lines | ||
| 64 | 64 | #ifndef __ASSEMBLY__ |
| 65 | 65 | |
| 66 | 66 | int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot); |
| 67 | +void unmap_kernel_page(unsigned long va); | |
| 67 | 68 | |
| 68 | 69 | #endif /* !__ASSEMBLY__ */ |
| 69 | 70 | |
| @@ -308,6 +308,7 @@ static inline void __ptep_set_access_flags(struct vm_area_struct *vma, · 307 unmodified lines | ||
| 308 | 308 | #define __swp_entry_to_pte(x) __pte((x).val) |
| 309 | 309 | |
| 310 | 310 | int map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot); |
| 311 | +void unmap_kernel_page(unsigned long va); | |
| 311 | 312 | extern int __meminit vmemmap_create_mapping(unsigned long start, |
| 312 | 313 | unsigned long page_size, |
| 313 | 314 | unsigned long phys); |
| @@ -500,6 +500,7 @@ · 499 unmodified lines | ||
| 500 | 500 | #define PPC_RAW_LDX(r, base, b) (0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) |
| 501 | 501 | #define PPC_RAW_LHZ(r, base, i) (0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) |
| 502 | 502 | #define PPC_RAW_LHBRX(r, base, b) (0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) |
| 503 | +#define PPC_RAW_LWBRX(r, base, b) (0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) | |
| 503 | 504 | #define PPC_RAW_LDBRX(r, base, b) (0x7c000428 | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) |
| 504 | 505 | #define PPC_RAW_STWCX(s, a, b) (0x7c00012d | ___PPC_RS(s) | ___PPC_RA(a) | ___PPC_RB(b)) |
| 505 | 506 | #define PPC_RAW_CMPWI(a, i) (0x2c000000 | ___PPC_RA(a) | IMM_L(i)) |
| @@ -90,7 +90,7 @@ static inline void syscall_get_arguments(struct task_struct *task, · 89 unmodified lines | ||
| 90 | 90 | unsigned long val, mask = -1UL; |
| 91 | 91 | unsigned int n = 6; |
| 92 | 92 | |
| 93 | − if (is_32bit_task()) | |
| 93 | + if (is_tsk_32bit_task(task)) | |
| 94 | 94 | mask = 0xffffffff; |
| 95 | 95 | |
| 96 | 96 | while (n--) { |
| @@ -105,7 +105,7 @@ static inline void syscall_get_arguments(struct task_struct *task, · 8 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | static inline int syscall_get_arch(struct task_struct *task) |
| 107 | 107 | { |
| 108 | − if (is_32bit_task()) | |
| 108 | + if (is_tsk_32bit_task(task)) | |
| 109 | 109 | return AUDIT_ARCH_PPC; |
| 110 | 110 | else if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) |
| 111 | 111 | return AUDIT_ARCH_PPC64LE; |
| @@ -168,8 +168,10 @@ static inline bool test_thread_local_flags(unsigned int flags) · 167 unmodified lines | ||
| 168 | 168 | |
| 169 | 169 | #ifdef CONFIG_COMPAT |
| 170 | 170 | #define is_32bit_task() (test_thread_flag(TIF_32BIT)) |
| 171 | +#define is_tsk_32bit_task(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT)) | |
| 171 | 172 | #else |
| 172 | 173 | #define is_32bit_task() (IS_ENABLED(CONFIG_PPC32)) |
| 174 | +#define is_tsk_32bit_task(tsk) (IS_ENABLED(CONFIG_PPC32)) | |
| 173 | 175 | #endif |
| 174 | 176 | |
| 175 | 177 | #if defined(CONFIG_PPC64) |
| @@ -30,6 +30,7 @@ COMPAT_SYS_CALL_TABLE: · 29 unmodified lines | ||
| 30 | 30 | .ifc \srr,srr |
| 31 | 31 | mfspr r11,SPRN_SRR0 |
| 32 | 32 | ld r12,_NIP(r1) |
| 33 | + clrrdi r11,r11,2 | |
| 33 | 34 | clrrdi r12,r12,2 |
| 34 | 35 | 100: tdne r11,r12 |
| 35 | 36 | EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
| @@ -40,6 +41,7 @@ COMPAT_SYS_CALL_TABLE: · 4 unmodified lines | ||
| 40 | 41 | .else |
| 41 | 42 | mfspr r11,SPRN_HSRR0 |
| 42 | 43 | ld r12,_NIP(r1) |
| 44 | + clrrdi r11,r11,2 | |
| 43 | 45 | clrrdi r12,r12,2 |
| 44 | 46 | 100: tdne r11,r12 |
| 45 | 47 | EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
| @@ -649,8 +649,9 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) · 648 unmodified lines | ||
| 649 | 649 | __this_cpu_inc(irq_stat.timer_irqs_event); |
| 650 | 650 | } else { |
| 651 | 651 | now = *next_tb - now; |
| 652 | − if (now <= decrementer_max) | |
| 653 | − set_dec_or_work(now); | |
| 652 | + if (now > decrementer_max) | |
| 653 | + now = decrementer_max; | |
| 654 | + set_dec_or_work(now); | |
| 654 | 655 | __this_cpu_inc(irq_stat.timer_irqs_others); |
| 655 | 656 | } |
| 656 | 657 | |
| @@ -1816,7 +1816,6 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, · 1815 unmodified lines | ||
| 1816 | 1816 | |
| 1817 | 1817 | static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) |
| 1818 | 1818 | { |
| 1819 | − struct kvm_nested_guest *nested = vcpu->arch.nested; | |
| 1820 | 1819 | int r; |
| 1821 | 1820 | int srcu_idx; |
| 1822 | 1821 | |
| @@ -1922,7 +1921,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) · 99 unmodified lines | ||
| 1922 | 1921 | * it into a HEAI. |
| 1923 | 1922 | */ |
| 1924 | 1923 | if (!(vcpu->arch.hfscr_permitted & (1UL << cause)) || |
| 1925 | − (nested->hfscr & (1UL << cause))) { | |
| 1924 | + (vcpu->arch.nested_hfscr & (1UL << cause))) { | |
| 1926 | 1925 | vcpu->arch.trap = BOOK3S_INTERRUPT_H_EMUL_ASSIST; |
| 1927 | 1926 | |
| 1928 | 1927 | /* |
| @@ -363,7 +363,7 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) · 362 unmodified lines | ||
| 363 | 363 | /* set L1 state to L2 state */ |
| 364 | 364 | vcpu->arch.nested = l2; |
| 365 | 365 | vcpu->arch.nested_vcpu_id = l2_hv.vcpu_token; |
| 366 | − l2->hfscr = l2_hv.hfscr; | |
| 366 | + vcpu->arch.nested_hfscr = l2_hv.hfscr; | |
| 367 | 367 | vcpu->arch.regs = l2_regs; |
| 368 | 368 | |
| 369 | 369 | /* Guest must always run with ME enabled, HV disabled. */ |
| @@ -76,7 +76,7 @@ unsigned long p_block_mapped(phys_addr_t pa) · 75 unmodified lines | ||
| 76 | 76 | return 0; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | −static int __init find_free_bat(void) | |
| 79 | +int __init find_free_bat(void) | |
| 80 | 80 | { |
| 81 | 81 | int b; |
| 82 | 82 | int n = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4; |
| @@ -100,7 +100,7 @@ static int __init find_free_bat(void) · 17 unmodified lines | ||
| 100 | 100 | * - block size has to be a power of two. This is calculated by finding the |
| 101 | 101 | * highest bit set to 1. |
| 102 | 102 | */ |
| 103 | −static unsigned int block_size(unsigned long base, unsigned long top) | |
| 103 | +unsigned int bat_block_size(unsigned long base, unsigned long top) | |
| 104 | 104 | { |
| 105 | 105 | unsigned int max_size = SZ_256M; |
| 106 | 106 | unsigned int base_shift = (ffs(base) - 1) & 31; |
| @@ -145,7 +145,7 @@ static unsigned long __init __mmu_mapin_ram(unsigned long base, unsigned long to · 38 unmodified lines | ||
| 145 | 145 | int idx; |
| 146 | 146 | |
| 147 | 147 | while ((idx = find_free_bat()) != -1 && base != top) { |
| 148 | − unsigned int size = block_size(base, top); | |
| 148 | + unsigned int size = bat_block_size(base, top); | |
| 149 | 149 | |
| 150 | 150 | if (size < 128 << 10) |
| 151 | 151 | break; |
| @@ -201,12 +201,12 @@ void mmu_mark_initmem_nx(void) · 49 unmodified lines | ||
| 201 | 201 | unsigned long size; |
| 202 | 202 | |
| 203 | 203 | for (i = 0; i < nb - 1 && base < top;) { |
| 204 | − size = block_size(base, top); | |
| 204 | + size = bat_block_size(base, top); | |
| 205 | 205 | setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT); |
| 206 | 206 | base += size; |
| 207 | 207 | } |
| 208 | 208 | if (base < top) { |
| 209 | − size = block_size(base, top); | |
| 209 | + size = bat_block_size(base, top); | |
| 210 | 210 | if ((top - base) > size) { |
| 211 | 211 | size <<= 1; |
| 212 | 212 | if (strict_kernel_rwx_enabled() && base + size > border) |
| @@ -10,48 +10,51 @@ int __init kasan_init_region(void *start, size_t size) · 9 unmodified lines | ||
| 10 | 10 | { |
| 11 | 11 | unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start); |
| 12 | 12 | unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size); |
| 13 | − unsigned long k_cur = k_start; | |
| 14 | − int k_size = k_end - k_start; | |
| 15 | − int k_size_base = 1 << (ffs(k_size) - 1); | |
| 13 | + unsigned long k_nobat = k_start; | |
| 14 | + unsigned long k_cur; | |
| 15 | + phys_addr_t phys; | |
| 16 | 16 | int ret; |
| 17 | − void *block; | |
| 18 | 17 | |
| 19 | − block = memblock_alloc(k_size, k_size_base); | |
| 20 | − | |
| 21 | − if (block && k_size_base >= SZ_128K && k_start == ALIGN(k_start, k_size_base)) { | |
| 22 | − int shift = ffs(k_size - k_size_base); | |
| 23 | − int k_size_more = shift ? 1 << (shift - 1) : 0; | |
| 24 | − | |
| 25 | − setbat(-1, k_start, __pa(block), k_size_base, PAGE_KERNEL); | |
| 26 | − if (k_size_more >= SZ_128K) | |
| 27 | − setbat(-1, k_start + k_size_base, __pa(block) + k_size_base, | |
| 28 | − k_size_more, PAGE_KERNEL); | |
| 29 | − if (v_block_mapped(k_start)) | |
| 30 | − k_cur = k_start + k_size_base; | |
| 31 | − if (v_block_mapped(k_start + k_size_base)) | |
| 32 | − k_cur = k_start + k_size_base + k_size_more; | |
| 33 | − | |
| 34 | − update_bats(); | |
| 18 | + while (k_nobat < k_end) { | |
| 19 | + unsigned int k_size = bat_block_size(k_nobat, k_end); | |
| 20 | + int idx = find_free_bat(); | |
| 21 | + | |
| 22 | + if (idx == -1) | |
| 23 | + break; | |
| 24 | + if (k_size < SZ_128K) | |
| 25 | + break; | |
| 26 | + phys = memblock_phys_alloc_range(k_size, k_size, 0, | |
| 27 | + MEMBLOCK_ALLOC_ANYWHERE); | |
| 28 | + if (!phys) | |
| 29 | + break; | |
| 30 | + | |
| 31 | + setbat(idx, k_nobat, phys, k_size, PAGE_KERNEL); | |
| 32 | + k_nobat += k_size; | |
| 35 | 33 | } |
| 34 | + if (k_nobat != k_start) | |
| 35 | + update_bats(); | |
| 36 | 36 | |
| 37 | − if (!block) | |
| 38 | − block = memblock_alloc(k_size, PAGE_SIZE); | |
| 39 | − if (!block) | |
| 40 | − return -ENOMEM; | |
| 37 | + if (k_nobat < k_end) { | |
| 38 | + phys = memblock_phys_alloc_range(k_end - k_nobat, PAGE_SIZE, 0, | |
| 39 | + MEMBLOCK_ALLOC_ANYWHERE); | |
| 40 | + if (!phys) | |
| 41 | + return -ENOMEM; | |
| 42 | + } | |
| 41 | 43 | |
| 42 | 44 | ret = kasan_init_shadow_page_tables(k_start, k_end); |
| 43 | 45 | if (ret) |
| 44 | 46 | return ret; |
| 45 | 47 | |
| 46 | − kasan_update_early_region(k_start, k_cur, __pte(0)); | |
| 48 | + kasan_update_early_region(k_start, k_nobat, __pte(0)); | |
| 47 | 49 | |
| 48 | − for (; k_cur < k_end; k_cur += PAGE_SIZE) { | |
| 50 | + for (k_cur = k_nobat; k_cur < k_end; k_cur += PAGE_SIZE) { | |
| 49 | 51 | pmd_t *pmd = pmd_off_k(k_cur); |
| 50 | − void *va = block + k_cur - k_start; | |
| 51 | − pte_t pte = pfn_pte(PHYS_PFN(__pa(va)), PAGE_KERNEL); | |
| 52 | + pte_t pte = pfn_pte(PHYS_PFN(phys + k_cur - k_nobat), PAGE_KERNEL); | |
| 52 | 53 | |
| 53 | 54 | __set_pte_at(&init_mm, k_cur, pte_offset_kernel(pmd, k_cur), pte, 0); |
| 54 | 55 | } |
| 55 | 56 | flush_tlb_kernel_range(k_start, k_end); |
| 57 | + memset(kasan_mem_to_shadow(start), 0, k_end - k_start); | |
| 58 | + | |
| 56 | 59 | return 0; |
| 57 | 60 | } |
| @@ -206,6 +206,15 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, · 205 unmodified lines | ||
| 206 | 206 | __set_pte_at(mm, addr, ptep, pte, 0); |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | +void unmap_kernel_page(unsigned long va) | |
| 210 | +{ | |
| 211 | + pmd_t *pmdp = pmd_off_k(va); | |
| 212 | + pte_t *ptep = pte_offset_kernel(pmdp, va); | |
| 213 | + | |
| 214 | + pte_clear(&init_mm, va, ptep); | |
| 215 | + flush_tlb_kernel_range(va, va + PAGE_SIZE); | |
| 216 | +} | |
| 217 | + | |
| 209 | 218 | /* |
| 210 | 219 | * This is called when relaxing access to a PTE. It's also called in the page |
| 211 | 220 | * fault path when we don't hit any of the major fault cases, ie, a minor |
| @@ -23,15 +23,15 @@ static void bpf_jit_fill_ill_insns(void *area, unsigned int size) · 22 unmodified lines | ||
| 23 | 23 | memset32(area, BREAKPOINT_INSTRUCTION, size / 4); |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | −/* Fix the branch target addresses for subprog calls */ | |
| 27 | −static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image, | |
| 28 | − struct codegen_context *ctx, u32 *addrs) | |
| 26 | +/* Fix updated addresses (for subprog calls, ldimm64, et al) during extra pass */ | |
| 27 | +static int bpf_jit_fixup_addresses(struct bpf_prog *fp, u32 *image, | |
| 28 | + struct codegen_context *ctx, u32 *addrs) | |
| 29 | 29 | { |
| 30 | 30 | const struct bpf_insn *insn = fp->insnsi; |
| 31 | 31 | bool func_addr_fixed; |
| 32 | 32 | u64 func_addr; |
| 33 | 33 | u32 tmp_idx; |
| 34 | − int i, ret; | |
| 34 | + int i, j, ret; | |
| 35 | 35 | |
| 36 | 36 | for (i = 0; i < fp->len; i++) { |
| 37 | 37 | /* |
| @@ -66,6 +66,23 @@ static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image, · 28 unmodified lines | ||
| 66 | 66 | * of the JITed sequence remains unchanged. |
| 67 | 67 | */ |
| 68 | 68 | ctx->idx = tmp_idx; |
| 69 | + } else if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW)) { | |
| 70 | + tmp_idx = ctx->idx; | |
| 71 | + ctx->idx = addrs[i] / 4; | |
| 72 | +#ifdef CONFIG_PPC32 | |
| 73 | + PPC_LI32(ctx->b2p[insn[i].dst_reg] - 1, (u32)insn[i + 1].imm); | |
| 74 | + PPC_LI32(ctx->b2p[insn[i].dst_reg], (u32)insn[i].imm); | |
| 75 | + for (j = ctx->idx - addrs[i] / 4; j < 4; j++) | |
| 76 | + EMIT(PPC_RAW_NOP()); | |
| 77 | +#else | |
| 78 | + func_addr = ((u64)(u32)insn[i].imm) | (((u64)(u32)insn[i + 1].imm) << 32); | |
| 79 | + PPC_LI64(b2p[insn[i].dst_reg], func_addr); | |
| 80 | + /* overwrite rest with nops */ | |
| 81 | + for (j = ctx->idx - addrs[i] / 4; j < 5; j++) | |
| 82 | + EMIT(PPC_RAW_NOP()); | |
| 83 | +#endif | |
| 84 | + ctx->idx = tmp_idx; | |
| 85 | + i++; | |
| 69 | 86 | } |
| 70 | 87 | } |
| 71 | 88 | |
| @@ -200,13 +217,13 @@ skip_init_ctx: · 128 unmodified lines | ||
| 200 | 217 | /* |
| 201 | 218 | * Do not touch the prologue and epilogue as they will remain |
| 202 | 219 | * unchanged. Only fix the branch target address for subprog |
| 203 | − * calls in the body. | |
| 220 | + * calls in the body, and ldimm64 instructions. | |
| 204 | 221 | * |
| 205 | 222 | * This does not change the offsets and lengths of the subprog |
| 206 | 223 | * call instruction sequences and hence, the size of the JITed |
| 207 | 224 | * image as well. |
| 208 | 225 | */ |
| 209 | − bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs); | |
| 226 | + bpf_jit_fixup_addresses(fp, code_base, &cgctx, addrs); | |
| 210 | 227 | |
| 211 | 228 | /* There is no need to perform the usual passes. */ |
| 212 | 229 | goto skip_codegen_passes; |
| @@ -191,6 +191,9 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun · 190 unmodified lines | ||
| 191 | 191 | |
| 192 | 192 | if (image && rel < 0x2000000 && rel >= -0x2000000) { |
| 193 | 193 | PPC_BL_ABS(func); |
| 194 | + EMIT(PPC_RAW_NOP()); | |
| 195 | + EMIT(PPC_RAW_NOP()); | |
| 196 | + EMIT(PPC_RAW_NOP()); | |
| 194 | 197 | } else { |
| 195 | 198 | /* Load function address into r0 */ |
| 196 | 199 | EMIT(PPC_RAW_LIS(_R0, IMM_H(func))); |
| @@ -290,6 +293,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * · 93 unmodified lines | ||
| 290 | 293 | bool func_addr_fixed; |
| 291 | 294 | u64 func_addr; |
| 292 | 295 | u32 true_cond; |
| 296 | + u32 tmp_idx; | |
| 297 | + int j; | |
| 293 | 298 | |
| 294 | 299 | /* |
| 295 | 300 | * addrs[] maps a BPF bytecode address into a real offset from |
| @@ -905,8 +910,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * · 609 unmodified lines | ||
| 905 | 910 | * 16 byte instruction that uses two 'struct bpf_insn' |
| 906 | 911 | */ |
| 907 | 912 | case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */ |
| 913 | + tmp_idx = ctx->idx; | |
| 908 | 914 | PPC_LI32(dst_reg_h, (u32)insn[i + 1].imm); |
| 909 | 915 | PPC_LI32(dst_reg, (u32)insn[i].imm); |
| 916 | + /* padding to allow full 4 instructions for later patching */ | |
| 917 | + for (j = ctx->idx - tmp_idx; j < 4; j++) | |
| 918 | + EMIT(PPC_RAW_NOP()); | |
| 910 | 919 | /* Adjust for two bpf instructions */ |
| 911 | 920 | addrs[++i] = ctx->idx * 4; |
| 912 | 921 | break; |
| @@ -319,6 +319,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context * · 318 unmodified lines | ||
| 319 | 319 | u64 imm64; |
| 320 | 320 | u32 true_cond; |
| 321 | 321 | u32 tmp_idx; |
| 322 | + int j; | |
| 322 | 323 | |
| 323 | 324 | /* |
| 324 | 325 | * addrs[] maps a BPF bytecode address into a real offset from |
| @@ -633,17 +634,21 @@ bpf_alu32_trunc: · 308 unmodified lines | ||
| 633 | 634 | EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1])); |
| 634 | 635 | break; |
| 635 | 636 | case 64: |
| 636 | − /* | |
| 637 | − * Way easier and faster(?) to store the value | |
| 638 | − * into stack and then use ldbrx | |
| 639 | − * | |
| 640 | − * ctx->seen will be reliable in pass2, but | |
| 641 | − * the instructions generated will remain the | |
| 642 | − * same across all passes | |
| 643 | − */ | |
| 637 | + /* Store the value to stack and then use byte-reverse loads */ | |
| 644 | 638 | PPC_BPF_STL(dst_reg, 1, bpf_jit_stack_local(ctx)); |
| 645 | 639 | EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx))); |
| 646 | − EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1])); | |
| 640 | + if (cpu_has_feature(CPU_FTR_ARCH_206)) { | |
| 641 | + EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1])); | |
| 642 | + } else { | |
| 643 | + EMIT(PPC_RAW_LWBRX(dst_reg, 0, b2p[TMP_REG_1])); | |
| 644 | + if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) | |
| 645 | + EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, 32)); | |
| 646 | + EMIT(PPC_RAW_LI(b2p[TMP_REG_2], 4)); | |
| 647 | + EMIT(PPC_RAW_LWBRX(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p[TMP_REG_1])); | |
| 648 | + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) | |
| 649 | + EMIT(PPC_RAW_SLDI(b2p[TMP_REG_2], b2p[TMP_REG_2], 32)); | |
| 650 | + EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_2])); | |
| 651 | + } | |
| 647 | 652 | break; |
| 648 | 653 | } |
| 649 | 654 | break; |
| @@ -848,9 +853,13 @@ emit_clear: · 198 unmodified lines | ||
| 848 | 853 | case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */ |
| 849 | 854 | imm64 = ((u64)(u32) insn[i].imm) | |
| 850 | 855 | (((u64)(u32) insn[i+1].imm) << 32); |
| 856 | + tmp_idx = ctx->idx; | |
| 857 | + PPC_LI64(dst_reg, imm64); | |
| 858 | + /* padding to allow full 5 instructions for later patching */ | |
| 859 | + for (j = ctx->idx - tmp_idx; j < 5; j++) | |
| 860 | + EMIT(PPC_RAW_NOP()); | |
| 851 | 861 | /* Adjust for two bpf instructions */ |
| 852 | 862 | addrs[++i] = ctx->idx * 4; |
| 853 | − PPC_LI64(dst_reg, imm64); | |
| 854 | 863 | break; |
| 855 | 864 | |
| 856 | 865 | /* |
| @@ -776,6 +776,34 @@ static void pmao_restore_workaround(bool ebb) · 775 unmodified lines | ||
| 776 | 776 | mtspr(SPRN_PMC6, pmcs[5]); |
| 777 | 777 | } |
| 778 | 778 | |
| 779 | +/* | |
| 780 | + * If the perf subsystem wants performance monitor interrupts as soon as | |
| 781 | + * possible (e.g., to sample the instruction address and stack chain), | |
| 782 | + * this should return true. The IRQ masking code can then enable MSR[EE] | |
| 783 | + * in some places (e.g., interrupt handlers) that allows PMI interrupts | |
| 784 | + * through to improve accuracy of profiles, at the cost of some performance. | |
| 785 | + * | |
| 786 | + * The PMU counters can be enabled by other means (e.g., sysfs raw SPR | |
| 787 | + * access), but in that case there is no need for prompt PMI handling. | |
| 788 | + * | |
| 789 | + * This currently returns true if any perf counter is being used. It | |
| 790 | + * could possibly return false if only events are being counted rather than | |
| 791 | + * samples being taken, but for now this is good enough. | |
| 792 | + */ | |
| 793 | +bool power_pmu_wants_prompt_pmi(void) | |
| 794 | +{ | |
| 795 | + struct cpu_hw_events *cpuhw; | |
| 796 | + | |
| 797 | + /* | |
| 798 | + * This could simply test local_paca->pmcregs_in_use if that were not | |
| 799 | + * under ifdef KVM. | |
| 800 | + */ | |
| 801 | + if (!ppmu) | |
| 802 | + return false; | |
| 803 | + | |
| 804 | + cpuhw = this_cpu_ptr(&cpu_hw_events); | |
| 805 | + return cpuhw->n_events; | |
| 806 | +} | |
| 779 | 807 | #endif /* CONFIG_PPC64 */ |
| 780 | 808 | |
| 781 | 809 | static void perf_event_interrupt(struct pt_regs *regs); |
| @@ -1327,9 +1355,20 @@ static void power_pmu_disable(struct pmu *pmu) · 545 unmodified lines | ||
| 1327 | 1355 | * Otherwise provide a warning if there is PMI pending, but |
| 1328 | 1356 | * no counter is found overflown. |
| 1329 | 1357 | */ |
| 1330 | − if (any_pmc_overflown(cpuhw)) | |
| 1331 | − clear_pmi_irq_pending(); | |
| 1332 | − else | |
| 1358 | + if (any_pmc_overflown(cpuhw)) { | |
| 1359 | + /* | |
| 1360 | + * Since power_pmu_disable runs under local_irq_save, it | |
| 1361 | + * could happen that code hits a PMC overflow without PMI | |
| 1362 | + * pending in paca. Hence only clear PMI pending if it was | |
| 1363 | + * set. | |
| 1364 | + * | |
| 1365 | + * If a PMI is pending, then MSR[EE] must be disabled (because | |
| 1366 | + * the masked PMI handler disabling EE). So it is safe to | |
| 1367 | + * call clear_pmi_irq_pending(). | |
| 1368 | + */ | |
| 1369 | + if (pmi_irq_pending()) | |
| 1370 | + clear_pmi_irq_pending(); | |
| 1371 | + } else | |
| 1333 | 1372 | WARN_ON(pmi_irq_pending()); |
| 1334 | 1373 | |
| 1335 | 1374 | val = mmcra = cpuhw->mmcr.mmcra; |
| @@ -2438,36 +2477,6 @@ static void perf_event_interrupt(struct pt_regs *regs) · 1102 unmodified lines | ||
| 2438 | 2477 | perf_sample_event_took(sched_clock() - start_clock); |
| 2439 | 2478 | } |
| 2440 | 2479 | |
| 2441 | −/* | |
| 2442 | − * If the perf subsystem wants performance monitor interrupts as soon as | |
| 2443 | − * possible (e.g., to sample the instruction address and stack chain), | |
| 2444 | − * this should return true. The IRQ masking code can then enable MSR[EE] | |
| 2445 | − * in some places (e.g., interrupt handlers) that allows PMI interrupts | |
| 2446 | − * though to improve accuracy of profiles, at the cost of some performance. | |
| 2447 | − * | |
| 2448 | − * The PMU counters can be enabled by other means (e.g., sysfs raw SPR | |
| 2449 | − * access), but in that case there is no need for prompt PMI handling. | |
| 2450 | − * | |
| 2451 | − * This currently returns true if any perf counter is being used. It | |
| 2452 | − * could possibly return false if only events are being counted rather than | |
| 2453 | − * samples being taken, but for now this is good enough. | |
| 2454 | − */ | |
| 2455 | −bool power_pmu_wants_prompt_pmi(void) | |
| 2456 | −{ | |
| 2457 | − struct cpu_hw_events *cpuhw; | |
| 2458 | − | |
| 2459 | − /* | |
| 2460 | − * This could simply test local_paca->pmcregs_in_use if that were not | |
| 2461 | − * under ifdef KVM. | |
| 2462 | − */ | |
| 2463 | − | |
| 2464 | − if (!ppmu) | |
| 2465 | − return false; | |
| 2466 | − | |
| 2467 | − cpuhw = this_cpu_ptr(&cpu_hw_events); | |
| 2468 | − return cpuhw->n_events; | |
| 2469 | −} | |
| 2470 | − | |
| 2471 | 2480 | static int power_pmu_prepare_cpu(unsigned int cpu) |
| 2472 | 2481 | { |
| 2473 | 2482 | struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); |
| @@ -945,6 +945,9 @@ config S390_GUEST · 944 unmodified lines | ||
| 945 | 945 | |
| 946 | 946 | endmenu |
| 947 | 947 | |
| 948 | +config S390_MODULES_SANITY_TEST_HELPERS | |
| 949 | + def_bool n | |
| 950 | + | |
| 948 | 951 | menu "Selftests" |
| 949 | 952 | |
| 950 | 953 | config S390_UNWIND_SELFTEST |
| @@ -971,4 +974,16 @@ config S390_KPROBES_SANITY_TEST · 20 unmodified lines | ||
| 971 | 974 | |
| 972 | 975 | Say N if you are unsure. |
| 973 | 976 | |
| 977 | +config S390_MODULES_SANITY_TEST | |
| 978 | + def_tristate n | |
| 979 | + depends on KUNIT | |
| 980 | + default KUNIT_ALL_TESTS | |
| 981 | + prompt "Enable s390 specific modules tests" | |
| 982 | + select S390_MODULES_SANITY_TEST_HELPERS | |
| 983 | + help | |
| 984 | + This option enables an s390 specific modules test. This option is | |
| 985 | + not useful for distributions or general kernels, but only for | |
| 986 | + kernel developers working on architecture code. | |
| 987 | + | |
| 988 | + Say N if you are unsure. | |
| 974 | 989 | endmenu |
| @@ -63,6 +63,7 @@ CONFIG_APPLDATA_BASE=y · 62 unmodified lines | ||
| 63 | 63 | CONFIG_KVM=m |
| 64 | 64 | CONFIG_S390_UNWIND_SELFTEST=m |
| 65 | 65 | CONFIG_S390_KPROBES_SANITY_TEST=m |
| 66 | +CONFIG_S390_MODULES_SANITY_TEST=m | |
| 66 | 67 | CONFIG_KPROBES=y |
| 67 | 68 | CONFIG_JUMP_LABEL=y |
| 68 | 69 | CONFIG_STATIC_KEYS_SELFTEST=y |
| @@ -96,7 +97,6 @@ CONFIG_MEMORY_HOTPLUG=y · 27 unmodified lines | ||
| 96 | 97 | CONFIG_MEMORY_HOTREMOVE=y |
| 97 | 98 | CONFIG_KSM=y |
| 98 | 99 | CONFIG_TRANSPARENT_HUGEPAGE=y |
| 99 | −CONFIG_FRONTSWAP=y | |
| 100 | 100 | CONFIG_CMA_DEBUG=y |
| 101 | 101 | CONFIG_CMA_DEBUGFS=y |
| 102 | 102 | CONFIG_CMA_SYSFS=y |
| @@ -109,6 +109,7 @@ CONFIG_DEFERRED_STRUCT_PAGE_INIT=y · 6 unmodified lines | ||
| 109 | 109 | CONFIG_IDLE_PAGE_TRACKING=y |
| 110 | 110 | CONFIG_PERCPU_STATS=y |
| 111 | 111 | CONFIG_GUP_TEST=y |
| 112 | +CONFIG_ANON_VMA_NAME=y | |
| 112 | 113 | CONFIG_NET=y |
| 113 | 114 | CONFIG_PACKET=y |
| 114 | 115 | CONFIG_PACKET_DIAG=m |
| @@ -116,7 +117,6 @@ CONFIG_UNIX=y · 1 unmodified line | ||
| 116 | 117 | CONFIG_UNIX_DIAG=m |
| 117 | 118 | CONFIG_XFRM_USER=m |
| 118 | 119 | CONFIG_NET_KEY=m |
| 119 | −CONFIG_NET_SWITCHDEV=y | |
| 120 | 120 | CONFIG_SMC=m |
| 121 | 121 | CONFIG_SMC_DIAG=m |
| 122 | 122 | CONFIG_INET=y |
| @@ -185,7 +185,6 @@ CONFIG_NF_CT_NETLINK_TIMEOUT=m · 62 unmodified lines | ||
| 185 | 185 | CONFIG_NF_TABLES=m |
| 186 | 186 | CONFIG_NF_TABLES_INET=y |
| 187 | 187 | CONFIG_NFT_CT=m |
| 188 | −CONFIG_NFT_COUNTER=m | |
| 189 | 188 | CONFIG_NFT_LOG=m |
| 190 | 189 | CONFIG_NFT_LIMIT=m |
| 191 | 190 | CONFIG_NFT_NAT=m |
| @@ -391,6 +390,7 @@ CONFIG_OPENVSWITCH=m · 199 unmodified lines | ||
| 391 | 390 | CONFIG_VSOCKETS=m |
| 392 | 391 | CONFIG_VIRTIO_VSOCKETS=m |
| 393 | 392 | CONFIG_NETLINK_DIAG=m |
| 393 | +CONFIG_NET_SWITCHDEV=y | |
| 394 | 394 | CONFIG_CGROUP_NET_PRIO=y |
| 395 | 395 | CONFIG_NET_PKTGEN=m |
| 396 | 396 | CONFIG_PCI=y |
| @@ -400,6 +400,7 @@ CONFIG_PCI_IOV=y · 3 unmodified lines | ||
| 400 | 400 | CONFIG_HOTPLUG_PCI=y |
| 401 | 401 | CONFIG_HOTPLUG_PCI_S390=y |
| 402 | 402 | CONFIG_DEVTMPFS=y |
| 403 | +CONFIG_DEVTMPFS_SAFE=y | |
| 403 | 404 | CONFIG_CONNECTOR=y |
| 404 | 405 | CONFIG_ZRAM=y |
| 405 | 406 | CONFIG_BLK_DEV_LOOP=m |
| @@ -501,6 +502,7 @@ CONFIG_NLMON=m · 95 unmodified lines | ||
| 501 | 502 | # CONFIG_NET_VENDOR_DEC is not set |
| 502 | 503 | # CONFIG_NET_VENDOR_DLINK is not set |
| 503 | 504 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 505 | +# CONFIG_NET_VENDOR_ENGLEDER is not set | |
| 504 | 506 | # CONFIG_NET_VENDOR_EZCHIP is not set |
| 505 | 507 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 506 | 508 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| @@ -511,7 +513,6 @@ CONFIG_NLMON=m · 4 unmodified lines | ||
| 511 | 513 | CONFIG_MLX4_EN=m |
| 512 | 514 | CONFIG_MLX5_CORE=m |
| 513 | 515 | CONFIG_MLX5_CORE_EN=y |
| 514 | −CONFIG_MLX5_ESWITCH=y | |
| 515 | 516 | # CONFIG_NET_VENDOR_MICREL is not set |
| 516 | 517 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 517 | 518 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -542,6 +543,7 @@ CONFIG_MLX5_ESWITCH=y · 24 unmodified lines | ||
| 542 | 543 | # CONFIG_NET_VENDOR_SYNOPSYS is not set |
| 543 | 544 | # CONFIG_NET_VENDOR_TEHUTI is not set |
| 544 | 545 | # CONFIG_NET_VENDOR_TI is not set |
| 546 | +# CONFIG_NET_VENDOR_VERTEXCOM is not set | |
| 545 | 547 | # CONFIG_NET_VENDOR_VIA is not set |
| 546 | 548 | # CONFIG_NET_VENDOR_WIZNET is not set |
| 547 | 549 | # CONFIG_NET_VENDOR_XILINX is not set |
| @@ -592,6 +594,7 @@ CONFIG_VIRTIO_BALLOON=m · 44 unmodified lines | ||
| 592 | 594 | CONFIG_VIRTIO_INPUT=y |
| 593 | 595 | CONFIG_VHOST_NET=m |
| 594 | 596 | CONFIG_VHOST_VSOCK=m |
| 597 | +# CONFIG_SURFACE_PLATFORMS is not set | |
| 595 | 598 | CONFIG_S390_CCW_IOMMU=y |
| 596 | 599 | CONFIG_S390_AP_IOMMU=y |
| 597 | 600 | CONFIG_EXT4_FS=y |
| @@ -756,9 +759,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 158 unmodified lines | ||
| 756 | 759 | CONFIG_CRYPTO_USER_API_RNG=m |
| 757 | 760 | CONFIG_CRYPTO_USER_API_AEAD=m |
| 758 | 761 | CONFIG_CRYPTO_STATS=y |
| 759 | −CONFIG_CRYPTO_LIB_BLAKE2S=m | |
| 760 | −CONFIG_CRYPTO_LIB_CURVE25519=m | |
| 761 | −CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | |
| 762 | 762 | CONFIG_ZCRYPT=m |
| 763 | 763 | CONFIG_PKEY=m |
| 764 | 764 | CONFIG_CRYPTO_PAES_S390=m |
| @@ -774,6 +774,8 @@ CONFIG_CRYPTO_GHASH_S390=m · 9 unmodified lines | ||
| 774 | 774 | CONFIG_CRYPTO_CRC32_S390=y |
| 775 | 775 | CONFIG_CRYPTO_DEV_VIRTIO=m |
| 776 | 776 | CONFIG_CORDIC=m |
| 777 | +CONFIG_CRYPTO_LIB_CURVE25519=m | |
| 778 | +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | |
| 777 | 779 | CONFIG_CRC32_SELFTEST=y |
| 778 | 780 | CONFIG_CRC4=m |
| 779 | 781 | CONFIG_CRC7=m |
| @@ -807,7 +809,6 @@ CONFIG_SLUB_DEBUG_ON=y · 27 unmodified lines | ||
| 807 | 809 | CONFIG_SLUB_STATS=y |
| 808 | 810 | CONFIG_DEBUG_STACK_USAGE=y |
| 809 | 811 | CONFIG_DEBUG_VM=y |
| 810 | −CONFIG_DEBUG_VM_VMACACHE=y | |
| 811 | 812 | CONFIG_DEBUG_VM_PGFLAGS=y |
| 812 | 813 | CONFIG_DEBUG_MEMORY_INIT=y |
| 813 | 814 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m |
| @@ -819,12 +820,11 @@ CONFIG_PANIC_ON_OOPS=y · 5 unmodified lines | ||
| 819 | 820 | CONFIG_DETECT_HUNG_TASK=y |
| 820 | 821 | CONFIG_WQ_WATCHDOG=y |
| 821 | 822 | CONFIG_TEST_LOCKUP=m |
| 822 | −CONFIG_DEBUG_TIMEKEEPING=y | |
| 823 | 823 | CONFIG_PROVE_LOCKING=y |
| 824 | 824 | CONFIG_LOCK_STAT=y |
| 825 | −CONFIG_DEBUG_LOCKDEP=y | |
| 826 | 825 | CONFIG_DEBUG_ATOMIC_SLEEP=y |
| 827 | 826 | CONFIG_DEBUG_LOCKING_API_SELFTESTS=y |
| 827 | +CONFIG_DEBUG_IRQFLAGS=y | |
| 828 | 828 | CONFIG_DEBUG_SG=y |
| 829 | 829 | CONFIG_DEBUG_NOTIFIERS=y |
| 830 | 830 | CONFIG_BUG_ON_DATA_CORRUPTION=y |
| @@ -61,6 +61,7 @@ CONFIG_APPLDATA_BASE=y · 60 unmodified lines | ||
| 61 | 61 | CONFIG_KVM=m |
| 62 | 62 | CONFIG_S390_UNWIND_SELFTEST=m |
| 63 | 63 | CONFIG_S390_KPROBES_SANITY_TEST=m |
| 64 | +CONFIG_S390_MODULES_SANITY_TEST=m | |
| 64 | 65 | CONFIG_KPROBES=y |
| 65 | 66 | CONFIG_JUMP_LABEL=y |
| 66 | 67 | # CONFIG_GCC_PLUGINS is not set |
| @@ -91,7 +92,6 @@ CONFIG_MEMORY_HOTPLUG=y · 24 unmodified lines | ||
| 91 | 92 | CONFIG_MEMORY_HOTREMOVE=y |
| 92 | 93 | CONFIG_KSM=y |
| 93 | 94 | CONFIG_TRANSPARENT_HUGEPAGE=y |
| 94 | −CONFIG_FRONTSWAP=y | |
| 95 | 95 | CONFIG_CMA_SYSFS=y |
| 96 | 96 | CONFIG_CMA_AREAS=7 |
| 97 | 97 | CONFIG_MEM_SOFT_DIRTY=y |
| @@ -101,6 +101,7 @@ CONFIG_ZSMALLOC_STAT=y · 3 unmodified lines | ||
| 101 | 101 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 102 | 102 | CONFIG_IDLE_PAGE_TRACKING=y |
| 103 | 103 | CONFIG_PERCPU_STATS=y |
| 104 | +CONFIG_ANON_VMA_NAME=y | |
| 104 | 105 | CONFIG_NET=y |
| 105 | 106 | CONFIG_PACKET=y |
| 106 | 107 | CONFIG_PACKET_DIAG=m |
| @@ -108,7 +109,6 @@ CONFIG_UNIX=y · 1 unmodified line | ||
| 108 | 109 | CONFIG_UNIX_DIAG=m |
| 109 | 110 | CONFIG_XFRM_USER=m |
| 110 | 111 | CONFIG_NET_KEY=m |
| 111 | −CONFIG_NET_SWITCHDEV=y | |
| 112 | 112 | CONFIG_SMC=m |
| 113 | 113 | CONFIG_SMC_DIAG=m |
| 114 | 114 | CONFIG_INET=y |
| @@ -177,7 +177,6 @@ CONFIG_NF_CT_NETLINK_TIMEOUT=m · 62 unmodified lines | ||
| 177 | 177 | CONFIG_NF_TABLES=m |
| 178 | 178 | CONFIG_NF_TABLES_INET=y |
| 179 | 179 | CONFIG_NFT_CT=m |
| 180 | −CONFIG_NFT_COUNTER=m | |
| 181 | 180 | CONFIG_NFT_LOG=m |
| 182 | 181 | CONFIG_NFT_LIMIT=m |
| 183 | 182 | CONFIG_NFT_NAT=m |
| @@ -382,6 +381,7 @@ CONFIG_OPENVSWITCH=m · 198 unmodified lines | ||
| 382 | 381 | CONFIG_VSOCKETS=m |
| 383 | 382 | CONFIG_VIRTIO_VSOCKETS=m |
| 384 | 383 | CONFIG_NETLINK_DIAG=m |
| 384 | +CONFIG_NET_SWITCHDEV=y | |
| 385 | 385 | CONFIG_CGROUP_NET_PRIO=y |
| 386 | 386 | CONFIG_NET_PKTGEN=m |
| 387 | 387 | CONFIG_PCI=y |
| @@ -391,6 +391,7 @@ CONFIG_HOTPLUG_PCI=y · 3 unmodified lines | ||
| 391 | 391 | CONFIG_HOTPLUG_PCI_S390=y |
| 392 | 392 | CONFIG_UEVENT_HELPER=y |
| 393 | 393 | CONFIG_DEVTMPFS=y |
| 394 | +CONFIG_DEVTMPFS_SAFE=y | |
| 394 | 395 | CONFIG_CONNECTOR=y |
| 395 | 396 | CONFIG_ZRAM=y |
| 396 | 397 | CONFIG_BLK_DEV_LOOP=m |
| @@ -492,6 +493,7 @@ CONFIG_NLMON=m · 95 unmodified lines | ||
| 492 | 493 | # CONFIG_NET_VENDOR_DEC is not set |
| 493 | 494 | # CONFIG_NET_VENDOR_DLINK is not set |
| 494 | 495 | # CONFIG_NET_VENDOR_EMULEX is not set |
| 496 | +# CONFIG_NET_VENDOR_ENGLEDER is not set | |
| 495 | 497 | # CONFIG_NET_VENDOR_EZCHIP is not set |
| 496 | 498 | # CONFIG_NET_VENDOR_GOOGLE is not set |
| 497 | 499 | # CONFIG_NET_VENDOR_HUAWEI is not set |
| @@ -502,7 +504,6 @@ CONFIG_NLMON=m · 4 unmodified lines | ||
| 502 | 504 | CONFIG_MLX4_EN=m |
| 503 | 505 | CONFIG_MLX5_CORE=m |
| 504 | 506 | CONFIG_MLX5_CORE_EN=y |
| 505 | −CONFIG_MLX5_ESWITCH=y | |
| 506 | 507 | # CONFIG_NET_VENDOR_MICREL is not set |
| 507 | 508 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 508 | 509 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -533,6 +534,7 @@ CONFIG_MLX5_ESWITCH=y · 24 unmodified lines | ||
| 533 | 534 | # CONFIG_NET_VENDOR_SYNOPSYS is not set |
| 534 | 535 | # CONFIG_NET_VENDOR_TEHUTI is not set |
| 535 | 536 | # CONFIG_NET_VENDOR_TI is not set |
| 537 | +# CONFIG_NET_VENDOR_VERTEXCOM is not set | |
| 536 | 538 | # CONFIG_NET_VENDOR_VIA is not set |
| 537 | 539 | # CONFIG_NET_VENDOR_WIZNET is not set |
| 538 | 540 | # CONFIG_NET_VENDOR_XILINX is not set |
| @@ -582,6 +584,7 @@ CONFIG_VIRTIO_BALLOON=m · 43 unmodified lines | ||
| 582 | 584 | CONFIG_VIRTIO_INPUT=y |
| 583 | 585 | CONFIG_VHOST_NET=m |
| 584 | 586 | CONFIG_VHOST_VSOCK=m |
| 587 | +# CONFIG_SURFACE_PLATFORMS is not set | |
| 585 | 588 | CONFIG_S390_CCW_IOMMU=y |
| 586 | 589 | CONFIG_S390_AP_IOMMU=y |
| 587 | 590 | CONFIG_EXT4_FS=y |
| @@ -743,9 +746,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 155 unmodified lines | ||
| 743 | 746 | CONFIG_CRYPTO_USER_API_RNG=m |
| 744 | 747 | CONFIG_CRYPTO_USER_API_AEAD=m |
| 745 | 748 | CONFIG_CRYPTO_STATS=y |
| 746 | −CONFIG_CRYPTO_LIB_BLAKE2S=m | |
| 747 | −CONFIG_CRYPTO_LIB_CURVE25519=m | |
| 748 | −CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | |
| 749 | 749 | CONFIG_ZCRYPT=m |
| 750 | 750 | CONFIG_PKEY=m |
| 751 | 751 | CONFIG_CRYPTO_PAES_S390=m |
| @@ -762,6 +762,8 @@ CONFIG_CRYPTO_CRC32_S390=y · 10 unmodified lines | ||
| 762 | 762 | CONFIG_CRYPTO_DEV_VIRTIO=m |
| 763 | 763 | CONFIG_CORDIC=m |
| 764 | 764 | CONFIG_PRIME_NUMBERS=m |
| 765 | +CONFIG_CRYPTO_LIB_CURVE25519=m | |
| 766 | +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m | |
| 765 | 767 | CONFIG_CRC4=m |
| 766 | 768 | CONFIG_CRC7=m |
| 767 | 769 | CONFIG_CRC8=m |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | # CONFIG_SWAP is not set |
| 2 | 2 | CONFIG_NO_HZ_IDLE=y |
| 3 | 3 | CONFIG_HIGH_RES_TIMERS=y |
| 4 | +CONFIG_BPF_SYSCALL=y | |
| 4 | 5 | # CONFIG_CPU_ISOLATION is not set |
| 5 | 6 | # CONFIG_UTS_NS is not set |
| 6 | 7 | # CONFIG_TIME_NS is not set |
| @@ -34,6 +35,7 @@ CONFIG_NET=y · 27 unmodified lines | ||
| 34 | 35 | # CONFIG_PCPU_DEV_REFCNT is not set |
| 35 | 36 | # CONFIG_ETHTOOL_NETLINK is not set |
| 36 | 37 | CONFIG_DEVTMPFS=y |
| 38 | +CONFIG_DEVTMPFS_SAFE=y | |
| 37 | 39 | CONFIG_BLK_DEV_RAM=y |
| 38 | 40 | # CONFIG_DCSSBLK is not set |
| 39 | 41 | # CONFIG_DASD is not set |
| @@ -58,6 +60,7 @@ CONFIG_ZFCP=y · 18 unmodified lines | ||
| 58 | 60 | # CONFIG_HID is not set |
| 59 | 61 | # CONFIG_VIRTIO_MENU is not set |
| 60 | 62 | # CONFIG_VHOST_MENU is not set |
| 63 | +# CONFIG_SURFACE_PLATFORMS is not set | |
| 61 | 64 | # CONFIG_IOMMU_SUPPORT is not set |
| 62 | 65 | # CONFIG_DNOTIFY is not set |
| 63 | 66 | # CONFIG_INOTIFY_USER is not set |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | static char local_guest[] = " "; |
| 22 | 22 | static char all_guests[] = "* "; |
| 23 | +static char *all_groups = all_guests; | |
| 23 | 24 | static char *guest_query; |
| 24 | 25 | |
| 25 | 26 | struct diag2fc_data { |
| @@ -62,10 +63,11 @@ static int diag2fc(int size, char* query, void *addr) · 36 unmodified lines | ||
| 62 | 63 | |
| 63 | 64 | memcpy(parm_list.userid, query, NAME_LEN); |
| 64 | 65 | ASCEBC(parm_list.userid, NAME_LEN); |
| 65 | − parm_list.addr = (unsigned long) addr ; | |
| 66 | + memcpy(parm_list.aci_grp, all_groups, NAME_LEN); | |
| 67 | + ASCEBC(parm_list.aci_grp, NAME_LEN); | |
| 68 | + parm_list.addr = (unsigned long)addr; | |
| 66 | 69 | parm_list.size = size; |
| 67 | 70 | parm_list.fmt = 0x02; |
| 68 | − memset(parm_list.aci_grp, 0x40, NAME_LEN); | |
| 69 | 71 | rc = -1; |
| 70 | 72 | |
| 71 | 73 | diag_stat_inc(DIAG_STAT_X2FC); |
| @@ -47,8 +47,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n); · 46 unmodified lines | ||
| 47 | 47 | int __put_user_bad(void) __attribute__((noreturn)); |
| 48 | 48 | int __get_user_bad(void) __attribute__((noreturn)); |
| 49 | 49 | |
| 50 | −#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES | |
| 51 | − | |
| 52 | 50 | union oac { |
| 53 | 51 | unsigned int val; |
| 54 | 52 | struct { |
| @@ -71,6 +69,8 @@ union oac { · 16 unmodified lines | ||
| 71 | 69 | }; |
| 72 | 70 | }; |
| 73 | 71 | |
| 72 | +#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES | |
| 73 | + | |
| 74 | 74 | #define __put_get_user_asm(to, from, size, oac_spec) \ |
| 75 | 75 | ({ \ |
| 76 | 76 | int __rc; \ |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #define DEBUGP(fmt , ...) |
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | −#define PLT_ENTRY_SIZE 20 | |
| 36 | +#define PLT_ENTRY_SIZE 22 | |
| 37 | 37 | |
| 38 | 38 | void *module_alloc(unsigned long size) |
| 39 | 39 | { |
| @@ -341,27 +341,26 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, · 301 unmodified lines | ||
| 341 | 341 | case R_390_PLTOFF32: /* 32 bit offset from GOT to PLT. */ |
| 342 | 342 | case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */ |
| 343 | 343 | if (info->plt_initialized == 0) { |
| 344 | − unsigned int insn[5]; | |
| 345 | − unsigned int *ip = me->core_layout.base + | |
| 346 | − me->arch.plt_offset + | |
| 347 | − info->plt_offset; | |
| 348 | − | |
| 349 | − insn[0] = 0x0d10e310; /* basr 1,0 */ | |
| 350 | − insn[1] = 0x100a0004; /* lg 1,10(1) */ | |
| 344 | + unsigned char insn[PLT_ENTRY_SIZE]; | |
| 345 | + char *plt_base; | |
| 346 | + char *ip; | |
| 347 | + | |
| 348 | + plt_base = me->core_layout.base + me->arch.plt_offset; | |
| 349 | + ip = plt_base + info->plt_offset; | |
| 350 | + *(int *)insn = 0x0d10e310; /* basr 1,0 */ | |
| 351 | + *(int *)&insn[4] = 0x100c0004; /* lg 1,12(1) */ | |
| 351 | 352 | if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) { |
| 352 | − unsigned int *ij; | |
| 353 | − ij = me->core_layout.base + | |
| 354 | − me->arch.plt_offset + | |
| 355 | − me->arch.plt_size - PLT_ENTRY_SIZE; | |
| 356 | − insn[2] = 0xa7f40000 + /* j __jump_r1 */ | |
| 357 | − (unsigned int)(u16) | |
| 358 | − (((unsigned long) ij - 8 - | |
| 359 | − (unsigned long) ip) / 2); | |
| 353 | + char *jump_r1; | |
| 354 | + | |
| 355 | + jump_r1 = plt_base + me->arch.plt_size - | |
| 356 | + PLT_ENTRY_SIZE; | |
| 357 | + /* brcl 0xf,__jump_r1 */ | |
| 358 | + *(short *)&insn[8] = 0xc0f4; | |
| 359 | + *(int *)&insn[10] = (jump_r1 - (ip + 8)) / 2; | |
| 360 | 360 | } else { |
| 361 | − insn[2] = 0x07f10000; /* br %r1 */ | |
| 361 | + *(int *)&insn[8] = 0x07f10000; /* br %r1 */ | |
| 362 | 362 | } |
| 363 | − insn[3] = (unsigned int) (val >> 32); | |
| 364 | − insn[4] = (unsigned int) val; | |
| 363 | + *(long *)&insn[14] = val; | |
| 365 | 364 | |
| 366 | 365 | write(ip, insn, sizeof(insn)); |
| 367 | 366 | info->plt_initialized = 1; |
| @@ -264,7 +264,14 @@ static int notrace s390_validate_registers(union mci mci, int umode) · 263 unmodified lines | ||
| 264 | 264 | /* Validate vector registers */ |
| 265 | 265 | union ctlreg0 cr0; |
| 266 | 266 | |
| 267 | − if (!mci.vr) { | |
| 267 | + /* | |
| 268 | + * The vector validity must only be checked if not running a | |
| 269 | + * KVM guest. For KVM guests the machine check is forwarded by | |
| 270 | + * KVM and it is the responsibility of the guest to take | |
| 271 | + * appropriate actions. The host vector or FPU values have been | |
| 272 | + * saved by KVM and will be restored by KVM. | |
| 273 | + */ | |
| 274 | + if (!mci.vr && !test_cpu_flag(CIF_MCCK_GUEST)) { | |
| 268 | 275 | /* |
| 269 | 276 | * Vector registers can't be restored. If the kernel |
| 270 | 277 | * currently uses vector registers the system is |
| @@ -307,11 +314,21 @@ static int notrace s390_validate_registers(union mci mci, int umode) · 36 unmodified lines | ||
| 307 | 314 | if (cr2.gse) { |
| 308 | 315 | if (!mci.gs) { |
| 309 | 316 | /* |
| 310 | − * Guarded storage register can't be restored and | |
| 311 | − * the current processes uses guarded storage. | |
| 312 | − * It has to be terminated. | |
| 317 | + * 2 cases: | |
| 318 | + * - machine check in kernel or userspace | |
| 319 | + * - machine check while running SIE (KVM guest) | |
| 320 | + * For kernel or userspace the userspace values of | |
| 321 | + * guarded storage control can not be recreated, the | |
| 322 | + * process must be terminated. | |
| 323 | + * For SIE the guest values of guarded storage can not | |
| 324 | + * be recreated. This is either due to a bug or due to | |
| 325 | + * GS being disabled in the guest. The guest will be | |
| 326 | + * notified by KVM code and the guests machine check | |
| 327 | + * handling must take care of this. The host values | |
| 328 | + * are saved by KVM and are not affected. | |
| 313 | 329 | */ |
| 314 | − kill_task = 1; | |
| 330 | + if (!test_cpu_flag(CIF_MCCK_GUEST)) | |
| 331 | + kill_task = 1; | |
| 315 | 332 | } else { |
| 316 | 333 | load_gs_cb((struct gs_cb *)mcesa->guarded_storage_save_area); |
| 317 | 334 | } |
| @@ -17,4 +17,7 @@ KASAN_SANITIZE_uaccess.o := n · 16 unmodified lines | ||
| 17 | 17 | obj-$(CONFIG_S390_UNWIND_SELFTEST) += test_unwind.o |
| 18 | 18 | CFLAGS_test_unwind.o += -fno-optimize-sibling-calls |
| 19 | 19 | |
| 20 | +obj-$(CONFIG_S390_MODULES_SANITY_TEST) += test_modules.o | |
| 21 | +obj-$(CONFIG_S390_MODULES_SANITY_TEST_HELPERS) += test_modules_helpers.o | |
| 22 | + | |
| 20 | 23 | lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o |
| @@ -0,0 +1,35 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | + | |
| 3 | +#include <kunit/test.h> | |
| 4 | +#include <linux/module.h> | |
| 5 | + | |
| 6 | +#include "test_modules.h" | |
| 7 | + | |
| 8 | +#define DECLARE_RETURN(i) int test_modules_return_ ## i(void) | |
| 9 | +REPEAT_10000(DECLARE_RETURN); | |
| 10 | + | |
| 11 | +/* | |
| 12 | + * Test that modules with many relocations are loaded properly. | |
| 13 | + */ | |
| 14 | +static void test_modules_many_vmlinux_relocs(struct kunit *test) | |
| 15 | +{ | |
| 16 | + int result = 0; | |
| 17 | + | |
| 18 | +#define CALL_RETURN(i) result += test_modules_return_ ## i() | |
| 19 | + REPEAT_10000(CALL_RETURN); | |
| 20 | + KUNIT_ASSERT_EQ(test, result, 49995000); | |
| 21 | +} | |
| 22 | + | |
| 23 | +static struct kunit_case modules_testcases[] = { | |
| 24 | + KUNIT_CASE(test_modules_many_vmlinux_relocs), | |
| 25 | + {} | |
| 26 | +}; | |
| 27 | + | |
| 28 | +static struct kunit_suite modules_test_suite = { | |
| 29 | + .name = "modules_test_s390", | |
| 30 | + .test_cases = modules_testcases, | |
| 31 | +}; | |
| 32 | + | |
| 33 | +kunit_test_suites(&modules_test_suite); | |
| 34 | + | |
| 35 | +MODULE_LICENSE("GPL"); | |
| @@ -0,0 +1,50 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0+ */ | |
| 2 | +#ifndef TEST_MODULES_H | |
| 3 | +#define TEST_MODULES_H | |
| 4 | + | |
| 5 | +#define __REPEAT_10000_3(f, x) \ | |
| 6 | + f(x ## 0); \ | |
| 7 | + f(x ## 1); \ | |
| 8 | + f(x ## 2); \ | |
| 9 | + f(x ## 3); \ | |
| 10 | + f(x ## 4); \ | |
| 11 | + f(x ## 5); \ | |
| 12 | + f(x ## 6); \ | |
| 13 | + f(x ## 7); \ | |
| 14 | + f(x ## 8); \ | |
| 15 | + f(x ## 9) | |
| 16 | +#define __REPEAT_10000_2(f, x) \ | |
| 17 | + __REPEAT_10000_3(f, x ## 0); \ | |
| 18 | + __REPEAT_10000_3(f, x ## 1); \ | |
| 19 | + __REPEAT_10000_3(f, x ## 2); \ | |
| 20 | + __REPEAT_10000_3(f, x ## 3); \ | |
| 21 | + __REPEAT_10000_3(f, x ## 4); \ | |
| 22 | + __REPEAT_10000_3(f, x ## 5); \ | |
| 23 | + __REPEAT_10000_3(f, x ## 6); \ | |
| 24 | + __REPEAT_10000_3(f, x ## 7); \ | |
| 25 | + __REPEAT_10000_3(f, x ## 8); \ | |
| 26 | + __REPEAT_10000_3(f, x ## 9) | |
| 27 | +#define __REPEAT_10000_1(f, x) \ | |
| 28 | + __REPEAT_10000_2(f, x ## 0); \ | |
| 29 | + __REPEAT_10000_2(f, x ## 1); \ | |
| 30 | + __REPEAT_10000_2(f, x ## 2); \ | |
| 31 | + __REPEAT_10000_2(f, x ## 3); \ | |
| 32 | + __REPEAT_10000_2(f, x ## 4); \ | |
| 33 | + __REPEAT_10000_2(f, x ## 5); \ | |
| 34 | + __REPEAT_10000_2(f, x ## 6); \ | |
| 35 | + __REPEAT_10000_2(f, x ## 7); \ | |
| 36 | + __REPEAT_10000_2(f, x ## 8); \ | |
| 37 | + __REPEAT_10000_2(f, x ## 9) | |
| 38 | +#define REPEAT_10000(f) \ | |
| 39 | + __REPEAT_10000_1(f, 0); \ | |
| 40 | + __REPEAT_10000_1(f, 1); \ | |
| 41 | + __REPEAT_10000_1(f, 2); \ | |
| 42 | + __REPEAT_10000_1(f, 3); \ | |
| 43 | + __REPEAT_10000_1(f, 4); \ | |
| 44 | + __REPEAT_10000_1(f, 5); \ | |
| 45 | + __REPEAT_10000_1(f, 6); \ | |
| 46 | + __REPEAT_10000_1(f, 7); \ | |
| 47 | + __REPEAT_10000_1(f, 8); \ | |
| 48 | + __REPEAT_10000_1(f, 9) | |
| 49 | + | |
| 50 | +#endif | |
| @@ -0,0 +1,13 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | + | |
| 3 | +#include <linux/export.h> | |
| 4 | + | |
| 5 | +#include "test_modules.h" | |
| 6 | + | |
| 7 | +#define DEFINE_RETURN(i) \ | |
| 8 | + int test_modules_return_ ## i(void) \ | |
| 9 | + { \ | |
| 10 | + return 1 ## i - 10000; \ | |
| 11 | + } \ | |
| 12 | + EXPORT_SYMBOL_GPL(test_modules_return_ ## i) | |
| 13 | +REPEAT_10000(DEFINE_RETURN); | |
| @@ -186,6 +186,7 @@ config X86 · 185 unmodified lines | ||
| 186 | 186 | select HAVE_CONTEXT_TRACKING_OFFSTACK if HAVE_CONTEXT_TRACKING |
| 187 | 187 | select HAVE_C_RECORDMCOUNT |
| 188 | 188 | select HAVE_OBJTOOL_MCOUNT if STACK_VALIDATION |
| 189 | + select HAVE_BUILDTIME_MCOUNT_SORT | |
| 189 | 190 | select HAVE_DEBUG_KMEMLEAK |
| 190 | 191 | select HAVE_DMA_CONTIGUOUS |
| 191 | 192 | select HAVE_DYNAMIC_FTRACE |
| @@ -6236,6 +6236,19 @@ __init int intel_pmu_init(void) · 6235 unmodified lines | ||
| 6236 | 6236 | pmu->num_counters = x86_pmu.num_counters; |
| 6237 | 6237 | pmu->num_counters_fixed = x86_pmu.num_counters_fixed; |
| 6238 | 6238 | } |
| 6239 | + | |
| 6240 | + /* | |
| 6241 | + * Quirk: For some Alder Lake machine, when all E-cores are disabled in | |
| 6242 | + * a BIOS, the leaf 0xA will enumerate all counters of P-cores. However, | |
| 6243 | + * the X86_FEATURE_HYBRID_CPU is still set. The above codes will | |
| 6244 | + * mistakenly add extra counters for P-cores. Correct the number of | |
| 6245 | + * counters here. | |
| 6246 | + */ | |
| 6247 | + if ((pmu->num_counters > 8) || (pmu->num_counters_fixed > 4)) { | |
| 6248 | + pmu->num_counters = x86_pmu.num_counters; | |
| 6249 | + pmu->num_counters_fixed = x86_pmu.num_counters_fixed; | |
| 6250 | + } | |
| 6251 | + | |
| 6239 | 6252 | pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters); |
| 6240 | 6253 | pmu->unconstrained = (struct event_constraint) |
| 6241 | 6254 | __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1, |
| @@ -6340,6 +6353,8 @@ __init int intel_pmu_init(void) · 98 unmodified lines | ||
| 6340 | 6353 | } |
| 6341 | 6354 | |
| 6342 | 6355 | if (x86_pmu.lbr_nr) { |
| 6356 | + intel_pmu_lbr_init(); | |
| 6357 | + | |
| 6343 | 6358 | pr_cont("%d-deep LBR, ", x86_pmu.lbr_nr); |
| 6344 | 6359 | |
| 6345 | 6360 | /* only support branch_stack snapshot for perfmon >= v2 */ |
| @@ -8,14 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #include "../perf_event.h" |
| 10 | 10 | |
| 11 | −static const enum { | |
| 12 | − LBR_EIP_FLAGS = 1, | |
| 13 | − LBR_TSX = 2, | |
| 14 | −} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = { | |
| 15 | − [LBR_FORMAT_EIP_FLAGS] = LBR_EIP_FLAGS, | |
| 16 | − [LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX, | |
| 17 | −}; | |
| 18 | − | |
| 19 | 11 | /* |
| 20 | 12 | * Intel LBR_SELECT bits |
| 21 | 13 | * Intel Vol3a, April 2011, Section 16.7 Table 16-10 |
| @@ -243,7 +235,7 @@ void intel_pmu_lbr_reset_64(void) · 221 unmodified lines | ||
| 243 | 235 | for (i = 0; i < x86_pmu.lbr_nr; i++) { |
| 244 | 236 | wrmsrl(x86_pmu.lbr_from + i, 0); |
| 245 | 237 | wrmsrl(x86_pmu.lbr_to + i, 0); |
| 246 | − if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) | |
| 238 | + if (x86_pmu.lbr_has_info) | |
| 247 | 239 | wrmsrl(x86_pmu.lbr_info + i, 0); |
| 248 | 240 | } |
| 249 | 241 | } |
| @@ -305,11 +297,10 @@ enum { · 55 unmodified lines | ||
| 305 | 297 | */ |
| 306 | 298 | static inline bool lbr_from_signext_quirk_needed(void) |
| 307 | 299 | { |
| 308 | − int lbr_format = x86_pmu.intel_cap.lbr_format; | |
| 309 | 300 | bool tsx_support = boot_cpu_has(X86_FEATURE_HLE) || |
| 310 | 301 | boot_cpu_has(X86_FEATURE_RTM); |
| 311 | 302 | |
| 312 | − return !tsx_support && (lbr_desc[lbr_format] & LBR_TSX); | |
| 303 | + return !tsx_support && x86_pmu.lbr_has_tsx; | |
| 313 | 304 | } |
| 314 | 305 | |
| 315 | 306 | static DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key); |
| @@ -427,12 +418,12 @@ rdlbr_all(struct lbr_entry *lbr, unsigned int idx, bool need_info) · 111 unmodified lines | ||
| 427 | 418 | |
| 428 | 419 | void intel_pmu_lbr_restore(void *ctx) |
| 429 | 420 | { |
| 430 | − bool need_info = x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO; | |
| 431 | 421 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 432 | 422 | struct x86_perf_task_context *task_ctx = ctx; |
| 433 | − int i; | |
| 434 | − unsigned lbr_idx, mask; | |
| 423 | + bool need_info = x86_pmu.lbr_has_info; | |
| 435 | 424 | u64 tos = task_ctx->tos; |
| 425 | + unsigned lbr_idx, mask; | |
| 426 | + int i; | |
| 436 | 427 | |
| 437 | 428 | mask = x86_pmu.lbr_nr - 1; |
| 438 | 429 | for (i = 0; i < task_ctx->valid_lbrs; i++) { |
| @@ -444,7 +435,7 @@ void intel_pmu_lbr_restore(void *ctx) · 5 unmodified lines | ||
| 444 | 435 | lbr_idx = (tos - i) & mask; |
| 445 | 436 | wrlbr_from(lbr_idx, 0); |
| 446 | 437 | wrlbr_to(lbr_idx, 0); |
| 447 | − if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) | |
| 438 | + if (need_info) | |
| 448 | 439 | wrlbr_info(lbr_idx, 0); |
| 449 | 440 | } |
| 450 | 441 | |
| @@ -519,9 +510,9 @@ static void __intel_pmu_lbr_restore(void *ctx) · 68 unmodified lines | ||
| 519 | 510 | |
| 520 | 511 | void intel_pmu_lbr_save(void *ctx) |
| 521 | 512 | { |
| 522 | − bool need_info = x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO; | |
| 523 | 513 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
| 524 | 514 | struct x86_perf_task_context *task_ctx = ctx; |
| 515 | + bool need_info = x86_pmu.lbr_has_info; | |
| 525 | 516 | unsigned lbr_idx, mask; |
| 526 | 517 | u64 tos; |
| 527 | 518 | int i; |
| @@ -816,7 +807,6 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) · 288 unmodified lines | ||
| 816 | 807 | { |
| 817 | 808 | bool need_info = false, call_stack = false; |
| 818 | 809 | unsigned long mask = x86_pmu.lbr_nr - 1; |
| 819 | − int lbr_format = x86_pmu.intel_cap.lbr_format; | |
| 820 | 810 | u64 tos = intel_pmu_lbr_tos(); |
| 821 | 811 | int i; |
| 822 | 812 | int out = 0; |
| @@ -831,9 +821,7 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) · 8 unmodified lines | ||
| 831 | 821 | for (i = 0; i < num; i++) { |
| 832 | 822 | unsigned long lbr_idx = (tos - i) & mask; |
| 833 | 823 | u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0; |
| 834 | − int skip = 0; | |
| 835 | 824 | u16 cycles = 0; |
| 836 | − int lbr_flags = lbr_desc[lbr_format]; | |
| 837 | 825 | |
| 838 | 826 | from = rdlbr_from(lbr_idx, NULL); |
| 839 | 827 | to = rdlbr_to(lbr_idx, NULL); |
| @@ -845,37 +833,39 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) · 5 unmodified lines | ||
| 845 | 833 | if (call_stack && !from) |
| 846 | 834 | break; |
| 847 | 835 | |
| 848 | − if (lbr_format == LBR_FORMAT_INFO && need_info) { | |
| 849 | − u64 info; | |
| 850 | − | |
| 851 | − info = rdlbr_info(lbr_idx, NULL); | |
| 852 | − mis = !!(info & LBR_INFO_MISPRED); | |
| 853 | − pred = !mis; | |
| 854 | − in_tx = !!(info & LBR_INFO_IN_TX); | |
| 855 | − abort = !!(info & LBR_INFO_ABORT); | |
| 856 | − cycles = (info & LBR_INFO_CYCLES); | |
| 857 | − } | |
| 858 | − | |
| 859 | − if (lbr_format == LBR_FORMAT_TIME) { | |
| 860 | − mis = !!(from & LBR_FROM_FLAG_MISPRED); | |
| 861 | − pred = !mis; | |
| 862 | − skip = 1; | |
| 863 | − cycles = ((to >> 48) & LBR_INFO_CYCLES); | |
| 864 | − | |
| 865 | − to = (u64)((((s64)to) << 16) >> 16); | |
| 866 | − } | |
| 867 | − | |
| 868 | − if (lbr_flags & LBR_EIP_FLAGS) { | |
| 869 | − mis = !!(from & LBR_FROM_FLAG_MISPRED); | |
| 870 | − pred = !mis; | |
| 871 | − skip = 1; | |
| 872 | − } | |
| 873 | − if (lbr_flags & LBR_TSX) { | |
| 874 | − in_tx = !!(from & LBR_FROM_FLAG_IN_TX); | |
| 875 | − abort = !!(from & LBR_FROM_FLAG_ABORT); | |
| 876 | − skip = 3; | |
| 836 | + if (x86_pmu.lbr_has_info) { | |
| 837 | + if (need_info) { | |
| 838 | + u64 info; | |
| 839 | + | |
| 840 | + info = rdlbr_info(lbr_idx, NULL); | |
| 841 | + mis = !!(info & LBR_INFO_MISPRED); | |
| 842 | + pred = !mis; | |
| 843 | + cycles = (info & LBR_INFO_CYCLES); | |
| 844 | + if (x86_pmu.lbr_has_tsx) { | |
| 845 | + in_tx = !!(info & LBR_INFO_IN_TX); | |
| 846 | + abort = !!(info & LBR_INFO_ABORT); | |
| 847 | + } | |
| 848 | + } | |
| 849 | + } else { | |
| 850 | + int skip = 0; | |
| 851 | + | |
| 852 | + if (x86_pmu.lbr_from_flags) { | |
| 853 | + mis = !!(from & LBR_FROM_FLAG_MISPRED); | |
| 854 | + pred = !mis; | |
| 855 | + skip = 1; | |
| 856 | + } | |
| 857 | + if (x86_pmu.lbr_has_tsx) { | |
| 858 | + in_tx = !!(from & LBR_FROM_FLAG_IN_TX); | |
| 859 | + abort = !!(from & LBR_FROM_FLAG_ABORT); | |
| 860 | + skip = 3; | |
| 861 | + } | |
| 862 | + from = (u64)((((s64)from) << skip) >> skip); | |
| 863 | + | |
| 864 | + if (x86_pmu.lbr_to_cycles) { | |
| 865 | + cycles = ((to >> 48) & LBR_INFO_CYCLES); | |
| 866 | + to = (u64)((((s64)to) << 16) >> 16); | |
| 867 | + } | |
| 877 | 868 | } |
| 878 | − from = (u64)((((s64)from) << skip) >> skip); | |
| 879 | 869 | |
| 880 | 870 | /* |
| 881 | 871 | * Some CPUs report duplicated abort records, |
| @@ -903,37 +893,40 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) · 21 unmodified lines | ||
| 903 | 893 | cpuc->lbr_stack.hw_idx = tos; |
| 904 | 894 | } |
| 905 | 895 | |
| 896 | +static DEFINE_STATIC_KEY_FALSE(x86_lbr_mispred); | |
| 897 | +static DEFINE_STATIC_KEY_FALSE(x86_lbr_cycles); | |
| 898 | +static DEFINE_STATIC_KEY_FALSE(x86_lbr_type); | |
| 899 | + | |
| 906 | 900 | static __always_inline int get_lbr_br_type(u64 info) |
| 907 | 901 | { |
| 908 | − if (!static_cpu_has(X86_FEATURE_ARCH_LBR) || !x86_pmu.lbr_br_type) | |
| 909 | − return 0; | |
| 902 | + int type = 0; | |
| 910 | 903 | |
| 911 | − return (info & LBR_INFO_BR_TYPE) >> LBR_INFO_BR_TYPE_OFFSET; | |
| 904 | + if (static_branch_likely(&x86_lbr_type)) | |
| 905 | + type = (info & LBR_INFO_BR_TYPE) >> LBR_INFO_BR_TYPE_OFFSET; | |
| 906 | + | |
| 907 | + return type; | |
| 912 | 908 | } |
| 913 | 909 | |
| 914 | 910 | static __always_inline bool get_lbr_mispred(u64 info) |
| 915 | 911 | { |
| 916 | − if (static_cpu_has(X86_FEATURE_ARCH_LBR) && !x86_pmu.lbr_mispred) | |
| 917 | − return 0; | |
| 912 | + bool mispred = 0; | |
| 918 | 913 | |
| 919 | − return !!(info & LBR_INFO_MISPRED); | |
| 920 | −} | |
| 914 | + if (static_branch_likely(&x86_lbr_mispred)) | |
| 915 | + mispred = !!(info & LBR_INFO_MISPRED); | |
| 921 | 916 | |
| 922 | −static __always_inline bool get_lbr_predicted(u64 info) | |
| 923 | −{ | |
| 924 | − if (static_cpu_has(X86_FEATURE_ARCH_LBR) && !x86_pmu.lbr_mispred) | |
| 925 | − return 0; | |
| 926 | − | |
| 927 | − return !(info & LBR_INFO_MISPRED); | |
| 917 | + return mispred; | |
| 928 | 918 | } |
| 929 | 919 | |
| 930 | 920 | static __always_inline u16 get_lbr_cycles(u64 info) |
| 931 | 921 | { |
| 922 | + u16 cycles = info & LBR_INFO_CYCLES; | |
| 923 | + | |
| 932 | 924 | if (static_cpu_has(X86_FEATURE_ARCH_LBR) && |
| 933 | − !(x86_pmu.lbr_timed_lbr && info & LBR_INFO_CYC_CNT_VALID)) | |
| 934 | − return 0; | |
| 925 | + (!static_branch_likely(&x86_lbr_cycles) || | |
| 926 | + !(info & LBR_INFO_CYC_CNT_VALID))) | |
| 927 | + cycles = 0; | |
| 935 | 928 | |
| 936 | − return info & LBR_INFO_CYCLES; | |
| 929 | + return cycles; | |
| 937 | 930 | } |
| 938 | 931 | |
| 939 | 932 | static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc, |
| @@ -961,7 +954,7 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc, · 21 unmodified lines | ||
| 961 | 954 | e->from = from; |
| 962 | 955 | e->to = to; |
| 963 | 956 | e->mispred = get_lbr_mispred(info); |
| 964 | − e->predicted = get_lbr_predicted(info); | |
| 957 | + e->predicted = !e->mispred; | |
| 965 | 958 | e->in_tx = !!(info & LBR_INFO_IN_TX); |
| 966 | 959 | e->abort = !!(info & LBR_INFO_ABORT); |
| 967 | 960 | e->cycles = get_lbr_cycles(info); |
| @@ -1120,7 +1113,7 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event) · 152 unmodified lines | ||
| 1120 | 1113 | |
| 1121 | 1114 | if ((br_type & PERF_SAMPLE_BRANCH_NO_CYCLES) && |
| 1122 | 1115 | (br_type & PERF_SAMPLE_BRANCH_NO_FLAGS) && |
| 1123 | − (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)) | |
| 1116 | + x86_pmu.lbr_has_info) | |
| 1124 | 1117 | reg->config |= LBR_NO_INFO; |
| 1125 | 1118 | |
| 1126 | 1119 | return 0; |
| @@ -1706,6 +1699,38 @@ void intel_pmu_lbr_init_knl(void) · 579 unmodified lines | ||
| 1706 | 1699 | x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS; |
| 1707 | 1700 | } |
| 1708 | 1701 | |
| 1702 | +void intel_pmu_lbr_init(void) | |
| 1703 | +{ | |
| 1704 | + switch (x86_pmu.intel_cap.lbr_format) { | |
| 1705 | + case LBR_FORMAT_EIP_FLAGS2: | |
| 1706 | + x86_pmu.lbr_has_tsx = 1; | |
| 1707 | + fallthrough; | |
| 1708 | + case LBR_FORMAT_EIP_FLAGS: | |
| 1709 | + x86_pmu.lbr_from_flags = 1; | |
| 1710 | + break; | |
| 1711 | + | |
| 1712 | + case LBR_FORMAT_INFO: | |
| 1713 | + x86_pmu.lbr_has_tsx = 1; | |
| 1714 | + fallthrough; | |
| 1715 | + case LBR_FORMAT_INFO2: | |
| 1716 | + x86_pmu.lbr_has_info = 1; | |
| 1717 | + break; | |
| 1718 | + | |
| 1719 | + case LBR_FORMAT_TIME: | |
| 1720 | + x86_pmu.lbr_from_flags = 1; | |
| 1721 | + x86_pmu.lbr_to_cycles = 1; | |
| 1722 | + break; | |
| 1723 | + } | |
| 1724 | + | |
| 1725 | + if (x86_pmu.lbr_has_info) { | |
| 1726 | + /* | |
| 1727 | + * Only used in combination with baseline pebs. | |
| 1728 | + */ | |
| 1729 | + static_branch_enable(&x86_lbr_mispred); | |
| 1730 | + static_branch_enable(&x86_lbr_cycles); | |
| 1731 | + } | |
| 1732 | +} | |
| 1733 | + | |
| 1709 | 1734 | /* |
| 1710 | 1735 | * LBR state size is variable based on the max number of registers. |
| 1711 | 1736 | * This calculates the expected state size, which should match |
| @@ -1726,6 +1751,9 @@ static bool is_arch_lbr_xsave_available(void) · 14 unmodified lines | ||
| 1726 | 1751 | * Check the LBR state with the corresponding software structure. |
| 1727 | 1752 | * Disable LBR XSAVES support if the size doesn't match. |
| 1728 | 1753 | */ |
| 1754 | + if (xfeature_size(XFEATURE_LBR) == 0) | |
| 1755 | + return false; | |
| 1756 | + | |
| 1729 | 1757 | if (WARN_ON(xfeature_size(XFEATURE_LBR) != get_lbr_state_size())) |
| 1730 | 1758 | return false; |
| 1731 | 1759 | |
| @@ -1765,6 +1793,12 @@ void __init intel_pmu_arch_lbr_init(void) · 33 unmodified lines | ||
| 1765 | 1793 | x86_pmu.lbr_br_type = ecx.split.lbr_br_type; |
| 1766 | 1794 | x86_pmu.lbr_nr = lbr_nr; |
| 1767 | 1795 | |
| 1796 | + if (x86_pmu.lbr_mispred) | |
| 1797 | + static_branch_enable(&x86_lbr_mispred); | |
| 1798 | + if (x86_pmu.lbr_timed_lbr) | |
| 1799 | + static_branch_enable(&x86_lbr_cycles); | |
| 1800 | + if (x86_pmu.lbr_br_type) | |
| 1801 | + static_branch_enable(&x86_lbr_type); | |
| 1768 | 1802 | |
| 1769 | 1803 | arch_lbr_xsave = is_arch_lbr_xsave_available(); |
| 1770 | 1804 | if (arch_lbr_xsave) { |
| @@ -1762,7 +1762,7 @@ static const struct intel_uncore_init_fun rkl_uncore_init __initconst = { · 1761 unmodified lines | ||
| 1762 | 1762 | |
| 1763 | 1763 | static const struct intel_uncore_init_fun adl_uncore_init __initconst = { |
| 1764 | 1764 | .cpu_init = adl_uncore_cpu_init, |
| 1765 | − .mmio_init = tgl_uncore_mmio_init, | |
| 1765 | + .mmio_init = adl_uncore_mmio_init, | |
| 1766 | 1766 | }; |
| 1767 | 1767 | |
| 1768 | 1768 | static const struct intel_uncore_init_fun icx_uncore_init __initconst = { |
| @@ -584,10 +584,11 @@ void snb_uncore_cpu_init(void); · 583 unmodified lines | ||
| 584 | 584 | void nhm_uncore_cpu_init(void); |
| 585 | 585 | void skl_uncore_cpu_init(void); |
| 586 | 586 | void icl_uncore_cpu_init(void); |
| 587 | −void adl_uncore_cpu_init(void); | |
| 588 | 587 | void tgl_uncore_cpu_init(void); |
| 588 | +void adl_uncore_cpu_init(void); | |
| 589 | 589 | void tgl_uncore_mmio_init(void); |
| 590 | 590 | void tgl_l_uncore_mmio_init(void); |
| 591 | +void adl_uncore_mmio_init(void); | |
| 591 | 592 | int snb_pci2phy_map_init(int devid); |
| 592 | 593 | |
| 593 | 594 | /* uncore_snbep.c */ |
| @@ -494,8 +494,8 @@ void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box) · 493 unmodified lines | ||
| 494 | 494 | writel(0, box->io_addr); |
| 495 | 495 | } |
| 496 | 496 | |
| 497 | −static void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box, | |
| 498 | − struct perf_event *event) | |
| 497 | +void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box, | |
| 498 | + struct perf_event *event) | |
| 499 | 499 | { |
| 500 | 500 | struct hw_perf_event *hwc = &event->hw; |
| 501 | 501 | |
| @@ -139,6 +139,8 @@ void intel_generic_uncore_mmio_disable_box(struct intel_uncore_box *box); · 138 unmodified lines | ||
| 139 | 139 | void intel_generic_uncore_mmio_enable_box(struct intel_uncore_box *box); |
| 140 | 140 | void intel_generic_uncore_mmio_disable_event(struct intel_uncore_box *box, |
| 141 | 141 | struct perf_event *event); |
| 142 | +void intel_generic_uncore_mmio_enable_event(struct intel_uncore_box *box, | |
| 143 | + struct perf_event *event); | |
| 142 | 144 | |
| 143 | 145 | void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box); |
| 144 | 146 | void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box); |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* Nehalem/SandBridge/Haswell/Broadwell/Skylake uncore support */ |
| 3 | 3 | #include "uncore.h" |
| 4 | +#include "uncore_discovery.h" | |
| 4 | 5 | |
| 5 | 6 | /* Uncore IMC PCI IDs */ |
| 6 | 7 | #define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100 |
| @@ -64,6 +65,20 @@ · 57 unmodified lines | ||
| 64 | 65 | #define PCI_DEVICE_ID_INTEL_RKL_2_IMC 0x4c53 |
| 65 | 66 | #define PCI_DEVICE_ID_INTEL_ADL_1_IMC 0x4660 |
| 66 | 67 | #define PCI_DEVICE_ID_INTEL_ADL_2_IMC 0x4641 |
| 68 | +#define PCI_DEVICE_ID_INTEL_ADL_3_IMC 0x4601 | |
| 69 | +#define PCI_DEVICE_ID_INTEL_ADL_4_IMC 0x4602 | |
| 70 | +#define PCI_DEVICE_ID_INTEL_ADL_5_IMC 0x4609 | |
| 71 | +#define PCI_DEVICE_ID_INTEL_ADL_6_IMC 0x460a | |
| 72 | +#define PCI_DEVICE_ID_INTEL_ADL_7_IMC 0x4621 | |
| 73 | +#define PCI_DEVICE_ID_INTEL_ADL_8_IMC 0x4623 | |
| 74 | +#define PCI_DEVICE_ID_INTEL_ADL_9_IMC 0x4629 | |
| 75 | +#define PCI_DEVICE_ID_INTEL_ADL_10_IMC 0x4637 | |
| 76 | +#define PCI_DEVICE_ID_INTEL_ADL_11_IMC 0x463b | |
| 77 | +#define PCI_DEVICE_ID_INTEL_ADL_12_IMC 0x4648 | |
| 78 | +#define PCI_DEVICE_ID_INTEL_ADL_13_IMC 0x4649 | |
| 79 | +#define PCI_DEVICE_ID_INTEL_ADL_14_IMC 0x4650 | |
| 80 | +#define PCI_DEVICE_ID_INTEL_ADL_15_IMC 0x4668 | |
| 81 | +#define PCI_DEVICE_ID_INTEL_ADL_16_IMC 0x4670 | |
| 67 | 82 | |
| 68 | 83 | /* SNB event control */ |
| 69 | 84 | #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff |
| @@ -155,6 +170,7 @@ · 85 unmodified lines | ||
| 155 | 170 | |
| 156 | 171 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); |
| 157 | 172 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); |
| 173 | +DEFINE_UNCORE_FORMAT_ATTR(chmask, chmask, "config:8-11"); | |
| 158 | 174 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); |
| 159 | 175 | DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); |
| 160 | 176 | DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); |
| @@ -1334,6 +1350,62 @@ static const struct pci_device_id tgl_uncore_pci_ids[] = { · 1173 unmodified lines | ||
| 1334 | 1350 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_2_IMC), |
| 1335 | 1351 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), |
| 1336 | 1352 | }, |
| 1353 | + { /* IMC */ | |
| 1354 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_3_IMC), | |
| 1355 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1356 | + }, | |
| 1357 | + { /* IMC */ | |
| 1358 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_4_IMC), | |
| 1359 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1360 | + }, | |
| 1361 | + { /* IMC */ | |
| 1362 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_5_IMC), | |
| 1363 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1364 | + }, | |
| 1365 | + { /* IMC */ | |
| 1366 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_6_IMC), | |
| 1367 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1368 | + }, | |
| 1369 | + { /* IMC */ | |
| 1370 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_7_IMC), | |
| 1371 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1372 | + }, | |
| 1373 | + { /* IMC */ | |
| 1374 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_8_IMC), | |
| 1375 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1376 | + }, | |
| 1377 | + { /* IMC */ | |
| 1378 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_9_IMC), | |
| 1379 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1380 | + }, | |
| 1381 | + { /* IMC */ | |
| 1382 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_10_IMC), | |
| 1383 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1384 | + }, | |
| 1385 | + { /* IMC */ | |
| 1386 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_11_IMC), | |
| 1387 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1388 | + }, | |
| 1389 | + { /* IMC */ | |
| 1390 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_12_IMC), | |
| 1391 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1392 | + }, | |
| 1393 | + { /* IMC */ | |
| 1394 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_13_IMC), | |
| 1395 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1396 | + }, | |
| 1397 | + { /* IMC */ | |
| 1398 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_14_IMC), | |
| 1399 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1400 | + }, | |
| 1401 | + { /* IMC */ | |
| 1402 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_15_IMC), | |
| 1403 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1404 | + }, | |
| 1405 | + { /* IMC */ | |
| 1406 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_16_IMC), | |
| 1407 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 1408 | + }, | |
| 1337 | 1409 | { /* end: all zeroes */ } |
| 1338 | 1410 | }; |
| 1339 | 1411 | |
| @@ -1390,7 +1462,8 @@ static struct pci_dev *tgl_uncore_get_mc_dev(void) · 50 unmodified lines | ||
| 1390 | 1462 | #define TGL_UNCORE_MMIO_IMC_MEM_OFFSET 0x10000 |
| 1391 | 1463 | #define TGL_UNCORE_PCI_IMC_MAP_SIZE 0xe000 |
| 1392 | 1464 | |
| 1393 | −static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) | |
| 1465 | +static void __uncore_imc_init_box(struct intel_uncore_box *box, | |
| 1466 | + unsigned int base_offset) | |
| 1394 | 1467 | { |
| 1395 | 1468 | struct pci_dev *pdev = tgl_uncore_get_mc_dev(); |
| 1396 | 1469 | struct intel_uncore_pmu *pmu = box->pmu; |
| @@ -1417,11 +1490,17 @@ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) · 20 unmodified lines | ||
| 1417 | 1490 | addr |= ((resource_size_t)mch_bar << 32); |
| 1418 | 1491 | #endif |
| 1419 | 1492 | |
| 1493 | + addr += base_offset; | |
| 1420 | 1494 | box->io_addr = ioremap(addr, type->mmio_map_size); |
| 1421 | 1495 | if (!box->io_addr) |
| 1422 | 1496 | pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name); |
| 1423 | 1497 | } |
| 1424 | 1498 | |
| 1499 | +static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) | |
| 1500 | +{ | |
| 1501 | + __uncore_imc_init_box(box, 0); | |
| 1502 | +} | |
| 1503 | + | |
| 1425 | 1504 | static struct intel_uncore_ops tgl_uncore_imc_freerunning_ops = { |
| 1426 | 1505 | .init_box = tgl_uncore_imc_freerunning_init_box, |
| 1427 | 1506 | .exit_box = uncore_mmio_exit_box, |
| @@ -1469,3 +1548,136 @@ void tgl_uncore_mmio_init(void) · 41 unmodified lines | ||
| 1469 | 1548 | } |
| 1470 | 1549 | |
| 1471 | 1550 | /* end of Tiger Lake MMIO uncore support */ |
| 1551 | + | |
| 1552 | +/* Alder Lake MMIO uncore support */ | |
| 1553 | +#define ADL_UNCORE_IMC_BASE 0xd900 | |
| 1554 | +#define ADL_UNCORE_IMC_MAP_SIZE 0x200 | |
| 1555 | +#define ADL_UNCORE_IMC_CTR 0xe8 | |
| 1556 | +#define ADL_UNCORE_IMC_CTRL 0xd0 | |
| 1557 | +#define ADL_UNCORE_IMC_GLOBAL_CTL 0xc0 | |
| 1558 | +#define ADL_UNCORE_IMC_BOX_CTL 0xc4 | |
| 1559 | +#define ADL_UNCORE_IMC_FREERUNNING_BASE 0xd800 | |
| 1560 | +#define ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE 0x100 | |
| 1561 | + | |
| 1562 | +#define ADL_UNCORE_IMC_CTL_FRZ (1 << 0) | |
| 1563 | +#define ADL_UNCORE_IMC_CTL_RST_CTRL (1 << 1) | |
| 1564 | +#define ADL_UNCORE_IMC_CTL_RST_CTRS (1 << 2) | |
| 1565 | +#define ADL_UNCORE_IMC_CTL_INT (ADL_UNCORE_IMC_CTL_RST_CTRL | \ | |
| 1566 | + ADL_UNCORE_IMC_CTL_RST_CTRS) | |
| 1567 | + | |
| 1568 | +static void adl_uncore_imc_init_box(struct intel_uncore_box *box) | |
| 1569 | +{ | |
| 1570 | + __uncore_imc_init_box(box, ADL_UNCORE_IMC_BASE); | |
| 1571 | + | |
| 1572 | + /* The global control in MC1 can control both MCs. */ | |
| 1573 | + if (box->io_addr && (box->pmu->pmu_idx == 1)) | |
| 1574 | + writel(ADL_UNCORE_IMC_CTL_INT, box->io_addr + ADL_UNCORE_IMC_GLOBAL_CTL); | |
| 1575 | +} | |
| 1576 | + | |
| 1577 | +static void adl_uncore_mmio_disable_box(struct intel_uncore_box *box) | |
| 1578 | +{ | |
| 1579 | + if (!box->io_addr) | |
| 1580 | + return; | |
| 1581 | + | |
| 1582 | + writel(ADL_UNCORE_IMC_CTL_FRZ, box->io_addr + uncore_mmio_box_ctl(box)); | |
| 1583 | +} | |
| 1584 | + | |
| 1585 | +static void adl_uncore_mmio_enable_box(struct intel_uncore_box *box) | |
| 1586 | +{ | |
| 1587 | + if (!box->io_addr) | |
| 1588 | + return; | |
| 1589 | + | |
| 1590 | + writel(0, box->io_addr + uncore_mmio_box_ctl(box)); | |
| 1591 | +} | |
| 1592 | + | |
| 1593 | +static struct intel_uncore_ops adl_uncore_mmio_ops = { | |
| 1594 | + .init_box = adl_uncore_imc_init_box, | |
| 1595 | + .exit_box = uncore_mmio_exit_box, | |
| 1596 | + .disable_box = adl_uncore_mmio_disable_box, | |
| 1597 | + .enable_box = adl_uncore_mmio_enable_box, | |
| 1598 | + .disable_event = intel_generic_uncore_mmio_disable_event, | |
| 1599 | + .enable_event = intel_generic_uncore_mmio_enable_event, | |
| 1600 | + .read_counter = uncore_mmio_read_counter, | |
| 1601 | +}; | |
| 1602 | + | |
| 1603 | +#define ADL_UNC_CTL_CHMASK_MASK 0x00000f00 | |
| 1604 | +#define ADL_UNC_IMC_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ | |
| 1605 | + ADL_UNC_CTL_CHMASK_MASK | \ | |
| 1606 | + SNB_UNC_CTL_EDGE_DET) | |
| 1607 | + | |
| 1608 | +static struct attribute *adl_uncore_imc_formats_attr[] = { | |
| 1609 | + &format_attr_event.attr, | |
| 1610 | + &format_attr_chmask.attr, | |
| 1611 | + &format_attr_edge.attr, | |
| 1612 | + NULL, | |
| 1613 | +}; | |
| 1614 | + | |
| 1615 | +static const struct attribute_group adl_uncore_imc_format_group = { | |
| 1616 | + .name = "format", | |
| 1617 | + .attrs = adl_uncore_imc_formats_attr, | |
| 1618 | +}; | |
| 1619 | + | |
| 1620 | +static struct intel_uncore_type adl_uncore_imc = { | |
| 1621 | + .name = "imc", | |
| 1622 | + .num_counters = 5, | |
| 1623 | + .num_boxes = 2, | |
| 1624 | + .perf_ctr_bits = 64, | |
| 1625 | + .perf_ctr = ADL_UNCORE_IMC_CTR, | |
| 1626 | + .event_ctl = ADL_UNCORE_IMC_CTRL, | |
| 1627 | + .event_mask = ADL_UNC_IMC_EVENT_MASK, | |
| 1628 | + .box_ctl = ADL_UNCORE_IMC_BOX_CTL, | |
| 1629 | + .mmio_offset = 0, | |
| 1630 | + .mmio_map_size = ADL_UNCORE_IMC_MAP_SIZE, | |
| 1631 | + .ops = &adl_uncore_mmio_ops, | |
| 1632 | + .format_group = &adl_uncore_imc_format_group, | |
| 1633 | +}; | |
| 1634 | + | |
| 1635 | +enum perf_adl_uncore_imc_freerunning_types { | |
| 1636 | + ADL_MMIO_UNCORE_IMC_DATA_TOTAL, | |
| 1637 | + ADL_MMIO_UNCORE_IMC_DATA_READ, | |
| 1638 | + ADL_MMIO_UNCORE_IMC_DATA_WRITE, | |
| 1639 | + ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX | |
| 1640 | +}; | |
| 1641 | + | |
| 1642 | +static struct freerunning_counters adl_uncore_imc_freerunning[] = { | |
| 1643 | + [ADL_MMIO_UNCORE_IMC_DATA_TOTAL] = { 0x40, 0x0, 0x0, 1, 64 }, | |
| 1644 | + [ADL_MMIO_UNCORE_IMC_DATA_READ] = { 0x58, 0x0, 0x0, 1, 64 }, | |
| 1645 | + [ADL_MMIO_UNCORE_IMC_DATA_WRITE] = { 0xA0, 0x0, 0x0, 1, 64 }, | |
| 1646 | +}; | |
| 1647 | + | |
| 1648 | +static void adl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box) | |
| 1649 | +{ | |
| 1650 | + __uncore_imc_init_box(box, ADL_UNCORE_IMC_FREERUNNING_BASE); | |
| 1651 | +} | |
| 1652 | + | |
| 1653 | +static struct intel_uncore_ops adl_uncore_imc_freerunning_ops = { | |
| 1654 | + .init_box = adl_uncore_imc_freerunning_init_box, | |
| 1655 | + .exit_box = uncore_mmio_exit_box, | |
| 1656 | + .read_counter = uncore_mmio_read_counter, | |
| 1657 | + .hw_config = uncore_freerunning_hw_config, | |
| 1658 | +}; | |
| 1659 | + | |
| 1660 | +static struct intel_uncore_type adl_uncore_imc_free_running = { | |
| 1661 | + .name = "imc_free_running", | |
| 1662 | + .num_counters = 3, | |
| 1663 | + .num_boxes = 2, | |
| 1664 | + .num_freerunning_types = ADL_MMIO_UNCORE_IMC_FREERUNNING_TYPE_MAX, | |
| 1665 | + .mmio_map_size = ADL_UNCORE_IMC_FREERUNNING_MAP_SIZE, | |
| 1666 | + .freerunning = adl_uncore_imc_freerunning, | |
| 1667 | + .ops = &adl_uncore_imc_freerunning_ops, | |
| 1668 | + .event_descs = tgl_uncore_imc_events, | |
| 1669 | + .format_group = &tgl_uncore_imc_format_group, | |
| 1670 | +}; | |
| 1671 | + | |
| 1672 | +static struct intel_uncore_type *adl_mmio_uncores[] = { | |
| 1673 | + &adl_uncore_imc, | |
| 1674 | + &adl_uncore_imc_free_running, | |
| 1675 | + NULL | |
| 1676 | +}; | |
| 1677 | + | |
| 1678 | +void adl_uncore_mmio_init(void) | |
| 1679 | +{ | |
| 1680 | + uncore_mmio_uncores = adl_mmio_uncores; | |
| 1681 | +} | |
| 1682 | + | |
| 1683 | +/* end of Alder Lake MMIO uncore support */ | |
| @@ -5482,7 +5482,7 @@ static struct intel_uncore_type icx_uncore_imc = { · 5481 unmodified lines | ||
| 5482 | 5482 | .fixed_ctr_bits = 48, |
| 5483 | 5483 | .fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR, |
| 5484 | 5484 | .fixed_ctl = SNR_IMC_MMIO_PMON_FIXED_CTL, |
| 5485 | − .event_descs = hswep_uncore_imc_events, | |
| 5485 | + .event_descs = snr_uncore_imc_events, | |
| 5486 | 5486 | .perf_ctr = SNR_IMC_MMIO_PMON_CTR0, |
| 5487 | 5487 | .event_ctl = SNR_IMC_MMIO_PMON_CTL0, |
| 5488 | 5488 | .event_mask = SNBEP_PMON_RAW_EVENT_MASK, |
| @@ -215,7 +215,8 @@ enum { · 214 unmodified lines | ||
| 215 | 215 | LBR_FORMAT_EIP_FLAGS2 = 0x04, |
| 216 | 216 | LBR_FORMAT_INFO = 0x05, |
| 217 | 217 | LBR_FORMAT_TIME = 0x06, |
| 218 | − LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_TIME, | |
| 218 | + LBR_FORMAT_INFO2 = 0x07, | |
| 219 | + LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_INFO2, | |
| 219 | 220 | }; |
| 220 | 221 | |
| 221 | 222 | enum { |
| @@ -840,6 +841,11 @@ struct x86_pmu { · 618 unmodified lines | ||
| 840 | 841 | bool lbr_double_abort; /* duplicated lbr aborts */ |
| 841 | 842 | bool lbr_pt_coexist; /* (LBR|BTS) may coexist with PT */ |
| 842 | 843 | |
| 844 | + unsigned int lbr_has_info:1; | |
| 845 | + unsigned int lbr_has_tsx:1; | |
| 846 | + unsigned int lbr_from_flags:1; | |
| 847 | + unsigned int lbr_to_cycles:1; | |
| 848 | + | |
| 843 | 849 | /* |
| 844 | 850 | * Intel Architectural LBR CPUID Enumeration |
| 845 | 851 | */ |
| @@ -1392,6 +1398,8 @@ void intel_pmu_lbr_init_skl(void); · 546 unmodified lines | ||
| 1392 | 1398 | |
| 1393 | 1399 | void intel_pmu_lbr_init_knl(void); |
| 1394 | 1400 | |
| 1401 | +void intel_pmu_lbr_init(void); | |
| 1402 | + | |
| 1395 | 1403 | void intel_pmu_arch_lbr_init(void); |
| 1396 | 1404 | |
| 1397 | 1405 | void intel_pmu_pebs_data_source_nhm(void); |
| @@ -536,11 +536,14 @@ static struct perf_msr intel_rapl_spr_msrs[] = { · 535 unmodified lines | ||
| 536 | 536 | * - perf_msr_probe(PERF_RAPL_MAX) |
| 537 | 537 | * - want to use same event codes across both architectures |
| 538 | 538 | */ |
| 539 | −static struct perf_msr amd_rapl_msrs[PERF_RAPL_MAX] = { | |
| 540 | − [PERF_RAPL_PKG] = { MSR_AMD_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr }, | |
| 539 | +static struct perf_msr amd_rapl_msrs[] = { | |
| 540 | + [PERF_RAPL_PP0] = { 0, &rapl_events_cores_group, 0, false, 0 }, | |
| 541 | + [PERF_RAPL_PKG] = { MSR_AMD_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr, false, RAPL_MSR_MASK }, | |
| 542 | + [PERF_RAPL_RAM] = { 0, &rapl_events_ram_group, 0, false, 0 }, | |
| 543 | + [PERF_RAPL_PP1] = { 0, &rapl_events_gpu_group, 0, false, 0 }, | |
| 544 | + [PERF_RAPL_PSYS] = { 0, &rapl_events_psys_group, 0, false, 0 }, | |
| 541 | 545 | }; |
| 542 | 546 | |
| 543 | − | |
| 544 | 547 | static int rapl_cpu_offline(unsigned int cpu) |
| 545 | 548 | { |
| 546 | 549 | struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu); |
| @@ -1483,7 +1483,8 @@ struct kvm_x86_ops { · 1482 unmodified lines | ||
| 1483 | 1483 | |
| 1484 | 1484 | int (*get_msr_feature)(struct kvm_msr_entry *entry); |
| 1485 | 1485 | |
| 1486 | − bool (*can_emulate_instruction)(struct kvm_vcpu *vcpu, void *insn, int insn_len); | |
| 1486 | + bool (*can_emulate_instruction)(struct kvm_vcpu *vcpu, int emul_type, | |
| 1487 | + void *insn, int insn_len); | |
| 1487 | 1488 | |
| 1488 | 1489 | bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu); |
| 1489 | 1490 | int (*enable_direct_tlbflush)(struct kvm_vcpu *vcpu); |
| @@ -1496,6 +1497,7 @@ struct kvm_x86_ops { · 6 unmodified lines | ||
| 1496 | 1497 | }; |
| 1497 | 1498 | |
| 1498 | 1499 | struct kvm_x86_nested_ops { |
| 1500 | + void (*leave_nested)(struct kvm_vcpu *vcpu); | |
| 1499 | 1501 | int (*check_events)(struct kvm_vcpu *vcpu); |
| 1500 | 1502 | bool (*hv_timer_pending)(struct kvm_vcpu *vcpu); |
| 1501 | 1503 | void (*triple_fault)(struct kvm_vcpu *vcpu); |
| @@ -1861,7 +1863,6 @@ int kvm_cpu_has_extint(struct kvm_vcpu *v); · 359 unmodified lines | ||
| 1861 | 1863 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); |
| 1862 | 1864 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); |
| 1863 | 1865 | void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); |
| 1864 | −void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu); | |
| 1865 | 1866 | |
| 1866 | 1867 | int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, |
| 1867 | 1868 | unsigned long ipi_bitmap_high, u32 min, |
| @@ -452,6 +452,9 @@ struct kvm_sync_regs { · 451 unmodified lines | ||
| 452 | 452 | |
| 453 | 453 | #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001 |
| 454 | 454 | |
| 455 | +/* attributes for system fd (group 0) */ | |
| 456 | +#define KVM_X86_XCOMP_GUEST_SUPP 0 | |
| 457 | + | |
| 455 | 458 | struct kvm_vmx_nested_state_data { |
| 456 | 459 | __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; |
| 457 | 460 | __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; |
| @@ -423,7 +423,7 @@ static void threshold_restart_bank(void *_tr) · 422 unmodified lines | ||
| 423 | 423 | u32 hi, lo; |
| 424 | 424 | |
| 425 | 425 | /* sysfs write might race against an offline operation */ |
| 426 | − if (this_cpu_read(threshold_banks)) | |
| 426 | + if (!this_cpu_read(threshold_banks) && !tr->set_lvt_off) | |
| 427 | 427 | return; |
| 428 | 428 | |
| 429 | 429 | rdmsr(tr->b->address, lo, hi); |
| @@ -486,6 +486,7 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) · 485 unmodified lines | ||
| 486 | 486 | case INTEL_FAM6_BROADWELL_X: |
| 487 | 487 | case INTEL_FAM6_SKYLAKE_X: |
| 488 | 488 | case INTEL_FAM6_ICELAKE_X: |
| 489 | + case INTEL_FAM6_ICELAKE_D: | |
| 489 | 490 | case INTEL_FAM6_SAPPHIRERAPIDS_X: |
| 490 | 491 | case INTEL_FAM6_XEON_PHI_KNL: |
| 491 | 492 | case INTEL_FAM6_XEON_PHI_KNM: |
| @@ -133,6 +133,7 @@ static int kvm_cpuid_check_equal(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 · 132 unmodified lines | ||
| 133 | 133 | orig = &vcpu->arch.cpuid_entries[i]; |
| 134 | 134 | if (e2[i].function != orig->function || |
| 135 | 135 | e2[i].index != orig->index || |
| 136 | + e2[i].flags != orig->flags || | |
| 136 | 137 | e2[i].eax != orig->eax || e2[i].ebx != orig->ebx || |
| 137 | 138 | e2[i].ecx != orig->ecx || e2[i].edx != orig->edx) |
| 138 | 139 | return -EINVAL; |
| @@ -196,10 +197,26 @@ void kvm_update_pv_runtime(struct kvm_vcpu *vcpu) · 57 unmodified lines | ||
| 196 | 197 | vcpu->arch.pv_cpuid.features = best->eax; |
| 197 | 198 | } |
| 198 | 199 | |
| 200 | +/* | |
| 201 | + * Calculate guest's supported XCR0 taking into account guest CPUID data and | |
| 202 | + * supported_xcr0 (comprised of host configuration and KVM_SUPPORTED_XCR0). | |
| 203 | + */ | |
| 204 | +static u64 cpuid_get_supported_xcr0(struct kvm_cpuid_entry2 *entries, int nent) | |
| 205 | +{ | |
| 206 | + struct kvm_cpuid_entry2 *best; | |
| 207 | + | |
| 208 | + best = cpuid_entry2_find(entries, nent, 0xd, 0); | |
| 209 | + if (!best) | |
| 210 | + return 0; | |
| 211 | + | |
| 212 | + return (best->eax | ((u64)best->edx << 32)) & supported_xcr0; | |
| 213 | +} | |
| 214 | + | |
| 199 | 215 | static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *entries, |
| 200 | 216 | int nent) |
| 201 | 217 | { |
| 202 | 218 | struct kvm_cpuid_entry2 *best; |
| 219 | + u64 guest_supported_xcr0 = cpuid_get_supported_xcr0(entries, nent); | |
| 203 | 220 | |
| 204 | 221 | best = cpuid_entry2_find(entries, nent, 1, 0); |
| 205 | 222 | if (best) { |
| @@ -238,6 +255,21 @@ static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e · 32 unmodified lines | ||
| 238 | 255 | vcpu->arch.ia32_misc_enable_msr & |
| 239 | 256 | MSR_IA32_MISC_ENABLE_MWAIT); |
| 240 | 257 | } |
| 258 | + | |
| 259 | + /* | |
| 260 | + * Bits 127:0 of the allowed SECS.ATTRIBUTES (CPUID.0x12.0x1) enumerate | |
| 261 | + * the supported XSAVE Feature Request Mask (XFRM), i.e. the enclave's | |
| 262 | + * requested XCR0 value. The enclave's XFRM must be a subset of XCRO | |
| 263 | + * at the time of EENTER, thus adjust the allowed XFRM by the guest's | |
| 264 | + * supported XCR0. Similar to XCR0 handling, FP and SSE are forced to | |
| 265 | + * '1' even on CPUs that don't support XSAVE. | |
| 266 | + */ | |
| 267 | + best = cpuid_entry2_find(entries, nent, 0x12, 0x1); | |
| 268 | + if (best) { | |
| 269 | + best->ecx &= guest_supported_xcr0 & 0xffffffff; | |
| 270 | + best->edx &= guest_supported_xcr0 >> 32; | |
| 271 | + best->ecx |= XFEATURE_MASK_FPSSE; | |
| 272 | + } | |
| 241 | 273 | } |
| 242 | 274 | |
| 243 | 275 | void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu) |
| @@ -261,27 +293,8 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) · 17 unmodified lines | ||
| 261 | 293 | kvm_apic_set_version(vcpu); |
| 262 | 294 | } |
| 263 | 295 | |
| 264 | − best = kvm_find_cpuid_entry(vcpu, 0xD, 0); | |
| 265 | − if (!best) | |
| 266 | − vcpu->arch.guest_supported_xcr0 = 0; | |
| 267 | − else | |
| 268 | − vcpu->arch.guest_supported_xcr0 = | |
| 269 | − (best->eax | ((u64)best->edx << 32)) & supported_xcr0; | |
| 270 | − | |
| 271 | − /* | |
| 272 | − * Bits 127:0 of the allowed SECS.ATTRIBUTES (CPUID.0x12.0x1) enumerate | |
| 273 | − * the supported XSAVE Feature Request Mask (XFRM), i.e. the enclave's | |
| 274 | − * requested XCR0 value. The enclave's XFRM must be a subset of XCRO | |
| 275 | − * at the time of EENTER, thus adjust the allowed XFRM by the guest's | |
| 276 | − * supported XCR0. Similar to XCR0 handling, FP and SSE are forced to | |
| 277 | − * '1' even on CPUs that don't support XSAVE. | |
| 278 | − */ | |
| 279 | − best = kvm_find_cpuid_entry(vcpu, 0x12, 0x1); | |
| 280 | − if (best) { | |
| 281 | − best->ecx &= vcpu->arch.guest_supported_xcr0 & 0xffffffff; | |
| 282 | − best->edx &= vcpu->arch.guest_supported_xcr0 >> 32; | |
| 283 | − best->ecx |= XFEATURE_MASK_FPSSE; | |
| 284 | − } | |
| 296 | + vcpu->arch.guest_supported_xcr0 = | |
| 297 | + cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent); | |
| 285 | 298 | |
| 286 | 299 | kvm_update_pv_runtime(vcpu); |
| 287 | 300 | |
| @@ -346,8 +359,14 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2, · 58 unmodified lines | ||
| 346 | 359 | * KVM_SET_CPUID{,2} again. To support this legacy behavior, check |
| 347 | 360 | * whether the supplied CPUID data is equal to what's already set. |
| 348 | 361 | */ |
| 349 | − if (vcpu->arch.last_vmentry_cpu != -1) | |
| 350 | − return kvm_cpuid_check_equal(vcpu, e2, nent); | |
| 362 | + if (vcpu->arch.last_vmentry_cpu != -1) { | |
| 363 | + r = kvm_cpuid_check_equal(vcpu, e2, nent); | |
| 364 | + if (r) | |
| 365 | + return r; | |
| 366 | + | |
| 367 | + kvfree(e2); | |
| 368 | + return 0; | |
| 369 | + } | |
| 351 | 370 | |
| 352 | 371 | r = kvm_check_cpuid(vcpu, e2, nent); |
| 353 | 372 | if (r) |
| @@ -887,13 +906,14 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 533 unmodified lines | ||
| 887 | 906 | } |
| 888 | 907 | break; |
| 889 | 908 | case 0xd: { |
| 890 | − u64 guest_perm = xstate_get_guest_group_perm(); | |
| 909 | + u64 permitted_xcr0 = supported_xcr0 & xstate_get_guest_group_perm(); | |
| 910 | + u64 permitted_xss = supported_xss; | |
| 891 | 911 | |
| 892 | − entry->eax &= supported_xcr0 & guest_perm; | |
| 893 | − entry->ebx = xstate_required_size(supported_xcr0, false); | |
| 912 | + entry->eax &= permitted_xcr0; | |
| 913 | + entry->ebx = xstate_required_size(permitted_xcr0, false); | |
| 894 | 914 | entry->ecx = entry->ebx; |
| 895 | − entry->edx &= (supported_xcr0 & guest_perm) >> 32; | |
| 896 | − if (!supported_xcr0) | |
| 915 | + entry->edx &= permitted_xcr0 >> 32; | |
| 916 | + if (!permitted_xcr0) | |
| 897 | 917 | break; |
| 898 | 918 | |
| 899 | 919 | entry = do_host_cpuid(array, function, 1); |
| @@ -902,20 +922,20 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 2 unmodified lines | ||
| 902 | 922 | |
| 903 | 923 | cpuid_entry_override(entry, CPUID_D_1_EAX); |
| 904 | 924 | if (entry->eax & (F(XSAVES)|F(XSAVEC))) |
| 905 | − entry->ebx = xstate_required_size(supported_xcr0 | supported_xss, | |
| 925 | + entry->ebx = xstate_required_size(permitted_xcr0 | permitted_xss, | |
| 906 | 926 | true); |
| 907 | 927 | else { |
| 908 | − WARN_ON_ONCE(supported_xss != 0); | |
| 928 | + WARN_ON_ONCE(permitted_xss != 0); | |
| 909 | 929 | entry->ebx = 0; |
| 910 | 930 | } |
| 911 | − entry->ecx &= supported_xss; | |
| 912 | − entry->edx &= supported_xss >> 32; | |
| 931 | + entry->ecx &= permitted_xss; | |
| 932 | + entry->edx &= permitted_xss >> 32; | |
| 913 | 933 | |
| 914 | 934 | for (i = 2; i < 64; ++i) { |
| 915 | 935 | bool s_state; |
| 916 | − if (supported_xcr0 & BIT_ULL(i)) | |
| 936 | + if (permitted_xcr0 & BIT_ULL(i)) | |
| 917 | 937 | s_state = false; |
| 918 | − else if (supported_xss & BIT_ULL(i)) | |
| 938 | + else if (permitted_xss & BIT_ULL(i)) | |
| 919 | 939 | s_state = true; |
| 920 | 940 | else |
| 921 | 941 | continue; |
| @@ -929,7 +949,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 7 unmodified lines | ||
| 929 | 949 | * invalid sub-leafs. Only valid sub-leafs should |
| 930 | 950 | * reach this point, and they should have a non-zero |
| 931 | 951 | * save state size. Furthermore, check whether the |
| 932 | − * processor agrees with supported_xcr0/supported_xss | |
| 952 | + * processor agrees with permitted_xcr0/permitted_xss | |
| 933 | 953 | * on whether this is an XCR0- or IA32_XSS-managed area. |
| 934 | 954 | */ |
| 935 | 955 | if (WARN_ON_ONCE(!entry->eax || (entry->ecx & 0x1) != s_state)) { |
| @@ -2629,7 +2629,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s) · 2628 unmodified lines | ||
| 2629 | 2629 | kvm_apic_set_version(vcpu); |
| 2630 | 2630 | |
| 2631 | 2631 | apic_update_ppr(apic); |
| 2632 | − hrtimer_cancel(&apic->lapic_timer.timer); | |
| 2632 | + cancel_apic_timer(apic); | |
| 2633 | 2633 | apic->lapic_timer.expired_tscdeadline = 0; |
| 2634 | 2634 | apic_update_lvtt(apic); |
| 2635 | 2635 | apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0)); |
| @@ -983,9 +983,9 @@ void svm_free_nested(struct vcpu_svm *svm) · 982 unmodified lines | ||
| 983 | 983 | /* |
| 984 | 984 | * Forcibly leave nested mode in order to be able to reset the VCPU later on. |
| 985 | 985 | */ |
| 986 | −void svm_leave_nested(struct vcpu_svm *svm) | |
| 986 | +void svm_leave_nested(struct kvm_vcpu *vcpu) | |
| 987 | 987 | { |
| 988 | − struct kvm_vcpu *vcpu = &svm->vcpu; | |
| 988 | + struct vcpu_svm *svm = to_svm(vcpu); | |
| 989 | 989 | |
| 990 | 990 | if (is_guest_mode(vcpu)) { |
| 991 | 991 | svm->nested.nested_run_pending = 0; |
| @@ -1411,7 +1411,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, · 419 unmodified lines | ||
| 1411 | 1411 | return -EINVAL; |
| 1412 | 1412 | |
| 1413 | 1413 | if (!(kvm_state->flags & KVM_STATE_NESTED_GUEST_MODE)) { |
| 1414 | − svm_leave_nested(svm); | |
| 1414 | + svm_leave_nested(vcpu); | |
| 1415 | 1415 | svm_set_gif(svm, !!(kvm_state->flags & KVM_STATE_NESTED_GIF_SET)); |
| 1416 | 1416 | return 0; |
| 1417 | 1417 | } |
| @@ -1478,7 +1478,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, · 60 unmodified lines | ||
| 1478 | 1478 | */ |
| 1479 | 1479 | |
| 1480 | 1480 | if (is_guest_mode(vcpu)) |
| 1481 | − svm_leave_nested(svm); | |
| 1481 | + svm_leave_nested(vcpu); | |
| 1482 | 1482 | else |
| 1483 | 1483 | svm->nested.vmcb02.ptr->save = svm->vmcb01.ptr->save; |
| 1484 | 1484 | |
| @@ -1532,6 +1532,7 @@ static bool svm_get_nested_state_pages(struct kvm_vcpu *vcpu) · 47 unmodified lines | ||
| 1532 | 1532 | } |
| 1533 | 1533 | |
| 1534 | 1534 | struct kvm_x86_nested_ops svm_nested_ops = { |
| 1535 | + .leave_nested = svm_leave_nested, | |
| 1535 | 1536 | .check_events = svm_check_nested_events, |
| 1536 | 1537 | .triple_fault = nested_svm_triple_fault, |
| 1537 | 1538 | .get_nested_state_pages = svm_get_nested_state_pages, |
| @@ -2100,8 +2100,13 @@ void __init sev_hardware_setup(void) · 2099 unmodified lines | ||
| 2100 | 2100 | if (!sev_enabled || !npt_enabled) |
| 2101 | 2101 | goto out; |
| 2102 | 2102 | |
| 2103 | − /* Does the CPU support SEV? */ | |
| 2104 | − if (!boot_cpu_has(X86_FEATURE_SEV)) | |
| 2103 | + /* | |
| 2104 | + * SEV must obviously be supported in hardware. Sanity check that the | |
| 2105 | + * CPU supports decode assists, which is mandatory for SEV guests to | |
| 2106 | + * support instruction emulation. | |
| 2107 | + */ | |
| 2108 | + if (!boot_cpu_has(X86_FEATURE_SEV) || | |
| 2109 | + WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_DECODEASSISTS))) | |
| 2105 | 2110 | goto out; |
| 2106 | 2111 | |
| 2107 | 2112 | /* Retrieve SEV CPUID information */ |
| @@ -290,7 +290,7 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) · 289 unmodified lines | ||
| 290 | 290 | |
| 291 | 291 | if ((old_efer & EFER_SVME) != (efer & EFER_SVME)) { |
| 292 | 292 | if (!(efer & EFER_SVME)) { |
| 293 | − svm_leave_nested(svm); | |
| 293 | + svm_leave_nested(vcpu); | |
| 294 | 294 | svm_set_gif(svm, true); |
| 295 | 295 | /* #GP intercept is still needed for vmware backdoor */ |
| 296 | 296 | if (!enable_vmware_backdoor) |
| @@ -312,7 +312,11 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) · 15 unmodified lines | ||
| 312 | 312 | return ret; |
| 313 | 313 | } |
| 314 | 314 | |
| 315 | − if (svm_gp_erratum_intercept) | |
| 315 | + /* | |
| 316 | + * Never intercept #GP for SEV guests, KVM can't | |
| 317 | + * decrypt guest memory to workaround the erratum. | |
| 318 | + */ | |
| 319 | + if (svm_gp_erratum_intercept && !sev_guest(vcpu->kvm)) | |
| 316 | 320 | set_exception_intercept(svm, GP_VECTOR); |
| 317 | 321 | } |
| 318 | 322 | } |
| @@ -1010,9 +1014,10 @@ static void init_vmcb(struct kvm_vcpu *vcpu) · 691 unmodified lines | ||
| 1010 | 1014 | * Guest access to VMware backdoor ports could legitimately |
| 1011 | 1015 | * trigger #GP because of TSS I/O permission bitmap. |
| 1012 | 1016 | * We intercept those #GP and allow access to them anyway |
| 1013 | − * as VMware does. | |
| 1017 | + * as VMware does. Don't intercept #GP for SEV guests as KVM can't | |
| 1018 | + * decrypt guest memory to decode the faulting instruction. | |
| 1014 | 1019 | */ |
| 1015 | − if (enable_vmware_backdoor) | |
| 1020 | + if (enable_vmware_backdoor && !sev_guest(vcpu->kvm)) | |
| 1016 | 1021 | set_exception_intercept(svm, GP_VECTOR); |
| 1017 | 1022 | |
| 1018 | 1023 | svm_set_intercept(svm, INTERCEPT_INTR); |
| @@ -2091,10 +2096,6 @@ static int gp_interception(struct kvm_vcpu *vcpu) · 1072 unmodified lines | ||
| 2091 | 2096 | if (error_code) |
| 2092 | 2097 | goto reinject; |
| 2093 | 2098 | |
| 2094 | − /* All SVM instructions expect page aligned RAX */ | |
| 2095 | − if (svm->vmcb->save.rax & ~PAGE_MASK) | |
| 2096 | − goto reinject; | |
| 2097 | − | |
| 2098 | 2099 | /* Decode the instruction for usage later */ |
| 2099 | 2100 | if (x86_decode_emulated_instruction(vcpu, 0, NULL, 0) != EMULATION_OK) |
| 2100 | 2101 | goto reinject; |
| @@ -2112,8 +2113,13 @@ static int gp_interception(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 2112 | 2113 | if (!is_guest_mode(vcpu)) |
| 2113 | 2114 | return kvm_emulate_instruction(vcpu, |
| 2114 | 2115 | EMULTYPE_VMWARE_GP | EMULTYPE_NO_DECODE); |
| 2115 | − } else | |
| 2116 | + } else { | |
| 2117 | + /* All SVM instructions expect page aligned RAX */ | |
| 2118 | + if (svm->vmcb->save.rax & ~PAGE_MASK) | |
| 2119 | + goto reinject; | |
| 2120 | + | |
| 2116 | 2121 | return emulate_svm_instr(vcpu, opcode); |
| 2122 | + } | |
| 2117 | 2123 | |
| 2118 | 2124 | reinject: |
| 2119 | 2125 | kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); |
| @@ -4252,79 +4258,140 @@ static void svm_enable_smi_window(struct kvm_vcpu *vcpu) · 2132 unmodified lines | ||
| 4252 | 4258 | } |
| 4253 | 4259 | } |
| 4254 | 4260 | |
| 4255 | −static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int insn_len) | |
| 4261 | +static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, | |
| 4262 | + void *insn, int insn_len) | |
| 4256 | 4263 | { |
| 4257 | 4264 | bool smep, smap, is_user; |
| 4258 | 4265 | unsigned long cr4; |
| 4266 | + u64 error_code; | |
| 4267 | + | |
| 4268 | + /* Emulation is always possible when KVM has access to all guest state. */ | |
| 4269 | + if (!sev_guest(vcpu->kvm)) | |
| 4270 | + return true; | |
| 4271 | + | |
| 4272 | + /* #UD and #GP should never be intercepted for SEV guests. */ | |
| 4273 | + WARN_ON_ONCE(emul_type & (EMULTYPE_TRAP_UD | | |
| 4274 | + EMULTYPE_TRAP_UD_FORCED | | |
| 4275 | + EMULTYPE_VMWARE_GP)); | |
| 4259 | 4276 | |
| 4260 | 4277 | /* |
| 4261 | − * When the guest is an SEV-ES guest, emulation is not possible. | |
| 4278 | + * Emulation is impossible for SEV-ES guests as KVM doesn't have access | |
| 4279 | + * to guest register state. | |
| 4262 | 4280 | */ |
| 4263 | 4281 | if (sev_es_guest(vcpu->kvm)) |
| 4264 | 4282 | return false; |
| 4265 | 4283 | |
| 4284 | + /* | |
| 4285 | + * Emulation is possible if the instruction is already decoded, e.g. | |
| 4286 | + * when completing I/O after returning from userspace. | |
| 4287 | + */ | |
| 4288 | + if (emul_type & EMULTYPE_NO_DECODE) | |
| 4289 | + return true; | |
| 4290 | + | |
| 4291 | + /* | |
| 4292 | + * Emulation is possible for SEV guests if and only if a prefilled | |
| 4293 | + * buffer containing the bytes of the intercepted instruction is | |
| 4294 | + * available. SEV guest memory is encrypted with a guest specific key | |
| 4295 | + * and cannot be decrypted by KVM, i.e. KVM would read cyphertext and | |
| 4296 | + * decode garbage. | |
| 4297 | + * | |
| 4298 | + * Inject #UD if KVM reached this point without an instruction buffer. | |
| 4299 | + * In practice, this path should never be hit by a well-behaved guest, | |
| 4300 | + * e.g. KVM doesn't intercept #UD or #GP for SEV guests, but this path | |
| 4301 | + * is still theoretically reachable, e.g. via unaccelerated fault-like | |
| 4302 | + * AVIC access, and needs to be handled by KVM to avoid putting the | |
| 4303 | + * guest into an infinite loop. Injecting #UD is somewhat arbitrary, | |
| 4304 | + * but its the least awful option given lack of insight into the guest. | |
| 4305 | + */ | |
| 4306 | + if (unlikely(!insn)) { | |
| 4307 | + kvm_queue_exception(vcpu, UD_VECTOR); | |
| 4308 | + return false; | |
| 4309 | + } | |
| 4310 | + | |
| 4311 | + /* | |
| 4312 | + * Emulate for SEV guests if the insn buffer is not empty. The buffer | |
| 4313 | + * will be empty if the DecodeAssist microcode cannot fetch bytes for | |
| 4314 | + * the faulting instruction because the code fetch itself faulted, e.g. | |
| 4315 | + * the guest attempted to fetch from emulated MMIO or a guest page | |
| 4316 | + * table used to translate CS:RIP resides in emulated MMIO. | |
| 4317 | + */ | |
| 4318 | + if (likely(insn_len)) | |
| 4319 | + return true; | |
| 4320 | + | |
| 4266 | 4321 | /* |
| 4267 | 4322 | * Detect and workaround Errata 1096 Fam_17h_00_0Fh. |
| 4268 | 4323 | * |
| 4269 | 4324 | * Errata: |
| 4270 | − * When CPU raise #NPF on guest data access and vCPU CR4.SMAP=1, it is | |
| 4271 | − * possible that CPU microcode implementing DecodeAssist will fail | |
| 4272 | − * to read bytes of instruction which caused #NPF. In this case, | |
| 4273 | − * GuestIntrBytes field of the VMCB on a VMEXIT will incorrectly | |
| 4274 | − * return 0 instead of the correct guest instruction bytes. | |
| 4275 | − * | |
| 4276 | − * This happens because CPU microcode reading instruction bytes | |
| 4277 | − * uses a special opcode which attempts to read data using CPL=0 | |
| 4278 | − * privileges. The microcode reads CS:RIP and if it hits a SMAP | |
| 4279 | − * fault, it gives up and returns no instruction bytes. | |
| 4325 | + * When CPU raises #NPF on guest data access and vCPU CR4.SMAP=1, it is | |
| 4326 | + * possible that CPU microcode implementing DecodeAssist will fail to | |
| 4327 | + * read guest memory at CS:RIP and vmcb.GuestIntrBytes will incorrectly | |
| 4328 | + * be '0'. This happens because microcode reads CS:RIP using a _data_ | |
| 4329 | + * loap uop with CPL=0 privileges. If the load hits a SMAP #PF, ucode | |
| 4330 | + * gives up and does not fill the instruction bytes buffer. | |
| 4280 | 4331 | * |
| 4281 | − * Detection: | |
| 4282 | − * We reach here in case CPU supports DecodeAssist, raised #NPF and | |
| 4283 | − * returned 0 in GuestIntrBytes field of the VMCB. | |
| 4284 | − * First, errata can only be triggered in case vCPU CR4.SMAP=1. | |
| 4285 | − * Second, if vCPU CR4.SMEP=1, errata could only be triggered | |
| 4286 | − * in case vCPU CPL==3 (Because otherwise guest would have triggered | |
| 4287 | − * a SMEP fault instead of #NPF). | |
| 4288 | − * Otherwise, vCPU CR4.SMEP=0, errata could be triggered by any vCPU CPL. | |
| 4289 | − * As most guests enable SMAP if they have also enabled SMEP, use above | |
| 4290 | − * logic in order to attempt minimize false-positive of detecting errata | |
| 4291 | − * while still preserving all cases semantic correctness. | |
| 4332 | + * As above, KVM reaches this point iff the VM is an SEV guest, the CPU | |
| 4333 | + * supports DecodeAssist, a #NPF was raised, KVM's page fault handler | |
| 4334 | + * triggered emulation (e.g. for MMIO), and the CPU returned 0 in the | |
| 4335 | + * GuestIntrBytes field of the VMCB. | |
| 4292 | 4336 | * |
| 4293 | − * Workaround: | |
| 4294 | − * To determine what instruction the guest was executing, the hypervisor | |
| 4295 | − * will have to decode the instruction at the instruction pointer. | |
| 4337 | + * This does _not_ mean that the erratum has been encountered, as the | |
| 4338 | + * DecodeAssist will also fail if the load for CS:RIP hits a legitimate | |
| 4339 | + * #PF, e.g. if the guest attempt to execute from emulated MMIO and | |
| 4340 | + * encountered a reserved/not-present #PF. | |
| 4296 | 4341 | * |
| 4297 | − * In non SEV guest, hypervisor will be able to read the guest | |
| 4298 | − * memory to decode the instruction pointer when insn_len is zero | |
| 4299 | − * so we return true to indicate that decoding is possible. | |
| 4342 | + * To hit the erratum, the following conditions must be true: | |
| 4343 | + * 1. CR4.SMAP=1 (obviously). | |
| 4344 | + * 2. CR4.SMEP=0 || CPL=3. If SMEP=1 and CPL<3, the erratum cannot | |
| 4345 | + * have been hit as the guest would have encountered a SMEP | |
| 4346 | + * violation #PF, not a #NPF. | |
| 4347 | + * 3. The #NPF is not due to a code fetch, in which case failure to | |
| 4348 | + * retrieve the instruction bytes is legitimate (see abvoe). | |
| 4300 | 4349 | * |
| 4301 | − * But in the SEV guest, the guest memory is encrypted with the | |
| 4302 | − * guest specific key and hypervisor will not be able to decode the | |
| 4303 | − * instruction pointer so we will not able to workaround it. Lets | |
| 4304 | − * print the error and request to kill the guest. | |
| 4350 | + * In addition, don't apply the erratum workaround if the #NPF occurred | |
| 4351 | + * while translating guest page tables (see below). | |
| 4305 | 4352 | */ |
| 4306 | − if (likely(!insn || insn_len)) | |
| 4307 | − return true; | |
| 4308 | − | |
| 4309 | − /* | |
| 4310 | − * If RIP is invalid, go ahead with emulation which will cause an | |
| 4311 | − * internal error exit. | |
| 4312 | − */ | |
| 4313 | − if (!kvm_vcpu_gfn_to_memslot(vcpu, kvm_rip_read(vcpu) >> PAGE_SHIFT)) | |
| 4314 | − return true; | |
| 4353 | + error_code = to_svm(vcpu)->vmcb->control.exit_info_1; | |
| 4354 | + if (error_code & (PFERR_GUEST_PAGE_MASK | PFERR_FETCH_MASK)) | |
| 4355 | + goto resume_guest; | |
| 4315 | 4356 | |
| 4316 | 4357 | cr4 = kvm_read_cr4(vcpu); |
| 4317 | 4358 | smep = cr4 & X86_CR4_SMEP; |
| 4318 | 4359 | smap = cr4 & X86_CR4_SMAP; |
| 4319 | 4360 | is_user = svm_get_cpl(vcpu) == 3; |
| 4320 | 4361 | if (smap && (!smep || is_user)) { |
| 4321 | − if (!sev_guest(vcpu->kvm)) | |
| 4322 | − return true; | |
| 4323 | − | |
| 4324 | 4362 | pr_err_ratelimited("KVM: SEV Guest triggered AMD Erratum 1096\n"); |
| 4325 | − kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); | |
| 4363 | + | |
| 4364 | + /* | |
| 4365 | + * If the fault occurred in userspace, arbitrarily inject #GP | |
| 4366 | + * to avoid killing the guest and to hopefully avoid confusing | |
| 4367 | + * the guest kernel too much, e.g. injecting #PF would not be | |
| 4368 | + * coherent with respect to the guest's page tables. Request | |
| 4369 | + * triple fault if the fault occurred in the kernel as there's | |
| 4370 | + * no fault that KVM can inject without confusing the guest. | |
| 4371 | + * In practice, the triple fault is moot as no sane SEV kernel | |
| 4372 | + * will execute from user memory while also running with SMAP=1. | |
| 4373 | + */ | |
| 4374 | + if (is_user) | |
| 4375 | + kvm_inject_gp(vcpu, 0); | |
| 4376 | + else | |
| 4377 | + kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); | |
| 4326 | 4378 | } |
| 4327 | 4379 | |
| 4380 | +resume_guest: | |
| 4381 | + /* | |
| 4382 | + * If the erratum was not hit, simply resume the guest and let it fault | |
| 4383 | + * again. While awful, e.g. the vCPU may get stuck in an infinite loop | |
| 4384 | + * if the fault is at CPL=0, it's the lesser of all evils. Exiting to | |
| 4385 | + * userspace will kill the guest, and letting the emulator read garbage | |
| 4386 | + * will yield random behavior and potentially corrupt the guest. | |
| 4387 | + * | |
| 4388 | + * Simply resuming the guest is technically not a violation of the SEV | |
| 4389 | + * architecture. AMD's APM states that all code fetches and page table | |
| 4390 | + * accesses for SEV guest are encrypted, regardless of the C-Bit. The | |
| 4391 | + * APM also states that encrypted accesses to MMIO are "ignored", but | |
| 4392 | + * doesn't explicitly define "ignored", i.e. doing nothing and letting | |
| 4393 | + * the guest spin is technically "ignoring" the access. | |
| 4394 | + */ | |
| 4328 | 4395 | return false; |
| 4329 | 4396 | } |
| 4330 | 4397 | |
| @@ -304,11 +304,6 @@ static inline void vmcb_mark_all_clean(struct vmcb *vmcb) · 303 unmodified lines | ||
| 304 | 304 | & ~VMCB_ALWAYS_DIRTY_MASK; |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | −static inline bool vmcb_is_clean(struct vmcb *vmcb, int bit) | |
| 308 | −{ | |
| 309 | − return (vmcb->control.clean & (1 << bit)); | |
| 310 | −} | |
| 311 | − | |
| 312 | 307 | static inline void vmcb_mark_dirty(struct vmcb *vmcb, int bit) |
| 313 | 308 | { |
| 314 | 309 | vmcb->control.clean &= ~(1 << bit); |
| @@ -525,7 +520,7 @@ static inline bool nested_exit_on_nmi(struct vcpu_svm *svm) · 210 unmodified lines | ||
| 525 | 520 | |
| 526 | 521 | int enter_svm_guest_mode(struct kvm_vcpu *vcpu, |
| 527 | 522 | u64 vmcb_gpa, struct vmcb *vmcb12, bool from_vmrun); |
| 528 | −void svm_leave_nested(struct vcpu_svm *svm); | |
| 523 | +void svm_leave_nested(struct kvm_vcpu *vcpu); | |
| 529 | 524 | void svm_free_nested(struct vcpu_svm *svm); |
| 530 | 525 | int svm_allocate_nested(struct vcpu_svm *svm); |
| 531 | 526 | int nested_svm_vmrun(struct kvm_vcpu *vcpu); |
| @@ -46,6 +46,9 @@ static inline void svm_hv_init_vmcb(struct vmcb *vmcb) · 45 unmodified lines | ||
| 46 | 46 | if (npt_enabled && |
| 47 | 47 | ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB) |
| 48 | 48 | hve->hv_enlightenments_control.enlightened_npt_tlb = 1; |
| 49 | + | |
| 50 | + if (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP) | |
| 51 | + hve->hv_enlightenments_control.msr_bitmap = 1; | |
| 49 | 52 | } |
| 50 | 53 | |
| 51 | 54 | static inline void svm_hv_hardware_setup(void) |
| @@ -83,14 +86,7 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments( · 31 unmodified lines | ||
| 83 | 86 | struct hv_enlightenments *hve = |
| 84 | 87 | (struct hv_enlightenments *)vmcb->control.reserved_sw; |
| 85 | 88 | |
| 86 | − /* | |
| 87 | − * vmcb can be NULL if called during early vcpu init. | |
| 88 | − * And its okay not to mark vmcb dirty during vcpu init | |
| 89 | − * as we mark it dirty unconditionally towards end of vcpu | |
| 90 | − * init phase. | |
| 91 | − */ | |
| 92 | − if (vmcb_is_clean(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS) && | |
| 93 | − hve->hv_enlightenments_control.msr_bitmap) | |
| 89 | + if (hve->hv_enlightenments_control.msr_bitmap) | |
| 94 | 90 | vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS); |
| 95 | 91 | } |
| 96 | 92 | |
| @@ -54,7 +54,6 @@ struct nested_vmx_msrs { · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | struct vmcs_config { |
| 56 | 56 | int size; |
| 57 | − int order; | |
| 58 | 57 | u32 basic_cap; |
| 59 | 58 | u32 revision_id; |
| 60 | 59 | u32 pin_based_exec_ctrl; |
| @@ -12,8 +12,6 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | DEFINE_STATIC_KEY_FALSE(enable_evmcs); |
| 14 | 14 | |
| 15 | −#if IS_ENABLED(CONFIG_HYPERV) | |
| 16 | − | |
| 17 | 15 | #define EVMCS1_OFFSET(x) offsetof(struct hv_enlightened_vmcs, x) |
| 18 | 16 | #define EVMCS1_FIELD(number, name, clean_field)[ROL16(number, 6)] = \ |
| 19 | 17 | {EVMCS1_OFFSET(name), clean_field} |
| @@ -296,6 +294,7 @@ const struct evmcs_field vmcs_field_to_evmcs_1[] = { · 276 unmodified lines | ||
| 296 | 294 | }; |
| 297 | 295 | const unsigned int nr_evmcs_1_fields = ARRAY_SIZE(vmcs_field_to_evmcs_1); |
| 298 | 296 | |
| 297 | +#if IS_ENABLED(CONFIG_HYPERV) | |
| 299 | 298 | __init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) |
| 300 | 299 | { |
| 301 | 300 | vmcs_conf->pin_based_exec_ctrl &= ~EVMCS1_UNSUPPORTED_PINCTRL; |
| @@ -362,6 +361,7 @@ void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata) · 60 unmodified lines | ||
| 362 | 361 | case MSR_IA32_VMX_PROCBASED_CTLS2: |
| 363 | 362 | ctl_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC; |
| 364 | 363 | break; |
| 364 | + case MSR_IA32_VMX_TRUE_PINBASED_CTLS: | |
| 365 | 365 | case MSR_IA32_VMX_PINBASED_CTLS: |
| 366 | 366 | ctl_high &= ~EVMCS1_UNSUPPORTED_PINCTRL; |
| 367 | 367 | break; |
| @@ -59,12 +59,12 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs); · 58 unmodified lines | ||
| 59 | 59 | SECONDARY_EXEC_SHADOW_VMCS | \ |
| 60 | 60 | SECONDARY_EXEC_TSC_SCALING | \ |
| 61 | 61 | SECONDARY_EXEC_PAUSE_LOOP_EXITING) |
| 62 | −#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL) | |
| 62 | +#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL \ | |
| 63 | + (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ | |
| 64 | + VM_EXIT_SAVE_VMX_PREEMPTION_TIMER) | |
| 63 | 65 | #define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) |
| 64 | 66 | #define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING) |
| 65 | 67 | |
| 66 | −#if IS_ENABLED(CONFIG_HYPERV) | |
| 67 | − | |
| 68 | 68 | struct evmcs_field { |
| 69 | 69 | u16 offset; |
| 70 | 70 | u16 clean_field; |
| @@ -73,26 +73,56 @@ struct evmcs_field { · 2 unmodified lines | ||
| 73 | 73 | extern const struct evmcs_field vmcs_field_to_evmcs_1[]; |
| 74 | 74 | extern const unsigned int nr_evmcs_1_fields; |
| 75 | 75 | |
| 76 | −static __always_inline int get_evmcs_offset(unsigned long field, | |
| 77 | − u16 *clean_field) | |
| 76 | +static __always_inline int evmcs_field_offset(unsigned long field, | |
| 77 | + u16 *clean_field) | |
| 78 | 78 | { |
| 79 | 79 | unsigned int index = ROL16(field, 6); |
| 80 | 80 | const struct evmcs_field *evmcs_field; |
| 81 | 81 | |
| 82 | − if (unlikely(index >= nr_evmcs_1_fields)) { | |
| 83 | − WARN_ONCE(1, "KVM: accessing unsupported EVMCS field %lx\n", | |
| 84 | − field); | |
| 82 | + if (unlikely(index >= nr_evmcs_1_fields)) | |
| 85 | 83 | return -ENOENT; |
| 86 | − } | |
| 87 | 84 | |
| 88 | 85 | evmcs_field = &vmcs_field_to_evmcs_1[index]; |
| 89 | 86 | |
| 87 | + /* | |
| 88 | + * Use offset=0 to detect holes in eVMCS. This offset belongs to | |
| 89 | + * 'revision_id' but this field has no encoding and is supposed to | |
| 90 | + * be accessed directly. | |
| 91 | + */ | |
| 92 | + if (unlikely(!evmcs_field->offset)) | |
| 93 | + return -ENOENT; | |
| 94 | + | |
| 90 | 95 | if (clean_field) |
| 91 | 96 | *clean_field = evmcs_field->clean_field; |
| 92 | 97 | |
| 93 | 98 | return evmcs_field->offset; |
| 94 | 99 | } |
| 95 | 100 | |
| 101 | +static inline u64 evmcs_read_any(struct hv_enlightened_vmcs *evmcs, | |
| 102 | + unsigned long field, u16 offset) | |
| 103 | +{ | |
| 104 | + /* | |
| 105 | + * vmcs12_read_any() doesn't care whether the supplied structure | |
| 106 | + * is 'struct vmcs12' or 'struct hv_enlightened_vmcs' as it takes | |
| 107 | + * the exact offset of the required field, use it for convenience | |
| 108 | + * here. | |
| 109 | + */ | |
| 110 | + return vmcs12_read_any((void *)evmcs, field, offset); | |
| 111 | +} | |
| 112 | + | |
| 113 | +#if IS_ENABLED(CONFIG_HYPERV) | |
| 114 | + | |
| 115 | +static __always_inline int get_evmcs_offset(unsigned long field, | |
| 116 | + u16 *clean_field) | |
| 117 | +{ | |
| 118 | + int offset = evmcs_field_offset(field, clean_field); | |
| 119 | + | |
| 120 | + WARN_ONCE(offset < 0, "KVM: accessing unsupported EVMCS field %lx\n", | |
| 121 | + field); | |
| 122 | + | |
| 123 | + return offset; | |
| 124 | +} | |
| 125 | + | |
| 96 | 126 | static __always_inline void evmcs_write64(unsigned long field, u64 value) |
| 97 | 127 | { |
| 98 | 128 | u16 clean_field; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <asm/mmu_context.h> |
| 8 | 8 | |
| 9 | 9 | #include "cpuid.h" |
| 10 | +#include "evmcs.h" | |
| 10 | 11 | #include "hyperv.h" |
| 11 | 12 | #include "mmu.h" |
| 12 | 13 | #include "nested.h" |
| @@ -4851,18 +4852,20 @@ static struct vmcs *alloc_shadow_vmcs(struct kvm_vcpu *vcpu) · 4838 unmodified lines | ||
| 4851 | 4852 | struct loaded_vmcs *loaded_vmcs = vmx->loaded_vmcs; |
| 4852 | 4853 | |
| 4853 | 4854 | /* |
| 4854 | − * We should allocate a shadow vmcs for vmcs01 only when L1 | |
| 4855 | − * executes VMXON and free it when L1 executes VMXOFF. | |
| 4856 | − * As it is invalid to execute VMXON twice, we shouldn't reach | |
| 4857 | − * here when vmcs01 already have an allocated shadow vmcs. | |
| 4855 | + * KVM allocates a shadow VMCS only when L1 executes VMXON and frees it | |
| 4856 | + * when L1 executes VMXOFF or the vCPU is forced out of nested | |
| 4857 | + * operation. VMXON faults if the CPU is already post-VMXON, so it | |
| 4858 | + * should be impossible to already have an allocated shadow VMCS. KVM | |
| 4859 | + * doesn't support virtualization of VMCS shadowing, so vmcs01 should | |
| 4860 | + * always be the loaded VMCS. | |
| 4858 | 4861 | */ |
| 4859 | − WARN_ON(loaded_vmcs == &vmx->vmcs01 && loaded_vmcs->shadow_vmcs); | |
| 4862 | + if (WARN_ON(loaded_vmcs != &vmx->vmcs01 || loaded_vmcs->shadow_vmcs)) | |
| 4863 | + return loaded_vmcs->shadow_vmcs; | |
| 4864 | + | |
| 4865 | + loaded_vmcs->shadow_vmcs = alloc_vmcs(true); | |
| 4866 | + if (loaded_vmcs->shadow_vmcs) | |
| 4867 | + vmcs_clear(loaded_vmcs->shadow_vmcs); | |
| 4860 | 4868 | |
| 4861 | − if (!loaded_vmcs->shadow_vmcs) { | |
| 4862 | − loaded_vmcs->shadow_vmcs = alloc_vmcs(true); | |
| 4863 | − if (loaded_vmcs->shadow_vmcs) | |
| 4864 | − vmcs_clear(loaded_vmcs->shadow_vmcs); | |
| 4865 | − } | |
| 4866 | 4869 | return loaded_vmcs->shadow_vmcs; |
| 4867 | 4870 | } |
| 4868 | 4871 | |
| @@ -5099,27 +5102,49 @@ static int handle_vmread(struct kvm_vcpu *vcpu) · 230 unmodified lines | ||
| 5099 | 5102 | if (!nested_vmx_check_permission(vcpu)) |
| 5100 | 5103 | return 1; |
| 5101 | 5104 | |
| 5102 | − /* | |
| 5103 | − * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA, | |
| 5104 | − * any VMREAD sets the ALU flags for VMfailInvalid. | |
| 5105 | − */ | |
| 5106 | − if (vmx->nested.current_vmptr == INVALID_GPA || | |
| 5107 | − (is_guest_mode(vcpu) && | |
| 5108 | − get_vmcs12(vcpu)->vmcs_link_pointer == INVALID_GPA)) | |
| 5109 | − return nested_vmx_failInvalid(vcpu); | |
| 5110 | − | |
| 5111 | 5105 | /* Decode instruction info and find the field to read */ |
| 5112 | 5106 | field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf)); |
| 5113 | 5107 | |
| 5114 | − offset = vmcs_field_to_offset(field); | |
| 5115 | − if (offset < 0) | |
| 5116 | − return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); | |
| 5108 | + if (!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) { | |
| 5109 | + /* | |
| 5110 | + * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA, | |
| 5111 | + * any VMREAD sets the ALU flags for VMfailInvalid. | |
| 5112 | + */ | |
| 5113 | + if (vmx->nested.current_vmptr == INVALID_GPA || | |
| 5114 | + (is_guest_mode(vcpu) && | |
| 5115 | + get_vmcs12(vcpu)->vmcs_link_pointer == INVALID_GPA)) | |
| 5116 | + return nested_vmx_failInvalid(vcpu); | |
| 5117 | 5117 | |
| 5118 | − if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field)) | |
| 5119 | − copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); | |
| 5118 | + offset = get_vmcs12_field_offset(field); | |
| 5119 | + if (offset < 0) | |
| 5120 | + return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); | |
| 5121 | + | |
| 5122 | + if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field)) | |
| 5123 | + copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); | |
| 5120 | 5124 | |
| 5121 | − /* Read the field, zero-extended to a u64 value */ | |
| 5122 | − value = vmcs12_read_any(vmcs12, field, offset); | |
| 5125 | + /* Read the field, zero-extended to a u64 value */ | |
| 5126 | + value = vmcs12_read_any(vmcs12, field, offset); | |
| 5127 | + } else { | |
| 5128 | + /* | |
| 5129 | + * Hyper-V TLFS (as of 6.0b) explicitly states, that while an | |
| 5130 | + * enlightened VMCS is active VMREAD/VMWRITE instructions are | |
| 5131 | + * unsupported. Unfortunately, certain versions of Windows 11 | |
| 5132 | + * don't comply with this requirement which is not enforced in | |
| 5133 | + * genuine Hyper-V. Allow VMREAD from an enlightened VMCS as a | |
| 5134 | + * workaround, as misbehaving guests will panic on VM-Fail. | |
| 5135 | + * Note, enlightened VMCS is incompatible with shadow VMCS so | |
| 5136 | + * all VMREADs from L2 should go to L1. | |
| 5137 | + */ | |
| 5138 | + if (WARN_ON_ONCE(is_guest_mode(vcpu))) | |
| 5139 | + return nested_vmx_failInvalid(vcpu); | |
| 5140 | + | |
| 5141 | + offset = evmcs_field_offset(field, NULL); | |
| 5142 | + if (offset < 0) | |
| 5143 | + return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); | |
| 5144 | + | |
| 5145 | + /* Read the field, zero-extended to a u64 value */ | |
| 5146 | + value = evmcs_read_any(vmx->nested.hv_evmcs, field, offset); | |
| 5147 | + } | |
| 5123 | 5148 | |
| 5124 | 5149 | /* |
| 5125 | 5150 | * Now copy part of this value to register or memory, as requested. |
| @@ -5214,7 +5239,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) · 88 unmodified lines | ||
| 5214 | 5239 | |
| 5215 | 5240 | field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf)); |
| 5216 | 5241 | |
| 5217 | − offset = vmcs_field_to_offset(field); | |
| 5242 | + offset = get_vmcs12_field_offset(field); | |
| 5218 | 5243 | if (offset < 0) |
| 5219 | 5244 | return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); |
| 5220 | 5245 | |
| @@ -6462,7 +6487,7 @@ static u64 nested_vmx_calc_vmcs_enum_msr(void) · 1241 unmodified lines | ||
| 6462 | 6487 | max_idx = 0; |
| 6463 | 6488 | for (i = 0; i < nr_vmcs12_fields; i++) { |
| 6464 | 6489 | /* The vmcs12 table is very, very sparsely populated. */ |
| 6465 | − if (!vmcs_field_to_offset_table[i]) | |
| 6490 | + if (!vmcs12_field_offsets[i]) | |
| 6466 | 6491 | continue; |
| 6467 | 6492 | |
| 6468 | 6493 | idx = vmcs_field_index(VMCS12_IDX_TO_ENC(i)); |
| @@ -6771,6 +6796,7 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)) · 302 unmodified lines | ||
| 6771 | 6796 | } |
| 6772 | 6797 | |
| 6773 | 6798 | struct kvm_x86_nested_ops vmx_nested_ops = { |
| 6799 | + .leave_nested = vmx_leave_nested, | |
| 6774 | 6800 | .check_events = vmx_check_nested_events, |
| 6775 | 6801 | .hv_timer_pending = nested_vmx_preemption_timer_pending, |
| 6776 | 6802 | .triple_fault = nested_vmx_triple_fault, |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | FIELD(number, name), \ |
| 9 | 9 | [ROL16(number##_HIGH, 6)] = VMCS12_OFFSET(name) + sizeof(u32) |
| 10 | 10 | |
| 11 | −const unsigned short vmcs_field_to_offset_table[] = { | |
| 11 | +const unsigned short vmcs12_field_offsets[] = { | |
| 12 | 12 | FIELD(VIRTUAL_PROCESSOR_ID, virtual_processor_id), |
| 13 | 13 | FIELD(POSTED_INTR_NV, posted_intr_nv), |
| 14 | 14 | FIELD(GUEST_ES_SELECTOR, guest_es_selector), |
| @@ -151,4 +151,4 @@ const unsigned short vmcs_field_to_offset_table[] = { · 136 unmodified lines | ||
| 151 | 151 | FIELD(HOST_RSP, host_rsp), |
| 152 | 152 | FIELD(HOST_RIP, host_rip), |
| 153 | 153 | }; |
| 154 | −const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs_field_to_offset_table); | |
| 154 | +const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs12_field_offsets); | |
| @@ -361,10 +361,10 @@ static inline void vmx_check_vmcs12_offsets(void) · 360 unmodified lines | ||
| 361 | 361 | CHECK_OFFSET(guest_pml_index, 996); |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | −extern const unsigned short vmcs_field_to_offset_table[]; | |
| 364 | +extern const unsigned short vmcs12_field_offsets[]; | |
| 365 | 365 | extern const unsigned int nr_vmcs12_fields; |
| 366 | 366 | |
| 367 | −static inline short vmcs_field_to_offset(unsigned long field) | |
| 367 | +static inline short get_vmcs12_field_offset(unsigned long field) | |
| 368 | 368 | { |
| 369 | 369 | unsigned short offset; |
| 370 | 370 | unsigned int index; |
| @@ -377,7 +377,7 @@ static inline short vmcs_field_to_offset(unsigned long field) · 6 unmodified lines | ||
| 377 | 377 | return -ENOENT; |
| 378 | 378 | |
| 379 | 379 | index = array_index_nospec(index, nr_vmcs12_fields); |
| 380 | − offset = vmcs_field_to_offset_table[index]; | |
| 380 | + offset = vmcs12_field_offsets[index]; | |
| 381 | 381 | if (offset == 0) |
| 382 | 382 | return -ENOENT; |
| 383 | 383 | return offset; |
| @@ -1487,11 +1487,12 @@ static int vmx_rtit_ctl_check(struct kvm_vcpu *vcpu, u64 data) · 1486 unmodified lines | ||
| 1487 | 1487 | return 0; |
| 1488 | 1488 | } |
| 1489 | 1489 | |
| 1490 | −static bool vmx_can_emulate_instruction(struct kvm_vcpu *vcpu, void *insn, int insn_len) | |
| 1490 | +static bool vmx_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, | |
| 1491 | + void *insn, int insn_len) | |
| 1491 | 1492 | { |
| 1492 | 1493 | /* |
| 1493 | 1494 | * Emulation of instructions in SGX enclaves is impossible as RIP does |
| 1494 | − * not point tthe failing instruction, and even if it did, the code | |
| 1495 | + * not point at the failing instruction, and even if it did, the code | |
| 1495 | 1496 | * stream is inaccessible. Inject #UD instead of exiting to userspace |
| 1496 | 1497 | * so that guest userspace can't DoS the guest simply by triggering |
| 1497 | 1498 | * emulation (enclaves are CPL3 only). |
| @@ -2603,7 +2604,6 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, · 1105 unmodified lines | ||
| 2603 | 2604 | return -EIO; |
| 2604 | 2605 | |
| 2605 | 2606 | vmcs_conf->size = vmx_msr_high & 0x1fff; |
| 2606 | − vmcs_conf->order = get_order(vmcs_conf->size); | |
| 2607 | 2607 | vmcs_conf->basic_cap = vmx_msr_high & ~0x1fff; |
| 2608 | 2608 | |
| 2609 | 2609 | vmcs_conf->revision_id = vmx_msr_low; |
| @@ -2628,7 +2628,7 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags) · 18 unmodified lines | ||
| 2628 | 2628 | struct page *pages; |
| 2629 | 2629 | struct vmcs *vmcs; |
| 2630 | 2630 | |
| 2631 | − pages = __alloc_pages_node(node, flags, vmcs_config.order); | |
| 2631 | + pages = __alloc_pages_node(node, flags, 0); | |
| 2632 | 2632 | if (!pages) |
| 2633 | 2633 | return NULL; |
| 2634 | 2634 | vmcs = page_address(pages); |
| @@ -2647,7 +2647,7 @@ struct vmcs *alloc_vmcs_cpu(bool shadow, int cpu, gfp_t flags) · 12 unmodified lines | ||
| 2647 | 2647 | |
| 2648 | 2648 | void free_vmcs(struct vmcs *vmcs) |
| 2649 | 2649 | { |
| 2650 | − free_pages((unsigned long)vmcs, vmcs_config.order); | |
| 2650 | + free_page((unsigned long)vmcs); | |
| 2651 | 2651 | } |
| 2652 | 2652 | |
| 2653 | 2653 | /* |
| @@ -4094,10 +4094,14 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx) · 1440 unmodified lines | ||
| 4094 | 4094 | vmcs_write32(HOST_IA32_SYSENTER_CS, low32); |
| 4095 | 4095 | |
| 4096 | 4096 | /* |
| 4097 | − * If 32-bit syscall is enabled, vmx_vcpu_load_vcms rewrites | |
| 4098 | − * HOST_IA32_SYSENTER_ESP. | |
| 4097 | + * SYSENTER is used for 32-bit system calls on either 32-bit or | |
| 4098 | + * 64-bit kernels. It is always zero If neither is allowed, otherwise | |
| 4099 | + * vmx_vcpu_load_vmcs loads it with the per-CPU entry stack (and may | |
| 4100 | + * have already done so!). | |
| 4099 | 4101 | */ |
| 4100 | − vmcs_writel(HOST_IA32_SYSENTER_ESP, 0); | |
| 4102 | + if (!IS_ENABLED(CONFIG_IA32_EMULATION) && !IS_ENABLED(CONFIG_X86_32)) | |
| 4103 | + vmcs_writel(HOST_IA32_SYSENTER_ESP, 0); | |
| 4104 | + | |
| 4101 | 4105 | rdmsrl(MSR_IA32_SYSENTER_EIP, tmpl); |
| 4102 | 4106 | vmcs_writel(HOST_IA32_SYSENTER_EIP, tmpl); /* 22.2.3 */ |
| 4103 | 4107 | |
| @@ -4901,8 +4905,33 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) · 797 unmodified lines | ||
| 4901 | 4905 | dr6 = vmx_get_exit_qual(vcpu); |
| 4902 | 4906 | if (!(vcpu->guest_debug & |
| 4903 | 4907 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { |
| 4908 | + /* | |
| 4909 | + * If the #DB was due to ICEBP, a.k.a. INT1, skip the | |
| 4910 | + * instruction. ICEBP generates a trap-like #DB, but | |
| 4911 | + * despite its interception control being tied to #DB, | |
| 4912 | + * is an instruction intercept, i.e. the VM-Exit occurs | |
| 4913 | + * on the ICEBP itself. Note, skipping ICEBP also | |
| 4914 | + * clears STI and MOVSS blocking. | |
| 4915 | + * | |
| 4916 | + * For all other #DBs, set vmcs.PENDING_DBG_EXCEPTIONS.BS | |
| 4917 | + * if single-step is enabled in RFLAGS and STI or MOVSS | |
| 4918 | + * blocking is active, as the CPU doesn't set the bit | |
| 4919 | + * on VM-Exit due to #DB interception. VM-Entry has a | |
| 4920 | + * consistency check that a single-step #DB is pending | |
| 4921 | + * in this scenario as the previous instruction cannot | |
| 4922 | + * have toggled RFLAGS.TF 0=>1 (because STI and POP/MOV | |
| 4923 | + * don't modify RFLAGS), therefore the one instruction | |
| 4924 | + * delay when activating single-step breakpoints must | |
| 4925 | + * have already expired. Note, the CPU sets/clears BS | |
| 4926 | + * as appropriate for all other VM-Exits types. | |
| 4927 | + */ | |
| 4904 | 4928 | if (is_icebp(intr_info)) |
| 4905 | 4929 | WARN_ON(!skip_emulated_instruction(vcpu)); |
| 4930 | + else if ((vmx_get_rflags(vcpu) & X86_EFLAGS_TF) && | |
| 4931 | + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & | |
| 4932 | + (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS))) | |
| 4933 | + vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, | |
| 4934 | + vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS) | DR6_BS); | |
| 4906 | 4935 | |
| 4907 | 4936 | kvm_queue_exception_p(vcpu, DB_VECTOR, dr6); |
| 4908 | 4937 | return 1; |
| @@ -5397,7 +5426,7 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu) · 488 unmodified lines | ||
| 5397 | 5426 | { |
| 5398 | 5427 | gpa_t gpa; |
| 5399 | 5428 | |
| 5400 | − if (!vmx_can_emulate_instruction(vcpu, NULL, 0)) | |
| 5429 | + if (!vmx_can_emulate_instruction(vcpu, EMULTYPE_PF, NULL, 0)) | |
| 5401 | 5430 | return 1; |
| 5402 | 5431 | |
| 5403 | 5432 | /* |
| @@ -3535,6 +3535,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 3534 unmodified lines | ||
| 3535 | 3535 | if (data & ~supported_xss) |
| 3536 | 3536 | return 1; |
| 3537 | 3537 | vcpu->arch.ia32_xss = data; |
| 3538 | + kvm_update_cpuid_runtime(vcpu); | |
| 3538 | 3539 | break; |
| 3539 | 3540 | case MSR_SMI_COUNT: |
| 3540 | 3541 | if (!msr_info->host_initiated) |
| @@ -4229,6 +4230,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 688 unmodified lines | ||
| 4229 | 4230 | case KVM_CAP_SREGS2: |
| 4230 | 4231 | case KVM_CAP_EXIT_ON_EMULATION_FAILURE: |
| 4231 | 4232 | case KVM_CAP_VCPU_ATTRIBUTES: |
| 4233 | + case KVM_CAP_SYS_ATTRIBUTES: | |
| 4232 | 4234 | r = 1; |
| 4233 | 4235 | break; |
| 4234 | 4236 | case KVM_CAP_EXIT_HYPERCALL: |
| @@ -4331,7 +4333,49 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 96 unmodified lines | ||
| 4331 | 4333 | break; |
| 4332 | 4334 | } |
| 4333 | 4335 | return r; |
| 4336 | +} | |
| 4337 | + | |
| 4338 | +static inline void __user *kvm_get_attr_addr(struct kvm_device_attr *attr) | |
| 4339 | +{ | |
| 4340 | + void __user *uaddr = (void __user*)(unsigned long)attr->addr; | |
| 4334 | 4341 | |
| 4342 | + if ((u64)(unsigned long)uaddr != attr->addr) | |
| 4343 | + return ERR_PTR(-EFAULT); | |
| 4344 | + return uaddr; | |
| 4345 | +} | |
| 4346 | + | |
| 4347 | +static int kvm_x86_dev_get_attr(struct kvm_device_attr *attr) | |
| 4348 | +{ | |
| 4349 | + u64 __user *uaddr = kvm_get_attr_addr(attr); | |
| 4350 | + | |
| 4351 | + if (attr->group) | |
| 4352 | + return -ENXIO; | |
| 4353 | + | |
| 4354 | + if (IS_ERR(uaddr)) | |
| 4355 | + return PTR_ERR(uaddr); | |
| 4356 | + | |
| 4357 | + switch (attr->attr) { | |
| 4358 | + case KVM_X86_XCOMP_GUEST_SUPP: | |
| 4359 | + if (put_user(supported_xcr0, uaddr)) | |
| 4360 | + return -EFAULT; | |
| 4361 | + return 0; | |
| 4362 | + default: | |
| 4363 | + return -ENXIO; | |
| 4364 | + break; | |
| 4365 | + } | |
| 4366 | +} | |
| 4367 | + | |
| 4368 | +static int kvm_x86_dev_has_attr(struct kvm_device_attr *attr) | |
| 4369 | +{ | |
| 4370 | + if (attr->group) | |
| 4371 | + return -ENXIO; | |
| 4372 | + | |
| 4373 | + switch (attr->attr) { | |
| 4374 | + case KVM_X86_XCOMP_GUEST_SUPP: | |
| 4375 | + return 0; | |
| 4376 | + default: | |
| 4377 | + return -ENXIO; | |
| 4378 | + } | |
| 4335 | 4379 | } |
| 4336 | 4380 | |
| 4337 | 4381 | long kvm_arch_dev_ioctl(struct file *filp, |
| @@ -4422,6 +4466,22 @@ long kvm_arch_dev_ioctl(struct file *filp, · 84 unmodified lines | ||
| 4422 | 4466 | case KVM_GET_SUPPORTED_HV_CPUID: |
| 4423 | 4467 | r = kvm_ioctl_get_supported_hv_cpuid(NULL, argp); |
| 4424 | 4468 | break; |
| 4469 | + case KVM_GET_DEVICE_ATTR: { | |
| 4470 | + struct kvm_device_attr attr; | |
| 4471 | + r = -EFAULT; | |
| 4472 | + if (copy_from_user(&attr, (void __user *)arg, sizeof(attr))) | |
| 4473 | + break; | |
| 4474 | + r = kvm_x86_dev_get_attr(&attr); | |
| 4475 | + break; | |
| 4476 | + } | |
| 4477 | + case KVM_HAS_DEVICE_ATTR: { | |
| 4478 | + struct kvm_device_attr attr; | |
| 4479 | + r = -EFAULT; | |
| 4480 | + if (copy_from_user(&attr, (void __user *)arg, sizeof(attr))) | |
| 4481 | + break; | |
| 4482 | + r = kvm_x86_dev_has_attr(&attr); | |
| 4483 | + break; | |
| 4484 | + } | |
| 4425 | 4485 | default: |
| 4426 | 4486 | r = -EINVAL; |
| 4427 | 4487 | break; |
| @@ -4860,8 +4920,10 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, · 432 unmodified lines | ||
| 4860 | 4920 | vcpu->arch.apic->sipi_vector = events->sipi_vector; |
| 4861 | 4921 | |
| 4862 | 4922 | if (events->flags & KVM_VCPUEVENT_VALID_SMM) { |
| 4863 | − if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) | |
| 4923 | + if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) { | |
| 4924 | + kvm_x86_ops.nested_ops->leave_nested(vcpu); | |
| 4864 | 4925 | kvm_smm_changed(vcpu, events->smi.smm); |
| 4926 | + } | |
| 4865 | 4927 | |
| 4866 | 4928 | vcpu->arch.smi_pending = events->smi.pending; |
| 4867 | 4929 | |
| @@ -5022,11 +5084,11 @@ static int kvm_arch_tsc_has_attr(struct kvm_vcpu *vcpu, · 154 unmodified lines | ||
| 5022 | 5084 | static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu, |
| 5023 | 5085 | struct kvm_device_attr *attr) |
| 5024 | 5086 | { |
| 5025 | − u64 __user *uaddr = (u64 __user *)(unsigned long)attr->addr; | |
| 5087 | + u64 __user *uaddr = kvm_get_attr_addr(attr); | |
| 5026 | 5088 | int r; |
| 5027 | 5089 | |
| 5028 | − if ((u64)(unsigned long)uaddr != attr->addr) | |
| 5029 | − return -EFAULT; | |
| 5090 | + if (IS_ERR(uaddr)) | |
| 5091 | + return PTR_ERR(uaddr); | |
| 5030 | 5092 | |
| 5031 | 5093 | switch (attr->attr) { |
| 5032 | 5094 | case KVM_VCPU_TSC_OFFSET: |
| @@ -5045,12 +5107,12 @@ static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu, · 12 unmodified lines | ||
| 5045 | 5107 | static int kvm_arch_tsc_set_attr(struct kvm_vcpu *vcpu, |
| 5046 | 5108 | struct kvm_device_attr *attr) |
| 5047 | 5109 | { |
| 5048 | − u64 __user *uaddr = (u64 __user *)(unsigned long)attr->addr; | |
| 5110 | + u64 __user *uaddr = kvm_get_attr_addr(attr); | |
| 5049 | 5111 | struct kvm *kvm = vcpu->kvm; |
| 5050 | 5112 | int r; |
| 5051 | 5113 | |
| 5052 | − if ((u64)(unsigned long)uaddr != attr->addr) | |
| 5053 | − return -EFAULT; | |
| 5114 | + if (IS_ERR(uaddr)) | |
| 5115 | + return PTR_ERR(uaddr); | |
| 5054 | 5116 | |
| 5055 | 5117 | switch (attr->attr) { |
| 5056 | 5118 | case KVM_VCPU_TSC_OFFSET: { |
| @@ -6810,6 +6872,13 @@ int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, · 1753 unmodified lines | ||
| 6810 | 6872 | } |
| 6811 | 6873 | EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system); |
| 6812 | 6874 | |
| 6875 | +static int kvm_can_emulate_insn(struct kvm_vcpu *vcpu, int emul_type, | |
| 6876 | + void *insn, int insn_len) | |
| 6877 | +{ | |
| 6878 | + return static_call(kvm_x86_can_emulate_instruction)(vcpu, emul_type, | |
| 6879 | + insn, insn_len); | |
| 6880 | +} | |
| 6881 | + | |
| 6813 | 6882 | int handle_ud(struct kvm_vcpu *vcpu) |
| 6814 | 6883 | { |
| 6815 | 6884 | static const char kvm_emulate_prefix[] = { __KVM_EMULATE_PREFIX }; |
| @@ -6817,7 +6886,7 @@ int handle_ud(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 6817 | 6886 | char sig[5]; /* ud2; .ascii "kvm" */ |
| 6818 | 6887 | struct x86_exception e; |
| 6819 | 6888 | |
| 6820 | − if (unlikely(!static_call(kvm_x86_can_emulate_instruction)(vcpu, NULL, 0))) | |
| 6889 | + if (unlikely(!kvm_can_emulate_insn(vcpu, emul_type, NULL, 0))) | |
| 6821 | 6890 | return 1; |
| 6822 | 6891 | |
| 6823 | 6892 | if (force_emulation_prefix && |
| @@ -8193,7 +8262,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, · 1369 unmodified lines | ||
| 8193 | 8262 | bool writeback = true; |
| 8194 | 8263 | bool write_fault_to_spt; |
| 8195 | 8264 | |
| 8196 | − if (unlikely(!static_call(kvm_x86_can_emulate_instruction)(vcpu, insn, insn_len))) | |
| 8265 | + if (unlikely(!kvm_can_emulate_insn(vcpu, emulation_type, insn, insn_len))) | |
| 8197 | 8266 | return 1; |
| 8198 | 8267 | |
| 8199 | 8268 | vcpu->arch.l1tf_flush_l1d = true; |
| @@ -9706,7 +9775,7 @@ void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, · 1506 unmodified lines | ||
| 9706 | 9775 | kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD); |
| 9707 | 9776 | } |
| 9708 | 9777 | |
| 9709 | −void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu) | |
| 9778 | +static void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu) | |
| 9710 | 9779 | { |
| 9711 | 9780 | if (!lapic_in_kernel(vcpu)) |
| 9712 | 9781 | return; |
| @@ -11209,7 +11278,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 1496 unmodified lines | ||
| 11209 | 11278 | |
| 11210 | 11279 | vcpu->arch.msr_misc_features_enables = 0; |
| 11211 | 11280 | |
| 11212 | − vcpu->arch.xcr0 = XFEATURE_MASK_FP; | |
| 11281 | + __kvm_set_xcr(vcpu, 0, XFEATURE_MASK_FP); | |
| 11282 | + __kvm_set_msr(vcpu, MSR_IA32_XSS, 0, true); | |
| 11213 | 11283 | } |
| 11214 | 11284 | |
| 11215 | 11285 | /* All GPRs except RDX (handled below) are zeroed on RESET/INIT. */ |
| @@ -11226,8 +11296,6 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 10 unmodified lines | ||
| 11226 | 11296 | cpuid_0x1 = kvm_find_cpuid_entry(vcpu, 1, 0); |
| 11227 | 11297 | kvm_rdx_write(vcpu, cpuid_0x1 ? cpuid_0x1->eax : 0x600); |
| 11228 | 11298 | |
| 11229 | − vcpu->arch.ia32_xss = 0; | |
| 11230 | − | |
| 11231 | 11299 | static_call(kvm_x86_vcpu_reset)(vcpu, init_event); |
| 11232 | 11300 | |
| 11233 | 11301 | kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); |
| @@ -316,10 +316,7 @@ int __kvm_xen_has_interrupt(struct kvm_vcpu *v) · 315 unmodified lines | ||
| 316 | 316 | "\tnotq %0\n" |
| 317 | 317 | "\t" LOCK_PREFIX "andq %0, %2\n" |
| 318 | 318 | "2:\n" |
| 319 | − "\t.section .fixup,\"ax\"\n" | |
| 320 | − "3:\tjmp\t2b\n" | |
| 321 | − "\t.previous\n" | |
| 322 | − _ASM_EXTABLE_UA(1b, 3b) | |
| 319 | + _ASM_EXTABLE_UA(1b, 2b) | |
| 323 | 320 | : "=r" (evtchn_pending_sel), |
| 324 | 321 | "+m" (vi->evtchn_pending_sel), |
| 325 | 322 | "+m" (v->arch.xen.evtchn_pending_sel) |
| @@ -335,10 +332,7 @@ int __kvm_xen_has_interrupt(struct kvm_vcpu *v) · 9 unmodified lines | ||
| 335 | 332 | "\tnotl %0\n" |
| 336 | 333 | "\t" LOCK_PREFIX "andl %0, %2\n" |
| 337 | 334 | "2:\n" |
| 338 | − "\t.section .fixup,\"ax\"\n" | |
| 339 | − "3:\tjmp\t2b\n" | |
| 340 | − "\t.previous\n" | |
| 341 | − _ASM_EXTABLE_UA(1b, 3b) | |
| 335 | + _ASM_EXTABLE_UA(1b, 2b) | |
| 342 | 336 | : "=r" (evtchn_pending_sel32), |
| 343 | 337 | "+m" (vi->evtchn_pending_sel), |
| 344 | 338 | "+m" (v->arch.xen.evtchn_pending_sel) |
| @@ -353,8 +353,8 @@ static void pci_fixup_video(struct pci_dev *pdev) · 352 unmodified lines | ||
| 353 | 353 | } |
| 354 | 354 | } |
| 355 | 355 | } |
| 356 | −DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, | |
| 357 | − PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); | |
| 356 | +DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, | |
| 357 | + PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); | |
| 358 | 358 | |
| 359 | 359 | |
| 360 | 360 | static const struct dmi_system_id msi_k8t_dmi_table[] = { |
| @@ -1061,20 +1061,32 @@ again: · 1060 unmodified lines | ||
| 1061 | 1061 | } |
| 1062 | 1062 | |
| 1063 | 1063 | static unsigned long __part_start_io_acct(struct block_device *part, |
| 1064 | − unsigned int sectors, unsigned int op) | |
| 1064 | + unsigned int sectors, unsigned int op, | |
| 1065 | + unsigned long start_time) | |
| 1065 | 1066 | { |
| 1066 | 1067 | const int sgrp = op_stat_group(op); |
| 1067 | − unsigned long now = READ_ONCE(jiffies); | |
| 1068 | 1068 | |
| 1069 | 1069 | part_stat_lock(); |
| 1070 | − update_io_ticks(part, now, false); | |
| 1070 | + update_io_ticks(part, start_time, false); | |
| 1071 | 1071 | part_stat_inc(part, ios[sgrp]); |
| 1072 | 1072 | part_stat_add(part, sectors[sgrp], sectors); |
| 1073 | 1073 | part_stat_local_inc(part, in_flight[op_is_write(op)]); |
| 1074 | 1074 | part_stat_unlock(); |
| 1075 | 1075 | |
| 1076 | − return now; | |
| 1076 | + return start_time; | |
| 1077 | +} | |
| 1078 | + | |
| 1079 | +/** | |
| 1080 | + * bio_start_io_acct_time - start I/O accounting for bio based drivers | |
| 1081 | + * @bio: bio to start account for | |
| 1082 | + * @start_time: start time that should be passed back to bio_end_io_acct(). | |
| 1083 | + */ | |
| 1084 | +void bio_start_io_acct_time(struct bio *bio, unsigned long start_time) | |
| 1085 | +{ | |
| 1086 | + __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), | |
| 1087 | + bio_op(bio), start_time); | |
| 1077 | 1088 | } |
| 1089 | +EXPORT_SYMBOL_GPL(bio_start_io_acct_time); | |
| 1078 | 1090 | |
| 1079 | 1091 | /** |
| 1080 | 1092 | * bio_start_io_acct - start I/O accounting for bio based drivers |
| @@ -1084,14 +1096,15 @@ static unsigned long __part_start_io_acct(struct block_device *part, · 3 unmodified lines | ||
| 1084 | 1096 | */ |
| 1085 | 1097 | unsigned long bio_start_io_acct(struct bio *bio) |
| 1086 | 1098 | { |
| 1087 | − return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), bio_op(bio)); | |
| 1099 | + return __part_start_io_acct(bio->bi_bdev, bio_sectors(bio), | |
| 1100 | + bio_op(bio), jiffies); | |
| 1088 | 1101 | } |
| 1089 | 1102 | EXPORT_SYMBOL_GPL(bio_start_io_acct); |
| 1090 | 1103 | |
| 1091 | 1104 | unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors, |
| 1092 | 1105 | unsigned int op) |
| 1093 | 1106 | { |
| 1094 | − return __part_start_io_acct(disk->part0, sectors, op); | |
| 1107 | + return __part_start_io_acct(disk->part0, sectors, op, jiffies); | |
| 1095 | 1108 | } |
| 1096 | 1109 | EXPORT_SYMBOL(disk_start_io_acct); |
| 1097 | 1110 | |
| @@ -144,7 +144,7 @@ int disk_register_independent_access_ranges(struct gendisk *disk, · 143 unmodified lines | ||
| 144 | 144 | &q->kobj, "%s", "independent_access_ranges"); |
| 145 | 145 | if (ret) { |
| 146 | 146 | q->ia_ranges = NULL; |
| 147 | − kfree(iars); | |
| 147 | + kobject_put(&iars->kobj); | |
| 148 | 148 | return ret; |
| 149 | 149 | } |
| 150 | 150 | |
| @@ -2922,6 +2922,8 @@ blk_status_t blk_insert_cloned_request(struct request_queue *q, struct request * · 2921 unmodified lines | ||
| 2922 | 2922 | */ |
| 2923 | 2923 | blk_mq_run_dispatch_ops(rq->q, |
| 2924 | 2924 | ret = blk_mq_request_issue_directly(rq, true)); |
| 2925 | + if (ret) | |
| 2926 | + blk_account_io_done(rq, ktime_get_ns()); | |
| 2925 | 2927 | return ret; |
| 2926 | 2928 | } |
| 2927 | 2929 | EXPORT_SYMBOL_GPL(blk_insert_cloned_request); |
| @@ -128,6 +128,8 @@ int __pata_platform_probe(struct device *dev, struct resource *io_res, · 127 unmodified lines | ||
| 128 | 128 | ap = host->ports[0]; |
| 129 | 129 | |
| 130 | 130 | ap->ops = devm_kzalloc(dev, sizeof(*ap->ops), GFP_KERNEL); |
| 131 | + if (!ap->ops) | |
| 132 | + return -ENOMEM; | |
| 131 | 133 | ap->ops->inherits = &ata_sff_port_ops; |
| 132 | 134 | ap->ops->cable_detect = ata_cable_unknown; |
| 133 | 135 | ap->ops->set_mode = pata_platform_set_mode; |
| @@ -358,7 +358,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, · 357 unmodified lines | ||
| 358 | 358 | * other namespaces. |
| 359 | 359 | */ |
| 360 | 360 | if ((current_user_ns() != &init_user_ns) || |
| 361 | − (task_active_pid_ns(current) != &init_pid_ns)) | |
| 361 | + !task_is_in_init_pid_ns(current)) | |
| 362 | 362 | return; |
| 363 | 363 | |
| 364 | 364 | /* Can only change if privileged. */ |
| @@ -90,10 +90,8 @@ struct counter_device *counter_alloc(size_t sizeof_priv) · 89 unmodified lines | ||
| 90 | 90 | int err; |
| 91 | 91 | |
| 92 | 92 | ch = kzalloc(sizeof(*ch) + sizeof_priv, GFP_KERNEL); |
| 93 | − if (!ch) { | |
| 94 | − err = -ENOMEM; | |
| 95 | − goto err_alloc_ch; | |
| 96 | − } | |
| 93 | + if (!ch) | |
| 94 | + return NULL; | |
| 97 | 95 | |
| 98 | 96 | counter = &ch->counter; |
| 99 | 97 | dev = &counter->dev; |
| @@ -123,9 +121,8 @@ err_chrdev_add: · 23 unmodified lines | ||
| 123 | 121 | err_ida_alloc: |
| 124 | 122 | |
| 125 | 123 | kfree(ch); |
| 126 | −err_alloc_ch: | |
| 127 | 124 | |
| 128 | − return ERR_PTR(err); | |
| 125 | + return NULL; | |
| 129 | 126 | } |
| 130 | 127 | EXPORT_SYMBOL_GPL(counter_alloc); |
| 131 | 128 | |
| @@ -208,12 +205,12 @@ struct counter_device *devm_counter_alloc(struct device *dev, size_t sizeof_priv · 76 unmodified lines | ||
| 208 | 205 | int err; |
| 209 | 206 | |
| 210 | 207 | counter = counter_alloc(sizeof_priv); |
| 211 | − if (IS_ERR(counter)) | |
| 212 | − return counter; | |
| 208 | + if (!counter) | |
| 209 | + return NULL; | |
| 213 | 210 | |
| 214 | 211 | err = devm_add_action_or_reset(dev, devm_counter_put, counter); |
| 215 | 212 | if (err < 0) |
| 216 | − return ERR_PTR(err); | |
| 213 | + return NULL; | |
| 217 | 214 | |
| 218 | 215 | return counter; |
| 219 | 216 | } |
| @@ -722,6 +722,13 @@ void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr, · 721 unmodified lines | ||
| 722 | 722 | systab_hdr->revision >> 16, |
| 723 | 723 | systab_hdr->revision & 0xffff, |
| 724 | 724 | vendor); |
| 725 | + | |
| 726 | + if (IS_ENABLED(CONFIG_X86_64) && | |
| 727 | + systab_hdr->revision > EFI_1_10_SYSTEM_TABLE_REVISION && | |
| 728 | + !strcmp(vendor, "Apple")) { | |
| 729 | + pr_info("Apple Mac detected, using EFI v1.10 runtime services only\n"); | |
| 730 | + efi.runtime_version = EFI_1_10_SYSTEM_TABLE_REVISION; | |
| 731 | + } | |
| 725 | 732 | } |
| 726 | 733 | |
| 727 | 734 | static __initdata char memory_type_name[][13] = { |
| @@ -119,9 +119,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, · 118 unmodified lines | ||
| 119 | 119 | if (image->image_base != _text) |
| 120 | 120 | efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n"); |
| 121 | 121 | |
| 122 | − if (!IS_ALIGNED((u64)_text, EFI_KIMG_ALIGN)) | |
| 123 | − efi_err("FIRMWARE BUG: kernel image not aligned on %ldk boundary\n", | |
| 124 | − EFI_KIMG_ALIGN >> 10); | |
| 122 | + if (!IS_ALIGNED((u64)_text, SEGMENT_ALIGN)) | |
| 123 | + efi_err("FIRMWARE BUG: kernel image not aligned on %dk boundary\n", | |
| 124 | + SEGMENT_ALIGN >> 10); | |
| 125 | 125 | |
| 126 | 126 | kernel_size = _edata - _text; |
| 127 | 127 | kernel_memsize = kernel_size + (_end - _edata); |
| @@ -816,7 +816,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, · 815 unmodified lines | ||
| 816 | 816 | |
| 817 | 817 | properties[prop_idx++] = PROPERTY_ENTRY_U32("ngpios", bank->num_lines); |
| 818 | 818 | |
| 819 | − if (bank->label) | |
| 819 | + if (bank->label && (strlen(bank->label) > 0)) | |
| 820 | 820 | properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label", |
| 821 | 821 | bank->label); |
| 822 | 822 | |
| @@ -1525,6 +1525,87 @@ static const u16 amdgpu_unsupported_pciidlist[] = { · 1524 unmodified lines | ||
| 1525 | 1525 | 0x99A0, |
| 1526 | 1526 | 0x99A2, |
| 1527 | 1527 | 0x99A4, |
| 1528 | + /* radeon secondary ids */ | |
| 1529 | + 0x3171, | |
| 1530 | + 0x3e70, | |
| 1531 | + 0x4164, | |
| 1532 | + 0x4165, | |
| 1533 | + 0x4166, | |
| 1534 | + 0x4168, | |
| 1535 | + 0x4170, | |
| 1536 | + 0x4171, | |
| 1537 | + 0x4172, | |
| 1538 | + 0x4173, | |
| 1539 | + 0x496e, | |
| 1540 | + 0x4a69, | |
| 1541 | + 0x4a6a, | |
| 1542 | + 0x4a6b, | |
| 1543 | + 0x4a70, | |
| 1544 | + 0x4a74, | |
| 1545 | + 0x4b69, | |
| 1546 | + 0x4b6b, | |
| 1547 | + 0x4b6c, | |
| 1548 | + 0x4c6e, | |
| 1549 | + 0x4e64, | |
| 1550 | + 0x4e65, | |
| 1551 | + 0x4e66, | |
| 1552 | + 0x4e67, | |
| 1553 | + 0x4e68, | |
| 1554 | + 0x4e69, | |
| 1555 | + 0x4e6a, | |
| 1556 | + 0x4e71, | |
| 1557 | + 0x4f73, | |
| 1558 | + 0x5569, | |
| 1559 | + 0x556b, | |
| 1560 | + 0x556d, | |
| 1561 | + 0x556f, | |
| 1562 | + 0x5571, | |
| 1563 | + 0x5854, | |
| 1564 | + 0x5874, | |
| 1565 | + 0x5940, | |
| 1566 | + 0x5941, | |
| 1567 | + 0x5b72, | |
| 1568 | + 0x5b73, | |
| 1569 | + 0x5b74, | |
| 1570 | + 0x5b75, | |
| 1571 | + 0x5d44, | |
| 1572 | + 0x5d45, | |
| 1573 | + 0x5d6d, | |
| 1574 | + 0x5d6f, | |
| 1575 | + 0x5d72, | |
| 1576 | + 0x5d77, | |
| 1577 | + 0x5e6b, | |
| 1578 | + 0x5e6d, | |
| 1579 | + 0x7120, | |
| 1580 | + 0x7124, | |
| 1581 | + 0x7129, | |
| 1582 | + 0x712e, | |
| 1583 | + 0x712f, | |
| 1584 | + 0x7162, | |
| 1585 | + 0x7163, | |
| 1586 | + 0x7166, | |
| 1587 | + 0x7167, | |
| 1588 | + 0x7172, | |
| 1589 | + 0x7173, | |
| 1590 | + 0x71a0, | |
| 1591 | + 0x71a1, | |
| 1592 | + 0x71a3, | |
| 1593 | + 0x71a7, | |
| 1594 | + 0x71bb, | |
| 1595 | + 0x71e0, | |
| 1596 | + 0x71e1, | |
| 1597 | + 0x71e2, | |
| 1598 | + 0x71e6, | |
| 1599 | + 0x71e7, | |
| 1600 | + 0x71f2, | |
| 1601 | + 0x7269, | |
| 1602 | + 0x726b, | |
| 1603 | + 0x726e, | |
| 1604 | + 0x72a0, | |
| 1605 | + 0x72a8, | |
| 1606 | + 0x72b1, | |
| 1607 | + 0x72b3, | |
| 1608 | + 0x793f, | |
| 1528 | 1609 | }; |
| 1529 | 1610 | |
| 1530 | 1611 | static const struct pci_device_id pciidlist[] = { |
| @@ -2033,10 +2033,10 @@ static void calculate_bandwidth( · 2032 unmodified lines | ||
| 2033 | 2033 | kfree(surface_type); |
| 2034 | 2034 | free_tiling_mode: |
| 2035 | 2035 | kfree(tiling_mode); |
| 2036 | −free_yclk: | |
| 2037 | − kfree(yclk); | |
| 2038 | 2036 | free_sclk: |
| 2039 | 2037 | kfree(sclk); |
| 2038 | +free_yclk: | |
| 2039 | + kfree(yclk); | |
| 2040 | 2040 | } |
| 2041 | 2041 | |
| 2042 | 2042 | /******************************************************************************* |
| @@ -503,7 +503,6 @@ static void dcn_bw_calc_rq_dlg_ttu( · 502 unmodified lines | ||
| 503 | 503 | //input[in_idx].dout.output_standard; |
| 504 | 504 | |
| 505 | 505 | /*todo: soc->sr_enter_plus_exit_time??*/ |
| 506 | − dlg_sys_param->t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep; | |
| 507 | 506 | |
| 508 | 507 | dml1_rq_dlg_get_rq_params(dml, rq_param, &input->pipe.src); |
| 509 | 508 | dml1_extract_rq_regs(dml, rq_regs, rq_param); |
| @@ -1404,20 +1404,34 @@ static void program_timing_sync( · 1403 unmodified lines | ||
| 1404 | 1404 | status->timing_sync_info.master = false; |
| 1405 | 1405 | |
| 1406 | 1406 | } |
| 1407 | − /* remove any other unblanked pipes as they have already been synced */ | |
| 1408 | − for (j = j + 1; j < group_size; j++) { | |
| 1409 | − bool is_blanked; | |
| 1410 | 1407 | |
| 1411 | − if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked) | |
| 1412 | − is_blanked = | |
| 1413 | − pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp); | |
| 1414 | − else | |
| 1415 | − is_blanked = | |
| 1416 | − pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg); | |
| 1417 | − if (!is_blanked) { | |
| 1418 | − group_size--; | |
| 1419 | − pipe_set[j] = pipe_set[group_size]; | |
| 1420 | − j--; | |
| 1408 | + /* remove any other pipes that are already been synced */ | |
| 1409 | + if (dc->config.use_pipe_ctx_sync_logic) { | |
| 1410 | + /* check pipe's syncd to decide which pipe to be removed */ | |
| 1411 | + for (j = 1; j < group_size; j++) { | |
| 1412 | + if (pipe_set[j]->pipe_idx_syncd == pipe_set[0]->pipe_idx_syncd) { | |
| 1413 | + group_size--; | |
| 1414 | + pipe_set[j] = pipe_set[group_size]; | |
| 1415 | + j--; | |
| 1416 | + } else | |
| 1417 | + /* link slave pipe's syncd with master pipe */ | |
| 1418 | + pipe_set[j]->pipe_idx_syncd = pipe_set[0]->pipe_idx_syncd; | |
| 1419 | + } | |
| 1420 | + } else { | |
| 1421 | + for (j = j + 1; j < group_size; j++) { | |
| 1422 | + bool is_blanked; | |
| 1423 | + | |
| 1424 | + if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked) | |
| 1425 | + is_blanked = | |
| 1426 | + pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp); | |
| 1427 | + else | |
| 1428 | + is_blanked = | |
| 1429 | + pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg); | |
| 1430 | + if (!is_blanked) { | |
| 1431 | + group_size--; | |
| 1432 | + pipe_set[j] = pipe_set[group_size]; | |
| 1433 | + j--; | |
| 1434 | + } | |
| 1421 | 1435 | } |
| 1422 | 1436 | } |
| 1423 | 1437 | |
| @@ -202,7 +202,7 @@ void dp_wait_for_training_aux_rd_interval( · 201 unmodified lines | ||
| 202 | 202 | uint32_t wait_in_micro_secs) |
| 203 | 203 | { |
| 204 | 204 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 205 | − if (wait_in_micro_secs > 16000) | |
| 205 | + if (wait_in_micro_secs > 1000) | |
| 206 | 206 | msleep(wait_in_micro_secs/1000); |
| 207 | 207 | else |
| 208 | 208 | udelay(wait_in_micro_secs); |
| @@ -6935,7 +6935,7 @@ bool dpcd_write_128b_132b_sst_payload_allocation_table( · 6726 unmodified lines | ||
| 6935 | 6935 | } |
| 6936 | 6936 | } |
| 6937 | 6937 | retries++; |
| 6938 | − udelay(5000); | |
| 6938 | + msleep(5); | |
| 6939 | 6939 | } |
| 6940 | 6940 | |
| 6941 | 6941 | if (!result && retries == max_retries) { |
| @@ -6987,7 +6987,7 @@ bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link) · 45 unmodified lines | ||
| 6987 | 6987 | break; |
| 6988 | 6988 | } |
| 6989 | 6989 | |
| 6990 | − udelay(5000); | |
| 6990 | + msleep(5); | |
| 6991 | 6991 | } |
| 6992 | 6992 | |
| 6993 | 6993 | if (result == ACT_FAILED) { |
| @@ -3217,6 +3217,60 @@ struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt( · 3216 unmodified lines | ||
| 3217 | 3217 | } |
| 3218 | 3218 | #endif |
| 3219 | 3219 | |
| 3220 | +void reset_syncd_pipes_from_disabled_pipes(struct dc *dc, | |
| 3221 | + struct dc_state *context) | |
| 3222 | +{ | |
| 3223 | + int i, j; | |
| 3224 | + struct pipe_ctx *pipe_ctx_old, *pipe_ctx, *pipe_ctx_syncd; | |
| 3225 | + | |
| 3226 | + /* If pipe backend is reset, need to reset pipe syncd status */ | |
| 3227 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 3228 | + pipe_ctx_old = &dc->current_state->res_ctx.pipe_ctx[i]; | |
| 3229 | + pipe_ctx = &context->res_ctx.pipe_ctx[i]; | |
| 3230 | + | |
| 3231 | + if (!pipe_ctx_old->stream) | |
| 3232 | + continue; | |
| 3233 | + | |
| 3234 | + if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe) | |
| 3235 | + continue; | |
| 3236 | + | |
| 3237 | + if (!pipe_ctx->stream || | |
| 3238 | + pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { | |
| 3239 | + | |
| 3240 | + /* Reset all the syncd pipes from the disabled pipe */ | |
| 3241 | + for (j = 0; j < dc->res_pool->pipe_count; j++) { | |
| 3242 | + pipe_ctx_syncd = &context->res_ctx.pipe_ctx[j]; | |
| 3243 | + if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_syncd) == pipe_ctx_old->pipe_idx) || | |
| 3244 | + !IS_PIPE_SYNCD_VALID(pipe_ctx_syncd)) | |
| 3245 | + SET_PIPE_SYNCD_TO_PIPE(pipe_ctx_syncd, j); | |
| 3246 | + } | |
| 3247 | + } | |
| 3248 | + } | |
| 3249 | +} | |
| 3250 | + | |
| 3251 | +void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc, | |
| 3252 | + struct dc_state *context, | |
| 3253 | + uint8_t disabled_master_pipe_idx) | |
| 3254 | +{ | |
| 3255 | + int i; | |
| 3256 | + struct pipe_ctx *pipe_ctx, *pipe_ctx_check; | |
| 3257 | + | |
| 3258 | + pipe_ctx = &context->res_ctx.pipe_ctx[disabled_master_pipe_idx]; | |
| 3259 | + if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx) != disabled_master_pipe_idx) || | |
| 3260 | + !IS_PIPE_SYNCD_VALID(pipe_ctx)) | |
| 3261 | + SET_PIPE_SYNCD_TO_PIPE(pipe_ctx, disabled_master_pipe_idx); | |
| 3262 | + | |
| 3263 | + /* for the pipe disabled, check if any slave pipe exists and assert */ | |
| 3264 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 3265 | + pipe_ctx_check = &context->res_ctx.pipe_ctx[i]; | |
| 3266 | + | |
| 3267 | + if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_check) == disabled_master_pipe_idx) && | |
| 3268 | + IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx)) | |
| 3269 | + DC_ERR("DC: Failure: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n", | |
| 3270 | + i, disabled_master_pipe_idx); | |
| 3271 | + } | |
| 3272 | +} | |
| 3273 | + | |
| 3220 | 3274 | uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter) |
| 3221 | 3275 | { |
| 3222 | 3276 | /* TODO - get transmitter to phy idx mapping from DMUB */ |
| @@ -344,6 +344,7 @@ struct dc_config { · 343 unmodified lines | ||
| 344 | 344 | uint8_t vblank_alignment_max_frame_time_diff; |
| 345 | 345 | bool is_asymmetric_memory; |
| 346 | 346 | bool is_single_rank_dimm; |
| 347 | + bool use_pipe_ctx_sync_logic; | |
| 347 | 348 | }; |
| 348 | 349 | |
| 349 | 350 | enum visual_confirm { |
| @@ -1566,6 +1566,10 @@ static enum dc_status apply_single_controller_ctx_to_hw( · 1565 unmodified lines | ||
| 1566 | 1566 | &pipe_ctx->stream->audio_info); |
| 1567 | 1567 | } |
| 1568 | 1568 | |
| 1569 | + /* make sure no pipes syncd to the pipe being enabled */ | |
| 1570 | + if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic) | |
| 1571 | + check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx); | |
| 1572 | + | |
| 1569 | 1573 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 1570 | 1574 | /* DCN3.1 FPGA Workaround |
| 1571 | 1575 | * Need to enable HPO DP Stream Encoder before setting OTG master enable. |
| @@ -1604,7 +1608,7 @@ static enum dc_status apply_single_controller_ctx_to_hw( · 32 unmodified lines | ||
| 1604 | 1608 | pipe_ctx->stream_res.stream_enc, |
| 1605 | 1609 | pipe_ctx->stream_res.tg->inst); |
| 1606 | 1610 | |
| 1607 | − if (dc_is_dp_signal(pipe_ctx->stream->signal) && | |
| 1611 | + if (dc_is_embedded_signal(pipe_ctx->stream->signal) && | |
| 1608 | 1612 | pipe_ctx->stream_res.stream_enc->funcs->reset_fifo) |
| 1609 | 1613 | pipe_ctx->stream_res.stream_enc->funcs->reset_fifo( |
| 1610 | 1614 | pipe_ctx->stream_res.stream_enc); |
| @@ -2297,6 +2301,10 @@ enum dc_status dce110_apply_ctx_to_hw( · 686 unmodified lines | ||
| 2297 | 2301 | enum dc_status status; |
| 2298 | 2302 | int i; |
| 2299 | 2303 | |
| 2304 | + /* reset syncd pipes from disabled pipes */ | |
| 2305 | + if (dc->config.use_pipe_ctx_sync_logic) | |
| 2306 | + reset_syncd_pipes_from_disabled_pipes(dc, context); | |
| 2307 | + | |
| 2300 | 2308 | /* Reset old context */ |
| 2301 | 2309 | /* look up the targets that have been removed since last commit */ |
| 2302 | 2310 | hws->funcs.reset_hw_ctx_wrap(dc, context); |
| @@ -1878,7 +1878,6 @@ noinline bool dcn30_internal_validate_bw( · 1877 unmodified lines | ||
| 1878 | 1878 | dc->res_pool->funcs->update_soc_for_wm_a(dc, context); |
| 1879 | 1879 | pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate); |
| 1880 | 1880 | |
| 1881 | − DC_FP_START(); | |
| 1882 | 1881 | if (!pipe_cnt) { |
| 1883 | 1882 | out = true; |
| 1884 | 1883 | goto validate_out; |
| @@ -2104,7 +2103,6 @@ validate_fail: · 219 unmodified lines | ||
| 2104 | 2103 | out = false; |
| 2105 | 2104 | |
| 2106 | 2105 | validate_out: |
| 2107 | − DC_FP_END(); | |
| 2108 | 2106 | return out; |
| 2109 | 2107 | } |
| 2110 | 2108 | |
| @@ -2306,7 +2304,9 @@ bool dcn30_validate_bandwidth(struct dc *dc, · 195 unmodified lines | ||
| 2306 | 2304 | |
| 2307 | 2305 | BW_VAL_TRACE_COUNT(); |
| 2308 | 2306 | |
| 2307 | + DC_FP_START(); | |
| 2309 | 2308 | out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate); |
| 2309 | + DC_FP_END(); | |
| 2310 | 2310 | |
| 2311 | 2311 | if (pipe_cnt == 0) |
| 2312 | 2312 | goto validate_out; |
| @@ -686,7 +686,7 @@ static const struct dc_debug_options debug_defaults_drv = { · 685 unmodified lines | ||
| 686 | 686 | .disable_clock_gate = true, |
| 687 | 687 | .disable_pplib_clock_request = true, |
| 688 | 688 | .disable_pplib_wm_range = true, |
| 689 | − .pipe_split_policy = MPC_SPLIT_DYNAMIC, | |
| 689 | + .pipe_split_policy = MPC_SPLIT_AVOID, | |
| 690 | 690 | .force_single_disp_pipe_split = false, |
| 691 | 691 | .disable_dcc = DCC_ENABLE, |
| 692 | 692 | .vsr_support = true, |
| @@ -1380,6 +1380,17 @@ static void set_wm_ranges( · 687 unmodified lines | ||
| 1380 | 1380 | pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges); |
| 1381 | 1381 | } |
| 1382 | 1382 | |
| 1383 | +static void dcn301_calculate_wm_and_dlg( | |
| 1384 | + struct dc *dc, struct dc_state *context, | |
| 1385 | + display_e2e_pipe_params_st *pipes, | |
| 1386 | + int pipe_cnt, | |
| 1387 | + int vlevel) | |
| 1388 | +{ | |
| 1389 | + DC_FP_START(); | |
| 1390 | + dcn301_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel); | |
| 1391 | + DC_FP_END(); | |
| 1392 | +} | |
| 1393 | + | |
| 1383 | 1394 | static struct resource_funcs dcn301_res_pool_funcs = { |
| 1384 | 1395 | .destroy = dcn301_destroy_resource_pool, |
| 1385 | 1396 | .link_enc_create = dcn301_link_encoder_create, |
| @@ -2260,6 +2260,9 @@ static bool dcn31_resource_construct( · 2259 unmodified lines | ||
| 2260 | 2260 | dc->caps.color.mpc.ogam_rom_caps.hlg = 0; |
| 2261 | 2261 | dc->caps.color.mpc.ocsc = 1; |
| 2262 | 2262 | |
| 2263 | + /* Use pipe context based otg sync logic */ | |
| 2264 | + dc->config.use_pipe_ctx_sync_logic = true; | |
| 2265 | + | |
| 2263 | 2266 | /* read VBIOS LTTPR caps */ |
| 2264 | 2267 | { |
| 2265 | 2268 | if (ctx->dc_bios->funcs->get_lttpr_caps) { |
| @@ -1576,8 +1576,6 @@ void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, · 1575 unmodified lines | ||
| 1576 | 1576 | dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, |
| 1577 | 1577 | e2e_pipe_param, |
| 1578 | 1578 | num_pipes); |
| 1579 | − dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency | |
| 1580 | − / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated | |
| 1581 | 1579 | |
| 1582 | 1580 | print__dlg_sys_params_st(mode_lib, &dlg_sys_param); |
| 1583 | 1581 | |
| @@ -1577,8 +1577,6 @@ void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, · 1576 unmodified lines | ||
| 1577 | 1577 | dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, |
| 1578 | 1578 | e2e_pipe_param, |
| 1579 | 1579 | num_pipes); |
| 1580 | − dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency | |
| 1581 | − / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated | |
| 1582 | 1580 | |
| 1583 | 1581 | print__dlg_sys_params_st(mode_lib, &dlg_sys_param); |
| 1584 | 1582 | |
| @@ -1688,8 +1688,6 @@ void dml21_rq_dlg_get_dlg_reg( · 1687 unmodified lines | ||
| 1688 | 1688 | mode_lib, |
| 1689 | 1689 | e2e_pipe_param, |
| 1690 | 1690 | num_pipes); |
| 1691 | − dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency | |
| 1692 | − / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated | |
| 1693 | 1691 | |
| 1694 | 1692 | print__dlg_sys_params_st(mode_lib, &dlg_sys_param); |
| 1695 | 1693 | |
| @@ -1858,8 +1858,6 @@ void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, · 1857 unmodified lines | ||
| 1858 | 1858 | dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, |
| 1859 | 1859 | e2e_pipe_param, |
| 1860 | 1860 | num_pipes); |
| 1861 | − dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency | |
| 1862 | − / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated | |
| 1863 | 1861 | |
| 1864 | 1862 | print__dlg_sys_params_st(mode_lib, &dlg_sys_param); |
| 1865 | 1863 | |
| @@ -327,7 +327,7 @@ void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info) · 326 unmodified lines | ||
| 327 | 327 | dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | −void dcn301_calculate_wm_and_dlg(struct dc *dc, | |
| 330 | +void dcn301_calculate_wm_and_dlg_fp(struct dc *dc, | |
| 331 | 331 | struct dc_state *context, |
| 332 | 332 | display_e2e_pipe_params_st *pipes, |
| 333 | 333 | int pipe_cnt, |
| @@ -34,7 +34,7 @@ void dcn301_fpu_set_wm_ranges(int i, · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info); |
| 36 | 36 | |
| 37 | −void dcn301_calculate_wm_and_dlg(struct dc *dc, | |
| 37 | +void dcn301_calculate_wm_and_dlg_fp(struct dc *dc, | |
| 38 | 38 | struct dc_state *context, |
| 39 | 39 | display_e2e_pipe_params_st *pipes, |
| 40 | 40 | int pipe_cnt, |
| @@ -546,7 +546,6 @@ struct _vcs_dpi_display_dlg_sys_params_st { · 545 unmodified lines | ||
| 546 | 546 | double t_sr_wm_us; |
| 547 | 547 | double t_extra_us; |
| 548 | 548 | double mem_trip_us; |
| 549 | − double t_srx_delay_us; | |
| 550 | 549 | double deepsleep_dcfclk_mhz; |
| 551 | 550 | double total_flip_bw; |
| 552 | 551 | unsigned int total_flip_bytes; |
| @@ -141,9 +141,6 @@ void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _v · 140 unmodified lines | ||
| 141 | 141 | dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param->t_urg_wm_us); |
| 142 | 142 | dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param->t_sr_wm_us); |
| 143 | 143 | dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param->t_extra_us); |
| 144 | − dml_print( | |
| 145 | − "DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n", | |
| 146 | − dlg_sys_param->t_srx_delay_us); | |
| 147 | 144 | dml_print( |
| 148 | 145 | "DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n", |
| 149 | 146 | dlg_sys_param->deepsleep_dcfclk_mhz); |
| @@ -1331,10 +1331,6 @@ void dml1_rq_dlg_get_dlg_params( · 1330 unmodified lines | ||
| 1331 | 1331 | if (dual_plane) |
| 1332 | 1332 | DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c); |
| 1333 | 1333 | |
| 1334 | − DTRACE( | |
| 1335 | − "DLG: %s: t_srx_delay_us = %3.2f", | |
| 1336 | − __func__, | |
| 1337 | − (double) dlg_sys_param->t_srx_delay_us); | |
| 1338 | 1334 | DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); |
| 1339 | 1335 | DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); |
| 1340 | 1336 | DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); |
| @@ -382,6 +382,7 @@ struct pipe_ctx { · 381 unmodified lines | ||
| 382 | 382 | struct pll_settings pll_settings; |
| 383 | 383 | |
| 384 | 384 | uint8_t pipe_idx; |
| 385 | + uint8_t pipe_idx_syncd; | |
| 385 | 386 | |
| 386 | 387 | struct pipe_ctx *top_pipe; |
| 387 | 388 | struct pipe_ctx *bottom_pipe; |
| @@ -34,6 +34,10 @@ · 33 unmodified lines | ||
| 34 | 34 | #define MEMORY_TYPE_HBM 2 |
| 35 | 35 | |
| 36 | 36 | |
| 37 | +#define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0) | |
| 38 | +#define GET_PIPE_SYNCD_FROM_PIPE(pipe) ((pipe)->pipe_idx_syncd & 0x7F) | |
| 39 | +#define SET_PIPE_SYNCD_TO_PIPE(pipe, pipe_syncd) ((pipe)->pipe_idx_syncd = (0x80 | pipe_syncd)) | |
| 40 | + | |
| 37 | 41 | enum dce_version resource_parse_asic_id( |
| 38 | 42 | struct hw_asic_id asic_id); |
| 39 | 43 | |
| @@ -208,6 +212,13 @@ struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt( · 168 unmodified lines | ||
| 208 | 212 | const struct dc_link *link); |
| 209 | 213 | #endif |
| 210 | 214 | |
| 215 | +void reset_syncd_pipes_from_disabled_pipes(struct dc *dc, | |
| 216 | + struct dc_state *context); | |
| 217 | + | |
| 218 | +void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc, | |
| 219 | + struct dc_state *context, | |
| 220 | + uint8_t disabled_master_pipe_idx); | |
| 221 | + | |
| 211 | 222 | uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter); |
| 212 | 223 | |
| 213 | 224 | #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ |
| @@ -282,8 +282,6 @@ static const struct ast_vbios_enhtable res_1360x768[] = { · 281 unmodified lines | ||
| 282 | 282 | }; |
| 283 | 283 | |
| 284 | 284 | static const struct ast_vbios_enhtable res_1600x900[] = { |
| 285 | − {1800, 1600, 24, 80, 1000, 900, 1, 3, VCLK108, /* 60Hz */ | |
| 286 | − (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo), 60, 3, 0x3A }, | |
| 287 | 285 | {1760, 1600, 48, 32, 926, 900, 3, 5, VCLK97_75, /* 60Hz CVT RB */ |
| 288 | 286 | (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | |
| 289 | 287 | AST2500PreCatchCRT), 60, 1, 0x3A }, |
| @@ -1327,8 +1327,10 @@ int drm_atomic_check_only(struct drm_atomic_state *state) · 1326 unmodified lines | ||
| 1327 | 1327 | |
| 1328 | 1328 | drm_dbg_atomic(dev, "checking %p\n", state); |
| 1329 | 1329 | |
| 1330 | − for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) | |
| 1331 | − requested_crtc |= drm_crtc_mask(crtc); | |
| 1330 | + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { | |
| 1331 | + if (new_crtc_state->enable) | |
| 1332 | + requested_crtc |= drm_crtc_mask(crtc); | |
| 1333 | + } | |
| 1332 | 1334 | |
| 1333 | 1335 | for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { |
| 1334 | 1336 | ret = drm_atomic_plane_check(old_plane_state, new_plane_state); |
| @@ -1377,8 +1379,10 @@ int drm_atomic_check_only(struct drm_atomic_state *state) · 42 unmodified lines | ||
| 1377 | 1379 | } |
| 1378 | 1380 | } |
| 1379 | 1381 | |
| 1380 | − for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) | |
| 1381 | − affected_crtc |= drm_crtc_mask(crtc); | |
| 1382 | + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { | |
| 1383 | + if (new_crtc_state->enable) | |
| 1384 | + affected_crtc |= drm_crtc_mask(crtc); | |
| 1385 | + } | |
| 1382 | 1386 | |
| 1383 | 1387 | /* |
| 1384 | 1388 | * For commits that allow modesets drivers can add other CRTCs to the |
| @@ -115,6 +115,12 @@ static const struct drm_dmi_panel_orientation_data lcd1280x1920_rightside_up = { · 114 unmodified lines | ||
| 115 | 115 | .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, |
| 116 | 116 | }; |
| 117 | 117 | |
| 118 | +static const struct drm_dmi_panel_orientation_data lcd1600x2560_leftside_up = { | |
| 119 | + .width = 1600, | |
| 120 | + .height = 2560, | |
| 121 | + .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, | |
| 122 | +}; | |
| 123 | + | |
| 118 | 124 | static const struct dmi_system_id orientation_data[] = { |
| 119 | 125 | { /* Acer One 10 (S1003) */ |
| 120 | 126 | .matches = { |
| @@ -275,6 +281,12 @@ static const struct dmi_system_id orientation_data[] = { · 154 unmodified lines | ||
| 275 | 281 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"), |
| 276 | 282 | }, |
| 277 | 283 | .driver_data = (void *)&onegx1_pro, |
| 284 | + }, { /* OneXPlayer */ | |
| 285 | + .matches = { | |
| 286 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONE-NETBOOK TECHNOLOGY CO., LTD."), | |
| 287 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"), | |
| 288 | + }, | |
| 289 | + .driver_data = (void *)&lcd1600x2560_leftside_up, | |
| 278 | 290 | }, { /* Samsung GalaxyBook 10.6 */ |
| 279 | 291 | .matches = { |
| 280 | 292 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
| @@ -33,6 +33,9 @@ static bool __init detect_thinkpad_privacy_screen(void) · 32 unmodified lines | ||
| 33 | 33 | unsigned long long output; |
| 34 | 34 | acpi_status status; |
| 35 | 35 | |
| 36 | + if (acpi_disabled) | |
| 37 | + return false; | |
| 38 | + | |
| 36 | 39 | /* Get embedded-controller handle */ |
| 37 | 40 | status = acpi_get_devices("PNP0C09", acpi_set_handle, NULL, &ec_handle); |
| 38 | 41 | if (ACPI_FAILURE(status) || !ec_handle) |
| @@ -469,8 +469,8 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, · 468 unmodified lines | ||
| 469 | 469 | return -EINVAL; |
| 470 | 470 | } |
| 471 | 471 | |
| 472 | − if (args->stream_size > SZ_64K || args->nr_relocs > SZ_64K || | |
| 473 | − args->nr_bos > SZ_64K || args->nr_pmrs > 128) { | |
| 472 | + if (args->stream_size > SZ_128K || args->nr_relocs > SZ_128K || | |
| 473 | + args->nr_bos > SZ_128K || args->nr_pmrs > 128) { | |
| 474 | 474 | DRM_ERROR("submit arguments out of size limits\n"); |
| 475 | 475 | return -EINVAL; |
| 476 | 476 | } |
| @@ -311,6 +311,7 @@ struct drm_i915_gem_object { · 310 unmodified lines | ||
| 311 | 311 | #define I915_BO_READONLY BIT(6) |
| 312 | 312 | #define I915_TILING_QUIRK_BIT 7 /* unknown swizzling; do not release! */ |
| 313 | 313 | #define I915_BO_PROTECTED BIT(8) |
| 314 | +#define I915_BO_WAS_BOUND_BIT 9 | |
| 314 | 315 | /** |
| 315 | 316 | * @mem_flags - Mutable placement-related flags |
| 316 | 317 | * |
| @@ -10,6 +10,8 @@ · 9 unmodified lines | ||
| 10 | 10 | #include "i915_gem_lmem.h" |
| 11 | 11 | #include "i915_gem_mman.h" |
| 12 | 12 | |
| 13 | +#include "gt/intel_gt.h" | |
| 14 | + | |
| 13 | 15 | void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, |
| 14 | 16 | struct sg_table *pages, |
| 15 | 17 | unsigned int sg_page_sizes) |
| @@ -221,6 +223,14 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj) · 205 unmodified lines | ||
| 221 | 223 | __i915_gem_object_reset_page_iter(obj); |
| 222 | 224 | obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0; |
| 223 | 225 | |
| 226 | + if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) { | |
| 227 | + struct drm_i915_private *i915 = to_i915(obj->base.dev); | |
| 228 | + intel_wakeref_t wakeref; | |
| 229 | + | |
| 230 | + with_intel_runtime_pm_if_active(&i915->runtime_pm, wakeref) | |
| 231 | + intel_gt_invalidate_tlbs(to_gt(i915)); | |
| 232 | + } | |
| 233 | + | |
| 224 | 234 | return pages; |
| 225 | 235 | } |
| 226 | 236 | |
| @@ -29,6 +29,8 @@ void __intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) · 28 unmodified lines | ||
| 29 | 29 | { |
| 30 | 30 | spin_lock_init(>->irq_lock); |
| 31 | 31 | |
| 32 | + mutex_init(>->tlb_invalidate_lock); | |
| 33 | + | |
| 32 | 34 | INIT_LIST_HEAD(>->closed_vma); |
| 33 | 35 | spin_lock_init(>->closed_lock); |
| 34 | 36 | |
| @@ -912,3 +914,109 @@ void intel_gt_info_print(const struct intel_gt_info *info, · 877 unmodified lines | ||
| 912 | 914 | |
| 913 | 915 | intel_sseu_dump(&info->sseu, p); |
| 914 | 916 | } |
| 917 | + | |
| 918 | +struct reg_and_bit { | |
| 919 | + i915_reg_t reg; | |
| 920 | + u32 bit; | |
| 921 | +}; | |
| 922 | + | |
| 923 | +static struct reg_and_bit | |
| 924 | +get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8, | |
| 925 | + const i915_reg_t *regs, const unsigned int num) | |
| 926 | +{ | |
| 927 | + const unsigned int class = engine->class; | |
| 928 | + struct reg_and_bit rb = { }; | |
| 929 | + | |
| 930 | + if (drm_WARN_ON_ONCE(&engine->i915->drm, | |
| 931 | + class >= num || !regs[class].reg)) | |
| 932 | + return rb; | |
| 933 | + | |
| 934 | + rb.reg = regs[class]; | |
| 935 | + if (gen8 && class == VIDEO_DECODE_CLASS) | |
| 936 | + rb.reg.reg += 4 * engine->instance; /* GEN8_M2TCR */ | |
| 937 | + else | |
| 938 | + rb.bit = engine->instance; | |
| 939 | + | |
| 940 | + rb.bit = BIT(rb.bit); | |
| 941 | + | |
| 942 | + return rb; | |
| 943 | +} | |
| 944 | + | |
| 945 | +void intel_gt_invalidate_tlbs(struct intel_gt *gt) | |
| 946 | +{ | |
| 947 | + static const i915_reg_t gen8_regs[] = { | |
| 948 | + [RENDER_CLASS] = GEN8_RTCR, | |
| 949 | + [VIDEO_DECODE_CLASS] = GEN8_M1TCR, /* , GEN8_M2TCR */ | |
| 950 | + [VIDEO_ENHANCEMENT_CLASS] = GEN8_VTCR, | |
| 951 | + [COPY_ENGINE_CLASS] = GEN8_BTCR, | |
| 952 | + }; | |
| 953 | + static const i915_reg_t gen12_regs[] = { | |
| 954 | + [RENDER_CLASS] = GEN12_GFX_TLB_INV_CR, | |
| 955 | + [VIDEO_DECODE_CLASS] = GEN12_VD_TLB_INV_CR, | |
| 956 | + [VIDEO_ENHANCEMENT_CLASS] = GEN12_VE_TLB_INV_CR, | |
| 957 | + [COPY_ENGINE_CLASS] = GEN12_BLT_TLB_INV_CR, | |
| 958 | + }; | |
| 959 | + struct drm_i915_private *i915 = gt->i915; | |
| 960 | + struct intel_uncore *uncore = gt->uncore; | |
| 961 | + struct intel_engine_cs *engine; | |
| 962 | + enum intel_engine_id id; | |
| 963 | + const i915_reg_t *regs; | |
| 964 | + unsigned int num = 0; | |
| 965 | + | |
| 966 | + if (I915_SELFTEST_ONLY(gt->awake == -ENODEV)) | |
| 967 | + return; | |
| 968 | + | |
| 969 | + if (GRAPHICS_VER(i915) == 12) { | |
| 970 | + regs = gen12_regs; | |
| 971 | + num = ARRAY_SIZE(gen12_regs); | |
| 972 | + } else if (GRAPHICS_VER(i915) >= 8 && GRAPHICS_VER(i915) <= 11) { | |
| 973 | + regs = gen8_regs; | |
| 974 | + num = ARRAY_SIZE(gen8_regs); | |
| 975 | + } else if (GRAPHICS_VER(i915) < 8) { | |
| 976 | + return; | |
| 977 | + } | |
| 978 | + | |
| 979 | + if (drm_WARN_ONCE(&i915->drm, !num, | |
| 980 | + "Platform does not implement TLB invalidation!")) | |
| 981 | + return; | |
| 982 | + | |
| 983 | + GEM_TRACE("\n"); | |
| 984 | + | |
| 985 | + assert_rpm_wakelock_held(&i915->runtime_pm); | |
| 986 | + | |
| 987 | + mutex_lock(>->tlb_invalidate_lock); | |
| 988 | + intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); | |
| 989 | + | |
| 990 | + for_each_engine(engine, gt, id) { | |
| 991 | + /* | |
| 992 | + * HW architecture suggest typical invalidation time at 40us, | |
| 993 | + * with pessimistic cases up to 100us and a recommendation to | |
| 994 | + * cap at 1ms. We go a bit higher just in case. | |
| 995 | + */ | |
| 996 | + const unsigned int timeout_us = 100; | |
| 997 | + const unsigned int timeout_ms = 4; | |
| 998 | + struct reg_and_bit rb; | |
| 999 | + | |
| 1000 | + rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); | |
| 1001 | + if (!i915_mmio_reg_offset(rb.reg)) | |
| 1002 | + continue; | |
| 1003 | + | |
| 1004 | + intel_uncore_write_fw(uncore, rb.reg, rb.bit); | |
| 1005 | + if (__intel_wait_for_register_fw(uncore, | |
| 1006 | + rb.reg, rb.bit, 0, | |
| 1007 | + timeout_us, timeout_ms, | |
| 1008 | + NULL)) | |
| 1009 | + drm_err_ratelimited(>->i915->drm, | |
| 1010 | + "%s TLB invalidation did not complete in %ums!\n", | |
| 1011 | + engine->name, timeout_ms); | |
| 1012 | + } | |
| 1013 | + | |
| 1014 | + /* | |
| 1015 | + * Use delayed put since a) we mostly expect a flurry of TLB | |
| 1016 | + * invalidations so it is good to avoid paying the forcewake cost and | |
| 1017 | + * b) it works around a bug in Icelake which cannot cope with too rapid | |
| 1018 | + * transitions. | |
| 1019 | + */ | |
| 1020 | + intel_uncore_forcewake_put_delayed(uncore, FORCEWAKE_ALL); | |
| 1021 | + mutex_unlock(>->tlb_invalidate_lock); | |
| 1022 | +} | |
| @@ -91,4 +91,6 @@ void intel_gt_info_print(const struct intel_gt_info *info, · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | void intel_gt_watchdog_work(struct work_struct *work); |
| 93 | 93 | |
| 94 | +void intel_gt_invalidate_tlbs(struct intel_gt *gt); | |
| 95 | + | |
| 94 | 96 | #endif /* __INTEL_GT_H__ */ |
| @@ -73,6 +73,8 @@ struct intel_gt { · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | struct intel_uc uc; |
| 75 | 75 | |
| 76 | + struct mutex tlb_invalidate_lock; | |
| 77 | + | |
| 76 | 78 | struct i915_wa_list wa_list; |
| 77 | 79 | |
| 78 | 80 | struct intel_gt_timelines { |
| @@ -2721,6 +2721,12 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) · 2720 unmodified lines | ||
| 2721 | 2721 | #define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1 << 28) |
| 2722 | 2722 | #define GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT (1 << 24) |
| 2723 | 2723 | |
| 2724 | +#define GEN8_RTCR _MMIO(0x4260) | |
| 2725 | +#define GEN8_M1TCR _MMIO(0x4264) | |
| 2726 | +#define GEN8_M2TCR _MMIO(0x4268) | |
| 2727 | +#define GEN8_BTCR _MMIO(0x426c) | |
| 2728 | +#define GEN8_VTCR _MMIO(0x4270) | |
| 2729 | + | |
| 2724 | 2730 | #if 0 |
| 2725 | 2731 | #define PRB0_TAIL _MMIO(0x2030) |
| 2726 | 2732 | #define PRB0_HEAD _MMIO(0x2034) |
| @@ -2819,6 +2825,11 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) · 92 unmodified lines | ||
| 2819 | 2825 | #define FAULT_VA_HIGH_BITS (0xf << 0) |
| 2820 | 2826 | #define FAULT_GTT_SEL (1 << 4) |
| 2821 | 2827 | |
| 2828 | +#define GEN12_GFX_TLB_INV_CR _MMIO(0xced8) | |
| 2829 | +#define GEN12_VD_TLB_INV_CR _MMIO(0xcedc) | |
| 2830 | +#define GEN12_VE_TLB_INV_CR _MMIO(0xcee0) | |
| 2831 | +#define GEN12_BLT_TLB_INV_CR _MMIO(0xcee4) | |
| 2832 | + | |
| 2822 | 2833 | #define GEN12_AUX_ERR_DBG _MMIO(0x43f4) |
| 2823 | 2834 | |
| 2824 | 2835 | #define FPGA_DBG _MMIO(0x42300) |
| @@ -457,6 +457,9 @@ int i915_vma_bind(struct i915_vma *vma, · 456 unmodified lines | ||
| 457 | 457 | vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags); |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | + if (vma->obj) | |
| 461 | + set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); | |
| 462 | + | |
| 460 | 463 | atomic_or(bind_flags, &vma->flags); |
| 461 | 464 | return 0; |
| 462 | 465 | } |
| @@ -724,7 +724,8 @@ void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore, · 723 unmodified lines | ||
| 724 | 724 | } |
| 725 | 725 | |
| 726 | 726 | static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, |
| 727 | − enum forcewake_domains fw_domains) | |
| 727 | + enum forcewake_domains fw_domains, | |
| 728 | + bool delayed) | |
| 728 | 729 | { |
| 729 | 730 | struct intel_uncore_forcewake_domain *domain; |
| 730 | 731 | unsigned int tmp; |
| @@ -739,7 +740,11 @@ static void __intel_uncore_forcewake_put(struct intel_uncore *uncore, · 8 unmodified lines | ||
| 739 | 740 | continue; |
| 740 | 741 | } |
| 741 | 742 | |
| 742 | − fw_domains_put(uncore, domain->mask); | |
| 743 | + if (delayed && | |
| 744 | + !(domain->uncore->fw_domains_timer & domain->mask)) | |
| 745 | + fw_domain_arm_timer(domain); | |
| 746 | + else | |
| 747 | + fw_domains_put(uncore, domain->mask); | |
| 743 | 748 | } |
| 744 | 749 | } |
| 745 | 750 | |
| @@ -760,7 +765,20 @@ void intel_uncore_forcewake_put(struct intel_uncore *uncore, · 14 unmodified lines | ||
| 760 | 765 | return; |
| 761 | 766 | |
| 762 | 767 | spin_lock_irqsave(&uncore->lock, irqflags); |
| 763 | − __intel_uncore_forcewake_put(uncore, fw_domains); | |
| 768 | + __intel_uncore_forcewake_put(uncore, fw_domains, false); | |
| 769 | + spin_unlock_irqrestore(&uncore->lock, irqflags); | |
| 770 | +} | |
| 771 | + | |
| 772 | +void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, | |
| 773 | + enum forcewake_domains fw_domains) | |
| 774 | +{ | |
| 775 | + unsigned long irqflags; | |
| 776 | + | |
| 777 | + if (!uncore->fw_get_funcs) | |
| 778 | + return; | |
| 779 | + | |
| 780 | + spin_lock_irqsave(&uncore->lock, irqflags); | |
| 781 | + __intel_uncore_forcewake_put(uncore, fw_domains, true); | |
| 764 | 782 | spin_unlock_irqrestore(&uncore->lock, irqflags); |
| 765 | 783 | } |
| 766 | 784 | |
| @@ -802,7 +820,7 @@ void intel_uncore_forcewake_put__locked(struct intel_uncore *uncore, · 35 unmodified lines | ||
| 802 | 820 | if (!uncore->fw_get_funcs) |
| 803 | 821 | return; |
| 804 | 822 | |
| 805 | − __intel_uncore_forcewake_put(uncore, fw_domains); | |
| 823 | + __intel_uncore_forcewake_put(uncore, fw_domains, false); | |
| 806 | 824 | } |
| 807 | 825 | |
| 808 | 826 | void assert_forcewakes_inactive(struct intel_uncore *uncore) |
| @@ -246,6 +246,8 @@ void intel_uncore_forcewake_get(struct intel_uncore *uncore, · 245 unmodified lines | ||
| 246 | 246 | enum forcewake_domains domains); |
| 247 | 247 | void intel_uncore_forcewake_put(struct intel_uncore *uncore, |
| 248 | 248 | enum forcewake_domains domains); |
| 249 | +void intel_uncore_forcewake_put_delayed(struct intel_uncore *uncore, | |
| 250 | + enum forcewake_domains domains); | |
| 249 | 251 | void intel_uncore_forcewake_flush(struct intel_uncore *uncore, |
| 250 | 252 | enum forcewake_domains fw_domains); |
| 251 | 253 | |
| @@ -1560,6 +1560,8 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) · 1559 unmodified lines | ||
| 1560 | 1560 | for (i = 0; i < gpu->nr_rings; i++) |
| 1561 | 1561 | a6xx_gpu->shadow[i] = 0; |
| 1562 | 1562 | |
| 1563 | + gpu->suspend_count++; | |
| 1564 | + | |
| 1563 | 1565 | return 0; |
| 1564 | 1566 | } |
| 1565 | 1567 | |
| @@ -608,9 +608,27 @@ static int adreno_resume(struct device *dev) · 607 unmodified lines | ||
| 608 | 608 | return gpu->funcs->pm_resume(gpu); |
| 609 | 609 | } |
| 610 | 610 | |
| 611 | +static int active_submits(struct msm_gpu *gpu) | |
| 612 | +{ | |
| 613 | + int active_submits; | |
| 614 | + mutex_lock(&gpu->active_lock); | |
| 615 | + active_submits = gpu->active_submits; | |
| 616 | + mutex_unlock(&gpu->active_lock); | |
| 617 | + return active_submits; | |
| 618 | +} | |
| 619 | + | |
| 611 | 620 | static int adreno_suspend(struct device *dev) |
| 612 | 621 | { |
| 613 | 622 | struct msm_gpu *gpu = dev_to_gpu(dev); |
| 623 | + int remaining; | |
| 624 | + | |
| 625 | + remaining = wait_event_timeout(gpu->retire_event, | |
| 626 | + active_submits(gpu) == 0, | |
| 627 | + msecs_to_jiffies(1000)); | |
| 628 | + if (remaining == 0) { | |
| 629 | + dev_err(dev, "Timeout waiting for GPU to suspend\n"); | |
| 630 | + return -EBUSY; | |
| 631 | + } | |
| 614 | 632 | |
| 615 | 633 | return gpu->funcs->pm_suspend(gpu); |
| 616 | 634 | } |
| @@ -26,9 +26,16 @@ static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx, · 25 unmodified lines | ||
| 26 | 26 | struct dpu_hw_pcc_cfg *cfg) |
| 27 | 27 | { |
| 28 | 28 | |
| 29 | − u32 base = ctx->cap->sblk->pcc.base; | |
| 29 | + u32 base; | |
| 30 | 30 | |
| 31 | − if (!ctx || !base) { | |
| 31 | + if (!ctx) { | |
| 32 | + DRM_ERROR("invalid ctx %pK\n", ctx); | |
| 33 | + return; | |
| 34 | + } | |
| 35 | + | |
| 36 | + base = ctx->cap->sblk->pcc.base; | |
| 37 | + | |
| 38 | + if (!base) { | |
| 32 | 39 | DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx, base); |
| 33 | 40 | return; |
| 34 | 41 | } |
| @@ -40,7 +40,12 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi) · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | of_node_put(phy_node); |
| 42 | 42 | |
| 43 | − if (!phy_pdev || !msm_dsi->phy) { | |
| 43 | + if (!phy_pdev) { | |
| 44 | + DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); | |
| 45 | + return -EPROBE_DEFER; | |
| 46 | + } | |
| 47 | + if (!msm_dsi->phy) { | |
| 48 | + put_device(&phy_pdev->dev); | |
| 44 | 49 | DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); |
| 45 | 50 | return -EPROBE_DEFER; |
| 46 | 51 | } |
| @@ -808,12 +808,14 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, · 807 unmodified lines | ||
| 808 | 808 | struct msm_dsi_phy_clk_request *clk_req, |
| 809 | 809 | struct msm_dsi_phy_shared_timings *shared_timings) |
| 810 | 810 | { |
| 811 | − struct device *dev = &phy->pdev->dev; | |
| 811 | + struct device *dev; | |
| 812 | 812 | int ret; |
| 813 | 813 | |
| 814 | 814 | if (!phy || !phy->cfg->ops.enable) |
| 815 | 815 | return -EINVAL; |
| 816 | 816 | |
| 817 | + dev = &phy->pdev->dev; | |
| 818 | + | |
| 817 | 819 | ret = dsi_phy_enable_resource(phy); |
| 818 | 820 | if (ret) { |
| 819 | 821 | DRM_DEV_ERROR(dev, "%s: resource enable failed, %d\n", |
| @@ -97,10 +97,15 @@ static int msm_hdmi_get_phy(struct hdmi *hdmi) · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | of_node_put(phy_node); |
| 99 | 99 | |
| 100 | − if (!phy_pdev || !hdmi->phy) { | |
| 100 | + if (!phy_pdev) { | |
| 101 | 101 | DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n"); |
| 102 | 102 | return -EPROBE_DEFER; |
| 103 | 103 | } |
| 104 | + if (!hdmi->phy) { | |
| 105 | + DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n"); | |
| 106 | + put_device(&phy_pdev->dev); | |
| 107 | + return -EPROBE_DEFER; | |
| 108 | + } | |
| 104 | 109 | |
| 105 | 110 | hdmi->phy_dev = get_device(&phy_pdev->dev); |
| 106 | 111 | |
| @@ -461,7 +461,7 @@ static int msm_init_vram(struct drm_device *dev) · 460 unmodified lines | ||
| 461 | 461 | of_node_put(node); |
| 462 | 462 | if (ret) |
| 463 | 463 | return ret; |
| 464 | − size = r.end - r.start; | |
| 464 | + size = r.end - r.start + 1; | |
| 465 | 465 | DRM_INFO("using VRAM carveout: %lx@%pa\n", size, &r.start); |
| 466 | 466 | |
| 467 | 467 | /* if we have no IOMMU, then we need to use carveout allocator. |
| @@ -510,7 +510,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) · 42 unmodified lines | ||
| 510 | 510 | struct msm_drm_private *priv = dev_get_drvdata(dev); |
| 511 | 511 | struct drm_device *ddev; |
| 512 | 512 | struct msm_kms *kms; |
| 513 | − struct msm_mdss *mdss; | |
| 514 | 513 | int ret, i; |
| 515 | 514 | |
| 516 | 515 | ddev = drm_dev_alloc(drv, dev); |
| @@ -521,8 +520,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) · 4 unmodified lines | ||
| 521 | 520 | ddev->dev_private = priv; |
| 522 | 521 | priv->dev = ddev; |
| 523 | 522 | |
| 524 | − mdss = priv->mdss; | |
| 525 | − | |
| 526 | 523 | priv->wq = alloc_ordered_workqueue("msm", 0); |
| 527 | 524 | priv->hangcheck_period = DRM_MSM_HANGCHECK_DEFAULT_PERIOD; |
| 528 | 525 | |
| @@ -703,6 +703,8 @@ static void retire_submits(struct msm_gpu *gpu) · 702 unmodified lines | ||
| 703 | 703 | } |
| 704 | 704 | } |
| 705 | 705 | } |
| 706 | + | |
| 707 | + wake_up_all(&gpu->retire_event); | |
| 706 | 708 | } |
| 707 | 709 | |
| 708 | 710 | static void retire_worker(struct kthread_work *work) |
| @@ -848,6 +850,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, · 139 unmodified lines | ||
| 848 | 850 | INIT_LIST_HEAD(&gpu->active_list); |
| 849 | 851 | mutex_init(&gpu->active_lock); |
| 850 | 852 | mutex_init(&gpu->lock); |
| 853 | + init_waitqueue_head(&gpu->retire_event); | |
| 851 | 854 | kthread_init_work(&gpu->retire_work, retire_worker); |
| 852 | 855 | kthread_init_work(&gpu->recover_work, recover_worker); |
| 853 | 856 | kthread_init_work(&gpu->fault_work, fault_worker); |
| @@ -230,6 +230,9 @@ struct msm_gpu { · 229 unmodified lines | ||
| 230 | 230 | /* work for handling GPU recovery: */ |
| 231 | 231 | struct kthread_work recover_work; |
| 232 | 232 | |
| 233 | + /** retire_event: notified when submits are retired: */ | |
| 234 | + wait_queue_head_t retire_event; | |
| 235 | + | |
| 233 | 236 | /* work for handling active-list retiring: */ |
| 234 | 237 | struct kthread_work retire_work; |
| 235 | 238 | |
| @@ -133,6 +133,18 @@ void msm_devfreq_init(struct msm_gpu *gpu) · 132 unmodified lines | ||
| 133 | 133 | CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | +static void cancel_idle_work(struct msm_gpu_devfreq *df) | |
| 137 | +{ | |
| 138 | + hrtimer_cancel(&df->idle_work.timer); | |
| 139 | + kthread_cancel_work_sync(&df->idle_work.work); | |
| 140 | +} | |
| 141 | + | |
| 142 | +static void cancel_boost_work(struct msm_gpu_devfreq *df) | |
| 143 | +{ | |
| 144 | + hrtimer_cancel(&df->boost_work.timer); | |
| 145 | + kthread_cancel_work_sync(&df->boost_work.work); | |
| 146 | +} | |
| 147 | + | |
| 136 | 148 | void msm_devfreq_cleanup(struct msm_gpu *gpu) |
| 137 | 149 | { |
| 138 | 150 | struct msm_gpu_devfreq *df = &gpu->devfreq; |
| @@ -152,7 +164,12 @@ void msm_devfreq_resume(struct msm_gpu *gpu) · 13 unmodified lines | ||
| 152 | 164 | |
| 153 | 165 | void msm_devfreq_suspend(struct msm_gpu *gpu) |
| 154 | 166 | { |
| 155 | − devfreq_suspend_device(gpu->devfreq.devfreq); | |
| 167 | + struct msm_gpu_devfreq *df = &gpu->devfreq; | |
| 168 | + | |
| 169 | + devfreq_suspend_device(df->devfreq); | |
| 170 | + | |
| 171 | + cancel_idle_work(df); | |
| 172 | + cancel_boost_work(df); | |
| 156 | 173 | } |
| 157 | 174 | |
| 158 | 175 | static void msm_devfreq_boost_work(struct kthread_work *work) |
| @@ -196,7 +213,7 @@ void msm_devfreq_active(struct msm_gpu *gpu) · 37 unmodified lines | ||
| 196 | 213 | /* |
| 197 | 214 | * Cancel any pending transition to idle frequency: |
| 198 | 215 | */ |
| 199 | − hrtimer_cancel(&df->idle_work.timer); | |
| 216 | + cancel_idle_work(df); | |
| 200 | 217 | |
| 201 | 218 | idle_time = ktime_to_ms(ktime_sub(ktime_get(), df->idle_time)); |
| 202 | 219 | |
| @@ -1262,7 +1262,6 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host, · 1261 unmodified lines | ||
| 1262 | 1262 | struct mipi_dsi_device *device) |
| 1263 | 1263 | { |
| 1264 | 1264 | struct vc4_dsi *dsi = host_to_dsi(host); |
| 1265 | − int ret; | |
| 1266 | 1265 | |
| 1267 | 1266 | dsi->lanes = device->lanes; |
| 1268 | 1267 | dsi->channel = device->channel; |
| @@ -1297,18 +1296,15 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host, · 28 unmodified lines | ||
| 1297 | 1296 | return 0; |
| 1298 | 1297 | } |
| 1299 | 1298 | |
| 1300 | − ret = component_add(&dsi->pdev->dev, &vc4_dsi_ops); | |
| 1301 | − if (ret) { | |
| 1302 | − mipi_dsi_host_unregister(&dsi->dsi_host); | |
| 1303 | − return ret; | |
| 1304 | − } | |
| 1305 | − | |
| 1306 | − return 0; | |
| 1299 | + return component_add(&dsi->pdev->dev, &vc4_dsi_ops); | |
| 1307 | 1300 | } |
| 1308 | 1301 | |
| 1309 | 1302 | static int vc4_dsi_host_detach(struct mipi_dsi_host *host, |
| 1310 | 1303 | struct mipi_dsi_device *device) |
| 1311 | 1304 | { |
| 1305 | + struct vc4_dsi *dsi = host_to_dsi(host); | |
| 1306 | + | |
| 1307 | + component_del(&dsi->pdev->dev, &vc4_dsi_ops); | |
| 1312 | 1308 | return 0; |
| 1313 | 1309 | } |
| 1314 | 1310 | |
| @@ -1686,9 +1682,7 @@ static int vc4_dsi_dev_remove(struct platform_device *pdev) · 371 unmodified lines | ||
| 1686 | 1682 | struct device *dev = &pdev->dev; |
| 1687 | 1683 | struct vc4_dsi *dsi = dev_get_drvdata(dev); |
| 1688 | 1684 | |
| 1689 | − component_del(&pdev->dev, &vc4_dsi_ops); | |
| 1690 | 1685 | mipi_dsi_host_unregister(&dsi->dsi_host); |
| 1691 | − | |
| 1692 | 1686 | return 0; |
| 1693 | 1687 | } |
| 1694 | 1688 | |
| @@ -1140,15 +1140,14 @@ extern int vmw_execbuf_fence_commands(struct drm_file *file_priv, · 1139 unmodified lines | ||
| 1140 | 1140 | struct vmw_private *dev_priv, |
| 1141 | 1141 | struct vmw_fence_obj **p_fence, |
| 1142 | 1142 | uint32_t *p_handle); |
| 1143 | −extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, | |
| 1143 | +extern int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, | |
| 1144 | 1144 | struct vmw_fpriv *vmw_fp, |
| 1145 | 1145 | int ret, |
| 1146 | 1146 | struct drm_vmw_fence_rep __user |
| 1147 | 1147 | *user_fence_rep, |
| 1148 | 1148 | struct vmw_fence_obj *fence, |
| 1149 | 1149 | uint32_t fence_handle, |
| 1150 | − int32_t out_fence_fd, | |
| 1151 | − struct sync_file *sync_file); | |
| 1150 | + int32_t out_fence_fd); | |
| 1152 | 1151 | bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd); |
| 1153 | 1152 | |
| 1154 | 1153 | /** |
| @@ -3879,17 +3879,17 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv, · 3878 unmodified lines | ||
| 3879 | 3879 | * Also if copying fails, user-space will be unable to signal the fence object |
| 3880 | 3880 | * so we wait for it immediately, and then unreference the user-space reference. |
| 3881 | 3881 | */ |
| 3882 | −void | |
| 3882 | +int | |
| 3883 | 3883 | vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, |
| 3884 | 3884 | struct vmw_fpriv *vmw_fp, int ret, |
| 3885 | 3885 | struct drm_vmw_fence_rep __user *user_fence_rep, |
| 3886 | 3886 | struct vmw_fence_obj *fence, uint32_t fence_handle, |
| 3887 | − int32_t out_fence_fd, struct sync_file *sync_file) | |
| 3887 | + int32_t out_fence_fd) | |
| 3888 | 3888 | { |
| 3889 | 3889 | struct drm_vmw_fence_rep fence_rep; |
| 3890 | 3890 | |
| 3891 | 3891 | if (user_fence_rep == NULL) |
| 3892 | − return; | |
| 3892 | + return 0; | |
| 3893 | 3893 | |
| 3894 | 3894 | memset(&fence_rep, 0, sizeof(fence_rep)); |
| 3895 | 3895 | |
| @@ -3917,19 +3917,13 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, · 21 unmodified lines | ||
| 3917 | 3917 | * handle. |
| 3918 | 3918 | */ |
| 3919 | 3919 | if (unlikely(ret != 0) && (fence_rep.error == 0)) { |
| 3920 | − if (sync_file) | |
| 3921 | − fput(sync_file->file); | |
| 3922 | − | |
| 3923 | − if (fence_rep.fd != -1) { | |
| 3924 | − put_unused_fd(fence_rep.fd); | |
| 3925 | − fence_rep.fd = -1; | |
| 3926 | − } | |
| 3927 | − | |
| 3928 | 3920 | ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle); |
| 3929 | 3921 | VMW_DEBUG_USER("Fence copy error. Syncing.\n"); |
| 3930 | 3922 | (void) vmw_fence_obj_wait(fence, false, false, |
| 3931 | 3923 | VMW_FENCE_WAIT_TIMEOUT); |
| 3932 | 3924 | } |
| 3925 | + | |
| 3926 | + return ret ? -EFAULT : 0; | |
| 3933 | 3927 | } |
| 3934 | 3928 | |
| 3935 | 3929 | /** |
| @@ -4266,16 +4260,23 @@ int vmw_execbuf_process(struct drm_file *file_priv, · 330 unmodified lines | ||
| 4266 | 4260 | |
| 4267 | 4261 | (void) vmw_fence_obj_wait(fence, false, false, |
| 4268 | 4262 | VMW_FENCE_WAIT_TIMEOUT); |
| 4263 | + } | |
| 4264 | + } | |
| 4265 | + | |
| 4266 | + ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, | |
| 4267 | + user_fence_rep, fence, handle, out_fence_fd); | |
| 4268 | + | |
| 4269 | + if (sync_file) { | |
| 4270 | + if (ret) { | |
| 4271 | + /* usercopy of fence failed, put the file object */ | |
| 4272 | + fput(sync_file->file); | |
| 4273 | + put_unused_fd(out_fence_fd); | |
| 4269 | 4274 | } else { |
| 4270 | 4275 | /* Link the fence with the FD created earlier */ |
| 4271 | 4276 | fd_install(out_fence_fd, sync_file->file); |
| 4272 | 4277 | } |
| 4273 | 4278 | } |
| 4274 | 4279 | |
| 4275 | − vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, | |
| 4276 | − user_fence_rep, fence, handle, out_fence_fd, | |
| 4277 | − sync_file); | |
| 4278 | − | |
| 4279 | 4280 | /* Don't unreference when handing fence out */ |
| 4280 | 4281 | if (unlikely(out_fence != NULL)) { |
| 4281 | 4282 | *out_fence = fence; |
| @@ -4293,7 +4294,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, · 11 unmodified lines | ||
| 4293 | 4294 | */ |
| 4294 | 4295 | vmw_validation_unref_lists(&val_ctx); |
| 4295 | 4296 | |
| 4296 | − return 0; | |
| 4297 | + return ret; | |
| 4297 | 4298 | |
| 4298 | 4299 | out_unlock_binding: |
| 4299 | 4300 | mutex_unlock(&dev_priv->binding_mutex); |
| @@ -1128,7 +1128,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, · 1127 unmodified lines | ||
| 1128 | 1128 | } |
| 1129 | 1129 | |
| 1130 | 1130 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence, |
| 1131 | − handle, -1, NULL); | |
| 1131 | + handle, -1); | |
| 1132 | 1132 | vmw_fence_obj_unreference(&fence); |
| 1133 | 1133 | return 0; |
| 1134 | 1134 | out_no_create: |
| @@ -2501,7 +2501,7 @@ void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv, · 2500 unmodified lines | ||
| 2501 | 2501 | if (file_priv) |
| 2502 | 2502 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), |
| 2503 | 2503 | ret, user_fence_rep, fence, |
| 2504 | − handle, -1, NULL); | |
| 2504 | + handle, -1); | |
| 2505 | 2505 | if (out_fence) |
| 2506 | 2506 | *out_fence = fence; |
| 2507 | 2507 | else |
| @@ -1660,6 +1660,13 @@ static int balloon_connect_vsp(struct hv_device *dev) · 1659 unmodified lines | ||
| 1660 | 1660 | unsigned long t; |
| 1661 | 1661 | int ret; |
| 1662 | 1662 | |
| 1663 | + /* | |
| 1664 | + * max_pkt_size should be large enough for one vmbus packet header plus | |
| 1665 | + * our receive buffer size. Hyper-V sends messages up to | |
| 1666 | + * HV_HYP_PAGE_SIZE bytes long on balloon channel. | |
| 1667 | + */ | |
| 1668 | + dev->channel->max_pkt_size = HV_HYP_PAGE_SIZE * 2; | |
| 1669 | + | |
| 1663 | 1670 | ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0, |
| 1664 | 1671 | balloon_onchannelcallback, dev); |
| 1665 | 1672 | if (ret) |
| @@ -662,6 +662,9 @@ static int adt7470_fan_write(struct device *dev, u32 attr, int channel, long val · 661 unmodified lines | ||
| 662 | 662 | struct adt7470_data *data = dev_get_drvdata(dev); |
| 663 | 663 | int err; |
| 664 | 664 | |
| 665 | + if (val <= 0) | |
| 666 | + return -EINVAL; | |
| 667 | + | |
| 665 | 668 | val = FAN_RPM_TO_PERIOD(val); |
| 666 | 669 | val = clamp_val(val, 1, 65534); |
| 667 | 670 | |
| @@ -373,7 +373,7 @@ static const struct lm90_params lm90_params[] = { · 372 unmodified lines | ||
| 373 | 373 | .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT |
| 374 | 374 | | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT, |
| 375 | 375 | .alert_alarms = 0x7c, |
| 376 | − .max_convrate = 8, | |
| 376 | + .max_convrate = 7, | |
| 377 | 377 | }, |
| 378 | 378 | [lm86] = { |
| 379 | 379 | .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT |
| @@ -394,12 +394,13 @@ static const struct lm90_params lm90_params[] = { · 14 unmodified lines | ||
| 394 | 394 | .max_convrate = 9, |
| 395 | 395 | }, |
| 396 | 396 | [max6646] = { |
| 397 | − .flags = LM90_HAVE_CRIT, | |
| 397 | + .flags = LM90_HAVE_CRIT | LM90_HAVE_BROKEN_ALERT, | |
| 398 | 398 | .alert_alarms = 0x7c, |
| 399 | 399 | .max_convrate = 6, |
| 400 | 400 | .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, |
| 401 | 401 | }, |
| 402 | 402 | [max6654] = { |
| 403 | + .flags = LM90_HAVE_BROKEN_ALERT, | |
| 403 | 404 | .alert_alarms = 0x7c, |
| 404 | 405 | .max_convrate = 7, |
| 405 | 406 | .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, |
| @@ -418,7 +419,7 @@ static const struct lm90_params lm90_params[] = { · 12 unmodified lines | ||
| 418 | 419 | }, |
| 419 | 420 | [max6680] = { |
| 420 | 421 | .flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT |
| 421 | − | LM90_HAVE_CRIT_ALRM_SWP, | |
| 422 | + | LM90_HAVE_CRIT_ALRM_SWP | LM90_HAVE_BROKEN_ALERT, | |
| 422 | 423 | .alert_alarms = 0x7c, |
| 423 | 424 | .max_convrate = 7, |
| 424 | 425 | }, |
| @@ -848,7 +849,7 @@ static int lm90_update_device(struct device *dev) · 423 unmodified lines | ||
| 848 | 849 | * Re-enable ALERT# output if it was originally enabled and |
| 849 | 850 | * relevant alarms are all clear |
| 850 | 851 | */ |
| 851 | − if (!(data->config_orig & 0x80) && | |
| 852 | + if ((client->irq || !(data->config_orig & 0x80)) && | |
| 852 | 853 | !(data->alarms & data->alert_alarms)) { |
| 853 | 854 | if (data->config & 0x80) { |
| 854 | 855 | dev_dbg(&client->dev, "Re-enabling ALERT#\n"); |
| @@ -1807,22 +1808,22 @@ static bool lm90_is_tripped(struct i2c_client *client, u16 *status) · 952 unmodified lines | ||
| 1807 | 1808 | |
| 1808 | 1809 | if (st & LM90_STATUS_LLOW) |
| 1809 | 1810 | hwmon_notify_event(data->hwmon_dev, hwmon_temp, |
| 1810 | − hwmon_temp_min, 0); | |
| 1811 | + hwmon_temp_min_alarm, 0); | |
| 1811 | 1812 | if (st & LM90_STATUS_RLOW) |
| 1812 | 1813 | hwmon_notify_event(data->hwmon_dev, hwmon_temp, |
| 1813 | − hwmon_temp_min, 1); | |
| 1814 | + hwmon_temp_min_alarm, 1); | |
| 1814 | 1815 | if (st2 & MAX6696_STATUS2_R2LOW) |
| 1815 | 1816 | hwmon_notify_event(data->hwmon_dev, hwmon_temp, |
| 1816 | − hwmon_temp_min, 2); | |
| 1817 | + hwmon_temp_min_alarm, 2); | |
| 1817 | 1818 | if (st & LM90_STATUS_LHIGH) |
| 1818 | 1819 | hwmon_notify_event(data->hwmon_dev, hwmon_temp, |
| 1819 | − hwmon_temp_max, 0); | |
| 1820 | + hwmon_temp_max_alarm, 0); | |
| 1820 | 1821 | if (st & LM90_STATUS_RHIGH) |
| 1821 | 1822 | hwmon_notify_event(data->hwmon_dev, hwmon_temp, |
| 1822 | − hwmon_temp_max, 1); | |
| 1823 | + hwmon_temp_max_alarm, 1); | |
| 1823 | 1824 | if (st2 & MAX6696_STATUS2_R2HIGH) |
| 1824 | 1825 | hwmon_notify_event(data->hwmon_dev, hwmon_temp, |
| 1825 | − hwmon_temp_max, 2); | |
| 1826 | + hwmon_temp_max_alarm, 2); | |
| 1826 | 1827 | |
| 1827 | 1828 | return true; |
| 1828 | 1829 | } |
| @@ -1175,7 +1175,7 @@ static inline u8 in_to_reg(u32 val, u8 nr) · 1174 unmodified lines | ||
| 1175 | 1175 | |
| 1176 | 1176 | struct nct6775_data { |
| 1177 | 1177 | int addr; /* IO base of hw monitor block */ |
| 1178 | − int sioreg; /* SIO register address */ | |
| 1178 | + struct nct6775_sio_data *sio_data; | |
| 1179 | 1179 | enum kinds kind; |
| 1180 | 1180 | const char *name; |
| 1181 | 1181 | |
| @@ -3559,7 +3559,7 @@ clear_caseopen(struct device *dev, struct device_attribute *attr, · 2377 unmodified lines | ||
| 3559 | 3559 | const char *buf, size_t count) |
| 3560 | 3560 | { |
| 3561 | 3561 | struct nct6775_data *data = dev_get_drvdata(dev); |
| 3562 | − struct nct6775_sio_data *sio_data = dev_get_platdata(dev); | |
| 3562 | + struct nct6775_sio_data *sio_data = data->sio_data; | |
| 3563 | 3563 | int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE; |
| 3564 | 3564 | unsigned long val; |
| 3565 | 3565 | u8 reg; |
| @@ -3967,7 +3967,7 @@ static int nct6775_probe(struct platform_device *pdev) · 401 unmodified lines | ||
| 3967 | 3967 | return -ENOMEM; |
| 3968 | 3968 | |
| 3969 | 3969 | data->kind = sio_data->kind; |
| 3970 | − data->sioreg = sio_data->sioreg; | |
| 3970 | + data->sio_data = sio_data; | |
| 3971 | 3971 | |
| 3972 | 3972 | if (sio_data->access == access_direct) { |
| 3973 | 3973 | data->addr = res->start; |
| @@ -62,7 +62,7 @@ static const struct i2c_device_id ir38064_id[] = { · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | MODULE_DEVICE_TABLE(i2c, ir38064_id); |
| 64 | 64 | |
| 65 | −static const struct of_device_id ir38064_of_match[] = { | |
| 65 | +static const struct of_device_id __maybe_unused ir38064_of_match[] = { | |
| 66 | 66 | { .compatible = "infineon,ir38060" }, |
| 67 | 67 | { .compatible = "infineon,ir38064" }, |
| 68 | 68 | { .compatible = "infineon,ir38164" }, |
| @@ -178,7 +178,6 @@ struct aic_irq_chip { · 177 unmodified lines | ||
| 178 | 178 | struct irq_domain *hw_domain; |
| 179 | 179 | struct irq_domain *ipi_domain; |
| 180 | 180 | int nr_hw; |
| 181 | − int ipi_hwirq; | |
| 182 | 181 | }; |
| 183 | 182 | |
| 184 | 183 | static DEFINE_PER_CPU(uint32_t, aic_fiq_unmasked); |
| @@ -4856,6 +4856,38 @@ static struct syscore_ops its_syscore_ops = { · 4855 unmodified lines | ||
| 4856 | 4856 | .resume = its_restore_enable, |
| 4857 | 4857 | }; |
| 4858 | 4858 | |
| 4859 | +static void __init __iomem *its_map_one(struct resource *res, int *err) | |
| 4860 | +{ | |
| 4861 | + void __iomem *its_base; | |
| 4862 | + u32 val; | |
| 4863 | + | |
| 4864 | + its_base = ioremap(res->start, SZ_64K); | |
| 4865 | + if (!its_base) { | |
| 4866 | + pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start); | |
| 4867 | + *err = -ENOMEM; | |
| 4868 | + return NULL; | |
| 4869 | + } | |
| 4870 | + | |
| 4871 | + val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK; | |
| 4872 | + if (val != 0x30 && val != 0x40) { | |
| 4873 | + pr_warn("ITS@%pa: No ITS detected, giving up\n", &res->start); | |
| 4874 | + *err = -ENODEV; | |
| 4875 | + goto out_unmap; | |
| 4876 | + } | |
| 4877 | + | |
| 4878 | + *err = its_force_quiescent(its_base); | |
| 4879 | + if (*err) { | |
| 4880 | + pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &res->start); | |
| 4881 | + goto out_unmap; | |
| 4882 | + } | |
| 4883 | + | |
| 4884 | + return its_base; | |
| 4885 | + | |
| 4886 | +out_unmap: | |
| 4887 | + iounmap(its_base); | |
| 4888 | + return NULL; | |
| 4889 | +} | |
| 4890 | + | |
| 4859 | 4891 | static int its_init_domain(struct fwnode_handle *handle, struct its_node *its) |
| 4860 | 4892 | { |
| 4861 | 4893 | struct irq_domain *inner_domain; |
| @@ -4963,29 +4995,14 @@ static int __init its_probe_one(struct resource *res, · 101 unmodified lines | ||
| 4963 | 4995 | { |
| 4964 | 4996 | struct its_node *its; |
| 4965 | 4997 | void __iomem *its_base; |
| 4966 | − u32 val, ctlr; | |
| 4967 | 4998 | u64 baser, tmp, typer; |
| 4968 | 4999 | struct page *page; |
| 5000 | + u32 ctlr; | |
| 4969 | 5001 | int err; |
| 4970 | 5002 | |
| 4971 | − its_base = ioremap(res->start, SZ_64K); | |
| 4972 | − if (!its_base) { | |
| 4973 | − pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start); | |
| 4974 | − return -ENOMEM; | |
| 4975 | − } | |
| 4976 | − | |
| 4977 | − val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK; | |
| 4978 | − if (val != 0x30 && val != 0x40) { | |
| 4979 | − pr_warn("ITS@%pa: No ITS detected, giving up\n", &res->start); | |
| 4980 | − err = -ENODEV; | |
| 4981 | − goto out_unmap; | |
| 4982 | − } | |
| 4983 | − | |
| 4984 | − err = its_force_quiescent(its_base); | |
| 4985 | − if (err) { | |
| 4986 | − pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &res->start); | |
| 4987 | − goto out_unmap; | |
| 4988 | − } | |
| 5003 | + its_base = its_map_one(res, &err); | |
| 5004 | + if (!its_base) | |
| 5005 | + return err; | |
| 4989 | 5006 | |
| 4990 | 5007 | pr_info("ITS %pR\n", res); |
| 4991 | 5008 | |
| @@ -5241,13 +5258,31 @@ static int its_cpu_memreserve_lpi(unsigned int cpu) · 249 unmodified lines | ||
| 5241 | 5258 | |
| 5242 | 5259 | out: |
| 5243 | 5260 | /* Last CPU being brought up gets to issue the cleanup */ |
| 5244 | − if (cpumask_equal(&cpus_booted_once_mask, cpu_possible_mask)) | |
| 5261 | + if (!IS_ENABLED(CONFIG_SMP) || | |
| 5262 | + cpumask_equal(&cpus_booted_once_mask, cpu_possible_mask)) | |
| 5245 | 5263 | schedule_work(&rdist_memreserve_cpuhp_cleanup_work); |
| 5246 | 5264 | |
| 5247 | 5265 | gic_data_rdist()->flags |= RD_LOCAL_MEMRESERVE_DONE; |
| 5248 | 5266 | return ret; |
| 5249 | 5267 | } |
| 5250 | 5268 | |
| 5269 | +/* Mark all the BASER registers as invalid before they get reprogrammed */ | |
| 5270 | +static int __init its_reset_one(struct resource *res) | |
| 5271 | +{ | |
| 5272 | + void __iomem *its_base; | |
| 5273 | + int err, i; | |
| 5274 | + | |
| 5275 | + its_base = its_map_one(res, &err); | |
| 5276 | + if (!its_base) | |
| 5277 | + return err; | |
| 5278 | + | |
| 5279 | + for (i = 0; i < GITS_BASER_NR_REGS; i++) | |
| 5280 | + gits_write_baser(0, its_base + GITS_BASER + (i << 3)); | |
| 5281 | + | |
| 5282 | + iounmap(its_base); | |
| 5283 | + return 0; | |
| 5284 | +} | |
| 5285 | + | |
| 5251 | 5286 | static const struct of_device_id its_device_id[] = { |
| 5252 | 5287 | { .compatible = "arm,gic-v3-its", }, |
| 5253 | 5288 | {}, |
| @@ -5258,6 +5293,26 @@ static int __init its_of_probe(struct device_node *node) · 4 unmodified lines | ||
| 5258 | 5293 | struct device_node *np; |
| 5259 | 5294 | struct resource res; |
| 5260 | 5295 | |
| 5296 | + /* | |
| 5297 | + * Make sure *all* the ITS are reset before we probe any, as | |
| 5298 | + * they may be sharing memory. If any of the ITS fails to | |
| 5299 | + * reset, don't even try to go any further, as this could | |
| 5300 | + * result in something even worse. | |
| 5301 | + */ | |
| 5302 | + for (np = of_find_matching_node(node, its_device_id); np; | |
| 5303 | + np = of_find_matching_node(np, its_device_id)) { | |
| 5304 | + int err; | |
| 5305 | + | |
| 5306 | + if (!of_device_is_available(np) || | |
| 5307 | + !of_property_read_bool(np, "msi-controller") || | |
| 5308 | + of_address_to_resource(np, 0, &res)) | |
| 5309 | + continue; | |
| 5310 | + | |
| 5311 | + err = its_reset_one(&res); | |
| 5312 | + if (err) | |
| 5313 | + return err; | |
| 5314 | + } | |
| 5315 | + | |
| 5261 | 5316 | for (np = of_find_matching_node(node, its_device_id); np; |
| 5262 | 5317 | np = of_find_matching_node(np, its_device_id)) { |
| 5263 | 5318 | if (!of_device_is_available(np)) |
| @@ -5420,11 +5475,35 @@ dom_err: · 156 unmodified lines | ||
| 5420 | 5475 | return err; |
| 5421 | 5476 | } |
| 5422 | 5477 | |
| 5478 | +static int __init its_acpi_reset(union acpi_subtable_headers *header, | |
| 5479 | + const unsigned long end) | |
| 5480 | +{ | |
| 5481 | + struct acpi_madt_generic_translator *its_entry; | |
| 5482 | + struct resource res; | |
| 5483 | + | |
| 5484 | + its_entry = (struct acpi_madt_generic_translator *)header; | |
| 5485 | + res = (struct resource) { | |
| 5486 | + .start = its_entry->base_address, | |
| 5487 | + .end = its_entry->base_address + ACPI_GICV3_ITS_MEM_SIZE - 1, | |
| 5488 | + .flags = IORESOURCE_MEM, | |
| 5489 | + }; | |
| 5490 | + | |
| 5491 | + return its_reset_one(&res); | |
| 5492 | +} | |
| 5493 | + | |
| 5423 | 5494 | static void __init its_acpi_probe(void) |
| 5424 | 5495 | { |
| 5425 | 5496 | acpi_table_parse_srat_its(); |
| 5426 | − acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, | |
| 5427 | − gic_acpi_parse_madt_its, 0); | |
| 5497 | + /* | |
| 5498 | + * Make sure *all* the ITS are reset before we probe any, as | |
| 5499 | + * they may be sharing memory. If any of the ITS fails to | |
| 5500 | + * reset, don't even try to go any further, as this could | |
| 5501 | + * result in something even worse. | |
| 5502 | + */ | |
| 5503 | + if (acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, | |
| 5504 | + its_acpi_reset, 0) > 0) | |
| 5505 | + acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, | |
| 5506 | + gic_acpi_parse_madt_its, 0); | |
| 5428 | 5507 | acpi_its_srat_maps_free(); |
| 5429 | 5508 | } |
| 5430 | 5509 | #else |
| @@ -241,7 +241,7 @@ static int pch_msi_init(struct device_node *node, · 240 unmodified lines | ||
| 241 | 241 | return 0; |
| 242 | 242 | |
| 243 | 243 | err_map: |
| 244 | − kfree(priv->msi_map); | |
| 244 | + bitmap_free(priv->msi_map); | |
| 245 | 245 | err_priv: |
| 246 | 246 | kfree(priv); |
| 247 | 247 | return ret; |
| @@ -62,7 +62,7 @@ static struct irq_chip realtek_ictl_irq = { · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) |
| 64 | 64 | { |
| 65 | − irq_set_chip_and_handler(hw, &realtek_ictl_irq, handle_level_irq); | |
| 65 | + irq_set_chip_and_handler(irq, &realtek_ictl_irq, handle_level_irq); | |
| 66 | 66 | |
| 67 | 67 | return 0; |
| 68 | 68 | } |
| @@ -76,16 +76,20 @@ static void realtek_irq_dispatch(struct irq_desc *desc) · 7 unmodified lines | ||
| 76 | 76 | { |
| 77 | 77 | struct irq_chip *chip = irq_desc_get_chip(desc); |
| 78 | 78 | struct irq_domain *domain; |
| 79 | − unsigned int pending; | |
| 79 | + unsigned long pending; | |
| 80 | + unsigned int soc_int; | |
| 80 | 81 | |
| 81 | 82 | chained_irq_enter(chip, desc); |
| 82 | 83 | pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR)); |
| 84 | + | |
| 83 | 85 | if (unlikely(!pending)) { |
| 84 | 86 | spurious_interrupt(); |
| 85 | 87 | goto out; |
| 86 | 88 | } |
| 89 | + | |
| 87 | 90 | domain = irq_desc_get_handler_data(desc); |
| 88 | − generic_handle_domain_irq(domain, __ffs(pending)); | |
| 91 | + for_each_set_bit(soc_int, &pending, 32) | |
| 92 | + generic_handle_domain_irq(domain, soc_int); | |
| 89 | 93 | |
| 90 | 94 | out: |
| 91 | 95 | chained_irq_exit(chip, desc); |
| @@ -95,7 +99,8 @@ out: · 3 unmodified lines | ||
| 95 | 99 | * SoC interrupts are cascaded to MIPS CPU interrupts according to the |
| 96 | 100 | * interrupt-map in the device tree. Each SoC interrupt gets 4 bits for |
| 97 | 101 | * the CPU interrupt in an Interrupt Routing Register. Max 32 SoC interrupts |
| 98 | − * thus go into 4 IRRs. | |
| 102 | + * thus go into 4 IRRs. A routing value of '0' means the interrupt is left | |
| 103 | + * disconnected. Routing values {1..15} connect to output lines {0..14}. | |
| 99 | 104 | */ |
| 100 | 105 | static int __init map_interrupts(struct device_node *node, struct irq_domain *domain) |
| 101 | 106 | { |
| @@ -134,7 +139,7 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do · 32 unmodified lines | ||
| 134 | 139 | of_node_put(cpu_ictl); |
| 135 | 140 | |
| 136 | 141 | cpu_int = be32_to_cpup(imap + 2); |
| 137 | − if (cpu_int > 7) | |
| 142 | + if (cpu_int > 7 || cpu_int < 2) | |
| 138 | 143 | return -EINVAL; |
| 139 | 144 | |
| 140 | 145 | if (!(mips_irqs_set & BIT(cpu_int))) { |
| @@ -143,7 +148,8 @@ static int __init map_interrupts(struct device_node *node, struct irq_domain *do · 2 unmodified lines | ||
| 143 | 148 | mips_irqs_set |= BIT(cpu_int); |
| 144 | 149 | } |
| 145 | 150 | |
| 146 | − regs[(soc_int * 4) / 32] |= cpu_int << (soc_int * 4) % 32; | |
| 151 | + /* Use routing values (1..6) for CPU interrupts (2..7) */ | |
| 152 | + regs[(soc_int * 4) / 32] |= (cpu_int - 1) << (soc_int * 4) % 32; | |
| 147 | 153 | imap += 3; |
| 148 | 154 | } |
| 149 | 155 | |
| @@ -489,7 +489,7 @@ static void start_io_acct(struct dm_io *io) · 488 unmodified lines | ||
| 489 | 489 | struct mapped_device *md = io->md; |
| 490 | 490 | struct bio *bio = io->orig_bio; |
| 491 | 491 | |
| 492 | − io->start_time = bio_start_io_acct(bio); | |
| 492 | + bio_start_io_acct_time(bio, io->start_time); | |
| 493 | 493 | if (unlikely(dm_stats_used(&md->stats))) |
| 494 | 494 | dm_stats_account_io(&md->stats, bio_data_dir(bio), |
| 495 | 495 | bio->bi_iter.bi_sector, bio_sectors(bio), |
| @@ -535,7 +535,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio) · 39 unmodified lines | ||
| 535 | 535 | io->md = md; |
| 536 | 536 | spin_lock_init(&io->endio_lock); |
| 537 | 537 | |
| 538 | − start_io_acct(io); | |
| 538 | + io->start_time = jiffies; | |
| 539 | 539 | |
| 540 | 540 | return io; |
| 541 | 541 | } |
| @@ -1442,9 +1442,6 @@ static void init_clone_info(struct clone_info *ci, struct mapped_device *md, · 900 unmodified lines | ||
| 1442 | 1442 | ci->sector = bio->bi_iter.bi_sector; |
| 1443 | 1443 | } |
| 1444 | 1444 | |
| 1445 | −#define __dm_part_stat_sub(part, field, subnd) \ | |
| 1446 | − (part_stat_get(part, field) -= (subnd)) | |
| 1447 | − | |
| 1448 | 1445 | /* |
| 1449 | 1446 | * Entry point to split a bio into clones and submit them to the targets. |
| 1450 | 1447 | */ |
| @@ -1480,23 +1477,12 @@ static void __split_and_process_bio(struct mapped_device *md, · 29 unmodified lines | ||
| 1480 | 1477 | GFP_NOIO, &md->queue->bio_split); |
| 1481 | 1478 | ci.io->orig_bio = b; |
| 1482 | 1479 | |
| 1483 | − /* | |
| 1484 | − * Adjust IO stats for each split, otherwise upon queue | |
| 1485 | − * reentry there will be redundant IO accounting. | |
| 1486 | − * NOTE: this is a stop-gap fix, a proper fix involves | |
| 1487 | − * significant refactoring of DM core's bio splitting | |
| 1488 | − * (by eliminating DM's splitting and just using bio_split) | |
| 1489 | − */ | |
| 1490 | − part_stat_lock(); | |
| 1491 | − __dm_part_stat_sub(dm_disk(md)->part0, | |
| 1492 | − sectors[op_stat_group(bio_op(bio))], ci.sector_count); | |
| 1493 | − part_stat_unlock(); | |
| 1494 | − | |
| 1495 | 1480 | bio_chain(b, bio); |
| 1496 | 1481 | trace_block_split(b, bio->bi_iter.bi_sector); |
| 1497 | 1482 | submit_bio_noacct(bio); |
| 1498 | 1483 | } |
| 1499 | 1484 | } |
| 1485 | + start_io_acct(ci.io); | |
| 1500 | 1486 | |
| 1501 | 1487 | /* drop the extra reference count */ |
| 1502 | 1488 | dm_io_dec_pending(ci.io, errno_to_blk_status(error)); |
| @@ -440,6 +440,10 @@ static int at25_probe(struct spi_device *spi) · 439 unmodified lines | ||
| 440 | 440 | return -ENXIO; |
| 441 | 441 | } |
| 442 | 442 | |
| 443 | + at25 = devm_kzalloc(&spi->dev, sizeof(*at25), GFP_KERNEL); | |
| 444 | + if (!at25) | |
| 445 | + return -ENOMEM; | |
| 446 | + | |
| 443 | 447 | mutex_init(&at25->lock); |
| 444 | 448 | at25->spi = spi; |
| 445 | 449 | spi_set_drvdata(spi, at25); |
| @@ -4133,9 +4133,7 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm · 4132 unmodified lines | ||
| 4133 | 4133 | |
| 4134 | 4134 | fallthrough; |
| 4135 | 4135 | case SIOCGHWTSTAMP: |
| 4136 | − rcu_read_lock(); | |
| 4137 | 4136 | real_dev = bond_option_active_slave_get_rcu(bond); |
| 4138 | − rcu_read_unlock(); | |
| 4139 | 4137 | if (!real_dev) |
| 4140 | 4138 | return -EOPNOTSUPP; |
| 4141 | 4139 | |
| @@ -5382,9 +5380,7 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev, · 1240 unmodified lines | ||
| 5382 | 5380 | struct net_device *real_dev; |
| 5383 | 5381 | struct phy_device *phydev; |
| 5384 | 5382 | |
| 5385 | − rcu_read_lock(); | |
| 5386 | 5383 | real_dev = bond_option_active_slave_get_rcu(bond); |
| 5387 | − rcu_read_unlock(); | |
| 5388 | 5384 | if (real_dev) { |
| 5389 | 5385 | ops = real_dev->ethtool_ops; |
| 5390 | 5386 | phydev = real_dev->phydev; |
| @@ -296,6 +296,7 @@ static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8); · 295 unmodified lines | ||
| 296 | 296 | static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = { |
| 297 | 297 | .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
| 298 | 298 | FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_NR_MB_16 | |
| 299 | + FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | | |
| 299 | 300 | FLEXCAN_QUIRK_SUPPPORT_RX_FIFO, |
| 300 | 301 | }; |
| 301 | 302 | |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | * Below is some version info we got: |
| 22 | 22 | * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB |
| 23 | 23 | * Filter? connected? Passive detection ption in MB Supported? |
| 24 | − * MCF5441X FlexCAN2 ? no yes no no yes no 16 | |
| 24 | + * MCF5441X FlexCAN2 ? no yes no no no no 16 | |
| 25 | 25 | * MX25 FlexCAN2 03.00.00.00 no no no no no no 64 |
| 26 | 26 | * MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 |
| 27 | 27 | * MX35 FlexCAN2 03.00.00.00 no no no no no no 64 |
| @@ -336,6 +336,9 @@ m_can_fifo_read(struct m_can_classdev *cdev, · 335 unmodified lines | ||
| 336 | 336 | u32 addr_offset = cdev->mcfg[MRAM_RXF0].off + fgi * RXF0_ELEMENT_SIZE + |
| 337 | 337 | offset; |
| 338 | 338 | |
| 339 | + if (val_count == 0) | |
| 340 | + return 0; | |
| 341 | + | |
| 339 | 342 | return cdev->ops->read_fifo(cdev, addr_offset, val, val_count); |
| 340 | 343 | } |
| 341 | 344 | |
| @@ -346,6 +349,9 @@ m_can_fifo_write(struct m_can_classdev *cdev, · 4 unmodified lines | ||
| 346 | 349 | u32 addr_offset = cdev->mcfg[MRAM_TXB].off + fpi * TXB_ELEMENT_SIZE + |
| 347 | 350 | offset; |
| 348 | 351 | |
| 352 | + if (val_count == 0) | |
| 353 | + return 0; | |
| 354 | + | |
| 349 | 355 | return cdev->ops->write_fifo(cdev, addr_offset, val, val_count); |
| 350 | 356 | } |
| 351 | 357 | |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #define TCAN4X5X_SPI_INSTRUCTION_WRITE (0x61 << 24) |
| 13 | 13 | #define TCAN4X5X_SPI_INSTRUCTION_READ (0x41 << 24) |
| 14 | 14 | |
| 15 | −#define TCAN4X5X_MAX_REGISTER 0x8ffc | |
| 15 | +#define TCAN4X5X_MAX_REGISTER 0x87fc | |
| 16 | 16 | |
| 17 | 17 | static int tcan4x5x_regmap_gather_write(void *context, |
| 18 | 18 | const void *reg, size_t reg_len, |
| @@ -2278,6 +2278,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 2277 unmodified lines | ||
| 2278 | 2278 | struct net_device *dev; |
| 2279 | 2279 | struct typhoon *tp; |
| 2280 | 2280 | int card_id = (int) ent->driver_data; |
| 2281 | + u8 addr[ETH_ALEN] __aligned(4); | |
| 2281 | 2282 | void __iomem *ioaddr; |
| 2282 | 2283 | void *shared; |
| 2283 | 2284 | dma_addr_t shared_dma; |
| @@ -2409,8 +2410,9 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 125 unmodified lines | ||
| 2409 | 2410 | goto error_out_reset; |
| 2410 | 2411 | } |
| 2411 | 2412 | |
| 2412 | − *(__be16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1)); | |
| 2413 | − *(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2)); | |
| 2413 | + *(__be16 *)&addr[0] = htons(le16_to_cpu(xp_resp[0].parm1)); | |
| 2414 | + *(__be32 *)&addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2)); | |
| 2415 | + eth_hw_addr_set(dev, addr); | |
| 2414 | 2416 | |
| 2415 | 2417 | if (!is_valid_ether_addr(dev->dev_addr)) { |
| 2416 | 2418 | err_msg = "Could not obtain valid ethernet address, aborting"; |
| @@ -655,6 +655,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) · 654 unmodified lines | ||
| 655 | 655 | struct ei_device *ei_local; |
| 656 | 656 | struct net_device *dev; |
| 657 | 657 | struct etherh_priv *eh; |
| 658 | + u8 addr[ETH_ALEN]; | |
| 658 | 659 | int ret; |
| 659 | 660 | |
| 660 | 661 | ret = ecard_request_resources(ec); |
| @@ -724,12 +725,13 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) · 63 unmodified lines | ||
| 724 | 725 | spin_lock_init(&ei_local->page_lock); |
| 725 | 726 | |
| 726 | 727 | if (ec->cid.product == PROD_ANT_ETHERM) { |
| 727 | − etherm_addr(dev->dev_addr); | |
| 728 | + etherm_addr(addr); | |
| 728 | 729 | ei_local->reg_offset = etherm_regoffsets; |
| 729 | 730 | } else { |
| 730 | − etherh_addr(dev->dev_addr, ec); | |
| 731 | + etherh_addr(addr, ec); | |
| 731 | 732 | ei_local->reg_offset = etherh_regoffsets; |
| 732 | 733 | } |
| 734 | + eth_hw_addr_set(dev, addr); | |
| 733 | 735 | |
| 734 | 736 | ei_local->name = dev->name; |
| 735 | 737 | ei_local->word16 = 1; |
| @@ -1032,6 +1032,7 @@ static int dec_lance_probe(struct device *bdev, const int type) · 1031 unmodified lines | ||
| 1032 | 1032 | int i, ret; |
| 1033 | 1033 | unsigned long esar_base; |
| 1034 | 1034 | unsigned char *esar; |
| 1035 | + u8 addr[ETH_ALEN]; | |
| 1035 | 1036 | const char *desc; |
| 1036 | 1037 | |
| 1037 | 1038 | if (dec_lance_debug && version_printed++ == 0) |
| @@ -1228,7 +1229,8 @@ static int dec_lance_probe(struct device *bdev, const int type) · 190 unmodified lines | ||
| 1228 | 1229 | break; |
| 1229 | 1230 | } |
| 1230 | 1231 | for (i = 0; i < 6; i++) |
| 1231 | − dev->dev_addr[i] = esar[i * 4]; | |
| 1232 | + addr[i] = esar[i * 4]; | |
| 1233 | + eth_hw_addr_set(dev, addr); | |
| 1232 | 1234 | |
| 1233 | 1235 | printk("%s: %s, addr = %pM, irq = %d\n", |
| 1234 | 1236 | name, desc, dev->dev_addr, dev->irq); |
| @@ -826,7 +826,6 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic) · 825 unmodified lines | ||
| 826 | 826 | struct aq_hw_s *aq_hw = aq_nic->aq_hw; |
| 827 | 827 | int hweight = 0; |
| 828 | 828 | int err = 0; |
| 829 | − int i; | |
| 830 | 829 | |
| 831 | 830 | if (unlikely(!aq_hw_ops->hw_filter_vlan_set)) |
| 832 | 831 | return -EOPNOTSUPP; |
| @@ -837,8 +836,7 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic) · 4 unmodified lines | ||
| 837 | 836 | aq_nic->aq_hw_rx_fltrs.fl2.aq_vlans); |
| 838 | 837 | |
| 839 | 838 | if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) { |
| 840 | − for (i = 0; i < BITS_TO_LONGS(VLAN_N_VID); i++) | |
| 841 | − hweight += hweight_long(aq_nic->active_vlans[i]); | |
| 839 | + hweight = bitmap_weight(aq_nic->active_vlans, VLAN_N_VID); | |
| 842 | 840 | |
| 843 | 841 | err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, false); |
| 844 | 842 | if (err) |
| @@ -871,7 +869,7 @@ int aq_filters_vlan_offload_off(struct aq_nic_s *aq_nic) · 26 unmodified lines | ||
| 871 | 869 | struct aq_hw_s *aq_hw = aq_nic->aq_hw; |
| 872 | 870 | int err = 0; |
| 873 | 871 | |
| 874 | − memset(aq_nic->active_vlans, 0, sizeof(aq_nic->active_vlans)); | |
| 872 | + bitmap_zero(aq_nic->active_vlans, VLAN_N_VID); | |
| 875 | 873 | aq_fvlan_rebuild(aq_nic, aq_nic->active_vlans, |
| 876 | 874 | aq_nic->aq_hw_rx_fltrs.fl2.aq_vlans); |
| 877 | 875 | |
| @@ -2183,9 +2183,7 @@ static int sbmac_init(struct platform_device *pldev, long long base) · 2182 unmodified lines | ||
| 2183 | 2183 | ea_reg >>= 8; |
| 2184 | 2184 | } |
| 2185 | 2185 | |
| 2186 | − for (i = 0; i < 6; i++) { | |
| 2187 | − dev->dev_addr[i] = eaddr[i]; | |
| 2188 | − } | |
| 2186 | + eth_hw_addr_set(dev, eaddr); | |
| 2189 | 2187 | |
| 2190 | 2188 | /* |
| 2191 | 2189 | * Initialize context (get pointers to registers and stuff), then |
| @@ -99,13 +99,13 @@ static void mpc52xx_fec_tx_timeout(struct net_device *dev, unsigned int txqueue) · 98 unmodified lines | ||
| 99 | 99 | netif_wake_queue(dev); |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | −static void mpc52xx_fec_set_paddr(struct net_device *dev, u8 *mac) | |
| 102 | +static void mpc52xx_fec_set_paddr(struct net_device *dev, const u8 *mac) | |
| 103 | 103 | { |
| 104 | 104 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); |
| 105 | 105 | struct mpc52xx_fec __iomem *fec = priv->fec; |
| 106 | 106 | |
| 107 | − out_be32(&fec->paddr1, *(u32 *)(&mac[0])); | |
| 108 | − out_be32(&fec->paddr2, (*(u16 *)(&mac[4]) << 16) | FEC_PADDR2_TYPE); | |
| 107 | + out_be32(&fec->paddr1, *(const u32 *)(&mac[0])); | |
| 108 | + out_be32(&fec->paddr2, (*(const u16 *)(&mac[4]) << 16) | FEC_PADDR2_TYPE); | |
| 109 | 109 | } |
| 110 | 110 | |
| 111 | 111 | static int mpc52xx_fec_set_mac_address(struct net_device *dev, void *addr) |
| @@ -893,13 +893,15 @@ static int mpc52xx_fec_probe(struct platform_device *op) · 781 unmodified lines | ||
| 893 | 893 | rv = of_get_ethdev_address(np, ndev); |
| 894 | 894 | if (rv) { |
| 895 | 895 | struct mpc52xx_fec __iomem *fec = priv->fec; |
| 896 | + u8 addr[ETH_ALEN] __aligned(4); | |
| 896 | 897 | |
| 897 | 898 | /* |
| 898 | 899 | * If the MAC addresse is not provided via DT then read |
| 899 | 900 | * it back from the controller regs |
| 900 | 901 | */ |
| 901 | − *(u32 *)(&ndev->dev_addr[0]) = in_be32(&fec->paddr1); | |
| 902 | − *(u16 *)(&ndev->dev_addr[4]) = in_be32(&fec->paddr2) >> 16; | |
| 902 | + *(u32 *)(&addr[0]) = in_be32(&fec->paddr1); | |
| 903 | + *(u16 *)(&addr[4]) = in_be32(&fec->paddr2) >> 16; | |
| 904 | + eth_hw_addr_set(ndev, addr); | |
| 903 | 905 | } |
| 904 | 906 | |
| 905 | 907 | /* |
| @@ -843,7 +843,7 @@ static inline bool gve_is_gqi(struct gve_priv *priv) · 842 unmodified lines | ||
| 843 | 843 | /* buffers */ |
| 844 | 844 | int gve_alloc_page(struct gve_priv *priv, struct device *dev, |
| 845 | 845 | struct page **page, dma_addr_t *dma, |
| 846 | − enum dma_data_direction); | |
| 846 | + enum dma_data_direction, gfp_t gfp_flags); | |
| 847 | 847 | void gve_free_page(struct device *dev, struct page *page, dma_addr_t dma, |
| 848 | 848 | enum dma_data_direction); |
| 849 | 849 | /* tx handling */ |
| @@ -766,9 +766,9 @@ static void gve_free_rings(struct gve_priv *priv) · 765 unmodified lines | ||
| 766 | 766 | |
| 767 | 767 | int gve_alloc_page(struct gve_priv *priv, struct device *dev, |
| 768 | 768 | struct page **page, dma_addr_t *dma, |
| 769 | − enum dma_data_direction dir) | |
| 769 | + enum dma_data_direction dir, gfp_t gfp_flags) | |
| 770 | 770 | { |
| 771 | − *page = alloc_page(GFP_KERNEL); | |
| 771 | + *page = alloc_page(gfp_flags); | |
| 772 | 772 | if (!*page) { |
| 773 | 773 | priv->page_alloc_fail++; |
| 774 | 774 | return -ENOMEM; |
| @@ -811,7 +811,7 @@ static int gve_alloc_queue_page_list(struct gve_priv *priv, u32 id, · 36 unmodified lines | ||
| 811 | 811 | for (i = 0; i < pages; i++) { |
| 812 | 812 | err = gve_alloc_page(priv, &priv->pdev->dev, &qpl->pages[i], |
| 813 | 813 | &qpl->page_buses[i], |
| 814 | − gve_qpl_dma_dir(priv, id)); | |
| 814 | + gve_qpl_dma_dir(priv, id), GFP_KERNEL); | |
| 815 | 815 | /* caller handles clean up */ |
| 816 | 816 | if (err) |
| 817 | 817 | return -ENOMEM; |
| @@ -86,7 +86,8 @@ static int gve_rx_alloc_buffer(struct gve_priv *priv, struct device *dev, · 85 unmodified lines | ||
| 86 | 86 | dma_addr_t dma; |
| 87 | 87 | int err; |
| 88 | 88 | |
| 89 | − err = gve_alloc_page(priv, dev, &page, &dma, DMA_FROM_DEVICE); | |
| 89 | + err = gve_alloc_page(priv, dev, &page, &dma, DMA_FROM_DEVICE, | |
| 90 | + GFP_ATOMIC); | |
| 90 | 91 | if (err) |
| 91 | 92 | return err; |
| 92 | 93 | |
| @@ -157,7 +157,7 @@ static int gve_alloc_page_dqo(struct gve_priv *priv, · 156 unmodified lines | ||
| 157 | 157 | int err; |
| 158 | 158 | |
| 159 | 159 | err = gve_alloc_page(priv, &priv->pdev->dev, &buf_state->page_info.page, |
| 160 | − &buf_state->addr, DMA_FROM_DEVICE); | |
| 160 | + &buf_state->addr, DMA_FROM_DEVICE, GFP_KERNEL); | |
| 161 | 161 | if (err) |
| 162 | 162 | return err; |
| 163 | 163 | |
| @@ -2043,8 +2043,7 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) · 2042 unmodified lines | ||
| 2043 | 2043 | break; |
| 2044 | 2044 | } |
| 2045 | 2045 | |
| 2046 | − if (event_cause != HCLGEVF_VECTOR0_EVENT_OTHER) | |
| 2047 | − hclgevf_enable_vector(&hdev->misc_vector, true); | |
| 2046 | + hclgevf_enable_vector(&hdev->misc_vector, true); | |
| 2048 | 2047 | |
| 2049 | 2048 | return IRQ_HANDLED; |
| 2050 | 2049 | } |
| @@ -986,6 +986,7 @@ static int · 985 unmodified lines | ||
| 986 | 986 | ether1_probe(struct expansion_card *ec, const struct ecard_id *id) |
| 987 | 987 | { |
| 988 | 988 | struct net_device *dev; |
| 989 | + u8 addr[ETH_ALEN]; | |
| 989 | 990 | int i, ret = 0; |
| 990 | 991 | |
| 991 | 992 | ether1_banner(); |
| @@ -1015,7 +1016,8 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) · 23 unmodified lines | ||
| 1015 | 1016 | } |
| 1016 | 1017 | |
| 1017 | 1018 | for (i = 0; i < 6; i++) |
| 1018 | − dev->dev_addr[i] = readb(IDPROM_ADDRESS + (i << 2)); | |
| 1019 | + addr[i] = readb(IDPROM_ADDRESS + (i << 2)); | |
| 1020 | + eth_hw_addr_set(dev, addr); | |
| 1019 | 1021 | |
| 1020 | 1022 | if (ether1_init_2(dev)) { |
| 1021 | 1023 | ret = -ENODEV; |
| @@ -2602,6 +2602,7 @@ static void __ibmvnic_reset(struct work_struct *work) · 2601 unmodified lines | ||
| 2602 | 2602 | struct ibmvnic_rwi *rwi; |
| 2603 | 2603 | unsigned long flags; |
| 2604 | 2604 | u32 reset_state; |
| 2605 | + int num_fails = 0; | |
| 2605 | 2606 | int rc = 0; |
| 2606 | 2607 | |
| 2607 | 2608 | adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); |
| @@ -2655,11 +2656,23 @@ static void __ibmvnic_reset(struct work_struct *work) · 47 unmodified lines | ||
| 2655 | 2656 | rc = do_hard_reset(adapter, rwi, reset_state); |
| 2656 | 2657 | rtnl_unlock(); |
| 2657 | 2658 | } |
| 2658 | − if (rc) { | |
| 2659 | − /* give backing device time to settle down */ | |
| 2659 | + if (rc) | |
| 2660 | + num_fails++; | |
| 2661 | + else | |
| 2662 | + num_fails = 0; | |
| 2663 | + | |
| 2664 | + /* If auto-priority-failover is enabled we can get | |
| 2665 | + * back to back failovers during resets, resulting | |
| 2666 | + * in at least two failed resets (from high-priority | |
| 2667 | + * backing device to low-priority one and then back) | |
| 2668 | + * If resets continue to fail beyond that, give the | |
| 2669 | + * adapter some time to settle down before retrying. | |
| 2670 | + */ | |
| 2671 | + if (num_fails >= 3) { | |
| 2660 | 2672 | netdev_dbg(adapter->netdev, |
| 2661 | − "[S:%s] Hard reset failed, waiting 60 secs\n", | |
| 2662 | − adapter_state_to_string(adapter->state)); | |
| 2673 | + "[S:%s] Hard reset failed %d times, waiting 60 secs\n", | |
| 2674 | + adapter_state_to_string(adapter->state), | |
| 2675 | + num_fails); | |
| 2663 | 2676 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 2664 | 2677 | schedule_timeout(60 * HZ); |
| 2665 | 2678 | } |
| @@ -3844,11 +3857,25 @@ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry) · 1178 unmodified lines | ||
| 3844 | 3857 | struct device *dev = &adapter->vdev->dev; |
| 3845 | 3858 | union ibmvnic_crq crq; |
| 3846 | 3859 | int max_entries; |
| 3860 | + int cap_reqs; | |
| 3861 | + | |
| 3862 | + /* We send out 6 or 7 REQUEST_CAPABILITY CRQs below (depending on | |
| 3863 | + * the PROMISC flag). Initialize this count upfront. When the tasklet | |
| 3864 | + * receives a response to all of these, it will send the next protocol | |
| 3865 | + * message (QUERY_IP_OFFLOAD). | |
| 3866 | + */ | |
| 3867 | + if (!(adapter->netdev->flags & IFF_PROMISC) || | |
| 3868 | + adapter->promisc_supported) | |
| 3869 | + cap_reqs = 7; | |
| 3870 | + else | |
| 3871 | + cap_reqs = 6; | |
| 3847 | 3872 | |
| 3848 | 3873 | if (!retry) { |
| 3849 | 3874 | /* Sub-CRQ entries are 32 byte long */ |
| 3850 | 3875 | int entries_page = 4 * PAGE_SIZE / (sizeof(u64) * 4); |
| 3851 | 3876 | |
| 3877 | + atomic_set(&adapter->running_cap_crqs, cap_reqs); | |
| 3878 | + | |
| 3852 | 3879 | if (adapter->min_tx_entries_per_subcrq > entries_page || |
| 3853 | 3880 | adapter->min_rx_add_entries_per_subcrq > entries_page) { |
| 3854 | 3881 | dev_err(dev, "Fatal, invalid entries per sub-crq\n"); |
| @@ -3909,44 +3936,45 @@ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry) · 54 unmodified lines | ||
| 3909 | 3936 | adapter->opt_rx_comp_queues; |
| 3910 | 3937 | |
| 3911 | 3938 | adapter->req_rx_add_queues = adapter->max_rx_add_queues; |
| 3939 | + } else { | |
| 3940 | + atomic_add(cap_reqs, &adapter->running_cap_crqs); | |
| 3912 | 3941 | } |
| 3913 | − | |
| 3914 | 3942 | memset(&crq, 0, sizeof(crq)); |
| 3915 | 3943 | crq.request_capability.first = IBMVNIC_CRQ_CMD; |
| 3916 | 3944 | crq.request_capability.cmd = REQUEST_CAPABILITY; |
| 3917 | 3945 | |
| 3918 | 3946 | crq.request_capability.capability = cpu_to_be16(REQ_TX_QUEUES); |
| 3919 | 3947 | crq.request_capability.number = cpu_to_be64(adapter->req_tx_queues); |
| 3920 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3948 | + cap_reqs--; | |
| 3921 | 3949 | ibmvnic_send_crq(adapter, &crq); |
| 3922 | 3950 | |
| 3923 | 3951 | crq.request_capability.capability = cpu_to_be16(REQ_RX_QUEUES); |
| 3924 | 3952 | crq.request_capability.number = cpu_to_be64(adapter->req_rx_queues); |
| 3925 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3953 | + cap_reqs--; | |
| 3926 | 3954 | ibmvnic_send_crq(adapter, &crq); |
| 3927 | 3955 | |
| 3928 | 3956 | crq.request_capability.capability = cpu_to_be16(REQ_RX_ADD_QUEUES); |
| 3929 | 3957 | crq.request_capability.number = cpu_to_be64(adapter->req_rx_add_queues); |
| 3930 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3958 | + cap_reqs--; | |
| 3931 | 3959 | ibmvnic_send_crq(adapter, &crq); |
| 3932 | 3960 | |
| 3933 | 3961 | crq.request_capability.capability = |
| 3934 | 3962 | cpu_to_be16(REQ_TX_ENTRIES_PER_SUBCRQ); |
| 3935 | 3963 | crq.request_capability.number = |
| 3936 | 3964 | cpu_to_be64(adapter->req_tx_entries_per_subcrq); |
| 3937 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3965 | + cap_reqs--; | |
| 3938 | 3966 | ibmvnic_send_crq(adapter, &crq); |
| 3939 | 3967 | |
| 3940 | 3968 | crq.request_capability.capability = |
| 3941 | 3969 | cpu_to_be16(REQ_RX_ADD_ENTRIES_PER_SUBCRQ); |
| 3942 | 3970 | crq.request_capability.number = |
| 3943 | 3971 | cpu_to_be64(adapter->req_rx_add_entries_per_subcrq); |
| 3944 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3972 | + cap_reqs--; | |
| 3945 | 3973 | ibmvnic_send_crq(adapter, &crq); |
| 3946 | 3974 | |
| 3947 | 3975 | crq.request_capability.capability = cpu_to_be16(REQ_MTU); |
| 3948 | 3976 | crq.request_capability.number = cpu_to_be64(adapter->req_mtu); |
| 3949 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3977 | + cap_reqs--; | |
| 3950 | 3978 | ibmvnic_send_crq(adapter, &crq); |
| 3951 | 3979 | |
| 3952 | 3980 | if (adapter->netdev->flags & IFF_PROMISC) { |
| @@ -3954,16 +3982,21 @@ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry) · 1 unmodified line | ||
| 3954 | 3982 | crq.request_capability.capability = |
| 3955 | 3983 | cpu_to_be16(PROMISC_REQUESTED); |
| 3956 | 3984 | crq.request_capability.number = cpu_to_be64(1); |
| 3957 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3985 | + cap_reqs--; | |
| 3958 | 3986 | ibmvnic_send_crq(adapter, &crq); |
| 3959 | 3987 | } |
| 3960 | 3988 | } else { |
| 3961 | 3989 | crq.request_capability.capability = |
| 3962 | 3990 | cpu_to_be16(PROMISC_REQUESTED); |
| 3963 | 3991 | crq.request_capability.number = cpu_to_be64(0); |
| 3964 | − atomic_inc(&adapter->running_cap_crqs); | |
| 3992 | + cap_reqs--; | |
| 3965 | 3993 | ibmvnic_send_crq(adapter, &crq); |
| 3966 | 3994 | } |
| 3995 | + | |
| 3996 | + /* Keep at end to catch any discrepancy between expected and actual | |
| 3997 | + * CRQs sent. | |
| 3998 | + */ | |
| 3999 | + WARN_ON(cap_reqs != 0); | |
| 3967 | 4000 | } |
| 3968 | 4001 | |
| 3969 | 4002 | static int pending_scrq(struct ibmvnic_adapter *adapter, |
| @@ -4357,118 +4390,132 @@ static void send_query_map(struct ibmvnic_adapter *adapter) · 387 unmodified lines | ||
| 4357 | 4390 | static void send_query_cap(struct ibmvnic_adapter *adapter) |
| 4358 | 4391 | { |
| 4359 | 4392 | union ibmvnic_crq crq; |
| 4393 | + int cap_reqs; | |
| 4394 | + | |
| 4395 | + /* We send out 25 QUERY_CAPABILITY CRQs below. Initialize this count | |
| 4396 | + * upfront. When the tasklet receives a response to all of these, it | |
| 4397 | + * can send out the next protocol messaage (REQUEST_CAPABILITY). | |
| 4398 | + */ | |
| 4399 | + cap_reqs = 25; | |
| 4400 | + | |
| 4401 | + atomic_set(&adapter->running_cap_crqs, cap_reqs); | |
| 4360 | 4402 | |
| 4361 | − atomic_set(&adapter->running_cap_crqs, 0); | |
| 4362 | 4403 | memset(&crq, 0, sizeof(crq)); |
| 4363 | 4404 | crq.query_capability.first = IBMVNIC_CRQ_CMD; |
| 4364 | 4405 | crq.query_capability.cmd = QUERY_CAPABILITY; |
| 4365 | 4406 | |
| 4366 | 4407 | crq.query_capability.capability = cpu_to_be16(MIN_TX_QUEUES); |
| 4367 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4368 | 4408 | ibmvnic_send_crq(adapter, &crq); |
| 4409 | + cap_reqs--; | |
| 4369 | 4410 | |
| 4370 | 4411 | crq.query_capability.capability = cpu_to_be16(MIN_RX_QUEUES); |
| 4371 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4372 | 4412 | ibmvnic_send_crq(adapter, &crq); |
| 4413 | + cap_reqs--; | |
| 4373 | 4414 | |
| 4374 | 4415 | crq.query_capability.capability = cpu_to_be16(MIN_RX_ADD_QUEUES); |
| 4375 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4376 | 4416 | ibmvnic_send_crq(adapter, &crq); |
| 4417 | + cap_reqs--; | |
| 4377 | 4418 | |
| 4378 | 4419 | crq.query_capability.capability = cpu_to_be16(MAX_TX_QUEUES); |
| 4379 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4380 | 4420 | ibmvnic_send_crq(adapter, &crq); |
| 4421 | + cap_reqs--; | |
| 4381 | 4422 | |
| 4382 | 4423 | crq.query_capability.capability = cpu_to_be16(MAX_RX_QUEUES); |
| 4383 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4384 | 4424 | ibmvnic_send_crq(adapter, &crq); |
| 4425 | + cap_reqs--; | |
| 4385 | 4426 | |
| 4386 | 4427 | crq.query_capability.capability = cpu_to_be16(MAX_RX_ADD_QUEUES); |
| 4387 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4388 | 4428 | ibmvnic_send_crq(adapter, &crq); |
| 4429 | + cap_reqs--; | |
| 4389 | 4430 | |
| 4390 | 4431 | crq.query_capability.capability = |
| 4391 | 4432 | cpu_to_be16(MIN_TX_ENTRIES_PER_SUBCRQ); |
| 4392 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4393 | 4433 | ibmvnic_send_crq(adapter, &crq); |
| 4434 | + cap_reqs--; | |
| 4394 | 4435 | |
| 4395 | 4436 | crq.query_capability.capability = |
| 4396 | 4437 | cpu_to_be16(MIN_RX_ADD_ENTRIES_PER_SUBCRQ); |
| 4397 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4398 | 4438 | ibmvnic_send_crq(adapter, &crq); |
| 4439 | + cap_reqs--; | |
| 4399 | 4440 | |
| 4400 | 4441 | crq.query_capability.capability = |
| 4401 | 4442 | cpu_to_be16(MAX_TX_ENTRIES_PER_SUBCRQ); |
| 4402 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4403 | 4443 | ibmvnic_send_crq(adapter, &crq); |
| 4444 | + cap_reqs--; | |
| 4404 | 4445 | |
| 4405 | 4446 | crq.query_capability.capability = |
| 4406 | 4447 | cpu_to_be16(MAX_RX_ADD_ENTRIES_PER_SUBCRQ); |
| 4407 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4408 | 4448 | ibmvnic_send_crq(adapter, &crq); |
| 4449 | + cap_reqs--; | |
| 4409 | 4450 | |
| 4410 | 4451 | crq.query_capability.capability = cpu_to_be16(TCP_IP_OFFLOAD); |
| 4411 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4412 | 4452 | ibmvnic_send_crq(adapter, &crq); |
| 4453 | + cap_reqs--; | |
| 4413 | 4454 | |
| 4414 | 4455 | crq.query_capability.capability = cpu_to_be16(PROMISC_SUPPORTED); |
| 4415 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4416 | 4456 | ibmvnic_send_crq(adapter, &crq); |
| 4457 | + cap_reqs--; | |
| 4417 | 4458 | |
| 4418 | 4459 | crq.query_capability.capability = cpu_to_be16(MIN_MTU); |
| 4419 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4420 | 4460 | ibmvnic_send_crq(adapter, &crq); |
| 4461 | + cap_reqs--; | |
| 4421 | 4462 | |
| 4422 | 4463 | crq.query_capability.capability = cpu_to_be16(MAX_MTU); |
| 4423 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4424 | 4464 | ibmvnic_send_crq(adapter, &crq); |
| 4465 | + cap_reqs--; | |
| 4425 | 4466 | |
| 4426 | 4467 | crq.query_capability.capability = cpu_to_be16(MAX_MULTICAST_FILTERS); |
| 4427 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4428 | 4468 | ibmvnic_send_crq(adapter, &crq); |
| 4469 | + cap_reqs--; | |
| 4429 | 4470 | |
| 4430 | 4471 | crq.query_capability.capability = cpu_to_be16(VLAN_HEADER_INSERTION); |
| 4431 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4432 | 4472 | ibmvnic_send_crq(adapter, &crq); |
| 4473 | + cap_reqs--; | |
| 4433 | 4474 | |
| 4434 | 4475 | crq.query_capability.capability = cpu_to_be16(RX_VLAN_HEADER_INSERTION); |
| 4435 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4436 | 4476 | ibmvnic_send_crq(adapter, &crq); |
| 4477 | + cap_reqs--; | |
| 4437 | 4478 | |
| 4438 | 4479 | crq.query_capability.capability = cpu_to_be16(MAX_TX_SG_ENTRIES); |
| 4439 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4440 | 4480 | ibmvnic_send_crq(adapter, &crq); |
| 4481 | + cap_reqs--; | |
| 4441 | 4482 | |
| 4442 | 4483 | crq.query_capability.capability = cpu_to_be16(RX_SG_SUPPORTED); |
| 4443 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4444 | 4484 | ibmvnic_send_crq(adapter, &crq); |
| 4485 | + cap_reqs--; | |
| 4445 | 4486 | |
| 4446 | 4487 | crq.query_capability.capability = cpu_to_be16(OPT_TX_COMP_SUB_QUEUES); |
| 4447 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4448 | 4488 | ibmvnic_send_crq(adapter, &crq); |
| 4489 | + cap_reqs--; | |
| 4449 | 4490 | |
| 4450 | 4491 | crq.query_capability.capability = cpu_to_be16(OPT_RX_COMP_QUEUES); |
| 4451 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4452 | 4492 | ibmvnic_send_crq(adapter, &crq); |
| 4493 | + cap_reqs--; | |
| 4453 | 4494 | |
| 4454 | 4495 | crq.query_capability.capability = |
| 4455 | 4496 | cpu_to_be16(OPT_RX_BUFADD_Q_PER_RX_COMP_Q); |
| 4456 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4457 | 4497 | ibmvnic_send_crq(adapter, &crq); |
| 4498 | + cap_reqs--; | |
| 4458 | 4499 | |
| 4459 | 4500 | crq.query_capability.capability = |
| 4460 | 4501 | cpu_to_be16(OPT_TX_ENTRIES_PER_SUBCRQ); |
| 4461 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4462 | 4502 | ibmvnic_send_crq(adapter, &crq); |
| 4503 | + cap_reqs--; | |
| 4463 | 4504 | |
| 4464 | 4505 | crq.query_capability.capability = |
| 4465 | 4506 | cpu_to_be16(OPT_RXBA_ENTRIES_PER_SUBCRQ); |
| 4466 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4467 | 4507 | ibmvnic_send_crq(adapter, &crq); |
| 4508 | + cap_reqs--; | |
| 4468 | 4509 | |
| 4469 | 4510 | crq.query_capability.capability = cpu_to_be16(TX_RX_DESC_REQ); |
| 4470 | − atomic_inc(&adapter->running_cap_crqs); | |
| 4511 | + | |
| 4471 | 4512 | ibmvnic_send_crq(adapter, &crq); |
| 4513 | + cap_reqs--; | |
| 4514 | + | |
| 4515 | + /* Keep at end to catch any discrepancy between expected and actual | |
| 4516 | + * CRQs sent. | |
| 4517 | + */ | |
| 4518 | + WARN_ON(cap_reqs != 0); | |
| 4472 | 4519 | } |
| 4473 | 4520 | |
| 4474 | 4521 | static void send_query_ip_offload(struct ibmvnic_adapter *adapter) |
| @@ -4772,6 +4819,8 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq, · 297 unmodified lines | ||
| 4772 | 4819 | char *name; |
| 4773 | 4820 | |
| 4774 | 4821 | atomic_dec(&adapter->running_cap_crqs); |
| 4822 | + netdev_dbg(adapter->netdev, "Outstanding request-caps: %d\n", | |
| 4823 | + atomic_read(&adapter->running_cap_crqs)); | |
| 4775 | 4824 | switch (be16_to_cpu(crq->request_capability_rsp.capability)) { |
| 4776 | 4825 | case REQ_TX_QUEUES: |
| 4777 | 4826 | req_value = &adapter->req_tx_queues; |
| @@ -4835,10 +4884,8 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq, · 57 unmodified lines | ||
| 4835 | 4884 | } |
| 4836 | 4885 | |
| 4837 | 4886 | /* Done receiving requested capabilities, query IP offload support */ |
| 4838 | − if (atomic_read(&adapter->running_cap_crqs) == 0) { | |
| 4839 | − adapter->wait_capability = false; | |
| 4887 | + if (atomic_read(&adapter->running_cap_crqs) == 0) | |
| 4840 | 4888 | send_query_ip_offload(adapter); |
| 4841 | − } | |
| 4842 | 4889 | } |
| 4843 | 4890 | |
| 4844 | 4891 | static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, |
| @@ -5136,10 +5183,8 @@ static void handle_query_cap_rsp(union ibmvnic_crq *crq, · 291 unmodified lines | ||
| 5136 | 5183 | } |
| 5137 | 5184 | |
| 5138 | 5185 | out: |
| 5139 | − if (atomic_read(&adapter->running_cap_crqs) == 0) { | |
| 5140 | − adapter->wait_capability = false; | |
| 5186 | + if (atomic_read(&adapter->running_cap_crqs) == 0) | |
| 5141 | 5187 | send_request_cap(adapter, 0); |
| 5142 | − } | |
| 5143 | 5188 | } |
| 5144 | 5189 | |
| 5145 | 5190 | static int send_query_phys_parms(struct ibmvnic_adapter *adapter) |
| @@ -5435,33 +5480,21 @@ static void ibmvnic_tasklet(struct tasklet_struct *t) · 289 unmodified lines | ||
| 5435 | 5480 | struct ibmvnic_crq_queue *queue = &adapter->crq; |
| 5436 | 5481 | union ibmvnic_crq *crq; |
| 5437 | 5482 | unsigned long flags; |
| 5438 | − bool done = false; | |
| 5439 | 5483 | |
| 5440 | 5484 | spin_lock_irqsave(&queue->lock, flags); |
| 5441 | − while (!done) { | |
| 5442 | − /* Pull all the valid messages off the CRQ */ | |
| 5443 | − while ((crq = ibmvnic_next_crq(adapter)) != NULL) { | |
| 5444 | − /* This barrier makes sure ibmvnic_next_crq()'s | |
| 5445 | − * crq->generic.first & IBMVNIC_CRQ_CMD_RSP is loaded | |
| 5446 | − * before ibmvnic_handle_crq()'s | |
| 5447 | − * switch(gen_crq->first) and switch(gen_crq->cmd). | |
| 5448 | − */ | |
| 5449 | − dma_rmb(); | |
| 5450 | − ibmvnic_handle_crq(crq, adapter); | |
| 5451 | − crq->generic.first = 0; | |
| 5452 | − } | |
| 5453 | 5485 | |
| 5454 | − /* remain in tasklet until all | |
| 5455 | − * capabilities responses are received | |
| 5486 | + /* Pull all the valid messages off the CRQ */ | |
| 5487 | + while ((crq = ibmvnic_next_crq(adapter)) != NULL) { | |
| 5488 | + /* This barrier makes sure ibmvnic_next_crq()'s | |
| 5489 | + * crq->generic.first & IBMVNIC_CRQ_CMD_RSP is loaded | |
| 5490 | + * before ibmvnic_handle_crq()'s | |
| 5491 | + * switch(gen_crq->first) and switch(gen_crq->cmd). | |
| 5456 | 5492 | */ |
| 5457 | − if (!adapter->wait_capability) | |
| 5458 | − done = true; | |
| 5493 | + dma_rmb(); | |
| 5494 | + ibmvnic_handle_crq(crq, adapter); | |
| 5495 | + crq->generic.first = 0; | |
| 5459 | 5496 | } |
| 5460 | − /* if capabilities CRQ's were sent in this tasklet, the following | |
| 5461 | − * tasklet must wait until all responses are received | |
| 5462 | − */ | |
| 5463 | − if (atomic_read(&adapter->running_cap_crqs) != 0) | |
| 5464 | − adapter->wait_capability = true; | |
| 5497 | + | |
| 5465 | 5498 | spin_unlock_irqrestore(&queue->lock, flags); |
| 5466 | 5499 | } |
| 5467 | 5500 | |
| @@ -919,7 +919,6 @@ struct ibmvnic_adapter { · 918 unmodified lines | ||
| 919 | 919 | int login_rsp_buf_sz; |
| 920 | 920 | |
| 921 | 921 | atomic_t running_cap_crqs; |
| 922 | − bool wait_capability; | |
| 923 | 922 | |
| 924 | 923 | struct ibmvnic_sub_crq_queue **tx_scrq ____cacheline_aligned; |
| 925 | 924 | struct ibmvnic_sub_crq_queue **rx_scrq ____cacheline_aligned; |
| @@ -174,7 +174,6 @@ enum i40e_interrupt_policy { · 173 unmodified lines | ||
| 174 | 174 | |
| 175 | 175 | struct i40e_lump_tracking { |
| 176 | 176 | u16 num_entries; |
| 177 | − u16 search_hint; | |
| 178 | 177 | u16 list[0]; |
| 179 | 178 | #define I40E_PILE_VALID_BIT 0x8000 |
| 180 | 179 | #define I40E_IWARP_IRQ_PILE_ID (I40E_PILE_VALID_BIT - 2) |
| @@ -848,12 +847,12 @@ struct i40e_vsi { · 667 unmodified lines | ||
| 848 | 847 | struct rtnl_link_stats64 net_stats_offsets; |
| 849 | 848 | struct i40e_eth_stats eth_stats; |
| 850 | 849 | struct i40e_eth_stats eth_stats_offsets; |
| 851 | − u32 tx_restart; | |
| 852 | − u32 tx_busy; | |
| 850 | + u64 tx_restart; | |
| 851 | + u64 tx_busy; | |
| 853 | 852 | u64 tx_linearize; |
| 854 | 853 | u64 tx_force_wb; |
| 855 | − u32 rx_buf_failed; | |
| 856 | − u32 rx_page_failed; | |
| 854 | + u64 rx_buf_failed; | |
| 855 | + u64 rx_page_failed; | |
| 857 | 856 | |
| 858 | 857 | /* These are containers of ring pointers, allocated at run-time */ |
| 859 | 858 | struct i40e_ring **rx_rings; |
| @@ -240,7 +240,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid) · 239 unmodified lines | ||
| 240 | 240 | (unsigned long int)vsi->net_stats_offsets.rx_compressed, |
| 241 | 241 | (unsigned long int)vsi->net_stats_offsets.tx_compressed); |
| 242 | 242 | dev_info(&pf->pdev->dev, |
| 243 | − " tx_restart = %d, tx_busy = %d, rx_buf_failed = %d, rx_page_failed = %d\n", | |
| 243 | + " tx_restart = %llu, tx_busy = %llu, rx_buf_failed = %llu, rx_page_failed = %llu\n", | |
| 244 | 244 | vsi->tx_restart, vsi->tx_busy, |
| 245 | 245 | vsi->rx_buf_failed, vsi->rx_page_failed); |
| 246 | 246 | rcu_read_lock(); |
| @@ -196,10 +196,6 @@ int i40e_free_virt_mem_d(struct i40e_hw *hw, struct i40e_virt_mem *mem) · 195 unmodified lines | ||
| 196 | 196 | * @id: an owner id to stick on the items assigned |
| 197 | 197 | * |
| 198 | 198 | * Returns the base item index of the lump, or negative for error |
| 199 | − * | |
| 200 | − * The search_hint trick and lack of advanced fit-finding only work | |
| 201 | − * because we're highly likely to have all the same size lump requests. | |
| 202 | − * Linear search time and any fragmentation should be minimal. | |
| 203 | 199 | **/ |
| 204 | 200 | static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile, |
| 205 | 201 | u16 needed, u16 id) |
| @@ -214,8 +210,21 @@ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile, · 8 unmodified lines | ||
| 214 | 210 | return -EINVAL; |
| 215 | 211 | } |
| 216 | 212 | |
| 217 | − /* start the linear search with an imperfect hint */ | |
| 218 | − i = pile->search_hint; | |
| 213 | + /* Allocate last queue in the pile for FDIR VSI queue | |
| 214 | + * so it doesn't fragment the qp_pile | |
| 215 | + */ | |
| 216 | + if (pile == pf->qp_pile && pf->vsi[id]->type == I40E_VSI_FDIR) { | |
| 217 | + if (pile->list[pile->num_entries - 1] & I40E_PILE_VALID_BIT) { | |
| 218 | + dev_err(&pf->pdev->dev, | |
| 219 | + "Cannot allocate queue %d for I40E_VSI_FDIR\n", | |
| 220 | + pile->num_entries - 1); | |
| 221 | + return -ENOMEM; | |
| 222 | + } | |
| 223 | + pile->list[pile->num_entries - 1] = id | I40E_PILE_VALID_BIT; | |
| 224 | + return pile->num_entries - 1; | |
| 225 | + } | |
| 226 | + | |
| 227 | + i = 0; | |
| 219 | 228 | while (i < pile->num_entries) { |
| 220 | 229 | /* skip already allocated entries */ |
| 221 | 230 | if (pile->list[i] & I40E_PILE_VALID_BIT) { |
| @@ -234,7 +243,6 @@ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile, · 12 unmodified lines | ||
| 234 | 243 | for (j = 0; j < needed; j++) |
| 235 | 244 | pile->list[i+j] = id | I40E_PILE_VALID_BIT; |
| 236 | 245 | ret = i; |
| 237 | − pile->search_hint = i + j; | |
| 238 | 246 | break; |
| 239 | 247 | } |
| 240 | 248 | |
| @@ -257,7 +265,7 @@ static int i40e_put_lump(struct i40e_lump_tracking *pile, u16 index, u16 id) · 16 unmodified lines | ||
| 257 | 265 | { |
| 258 | 266 | int valid_id = (id | I40E_PILE_VALID_BIT); |
| 259 | 267 | int count = 0; |
| 260 | − int i; | |
| 268 | + u16 i; | |
| 261 | 269 | |
| 262 | 270 | if (!pile || index >= pile->num_entries) |
| 263 | 271 | return -EINVAL; |
| @@ -269,8 +277,6 @@ static int i40e_put_lump(struct i40e_lump_tracking *pile, u16 index, u16 id) · 5 unmodified lines | ||
| 269 | 277 | count++; |
| 270 | 278 | } |
| 271 | 279 | |
| 272 | − if (count && index < pile->search_hint) | |
| 273 | − pile->search_hint = index; | |
| 274 | 280 | |
| 275 | 281 | return count; |
| 276 | 282 | } |
| @@ -772,9 +778,9 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) · 495 unmodified lines | ||
| 772 | 778 | struct rtnl_link_stats64 *ns; /* netdev stats */ |
| 773 | 779 | struct i40e_eth_stats *oes; |
| 774 | 780 | struct i40e_eth_stats *es; /* device's eth stats */ |
| 775 | − u32 tx_restart, tx_busy; | |
| 781 | + u64 tx_restart, tx_busy; | |
| 776 | 782 | struct i40e_ring *p; |
| 777 | − u32 rx_page, rx_buf; | |
| 783 | + u64 rx_page, rx_buf; | |
| 778 | 784 | u64 bytes, packets; |
| 779 | 785 | unsigned int start; |
| 780 | 786 | u64 tx_linearize; |
| @@ -10574,15 +10580,9 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) · 9793 unmodified lines | ||
| 10574 | 10580 | } |
| 10575 | 10581 | i40e_get_oem_version(&pf->hw); |
| 10576 | 10582 | |
| 10577 | − if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) && | |
| 10578 | − ((hw->aq.fw_maj_ver == 4 && hw->aq.fw_min_ver <= 33) || | |
| 10579 | − hw->aq.fw_maj_ver < 4) && hw->mac.type == I40E_MAC_XL710) { | |
| 10580 | − /* The following delay is necessary for 4.33 firmware and older | |
| 10581 | − * to recover after EMP reset. 200 ms should suffice but we | |
| 10582 | − * put here 300 ms to be sure that FW is ready to operate | |
| 10583 | − * after reset. | |
| 10584 | − */ | |
| 10585 | − mdelay(300); | |
| 10583 | + if (test_and_clear_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state)) { | |
| 10584 | + /* The following delay is necessary for firmware update. */ | |
| 10585 | + mdelay(1000); | |
| 10586 | 10586 | } |
| 10587 | 10587 | |
| 10588 | 10588 | /* re-verify the eeprom if we just had an EMP reset */ |
| @@ -11792,7 +11792,6 @@ static int i40e_init_interrupt_scheme(struct i40e_pf *pf) · 1203 unmodified lines | ||
| 11792 | 11792 | return -ENOMEM; |
| 11793 | 11793 | |
| 11794 | 11794 | pf->irq_pile->num_entries = vectors; |
| 11795 | − pf->irq_pile->search_hint = 0; | |
| 11796 | 11795 | |
| 11797 | 11796 | /* track first vector for misc interrupts, ignore return */ |
| 11798 | 11797 | (void)i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT - 1); |
| @@ -12595,7 +12594,6 @@ static int i40e_sw_init(struct i40e_pf *pf) · 796 unmodified lines | ||
| 12595 | 12594 | goto sw_init_done; |
| 12596 | 12595 | } |
| 12597 | 12596 | pf->qp_pile->num_entries = pf->hw.func_caps.num_tx_qp; |
| 12598 | − pf->qp_pile->search_hint = 0; | |
| 12599 | 12597 | |
| 12600 | 12598 | pf->tx_timeout_recovery_level = 1; |
| 12601 | 12599 | |
| @@ -413,6 +413,9 @@ · 412 unmodified lines | ||
| 413 | 413 | #define I40E_VFINT_DYN_CTLN(_INTVF) (0x00024800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */ |
| 414 | 414 | #define I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT 1 |
| 415 | 415 | #define I40E_VFINT_DYN_CTLN_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT) |
| 416 | +#define I40E_VFINT_ICR0_ADMINQ_SHIFT 30 | |
| 417 | +#define I40E_VFINT_ICR0_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ADMINQ_SHIFT) | |
| 418 | +#define I40E_VFINT_ICR0_ENA(_VF) (0x0002C000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */ | |
| 416 | 419 | #define I40E_VPINT_AEQCTL(_VF) (0x0002B800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */ |
| 417 | 420 | #define I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT 0 |
| 418 | 421 | #define I40E_VPINT_AEQCTL_ITR_INDX_SHIFT 11 |
| @@ -1376,6 +1376,32 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf, · 1375 unmodified lines | ||
| 1376 | 1376 | return aq_ret; |
| 1377 | 1377 | } |
| 1378 | 1378 | |
| 1379 | +/** | |
| 1380 | + * i40e_sync_vfr_reset | |
| 1381 | + * @hw: pointer to hw struct | |
| 1382 | + * @vf_id: VF identifier | |
| 1383 | + * | |
| 1384 | + * Before trigger hardware reset, we need to know if no other process has | |
| 1385 | + * reserved the hardware for any reset operations. This check is done by | |
| 1386 | + * examining the status of the RSTAT1 register used to signal the reset. | |
| 1387 | + **/ | |
| 1388 | +static int i40e_sync_vfr_reset(struct i40e_hw *hw, int vf_id) | |
| 1389 | +{ | |
| 1390 | + u32 reg; | |
| 1391 | + int i; | |
| 1392 | + | |
| 1393 | + for (i = 0; i < I40E_VFR_WAIT_COUNT; i++) { | |
| 1394 | + reg = rd32(hw, I40E_VFINT_ICR0_ENA(vf_id)) & | |
| 1395 | + I40E_VFINT_ICR0_ADMINQ_MASK; | |
| 1396 | + if (reg) | |
| 1397 | + return 0; | |
| 1398 | + | |
| 1399 | + usleep_range(100, 200); | |
| 1400 | + } | |
| 1401 | + | |
| 1402 | + return -EAGAIN; | |
| 1403 | +} | |
| 1404 | + | |
| 1379 | 1405 | /** |
| 1380 | 1406 | * i40e_trigger_vf_reset |
| 1381 | 1407 | * @vf: pointer to the VF structure |
| @@ -1390,9 +1416,11 @@ static void i40e_trigger_vf_reset(struct i40e_vf *vf, bool flr) · 8 unmodified lines | ||
| 1390 | 1416 | struct i40e_pf *pf = vf->pf; |
| 1391 | 1417 | struct i40e_hw *hw = &pf->hw; |
| 1392 | 1418 | u32 reg, reg_idx, bit_idx; |
| 1419 | + bool vf_active; | |
| 1420 | + u32 radq; | |
| 1393 | 1421 | |
| 1394 | 1422 | /* warn the VF */ |
| 1395 | − clear_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states); | |
| 1423 | + vf_active = test_and_clear_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states); | |
| 1396 | 1424 | |
| 1397 | 1425 | /* Disable VF's configuration API during reset. The flag is re-enabled |
| 1398 | 1426 | * in i40e_alloc_vf_res(), when it's safe again to access VF's VSI. |
| @@ -1406,7 +1434,19 @@ static void i40e_trigger_vf_reset(struct i40e_vf *vf, bool flr) · 7 unmodified lines | ||
| 1406 | 1434 | * just need to clean up, so don't hit the VFRTRIG register. |
| 1407 | 1435 | */ |
| 1408 | 1436 | if (!flr) { |
| 1409 | − /* reset VF using VPGEN_VFRTRIG reg */ | |
| 1437 | + /* Sync VFR reset before trigger next one */ | |
| 1438 | + radq = rd32(hw, I40E_VFINT_ICR0_ENA(vf->vf_id)) & | |
| 1439 | + I40E_VFINT_ICR0_ADMINQ_MASK; | |
| 1440 | + if (vf_active && !radq) | |
| 1441 | + /* waiting for finish reset by virtual driver */ | |
| 1442 | + if (i40e_sync_vfr_reset(hw, vf->vf_id)) | |
| 1443 | + dev_info(&pf->pdev->dev, | |
| 1444 | + "Reset VF %d never finished\n", | |
| 1445 | + vf->vf_id); | |
| 1446 | + | |
| 1447 | + /* Reset VF using VPGEN_VFRTRIG reg. It is also setting | |
| 1448 | + * in progress state in rstat1 register. | |
| 1449 | + */ | |
| 1410 | 1450 | reg = rd32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id)); |
| 1411 | 1451 | reg |= I40E_VPGEN_VFRTRIG_VFSWR_MASK; |
| 1412 | 1452 | wr32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id), reg); |
| @@ -2617,6 +2657,59 @@ error_param: · 1204 unmodified lines | ||
| 2617 | 2657 | aq_ret); |
| 2618 | 2658 | } |
| 2619 | 2659 | |
| 2660 | +/** | |
| 2661 | + * i40e_check_enough_queue - find big enough queue number | |
| 2662 | + * @vf: pointer to the VF info | |
| 2663 | + * @needed: the number of items needed | |
| 2664 | + * | |
| 2665 | + * Returns the base item index of the queue, or negative for error | |
| 2666 | + **/ | |
| 2667 | +static int i40e_check_enough_queue(struct i40e_vf *vf, u16 needed) | |
| 2668 | +{ | |
| 2669 | + unsigned int i, cur_queues, more, pool_size; | |
| 2670 | + struct i40e_lump_tracking *pile; | |
| 2671 | + struct i40e_pf *pf = vf->pf; | |
| 2672 | + struct i40e_vsi *vsi; | |
| 2673 | + | |
| 2674 | + vsi = pf->vsi[vf->lan_vsi_idx]; | |
| 2675 | + cur_queues = vsi->alloc_queue_pairs; | |
| 2676 | + | |
| 2677 | + /* if current allocated queues are enough for need */ | |
| 2678 | + if (cur_queues >= needed) | |
| 2679 | + return vsi->base_queue; | |
| 2680 | + | |
| 2681 | + pile = pf->qp_pile; | |
| 2682 | + if (cur_queues > 0) { | |
| 2683 | + /* if the allocated queues are not zero | |
| 2684 | + * just check if there are enough queues for more | |
| 2685 | + * behind the allocated queues. | |
| 2686 | + */ | |
| 2687 | + more = needed - cur_queues; | |
| 2688 | + for (i = vsi->base_queue + cur_queues; | |
| 2689 | + i < pile->num_entries; i++) { | |
| 2690 | + if (pile->list[i] & I40E_PILE_VALID_BIT) | |
| 2691 | + break; | |
| 2692 | + | |
| 2693 | + if (more-- == 1) | |
| 2694 | + /* there is enough */ | |
| 2695 | + return vsi->base_queue; | |
| 2696 | + } | |
| 2697 | + } | |
| 2698 | + | |
| 2699 | + pool_size = 0; | |
| 2700 | + for (i = 0; i < pile->num_entries; i++) { | |
| 2701 | + if (pile->list[i] & I40E_PILE_VALID_BIT) { | |
| 2702 | + pool_size = 0; | |
| 2703 | + continue; | |
| 2704 | + } | |
| 2705 | + if (needed <= ++pool_size) | |
| 2706 | + /* there is enough */ | |
| 2707 | + return i; | |
| 2708 | + } | |
| 2709 | + | |
| 2710 | + return -ENOMEM; | |
| 2711 | +} | |
| 2712 | + | |
| 2620 | 2713 | /** |
| 2621 | 2714 | * i40e_vc_request_queues_msg |
| 2622 | 2715 | * @vf: pointer to the VF info |
| @@ -2651,6 +2744,12 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg) · 28 unmodified lines | ||
| 2651 | 2744 | req_pairs - cur_pairs, |
| 2652 | 2745 | pf->queues_left); |
| 2653 | 2746 | vfres->num_queue_pairs = pf->queues_left + cur_pairs; |
| 2747 | + } else if (i40e_check_enough_queue(vf, req_pairs) < 0) { | |
| 2748 | + dev_warn(&pf->pdev->dev, | |
| 2749 | + "VF %d requested %d more queues, but there is not enough for it.\n", | |
| 2750 | + vf->vf_id, | |
| 2751 | + req_pairs - cur_pairs); | |
| 2752 | + vfres->num_queue_pairs = cur_pairs; | |
| 2654 | 2753 | } else { |
| 2655 | 2754 | /* successful request */ |
| 2656 | 2755 | vf->num_req_queues = req_pairs; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #define I40E_MAX_VF_PROMISC_FLAGS 3 |
| 20 | 20 | |
| 21 | 21 | #define I40E_VF_STATE_WAIT_COUNT 20 |
| 22 | +#define I40E_VFR_WAIT_COUNT 100 | |
| 22 | 23 | |
| 23 | 24 | /* Various queue ctrls */ |
| 24 | 25 | enum i40e_queue_ctrl { |
| @@ -1570,6 +1570,8 @@ static struct mac_ops cgx_mac_ops = { · 1569 unmodified lines | ||
| 1570 | 1570 | .mac_enadis_pause_frm = cgx_lmac_enadis_pause_frm, |
| 1571 | 1571 | .mac_pause_frm_config = cgx_lmac_pause_frm_config, |
| 1572 | 1572 | .mac_enadis_ptp_config = cgx_lmac_ptp_config, |
| 1573 | + .mac_rx_tx_enable = cgx_lmac_rx_tx_enable, | |
| 1574 | + .mac_tx_enable = cgx_lmac_tx_enable, | |
| 1573 | 1575 | }; |
| 1574 | 1576 | |
| 1575 | 1577 | static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
| @@ -107,6 +107,9 @@ struct mac_ops { · 106 unmodified lines | ||
| 107 | 107 | void (*mac_enadis_ptp_config)(void *cgxd, |
| 108 | 108 | int lmac_id, |
| 109 | 109 | bool enable); |
| 110 | + | |
| 111 | + int (*mac_rx_tx_enable)(void *cgxd, int lmac_id, bool enable); | |
| 112 | + int (*mac_tx_enable)(void *cgxd, int lmac_id, bool enable); | |
| 110 | 113 | }; |
| 111 | 114 | |
| 112 | 115 | struct cgx { |
| @@ -732,6 +732,7 @@ enum nix_af_status { · 731 unmodified lines | ||
| 732 | 732 | NIX_AF_ERR_BANDPROF_INVAL_REQ = -428, |
| 733 | 733 | NIX_AF_ERR_CQ_CTX_WRITE_ERR = -429, |
| 734 | 734 | NIX_AF_ERR_AQ_CTX_RETRY_WRITE = -430, |
| 735 | + NIX_AF_ERR_LINK_CREDITS = -431, | |
| 735 | 736 | }; |
| 736 | 737 | |
| 737 | 738 | /* For NIX RX vtag action */ |
| @@ -185,7 +185,6 @@ enum npc_kpu_parser_state { · 184 unmodified lines | ||
| 185 | 185 | NPC_S_KPU2_QINQ, |
| 186 | 186 | NPC_S_KPU2_ETAG, |
| 187 | 187 | NPC_S_KPU2_EXDSA, |
| 188 | − NPC_S_KPU2_NGIO, | |
| 189 | 188 | NPC_S_KPU2_CPT_CTAG, |
| 190 | 189 | NPC_S_KPU2_CPT_QINQ, |
| 191 | 190 | NPC_S_KPU3_CTAG, |
| @@ -212,6 +211,7 @@ enum npc_kpu_parser_state { · 20 unmodified lines | ||
| 212 | 211 | NPC_S_KPU5_NSH, |
| 213 | 212 | NPC_S_KPU5_CPT_IP, |
| 214 | 213 | NPC_S_KPU5_CPT_IP6, |
| 214 | + NPC_S_KPU5_NGIO, | |
| 215 | 215 | NPC_S_KPU6_IP6_EXT, |
| 216 | 216 | NPC_S_KPU6_IP6_HOP_DEST, |
| 217 | 217 | NPC_S_KPU6_IP6_ROUT, |
| @@ -1120,15 +1120,6 @@ static struct npc_kpu_profile_cam kpu1_cam_entries[] = { · 902 unmodified lines | ||
| 1120 | 1120 | 0x0000, |
| 1121 | 1121 | 0x0000, |
| 1122 | 1122 | }, |
| 1123 | − { | |
| 1124 | − NPC_S_KPU1_ETHER, 0xff, | |
| 1125 | − NPC_ETYPE_CTAG, | |
| 1126 | − 0xffff, | |
| 1127 | − NPC_ETYPE_NGIO, | |
| 1128 | − 0xffff, | |
| 1129 | − 0x0000, | |
| 1130 | − 0x0000, | |
| 1131 | − }, | |
| 1132 | 1123 | { |
| 1133 | 1124 | NPC_S_KPU1_ETHER, 0xff, |
| 1134 | 1125 | NPC_ETYPE_CTAG, |
| @@ -1966,6 +1957,15 @@ static struct npc_kpu_profile_cam kpu2_cam_entries[] = { · 831 unmodified lines | ||
| 1966 | 1957 | 0x0000, |
| 1967 | 1958 | 0x0000, |
| 1968 | 1959 | }, |
| 1960 | + { | |
| 1961 | + NPC_S_KPU2_CTAG, 0xff, | |
| 1962 | + NPC_ETYPE_NGIO, | |
| 1963 | + 0xffff, | |
| 1964 | + 0x0000, | |
| 1965 | + 0x0000, | |
| 1966 | + 0x0000, | |
| 1967 | + 0x0000, | |
| 1968 | + }, | |
| 1969 | 1969 | { |
| 1970 | 1970 | NPC_S_KPU2_CTAG, 0xff, |
| 1971 | 1971 | NPC_ETYPE_PPPOE, |
| @@ -2749,15 +2749,6 @@ static struct npc_kpu_profile_cam kpu2_cam_entries[] = { · 777 unmodified lines | ||
| 2749 | 2749 | 0x0000, |
| 2750 | 2750 | 0x0000, |
| 2751 | 2751 | }, |
| 2752 | − { | |
| 2753 | − NPC_S_KPU2_NGIO, 0xff, | |
| 2754 | − 0x0000, | |
| 2755 | − 0x0000, | |
| 2756 | − 0x0000, | |
| 2757 | − 0x0000, | |
| 2758 | − 0x0000, | |
| 2759 | − 0x0000, | |
| 2760 | − }, | |
| 2761 | 2752 | { |
| 2762 | 2753 | NPC_S_KPU2_CPT_CTAG, 0xff, |
| 2763 | 2754 | NPC_ETYPE_IP, |
| @@ -5089,6 +5080,15 @@ static struct npc_kpu_profile_cam kpu5_cam_entries[] = { · 2325 unmodified lines | ||
| 5089 | 5080 | 0x0000, |
| 5090 | 5081 | 0x0000, |
| 5091 | 5082 | }, |
| 5083 | + { | |
| 5084 | + NPC_S_KPU5_NGIO, 0xff, | |
| 5085 | + 0x0000, | |
| 5086 | + 0x0000, | |
| 5087 | + 0x0000, | |
| 5088 | + 0x0000, | |
| 5089 | + 0x0000, | |
| 5090 | + 0x0000, | |
| 5091 | + }, | |
| 5092 | 5092 | { |
| 5093 | 5093 | NPC_S_NA, 0X00, |
| 5094 | 5094 | 0x0000, |
| @@ -8422,14 +8422,6 @@ static struct npc_kpu_profile_action kpu1_action_entries[] = { · 3327 unmodified lines | ||
| 8422 | 8422 | 0, |
| 8423 | 8423 | 0, 0, 0, 0, |
| 8424 | 8424 | }, |
| 8425 | − { | |
| 8426 | − NPC_ERRLEV_RE, NPC_EC_NOERR, | |
| 8427 | − 8, 12, 0, 0, 0, | |
| 8428 | − NPC_S_KPU2_NGIO, 12, 1, | |
| 8429 | − NPC_LID_LA, NPC_LT_LA_ETHER, | |
| 8430 | − 0, | |
| 8431 | − 0, 0, 0, 0, | |
| 8432 | − }, | |
| 8433 | 8425 | { |
| 8434 | 8426 | NPC_ERRLEV_RE, NPC_EC_NOERR, |
| 8435 | 8427 | 8, 12, 0, 0, 0, |
| @@ -9194,6 +9186,14 @@ static struct npc_kpu_profile_action kpu2_action_entries[] = { · 758 unmodified lines | ||
| 9194 | 9186 | 0, |
| 9195 | 9187 | 0, 0, 0, 0, |
| 9196 | 9188 | }, |
| 9189 | + { | |
| 9190 | + NPC_ERRLEV_RE, NPC_EC_NOERR, | |
| 9191 | + 0, 0, 0, 2, 0, | |
| 9192 | + NPC_S_KPU5_NGIO, 6, 1, | |
| 9193 | + NPC_LID_LB, NPC_LT_LB_CTAG, | |
| 9194 | + 0, | |
| 9195 | + 0, 0, 0, 0, | |
| 9196 | + }, | |
| 9197 | 9197 | { |
| 9198 | 9198 | NPC_ERRLEV_RE, NPC_EC_NOERR, |
| 9199 | 9199 | 8, 0, 6, 2, 0, |
| @@ -9890,14 +9890,6 @@ static struct npc_kpu_profile_action kpu2_action_entries[] = { · 690 unmodified lines | ||
| 9890 | 9890 | NPC_F_LB_U_UNK_ETYPE | NPC_F_LB_L_EXDSA, |
| 9891 | 9891 | 0, 0, 0, 0, |
| 9892 | 9892 | }, |
| 9893 | − { | |
| 9894 | − NPC_ERRLEV_RE, NPC_EC_NOERR, | |
| 9895 | − 0, 0, 0, 0, 1, | |
| 9896 | − NPC_S_NA, 0, 1, | |
| 9897 | − NPC_LID_LC, NPC_LT_LC_NGIO, | |
| 9898 | − 0, | |
| 9899 | − 0, 0, 0, 0, | |
| 9900 | − }, | |
| 9901 | 9893 | { |
| 9902 | 9894 | NPC_ERRLEV_RE, NPC_EC_NOERR, |
| 9903 | 9895 | 8, 0, 6, 2, 0, |
| @@ -11973,6 +11965,14 @@ static struct npc_kpu_profile_action kpu5_action_entries[] = { · 2069 unmodified lines | ||
| 11973 | 11965 | 0, |
| 11974 | 11966 | 0, 0, 0, 0, |
| 11975 | 11967 | }, |
| 11968 | + { | |
| 11969 | + NPC_ERRLEV_RE, NPC_EC_NOERR, | |
| 11970 | + 0, 0, 0, 0, 1, | |
| 11971 | + NPC_S_NA, 0, 1, | |
| 11972 | + NPC_LID_LC, NPC_LT_LC_NGIO, | |
| 11973 | + 0, | |
| 11974 | + 0, 0, 0, 0, | |
| 11975 | + }, | |
| 11976 | 11976 | { |
| 11977 | 11977 | NPC_ERRLEV_LC, NPC_EC_UNK, |
| 11978 | 11978 | 0, 0, 0, 0, 1, |
| @@ -30,6 +30,8 @@ static struct mac_ops rpm_mac_ops = { · 29 unmodified lines | ||
| 30 | 30 | .mac_enadis_pause_frm = rpm_lmac_enadis_pause_frm, |
| 31 | 31 | .mac_pause_frm_config = rpm_lmac_pause_frm_config, |
| 32 | 32 | .mac_enadis_ptp_config = rpm_lmac_ptp_config, |
| 33 | + .mac_rx_tx_enable = rpm_lmac_rx_tx_enable, | |
| 34 | + .mac_tx_enable = rpm_lmac_tx_enable, | |
| 33 | 35 | }; |
| 34 | 36 | |
| 35 | 37 | struct mac_ops *rpm_get_mac_ops(void) |
| @@ -54,6 +56,43 @@ int rpm_get_nr_lmacs(void *rpmd) · 18 unmodified lines | ||
| 54 | 56 | return hweight8(rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS) & 0xFULL); |
| 55 | 57 | } |
| 56 | 58 | |
| 59 | +int rpm_lmac_tx_enable(void *rpmd, int lmac_id, bool enable) | |
| 60 | +{ | |
| 61 | + rpm_t *rpm = rpmd; | |
| 62 | + u64 cfg, last; | |
| 63 | + | |
| 64 | + if (!is_lmac_valid(rpm, lmac_id)) | |
| 65 | + return -ENODEV; | |
| 66 | + | |
| 67 | + cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); | |
| 68 | + last = cfg; | |
| 69 | + if (enable) | |
| 70 | + cfg |= RPM_TX_EN; | |
| 71 | + else | |
| 72 | + cfg &= ~(RPM_TX_EN); | |
| 73 | + | |
| 74 | + if (cfg != last) | |
| 75 | + rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); | |
| 76 | + return !!(last & RPM_TX_EN); | |
| 77 | +} | |
| 78 | + | |
| 79 | +int rpm_lmac_rx_tx_enable(void *rpmd, int lmac_id, bool enable) | |
| 80 | +{ | |
| 81 | + rpm_t *rpm = rpmd; | |
| 82 | + u64 cfg; | |
| 83 | + | |
| 84 | + if (!is_lmac_valid(rpm, lmac_id)) | |
| 85 | + return -ENODEV; | |
| 86 | + | |
| 87 | + cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); | |
| 88 | + if (enable) | |
| 89 | + cfg |= RPM_RX_EN | RPM_TX_EN; | |
| 90 | + else | |
| 91 | + cfg &= ~(RPM_RX_EN | RPM_TX_EN); | |
| 92 | + rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); | |
| 93 | + return 0; | |
| 94 | +} | |
| 95 | + | |
| 57 | 96 | void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable) |
| 58 | 97 | { |
| 59 | 98 | rpm_t *rpm = rpmd; |
| @@ -252,23 +291,20 @@ int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable) · 192 unmodified lines | ||
| 252 | 291 | if (!rpm || lmac_id >= rpm->lmac_count) |
| 253 | 292 | return -ENODEV; |
| 254 | 293 | lmac_type = rpm->mac_ops->get_lmac_type(rpm, lmac_id); |
| 255 | − if (lmac_type == LMAC_MODE_100G_R) { | |
| 256 | − cfg = rpm_read(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1); | |
| 257 | − | |
| 258 | − if (enable) | |
| 259 | − cfg |= RPMX_MTI_PCS_LBK; | |
| 260 | − else | |
| 261 | − cfg &= ~RPMX_MTI_PCS_LBK; | |
| 262 | − rpm_write(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1, cfg); | |
| 263 | − } else { | |
| 264 | − cfg = rpm_read(rpm, lmac_id, RPMX_MTI_LPCSX_CONTROL1); | |
| 265 | − if (enable) | |
| 266 | − cfg |= RPMX_MTI_PCS_LBK; | |
| 267 | − else | |
| 268 | − cfg &= ~RPMX_MTI_PCS_LBK; | |
| 269 | − rpm_write(rpm, lmac_id, RPMX_MTI_LPCSX_CONTROL1, cfg); | |
| 294 | + | |
| 295 | + if (lmac_type == LMAC_MODE_QSGMII || lmac_type == LMAC_MODE_SGMII) { | |
| 296 | + dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n"); | |
| 297 | + return 0; | |
| 270 | 298 | } |
| 271 | 299 | |
| 300 | + cfg = rpm_read(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1); | |
| 301 | + | |
| 302 | + if (enable) | |
| 303 | + cfg |= RPMX_MTI_PCS_LBK; | |
| 304 | + else | |
| 305 | + cfg &= ~RPMX_MTI_PCS_LBK; | |
| 306 | + rpm_write(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1, cfg); | |
| 307 | + | |
| 272 | 308 | return 0; |
| 273 | 309 | } |
| 274 | 310 | |
| @@ -43,6 +43,8 @@ · 42 unmodified lines | ||
| 43 | 43 | #define RPMX_MTI_STAT_DATA_HI_CDC 0x10038 |
| 44 | 44 | |
| 45 | 45 | #define RPM_LMAC_FWI 0xa |
| 46 | +#define RPM_TX_EN BIT_ULL(0) | |
| 47 | +#define RPM_RX_EN BIT_ULL(1) | |
| 46 | 48 | |
| 47 | 49 | /* Function Declarations */ |
| 48 | 50 | int rpm_get_nr_lmacs(void *rpmd); |
| @@ -57,4 +59,6 @@ int rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause, · 8 unmodified lines | ||
| 57 | 59 | int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat); |
| 58 | 60 | int rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat); |
| 59 | 61 | void rpm_lmac_ptp_config(void *rpmd, int lmac_id, bool enable); |
| 62 | +int rpm_lmac_rx_tx_enable(void *rpmd, int lmac_id, bool enable); | |
| 63 | +int rpm_lmac_tx_enable(void *rpmd, int lmac_id, bool enable); | |
| 60 | 64 | #endif /* RPM_H */ |
| @@ -520,8 +520,11 @@ static void rvu_block_reset(struct rvu *rvu, int blkaddr, u64 rst_reg) · 519 unmodified lines | ||
| 520 | 520 | |
| 521 | 521 | rvu_write64(rvu, blkaddr, rst_reg, BIT_ULL(0)); |
| 522 | 522 | err = rvu_poll_reg(rvu, blkaddr, rst_reg, BIT_ULL(63), true); |
| 523 | − if (err) | |
| 524 | − dev_err(rvu->dev, "HW block:%d reset failed\n", blkaddr); | |
| 523 | + if (err) { | |
| 524 | + dev_err(rvu->dev, "HW block:%d reset timeout retrying again\n", blkaddr); | |
| 525 | + while (rvu_poll_reg(rvu, blkaddr, rst_reg, BIT_ULL(63), true) == -EBUSY) | |
| 526 | + ; | |
| 527 | + } | |
| 525 | 528 | } |
| 526 | 529 | |
| 527 | 530 | static void rvu_reset_all_blocks(struct rvu *rvu) |
| @@ -806,6 +806,7 @@ bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature); · 805 unmodified lines | ||
| 806 | 806 | u32 rvu_cgx_get_fifolen(struct rvu *rvu); |
| 807 | 807 | void *rvu_first_cgx_pdata(struct rvu *rvu); |
| 808 | 808 | int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id); |
| 809 | +int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable); | |
| 809 | 810 | |
| 810 | 811 | int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf, |
| 811 | 812 | int type); |
| @@ -441,16 +441,26 @@ void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable) · 440 unmodified lines | ||
| 441 | 441 | int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start) |
| 442 | 442 | { |
| 443 | 443 | int pf = rvu_get_pf(pcifunc); |
| 444 | + struct mac_ops *mac_ops; | |
| 444 | 445 | u8 cgx_id, lmac_id; |
| 446 | + void *cgxd; | |
| 445 | 447 | |
| 446 | 448 | if (!is_cgx_config_permitted(rvu, pcifunc)) |
| 447 | 449 | return LMAC_AF_ERR_PERM_DENIED; |
| 448 | 450 | |
| 449 | 451 | rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); |
| 452 | + cgxd = rvu_cgx_pdata(cgx_id, rvu); | |
| 453 | + mac_ops = get_mac_ops(cgxd); | |
| 454 | + | |
| 455 | + return mac_ops->mac_rx_tx_enable(cgxd, lmac_id, start); | |
| 456 | +} | |
| 450 | 457 | |
| 451 | − cgx_lmac_rx_tx_enable(rvu_cgx_pdata(cgx_id, rvu), lmac_id, start); | |
| 458 | +int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable) | |
| 459 | +{ | |
| 460 | + struct mac_ops *mac_ops; | |
| 452 | 461 | |
| 453 | − return 0; | |
| 462 | + mac_ops = get_mac_ops(cgxd); | |
| 463 | + return mac_ops->mac_tx_enable(cgxd, lmac_id, enable); | |
| 454 | 464 | } |
| 455 | 465 | |
| 456 | 466 | void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc) |
| @@ -1224,6 +1224,8 @@ static void print_nix_cn10k_sq_ctx(struct seq_file *m, · 1223 unmodified lines | ||
| 1224 | 1224 | seq_printf(m, "W3: head_offset\t\t\t%d\nW3: smenq_next_sqb_vld\t\t%d\n\n", |
| 1225 | 1225 | sq_ctx->head_offset, sq_ctx->smenq_next_sqb_vld); |
| 1226 | 1226 | |
| 1227 | + seq_printf(m, "W3: smq_next_sq_vld\t\t%d\nW3: smq_pend\t\t\t%d\n", | |
| 1228 | + sq_ctx->smq_next_sq_vld, sq_ctx->smq_pend); | |
| 1227 | 1229 | seq_printf(m, "W4: next_sqb \t\t\t%llx\n\n", sq_ctx->next_sqb); |
| 1228 | 1230 | seq_printf(m, "W5: tail_sqb \t\t\t%llx\n\n", sq_ctx->tail_sqb); |
| 1229 | 1231 | seq_printf(m, "W6: smenq_sqb \t\t\t%llx\n\n", sq_ctx->smenq_sqb); |
| @@ -512,11 +512,11 @@ static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req, · 511 unmodified lines | ||
| 512 | 512 | cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST); |
| 513 | 513 | lmac_chan_cnt = cfg & 0xFF; |
| 514 | 514 | |
| 515 | − cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST1); | |
| 516 | − sdp_chan_cnt = cfg & 0xFFF; | |
| 517 | − | |
| 518 | 515 | cgx_bpid_cnt = hw->cgx_links * lmac_chan_cnt; |
| 519 | 516 | lbk_bpid_cnt = hw->lbk_links * ((cfg >> 16) & 0xFF); |
| 517 | + | |
| 518 | + cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST1); | |
| 519 | + sdp_chan_cnt = cfg & 0xFFF; | |
| 520 | 520 | sdp_bpid_cnt = hw->sdp_links * sdp_chan_cnt; |
| 521 | 521 | |
| 522 | 522 | pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc); |
| @@ -2068,8 +2068,8 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 1545 unmodified lines | ||
| 2068 | 2068 | /* enable cgx tx if disabled */ |
| 2069 | 2069 | if (is_pf_cgxmapped(rvu, pf)) { |
| 2070 | 2070 | rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); |
| 2071 | − restore_tx_en = !cgx_lmac_tx_enable(rvu_cgx_pdata(cgx_id, rvu), | |
| 2072 | − lmac_id, true); | |
| 2071 | + restore_tx_en = !rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), | |
| 2072 | + lmac_id, true); | |
| 2073 | 2073 | } |
| 2074 | 2074 | |
| 2075 | 2075 | cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq)); |
| @@ -2092,7 +2092,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 16 unmodified lines | ||
| 2092 | 2092 | rvu_cgx_enadis_rx_bp(rvu, pf, true); |
| 2093 | 2093 | /* restore cgx tx state */ |
| 2094 | 2094 | if (restore_tx_en) |
| 2095 | − cgx_lmac_tx_enable(rvu_cgx_pdata(cgx_id, rvu), lmac_id, false); | |
| 2095 | + rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), lmac_id, false); | |
| 2096 | 2096 | return err; |
| 2097 | 2097 | } |
| 2098 | 2098 | |
| @@ -3878,7 +3878,7 @@ nix_config_link_credits(struct rvu *rvu, int blkaddr, int link, · 1779 unmodified lines | ||
| 3878 | 3878 | /* Enable cgx tx if disabled for credits to be back */ |
| 3879 | 3879 | if (is_pf_cgxmapped(rvu, pf)) { |
| 3880 | 3880 | rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); |
| 3881 | − restore_tx_en = !cgx_lmac_tx_enable(rvu_cgx_pdata(cgx_id, rvu), | |
| 3881 | + restore_tx_en = !rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), | |
| 3882 | 3882 | lmac_id, true); |
| 3883 | 3883 | } |
| 3884 | 3884 | |
| @@ -3891,8 +3891,8 @@ nix_config_link_credits(struct rvu *rvu, int blkaddr, int link, · 6 unmodified lines | ||
| 3891 | 3891 | NIX_AF_TL1X_SW_XOFF(schq), BIT_ULL(0)); |
| 3892 | 3892 | } |
| 3893 | 3893 | |
| 3894 | − rc = -EBUSY; | |
| 3895 | − poll_tmo = jiffies + usecs_to_jiffies(10000); | |
| 3894 | + rc = NIX_AF_ERR_LINK_CREDITS; | |
| 3895 | + poll_tmo = jiffies + usecs_to_jiffies(200000); | |
| 3896 | 3896 | /* Wait for credits to return */ |
| 3897 | 3897 | do { |
| 3898 | 3898 | if (time_after(jiffies, poll_tmo)) |
| @@ -3918,7 +3918,7 @@ exit: · 19 unmodified lines | ||
| 3918 | 3918 | |
| 3919 | 3919 | /* Restore state of cgx tx */ |
| 3920 | 3920 | if (restore_tx_en) |
| 3921 | − cgx_lmac_tx_enable(rvu_cgx_pdata(cgx_id, rvu), lmac_id, false); | |
| 3921 | + rvu_cgx_config_tx(rvu_cgx_pdata(cgx_id, rvu), lmac_id, false); | |
| 3922 | 3922 | |
| 3923 | 3923 | mutex_unlock(&rvu->rsrc_lock); |
| 3924 | 3924 | return rc; |
| @@ -402,6 +402,7 @@ static void npc_fixup_vf_rule(struct rvu *rvu, struct npc_mcam *mcam, · 401 unmodified lines | ||
| 402 | 402 | int blkaddr, int index, struct mcam_entry *entry, |
| 403 | 403 | bool *enable) |
| 404 | 404 | { |
| 405 | + struct rvu_npc_mcam_rule *rule; | |
| 405 | 406 | u16 owner, target_func; |
| 406 | 407 | struct rvu_pfvf *pfvf; |
| 407 | 408 | u64 rx_action; |
| @@ -423,6 +424,12 @@ static void npc_fixup_vf_rule(struct rvu *rvu, struct npc_mcam *mcam, · 15 unmodified lines | ||
| 423 | 424 | test_bit(NIXLF_INITIALIZED, &pfvf->flags))) |
| 424 | 425 | *enable = false; |
| 425 | 426 | |
| 427 | + /* fix up not needed for the rules added by user(ntuple filters) */ | |
| 428 | + list_for_each_entry(rule, &mcam->mcam_rules, list) { | |
| 429 | + if (rule->entry == index) | |
| 430 | + return; | |
| 431 | + } | |
| 432 | + | |
| 426 | 433 | /* copy VF default entry action to the VF mcam entry */ |
| 427 | 434 | rx_action = npc_get_default_entry_action(rvu, mcam, blkaddr, |
| 428 | 435 | target_func); |
| @@ -489,8 +496,8 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, · 60 unmodified lines | ||
| 489 | 496 | } |
| 490 | 497 | |
| 491 | 498 | /* PF installing VF rule */ |
| 492 | − if (intf == NIX_INTF_RX && actindex < mcam->bmap_entries) | |
| 493 | − npc_fixup_vf_rule(rvu, mcam, blkaddr, index, entry, &enable); | |
| 499 | + if (is_npc_intf_rx(intf) && actindex < mcam->bmap_entries) | |
| 500 | + npc_fixup_vf_rule(rvu, mcam, blkaddr, actindex, entry, &enable); | |
| 494 | 501 | |
| 495 | 502 | /* Set 'action' */ |
| 496 | 503 | rvu_write64(rvu, blkaddr, |
| @@ -916,7 +923,8 @@ static void npc_update_vf_flow_entry(struct rvu *rvu, struct npc_mcam *mcam, · 419 unmodified lines | ||
| 916 | 923 | int blkaddr, u16 pcifunc, u64 rx_action) |
| 917 | 924 | { |
| 918 | 925 | int actindex, index, bank, entry; |
| 919 | − bool enable; | |
| 926 | + struct rvu_npc_mcam_rule *rule; | |
| 927 | + bool enable, update; | |
| 920 | 928 | |
| 921 | 929 | if (!(pcifunc & RVU_PFVF_FUNC_MASK)) |
| 922 | 930 | return; |
| @@ -924,6 +932,14 @@ static void npc_update_vf_flow_entry(struct rvu *rvu, struct npc_mcam *mcam, · 1 unmodified line | ||
| 924 | 932 | mutex_lock(&mcam->lock); |
| 925 | 933 | for (index = 0; index < mcam->bmap_entries; index++) { |
| 926 | 934 | if (mcam->entry2target_pffunc[index] == pcifunc) { |
| 935 | + update = true; | |
| 936 | + /* update not needed for the rules added via ntuple filters */ | |
| 937 | + list_for_each_entry(rule, &mcam->mcam_rules, list) { | |
| 938 | + if (rule->entry == index) | |
| 939 | + update = false; | |
| 940 | + } | |
| 941 | + if (!update) | |
| 942 | + continue; | |
| 927 | 943 | bank = npc_get_bank(mcam, index); |
| 928 | 944 | actindex = index; |
| 929 | 945 | entry = index & (mcam->banksize - 1); |
| @@ -1098,14 +1098,6 @@ find_rule: · 1097 unmodified lines | ||
| 1098 | 1098 | write_req.cntr = rule->cntr; |
| 1099 | 1099 | } |
| 1100 | 1100 | |
| 1101 | − err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req, | |
| 1102 | − &write_rsp); | |
| 1103 | − if (err) { | |
| 1104 | − rvu_mcam_remove_counter_from_rule(rvu, owner, rule); | |
| 1105 | − if (new) | |
| 1106 | − kfree(rule); | |
| 1107 | − return err; | |
| 1108 | − } | |
| 1109 | 1101 | /* update rule */ |
| 1110 | 1102 | memcpy(&rule->packet, &dummy.packet, sizeof(rule->packet)); |
| 1111 | 1103 | memcpy(&rule->mask, &dummy.mask, sizeof(rule->mask)); |
| @@ -1132,6 +1124,18 @@ find_rule: · 20 unmodified lines | ||
| 1132 | 1124 | if (req->default_rule) |
| 1133 | 1125 | pfvf->def_ucast_rule = rule; |
| 1134 | 1126 | |
| 1127 | + /* write to mcam entry registers */ | |
| 1128 | + err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req, | |
| 1129 | + &write_rsp); | |
| 1130 | + if (err) { | |
| 1131 | + rvu_mcam_remove_counter_from_rule(rvu, owner, rule); | |
| 1132 | + if (new) { | |
| 1133 | + list_del(&rule->list); | |
| 1134 | + kfree(rule); | |
| 1135 | + } | |
| 1136 | + return err; | |
| 1137 | + } | |
| 1138 | + | |
| 1135 | 1139 | /* VF's MAC address is being changed via PF */ |
| 1136 | 1140 | if (pf_set_vfs_mac) { |
| 1137 | 1141 | ether_addr_copy(pfvf->default_mac, req->packet.dmac); |
| @@ -603,6 +603,7 @@ static inline void __cn10k_aura_freeptr(struct otx2_nic *pfvf, u64 aura, · 602 unmodified lines | ||
| 603 | 603 | size++; |
| 604 | 604 | tar_addr |= ((size - 1) & 0x7) << 4; |
| 605 | 605 | } |
| 606 | + dma_wmb(); | |
| 606 | 607 | memcpy((u64 *)lmt_info->lmt_addr, ptrs, sizeof(u64) * num_ptrs); |
| 607 | 608 | /* Perform LMTST flush */ |
| 608 | 609 | cn10k_lmt_flush(val, tar_addr); |
| @@ -394,7 +394,12 @@ static int otx2_forward_vf_mbox_msgs(struct otx2_nic *pf, · 393 unmodified lines | ||
| 394 | 394 | dst_mdev->msg_size = mbox_hdr->msg_size; |
| 395 | 395 | dst_mdev->num_msgs = num_msgs; |
| 396 | 396 | err = otx2_sync_mbox_msg(dst_mbox); |
| 397 | − if (err) { | |
| 397 | + /* Error code -EIO indicate there is a communication failure | |
| 398 | + * to the AF. Rest of the error codes indicate that AF processed | |
| 399 | + * VF messages and set the error codes in response messages | |
| 400 | + * (if any) so simply forward responses to VF. | |
| 401 | + */ | |
| 402 | + if (err == -EIO) { | |
| 398 | 403 | dev_warn(pf->dev, |
| 399 | 404 | "AF not responding to VF%d messages\n", vf); |
| 400 | 405 | /* restore PF mbase and exit */ |
| @@ -40,11 +40,12 @@ static int lan966x_mac_wait_for_completion(struct lan966x *lan966x) · 39 unmodified lines | ||
| 40 | 40 | { |
| 41 | 41 | u32 val; |
| 42 | 42 | |
| 43 | − return readx_poll_timeout(lan966x_mac_get_status, | |
| 44 | − lan966x, val, | |
| 45 | − (ANA_MACACCESS_MAC_TABLE_CMD_GET(val)) == | |
| 46 | − MACACCESS_CMD_IDLE, | |
| 47 | − TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US); | |
| 43 | + return readx_poll_timeout_atomic(lan966x_mac_get_status, | |
| 44 | + lan966x, val, | |
| 45 | + (ANA_MACACCESS_MAC_TABLE_CMD_GET(val)) == | |
| 46 | + MACACCESS_CMD_IDLE, | |
| 47 | + TABLE_UPDATE_SLEEP_US, | |
| 48 | + TABLE_UPDATE_TIMEOUT_US); | |
| 48 | 49 | } |
| 49 | 50 | |
| 50 | 51 | static void lan966x_mac_select(struct lan966x *lan966x, |
| @@ -182,9 +182,9 @@ static int lan966x_port_inj_ready(struct lan966x *lan966x, u8 grp) · 181 unmodified lines | ||
| 182 | 182 | { |
| 183 | 183 | u32 val; |
| 184 | 184 | |
| 185 | − return readx_poll_timeout(lan966x_port_inj_status, lan966x, val, | |
| 186 | − QS_INJ_STATUS_FIFO_RDY_GET(val) & BIT(grp), | |
| 187 | − READL_SLEEP_US, READL_TIMEOUT_US); | |
| 185 | + return readx_poll_timeout_atomic(lan966x_port_inj_status, lan966x, val, | |
| 186 | + QS_INJ_STATUS_FIFO_RDY_GET(val) & BIT(grp), | |
| 187 | + READL_SLEEP_US, READL_TIMEOUT_US); | |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | 190 | static int lan966x_port_ifh_xmit(struct sk_buff *skb, |
| @@ -749,6 +749,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) · 748 unmodified lines | ||
| 749 | 749 | const struct ether3_data *data = id->data; |
| 750 | 750 | struct net_device *dev; |
| 751 | 751 | int bus_type, ret; |
| 752 | + u8 addr[ETH_ALEN]; | |
| 752 | 753 | |
| 753 | 754 | ether3_banner(); |
| 754 | 755 | |
| @@ -776,7 +777,8 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) · 21 unmodified lines | ||
| 776 | 777 | priv(dev)->seeq = priv(dev)->base + data->base_offset; |
| 777 | 778 | dev->irq = ec->irq; |
| 778 | 779 | |
| 779 | − ether3_addr(dev->dev_addr, ec); | |
| 780 | + ether3_addr(addr, ec); | |
| 781 | + eth_hw_addr_set(dev, addr); | |
| 780 | 782 | |
| 781 | 783 | priv(dev)->dev = dev; |
| 782 | 784 | timer_setup(&priv(dev)->timer, ether3_ledoff, 0); |
| @@ -756,7 +756,7 @@ static int sun8i_dwmac_reset(struct stmmac_priv *priv) · 755 unmodified lines | ||
| 756 | 756 | |
| 757 | 757 | if (err) { |
| 758 | 758 | dev_err(priv->device, "EMAC reset timeout\n"); |
| 759 | − return -EFAULT; | |
| 759 | + return err; | |
| 760 | 760 | } |
| 761 | 761 | return 0; |
| 762 | 762 | } |
| @@ -22,21 +22,21 @@ · 21 unmodified lines | ||
| 22 | 22 | #define ETHER_CLK_SEL_RMII_CLK_EN BIT(2) |
| 23 | 23 | #define ETHER_CLK_SEL_RMII_CLK_RST BIT(3) |
| 24 | 24 | #define ETHER_CLK_SEL_DIV_SEL_2 BIT(4) |
| 25 | −#define ETHER_CLK_SEL_DIV_SEL_20 BIT(0) | |
| 25 | +#define ETHER_CLK_SEL_DIV_SEL_20 0 | |
| 26 | 26 | #define ETHER_CLK_SEL_FREQ_SEL_125M (BIT(9) | BIT(8)) |
| 27 | 27 | #define ETHER_CLK_SEL_FREQ_SEL_50M BIT(9) |
| 28 | 28 | #define ETHER_CLK_SEL_FREQ_SEL_25M BIT(8) |
| 29 | 29 | #define ETHER_CLK_SEL_FREQ_SEL_2P5M 0 |
| 30 | −#define ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN BIT(0) | |
| 30 | +#define ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN 0 | |
| 31 | 31 | #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC BIT(10) |
| 32 | 32 | #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV BIT(11) |
| 33 | −#define ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN BIT(0) | |
| 33 | +#define ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN 0 | |
| 34 | 34 | #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC BIT(12) |
| 35 | 35 | #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV BIT(13) |
| 36 | −#define ETHER_CLK_SEL_TX_CLK_O_TX_I BIT(0) | |
| 36 | +#define ETHER_CLK_SEL_TX_CLK_O_TX_I 0 | |
| 37 | 37 | #define ETHER_CLK_SEL_TX_CLK_O_RMII_I BIT(14) |
| 38 | 38 | #define ETHER_CLK_SEL_TX_O_E_N_IN BIT(15) |
| 39 | −#define ETHER_CLK_SEL_RMII_CLK_SEL_IN BIT(0) | |
| 39 | +#define ETHER_CLK_SEL_RMII_CLK_SEL_IN 0 | |
| 40 | 40 | #define ETHER_CLK_SEL_RMII_CLK_SEL_RX_C BIT(16) |
| 41 | 41 | |
| 42 | 42 | #define ETHER_CLK_SEL_RX_TX_CLK_EN (ETHER_CLK_SEL_RX_CLK_EN | ETHER_CLK_SEL_TX_CLK_EN) |
| @@ -96,31 +96,41 @@ static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed) · 53 unmodified lines | ||
| 96 | 96 | val |= ETHER_CLK_SEL_TX_O_E_N_IN; |
| 97 | 97 | writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); |
| 98 | 98 | |
| 99 | + /* Set Clock-Mux, Start clock, Set TX_O direction */ | |
| 99 | 100 | switch (dwmac->phy_intf_sel) { |
| 100 | 101 | case ETHER_CONFIG_INTF_RGMII: |
| 101 | 102 | val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC; |
| 103 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 104 | + | |
| 105 | + val |= ETHER_CLK_SEL_RX_TX_CLK_EN; | |
| 106 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 107 | + | |
| 108 | + val &= ~ETHER_CLK_SEL_TX_O_E_N_IN; | |
| 109 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 102 | 110 | break; |
| 103 | 111 | case ETHER_CONFIG_INTF_RMII: |
| 104 | 112 | val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV | |
| 105 | − ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN | | |
| 113 | + ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN | | |
| 106 | 114 | ETHER_CLK_SEL_RMII_CLK_SEL_RX_C; |
| 115 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 116 | + | |
| 117 | + val |= ETHER_CLK_SEL_RMII_CLK_RST; | |
| 118 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 119 | + | |
| 120 | + val |= ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN; | |
| 121 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 107 | 122 | break; |
| 108 | 123 | case ETHER_CONFIG_INTF_MII: |
| 109 | 124 | default: |
| 110 | 125 | val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC | |
| 111 | − ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN | | |
| 112 | − ETHER_CLK_SEL_RMII_CLK_EN; | |
| 126 | + ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN; | |
| 127 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 128 | + | |
| 129 | + val |= ETHER_CLK_SEL_RX_TX_CLK_EN; | |
| 130 | + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 113 | 131 | break; |
| 114 | 132 | } |
| 115 | 133 | |
| 116 | − /* Start clock */ | |
| 117 | − writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 118 | − val |= ETHER_CLK_SEL_RX_TX_CLK_EN; | |
| 119 | − writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 120 | − | |
| 121 | − val &= ~ETHER_CLK_SEL_TX_O_E_N_IN; | |
| 122 | − writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); | |
| 123 | − | |
| 124 | 134 | spin_unlock_irqrestore(&dwmac->lock, flags); |
| 125 | 135 | } |
| 126 | 136 | |
| @@ -194,7 +194,6 @@ struct stmmac_priv { · 193 unmodified lines | ||
| 194 | 194 | u32 tx_coal_timer[MTL_MAX_TX_QUEUES]; |
| 195 | 195 | u32 rx_coal_frames[MTL_MAX_TX_QUEUES]; |
| 196 | 196 | |
| 197 | − int tx_coalesce; | |
| 198 | 197 | int hwts_tx_en; |
| 199 | 198 | bool tx_path_in_lpi_mode; |
| 200 | 199 | bool tso; |
| @@ -229,7 +228,6 @@ struct stmmac_priv { · 28 unmodified lines | ||
| 229 | 228 | unsigned int flow_ctrl; |
| 230 | 229 | unsigned int pause; |
| 231 | 230 | struct mii_bus *mii; |
| 232 | − int mii_irq[PHY_MAX_ADDR]; | |
| 233 | 231 | |
| 234 | 232 | struct phylink_config phylink_config; |
| 235 | 233 | struct phylink *phylink; |
| @@ -402,7 +402,7 @@ static void stmmac_lpi_entry_timer_config(struct stmmac_priv *priv, bool en) · 401 unmodified lines | ||
| 402 | 402 | * Description: this function is to verify and enter in LPI mode in case of |
| 403 | 403 | * EEE. |
| 404 | 404 | */ |
| 405 | −static void stmmac_enable_eee_mode(struct stmmac_priv *priv) | |
| 405 | +static int stmmac_enable_eee_mode(struct stmmac_priv *priv) | |
| 406 | 406 | { |
| 407 | 407 | u32 tx_cnt = priv->plat->tx_queues_to_use; |
| 408 | 408 | u32 queue; |
| @@ -412,13 +412,14 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv) · 3 unmodified lines | ||
| 412 | 412 | struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; |
| 413 | 413 | |
| 414 | 414 | if (tx_q->dirty_tx != tx_q->cur_tx) |
| 415 | − return; /* still unfinished work */ | |
| 415 | + return -EBUSY; /* still unfinished work */ | |
| 416 | 416 | } |
| 417 | 417 | |
| 418 | 418 | /* Check and enter in LPI mode */ |
| 419 | 419 | if (!priv->tx_path_in_lpi_mode) |
| 420 | 420 | stmmac_set_eee_mode(priv, priv->hw, |
| 421 | 421 | priv->plat->en_tx_lpi_clockgating); |
| 422 | + return 0; | |
| 422 | 423 | } |
| 423 | 424 | |
| 424 | 425 | /** |
| @@ -450,8 +451,8 @@ static void stmmac_eee_ctrl_timer(struct timer_list *t) · 25 unmodified lines | ||
| 450 | 451 | { |
| 451 | 452 | struct stmmac_priv *priv = from_timer(priv, t, eee_ctrl_timer); |
| 452 | 453 | |
| 453 | − stmmac_enable_eee_mode(priv); | |
| 454 | − mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer)); | |
| 454 | + if (stmmac_enable_eee_mode(priv)) | |
| 455 | + mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer)); | |
| 455 | 456 | } |
| 456 | 457 | |
| 457 | 458 | /** |
| @@ -889,6 +890,9 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) · 431 unmodified lines | ||
| 889 | 890 | bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac; |
| 890 | 891 | int ret; |
| 891 | 892 | |
| 893 | + if (priv->plat->ptp_clk_freq_config) | |
| 894 | + priv->plat->ptp_clk_freq_config(priv); | |
| 895 | + | |
| 892 | 896 | ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE); |
| 893 | 897 | if (ret) |
| 894 | 898 | return ret; |
| @@ -911,8 +915,6 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) · 16 unmodified lines | ||
| 911 | 915 | priv->hwts_tx_en = 0; |
| 912 | 916 | priv->hwts_rx_en = 0; |
| 913 | 917 | |
| 914 | − stmmac_ptp_register(priv); | |
| 915 | − | |
| 916 | 918 | return 0; |
| 917 | 919 | } |
| 918 | 920 | |
| @@ -2647,8 +2649,8 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) · 1728 unmodified lines | ||
| 2647 | 2649 | |
| 2648 | 2650 | if (priv->eee_enabled && !priv->tx_path_in_lpi_mode && |
| 2649 | 2651 | priv->eee_sw_timer_en) { |
| 2650 | − stmmac_enable_eee_mode(priv); | |
| 2651 | − mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer)); | |
| 2652 | + if (stmmac_enable_eee_mode(priv)) | |
| 2653 | + mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer)); | |
| 2652 | 2654 | } |
| 2653 | 2655 | |
| 2654 | 2656 | /* We still have pending packets, let's call for a new scheduling */ |
| @@ -3238,7 +3240,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv) · 583 unmodified lines | ||
| 3238 | 3240 | /** |
| 3239 | 3241 | * stmmac_hw_setup - setup mac in a usable state. |
| 3240 | 3242 | * @dev : pointer to the device structure. |
| 3241 | − * @init_ptp: initialize PTP if set | |
| 3243 | + * @ptp_register: register PTP if set | |
| 3242 | 3244 | * Description: |
| 3243 | 3245 | * this is the main function to setup the HW in a usable state because the |
| 3244 | 3246 | * dma engine is reset, the core registers are configured (e.g. AXI, |
| @@ -3248,7 +3250,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv) · 3 unmodified lines | ||
| 3248 | 3250 | * 0 on success and an appropriate (-)ve integer as defined in errno.h |
| 3249 | 3251 | * file on failure. |
| 3250 | 3252 | */ |
| 3251 | −static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) | |
| 3253 | +static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) | |
| 3252 | 3254 | { |
| 3253 | 3255 | struct stmmac_priv *priv = netdev_priv(dev); |
| 3254 | 3256 | u32 rx_cnt = priv->plat->rx_queues_to_use; |
| @@ -3305,13 +3307,13 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) · 50 unmodified lines | ||
| 3305 | 3307 | |
| 3306 | 3308 | stmmac_mmc_setup(priv); |
| 3307 | 3309 | |
| 3308 | − if (init_ptp) { | |
| 3309 | − ret = stmmac_init_ptp(priv); | |
| 3310 | − if (ret == -EOPNOTSUPP) | |
| 3311 | − netdev_warn(priv->dev, "PTP not supported by HW\n"); | |
| 3312 | − else if (ret) | |
| 3313 | − netdev_warn(priv->dev, "PTP init failed\n"); | |
| 3314 | − } | |
| 3310 | + ret = stmmac_init_ptp(priv); | |
| 3311 | + if (ret == -EOPNOTSUPP) | |
| 3312 | + netdev_warn(priv->dev, "PTP not supported by HW\n"); | |
| 3313 | + else if (ret) | |
| 3314 | + netdev_warn(priv->dev, "PTP init failed\n"); | |
| 3315 | + else if (ptp_register) | |
| 3316 | + stmmac_ptp_register(priv); | |
| 3315 | 3317 | |
| 3316 | 3318 | priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS; |
| 3317 | 3319 | |
| @@ -297,9 +297,6 @@ void stmmac_ptp_register(struct stmmac_priv *priv) · 296 unmodified lines | ||
| 297 | 297 | { |
| 298 | 298 | int i; |
| 299 | 299 | |
| 300 | − if (priv->plat->ptp_clk_freq_config) | |
| 301 | − priv->plat->ptp_clk_freq_config(priv); | |
| 302 | − | |
| 303 | 300 | for (i = 0; i < priv->dma_cap.pps_out_num; i++) { |
| 304 | 301 | if (i >= STMMAC_PPS_MAX) |
| 305 | 302 | break; |
| @@ -1146,7 +1146,7 @@ int cpsw_fill_rx_channels(struct cpsw_priv *priv) · 1145 unmodified lines | ||
| 1146 | 1146 | static struct page_pool *cpsw_create_page_pool(struct cpsw_common *cpsw, |
| 1147 | 1147 | int size) |
| 1148 | 1148 | { |
| 1149 | − struct page_pool_params pp_params; | |
| 1149 | + struct page_pool_params pp_params = {}; | |
| 1150 | 1150 | struct page_pool *pool; |
| 1151 | 1151 | |
| 1152 | 1152 | pp_params.order = 0; |
| @@ -1091,20 +1091,22 @@ static int tsi108_get_mac(struct net_device *dev) · 1090 unmodified lines | ||
| 1091 | 1091 | struct tsi108_prv_data *data = netdev_priv(dev); |
| 1092 | 1092 | u32 word1 = TSI_READ(TSI108_MAC_ADDR1); |
| 1093 | 1093 | u32 word2 = TSI_READ(TSI108_MAC_ADDR2); |
| 1094 | + u8 addr[ETH_ALEN]; | |
| 1094 | 1095 | |
| 1095 | 1096 | /* Note that the octets are reversed from what the manual says, |
| 1096 | 1097 | * producing an even weirder ordering... |
| 1097 | 1098 | */ |
| 1098 | 1099 | if (word2 == 0 && word1 == 0) { |
| 1099 | − dev->dev_addr[0] = 0x00; | |
| 1100 | − dev->dev_addr[1] = 0x06; | |
| 1101 | − dev->dev_addr[2] = 0xd2; | |
| 1102 | − dev->dev_addr[3] = 0x00; | |
| 1103 | − dev->dev_addr[4] = 0x00; | |
| 1100 | + addr[0] = 0x00; | |
| 1101 | + addr[1] = 0x06; | |
| 1102 | + addr[2] = 0xd2; | |
| 1103 | + addr[3] = 0x00; | |
| 1104 | + addr[4] = 0x00; | |
| 1104 | 1105 | if (0x8 == data->phy) |
| 1105 | − dev->dev_addr[5] = 0x01; | |
| 1106 | + addr[5] = 0x01; | |
| 1106 | 1107 | else |
| 1107 | − dev->dev_addr[5] = 0x02; | |
| 1108 | + addr[5] = 0x02; | |
| 1109 | + eth_hw_addr_set(dev, addr); | |
| 1108 | 1110 | |
| 1109 | 1111 | word2 = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 24); |
| 1110 | 1112 | |
| @@ -1114,12 +1116,13 @@ static int tsi108_get_mac(struct net_device *dev) · 3 unmodified lines | ||
| 1114 | 1116 | TSI_WRITE(TSI108_MAC_ADDR1, word1); |
| 1115 | 1117 | TSI_WRITE(TSI108_MAC_ADDR2, word2); |
| 1116 | 1118 | } else { |
| 1117 | − dev->dev_addr[0] = (word2 >> 16) & 0xff; | |
| 1118 | − dev->dev_addr[1] = (word2 >> 24) & 0xff; | |
| 1119 | − dev->dev_addr[2] = (word1 >> 0) & 0xff; | |
| 1120 | − dev->dev_addr[3] = (word1 >> 8) & 0xff; | |
| 1121 | − dev->dev_addr[4] = (word1 >> 16) & 0xff; | |
| 1122 | − dev->dev_addr[5] = (word1 >> 24) & 0xff; | |
| 1119 | + addr[0] = (word2 >> 16) & 0xff; | |
| 1120 | + addr[1] = (word2 >> 24) & 0xff; | |
| 1121 | + addr[2] = (word1 >> 0) & 0xff; | |
| 1122 | + addr[3] = (word1 >> 8) & 0xff; | |
| 1123 | + addr[4] = (word1 >> 16) & 0xff; | |
| 1124 | + addr[5] = (word1 >> 24) & 0xff; | |
| 1125 | + eth_hw_addr_set(dev, addr); | |
| 1123 | 1126 | } |
| 1124 | 1127 | |
| 1125 | 1128 | if (!is_valid_ether_addr(dev->dev_addr)) { |
| @@ -1136,14 +1139,12 @@ static int tsi108_set_mac(struct net_device *dev, void *addr) · 10 unmodified lines | ||
| 1136 | 1139 | { |
| 1137 | 1140 | struct tsi108_prv_data *data = netdev_priv(dev); |
| 1138 | 1141 | u32 word1, word2; |
| 1139 | − int i; | |
| 1140 | 1142 | |
| 1141 | 1143 | if (!is_valid_ether_addr(addr)) |
| 1142 | 1144 | return -EADDRNOTAVAIL; |
| 1143 | 1145 | |
| 1144 | − for (i = 0; i < 6; i++) | |
| 1145 | − /* +2 is for the offset of the HW addr type */ | |
| 1146 | − dev->dev_addr[i] = ((unsigned char *)addr)[i + 2]; | |
| 1146 | + /* +2 is for the offset of the HW addr type */ | |
| 1147 | + eth_hw_addr_set(dev, ((unsigned char *)addr) + 2); | |
| 1147 | 1148 | |
| 1148 | 1149 | word2 = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 24); |
| 1149 | 1150 | |
| @@ -950,9 +950,7 @@ static int yam_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __ · 949 unmodified lines | ||
| 950 | 950 | ym = memdup_user(data, sizeof(struct yamdrv_ioctl_mcs)); |
| 951 | 951 | if (IS_ERR(ym)) |
| 952 | 952 | return PTR_ERR(ym); |
| 953 | − if (ym->cmd != SIOCYAMSMCS) | |
| 954 | − return -EINVAL; | |
| 955 | − if (ym->bitrate > YAM_MAXBITRATE) { | |
| 953 | + if (ym->cmd != SIOCYAMSMCS || ym->bitrate > YAM_MAXBITRATE) { | |
| 956 | 954 | kfree(ym); |
| 957 | 955 | return -EINVAL; |
| 958 | 956 | } |
| @@ -854,6 +854,7 @@ static struct phy_driver broadcom_drivers[] = { · 853 unmodified lines | ||
| 854 | 854 | .phy_id_mask = 0xfffffff0, |
| 855 | 855 | .name = "Broadcom BCM54616S", |
| 856 | 856 | /* PHY_GBIT_FEATURES */ |
| 857 | + .soft_reset = genphy_soft_reset, | |
| 857 | 858 | .config_init = bcm54xx_config_init, |
| 858 | 859 | .config_aneg = bcm54616s_config_aneg, |
| 859 | 860 | .config_intr = bcm_phy_config_intr, |
| @@ -1746,6 +1746,9 @@ void phy_detach(struct phy_device *phydev) · 1745 unmodified lines | ||
| 1746 | 1746 | phy_driver_is_genphy_10g(phydev)) |
| 1747 | 1747 | device_release_driver(&phydev->mdio.dev); |
| 1748 | 1748 | |
| 1749 | + /* Assert the reset signal */ | |
| 1750 | + phy_device_reset(phydev, 1); | |
| 1751 | + | |
| 1749 | 1752 | /* |
| 1750 | 1753 | * The phydev might go away on the put_device() below, so avoid |
| 1751 | 1754 | * a use-after-free bug by reading the underlying bus first. |
| @@ -1757,9 +1760,6 @@ void phy_detach(struct phy_device *phydev) · 5 unmodified lines | ||
| 1757 | 1760 | ndev_owner = dev->dev.parent->driver->owner; |
| 1758 | 1761 | if (ndev_owner != bus->owner) |
| 1759 | 1762 | module_put(bus->owner); |
| 1760 | − | |
| 1761 | − /* Assert the reset signal */ | |
| 1762 | − phy_device_reset(phydev, 1); | |
| 1763 | 1763 | } |
| 1764 | 1764 | EXPORT_SYMBOL(phy_detach); |
| 1765 | 1765 | |
| @@ -651,6 +651,11 @@ struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) · 650 unmodified lines | ||
| 651 | 651 | else if (ret < 0) |
| 652 | 652 | return ERR_PTR(ret); |
| 653 | 653 | |
| 654 | + if (!fwnode_device_is_available(ref.fwnode)) { | |
| 655 | + fwnode_handle_put(ref.fwnode); | |
| 656 | + return NULL; | |
| 657 | + } | |
| 658 | + | |
| 654 | 659 | bus = sfp_bus_get(ref.fwnode); |
| 655 | 660 | fwnode_handle_put(ref.fwnode); |
| 656 | 661 | if (!bus) |
| @@ -1092,7 +1092,6 @@ static void __nvmf_concat_opt_tokens(struct seq_file *seq_file) · 1091 unmodified lines | ||
| 1092 | 1092 | static int nvmf_dev_show(struct seq_file *seq_file, void *private) |
| 1093 | 1093 | { |
| 1094 | 1094 | struct nvme_ctrl *ctrl; |
| 1095 | − int ret = 0; | |
| 1096 | 1095 | |
| 1097 | 1096 | mutex_lock(&nvmf_dev_mutex); |
| 1098 | 1097 | ctrl = seq_file->private; |
| @@ -1106,7 +1105,7 @@ static int nvmf_dev_show(struct seq_file *seq_file, void *private) · 7 unmodified lines | ||
| 1106 | 1105 | |
| 1107 | 1106 | out_unlock: |
| 1108 | 1107 | mutex_unlock(&nvmf_dev_mutex); |
| 1109 | − return ret; | |
| 1108 | + return 0; | |
| 1110 | 1109 | } |
| 1111 | 1110 | |
| 1112 | 1111 | static int nvmf_dev_open(struct inode *inode, struct file *file) |
| @@ -3391,7 +3391,8 @@ static const struct pci_device_id nvme_id_table[] = { · 3390 unmodified lines | ||
| 3391 | 3391 | NVME_QUIRK_DEALLOCATE_ZEROES, }, |
| 3392 | 3392 | { PCI_VDEVICE(INTEL, 0x0a54), /* Intel P4500/P4600 */ |
| 3393 | 3393 | .driver_data = NVME_QUIRK_STRIPE_SIZE | |
| 3394 | − NVME_QUIRK_DEALLOCATE_ZEROES, }, | |
| 3394 | + NVME_QUIRK_DEALLOCATE_ZEROES | | |
| 3395 | + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | |
| 3395 | 3396 | { PCI_VDEVICE(INTEL, 0x0a55), /* Dell Express Flash P4600 */ |
| 3396 | 3397 | .driver_data = NVME_QUIRK_STRIPE_SIZE | |
| 3397 | 3398 | NVME_QUIRK_DEALLOCATE_ZEROES, }, |
| @@ -109,15 +109,6 @@ static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) · 108 unmodified lines | ||
| 109 | 109 | writel_relaxed(val, pcie->base + reg); |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | −static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) | |
| 113 | −{ | |
| 114 | − u32 val = readl_relaxed(pcie->base + reg); | |
| 115 | − | |
| 116 | − val &= ~clr; | |
| 117 | − val |= set; | |
| 118 | − writel_relaxed(val, pcie->base + reg); | |
| 119 | −} | |
| 120 | − | |
| 121 | 112 | static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) |
| 122 | 113 | { |
| 123 | 114 | return readl_relaxed(port->base + reg); |
| @@ -557,7 +548,7 @@ static struct platform_driver mt7621_pcie_driver = { · 433 unmodified lines | ||
| 557 | 548 | .remove = mt7621_pcie_remove, |
| 558 | 549 | .driver = { |
| 559 | 550 | .name = "mt7621-pci", |
| 560 | − .of_match_table = of_match_ptr(mt7621_pcie_ids), | |
| 551 | + .of_match_table = mt7621_pcie_ids, | |
| 561 | 552 | }, |
| 562 | 553 | }; |
| 563 | 554 | builtin_platform_driver(mt7621_pcie_driver); |
| @@ -28,6 +28,7 @@ void pci_msi_teardown_msi_irqs(struct pci_dev *dev) · 27 unmodified lines | ||
| 28 | 28 | msi_domain_free_irqs_descs_locked(domain, &dev->dev); |
| 29 | 29 | else |
| 30 | 30 | pci_msi_legacy_teardown_msi_irqs(dev); |
| 31 | + msi_free_msi_descs(&dev->dev); | |
| 31 | 32 | } |
| 32 | 33 | |
| 33 | 34 | /** |
| @@ -171,8 +172,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, · 137 unmodified lines | ||
| 171 | 172 | if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) |
| 172 | 173 | pci_msi_domain_update_chip_ops(info); |
| 173 | 174 | |
| 174 | − info->flags |= MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS | | |
| 175 | − MSI_FLAG_FREE_MSI_DESCS; | |
| 175 | + info->flags |= MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS; | |
| 176 | 176 | if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE)) |
| 177 | 177 | info->flags |= MSI_FLAG_MUST_REACTIVATE; |
| 178 | 178 | |
| @@ -77,5 +77,4 @@ void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev) · 76 unmodified lines | ||
| 77 | 77 | { |
| 78 | 78 | msi_device_destroy_sysfs(&dev->dev); |
| 79 | 79 | arch_teardown_msi_irqs(dev); |
| 80 | − msi_free_msi_descs(&dev->dev); | |
| 81 | 80 | } |
| @@ -180,6 +180,7 @@ config QCOM_Q6V5_ADSP · 179 unmodified lines | ||
| 180 | 180 | depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n |
| 181 | 181 | depends on QCOM_SYSMON || QCOM_SYSMON=n |
| 182 | 182 | depends on RPMSG_QCOM_GLINK || RPMSG_QCOM_GLINK=n |
| 183 | + depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n | |
| 183 | 184 | select MFD_SYSCON |
| 184 | 185 | select QCOM_PIL_INFO |
| 185 | 186 | select QCOM_MDT_LOADER |
| @@ -199,6 +200,7 @@ config QCOM_Q6V5_MSS · 13 unmodified lines | ||
| 199 | 200 | depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n |
| 200 | 201 | depends on QCOM_SYSMON || QCOM_SYSMON=n |
| 201 | 202 | depends on RPMSG_QCOM_GLINK || RPMSG_QCOM_GLINK=n |
| 203 | + depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n | |
| 202 | 204 | select MFD_SYSCON |
| 203 | 205 | select QCOM_MDT_LOADER |
| 204 | 206 | select QCOM_PIL_INFO |
| @@ -218,6 +220,7 @@ config QCOM_Q6V5_PAS · 13 unmodified lines | ||
| 218 | 220 | depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n |
| 219 | 221 | depends on QCOM_SYSMON || QCOM_SYSMON=n |
| 220 | 222 | depends on RPMSG_QCOM_GLINK || RPMSG_QCOM_GLINK=n |
| 223 | + depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n | |
| 221 | 224 | select MFD_SYSCON |
| 222 | 225 | select QCOM_PIL_INFO |
| 223 | 226 | select QCOM_MDT_LOADER |
| @@ -239,6 +242,7 @@ config QCOM_Q6V5_WCSS · 15 unmodified lines | ||
| 239 | 242 | depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n |
| 240 | 243 | depends on QCOM_SYSMON || QCOM_SYSMON=n |
| 241 | 244 | depends on RPMSG_QCOM_GLINK || RPMSG_QCOM_GLINK=n |
| 245 | + depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n | |
| 242 | 246 | select MFD_SYSCON |
| 243 | 247 | select QCOM_MDT_LOADER |
| 244 | 248 | select QCOM_PIL_INFO |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/platform_device.h> |
| 11 | 11 | #include <linux/interrupt.h> |
| 12 | 12 | #include <linux/module.h> |
| 13 | +#include <linux/soc/qcom/qcom_aoss.h> | |
| 13 | 14 | #include <linux/soc/qcom/smem.h> |
| 14 | 15 | #include <linux/soc/qcom/smem_state.h> |
| 15 | 16 | #include <linux/remoteproc.h> |
| @@ -93,7 +93,7 @@ static int rpmsg_eptdev_destroy(struct device *dev, void *data) · 92 unmodified lines | ||
| 93 | 93 | /* wake up any blocked readers */ |
| 94 | 94 | wake_up_interruptible(&eptdev->readq); |
| 95 | 95 | |
| 96 | − device_del(&eptdev->dev); | |
| 96 | + cdev_device_del(&eptdev->cdev, &eptdev->dev); | |
| 97 | 97 | put_device(&eptdev->dev); |
| 98 | 98 | |
| 99 | 99 | return 0; |
| @@ -336,7 +336,6 @@ static void rpmsg_eptdev_release_device(struct device *dev) · 236 unmodified lines | ||
| 336 | 336 | |
| 337 | 337 | ida_simple_remove(&rpmsg_ept_ida, dev->id); |
| 338 | 338 | ida_simple_remove(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); |
| 339 | − cdev_del(&eptdev->cdev); | |
| 340 | 339 | kfree(eptdev); |
| 341 | 340 | } |
| 342 | 341 | |
| @@ -381,19 +380,13 @@ static int rpmsg_eptdev_create(struct rpmsg_ctrldev *ctrldev, · 38 unmodified lines | ||
| 381 | 380 | dev->id = ret; |
| 382 | 381 | dev_set_name(dev, "rpmsg%d", ret); |
| 383 | 382 | |
| 384 | − ret = cdev_add(&eptdev->cdev, dev->devt, 1); | |
| 383 | + ret = cdev_device_add(&eptdev->cdev, &eptdev->dev); | |
| 385 | 384 | if (ret) |
| 386 | 385 | goto free_ept_ida; |
| 387 | 386 | |
| 388 | 387 | /* We can now rely on the release function for cleanup */ |
| 389 | 388 | dev->release = rpmsg_eptdev_release_device; |
| 390 | 389 | |
| 391 | − ret = device_add(dev); | |
| 392 | − if (ret) { | |
| 393 | − dev_err(dev, "device_add failed: %d\n", ret); | |
| 394 | − put_device(dev); | |
| 395 | − } | |
| 396 | − | |
| 397 | 390 | return ret; |
| 398 | 391 | |
| 399 | 392 | free_ept_ida: |
| @@ -462,7 +455,6 @@ static void rpmsg_ctrldev_release_device(struct device *dev) · 62 unmodified lines | ||
| 462 | 455 | |
| 463 | 456 | ida_simple_remove(&rpmsg_ctrl_ida, dev->id); |
| 464 | 457 | ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); |
| 465 | − cdev_del(&ctrldev->cdev); | |
| 466 | 458 | kfree(ctrldev); |
| 467 | 459 | } |
| 468 | 460 | |
| @@ -497,19 +489,13 @@ static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev) · 28 unmodified lines | ||
| 497 | 489 | dev->id = ret; |
| 498 | 490 | dev_set_name(&ctrldev->dev, "rpmsg_ctrl%d", ret); |
| 499 | 491 | |
| 500 | − ret = cdev_add(&ctrldev->cdev, dev->devt, 1); | |
| 492 | + ret = cdev_device_add(&ctrldev->cdev, &ctrldev->dev); | |
| 501 | 493 | if (ret) |
| 502 | 494 | goto free_ctrl_ida; |
| 503 | 495 | |
| 504 | 496 | /* We can now rely on the release function for cleanup */ |
| 505 | 497 | dev->release = rpmsg_ctrldev_release_device; |
| 506 | 498 | |
| 507 | − ret = device_add(dev); | |
| 508 | − if (ret) { | |
| 509 | − dev_err(&rpdev->dev, "device_add failed: %d\n", ret); | |
| 510 | − put_device(dev); | |
| 511 | − } | |
| 512 | − | |
| 513 | 499 | dev_set_drvdata(&rpdev->dev, ctrldev); |
| 514 | 500 | |
| 515 | 501 | return ret; |
| @@ -535,7 +521,7 @@ static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev) · 19 unmodified lines | ||
| 535 | 521 | if (ret) |
| 536 | 522 | dev_warn(&rpdev->dev, "failed to nuke endpoints: %d\n", ret); |
| 537 | 523 | |
| 538 | − device_del(&ctrldev->dev); | |
| 524 | + cdev_device_del(&ctrldev->cdev, &ctrldev->dev); | |
| 539 | 525 | put_device(&ctrldev->dev); |
| 540 | 526 | } |
| 541 | 527 | |
| @@ -521,6 +521,8 @@ static void zfcp_fc_adisc_handler(void *data) · 520 unmodified lines | ||
| 521 | 521 | goto out; |
| 522 | 522 | } |
| 523 | 523 | |
| 524 | + /* re-init to undo drop from zfcp_fc_adisc() */ | |
| 525 | + port->d_id = ntoh24(adisc_resp->adisc_port_id); | |
| 524 | 526 | /* port is good, unblock rport without going through erp */ |
| 525 | 527 | zfcp_scsi_schedule_rport_register(port); |
| 526 | 528 | out: |
| @@ -534,6 +536,7 @@ static int zfcp_fc_adisc(struct zfcp_port *port) · 7 unmodified lines | ||
| 534 | 536 | struct zfcp_fc_req *fc_req; |
| 535 | 537 | struct zfcp_adapter *adapter = port->adapter; |
| 536 | 538 | struct Scsi_Host *shost = adapter->scsi_host; |
| 539 | + u32 d_id; | |
| 537 | 540 | int ret; |
| 538 | 541 | |
| 539 | 542 | fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_ATOMIC); |
| @@ -558,7 +561,15 @@ static int zfcp_fc_adisc(struct zfcp_port *port) · 18 unmodified lines | ||
| 558 | 561 | fc_req->u.adisc.req.adisc_cmd = ELS_ADISC; |
| 559 | 562 | hton24(fc_req->u.adisc.req.adisc_port_id, fc_host_port_id(shost)); |
| 560 | 563 | |
| 561 | − ret = zfcp_fsf_send_els(adapter, port->d_id, &fc_req->ct_els, | |
| 564 | + d_id = port->d_id; /* remember as destination for send els below */ | |
| 565 | + /* | |
| 566 | + * Force fresh GID_PN lookup on next port recovery. | |
| 567 | + * Must happen after request setup and before sending request, | |
| 568 | + * to prevent race with port->d_id re-init in zfcp_fc_adisc_handler(). | |
| 569 | + */ | |
| 570 | + port->d_id = 0; | |
| 571 | + | |
| 572 | + ret = zfcp_fsf_send_els(adapter, d_id, &fc_req->ct_els, | |
| 562 | 573 | ZFCP_FC_CTELS_TMO); |
| 563 | 574 | if (ret) |
| 564 | 575 | kmem_cache_free(zfcp_fc_req_cache, fc_req); |
| @@ -1567,8 +1567,6 @@ static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) · 1566 unmodified lines | ||
| 1567 | 1567 | pci_try_set_mwi(pdev); |
| 1568 | 1568 | |
| 1569 | 1569 | retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
| 1570 | − if (retval) | |
| 1571 | − retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | |
| 1572 | 1570 | if (retval) { |
| 1573 | 1571 | TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask"); |
| 1574 | 1572 | retval = -ENODEV; |
| @@ -1786,8 +1784,6 @@ static int __maybe_unused twl_resume(struct device *dev) · 211 unmodified lines | ||
| 1786 | 1784 | pci_try_set_mwi(pdev); |
| 1787 | 1785 | |
| 1788 | 1786 | retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
| 1789 | − if (retval) | |
| 1790 | − retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | |
| 1791 | 1787 | if (retval) { |
| 1792 | 1788 | TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume"); |
| 1793 | 1789 | retval = -ENODEV; |
| @@ -1507,7 +1507,6 @@ NCR_700_intr(int irq, void *dev_id) · 1506 unmodified lines | ||
| 1507 | 1507 | struct scsi_cmnd *SCp = hostdata->cmd; |
| 1508 | 1508 | |
| 1509 | 1509 | handled = 1; |
| 1510 | − SCp = hostdata->cmd; | |
| 1511 | 1510 | |
| 1512 | 1511 | if(istat & SCSI_INT_PENDING) { |
| 1513 | 1512 | udelay(10); |
| @@ -732,9 +732,6 @@ bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad) · 731 unmodified lines | ||
| 732 | 732 | pci_set_master(pdev); |
| 733 | 733 | |
| 734 | 734 | rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
| 735 | − if (rc) | |
| 736 | − rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | |
| 737 | − | |
| 738 | 735 | if (rc) { |
| 739 | 736 | rc = -ENODEV; |
| 740 | 737 | printk(KERN_ERR "dma_set_mask_and_coherent fail %p\n", pdev); |
| @@ -1559,9 +1556,6 @@ bfad_pci_slot_reset(struct pci_dev *pdev) · 818 unmodified lines | ||
| 1559 | 1556 | pci_set_master(pdev); |
| 1560 | 1557 | |
| 1561 | 1558 | rc = dma_set_mask_and_coherent(&bfad->pcidev->dev, DMA_BIT_MASK(64)); |
| 1562 | − if (rc) | |
| 1563 | − rc = dma_set_mask_and_coherent(&bfad->pcidev->dev, | |
| 1564 | − DMA_BIT_MASK(32)); | |
| 1565 | 1559 | if (rc) |
| 1566 | 1560 | goto out_disable_device; |
| 1567 | 1561 | |
| @@ -82,7 +82,7 @@ static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba); · 81 unmodified lines | ||
| 82 | 82 | static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba); |
| 83 | 83 | static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, |
| 84 | 84 | struct device *parent, int npiv); |
| 85 | −static void bnx2fc_destroy_work(struct work_struct *work); | |
| 85 | +static void bnx2fc_port_destroy(struct fcoe_port *port); | |
| 86 | 86 | |
| 87 | 87 | static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev); |
| 88 | 88 | static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device |
| @@ -907,9 +907,6 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, · 818 unmodified lines | ||
| 907 | 907 | __bnx2fc_destroy(interface); |
| 908 | 908 | } |
| 909 | 909 | mutex_unlock(&bnx2fc_dev_lock); |
| 910 | − | |
| 911 | − /* Ensure ALL destroy work has been completed before return */ | |
| 912 | − flush_workqueue(bnx2fc_wq); | |
| 913 | 910 | return; |
| 914 | 911 | |
| 915 | 912 | default: |
| @@ -1215,8 +1212,8 @@ static int bnx2fc_vport_destroy(struct fc_vport *vport) · 299 unmodified lines | ||
| 1215 | 1212 | mutex_unlock(&n_port->lp_mutex); |
| 1216 | 1213 | bnx2fc_free_vport(interface->hba, port->lport); |
| 1217 | 1214 | bnx2fc_port_shutdown(port->lport); |
| 1215 | + bnx2fc_port_destroy(port); | |
| 1218 | 1216 | bnx2fc_interface_put(interface); |
| 1219 | − queue_work(bnx2fc_wq, &port->destroy_work); | |
| 1220 | 1217 | return 0; |
| 1221 | 1218 | } |
| 1222 | 1219 | |
| @@ -1525,7 +1522,6 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, · 302 unmodified lines | ||
| 1525 | 1522 | port->lport = lport; |
| 1526 | 1523 | port->priv = interface; |
| 1527 | 1524 | port->get_netdev = bnx2fc_netdev; |
| 1528 | − INIT_WORK(&port->destroy_work, bnx2fc_destroy_work); | |
| 1529 | 1525 | |
| 1530 | 1526 | /* Configure fcoe_port */ |
| 1531 | 1527 | rc = bnx2fc_lport_config(lport); |
| @@ -1653,8 +1649,8 @@ static void __bnx2fc_destroy(struct bnx2fc_interface *interface) · 121 unmodified lines | ||
| 1653 | 1649 | bnx2fc_interface_cleanup(interface); |
| 1654 | 1650 | bnx2fc_stop(interface); |
| 1655 | 1651 | list_del(&interface->list); |
| 1652 | + bnx2fc_port_destroy(port); | |
| 1656 | 1653 | bnx2fc_interface_put(interface); |
| 1657 | − queue_work(bnx2fc_wq, &port->destroy_work); | |
| 1658 | 1654 | } |
| 1659 | 1655 | |
| 1660 | 1656 | /** |
| @@ -1694,15 +1690,12 @@ netdev_err: · 33 unmodified lines | ||
| 1694 | 1690 | return rc; |
| 1695 | 1691 | } |
| 1696 | 1692 | |
| 1697 | −static void bnx2fc_destroy_work(struct work_struct *work) | |
| 1693 | +static void bnx2fc_port_destroy(struct fcoe_port *port) | |
| 1698 | 1694 | { |
| 1699 | − struct fcoe_port *port; | |
| 1700 | 1695 | struct fc_lport *lport; |
| 1701 | 1696 | |
| 1702 | − port = container_of(work, struct fcoe_port, destroy_work); | |
| 1703 | 1697 | lport = port->lport; |
| 1704 | − | |
| 1705 | − BNX2FC_HBA_DBG(lport, "Entered bnx2fc_destroy_work\n"); | |
| 1698 | + BNX2FC_HBA_DBG(lport, "Entered %s, destroying lport %p\n", __func__, lport); | |
| 1706 | 1699 | |
| 1707 | 1700 | bnx2fc_if_destroy(lport); |
| 1708 | 1701 | } |
| @@ -2556,9 +2549,6 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev) · 847 unmodified lines | ||
| 2556 | 2549 | __bnx2fc_destroy(interface); |
| 2557 | 2550 | mutex_unlock(&bnx2fc_dev_lock); |
| 2558 | 2551 | |
| 2559 | − /* Ensure ALL destroy work has been completed before return */ | |
| 2560 | − flush_workqueue(bnx2fc_wq); | |
| 2561 | − | |
| 2562 | 2552 | bnx2fc_ulp_stop(hba); |
| 2563 | 2553 | /* unregister cnic device */ |
| 2564 | 2554 | if (test_and_clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic)) |
| @@ -46,18 +46,14 @@ efc_els_io_alloc_size(struct efc_node *node, u32 reqlen, u32 rsplen) · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | efc = node->efc; |
| 48 | 48 | |
| 49 | − spin_lock_irqsave(&node->els_ios_lock, flags); | |
| 50 | − | |
| 51 | 49 | if (!node->els_io_enabled) { |
| 52 | 50 | efc_log_err(efc, "els io alloc disabled\n"); |
| 53 | − spin_unlock_irqrestore(&node->els_ios_lock, flags); | |
| 54 | 51 | return NULL; |
| 55 | 52 | } |
| 56 | 53 | |
| 57 | 54 | els = mempool_alloc(efc->els_io_pool, GFP_ATOMIC); |
| 58 | 55 | if (!els) { |
| 59 | 56 | atomic_add_return(1, &efc->els_io_alloc_failed_count); |
| 60 | − spin_unlock_irqrestore(&node->els_ios_lock, flags); | |
| 61 | 57 | return NULL; |
| 62 | 58 | } |
| 63 | 59 | |
| @@ -74,7 +70,6 @@ efc_els_io_alloc_size(struct efc_node *node, u32 reqlen, u32 rsplen) · 10 unmodified lines | ||
| 74 | 70 | &els->io.req.phys, GFP_KERNEL); |
| 75 | 71 | if (!els->io.req.virt) { |
| 76 | 72 | mempool_free(els, efc->els_io_pool); |
| 77 | − spin_unlock_irqrestore(&node->els_ios_lock, flags); | |
| 78 | 73 | return NULL; |
| 79 | 74 | } |
| 80 | 75 | |
| @@ -94,10 +89,11 @@ efc_els_io_alloc_size(struct efc_node *node, u32 reqlen, u32 rsplen) · 13 unmodified lines | ||
| 94 | 89 | |
| 95 | 90 | /* add els structure to ELS IO list */ |
| 96 | 91 | INIT_LIST_HEAD(&els->list_entry); |
| 92 | + spin_lock_irqsave(&node->els_ios_lock, flags); | |
| 97 | 93 | list_add_tail(&els->list_entry, &node->els_ios_list); |
| 94 | + spin_unlock_irqrestore(&node->els_ios_lock, flags); | |
| 98 | 95 | } |
| 99 | 96 | |
| 100 | − spin_unlock_irqrestore(&node->els_ios_lock, flags); | |
| 101 | 97 | return els; |
| 102 | 98 | } |
| 103 | 99 | |
| @@ -2666,9 +2666,6 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, · 2665 unmodified lines | ||
| 2666 | 2666 | goto err_out; |
| 2667 | 2667 | |
| 2668 | 2668 | error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); |
| 2669 | − if (error) | |
| 2670 | − error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); | |
| 2671 | − | |
| 2672 | 2669 | if (error) { |
| 2673 | 2670 | dev_err(dev, "No usable DMA addressing method\n"); |
| 2674 | 2671 | goto err_out; |
| @@ -4695,8 +4695,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 4694 unmodified lines | ||
| 4695 | 4695 | goto err_out; |
| 4696 | 4696 | |
| 4697 | 4697 | rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
| 4698 | − if (rc) | |
| 4699 | − rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | |
| 4700 | 4698 | if (rc) { |
| 4701 | 4699 | dev_err(dev, "No usable DMA addressing method\n"); |
| 4702 | 4700 | rc = -ENODEV; |
| @@ -2267,7 +2267,8 @@ static void myrs_cleanup(struct myrs_hba *cs) · 2266 unmodified lines | ||
| 2267 | 2267 | myrs_unmap(cs); |
| 2268 | 2268 | |
| 2269 | 2269 | if (cs->mmio_base) { |
| 2270 | − cs->disable_intr(cs); | |
| 2270 | + if (cs->disable_intr) | |
| 2271 | + cs->disable_intr(cs); | |
| 2271 | 2272 | iounmap(cs->mmio_base); |
| 2272 | 2273 | cs->mmio_base = NULL; |
| 2273 | 2274 | } |
| @@ -4151,10 +4151,22 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) · 4150 unmodified lines | ||
| 4151 | 4151 | u32 ret = MPI_IO_STATUS_FAIL; |
| 4152 | 4152 | u32 regval; |
| 4153 | 4153 | |
| 4154 | + /* | |
| 4155 | + * Fatal errors are programmed to be signalled in irq vector | |
| 4156 | + * pm8001_ha->max_q_num - 1 through pm8001_ha->main_cfg_tbl.pm80xx_tbl. | |
| 4157 | + * fatal_err_interrupt | |
| 4158 | + */ | |
| 4154 | 4159 | if (vec == (pm8001_ha->max_q_num - 1)) { |
| 4160 | + u32 mipsall_ready; | |
| 4161 | + | |
| 4162 | + if (pm8001_ha->chip_id == chip_8008 || | |
| 4163 | + pm8001_ha->chip_id == chip_8009) | |
| 4164 | + mipsall_ready = SCRATCH_PAD_MIPSALL_READY_8PORT; | |
| 4165 | + else | |
| 4166 | + mipsall_ready = SCRATCH_PAD_MIPSALL_READY_16PORT; | |
| 4167 | + | |
| 4155 | 4168 | regval = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); |
| 4156 | − if ((regval & SCRATCH_PAD_MIPSALL_READY) != | |
| 4157 | − SCRATCH_PAD_MIPSALL_READY) { | |
| 4169 | + if ((regval & mipsall_ready) != mipsall_ready) { | |
| 4158 | 4170 | pm8001_ha->controller_fatal_error = true; |
| 4159 | 4171 | pm8001_dbg(pm8001_ha, FAIL, |
| 4160 | 4172 | "Firmware Fatal error! Regval:0x%x\n", |
| @@ -1405,8 +1405,12 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t; · 1404 unmodified lines | ||
| 1405 | 1405 | #define SCRATCH_PAD_BOOT_LOAD_SUCCESS 0x0 |
| 1406 | 1406 | #define SCRATCH_PAD_IOP0_READY 0xC00 |
| 1407 | 1407 | #define SCRATCH_PAD_IOP1_READY 0x3000 |
| 1408 | −#define SCRATCH_PAD_MIPSALL_READY (SCRATCH_PAD_IOP1_READY | \ | |
| 1408 | +#define SCRATCH_PAD_MIPSALL_READY_16PORT (SCRATCH_PAD_IOP1_READY | \ | |
| 1409 | 1409 | SCRATCH_PAD_IOP0_READY | \ |
| 1410 | + SCRATCH_PAD_ILA_READY | \ | |
| 1411 | + SCRATCH_PAD_RAAE_READY) | |
| 1412 | +#define SCRATCH_PAD_MIPSALL_READY_8PORT (SCRATCH_PAD_IOP0_READY | \ | |
| 1413 | + SCRATCH_PAD_ILA_READY | \ | |
| 1410 | 1414 | SCRATCH_PAD_RAAE_READY) |
| 1411 | 1415 | |
| 1412 | 1416 | /* boot loader state */ |
| @@ -2250,6 +2250,7 @@ process_els: · 2249 unmodified lines | ||
| 2250 | 2250 | io_req->tm_flags == FCP_TMF_TGT_RESET) { |
| 2251 | 2251 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); |
| 2252 | 2252 | io_req->sc_cmd = NULL; |
| 2253 | + kref_put(&io_req->refcount, qedf_release_cmd); | |
| 2253 | 2254 | complete(&io_req->tm_done); |
| 2254 | 2255 | } |
| 2255 | 2256 | |
| @@ -911,7 +911,7 @@ void qedf_ctx_soft_reset(struct fc_lport *lport) · 910 unmodified lines | ||
| 911 | 911 | struct qed_link_output if_link; |
| 912 | 912 | |
| 913 | 913 | if (lport->vport) { |
| 914 | − QEDF_ERR(NULL, "Cannot issue host reset on NPIV port.\n"); | |
| 914 | + printk_ratelimited("Cannot issue host reset on NPIV port.\n"); | |
| 915 | 915 | return; |
| 916 | 916 | } |
| 917 | 917 | |
| @@ -1864,6 +1864,7 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled) · 946 unmodified lines | ||
| 1864 | 1864 | vport_qedf->cmd_mgr = base_qedf->cmd_mgr; |
| 1865 | 1865 | init_completion(&vport_qedf->flogi_compl); |
| 1866 | 1866 | INIT_LIST_HEAD(&vport_qedf->fcports); |
| 1867 | + INIT_DELAYED_WORK(&vport_qedf->stag_work, qedf_stag_change_work); | |
| 1867 | 1868 | |
| 1868 | 1869 | rc = qedf_vport_libfc_config(vport, vn_port); |
| 1869 | 1870 | if (rc) { |
| @@ -3980,7 +3981,9 @@ void qedf_stag_change_work(struct work_struct *work) · 2110 unmodified lines | ||
| 3980 | 3981 | struct qedf_ctx *qedf = |
| 3981 | 3982 | container_of(work, struct qedf_ctx, stag_work.work); |
| 3982 | 3983 | |
| 3983 | − QEDF_ERR(&qedf->dbg_ctx, "Performing software context reset.\n"); | |
| 3984 | + printk_ratelimited("[%s]:[%s:%d]:%d: Performing software context reset.", | |
| 3985 | + dev_name(&qedf->pdev->dev), __func__, __LINE__, | |
| 3986 | + qedf->dbg_ctx.host_no); | |
| 3984 | 3987 | qedf_ctx_soft_reset(qedf->lport); |
| 3985 | 3988 | } |
| 3986 | 3989 | |
| @@ -92,6 +92,11 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) · 91 unmodified lines | ||
| 92 | 92 | clki->min_freq = clkfreq[i]; |
| 93 | 93 | clki->max_freq = clkfreq[i+1]; |
| 94 | 94 | clki->name = devm_kstrdup(dev, name, GFP_KERNEL); |
| 95 | + if (!clki->name) { | |
| 96 | + ret = -ENOMEM; | |
| 97 | + goto out; | |
| 98 | + } | |
| 99 | + | |
| 95 | 100 | if (!strcmp(name, "ref_clk")) |
| 96 | 101 | clki->keep_link_active = true; |
| 97 | 102 | dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz", |
| @@ -127,6 +132,8 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name, · 29 unmodified lines | ||
| 127 | 132 | return -ENOMEM; |
| 128 | 133 | |
| 129 | 134 | vreg->name = devm_kstrdup(dev, name, GFP_KERNEL); |
| 135 | + if (!vreg->name) | |
| 136 | + return -ENOMEM; | |
| 130 | 137 | |
| 131 | 138 | snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); |
| 132 | 139 | if (of_property_read_u32(np, prop_name, &vreg->max_uA)) { |
| @@ -8613,7 +8613,7 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) · 8612 unmodified lines | ||
| 8613 | 8613 | * @pwr_mode: device power mode to set |
| 8614 | 8614 | * |
| 8615 | 8615 | * Returns 0 if requested power mode is set successfully |
| 8616 | − * Returns non-zero if failed to set the requested power mode | |
| 8616 | + * Returns < 0 if failed to set the requested power mode | |
| 8617 | 8617 | */ |
| 8618 | 8618 | static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, |
| 8619 | 8619 | enum ufs_dev_pwr_mode pwr_mode) |
| @@ -8667,8 +8667,11 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, · 47 unmodified lines | ||
| 8667 | 8667 | sdev_printk(KERN_WARNING, sdp, |
| 8668 | 8668 | "START_STOP failed for power mode: %d, result %x\n", |
| 8669 | 8669 | pwr_mode, ret); |
| 8670 | − if (ret > 0 && scsi_sense_valid(&sshdr)) | |
| 8671 | − scsi_print_sense_hdr(sdp, NULL, &sshdr); | |
| 8670 | + if (ret > 0) { | |
| 8671 | + if (scsi_sense_valid(&sshdr)) | |
| 8672 | + scsi_print_sense_hdr(sdp, NULL, &sshdr); | |
| 8673 | + ret = -EIO; | |
| 8674 | + } | |
| 8672 | 8675 | } |
| 8673 | 8676 | |
| 8674 | 8677 | if (!ret) |
| @@ -142,7 +142,8 @@ static inline u32 ufshci_version(u32 major, u32 minor) · 141 unmodified lines | ||
| 142 | 142 | #define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\ |
| 143 | 143 | CONTROLLER_FATAL_ERROR |\ |
| 144 | 144 | SYSTEM_BUS_FATAL_ERROR |\ |
| 145 | − CRYPTO_ENGINE_FATAL_ERROR) | |
| 145 | + CRYPTO_ENGINE_FATAL_ERROR |\ | |
| 146 | + UIC_LINK_LOST) | |
| 146 | 147 | |
| 147 | 148 | /* HCS - Host Controller Status 30h */ |
| 148 | 149 | #define DEVICE_PRESENT 0x1 |
| @@ -443,6 +443,9 @@ static bool iscsit_tpg_check_network_portal( · 442 unmodified lines | ||
| 443 | 443 | break; |
| 444 | 444 | } |
| 445 | 445 | spin_unlock(&tpg->tpg_np_lock); |
| 446 | + | |
| 447 | + if (match) | |
| 448 | + break; | |
| 446 | 449 | } |
| 447 | 450 | spin_unlock(&tiqn->tiqn_tpg_lock); |
| 448 | 451 | |
| @@ -322,6 +322,7 @@ static int addr_cnt; · 321 unmodified lines | ||
| 322 | 322 | #define GSM1_ESCAPE_BITS 0x20 |
| 323 | 323 | #define XON 0x11 |
| 324 | 324 | #define XOFF 0x13 |
| 325 | +#define ISO_IEC_646_MASK 0x7F | |
| 325 | 326 | |
| 326 | 327 | static const struct tty_port_operations gsm_port_ops; |
| 327 | 328 | |
| @@ -531,7 +532,8 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len) · 203 unmodified lines | ||
| 531 | 532 | int olen = 0; |
| 532 | 533 | while (len--) { |
| 533 | 534 | if (*input == GSM1_SOF || *input == GSM1_ESCAPE |
| 534 | − || *input == XON || *input == XOFF) { | |
| 535 | + || (*input & ISO_IEC_646_MASK) == XON | |
| 536 | + || (*input & ISO_IEC_646_MASK) == XOFF) { | |
| 535 | 537 | *output++ = GSM1_ESCAPE; |
| 536 | 538 | *output++ = *input++ ^ GSM1_ESCAPE_BITS; |
| 537 | 539 | olen++; |
| @@ -50,10 +50,17 @@ static int rpmsg_tty_cb(struct rpmsg_device *rpdev, void *data, int len, void *p · 49 unmodified lines | ||
| 50 | 50 | static int rpmsg_tty_install(struct tty_driver *driver, struct tty_struct *tty) |
| 51 | 51 | { |
| 52 | 52 | struct rpmsg_tty_port *cport = idr_find(&tty_idr, tty->index); |
| 53 | + struct tty_port *port; | |
| 53 | 54 | |
| 54 | 55 | tty->driver_data = cport; |
| 55 | 56 | |
| 56 | − return tty_port_install(&cport->port, driver, tty); | |
| 57 | + port = tty_port_get(&cport->port); | |
| 58 | + return tty_port_install(port, driver, tty); | |
| 59 | +} | |
| 60 | + | |
| 61 | +static void rpmsg_tty_cleanup(struct tty_struct *tty) | |
| 62 | +{ | |
| 63 | + tty_port_put(tty->port); | |
| 57 | 64 | } |
| 58 | 65 | |
| 59 | 66 | static int rpmsg_tty_open(struct tty_struct *tty, struct file *filp) |
| @@ -106,12 +113,19 @@ static unsigned int rpmsg_tty_write_room(struct tty_struct *tty) · 46 unmodified lines | ||
| 106 | 113 | return size; |
| 107 | 114 | } |
| 108 | 115 | |
| 116 | +static void rpmsg_tty_hangup(struct tty_struct *tty) | |
| 117 | +{ | |
| 118 | + tty_port_hangup(tty->port); | |
| 119 | +} | |
| 120 | + | |
| 109 | 121 | static const struct tty_operations rpmsg_tty_ops = { |
| 110 | 122 | .install = rpmsg_tty_install, |
| 111 | 123 | .open = rpmsg_tty_open, |
| 112 | 124 | .close = rpmsg_tty_close, |
| 113 | 125 | .write = rpmsg_tty_write, |
| 114 | 126 | .write_room = rpmsg_tty_write_room, |
| 127 | + .hangup = rpmsg_tty_hangup, | |
| 128 | + .cleanup = rpmsg_tty_cleanup, | |
| 115 | 129 | }; |
| 116 | 130 | |
| 117 | 131 | static struct rpmsg_tty_port *rpmsg_tty_alloc_cport(void) |
| @@ -137,8 +151,10 @@ static struct rpmsg_tty_port *rpmsg_tty_alloc_cport(void) · 19 unmodified lines | ||
| 137 | 151 | return cport; |
| 138 | 152 | } |
| 139 | 153 | |
| 140 | −static void rpmsg_tty_release_cport(struct rpmsg_tty_port *cport) | |
| 154 | +static void rpmsg_tty_destruct_port(struct tty_port *port) | |
| 141 | 155 | { |
| 156 | + struct rpmsg_tty_port *cport = container_of(port, struct rpmsg_tty_port, port); | |
| 157 | + | |
| 142 | 158 | mutex_lock(&idr_lock); |
| 143 | 159 | idr_remove(&tty_idr, cport->id); |
| 144 | 160 | mutex_unlock(&idr_lock); |
| @@ -146,7 +162,10 @@ static void rpmsg_tty_release_cport(struct rpmsg_tty_port *cport) · 1 unmodified line | ||
| 146 | 162 | kfree(cport); |
| 147 | 163 | } |
| 148 | 164 | |
| 149 | −static const struct tty_port_operations rpmsg_tty_port_ops = { }; | |
| 165 | +static const struct tty_port_operations rpmsg_tty_port_ops = { | |
| 166 | + .destruct = rpmsg_tty_destruct_port, | |
| 167 | +}; | |
| 168 | + | |
| 150 | 169 | |
| 151 | 170 | static int rpmsg_tty_probe(struct rpmsg_device *rpdev) |
| 152 | 171 | { |
| @@ -166,7 +185,8 @@ static int rpmsg_tty_probe(struct rpmsg_device *rpdev) · 13 unmodified lines | ||
| 166 | 185 | cport->id, dev); |
| 167 | 186 | if (IS_ERR(tty_dev)) { |
| 168 | 187 | ret = dev_err_probe(dev, PTR_ERR(tty_dev), "Failed to register tty port\n"); |
| 169 | − goto err_destroy; | |
| 188 | + tty_port_put(&cport->port); | |
| 189 | + return ret; | |
| 170 | 190 | } |
| 171 | 191 | |
| 172 | 192 | cport->rpdev = rpdev; |
| @@ -177,12 +197,6 @@ static int rpmsg_tty_probe(struct rpmsg_device *rpdev) · 4 unmodified lines | ||
| 177 | 197 | rpdev->src, rpdev->dst, cport->id); |
| 178 | 198 | |
| 179 | 199 | return 0; |
| 180 | − | |
| 181 | −err_destroy: | |
| 182 | − tty_port_destroy(&cport->port); | |
| 183 | − rpmsg_tty_release_cport(cport); | |
| 184 | − | |
| 185 | − return ret; | |
| 186 | 200 | } |
| 187 | 201 | |
| 188 | 202 | static void rpmsg_tty_remove(struct rpmsg_device *rpdev) |
| @@ -192,13 +206,11 @@ static void rpmsg_tty_remove(struct rpmsg_device *rpdev) · 3 unmodified lines | ||
| 192 | 206 | dev_dbg(&rpdev->dev, "Removing rpmsg tty device %d\n", cport->id); |
| 193 | 207 | |
| 194 | 208 | /* User hang up to release the tty */ |
| 195 | − if (tty_port_initialized(&cport->port)) | |
| 196 | − tty_port_tty_hangup(&cport->port, false); | |
| 209 | + tty_port_tty_hangup(&cport->port, false); | |
| 197 | 210 | |
| 198 | 211 | tty_unregister_device(rpmsg_tty_driver, cport->id); |
| 199 | 212 | |
| 200 | − tty_port_destroy(&cport->port); | |
| 201 | − rpmsg_tty_release_cport(cport); | |
| 213 | + tty_port_put(&cport->port); | |
| 202 | 214 | } |
| 203 | 215 | |
| 204 | 216 | static struct rpmsg_device_id rpmsg_driver_tty_id_table[] = { |
| @@ -83,8 +83,17 @@ static int of_platform_serial_setup(struct platform_device *ofdev, · 82 unmodified lines | ||
| 83 | 83 | port->mapsize = resource_size(&resource); |
| 84 | 84 | |
| 85 | 85 | /* Check for shifted address mapping */ |
| 86 | − if (of_property_read_u32(np, "reg-offset", &prop) == 0) | |
| 86 | + if (of_property_read_u32(np, "reg-offset", &prop) == 0) { | |
| 87 | + if (prop >= port->mapsize) { | |
| 88 | + dev_warn(&ofdev->dev, "reg-offset %u exceeds region size %pa\n", | |
| 89 | + prop, &port->mapsize); | |
| 90 | + ret = -EINVAL; | |
| 91 | + goto err_unprepare; | |
| 92 | + } | |
| 93 | + | |
| 87 | 94 | port->mapbase += prop; |
| 95 | + port->mapsize -= prop; | |
| 96 | + } | |
| 88 | 97 | |
| 89 | 98 | port->iotype = UPIO_MEM; |
| 90 | 99 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { |
| @@ -4779,8 +4779,30 @@ static const struct pci_device_id serial_pci_tbl[] = { · 4778 unmodified lines | ||
| 4779 | 4779 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, |
| 4780 | 4780 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ |
| 4781 | 4781 | pbn_b2_4_115200 }, |
| 4782 | + /* Brainboxes Devices */ | |
| 4782 | 4783 | /* |
| 4783 | − * BrainBoxes UC-260 | |
| 4784 | + * Brainboxes UC-101 | |
| 4785 | + */ | |
| 4786 | + { PCI_VENDOR_ID_INTASHIELD, 0x0BA1, | |
| 4787 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4788 | + 0, 0, | |
| 4789 | + pbn_b2_2_115200 }, | |
| 4790 | + /* | |
| 4791 | + * Brainboxes UC-235/246 | |
| 4792 | + */ | |
| 4793 | + { PCI_VENDOR_ID_INTASHIELD, 0x0AA1, | |
| 4794 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4795 | + 0, 0, | |
| 4796 | + pbn_b2_1_115200 }, | |
| 4797 | + /* | |
| 4798 | + * Brainboxes UC-257 | |
| 4799 | + */ | |
| 4800 | + { PCI_VENDOR_ID_INTASHIELD, 0x0861, | |
| 4801 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4802 | + 0, 0, | |
| 4803 | + pbn_b2_2_115200 }, | |
| 4804 | + /* | |
| 4805 | + * Brainboxes UC-260/271/701/756 | |
| 4784 | 4806 | */ |
| 4785 | 4807 | { PCI_VENDOR_ID_INTASHIELD, 0x0D21, |
| 4786 | 4808 | PCI_ANY_ID, PCI_ANY_ID, |
| @@ -4788,7 +4810,81 @@ static const struct pci_device_id serial_pci_tbl[] = { · 1 unmodified line | ||
| 4788 | 4810 | pbn_b2_4_115200 }, |
| 4789 | 4811 | { PCI_VENDOR_ID_INTASHIELD, 0x0E34, |
| 4790 | 4812 | PCI_ANY_ID, PCI_ANY_ID, |
| 4791 | − PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, | |
| 4813 | + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, | |
| 4814 | + pbn_b2_4_115200 }, | |
| 4815 | + /* | |
| 4816 | + * Brainboxes UC-268 | |
| 4817 | + */ | |
| 4818 | + { PCI_VENDOR_ID_INTASHIELD, 0x0841, | |
| 4819 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4820 | + 0, 0, | |
| 4821 | + pbn_b2_4_115200 }, | |
| 4822 | + /* | |
| 4823 | + * Brainboxes UC-275/279 | |
| 4824 | + */ | |
| 4825 | + { PCI_VENDOR_ID_INTASHIELD, 0x0881, | |
| 4826 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4827 | + 0, 0, | |
| 4828 | + pbn_b2_8_115200 }, | |
| 4829 | + /* | |
| 4830 | + * Brainboxes UC-302 | |
| 4831 | + */ | |
| 4832 | + { PCI_VENDOR_ID_INTASHIELD, 0x08E1, | |
| 4833 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4834 | + 0, 0, | |
| 4835 | + pbn_b2_2_115200 }, | |
| 4836 | + /* | |
| 4837 | + * Brainboxes UC-310 | |
| 4838 | + */ | |
| 4839 | + { PCI_VENDOR_ID_INTASHIELD, 0x08C1, | |
| 4840 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4841 | + 0, 0, | |
| 4842 | + pbn_b2_2_115200 }, | |
| 4843 | + /* | |
| 4844 | + * Brainboxes UC-313 | |
| 4845 | + */ | |
| 4846 | + { PCI_VENDOR_ID_INTASHIELD, 0x08A3, | |
| 4847 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4848 | + 0, 0, | |
| 4849 | + pbn_b2_2_115200 }, | |
| 4850 | + /* | |
| 4851 | + * Brainboxes UC-320/324 | |
| 4852 | + */ | |
| 4853 | + { PCI_VENDOR_ID_INTASHIELD, 0x0A61, | |
| 4854 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4855 | + 0, 0, | |
| 4856 | + pbn_b2_1_115200 }, | |
| 4857 | + /* | |
| 4858 | + * Brainboxes UC-346 | |
| 4859 | + */ | |
| 4860 | + { PCI_VENDOR_ID_INTASHIELD, 0x0B02, | |
| 4861 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4862 | + 0, 0, | |
| 4863 | + pbn_b2_4_115200 }, | |
| 4864 | + /* | |
| 4865 | + * Brainboxes UC-357 | |
| 4866 | + */ | |
| 4867 | + { PCI_VENDOR_ID_INTASHIELD, 0x0A81, | |
| 4868 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4869 | + 0, 0, | |
| 4870 | + pbn_b2_2_115200 }, | |
| 4871 | + { PCI_VENDOR_ID_INTASHIELD, 0x0A83, | |
| 4872 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4873 | + 0, 0, | |
| 4874 | + pbn_b2_2_115200 }, | |
| 4875 | + /* | |
| 4876 | + * Brainboxes UC-368 | |
| 4877 | + */ | |
| 4878 | + { PCI_VENDOR_ID_INTASHIELD, 0x0C41, | |
| 4879 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4880 | + 0, 0, | |
| 4881 | + pbn_b2_4_115200 }, | |
| 4882 | + /* | |
| 4883 | + * Brainboxes UC-420/431 | |
| 4884 | + */ | |
| 4885 | + { PCI_VENDOR_ID_INTASHIELD, 0x0921, | |
| 4886 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 4887 | + 0, 0, | |
| 4792 | 4888 | pbn_b2_4_115200 }, |
| 4793 | 4889 | /* |
| 4794 | 4890 | * Perle PCI-RAS cards |
| @@ -2056,7 +2056,10 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) · 2055 unmodified lines | ||
| 2056 | 2056 | serial8250_rpm_put(up); |
| 2057 | 2057 | } |
| 2058 | 2058 | |
| 2059 | −static void wait_for_lsr(struct uart_8250_port *up, int bits) | |
| 2059 | +/* | |
| 2060 | + * Wait for transmitter & holding register to empty | |
| 2061 | + */ | |
| 2062 | +static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |
| 2060 | 2063 | { |
| 2061 | 2064 | unsigned int status, tmout = 10000; |
| 2062 | 2065 | |
| @@ -2073,16 +2076,6 @@ static void wait_for_lsr(struct uart_8250_port *up, int bits) · 10 unmodified lines | ||
| 2073 | 2076 | udelay(1); |
| 2074 | 2077 | touch_nmi_watchdog(); |
| 2075 | 2078 | } |
| 2076 | −} | |
| 2077 | − | |
| 2078 | −/* | |
| 2079 | − * Wait for transmitter & holding register to empty | |
| 2080 | − */ | |
| 2081 | −static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |
| 2082 | −{ | |
| 2083 | − unsigned int tmout; | |
| 2084 | − | |
| 2085 | − wait_for_lsr(up, bits); | |
| 2086 | 2079 | |
| 2087 | 2080 | /* Wait up to 1s for flow control if necessary */ |
| 2088 | 2081 | if (up->port.flags & UPF_CONS_FLOW) { |
| @@ -3332,35 +3325,6 @@ static void serial8250_console_restore(struct uart_8250_port *up) · 1243 unmodified lines | ||
| 3332 | 3325 | serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); |
| 3333 | 3326 | } |
| 3334 | 3327 | |
| 3335 | −/* | |
| 3336 | − * Print a string to the serial port using the device FIFO | |
| 3337 | − * | |
| 3338 | − * It sends fifosize bytes and then waits for the fifo | |
| 3339 | − * to get empty. | |
| 3340 | − */ | |
| 3341 | −static void serial8250_console_fifo_write(struct uart_8250_port *up, | |
| 3342 | − const char *s, unsigned int count) | |
| 3343 | −{ | |
| 3344 | − int i; | |
| 3345 | − const char *end = s + count; | |
| 3346 | − unsigned int fifosize = up->port.fifosize; | |
| 3347 | − bool cr_sent = false; | |
| 3348 | − | |
| 3349 | − while (s != end) { | |
| 3350 | − wait_for_lsr(up, UART_LSR_THRE); | |
| 3351 | − | |
| 3352 | − for (i = 0; i < fifosize && s != end; ++i) { | |
| 3353 | − if (*s == '\n' && !cr_sent) { | |
| 3354 | − serial_out(up, UART_TX, '\r'); | |
| 3355 | − cr_sent = true; | |
| 3356 | − } else { | |
| 3357 | − serial_out(up, UART_TX, *s++); | |
| 3358 | − cr_sent = false; | |
| 3359 | − } | |
| 3360 | − } | |
| 3361 | − } | |
| 3362 | −} | |
| 3363 | − | |
| 3364 | 3328 | /* |
| 3365 | 3329 | * Print a string to the serial port trying not to disturb |
| 3366 | 3330 | * any possible real use of the port... |
| @@ -3376,7 +3340,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, · 9 unmodified lines | ||
| 3376 | 3340 | struct uart_8250_em485 *em485 = up->em485; |
| 3377 | 3341 | struct uart_port *port = &up->port; |
| 3378 | 3342 | unsigned long flags; |
| 3379 | − unsigned int ier, use_fifo; | |
| 3343 | + unsigned int ier; | |
| 3380 | 3344 | int locked = 1; |
| 3381 | 3345 | |
| 3382 | 3346 | touch_nmi_watchdog(); |
| @@ -3408,20 +3372,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, · 25 unmodified lines | ||
| 3408 | 3372 | mdelay(port->rs485.delay_rts_before_send); |
| 3409 | 3373 | } |
| 3410 | 3374 | |
| 3411 | − use_fifo = (up->capabilities & UART_CAP_FIFO) && | |
| 3412 | − port->fifosize > 1 && | |
| 3413 | − (serial_port_in(port, UART_FCR) & UART_FCR_ENABLE_FIFO) && | |
| 3414 | − /* | |
| 3415 | − * After we put a data in the fifo, the controller will send | |
| 3416 | − * it regardless of the CTS state. Therefore, only use fifo | |
| 3417 | − * if we don't use control flow. | |
| 3418 | − */ | |
| 3419 | − !(up->port.flags & UPF_CONS_FLOW); | |
| 3420 | − | |
| 3421 | − if (likely(use_fifo)) | |
| 3422 | − serial8250_console_fifo_write(up, s, count); | |
| 3423 | − else | |
| 3424 | − uart_console_write(port, s, count, serial8250_console_putchar); | |
| 3375 | + uart_console_write(port, s, count, serial8250_console_putchar); | |
| 3425 | 3376 | |
| 3426 | 3377 | /* |
| 3427 | 3378 | * Finally, wait for transmitter to become empty |
| @@ -1582,9 +1582,6 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) · 1581 unmodified lines | ||
| 1582 | 1582 | container_of(port, struct uart_amba_port, port); |
| 1583 | 1583 | unsigned int cr; |
| 1584 | 1584 | |
| 1585 | − if (port->rs485.flags & SER_RS485_ENABLED) | |
| 1586 | − mctrl &= ~TIOCM_RTS; | |
| 1587 | − | |
| 1588 | 1585 | cr = pl011_read(uap, REG_CR); |
| 1589 | 1586 | |
| 1590 | 1587 | #define TIOCMBIT(tiocmbit, uartbit) \ |
| @@ -1808,14 +1805,8 @@ static int pl011_startup(struct uart_port *port) · 217 unmodified lines | ||
| 1808 | 1805 | cr &= UART011_CR_RTS | UART011_CR_DTR; |
| 1809 | 1806 | cr |= UART01x_CR_UARTEN | UART011_CR_RXE; |
| 1810 | 1807 | |
| 1811 | − if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 1812 | − if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) | |
| 1813 | − cr &= ~UART011_CR_RTS; | |
| 1814 | − else | |
| 1815 | − cr |= UART011_CR_RTS; | |
| 1816 | − } else { | |
| 1808 | + if (!(port->rs485.flags & SER_RS485_ENABLED)) | |
| 1817 | 1809 | cr |= UART011_CR_TXE; |
| 1818 | − } | |
| 1819 | 1810 | |
| 1820 | 1811 | pl011_write(cr, uap, REG_CR); |
| 1821 | 1812 | |
| @@ -144,6 +144,11 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) · 143 unmodified lines | ||
| 144 | 144 | unsigned long flags; |
| 145 | 145 | unsigned int old; |
| 146 | 146 | |
| 147 | + if (port->rs485.flags & SER_RS485_ENABLED) { | |
| 148 | + set &= ~TIOCM_RTS; | |
| 149 | + clear &= ~TIOCM_RTS; | |
| 150 | + } | |
| 151 | + | |
| 147 | 152 | spin_lock_irqsave(&port->lock, flags); |
| 148 | 153 | old = port->mctrl; |
| 149 | 154 | port->mctrl = (old & ~clear) | set; |
| @@ -157,23 +162,10 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) · 7 unmodified lines | ||
| 157 | 162 | |
| 158 | 163 | static void uart_port_dtr_rts(struct uart_port *uport, int raise) |
| 159 | 164 | { |
| 160 | − int rs485_on = uport->rs485_config && | |
| 161 | − (uport->rs485.flags & SER_RS485_ENABLED); | |
| 162 | − int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND); | |
| 163 | − | |
| 164 | − if (raise) { | |
| 165 | − if (rs485_on && RTS_after_send) { | |
| 166 | − uart_set_mctrl(uport, TIOCM_DTR); | |
| 167 | − uart_clear_mctrl(uport, TIOCM_RTS); | |
| 168 | − } else { | |
| 169 | − uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | |
| 170 | − } | |
| 171 | − } else { | |
| 172 | − unsigned int clear = TIOCM_DTR; | |
| 173 | − | |
| 174 | − clear |= (!rs485_on || RTS_after_send) ? TIOCM_RTS : 0; | |
| 175 | − uart_clear_mctrl(uport, clear); | |
| 176 | − } | |
| 165 | + if (raise) | |
| 166 | + uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | |
| 167 | + else | |
| 168 | + uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | |
| 177 | 169 | } |
| 178 | 170 | |
| 179 | 171 | /* |
| @@ -1075,11 +1067,6 @@ uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) · 895 unmodified lines | ||
| 1075 | 1067 | goto out; |
| 1076 | 1068 | |
| 1077 | 1069 | if (!tty_io_error(tty)) { |
| 1078 | − if (uport->rs485.flags & SER_RS485_ENABLED) { | |
| 1079 | − set &= ~TIOCM_RTS; | |
| 1080 | − clear &= ~TIOCM_RTS; | |
| 1081 | − } | |
| 1082 | − | |
| 1083 | 1070 | uart_update_mctrl(uport, set, clear); |
| 1084 | 1071 | ret = 0; |
| 1085 | 1072 | } |
| @@ -2390,6 +2377,9 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, · 1304 unmodified lines | ||
| 2390 | 2377 | */ |
| 2391 | 2378 | spin_lock_irqsave(&port->lock, flags); |
| 2392 | 2379 | port->mctrl &= TIOCM_DTR; |
| 2380 | + if (port->rs485.flags & SER_RS485_ENABLED && | |
| 2381 | + !(port->rs485.flags & SER_RS485_RTS_AFTER_SEND)) | |
| 2382 | + port->mctrl |= TIOCM_RTS; | |
| 2393 | 2383 | port->ops->set_mctrl(port, port->mctrl); |
| 2394 | 2384 | spin_unlock_irqrestore(&port->lock, flags); |
| 2395 | 2385 | |
| @@ -550,11 +550,23 @@ static void stm32_usart_transmit_chars(struct uart_port *port) · 549 unmodified lines | ||
| 550 | 550 | struct stm32_port *stm32_port = to_stm32_port(port); |
| 551 | 551 | const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; |
| 552 | 552 | struct circ_buf *xmit = &port->state->xmit; |
| 553 | + u32 isr; | |
| 554 | + int ret; | |
| 553 | 555 | |
| 554 | 556 | if (port->x_char) { |
| 555 | 557 | if (stm32_usart_tx_dma_started(stm32_port) && |
| 556 | 558 | stm32_usart_tx_dma_enabled(stm32_port)) |
| 557 | 559 | stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); |
| 560 | + | |
| 561 | + /* Check that TDR is empty before filling FIFO */ | |
| 562 | + ret = | |
| 563 | + readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, | |
| 564 | + isr, | |
| 565 | + (isr & USART_SR_TXE), | |
| 566 | + 10, 1000); | |
| 567 | + if (ret) | |
| 568 | + dev_warn(port->dev, "1 character may be erased\n"); | |
| 569 | + | |
| 558 | 570 | writel_relaxed(port->x_char, port->membase + ofs->tdr); |
| 559 | 571 | port->x_char = 0; |
| 560 | 572 | port->icount.tx++; |
| @@ -730,7 +742,7 @@ static void stm32_usart_start_tx(struct uart_port *port) · 169 unmodified lines | ||
| 730 | 742 | struct serial_rs485 *rs485conf = &port->rs485; |
| 731 | 743 | struct circ_buf *xmit = &port->state->xmit; |
| 732 | 744 | |
| 733 | − if (uart_circ_empty(xmit)) | |
| 745 | + if (uart_circ_empty(xmit) && !port->x_char) | |
| 734 | 746 | return; |
| 735 | 747 | |
| 736 | 748 | if (rs485conf->flags & SER_RS485_ENABLED) { |
| @@ -483,11 +483,11 @@ int cdns_drd_exit(struct cdns *cdns) · 482 unmodified lines | ||
| 483 | 483 | /* Indicate the cdns3 core was power lost before */ |
| 484 | 484 | bool cdns_power_is_lost(struct cdns *cdns) |
| 485 | 485 | { |
| 486 | − if (cdns->version == CDNS3_CONTROLLER_V1) { | |
| 487 | − if (!(readl(&cdns->otg_v1_regs->simulate) & BIT(0))) | |
| 486 | + if (cdns->version == CDNS3_CONTROLLER_V0) { | |
| 487 | + if (!(readl(&cdns->otg_v0_regs->simulate) & BIT(0))) | |
| 488 | 488 | return true; |
| 489 | 489 | } else { |
| 490 | − if (!(readl(&cdns->otg_v0_regs->simulate) & BIT(0))) | |
| 490 | + if (!(readl(&cdns->otg_v1_regs->simulate) & BIT(0))) | |
| 491 | 491 | return true; |
| 492 | 492 | } |
| 493 | 493 | return false; |
| @@ -39,8 +39,11 @@ static int ulpi_match(struct device *dev, struct device_driver *driver) · 38 unmodified lines | ||
| 39 | 39 | struct ulpi *ulpi = to_ulpi_dev(dev); |
| 40 | 40 | const struct ulpi_device_id *id; |
| 41 | 41 | |
| 42 | − /* Some ULPI devices don't have a vendor id so rely on OF match */ | |
| 43 | − if (ulpi->id.vendor == 0) | |
| 42 | + /* | |
| 43 | + * Some ULPI devices don't have a vendor id | |
| 44 | + * or provide an id_table so rely on OF match. | |
| 45 | + */ | |
| 46 | + if (ulpi->id.vendor == 0 || !drv->id_table) | |
| 44 | 47 | return of_driver_match_device(dev, driver); |
| 45 | 48 | |
| 46 | 49 | for (id = drv->id_table; id->vendor; id++) |
| @@ -1563,6 +1563,13 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) · 1562 unmodified lines | ||
| 1563 | 1563 | urb->hcpriv = NULL; |
| 1564 | 1564 | INIT_LIST_HEAD(&urb->urb_list); |
| 1565 | 1565 | atomic_dec(&urb->use_count); |
| 1566 | + /* | |
| 1567 | + * Order the write of urb->use_count above before the read | |
| 1568 | + * of urb->reject below. Pairs with the memory barriers in | |
| 1569 | + * usb_kill_urb() and usb_poison_urb(). | |
| 1570 | + */ | |
| 1571 | + smp_mb__after_atomic(); | |
| 1572 | + | |
| 1566 | 1573 | atomic_dec(&urb->dev->urbnum); |
| 1567 | 1574 | if (atomic_read(&urb->reject)) |
| 1568 | 1575 | wake_up(&usb_kill_urb_queue); |
| @@ -1665,6 +1672,13 @@ static void __usb_hcd_giveback_urb(struct urb *urb) · 96 unmodified lines | ||
| 1665 | 1672 | |
| 1666 | 1673 | usb_anchor_resume_wakeups(anchor); |
| 1667 | 1674 | atomic_dec(&urb->use_count); |
| 1675 | + /* | |
| 1676 | + * Order the write of urb->use_count above before the read | |
| 1677 | + * of urb->reject below. Pairs with the memory barriers in | |
| 1678 | + * usb_kill_urb() and usb_poison_urb(). | |
| 1679 | + */ | |
| 1680 | + smp_mb__after_atomic(); | |
| 1681 | + | |
| 1668 | 1682 | if (unlikely(atomic_read(&urb->reject))) |
| 1669 | 1683 | wake_up(&usb_kill_urb_queue); |
| 1670 | 1684 | usb_put_urb(urb); |
| @@ -715,6 +715,12 @@ void usb_kill_urb(struct urb *urb) · 714 unmodified lines | ||
| 715 | 715 | if (!(urb && urb->dev && urb->ep)) |
| 716 | 716 | return; |
| 717 | 717 | atomic_inc(&urb->reject); |
| 718 | + /* | |
| 719 | + * Order the write of urb->reject above before the read | |
| 720 | + * of urb->use_count below. Pairs with the barriers in | |
| 721 | + * __usb_hcd_giveback_urb() and usb_hcd_submit_urb(). | |
| 722 | + */ | |
| 723 | + smp_mb__after_atomic(); | |
| 718 | 724 | |
| 719 | 725 | usb_hcd_unlink_urb(urb, -ENOENT); |
| 720 | 726 | wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); |
| @@ -756,6 +762,12 @@ void usb_poison_urb(struct urb *urb) · 35 unmodified lines | ||
| 756 | 762 | if (!urb) |
| 757 | 763 | return; |
| 758 | 764 | atomic_inc(&urb->reject); |
| 765 | + /* | |
| 766 | + * Order the write of urb->reject above before the read | |
| 767 | + * of urb->use_count below. Pairs with the barriers in | |
| 768 | + * __usb_hcd_giveback_urb() and usb_hcd_submit_urb(). | |
| 769 | + */ | |
| 770 | + smp_mb__after_atomic(); | |
| 759 | 771 | |
| 760 | 772 | if (!urb->dev || !urb->ep) |
| 761 | 773 | return; |
| @@ -5097,7 +5097,7 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg) · 5096 unmodified lines | ||
| 5097 | 5097 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
| 5098 | 5098 | spin_unlock_irqrestore(&hsotg->lock, flags); |
| 5099 | 5099 | |
| 5100 | − for (ep = 0; ep < hsotg->num_of_eps; ep++) { | |
| 5100 | + for (ep = 1; ep < hsotg->num_of_eps; ep++) { | |
| 5101 | 5101 | if (hsotg->eps_in[ep]) |
| 5102 | 5102 | dwc2_hsotg_ep_disable_lock(&hsotg->eps_in[ep]->ep); |
| 5103 | 5103 | if (hsotg->eps_out[ep]) |
| @@ -102,14 +102,26 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) · 101 unmodified lines | ||
| 102 | 102 | int ret; |
| 103 | 103 | u32 reg; |
| 104 | 104 | |
| 105 | − usb3_phy = devm_phy_get(dev, "usb3-phy"); | |
| 106 | − if (PTR_ERR(usb3_phy) == -EPROBE_DEFER) { | |
| 107 | − ret = -EPROBE_DEFER; | |
| 105 | + usb3_phy = devm_phy_optional_get(dev, "usb3-phy"); | |
| 106 | + if (IS_ERR(usb3_phy)) { | |
| 107 | + ret = PTR_ERR(usb3_phy); | |
| 108 | + dev_err_probe(dev, ret, | |
| 109 | + "failed to get USB3 PHY\n"); | |
| 108 | 110 | goto err; |
| 109 | − } else if (IS_ERR(usb3_phy)) { | |
| 110 | − usb3_phy = NULL; | |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | + /* | |
| 114 | + * The following core resets are not required unless a USB3 PHY | |
| 115 | + * is used, and the subsequent register settings are not required | |
| 116 | + * unless a core reset is performed (they should be set properly | |
| 117 | + * by the first-stage boot loader, but may be reverted by a core | |
| 118 | + * reset). They may also break the configuration if USB3 is actually | |
| 119 | + * in use but the usb3-phy entry is missing from the device tree. | |
| 120 | + * Therefore, skip these operations in this case. | |
| 121 | + */ | |
| 122 | + if (!usb3_phy) | |
| 123 | + goto skip_usb3_phy; | |
| 124 | + | |
| 113 | 125 | crst = devm_reset_control_get_exclusive(dev, "usb_crst"); |
| 114 | 126 | if (IS_ERR(crst)) { |
| 115 | 127 | ret = PTR_ERR(crst); |
| @@ -188,6 +200,7 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) · 72 unmodified lines | ||
| 188 | 200 | goto err; |
| 189 | 201 | } |
| 190 | 202 | |
| 203 | +skip_usb3_phy: | |
| 191 | 204 | /* |
| 192 | 205 | * This routes the USB DMA traffic to go through FPD path instead |
| 193 | 206 | * of reaching DDR directly. This traffic routing is needed to |
| @@ -584,6 +584,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, · 583 unmodified lines | ||
| 584 | 584 | |
| 585 | 585 | if (is_iso) { |
| 586 | 586 | switch (speed) { |
| 587 | + case USB_SPEED_SUPER_PLUS: | |
| 587 | 588 | case USB_SPEED_SUPER: |
| 588 | 589 | size = ss->isoc_maxpacket * |
| 589 | 590 | (ss->isoc_mult + 1) * |
| @@ -1895,7 +1895,7 @@ static int at91udc_probe(struct platform_device *pdev) · 1894 unmodified lines | ||
| 1895 | 1895 | at91_vbus_irq, 0, driver_name, udc); |
| 1896 | 1896 | if (retval) { |
| 1897 | 1897 | DBG("request vbus irq %d failed\n", |
| 1898 | − udc->board.vbus_pin); | |
| 1898 | + desc_to_gpio(udc->board.vbus_pin)); | |
| 1899 | 1899 | goto err_unprepare_iclk; |
| 1900 | 1900 | } |
| 1901 | 1901 | } |
| @@ -437,6 +437,9 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev) · 436 unmodified lines | ||
| 437 | 437 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| 438 | 438 | int ret; |
| 439 | 439 | |
| 440 | + if (pm_runtime_suspended(dev)) | |
| 441 | + pm_runtime_resume(dev); | |
| 442 | + | |
| 440 | 443 | ret = xhci_priv_suspend_quirk(hcd); |
| 441 | 444 | if (ret) |
| 442 | 445 | return ret; |
| @@ -2301,6 +2301,16 @@ UNUSUAL_DEV( 0x2027, 0xa001, 0x0000, 0x9999, · 2300 unmodified lines | ||
| 2301 | 2301 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, |
| 2302 | 2302 | US_FL_SCM_MULT_TARG ), |
| 2303 | 2303 | |
| 2304 | +/* | |
| 2305 | + * Reported by DocMAX <mail@vacharakis.de> | |
| 2306 | + * and Thomas Weißschuh <linux@weissschuh.net> | |
| 2307 | + */ | |
| 2308 | +UNUSUAL_DEV( 0x2109, 0x0715, 0x9999, 0x9999, | |
| 2309 | + "VIA Labs, Inc.", | |
| 2310 | + "VL817 SATA Bridge", | |
| 2311 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 2312 | + US_FL_IGNORE_UAS), | |
| 2313 | + | |
| 2304 | 2314 | UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, |
| 2305 | 2315 | "ST", |
| 2306 | 2316 | "2A", |
| @@ -56,7 +56,12 @@ int typec_link_ports(struct typec_port *con) · 55 unmodified lines | ||
| 56 | 56 | { |
| 57 | 57 | struct each_port_arg arg = { .port = con, .match = NULL }; |
| 58 | 58 | |
| 59 | + if (!has_acpi_companion(&con->dev)) | |
| 60 | + return 0; | |
| 61 | + | |
| 59 | 62 | bus_for_each_dev(&acpi_bus_type, NULL, &arg, typec_port_match); |
| 63 | + if (!arg.match) | |
| 64 | + return 0; | |
| 60 | 65 | |
| 61 | 66 | /* |
| 62 | 67 | * REVISIT: Now each connector can have only a single component master. |
| @@ -74,5 +79,6 @@ int typec_link_ports(struct typec_port *con) · 11 unmodified lines | ||
| 74 | 79 | |
| 75 | 80 | void typec_unlink_ports(struct typec_port *con) |
| 76 | 81 | { |
| 77 | − component_master_del(&con->dev, &typec_aggregate_ops); | |
| 82 | + if (has_acpi_companion(&con->dev)) | |
| 83 | + component_master_del(&con->dev, &typec_aggregate_ops); | |
| 78 | 84 | } |
| @@ -75,9 +75,25 @@ static int tcpci_write16(struct tcpci *tcpci, unsigned int reg, u16 val) · 74 unmodified lines | ||
| 75 | 75 | static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc) |
| 76 | 76 | { |
| 77 | 77 | struct tcpci *tcpci = tcpc_to_tcpci(tcpc); |
| 78 | + bool vconn_pres; | |
| 79 | + enum typec_cc_polarity polarity = TYPEC_POLARITY_CC1; | |
| 78 | 80 | unsigned int reg; |
| 79 | 81 | int ret; |
| 80 | 82 | |
| 83 | + ret = regmap_read(tcpci->regmap, TCPC_POWER_STATUS, ®); | |
| 84 | + if (ret < 0) | |
| 85 | + return ret; | |
| 86 | + | |
| 87 | + vconn_pres = !!(reg & TCPC_POWER_STATUS_VCONN_PRES); | |
| 88 | + if (vconn_pres) { | |
| 89 | + ret = regmap_read(tcpci->regmap, TCPC_TCPC_CTRL, ®); | |
| 90 | + if (ret < 0) | |
| 91 | + return ret; | |
| 92 | + | |
| 93 | + if (reg & TCPC_TCPC_CTRL_ORIENTATION) | |
| 94 | + polarity = TYPEC_POLARITY_CC2; | |
| 95 | + } | |
| 96 | + | |
| 81 | 97 | switch (cc) { |
| 82 | 98 | case TYPEC_CC_RA: |
| 83 | 99 | reg = (TCPC_ROLE_CTRL_CC_RA << TCPC_ROLE_CTRL_CC1_SHIFT) | |
| @@ -112,6 +128,16 @@ static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc) · 28 unmodified lines | ||
| 112 | 128 | break; |
| 113 | 129 | } |
| 114 | 130 | |
| 131 | + if (vconn_pres) { | |
| 132 | + if (polarity == TYPEC_POLARITY_CC2) { | |
| 133 | + reg &= ~(TCPC_ROLE_CTRL_CC1_MASK << TCPC_ROLE_CTRL_CC1_SHIFT); | |
| 134 | + reg |= (TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC1_SHIFT); | |
| 135 | + } else { | |
| 136 | + reg &= ~(TCPC_ROLE_CTRL_CC2_MASK << TCPC_ROLE_CTRL_CC2_SHIFT); | |
| 137 | + reg |= (TCPC_ROLE_CTRL_CC_OPEN << TCPC_ROLE_CTRL_CC2_SHIFT); | |
| 138 | + } | |
| 139 | + } | |
| 140 | + | |
| 115 | 141 | ret = regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg); |
| 116 | 142 | if (ret < 0) |
| 117 | 143 | return ret; |
| @@ -98,6 +98,7 @@ · 97 unmodified lines | ||
| 98 | 98 | #define TCPC_POWER_STATUS_SOURCING_VBUS BIT(4) |
| 99 | 99 | #define TCPC_POWER_STATUS_VBUS_DET BIT(3) |
| 100 | 100 | #define TCPC_POWER_STATUS_VBUS_PRES BIT(2) |
| 101 | +#define TCPC_POWER_STATUS_VCONN_PRES BIT(1) | |
| 101 | 102 | #define TCPC_POWER_STATUS_SINKING_VBUS BIT(0) |
| 102 | 103 | |
| 103 | 104 | #define TCPC_FAULT_STATUS 0x1f |
| @@ -5156,7 +5156,8 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) · 5155 unmodified lines | ||
| 5156 | 5156 | case SNK_TRYWAIT_DEBOUNCE: |
| 5157 | 5157 | break; |
| 5158 | 5158 | case SNK_ATTACH_WAIT: |
| 5159 | − tcpm_set_state(port, SNK_UNATTACHED, 0); | |
| 5159 | + case SNK_DEBOUNCED: | |
| 5160 | + /* Do nothing, as TCPM is still waiting for vbus to reaach VSAFE5V to connect */ | |
| 5160 | 5161 | break; |
| 5161 | 5162 | |
| 5162 | 5163 | case SNK_NEGOTIATE_CAPABILITIES: |
| @@ -5263,6 +5264,10 @@ static void _tcpm_pd_vbus_vsafe0v(struct tcpm_port *port) · 100 unmodified lines | ||
| 5263 | 5264 | case PR_SWAP_SNK_SRC_SOURCE_ON: |
| 5264 | 5265 | /* Do nothing, vsafe0v is expected during transition */ |
| 5265 | 5266 | break; |
| 5267 | + case SNK_ATTACH_WAIT: | |
| 5268 | + case SNK_DEBOUNCED: | |
| 5269 | + /*Do nothing, still waiting for VSAFE5V for connect */ | |
| 5270 | + break; | |
| 5266 | 5271 | default: |
| 5267 | 5272 | if (port->pwr_role == TYPEC_SINK && port->auto_vbus_discharge_enabled) |
| 5268 | 5273 | tcpm_set_state(port, SNK_UNATTACHED, 0); |
| @@ -325,7 +325,7 @@ static int ucsi_ccg_init(struct ucsi_ccg *uc) · 324 unmodified lines | ||
| 325 | 325 | if (status < 0) |
| 326 | 326 | return status; |
| 327 | 327 | |
| 328 | − if (!data) | |
| 328 | + if (!(data & DEV_INT)) | |
| 329 | 329 | return 0; |
| 330 | 330 | |
| 331 | 331 | status = ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data)); |
| @@ -287,8 +287,6 @@ struct hvfb_par { · 286 unmodified lines | ||
| 287 | 287 | |
| 288 | 288 | static uint screen_width = HVFB_WIDTH; |
| 289 | 289 | static uint screen_height = HVFB_HEIGHT; |
| 290 | −static uint screen_width_max = HVFB_WIDTH; | |
| 291 | −static uint screen_height_max = HVFB_HEIGHT; | |
| 292 | 290 | static uint screen_depth; |
| 293 | 291 | static uint screen_fb_size; |
| 294 | 292 | static uint dio_fb_size; /* FB size for deferred IO */ |
| @@ -582,7 +580,6 @@ static int synthvid_get_supported_resolution(struct hv_device *hdev) · 287 unmodified lines | ||
| 582 | 580 | int ret = 0; |
| 583 | 581 | unsigned long t; |
| 584 | 582 | u8 index; |
| 585 | − int i; | |
| 586 | 583 | |
| 587 | 584 | memset(msg, 0, sizeof(struct synthvid_msg)); |
| 588 | 585 | msg->vid_hdr.type = SYNTHVID_RESOLUTION_REQUEST; |
| @@ -613,13 +610,6 @@ static int synthvid_get_supported_resolution(struct hv_device *hdev) · 24 unmodified lines | ||
| 613 | 610 | goto out; |
| 614 | 611 | } |
| 615 | 612 | |
| 616 | − for (i = 0; i < msg->resolution_resp.resolution_count; i++) { | |
| 617 | − screen_width_max = max_t(unsigned int, screen_width_max, | |
| 618 | − msg->resolution_resp.supported_resolution[i].width); | |
| 619 | − screen_height_max = max_t(unsigned int, screen_height_max, | |
| 620 | − msg->resolution_resp.supported_resolution[i].height); | |
| 621 | − } | |
| 622 | − | |
| 623 | 613 | screen_width = |
| 624 | 614 | msg->resolution_resp.supported_resolution[index].width; |
| 625 | 615 | screen_height = |
| @@ -941,7 +931,7 @@ static void hvfb_get_option(struct fb_info *info) · 315 unmodified lines | ||
| 941 | 931 | |
| 942 | 932 | if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN || |
| 943 | 933 | (synthvid_ver_ge(par->synthvid_version, SYNTHVID_VERSION_WIN10) && |
| 944 | − (x > screen_width_max || y > screen_height_max)) || | |
| 934 | + (x * y * screen_depth / 8 > screen_fb_size)) || | |
| 945 | 935 | (par->synthvid_version == SYNTHVID_VERSION_WIN8 && |
| 946 | 936 | x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8) || |
| 947 | 937 | (par->synthvid_version == SYNTHVID_VERSION_WIN7 && |
| @@ -1194,8 +1184,8 @@ static int hvfb_probe(struct hv_device *hdev, · 246 unmodified lines | ||
| 1194 | 1184 | } |
| 1195 | 1185 | |
| 1196 | 1186 | hvfb_get_option(info); |
| 1197 | − pr_info("Screen resolution: %dx%d, Color depth: %d\n", | |
| 1198 | − screen_width, screen_height, screen_depth); | |
| 1187 | + pr_info("Screen resolution: %dx%d, Color depth: %d, Frame buffer size: %d\n", | |
| 1188 | + screen_width, screen_height, screen_depth, screen_fb_size); | |
| 1199 | 1189 | |
| 1200 | 1190 | ret = hvfb_getmem(hdev, info); |
| 1201 | 1191 | if (ret) { |
| @@ -817,20 +817,20 @@ static struct file_system_type bm_fs_type = { · 816 unmodified lines | ||
| 817 | 817 | }; |
| 818 | 818 | MODULE_ALIAS_FS("binfmt_misc"); |
| 819 | 819 | |
| 820 | +static struct ctl_table_header *binfmt_misc_header; | |
| 821 | + | |
| 820 | 822 | static int __init init_misc_binfmt(void) |
| 821 | 823 | { |
| 822 | 824 | int err = register_filesystem(&bm_fs_type); |
| 823 | 825 | if (!err) |
| 824 | 826 | insert_binfmt(&misc_format); |
| 825 | − if (!register_sysctl_mount_point("fs/binfmt_misc")) { | |
| 826 | − pr_warn("Failed to create fs/binfmt_misc sysctl mount point"); | |
| 827 | − return -ENOMEM; | |
| 828 | − } | |
| 827 | + binfmt_misc_header = register_sysctl_mount_point("fs/binfmt_misc"); | |
| 829 | 828 | return 0; |
| 830 | 829 | } |
| 831 | 830 | |
| 832 | 831 | static void __exit exit_misc_binfmt(void) |
| 833 | 832 | { |
| 833 | + unregister_sysctl_table(binfmt_misc_header); | |
| 834 | 834 | unregister_binfmt(&misc_format); |
| 835 | 835 | unregister_filesystem(&bm_fs_type); |
| 836 | 836 | } |
| @@ -1213,6 +1213,35 @@ static int defrag_collect_targets(struct btrfs_inode *inode, · 1212 unmodified lines | ||
| 1213 | 1213 | if (em->generation < newer_than) |
| 1214 | 1214 | goto next; |
| 1215 | 1215 | |
| 1216 | + /* | |
| 1217 | + * Our start offset might be in the middle of an existing extent | |
| 1218 | + * map, so take that into account. | |
| 1219 | + */ | |
| 1220 | + range_len = em->len - (cur - em->start); | |
| 1221 | + /* | |
| 1222 | + * If this range of the extent map is already flagged for delalloc, | |
| 1223 | + * skip it, because: | |
| 1224 | + * | |
| 1225 | + * 1) We could deadlock later, when trying to reserve space for | |
| 1226 | + * delalloc, because in case we can't immediately reserve space | |
| 1227 | + * the flusher can start delalloc and wait for the respective | |
| 1228 | + * ordered extents to complete. The deadlock would happen | |
| 1229 | + * because we do the space reservation while holding the range | |
| 1230 | + * locked, and starting writeback, or finishing an ordered | |
| 1231 | + * extent, requires locking the range; | |
| 1232 | + * | |
| 1233 | + * 2) If there's delalloc there, it means there's dirty pages for | |
| 1234 | + * which writeback has not started yet (we clean the delalloc | |
| 1235 | + * flag when starting writeback and after creating an ordered | |
| 1236 | + * extent). If we mark pages in an adjacent range for defrag, | |
| 1237 | + * then we will have a larger contiguous range for delalloc, | |
| 1238 | + * very likely resulting in a larger extent after writeback is | |
| 1239 | + * triggered (except in a case of free space fragmentation). | |
| 1240 | + */ | |
| 1241 | + if (test_range_bit(&inode->io_tree, cur, cur + range_len - 1, | |
| 1242 | + EXTENT_DELALLOC, 0, NULL)) | |
| 1243 | + goto next; | |
| 1244 | + | |
| 1216 | 1245 | /* |
| 1217 | 1246 | * For do_compress case, we want to compress all valid file |
| 1218 | 1247 | * extents, thus no @extent_thresh or mergeable check. |
| @@ -1221,7 +1250,7 @@ static int defrag_collect_targets(struct btrfs_inode *inode, · 2 unmodified lines | ||
| 1221 | 1250 | goto add; |
| 1222 | 1251 | |
| 1223 | 1252 | /* Skip too large extent */ |
| 1224 | − if (em->len >= extent_thresh) | |
| 1253 | + if (range_len >= extent_thresh) | |
| 1225 | 1254 | goto next; |
| 1226 | 1255 | |
| 1227 | 1256 | next_mergeable = defrag_check_next_extent(&inode->vfs_inode, em, |
| @@ -1442,9 +1471,11 @@ static int defrag_one_cluster(struct btrfs_inode *inode, · 214 unmodified lines | ||
| 1442 | 1471 | list_for_each_entry(entry, &target_list, list) { |
| 1443 | 1472 | u32 range_len = entry->len; |
| 1444 | 1473 | |
| 1445 | − /* Reached the limit */ | |
| 1446 | − if (max_sectors && max_sectors == *sectors_defragged) | |
| 1474 | + /* Reached or beyond the limit */ | |
| 1475 | + if (max_sectors && *sectors_defragged >= max_sectors) { | |
| 1476 | + ret = 1; | |
| 1447 | 1477 | break; |
| 1478 | + } | |
| 1448 | 1479 | |
| 1449 | 1480 | if (max_sectors) |
| 1450 | 1481 | range_len = min_t(u32, range_len, |
| @@ -1465,7 +1496,8 @@ static int defrag_one_cluster(struct btrfs_inode *inode, · 14 unmodified lines | ||
| 1465 | 1496 | extent_thresh, newer_than, do_compress); |
| 1466 | 1497 | if (ret < 0) |
| 1467 | 1498 | break; |
| 1468 | − *sectors_defragged += range_len; | |
| 1499 | + *sectors_defragged += range_len >> | |
| 1500 | + inode->root->fs_info->sectorsize_bits; | |
| 1469 | 1501 | } |
| 1470 | 1502 | out: |
| 1471 | 1503 | list_for_each_entry_safe(entry, tmp, &target_list, list) { |
| @@ -1484,6 +1516,12 @@ out: · 12 unmodified lines | ||
| 1484 | 1516 | * @newer_than: minimum transid to defrag |
| 1485 | 1517 | * @max_to_defrag: max number of sectors to be defragged, if 0, the whole inode |
| 1486 | 1518 | * will be defragged. |
| 1519 | + * | |
| 1520 | + * Return <0 for error. | |
| 1521 | + * Return >=0 for the number of sectors defragged, and range->start will be updated | |
| 1522 | + * to indicate the file offset where next defrag should be started at. | |
| 1523 | + * (Mostly for autodefrag, which sets @max_to_defrag thus we may exit early without | |
| 1524 | + * defragging all the range). | |
| 1487 | 1525 | */ |
| 1488 | 1526 | int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra, |
| 1489 | 1527 | struct btrfs_ioctl_defrag_range_args *range, |
| @@ -1499,6 +1537,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra, · 9 unmodified lines | ||
| 1499 | 1537 | int compress_type = BTRFS_COMPRESS_ZLIB; |
| 1500 | 1538 | int ret = 0; |
| 1501 | 1539 | u32 extent_thresh = range->extent_thresh; |
| 1540 | + pgoff_t start_index; | |
| 1502 | 1541 | |
| 1503 | 1542 | if (isize == 0) |
| 1504 | 1543 | return 0; |
| @@ -1518,12 +1557,16 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra, · 13 unmodified lines | ||
| 1518 | 1557 | |
| 1519 | 1558 | if (range->start + range->len > range->start) { |
| 1520 | 1559 | /* Got a specific range */ |
| 1521 | − last_byte = min(isize, range->start + range->len) - 1; | |
| 1560 | + last_byte = min(isize, range->start + range->len); | |
| 1522 | 1561 | } else { |
| 1523 | 1562 | /* Defrag until file end */ |
| 1524 | − last_byte = isize - 1; | |
| 1563 | + last_byte = isize; | |
| 1525 | 1564 | } |
| 1526 | 1565 | |
| 1566 | + /* Align the range */ | |
| 1567 | + cur = round_down(range->start, fs_info->sectorsize); | |
| 1568 | + last_byte = round_up(last_byte, fs_info->sectorsize) - 1; | |
| 1569 | + | |
| 1527 | 1570 | /* |
| 1528 | 1571 | * If we were not given a ra, allocate a readahead context. As |
| 1529 | 1572 | * readahead is just an optimization, defrag will work without it so |
| @@ -1536,16 +1579,26 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra, · 6 unmodified lines | ||
| 1536 | 1579 | file_ra_state_init(ra, inode->i_mapping); |
| 1537 | 1580 | } |
| 1538 | 1581 | |
| 1539 | − /* Align the range */ | |
| 1540 | − cur = round_down(range->start, fs_info->sectorsize); | |
| 1541 | − last_byte = round_up(last_byte, fs_info->sectorsize) - 1; | |
| 1582 | + /* | |
| 1583 | + * Make writeback start from the beginning of the range, so that the | |
| 1584 | + * defrag range can be written sequentially. | |
| 1585 | + */ | |
| 1586 | + start_index = cur >> PAGE_SHIFT; | |
| 1587 | + if (start_index < inode->i_mapping->writeback_index) | |
| 1588 | + inode->i_mapping->writeback_index = start_index; | |
| 1542 | 1589 | |
| 1543 | 1590 | while (cur < last_byte) { |
| 1591 | + const unsigned long prev_sectors_defragged = sectors_defragged; | |
| 1544 | 1592 | u64 cluster_end; |
| 1545 | 1593 | |
| 1546 | 1594 | /* The cluster size 256K should always be page aligned */ |
| 1547 | 1595 | BUILD_BUG_ON(!IS_ALIGNED(CLUSTER_SIZE, PAGE_SIZE)); |
| 1548 | 1596 | |
| 1597 | + if (btrfs_defrag_cancelled(fs_info)) { | |
| 1598 | + ret = -EAGAIN; | |
| 1599 | + break; | |
| 1600 | + } | |
| 1601 | + | |
| 1549 | 1602 | /* We want the cluster end at page boundary when possible */ |
| 1550 | 1603 | cluster_end = (((cur >> PAGE_SHIFT) + |
| 1551 | 1604 | (SZ_256K >> PAGE_SHIFT)) << PAGE_SHIFT) - 1; |
| @@ -1567,14 +1620,27 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra, · 15 unmodified lines | ||
| 1567 | 1620 | cluster_end + 1 - cur, extent_thresh, |
| 1568 | 1621 | newer_than, do_compress, |
| 1569 | 1622 | §ors_defragged, max_to_defrag); |
| 1623 | + | |
| 1624 | + if (sectors_defragged > prev_sectors_defragged) | |
| 1625 | + balance_dirty_pages_ratelimited(inode->i_mapping); | |
| 1626 | + | |
| 1570 | 1627 | btrfs_inode_unlock(inode, 0); |
| 1571 | 1628 | if (ret < 0) |
| 1572 | 1629 | break; |
| 1573 | 1630 | cur = cluster_end + 1; |
| 1631 | + if (ret > 0) { | |
| 1632 | + ret = 0; | |
| 1633 | + break; | |
| 1634 | + } | |
| 1574 | 1635 | } |
| 1575 | 1636 | |
| 1576 | 1637 | if (ra_allocated) |
| 1577 | 1638 | kfree(ra); |
| 1639 | + /* | |
| 1640 | + * Update range.start for autodefrag, this will indicate where to start | |
| 1641 | + * in next run. | |
| 1642 | + */ | |
| 1643 | + range->start = cur; | |
| 1578 | 1644 | if (sectors_defragged) { |
| 1579 | 1645 | /* |
| 1580 | 1646 | * We have defragged some sectors, for compression case they |
| @@ -3086,10 +3152,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, · 1505 unmodified lines | ||
| 3086 | 3152 | btrfs_inode_lock(inode, 0); |
| 3087 | 3153 | err = btrfs_delete_subvolume(dir, dentry); |
| 3088 | 3154 | btrfs_inode_unlock(inode, 0); |
| 3089 | − if (!err) { | |
| 3090 | − fsnotify_rmdir(dir, dentry); | |
| 3091 | − d_delete(dentry); | |
| 3092 | − } | |
| 3155 | + if (!err) | |
| 3156 | + d_delete_notify(dir, dentry); | |
| 3093 | 3157 | |
| 3094 | 3158 | out_dput: |
| 3095 | 3159 | dput(dentry); |
| @@ -2218,6 +2218,7 @@ static int unsafe_request_wait(struct inode *inode) · 2217 unmodified lines | ||
| 2218 | 2218 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; |
| 2219 | 2219 | struct ceph_inode_info *ci = ceph_inode(inode); |
| 2220 | 2220 | struct ceph_mds_request *req1 = NULL, *req2 = NULL; |
| 2221 | + unsigned int max_sessions; | |
| 2221 | 2222 | int ret, err = 0; |
| 2222 | 2223 | |
| 2223 | 2224 | spin_lock(&ci->i_unsafe_lock); |
| @@ -2235,37 +2236,45 @@ static int unsafe_request_wait(struct inode *inode) · 11 unmodified lines | ||
| 2235 | 2236 | } |
| 2236 | 2237 | spin_unlock(&ci->i_unsafe_lock); |
| 2237 | 2238 | |
| 2239 | + /* | |
| 2240 | + * The mdsc->max_sessions is unlikely to be changed | |
| 2241 | + * mostly, here we will retry it by reallocating the | |
| 2242 | + * sessions array memory to get rid of the mdsc->mutex | |
| 2243 | + * lock. | |
| 2244 | + */ | |
| 2245 | +retry: | |
| 2246 | + max_sessions = mdsc->max_sessions; | |
| 2247 | + | |
| 2238 | 2248 | /* |
| 2239 | 2249 | * Trigger to flush the journal logs in all the relevant MDSes |
| 2240 | 2250 | * manually, or in the worst case we must wait at most 5 seconds |
| 2241 | 2251 | * to wait the journal logs to be flushed by the MDSes periodically. |
| 2242 | 2252 | */ |
| 2243 | − if (req1 || req2) { | |
| 2253 | + if ((req1 || req2) && likely(max_sessions)) { | |
| 2244 | 2254 | struct ceph_mds_session **sessions = NULL; |
| 2245 | 2255 | struct ceph_mds_session *s; |
| 2246 | 2256 | struct ceph_mds_request *req; |
| 2247 | − unsigned int max; | |
| 2248 | 2257 | int i; |
| 2249 | 2258 | |
| 2250 | − /* | |
| 2251 | − * The mdsc->max_sessions is unlikely to be changed | |
| 2252 | − * mostly, here we will retry it by reallocating the | |
| 2253 | − * sessions arrary memory to get rid of the mdsc->mutex | |
| 2254 | − * lock. | |
| 2255 | − */ | |
| 2256 | −retry: | |
| 2257 | − max = mdsc->max_sessions; | |
| 2258 | − sessions = krealloc(sessions, max * sizeof(s), __GFP_ZERO); | |
| 2259 | − if (!sessions) | |
| 2260 | − return -ENOMEM; | |
| 2259 | + sessions = kzalloc(max_sessions * sizeof(s), GFP_KERNEL); | |
| 2260 | + if (!sessions) { | |
| 2261 | + err = -ENOMEM; | |
| 2262 | + goto out; | |
| 2263 | + } | |
| 2261 | 2264 | |
| 2262 | 2265 | spin_lock(&ci->i_unsafe_lock); |
| 2263 | 2266 | if (req1) { |
| 2264 | 2267 | list_for_each_entry(req, &ci->i_unsafe_dirops, |
| 2265 | 2268 | r_unsafe_dir_item) { |
| 2266 | 2269 | s = req->r_session; |
| 2267 | − if (unlikely(s->s_mds >= max)) { | |
| 2270 | + if (unlikely(s->s_mds >= max_sessions)) { | |
| 2268 | 2271 | spin_unlock(&ci->i_unsafe_lock); |
| 2272 | + for (i = 0; i < max_sessions; i++) { | |
| 2273 | + s = sessions[i]; | |
| 2274 | + if (s) | |
| 2275 | + ceph_put_mds_session(s); | |
| 2276 | + } | |
| 2277 | + kfree(sessions); | |
| 2269 | 2278 | goto retry; |
| 2270 | 2279 | } |
| 2271 | 2280 | if (!sessions[s->s_mds]) { |
| @@ -2278,8 +2287,14 @@ retry: · 6 unmodified lines | ||
| 2278 | 2287 | list_for_each_entry(req, &ci->i_unsafe_iops, |
| 2279 | 2288 | r_unsafe_target_item) { |
| 2280 | 2289 | s = req->r_session; |
| 2281 | − if (unlikely(s->s_mds >= max)) { | |
| 2290 | + if (unlikely(s->s_mds >= max_sessions)) { | |
| 2282 | 2291 | spin_unlock(&ci->i_unsafe_lock); |
| 2292 | + for (i = 0; i < max_sessions; i++) { | |
| 2293 | + s = sessions[i]; | |
| 2294 | + if (s) | |
| 2295 | + ceph_put_mds_session(s); | |
| 2296 | + } | |
| 2297 | + kfree(sessions); | |
| 2283 | 2298 | goto retry; |
| 2284 | 2299 | } |
| 2285 | 2300 | if (!sessions[s->s_mds]) { |
| @@ -2300,7 +2315,7 @@ retry: · 14 unmodified lines | ||
| 2300 | 2315 | spin_unlock(&ci->i_ceph_lock); |
| 2301 | 2316 | |
| 2302 | 2317 | /* send flush mdlog request to MDSes */ |
| 2303 | − for (i = 0; i < max; i++) { | |
| 2318 | + for (i = 0; i < max_sessions; i++) { | |
| 2304 | 2319 | s = sessions[i]; |
| 2305 | 2320 | if (s) { |
| 2306 | 2321 | send_flush_mdlog(s); |
| @@ -2317,15 +2332,19 @@ retry: · 10 unmodified lines | ||
| 2317 | 2332 | ceph_timeout_jiffies(req1->r_timeout)); |
| 2318 | 2333 | if (ret) |
| 2319 | 2334 | err = -EIO; |
| 2320 | − ceph_mdsc_put_request(req1); | |
| 2321 | 2335 | } |
| 2322 | 2336 | if (req2) { |
| 2323 | 2337 | ret = !wait_for_completion_timeout(&req2->r_safe_completion, |
| 2324 | 2338 | ceph_timeout_jiffies(req2->r_timeout)); |
| 2325 | 2339 | if (ret) |
| 2326 | 2340 | err = -EIO; |
| 2327 | − ceph_mdsc_put_request(req2); | |
| 2328 | 2341 | } |
| 2342 | + | |
| 2343 | +out: | |
| 2344 | + if (req1) | |
| 2345 | + ceph_mdsc_put_request(req1); | |
| 2346 | + if (req2) | |
| 2347 | + ceph_mdsc_put_request(req2); | |
| 2329 | 2348 | return err; |
| 2330 | 2349 | } |
| 2331 | 2350 | |
| @@ -583,6 +583,7 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry, · 582 unmodified lines | ||
| 583 | 583 | struct ceph_inode_info *ci = ceph_inode(dir); |
| 584 | 584 | struct inode *inode; |
| 585 | 585 | struct timespec64 now; |
| 586 | + struct ceph_string *pool_ns; | |
| 586 | 587 | struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); |
| 587 | 588 | struct ceph_vino vino = { .ino = req->r_deleg_ino, |
| 588 | 589 | .snap = CEPH_NOSNAP }; |
| @@ -632,6 +633,12 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry, · 43 unmodified lines | ||
| 632 | 633 | in.max_size = cpu_to_le64(lo->stripe_unit); |
| 633 | 634 | |
| 634 | 635 | ceph_file_layout_to_legacy(lo, &in.layout); |
| 636 | + /* lo is private, so pool_ns can't change */ | |
| 637 | + pool_ns = rcu_dereference_raw(lo->pool_ns); | |
| 638 | + if (pool_ns) { | |
| 639 | + iinfo.pool_ns_len = pool_ns->len; | |
| 640 | + iinfo.pool_ns_data = pool_ns->str; | |
| 641 | + } | |
| 635 | 642 | |
| 636 | 643 | down_read(&mdsc->snap_rwsem); |
| 637 | 644 | ret = ceph_fill_inode(inode, NULL, &iinfo, NULL, req->r_session, |
| @@ -750,8 +757,10 @@ retry: · 112 unmodified lines | ||
| 750 | 757 | restore_deleg_ino(dir, req->r_deleg_ino); |
| 751 | 758 | ceph_mdsc_put_request(req); |
| 752 | 759 | try_async = false; |
| 760 | + ceph_put_string(rcu_dereference_raw(lo.pool_ns)); | |
| 753 | 761 | goto retry; |
| 754 | 762 | } |
| 763 | + ceph_put_string(rcu_dereference_raw(lo.pool_ns)); | |
| 755 | 764 | goto out_req; |
| 756 | 765 | } |
| 757 | 766 | } |
| @@ -1780,8 +1780,8 @@ void configfs_unregister_group(struct config_group *group) · 1779 unmodified lines | ||
| 1780 | 1780 | configfs_detach_group(&group->cg_item); |
| 1781 | 1781 | d_inode(dentry)->i_flags |= S_DEAD; |
| 1782 | 1782 | dont_mount(dentry); |
| 1783 | + d_drop(dentry); | |
| 1783 | 1784 | fsnotify_rmdir(d_inode(parent), dentry); |
| 1784 | − d_delete(dentry); | |
| 1785 | 1785 | inode_unlock(d_inode(parent)); |
| 1786 | 1786 | |
| 1787 | 1787 | dput(dentry); |
| @@ -1922,10 +1922,10 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) · 134 unmodified lines | ||
| 1922 | 1922 | configfs_detach_group(&group->cg_item); |
| 1923 | 1923 | d_inode(dentry)->i_flags |= S_DEAD; |
| 1924 | 1924 | dont_mount(dentry); |
| 1925 | − fsnotify_rmdir(d_inode(root), dentry); | |
| 1926 | 1925 | inode_unlock(d_inode(dentry)); |
| 1927 | 1926 | |
| 1928 | − d_delete(dentry); | |
| 1927 | + d_drop(dentry); | |
| 1928 | + fsnotify_rmdir(d_inode(root), dentry); | |
| 1929 | 1929 | |
| 1930 | 1930 | inode_unlock(d_inode(root)); |
| 1931 | 1931 | |
| @@ -621,8 +621,8 @@ void devpts_pty_kill(struct dentry *dentry) · 620 unmodified lines | ||
| 621 | 621 | |
| 622 | 622 | dentry->d_fsdata = NULL; |
| 623 | 623 | drop_nlink(dentry->d_inode); |
| 624 | − fsnotify_unlink(d_inode(dentry->d_parent), dentry); | |
| 625 | 624 | d_drop(dentry); |
| 625 | + fsnotify_unlink(d_inode(dentry->d_parent), dentry); | |
| 626 | 626 | dput(dentry); /* d_alloc_name() in devpts_pty_new() */ |
| 627 | 627 | } |
| 628 | 628 | |
| @@ -7822,10 +7822,15 @@ static __cold void io_rsrc_node_ref_zero(struct percpu_ref *ref) · 7821 unmodified lines | ||
| 7822 | 7822 | struct io_ring_ctx *ctx = node->rsrc_data->ctx; |
| 7823 | 7823 | unsigned long flags; |
| 7824 | 7824 | bool first_add = false; |
| 7825 | + unsigned long delay = HZ; | |
| 7825 | 7826 | |
| 7826 | 7827 | spin_lock_irqsave(&ctx->rsrc_ref_lock, flags); |
| 7827 | 7828 | node->done = true; |
| 7828 | 7829 | |
| 7830 | + /* if we are mid-quiesce then do not delay */ | |
| 7831 | + if (node->rsrc_data->quiesce) | |
| 7832 | + delay = 0; | |
| 7833 | + | |
| 7829 | 7834 | while (!list_empty(&ctx->rsrc_ref_list)) { |
| 7830 | 7835 | node = list_first_entry(&ctx->rsrc_ref_list, |
| 7831 | 7836 | struct io_rsrc_node, node); |
| @@ -7838,10 +7843,10 @@ static __cold void io_rsrc_node_ref_zero(struct percpu_ref *ref) · 6 unmodified lines | ||
| 7838 | 7843 | spin_unlock_irqrestore(&ctx->rsrc_ref_lock, flags); |
| 7839 | 7844 | |
| 7840 | 7845 | if (first_add) |
| 7841 | − mod_delayed_work(system_wq, &ctx->rsrc_put_work, HZ); | |
| 7846 | + mod_delayed_work(system_wq, &ctx->rsrc_put_work, delay); | |
| 7842 | 7847 | } |
| 7843 | 7848 | |
| 7844 | −static struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx) | |
| 7849 | +static struct io_rsrc_node *io_rsrc_node_alloc(void) | |
| 7845 | 7850 | { |
| 7846 | 7851 | struct io_rsrc_node *ref_node; |
| 7847 | 7852 | |
| @@ -7892,7 +7897,7 @@ static int io_rsrc_node_switch_start(struct io_ring_ctx *ctx) · 44 unmodified lines | ||
| 7892 | 7897 | { |
| 7893 | 7898 | if (ctx->rsrc_backup_node) |
| 7894 | 7899 | return 0; |
| 7895 | − ctx->rsrc_backup_node = io_rsrc_node_alloc(ctx); | |
| 7900 | + ctx->rsrc_backup_node = io_rsrc_node_alloc(); | |
| 7896 | 7901 | return ctx->rsrc_backup_node ? 0 : -ENOMEM; |
| 7897 | 7902 | } |
| 7898 | 7903 | |
| @@ -2972,6 +2972,7 @@ struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh) · 2971 unmodified lines | ||
| 2972 | 2972 | jbd_unlock_bh_journal_head(bh); |
| 2973 | 2973 | return jh; |
| 2974 | 2974 | } |
| 2975 | +EXPORT_SYMBOL(jbd2_journal_grab_journal_head); | |
| 2975 | 2976 | |
| 2976 | 2977 | static void __journal_remove_journal_head(struct buffer_head *bh) |
| 2977 | 2978 | { |
| @@ -3024,6 +3025,7 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) · 46 unmodified lines | ||
| 3024 | 3025 | jbd_unlock_bh_journal_head(bh); |
| 3025 | 3026 | } |
| 3026 | 3027 | } |
| 3028 | +EXPORT_SYMBOL(jbd2_journal_put_journal_head); | |
| 3027 | 3029 | |
| 3028 | 3030 | /* |
| 3029 | 3031 | * Initialize jbd inode head |
| @@ -4024,13 +4024,12 @@ int vfs_rmdir(struct user_namespace *mnt_userns, struct inode *dir, · 4023 unmodified lines | ||
| 4024 | 4024 | dentry->d_inode->i_flags |= S_DEAD; |
| 4025 | 4025 | dont_mount(dentry); |
| 4026 | 4026 | detach_mounts(dentry); |
| 4027 | − fsnotify_rmdir(dir, dentry); | |
| 4028 | 4027 | |
| 4029 | 4028 | out: |
| 4030 | 4029 | inode_unlock(dentry->d_inode); |
| 4031 | 4030 | dput(dentry); |
| 4032 | 4031 | if (!error) |
| 4033 | − d_delete(dentry); | |
| 4032 | + d_delete_notify(dir, dentry); | |
| 4034 | 4033 | return error; |
| 4035 | 4034 | } |
| 4036 | 4035 | EXPORT_SYMBOL(vfs_rmdir); |
| @@ -4152,7 +4151,6 @@ int vfs_unlink(struct user_namespace *mnt_userns, struct inode *dir, · 115 unmodified lines | ||
| 4152 | 4151 | if (!error) { |
| 4153 | 4152 | dont_mount(dentry); |
| 4154 | 4153 | detach_mounts(dentry); |
| 4155 | − fsnotify_unlink(dir, dentry); | |
| 4156 | 4154 | } |
| 4157 | 4155 | } |
| 4158 | 4156 | } |
| @@ -4160,9 +4158,11 @@ out: · 1 unmodified line | ||
| 4160 | 4158 | inode_unlock(target); |
| 4161 | 4159 | |
| 4162 | 4160 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ |
| 4163 | − if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { | |
| 4161 | + if (!error && dentry->d_flags & DCACHE_NFSFS_RENAMED) { | |
| 4162 | + fsnotify_unlink(dir, dentry); | |
| 4163 | + } else if (!error) { | |
| 4164 | 4164 | fsnotify_link_count(target); |
| 4165 | − d_delete(dentry); | |
| 4165 | + d_delete_notify(dir, dentry); | |
| 4166 | 4166 | } |
| 4167 | 4167 | |
| 4168 | 4168 | return error; |
| @@ -170,7 +170,7 @@ struct cb_devicenotifyitem { · 169 unmodified lines | ||
| 170 | 170 | }; |
| 171 | 171 | |
| 172 | 172 | struct cb_devicenotifyargs { |
| 173 | − int ndevs; | |
| 173 | + uint32_t ndevs; | |
| 174 | 174 | struct cb_devicenotifyitem *devs; |
| 175 | 175 | }; |
| 176 | 176 | |
| @@ -358,7 +358,7 @@ __be32 nfs4_callback_devicenotify(void *argp, void *resp, · 357 unmodified lines | ||
| 358 | 358 | struct cb_process_state *cps) |
| 359 | 359 | { |
| 360 | 360 | struct cb_devicenotifyargs *args = argp; |
| 361 | − int i; | |
| 361 | + uint32_t i; | |
| 362 | 362 | __be32 res = 0; |
| 363 | 363 | struct nfs_client *clp = cps->clp; |
| 364 | 364 | struct nfs_server *server = NULL; |
| @@ -258,11 +258,9 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, · 257 unmodified lines | ||
| 258 | 258 | void *argp) |
| 259 | 259 | { |
| 260 | 260 | struct cb_devicenotifyargs *args = argp; |
| 261 | + uint32_t tmp, n, i; | |
| 261 | 262 | __be32 *p; |
| 262 | 263 | __be32 status = 0; |
| 263 | − u32 tmp; | |
| 264 | − int n, i; | |
| 265 | − args->ndevs = 0; | |
| 266 | 264 | |
| 267 | 265 | /* Num of device notifications */ |
| 268 | 266 | p = xdr_inline_decode(xdr, sizeof(uint32_t)); |
| @@ -271,7 +269,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, · 2 unmodified lines | ||
| 271 | 269 | goto out; |
| 272 | 270 | } |
| 273 | 271 | n = ntohl(*p++); |
| 274 | − if (n <= 0) | |
| 272 | + if (n == 0) | |
| 275 | 273 | goto out; |
| 276 | 274 | if (n > ULONG_MAX / sizeof(*args->devs)) { |
| 277 | 275 | status = htonl(NFS4ERR_BADXDR); |
| @@ -330,19 +328,21 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, · 52 unmodified lines | ||
| 330 | 328 | dev->cbd_immediate = 0; |
| 331 | 329 | } |
| 332 | 330 | |
| 333 | − args->ndevs++; | |
| 334 | − | |
| 335 | 331 | dprintk("%s: type %d layout 0x%x immediate %d\n", |
| 336 | 332 | __func__, dev->cbd_notify_type, dev->cbd_layout_type, |
| 337 | 333 | dev->cbd_immediate); |
| 338 | 334 | } |
| 335 | + args->ndevs = n; | |
| 336 | + dprintk("%s: ndevs %d\n", __func__, args->ndevs); | |
| 337 | + return 0; | |
| 338 | +err: | |
| 339 | + kfree(args->devs); | |
| 339 | 340 | out: |
| 341 | + args->devs = NULL; | |
| 342 | + args->ndevs = 0; | |
| 340 | 343 | dprintk("%s: status %d ndevs %d\n", |
| 341 | 344 | __func__, ntohl(status), args->ndevs); |
| 342 | 345 | return status; |
| 343 | −err: | |
| 344 | − kfree(args->devs); | |
| 345 | − goto out; | |
| 346 | 346 | } |
| 347 | 347 | |
| 348 | 348 | static __be32 decode_sessionid(struct xdr_stream *xdr, |
| @@ -856,6 +856,13 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str · 855 unmodified lines | ||
| 856 | 856 | server->namelen = pathinfo.max_namelen; |
| 857 | 857 | } |
| 858 | 858 | |
| 859 | + if (clp->rpc_ops->discover_trunking != NULL && | |
| 860 | + (server->caps & NFS_CAP_FS_LOCATIONS)) { | |
| 861 | + error = clp->rpc_ops->discover_trunking(server, mntfh); | |
| 862 | + if (error < 0) | |
| 863 | + return error; | |
| 864 | + } | |
| 865 | + | |
| 859 | 866 | return 0; |
| 860 | 867 | } |
| 861 | 868 | |
| @@ -1325,6 +1325,14 @@ void nfs_clear_verifier_delegated(struct inode *inode) · 1324 unmodified lines | ||
| 1325 | 1325 | EXPORT_SYMBOL_GPL(nfs_clear_verifier_delegated); |
| 1326 | 1326 | #endif /* IS_ENABLED(CONFIG_NFS_V4) */ |
| 1327 | 1327 | |
| 1328 | +static int nfs_dentry_verify_change(struct inode *dir, struct dentry *dentry) | |
| 1329 | +{ | |
| 1330 | + if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE) && | |
| 1331 | + d_really_is_negative(dentry)) | |
| 1332 | + return dentry->d_time == inode_peek_iversion_raw(dir); | |
| 1333 | + return nfs_verify_change_attribute(dir, dentry->d_time); | |
| 1334 | +} | |
| 1335 | + | |
| 1328 | 1336 | /* |
| 1329 | 1337 | * A check for whether or not the parent directory has changed. |
| 1330 | 1338 | * In the case it has, we assume that the dentries are untrustworthy |
| @@ -1338,7 +1346,7 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry, · 7 unmodified lines | ||
| 1338 | 1346 | return 1; |
| 1339 | 1347 | if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE) |
| 1340 | 1348 | return 0; |
| 1341 | − if (!nfs_verify_change_attribute(dir, dentry->d_time)) | |
| 1349 | + if (!nfs_dentry_verify_change(dir, dentry)) | |
| 1342 | 1350 | return 0; |
| 1343 | 1351 | /* Revalidate nfsi->cache_change_attribute before we declare a match */ |
| 1344 | 1352 | if (nfs_mapping_need_revalidate_inode(dir)) { |
| @@ -1347,7 +1355,7 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry, · 2 unmodified lines | ||
| 1347 | 1355 | if (__nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0) |
| 1348 | 1356 | return 0; |
| 1349 | 1357 | } |
| 1350 | − if (!nfs_verify_change_attribute(dir, dentry->d_time)) | |
| 1358 | + if (!nfs_dentry_verify_change(dir, dentry)) | |
| 1351 | 1359 | return 0; |
| 1352 | 1360 | return 1; |
| 1353 | 1361 | } |
| @@ -1437,6 +1445,9 @@ int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, · 83 unmodified lines | ||
| 1437 | 1445 | return 0; |
| 1438 | 1446 | if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) |
| 1439 | 1447 | return 1; |
| 1448 | + /* Case insensitive server? Revalidate negative dentries */ | |
| 1449 | + if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE)) | |
| 1450 | + return 1; | |
| 1440 | 1451 | return !nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU); |
| 1441 | 1452 | } |
| 1442 | 1453 | |
| @@ -1537,7 +1548,7 @@ out: · 94 unmodified lines | ||
| 1537 | 1548 | * If the lookup failed despite the dentry change attribute being |
| 1538 | 1549 | * a match, then we should revalidate the directory cache. |
| 1539 | 1550 | */ |
| 1540 | − if (!ret && nfs_verify_change_attribute(dir, dentry->d_time)) | |
| 1551 | + if (!ret && nfs_dentry_verify_change(dir, dentry)) | |
| 1541 | 1552 | nfs_mark_dir_for_revalidate(dir); |
| 1542 | 1553 | return nfs_lookup_revalidate_done(dir, dentry, inode, ret); |
| 1543 | 1554 | } |
| @@ -1776,8 +1787,11 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in · 232 unmodified lines | ||
| 1776 | 1787 | dir_verifier = nfs_save_change_attribute(dir); |
| 1777 | 1788 | trace_nfs_lookup_enter(dir, dentry, flags); |
| 1778 | 1789 | error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr); |
| 1779 | − if (error == -ENOENT) | |
| 1790 | + if (error == -ENOENT) { | |
| 1791 | + if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE)) | |
| 1792 | + dir_verifier = inode_peek_iversion_raw(dir); | |
| 1780 | 1793 | goto no_entry; |
| 1794 | + } | |
| 1781 | 1795 | if (error < 0) { |
| 1782 | 1796 | res = ERR_PTR(error); |
| 1783 | 1797 | goto out; |
| @@ -1806,6 +1820,14 @@ out: · 22 unmodified lines | ||
| 1806 | 1820 | } |
| 1807 | 1821 | EXPORT_SYMBOL_GPL(nfs_lookup); |
| 1808 | 1822 | |
| 1823 | +void nfs_d_prune_case_insensitive_aliases(struct inode *inode) | |
| 1824 | +{ | |
| 1825 | + /* Case insensitive server? Revalidate dentries */ | |
| 1826 | + if (inode && nfs_server_capable(inode, NFS_CAP_CASE_INSENSITIVE)) | |
| 1827 | + d_prune_aliases(inode); | |
| 1828 | +} | |
| 1829 | +EXPORT_SYMBOL_GPL(nfs_d_prune_case_insensitive_aliases); | |
| 1830 | + | |
| 1809 | 1831 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 1810 | 1832 | static int nfs4_lookup_revalidate(struct dentry *, unsigned int); |
| 1811 | 1833 | |
| @@ -1867,6 +1889,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, · 55 unmodified lines | ||
| 1867 | 1889 | struct iattr attr = { .ia_valid = ATTR_OPEN }; |
| 1868 | 1890 | struct inode *inode; |
| 1869 | 1891 | unsigned int lookup_flags = 0; |
| 1892 | + unsigned long dir_verifier; | |
| 1870 | 1893 | bool switched = false; |
| 1871 | 1894 | int created = 0; |
| 1872 | 1895 | int err; |
| @@ -1940,7 +1963,11 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, · 67 unmodified lines | ||
| 1940 | 1963 | switch (err) { |
| 1941 | 1964 | case -ENOENT: |
| 1942 | 1965 | d_splice_alias(NULL, dentry); |
| 1943 | − nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | |
| 1966 | + if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE)) | |
| 1967 | + dir_verifier = inode_peek_iversion_raw(dir); | |
| 1968 | + else | |
| 1969 | + dir_verifier = nfs_save_change_attribute(dir); | |
| 1970 | + nfs_set_verifier(dentry, dir_verifier); | |
| 1944 | 1971 | break; |
| 1945 | 1972 | case -EISDIR: |
| 1946 | 1973 | case -ENOTDIR: |
| @@ -1968,6 +1995,24 @@ out: · 21 unmodified lines | ||
| 1968 | 1995 | |
| 1969 | 1996 | no_open: |
| 1970 | 1997 | res = nfs_lookup(dir, dentry, lookup_flags); |
| 1998 | + if (!res) { | |
| 1999 | + inode = d_inode(dentry); | |
| 2000 | + if ((lookup_flags & LOOKUP_DIRECTORY) && inode && | |
| 2001 | + !S_ISDIR(inode->i_mode)) | |
| 2002 | + res = ERR_PTR(-ENOTDIR); | |
| 2003 | + else if (inode && S_ISREG(inode->i_mode)) | |
| 2004 | + res = ERR_PTR(-EOPENSTALE); | |
| 2005 | + } else if (!IS_ERR(res)) { | |
| 2006 | + inode = d_inode(res); | |
| 2007 | + if ((lookup_flags & LOOKUP_DIRECTORY) && inode && | |
| 2008 | + !S_ISDIR(inode->i_mode)) { | |
| 2009 | + dput(res); | |
| 2010 | + res = ERR_PTR(-ENOTDIR); | |
| 2011 | + } else if (inode && S_ISREG(inode->i_mode)) { | |
| 2012 | + dput(res); | |
| 2013 | + res = ERR_PTR(-EOPENSTALE); | |
| 2014 | + } | |
| 2015 | + } | |
| 1971 | 2016 | if (switched) { |
| 1972 | 2017 | d_lookup_done(dentry); |
| 1973 | 2018 | if (!res) |
| @@ -2186,8 +2231,10 @@ static void nfs_dentry_remove_handle_error(struct inode *dir, · 212 unmodified lines | ||
| 2186 | 2231 | switch (error) { |
| 2187 | 2232 | case -ENOENT: |
| 2188 | 2233 | d_delete(dentry); |
| 2189 | − fallthrough; | |
| 2234 | + nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | |
| 2235 | + break; | |
| 2190 | 2236 | case 0: |
| 2237 | + nfs_d_prune_case_insensitive_aliases(d_inode(dentry)); | |
| 2191 | 2238 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
| 2192 | 2239 | } |
| 2193 | 2240 | } |
| @@ -2380,6 +2427,8 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) · 186 unmodified lines | ||
| 2380 | 2427 | |
| 2381 | 2428 | trace_nfs_link_enter(inode, dir, dentry); |
| 2382 | 2429 | d_drop(dentry); |
| 2430 | + if (S_ISREG(inode->i_mode)) | |
| 2431 | + nfs_sync_inode(inode); | |
| 2383 | 2432 | error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); |
| 2384 | 2433 | if (error == 0) { |
| 2385 | 2434 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
| @@ -2469,6 +2518,8 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, · 83 unmodified lines | ||
| 2469 | 2518 | } |
| 2470 | 2519 | } |
| 2471 | 2520 | |
| 2521 | + if (S_ISREG(old_inode->i_mode)) | |
| 2522 | + nfs_sync_inode(old_inode); | |
| 2472 | 2523 | task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL); |
| 2473 | 2524 | if (IS_ERR(task)) { |
| 2474 | 2525 | error = PTR_ERR(task); |
| @@ -2529,7 +2580,7 @@ MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache lengt · 54 unmodified lines | ||
| 2529 | 2580 | |
| 2530 | 2581 | static void nfs_access_free_entry(struct nfs_access_entry *entry) |
| 2531 | 2582 | { |
| 2532 | − put_cred(entry->cred); | |
| 2583 | + put_group_info(entry->group_info); | |
| 2533 | 2584 | kfree_rcu(entry, rcu_head); |
| 2534 | 2585 | smp_mb__before_atomic(); |
| 2535 | 2586 | atomic_long_dec(&nfs_access_nr_entries); |
| @@ -2655,6 +2706,43 @@ void nfs_access_zap_cache(struct inode *inode) · 119 unmodified lines | ||
| 2655 | 2706 | } |
| 2656 | 2707 | EXPORT_SYMBOL_GPL(nfs_access_zap_cache); |
| 2657 | 2708 | |
| 2709 | +static int access_cmp(const struct cred *a, const struct nfs_access_entry *b) | |
| 2710 | +{ | |
| 2711 | + struct group_info *ga, *gb; | |
| 2712 | + int g; | |
| 2713 | + | |
| 2714 | + if (uid_lt(a->fsuid, b->fsuid)) | |
| 2715 | + return -1; | |
| 2716 | + if (uid_gt(a->fsuid, b->fsuid)) | |
| 2717 | + return 1; | |
| 2718 | + | |
| 2719 | + if (gid_lt(a->fsgid, b->fsgid)) | |
| 2720 | + return -1; | |
| 2721 | + if (gid_gt(a->fsgid, b->fsgid)) | |
| 2722 | + return 1; | |
| 2723 | + | |
| 2724 | + ga = a->group_info; | |
| 2725 | + gb = b->group_info; | |
| 2726 | + if (ga == gb) | |
| 2727 | + return 0; | |
| 2728 | + if (ga == NULL) | |
| 2729 | + return -1; | |
| 2730 | + if (gb == NULL) | |
| 2731 | + return 1; | |
| 2732 | + if (ga->ngroups < gb->ngroups) | |
| 2733 | + return -1; | |
| 2734 | + if (ga->ngroups > gb->ngroups) | |
| 2735 | + return 1; | |
| 2736 | + | |
| 2737 | + for (g = 0; g < ga->ngroups; g++) { | |
| 2738 | + if (gid_lt(ga->gid[g], gb->gid[g])) | |
| 2739 | + return -1; | |
| 2740 | + if (gid_gt(ga->gid[g], gb->gid[g])) | |
| 2741 | + return 1; | |
| 2742 | + } | |
| 2743 | + return 0; | |
| 2744 | +} | |
| 2745 | + | |
| 2658 | 2746 | static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, const struct cred *cred) |
| 2659 | 2747 | { |
| 2660 | 2748 | struct rb_node *n = NFS_I(inode)->access_cache.rb_node; |
| @@ -2662,7 +2750,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, co · 1 unmodified line | ||
| 2662 | 2750 | while (n != NULL) { |
| 2663 | 2751 | struct nfs_access_entry *entry = |
| 2664 | 2752 | rb_entry(n, struct nfs_access_entry, rb_node); |
| 2665 | − int cmp = cred_fscmp(cred, entry->cred); | |
| 2753 | + int cmp = access_cmp(cred, entry); | |
| 2666 | 2754 | |
| 2667 | 2755 | if (cmp < 0) |
| 2668 | 2756 | n = n->rb_left; |
| @@ -2674,7 +2762,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, co · 5 unmodified lines | ||
| 2674 | 2762 | return NULL; |
| 2675 | 2763 | } |
| 2676 | 2764 | |
| 2677 | −static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block) | |
| 2765 | +static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, u32 *mask, bool may_block) | |
| 2678 | 2766 | { |
| 2679 | 2767 | struct nfs_inode *nfsi = NFS_I(inode); |
| 2680 | 2768 | struct nfs_access_entry *cache; |
| @@ -2704,8 +2792,7 @@ static int nfs_access_get_cached_locked(struct inode *inode, const struct cred * · 23 unmodified lines | ||
| 2704 | 2792 | spin_lock(&inode->i_lock); |
| 2705 | 2793 | retry = false; |
| 2706 | 2794 | } |
| 2707 | − res->cred = cache->cred; | |
| 2708 | − res->mask = cache->mask; | |
| 2795 | + *mask = cache->mask; | |
| 2709 | 2796 | list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru); |
| 2710 | 2797 | err = 0; |
| 2711 | 2798 | out: |
| @@ -2717,7 +2804,7 @@ out_zap: · 5 unmodified lines | ||
| 2717 | 2804 | return -ENOENT; |
| 2718 | 2805 | } |
| 2719 | 2806 | |
| 2720 | −static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res) | |
| 2807 | +static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, u32 *mask) | |
| 2721 | 2808 | { |
| 2722 | 2809 | /* Only check the most recently returned cache entry, |
| 2723 | 2810 | * but do it without locking. |
| @@ -2733,35 +2820,36 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre · 9 unmodified lines | ||
| 2733 | 2820 | lh = rcu_dereference(list_tail_rcu(&nfsi->access_cache_entry_lru)); |
| 2734 | 2821 | cache = list_entry(lh, struct nfs_access_entry, lru); |
| 2735 | 2822 | if (lh == &nfsi->access_cache_entry_lru || |
| 2736 | − cred_fscmp(cred, cache->cred) != 0) | |
| 2823 | + access_cmp(cred, cache) != 0) | |
| 2737 | 2824 | cache = NULL; |
| 2738 | 2825 | if (cache == NULL) |
| 2739 | 2826 | goto out; |
| 2740 | 2827 | if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS)) |
| 2741 | 2828 | goto out; |
| 2742 | − res->cred = cache->cred; | |
| 2743 | − res->mask = cache->mask; | |
| 2829 | + *mask = cache->mask; | |
| 2744 | 2830 | err = 0; |
| 2745 | 2831 | out: |
| 2746 | 2832 | rcu_read_unlock(); |
| 2747 | 2833 | return err; |
| 2748 | 2834 | } |
| 2749 | 2835 | |
| 2750 | −int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct | |
| 2751 | −nfs_access_entry *res, bool may_block) | |
| 2836 | +int nfs_access_get_cached(struct inode *inode, const struct cred *cred, | |
| 2837 | + u32 *mask, bool may_block) | |
| 2752 | 2838 | { |
| 2753 | 2839 | int status; |
| 2754 | 2840 | |
| 2755 | − status = nfs_access_get_cached_rcu(inode, cred, res); | |
| 2841 | + status = nfs_access_get_cached_rcu(inode, cred, mask); | |
| 2756 | 2842 | if (status != 0) |
| 2757 | − status = nfs_access_get_cached_locked(inode, cred, res, | |
| 2843 | + status = nfs_access_get_cached_locked(inode, cred, mask, | |
| 2758 | 2844 | may_block); |
| 2759 | 2845 | |
| 2760 | 2846 | return status; |
| 2761 | 2847 | } |
| 2762 | 2848 | EXPORT_SYMBOL_GPL(nfs_access_get_cached); |
| 2763 | 2849 | |
| 2764 | −static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set) | |
| 2850 | +static void nfs_access_add_rbtree(struct inode *inode, | |
| 2851 | + struct nfs_access_entry *set, | |
| 2852 | + const struct cred *cred) | |
| 2765 | 2853 | { |
| 2766 | 2854 | struct nfs_inode *nfsi = NFS_I(inode); |
| 2767 | 2855 | struct rb_root *root_node = &nfsi->access_cache; |
| @@ -2774,7 +2862,7 @@ static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry * · 6 unmodified lines | ||
| 2774 | 2862 | while (*p != NULL) { |
| 2775 | 2863 | parent = *p; |
| 2776 | 2864 | entry = rb_entry(parent, struct nfs_access_entry, rb_node); |
| 2777 | − cmp = cred_fscmp(set->cred, entry->cred); | |
| 2865 | + cmp = access_cmp(cred, entry); | |
| 2778 | 2866 | |
| 2779 | 2867 | if (cmp < 0) |
| 2780 | 2868 | p = &parent->rb_left; |
| @@ -2796,13 +2884,16 @@ found: · 15 unmodified lines | ||
| 2796 | 2884 | nfs_access_free_entry(entry); |
| 2797 | 2885 | } |
| 2798 | 2886 | |
| 2799 | −void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) | |
| 2887 | +void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set, | |
| 2888 | + const struct cred *cred) | |
| 2800 | 2889 | { |
| 2801 | 2890 | struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL); |
| 2802 | 2891 | if (cache == NULL) |
| 2803 | 2892 | return; |
| 2804 | 2893 | RB_CLEAR_NODE(&cache->rb_node); |
| 2805 | − cache->cred = get_cred(set->cred); | |
| 2894 | + cache->fsuid = cred->fsuid; | |
| 2895 | + cache->fsgid = cred->fsgid; | |
| 2896 | + cache->group_info = get_group_info(cred->group_info); | |
| 2806 | 2897 | cache->mask = set->mask; |
| 2807 | 2898 | |
| 2808 | 2899 | /* The above field assignments must be visible |
| @@ -2810,7 +2901,7 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) · 1 unmodified line | ||
| 2810 | 2901 | * use rcu_assign_pointer, so just force the memory barrier. |
| 2811 | 2902 | */ |
| 2812 | 2903 | smp_wmb(); |
| 2813 | − nfs_access_add_rbtree(inode, cache); | |
| 2904 | + nfs_access_add_rbtree(inode, cache, cred); | |
| 2814 | 2905 | |
| 2815 | 2906 | /* Update accounting */ |
| 2816 | 2907 | smp_mb__before_atomic(); |
| @@ -2875,7 +2966,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask) · 58 unmodified lines | ||
| 2875 | 2966 | |
| 2876 | 2967 | trace_nfs_access_enter(inode); |
| 2877 | 2968 | |
| 2878 | − status = nfs_access_get_cached(inode, cred, &cache, may_block); | |
| 2969 | + status = nfs_access_get_cached(inode, cred, &cache.mask, may_block); | |
| 2879 | 2970 | if (status == 0) |
| 2880 | 2971 | goto out_cached; |
| 2881 | 2972 | |
| @@ -2895,8 +2986,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask) · 13 unmodified lines | ||
| 2895 | 2986 | cache.mask |= NFS_ACCESS_DELETE | NFS_ACCESS_LOOKUP; |
| 2896 | 2987 | else |
| 2897 | 2988 | cache.mask |= NFS_ACCESS_EXECUTE; |
| 2898 | − cache.cred = cred; | |
| 2899 | − status = NFS_PROTO(inode)->access(inode, &cache); | |
| 2989 | + status = NFS_PROTO(inode)->access(inode, &cache, cred); | |
| 2900 | 2990 | if (status != 0) { |
| 2901 | 2991 | if (status == -ESTALE) { |
| 2902 | 2992 | if (!S_ISDIR(inode->i_mode)) |
| @@ -2906,7 +2996,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask) · 3 unmodified lines | ||
| 2906 | 2996 | } |
| 2907 | 2997 | goto out; |
| 2908 | 2998 | } |
| 2909 | − nfs_access_add_cache(inode, &cache); | |
| 2999 | + nfs_access_add_cache(inode, &cache, cred); | |
| 2910 | 3000 | out_cached: |
| 2911 | 3001 | cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode); |
| 2912 | 3002 | if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0) |
| @@ -51,7 +51,7 @@ struct nfs4_file_layout_dsaddr { · 50 unmodified lines | ||
| 51 | 51 | u32 stripe_count; |
| 52 | 52 | u8 *stripe_indices; |
| 53 | 53 | u32 ds_num; |
| 54 | − struct nfs4_pnfs_ds *ds_list[1]; | |
| 54 | + struct nfs4_pnfs_ds *ds_list[]; | |
| 55 | 55 | }; |
| 56 | 56 | |
| 57 | 57 | struct nfs4_filelayout_segment { |
| @@ -136,9 +136,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, · 135 unmodified lines | ||
| 136 | 136 | goto out_err_free_stripe_indices; |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | − dsaddr = kzalloc(sizeof(*dsaddr) + | |
| 140 | − (sizeof(struct nfs4_pnfs_ds *) * (num - 1)), | |
| 141 | − gfp_flags); | |
| 139 | + dsaddr = kzalloc(struct_size(dsaddr, ds_list, num), gfp_flags); | |
| 142 | 140 | if (!dsaddr) |
| 143 | 141 | goto out_err_free_stripe_indices; |
| 144 | 142 | |
| @@ -373,6 +373,7 @@ extern unsigned long nfs_access_cache_count(struct shrinker *shrink, · 372 unmodified lines | ||
| 373 | 373 | extern unsigned long nfs_access_cache_scan(struct shrinker *shrink, |
| 374 | 374 | struct shrink_control *sc); |
| 375 | 375 | struct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int); |
| 376 | +void nfs_d_prune_case_insensitive_aliases(struct inode *inode); | |
| 376 | 377 | int nfs_create(struct user_namespace *, struct inode *, struct dentry *, |
| 377 | 378 | umode_t, bool); |
| 378 | 379 | int nfs_mkdir(struct user_namespace *, struct inode *, struct dentry *, |
| @@ -220,7 +220,8 @@ static int nfs3_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle, · 219 unmodified lines | ||
| 220 | 220 | task_flags); |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | −static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) | |
| 223 | +static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry, | |
| 224 | + const struct cred *cred) | |
| 224 | 225 | { |
| 225 | 226 | struct nfs3_accessargs arg = { |
| 226 | 227 | .fh = NFS_FH(inode), |
| @@ -231,7 +232,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) · 4 unmodified lines | ||
| 231 | 232 | .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS], |
| 232 | 233 | .rpc_argp = &arg, |
| 233 | 234 | .rpc_resp = &res, |
| 234 | − .rpc_cred = entry->cred, | |
| 235 | + .rpc_cred = cred, | |
| 235 | 236 | }; |
| 236 | 237 | int status = -ENOMEM; |
| 237 | 238 | |
| @@ -46,7 +46,7 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, · 45 unmodified lines | ||
| 46 | 46 | { |
| 47 | 47 | struct inode *inode = file_inode(filep); |
| 48 | 48 | struct nfs_server *server = NFS_SERVER(inode); |
| 49 | − u32 bitmask[3]; | |
| 49 | + u32 bitmask[NFS_BITMASK_SZ]; | |
| 50 | 50 | struct nfs42_falloc_args args = { |
| 51 | 51 | .falloc_fh = NFS_FH(inode), |
| 52 | 52 | .falloc_offset = offset, |
| @@ -69,9 +69,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, · 16 unmodified lines | ||
| 69 | 69 | return status; |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | − memcpy(bitmask, server->cache_consistency_bitmask, sizeof(bitmask)); | |
| 73 | − if (server->attr_bitmask[1] & FATTR4_WORD1_SPACE_USED) | |
| 74 | − bitmask[1] |= FATTR4_WORD1_SPACE_USED; | |
| 72 | + nfs4_bitmask_set(bitmask, server->cache_consistency_bitmask, inode, | |
| 73 | + NFS_INO_INVALID_BLOCKS); | |
| 75 | 74 | |
| 76 | 75 | res.falloc_fattr = nfs_alloc_fattr(); |
| 77 | 76 | if (!res.falloc_fattr) |
| @@ -1044,13 +1043,14 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, · 966 unmodified lines | ||
| 1044 | 1043 | struct inode *src_inode = file_inode(src_f); |
| 1045 | 1044 | struct inode *dst_inode = file_inode(dst_f); |
| 1046 | 1045 | struct nfs_server *server = NFS_SERVER(dst_inode); |
| 1046 | + __u32 dst_bitmask[NFS_BITMASK_SZ]; | |
| 1047 | 1047 | struct nfs42_clone_args args = { |
| 1048 | 1048 | .src_fh = NFS_FH(src_inode), |
| 1049 | 1049 | .dst_fh = NFS_FH(dst_inode), |
| 1050 | 1050 | .src_offset = src_offset, |
| 1051 | 1051 | .dst_offset = dst_offset, |
| 1052 | 1052 | .count = count, |
| 1053 | − .dst_bitmask = server->cache_consistency_bitmask, | |
| 1053 | + .dst_bitmask = dst_bitmask, | |
| 1054 | 1054 | }; |
| 1055 | 1055 | struct nfs42_clone_res res = { |
| 1056 | 1056 | .server = server, |
| @@ -1079,6 +1079,9 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, · 22 unmodified lines | ||
| 1079 | 1079 | if (!res.dst_fattr) |
| 1080 | 1080 | return -ENOMEM; |
| 1081 | 1081 | |
| 1082 | + nfs4_bitmask_set(dst_bitmask, server->cache_consistency_bitmask, | |
| 1083 | + dst_inode, NFS_INO_INVALID_BLOCKS); | |
| 1084 | + | |
| 1082 | 1085 | status = nfs4_call_sync(server->client, server, msg, |
| 1083 | 1086 | &args.seq_args, &res.seq_res, 0); |
| 1084 | 1087 | trace_nfs4_clone(src_inode, dst_inode, &args, status); |
| @@ -260,8 +260,8 @@ struct nfs4_state_maintenance_ops { · 259 unmodified lines | ||
| 260 | 260 | }; |
| 261 | 261 | |
| 262 | 262 | struct nfs4_mig_recovery_ops { |
| 263 | − int (*get_locations)(struct inode *, struct nfs4_fs_locations *, | |
| 264 | − struct page *, const struct cred *); | |
| 263 | + int (*get_locations)(struct nfs_server *, struct nfs_fh *, | |
| 264 | + struct nfs4_fs_locations *, struct page *, const struct cred *); | |
| 265 | 265 | int (*fsid_present)(struct inode *, const struct cred *); |
| 266 | 266 | }; |
| 267 | 267 | |
| @@ -280,7 +280,8 @@ struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *, · 12 unmodified lines | ||
| 280 | 280 | int nfs4_submount(struct fs_context *, struct nfs_server *); |
| 281 | 281 | int nfs4_replace_transport(struct nfs_server *server, |
| 282 | 282 | const struct nfs4_fs_locations *locations); |
| 283 | − | |
| 283 | +size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa, | |
| 284 | + size_t salen, struct net *net, int port); | |
| 284 | 285 | /* nfs4proc.c */ |
| 285 | 286 | extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *); |
| 286 | 287 | extern int nfs4_async_handle_error(struct rpc_task *task, |
| @@ -302,8 +303,9 @@ extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait); · 15 unmodified lines | ||
| 302 | 303 | extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); |
| 303 | 304 | extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *, |
| 304 | 305 | struct nfs4_fs_locations *, struct page *); |
| 305 | −extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *, | |
| 306 | − struct page *page, const struct cred *); | |
| 306 | +extern int nfs4_proc_get_locations(struct nfs_server *, struct nfs_fh *, | |
| 307 | + struct nfs4_fs_locations *, | |
| 308 | + struct page *page, const struct cred *); | |
| 307 | 309 | extern int nfs4_proc_fsid_present(struct inode *, const struct cred *); |
| 308 | 310 | extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, |
| 309 | 311 | struct dentry *, |
| @@ -315,6 +317,8 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid, · 5 unmodified lines | ||
| 315 | 317 | const struct nfs_open_context *ctx, |
| 316 | 318 | const struct nfs_lock_context *l_ctx, |
| 317 | 319 | fmode_t fmode); |
| 320 | +extern void nfs4_bitmask_set(__u32 bitmask[], const __u32 src[], | |
| 321 | + struct inode *inode, unsigned long cache_validity); | |
| 318 | 322 | extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, |
| 319 | 323 | struct nfs_fattr *fattr, struct inode *inode); |
| 320 | 324 | extern int update_open_stateid(struct nfs4_state *state, |
| @@ -1343,8 +1343,11 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname, · 1342 unmodified lines | ||
| 1343 | 1343 | } |
| 1344 | 1344 | nfs_put_client(clp); |
| 1345 | 1345 | |
| 1346 | − if (server->nfs_client->cl_hostname == NULL) | |
| 1346 | + if (server->nfs_client->cl_hostname == NULL) { | |
| 1347 | 1347 | server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL); |
| 1348 | + if (server->nfs_client->cl_hostname == NULL) | |
| 1349 | + return -ENOMEM; | |
| 1350 | + } | |
| 1348 | 1351 | nfs_server_insert_lists(server); |
| 1349 | 1352 | |
| 1350 | 1353 | return nfs_probe_server(server, NFS_FH(d_inode(server->super->s_root))); |
| @@ -164,16 +164,21 @@ static int nfs4_validate_fspath(struct dentry *dentry, · 163 unmodified lines | ||
| 164 | 164 | return 0; |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | −static size_t nfs_parse_server_name(char *string, size_t len, | |
| 168 | − struct sockaddr *sa, size_t salen, struct net *net) | |
| 167 | +size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa, | |
| 168 | + size_t salen, struct net *net, int port) | |
| 169 | 169 | { |
| 170 | 170 | ssize_t ret; |
| 171 | 171 | |
| 172 | 172 | ret = rpc_pton(net, string, len, sa, salen); |
| 173 | 173 | if (ret == 0) { |
| 174 | − ret = nfs_dns_resolve_name(net, string, len, sa, salen); | |
| 175 | − if (ret < 0) | |
| 176 | − ret = 0; | |
| 174 | + ret = rpc_uaddr2sockaddr(net, string, len, sa, salen); | |
| 175 | + if (ret == 0) { | |
| 176 | + ret = nfs_dns_resolve_name(net, string, len, sa, salen); | |
| 177 | + if (ret < 0) | |
| 178 | + ret = 0; | |
| 179 | + } | |
| 180 | + } else if (port) { | |
| 181 | + rpc_set_port(sa, port); | |
| 177 | 182 | } |
| 178 | 183 | return ret; |
| 179 | 184 | } |
| @@ -328,7 +333,7 @@ static int try_location(struct fs_context *fc, · 148 unmodified lines | ||
| 328 | 333 | nfs_parse_server_name(buf->data, buf->len, |
| 329 | 334 | &ctx->nfs_server.address, |
| 330 | 335 | sizeof(ctx->nfs_server._address), |
| 331 | − fc->net_ns); | |
| 336 | + fc->net_ns, 0); | |
| 332 | 337 | if (ctx->nfs_server.addrlen == 0) |
| 333 | 338 | continue; |
| 334 | 339 | |
| @@ -496,7 +501,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server, · 161 unmodified lines | ||
| 496 | 501 | continue; |
| 497 | 502 | |
| 498 | 503 | salen = nfs_parse_server_name(buf->data, buf->len, |
| 499 | − sap, addr_bufsize, net); | |
| 504 | + sap, addr_bufsize, net, 0); | |
| 500 | 505 | if (salen == 0) |
| 501 | 506 | continue; |
| 502 | 507 | rpc_set_port(sap, NFS_PORT); |
| @@ -108,10 +108,6 @@ static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *, · 107 unmodified lines | ||
| 108 | 108 | static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *, |
| 109 | 109 | const struct cred *, bool); |
| 110 | 110 | #endif |
| 111 | −static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], | |
| 112 | − const __u32 *src, struct inode *inode, | |
| 113 | − struct nfs_server *server, | |
| 114 | − struct nfs4_label *label); | |
| 115 | 111 | |
| 116 | 112 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL |
| 117 | 113 | static inline struct nfs4_label * |
| @@ -2653,9 +2649,8 @@ static int nfs4_opendata_access(const struct cred *cred, · 2535 unmodified lines | ||
| 2653 | 2649 | } else if ((fmode & FMODE_READ) && !opendata->file_created) |
| 2654 | 2650 | mask = NFS4_ACCESS_READ; |
| 2655 | 2651 | |
| 2656 | − cache.cred = cred; | |
| 2657 | 2652 | nfs_access_set_mask(&cache, opendata->o_res.access_result); |
| 2658 | − nfs_access_add_cache(state->inode, &cache); | |
| 2653 | + nfs_access_add_cache(state->inode, &cache, cred); | |
| 2659 | 2654 | |
| 2660 | 2655 | flags = NFS4_ACCESS_READ | NFS4_ACCESS_EXECUTE | NFS4_ACCESS_LOOKUP; |
| 2661 | 2656 | if ((mask & ~cache.mask & flags) == 0) |
| @@ -3670,7 +3665,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) · 1008 unmodified lines | ||
| 3670 | 3665 | if (!nfs4_have_delegation(inode, FMODE_READ)) { |
| 3671 | 3666 | nfs4_bitmask_set(calldata->arg.bitmask_store, |
| 3672 | 3667 | server->cache_consistency_bitmask, |
| 3673 | − inode, server, NULL); | |
| 3668 | + inode, 0); | |
| 3674 | 3669 | calldata->arg.bitmask = calldata->arg.bitmask_store; |
| 3675 | 3670 | } else |
| 3676 | 3671 | calldata->arg.bitmask = NULL; |
| @@ -3841,7 +3836,9 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f · 164 unmodified lines | ||
| 3841 | 3836 | FATTR4_WORD0_FH_EXPIRE_TYPE | |
| 3842 | 3837 | FATTR4_WORD0_LINK_SUPPORT | |
| 3843 | 3838 | FATTR4_WORD0_SYMLINK_SUPPORT | |
| 3844 | − FATTR4_WORD0_ACLSUPPORT; | |
| 3839 | + FATTR4_WORD0_ACLSUPPORT | | |
| 3840 | + FATTR4_WORD0_CASE_INSENSITIVE | | |
| 3841 | + FATTR4_WORD0_CASE_PRESERVING; | |
| 3845 | 3842 | if (minorversion) |
| 3846 | 3843 | bitmask[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT; |
| 3847 | 3844 | |
| @@ -3870,10 +3867,16 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f · 22 unmodified lines | ||
| 3870 | 3867 | server->caps |= NFS_CAP_HARDLINKS; |
| 3871 | 3868 | if (res.has_symlinks != 0) |
| 3872 | 3869 | server->caps |= NFS_CAP_SYMLINKS; |
| 3870 | + if (res.case_insensitive) | |
| 3871 | + server->caps |= NFS_CAP_CASE_INSENSITIVE; | |
| 3872 | + if (res.case_preserving) | |
| 3873 | + server->caps |= NFS_CAP_CASE_PRESERVING; | |
| 3873 | 3874 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL |
| 3874 | 3875 | if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL) |
| 3875 | 3876 | server->caps |= NFS_CAP_SECURITY_LABEL; |
| 3876 | 3877 | #endif |
| 3878 | + if (res.attr_bitmask[0] & FATTR4_WORD0_FS_LOCATIONS) | |
| 3879 | + server->caps |= NFS_CAP_FS_LOCATIONS; | |
| 3877 | 3880 | if (!(res.attr_bitmask[0] & FATTR4_WORD0_FILEID)) |
| 3878 | 3881 | server->fattr_valid &= ~NFS_ATTR_FATTR_FILEID; |
| 3879 | 3882 | if (!(res.attr_bitmask[1] & FATTR4_WORD1_MODE)) |
| @@ -3932,6 +3935,114 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) · 52 unmodified lines | ||
| 3932 | 3935 | return err; |
| 3933 | 3936 | } |
| 3934 | 3937 | |
| 3938 | +static void test_fs_location_for_trunking(struct nfs4_fs_location *location, | |
| 3939 | + struct nfs_client *clp, | |
| 3940 | + struct nfs_server *server) | |
| 3941 | +{ | |
| 3942 | + int i; | |
| 3943 | + | |
| 3944 | + for (i = 0; i < location->nservers; i++) { | |
| 3945 | + struct nfs4_string *srv_loc = &location->servers[i]; | |
| 3946 | + struct sockaddr addr; | |
| 3947 | + size_t addrlen; | |
| 3948 | + struct xprt_create xprt_args = { | |
| 3949 | + .ident = 0, | |
| 3950 | + .net = clp->cl_net, | |
| 3951 | + }; | |
| 3952 | + struct nfs4_add_xprt_data xprtdata = { | |
| 3953 | + .clp = clp, | |
| 3954 | + }; | |
| 3955 | + struct rpc_add_xprt_test rpcdata = { | |
| 3956 | + .add_xprt_test = clp->cl_mvops->session_trunk, | |
| 3957 | + .data = &xprtdata, | |
| 3958 | + }; | |
| 3959 | + char *servername = NULL; | |
| 3960 | + | |
| 3961 | + if (!srv_loc->len) | |
| 3962 | + continue; | |
| 3963 | + | |
| 3964 | + addrlen = nfs_parse_server_name(srv_loc->data, srv_loc->len, | |
| 3965 | + &addr, sizeof(addr), | |
| 3966 | + clp->cl_net, server->port); | |
| 3967 | + if (!addrlen) | |
| 3968 | + return; | |
| 3969 | + xprt_args.dstaddr = &addr; | |
| 3970 | + xprt_args.addrlen = addrlen; | |
| 3971 | + servername = kmalloc(srv_loc->len + 1, GFP_KERNEL); | |
| 3972 | + if (!servername) | |
| 3973 | + return; | |
| 3974 | + memcpy(servername, srv_loc->data, srv_loc->len); | |
| 3975 | + servername[srv_loc->len] = '\0'; | |
| 3976 | + xprt_args.servername = servername; | |
| 3977 | + | |
| 3978 | + xprtdata.cred = nfs4_get_clid_cred(clp); | |
| 3979 | + rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, | |
| 3980 | + rpc_clnt_setup_test_and_add_xprt, | |
| 3981 | + &rpcdata); | |
| 3982 | + if (xprtdata.cred) | |
| 3983 | + put_cred(xprtdata.cred); | |
| 3984 | + kfree(servername); | |
| 3985 | + } | |
| 3986 | +} | |
| 3987 | + | |
| 3988 | +static int _nfs4_discover_trunking(struct nfs_server *server, | |
| 3989 | + struct nfs_fh *fhandle) | |
| 3990 | +{ | |
| 3991 | + struct nfs4_fs_locations *locations = NULL; | |
| 3992 | + struct page *page; | |
| 3993 | + const struct cred *cred; | |
| 3994 | + struct nfs_client *clp = server->nfs_client; | |
| 3995 | + const struct nfs4_state_maintenance_ops *ops = | |
| 3996 | + clp->cl_mvops->state_renewal_ops; | |
| 3997 | + int status = -ENOMEM, i; | |
| 3998 | + | |
| 3999 | + cred = ops->get_state_renewal_cred(clp); | |
| 4000 | + if (cred == NULL) { | |
| 4001 | + cred = nfs4_get_clid_cred(clp); | |
| 4002 | + if (cred == NULL) | |
| 4003 | + return -ENOKEY; | |
| 4004 | + } | |
| 4005 | + | |
| 4006 | + page = alloc_page(GFP_KERNEL); | |
| 4007 | + locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); | |
| 4008 | + if (page == NULL || locations == NULL) | |
| 4009 | + goto out; | |
| 4010 | + | |
| 4011 | + status = nfs4_proc_get_locations(server, fhandle, locations, page, | |
| 4012 | + cred); | |
| 4013 | + if (status) | |
| 4014 | + goto out; | |
| 4015 | + | |
| 4016 | + for (i = 0; i < locations->nlocations; i++) | |
| 4017 | + test_fs_location_for_trunking(&locations->locations[i], clp, | |
| 4018 | + server); | |
| 4019 | +out: | |
| 4020 | + if (page) | |
| 4021 | + __free_page(page); | |
| 4022 | + kfree(locations); | |
| 4023 | + return status; | |
| 4024 | +} | |
| 4025 | + | |
| 4026 | +static int nfs4_discover_trunking(struct nfs_server *server, | |
| 4027 | + struct nfs_fh *fhandle) | |
| 4028 | +{ | |
| 4029 | + struct nfs4_exception exception = { | |
| 4030 | + .interruptible = true, | |
| 4031 | + }; | |
| 4032 | + struct nfs_client *clp = server->nfs_client; | |
| 4033 | + int err = 0; | |
| 4034 | + | |
| 4035 | + if (!nfs4_has_session(clp)) | |
| 4036 | + goto out; | |
| 4037 | + do { | |
| 4038 | + err = nfs4_handle_exception(server, | |
| 4039 | + _nfs4_discover_trunking(server, fhandle), | |
| 4040 | + &exception); | |
| 4041 | + } while (exception.retry); | |
| 4042 | +out: | |
| 4043 | + return err; | |
| 4044 | +} | |
| 4045 | + | |
| 3935 | 4046 | static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, |
| 3936 | 4047 | struct nfs_fsinfo *info) |
| 3937 | 4048 | { |
| @@ -4441,7 +4552,8 @@ static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle, · 503 unmodified lines | ||
| 4441 | 4552 | return err; |
| 4442 | 4553 | } |
| 4443 | 4554 | |
| 4444 | −static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) | |
| 4555 | +static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry, | |
| 4556 | + const struct cred *cred) | |
| 4445 | 4557 | { |
| 4446 | 4558 | struct nfs_server *server = NFS_SERVER(inode); |
| 4447 | 4559 | struct nfs4_accessargs args = { |
| @@ -4455,7 +4567,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry · 7 unmodified lines | ||
| 4455 | 4567 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS], |
| 4456 | 4568 | .rpc_argp = &args, |
| 4457 | 4569 | .rpc_resp = &res, |
| 4458 | − .rpc_cred = entry->cred, | |
| 4570 | + .rpc_cred = cred, | |
| 4459 | 4571 | }; |
| 4460 | 4572 | int status = 0; |
| 4461 | 4573 | |
| @@ -4475,14 +4587,15 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry · 13 unmodified lines | ||
| 4475 | 4587 | return status; |
| 4476 | 4588 | } |
| 4477 | 4589 | |
| 4478 | −static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) | |
| 4590 | +static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry, | |
| 4591 | + const struct cred *cred) | |
| 4479 | 4592 | { |
| 4480 | 4593 | struct nfs4_exception exception = { |
| 4481 | 4594 | .interruptible = true, |
| 4482 | 4595 | }; |
| 4483 | 4596 | int err; |
| 4484 | 4597 | do { |
| 4485 | − err = _nfs4_proc_access(inode, entry); | |
| 4598 | + err = _nfs4_proc_access(inode, entry, cred); | |
| 4486 | 4599 | trace_nfs4_access(inode, err); |
| 4487 | 4600 | err = nfs4_handle_exception(NFS_SERVER(inode), err, |
| 4488 | 4601 | &exception); |
| @@ -4663,8 +4776,10 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, · 174 unmodified lines | ||
| 4663 | 4776 | |
| 4664 | 4777 | nfs_fattr_init(res->dir_attr); |
| 4665 | 4778 | |
| 4666 | − if (inode) | |
| 4779 | + if (inode) { | |
| 4667 | 4780 | nfs4_inode_return_delegation(inode); |
| 4781 | + nfs_d_prune_case_insensitive_aliases(inode); | |
| 4782 | + } | |
| 4668 | 4783 | } |
| 4669 | 4784 | |
| 4670 | 4785 | static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data) |
| @@ -4730,6 +4845,7 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, · 59 unmodified lines | ||
| 4730 | 4845 | return 0; |
| 4731 | 4846 | |
| 4732 | 4847 | if (task->tk_status == 0) { |
| 4848 | + nfs_d_prune_case_insensitive_aliases(d_inode(data->old_dentry)); | |
| 4733 | 4849 | if (new_dir != old_dir) { |
| 4734 | 4850 | /* Note: If we moved a directory, nlink will change */ |
| 4735 | 4851 | nfs4_update_changeattr(old_dir, &res->old_cinfo, |
| @@ -5422,14 +5538,14 @@ bool nfs4_write_need_cache_consistency_data(struct nfs_pgio_header *hdr) · 686 unmodified lines | ||
| 5422 | 5538 | return nfs4_have_delegation(hdr->inode, FMODE_READ) == 0; |
| 5423 | 5539 | } |
| 5424 | 5540 | |
| 5425 | −static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src, | |
| 5426 | − struct inode *inode, struct nfs_server *server, | |
| 5427 | − struct nfs4_label *label) | |
| 5541 | +void nfs4_bitmask_set(__u32 bitmask[], const __u32 src[], | |
| 5542 | + struct inode *inode, unsigned long cache_validity) | |
| 5428 | 5543 | { |
| 5429 | − unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity); | |
| 5544 | + struct nfs_server *server = NFS_SERVER(inode); | |
| 5430 | 5545 | unsigned int i; |
| 5431 | 5546 | |
| 5432 | 5547 | memcpy(bitmask, src, sizeof(*bitmask) * NFS4_BITMASK_SZ); |
| 5548 | + cache_validity |= READ_ONCE(NFS_I(inode)->cache_validity); | |
| 5433 | 5549 | |
| 5434 | 5550 | if (cache_validity & NFS_INO_INVALID_CHANGE) |
| 5435 | 5551 | bitmask[0] |= FATTR4_WORD0_CHANGE; |
| @@ -5441,8 +5557,6 @@ static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src, · 5 unmodified lines | ||
| 5441 | 5557 | bitmask[1] |= FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP; |
| 5442 | 5558 | if (cache_validity & NFS_INO_INVALID_NLINK) |
| 5443 | 5559 | bitmask[1] |= FATTR4_WORD1_NUMLINKS; |
| 5444 | − if (label && label->len && cache_validity & NFS_INO_INVALID_LABEL) | |
| 5445 | − bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL; | |
| 5446 | 5560 | if (cache_validity & NFS_INO_INVALID_CTIME) |
| 5447 | 5561 | bitmask[1] |= FATTR4_WORD1_TIME_METADATA; |
| 5448 | 5562 | if (cache_validity & NFS_INO_INVALID_MTIME) |
| @@ -5469,7 +5583,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr, · 20 unmodified lines | ||
| 5469 | 5583 | } else { |
| 5470 | 5584 | nfs4_bitmask_set(hdr->args.bitmask_store, |
| 5471 | 5585 | server->cache_consistency_bitmask, |
| 5472 | − hdr->inode, server, NULL); | |
| 5586 | + hdr->inode, NFS_INO_INVALID_BLOCKS); | |
| 5473 | 5587 | hdr->args.bitmask = hdr->args.bitmask_store; |
| 5474 | 5588 | } |
| 5475 | 5589 | |
| @@ -6507,8 +6621,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, · 1031 unmodified lines | ||
| 6507 | 6621 | data->args.fhandle = &data->fh; |
| 6508 | 6622 | data->args.stateid = &data->stateid; |
| 6509 | 6623 | nfs4_bitmask_set(data->args.bitmask_store, |
| 6510 | − server->cache_consistency_bitmask, inode, server, | |
| 6511 | − NULL); | |
| 6624 | + server->cache_consistency_bitmask, inode, 0); | |
| 6512 | 6625 | data->args.bitmask = data->args.bitmask_store; |
| 6513 | 6626 | nfs_copy_fh(&data->fh, NFS_FH(inode)); |
| 6514 | 6627 | nfs4_stateid_copy(&data->stateid, stateid); |
| @@ -7611,7 +7724,7 @@ static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler, · 1096 unmodified lines | ||
| 7611 | 7724 | const char *key, const void *buf, |
| 7612 | 7725 | size_t buflen, int flags) |
| 7613 | 7726 | { |
| 7614 | − struct nfs_access_entry cache; | |
| 7727 | + u32 mask; | |
| 7615 | 7728 | int ret; |
| 7616 | 7729 | |
| 7617 | 7730 | if (!nfs_server_capable(inode, NFS_CAP_XATTR)) |
| @@ -7626,8 +7739,8 @@ static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler, · 8 unmodified lines | ||
| 7626 | 7739 | * do a cached access check for the XA* flags to possibly avoid |
| 7627 | 7740 | * doing an RPC and getting EACCES back. |
| 7628 | 7741 | */ |
| 7629 | − if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) { | |
| 7630 | − if (!(cache.mask & NFS_ACCESS_XAWRITE)) | |
| 7742 | + if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) { | |
| 7743 | + if (!(mask & NFS_ACCESS_XAWRITE)) | |
| 7631 | 7744 | return -EACCES; |
| 7632 | 7745 | } |
| 7633 | 7746 | |
| @@ -7648,14 +7761,14 @@ static int nfs4_xattr_get_nfs4_user(const struct xattr_handler *handler, · 14 unmodified lines | ||
| 7648 | 7761 | struct dentry *unused, struct inode *inode, |
| 7649 | 7762 | const char *key, void *buf, size_t buflen) |
| 7650 | 7763 | { |
| 7651 | − struct nfs_access_entry cache; | |
| 7764 | + u32 mask; | |
| 7652 | 7765 | ssize_t ret; |
| 7653 | 7766 | |
| 7654 | 7767 | if (!nfs_server_capable(inode, NFS_CAP_XATTR)) |
| 7655 | 7768 | return -EOPNOTSUPP; |
| 7656 | 7769 | |
| 7657 | − if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) { | |
| 7658 | − if (!(cache.mask & NFS_ACCESS_XAREAD)) | |
| 7770 | + if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) { | |
| 7771 | + if (!(mask & NFS_ACCESS_XAREAD)) | |
| 7659 | 7772 | return -EACCES; |
| 7660 | 7773 | } |
| 7661 | 7774 | |
| @@ -7680,13 +7793,13 @@ nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len) · 18 unmodified lines | ||
| 7680 | 7793 | ssize_t ret, size; |
| 7681 | 7794 | char *buf; |
| 7682 | 7795 | size_t buflen; |
| 7683 | − struct nfs_access_entry cache; | |
| 7796 | + u32 mask; | |
| 7684 | 7797 | |
| 7685 | 7798 | if (!nfs_server_capable(inode, NFS_CAP_XATTR)) |
| 7686 | 7799 | return 0; |
| 7687 | 7800 | |
| 7688 | − if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) { | |
| 7689 | − if (!(cache.mask & NFS_ACCESS_XALIST)) | |
| 7801 | + if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) { | |
| 7802 | + if (!(mask & NFS_ACCESS_XALIST)) | |
| 7690 | 7803 | return 0; |
| 7691 | 7804 | } |
| 7692 | 7805 | |
| @@ -7818,18 +7931,18 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, · 125 unmodified lines | ||
| 7818 | 7931 | * appended to this compound to identify the client ID which is |
| 7819 | 7932 | * performing recovery. |
| 7820 | 7933 | */ |
| 7821 | −static int _nfs40_proc_get_locations(struct inode *inode, | |
| 7934 | +static int _nfs40_proc_get_locations(struct nfs_server *server, | |
| 7935 | + struct nfs_fh *fhandle, | |
| 7822 | 7936 | struct nfs4_fs_locations *locations, |
| 7823 | 7937 | struct page *page, const struct cred *cred) |
| 7824 | 7938 | { |
| 7825 | − struct nfs_server *server = NFS_SERVER(inode); | |
| 7826 | 7939 | struct rpc_clnt *clnt = server->client; |
| 7827 | 7940 | u32 bitmask[2] = { |
| 7828 | 7941 | [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, |
| 7829 | 7942 | }; |
| 7830 | 7943 | struct nfs4_fs_locations_arg args = { |
| 7831 | 7944 | .clientid = server->nfs_client->cl_clientid, |
| 7832 | − .fh = NFS_FH(inode), | |
| 7945 | + .fh = fhandle, | |
| 7833 | 7946 | .page = page, |
| 7834 | 7947 | .bitmask = bitmask, |
| 7835 | 7948 | .migration = 1, /* skip LOOKUP */ |
| @@ -7875,17 +7988,17 @@ static int _nfs40_proc_get_locations(struct inode *inode, · 39 unmodified lines | ||
| 7875 | 7988 | * When the client supports GETATTR(fs_locations_info), it can |
| 7876 | 7989 | * be plumbed in here. |
| 7877 | 7990 | */ |
| 7878 | −static int _nfs41_proc_get_locations(struct inode *inode, | |
| 7991 | +static int _nfs41_proc_get_locations(struct nfs_server *server, | |
| 7992 | + struct nfs_fh *fhandle, | |
| 7879 | 7993 | struct nfs4_fs_locations *locations, |
| 7880 | 7994 | struct page *page, const struct cred *cred) |
| 7881 | 7995 | { |
| 7882 | − struct nfs_server *server = NFS_SERVER(inode); | |
| 7883 | 7996 | struct rpc_clnt *clnt = server->client; |
| 7884 | 7997 | u32 bitmask[2] = { |
| 7885 | 7998 | [0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS, |
| 7886 | 7999 | }; |
| 7887 | 8000 | struct nfs4_fs_locations_arg args = { |
| 7888 | − .fh = NFS_FH(inode), | |
| 8001 | + .fh = fhandle, | |
| 7889 | 8002 | .page = page, |
| 7890 | 8003 | .bitmask = bitmask, |
| 7891 | 8004 | .migration = 1, /* skip LOOKUP */ |
| @@ -7934,11 +8047,11 @@ static int _nfs41_proc_get_locations(struct inode *inode, · 42 unmodified lines | ||
| 7934 | 8047 | * -NFS4ERR_LEASE_MOVED is returned if the server still has leases |
| 7935 | 8048 | * from this client that require migration recovery. |
| 7936 | 8049 | */ |
| 7937 | −int nfs4_proc_get_locations(struct inode *inode, | |
| 8050 | +int nfs4_proc_get_locations(struct nfs_server *server, | |
| 8051 | + struct nfs_fh *fhandle, | |
| 7938 | 8052 | struct nfs4_fs_locations *locations, |
| 7939 | 8053 | struct page *page, const struct cred *cred) |
| 7940 | 8054 | { |
| 7941 | − struct nfs_server *server = NFS_SERVER(inode); | |
| 7942 | 8055 | struct nfs_client *clp = server->nfs_client; |
| 7943 | 8056 | const struct nfs4_mig_recovery_ops *ops = |
| 7944 | 8057 | clp->cl_mvops->mig_recovery_ops; |
| @@ -7951,10 +8064,11 @@ int nfs4_proc_get_locations(struct inode *inode, · 6 unmodified lines | ||
| 7951 | 8064 | (unsigned long long)server->fsid.major, |
| 7952 | 8065 | (unsigned long long)server->fsid.minor, |
| 7953 | 8066 | clp->cl_hostname); |
| 7954 | − nfs_display_fhandle(NFS_FH(inode), __func__); | |
| 8067 | + nfs_display_fhandle(fhandle, __func__); | |
| 7955 | 8068 | |
| 7956 | 8069 | do { |
| 7957 | − status = ops->get_locations(inode, locations, page, cred); | |
| 8070 | + status = ops->get_locations(server, fhandle, locations, page, | |
| 8071 | + cred); | |
| 7958 | 8072 | if (status != -NFS4ERR_DELAY) |
| 7959 | 8073 | break; |
| 7960 | 8074 | nfs4_handle_exception(server, status, &exception); |
| @@ -10423,6 +10537,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { · 2462 unmodified lines | ||
| 10423 | 10537 | .free_client = nfs4_free_client, |
| 10424 | 10538 | .create_server = nfs4_create_server, |
| 10425 | 10539 | .clone_server = nfs_clone_server, |
| 10540 | + .discover_trunking = nfs4_discover_trunking, | |
| 10426 | 10541 | }; |
| 10427 | 10542 | |
| 10428 | 10543 | static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { |
| @@ -2098,7 +2098,8 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred · 2097 unmodified lines | ||
| 2098 | 2098 | } |
| 2099 | 2099 | |
| 2100 | 2100 | inode = d_inode(server->super->s_root); |
| 2101 | − result = nfs4_proc_get_locations(inode, locations, page, cred); | |
| 2101 | + result = nfs4_proc_get_locations(server, NFS_FH(inode), locations, | |
| 2102 | + page, cred); | |
| 2102 | 2103 | if (result) { |
| 2103 | 2104 | dprintk("<-- %s: failed to retrieve fs_locations: %d\n", |
| 2104 | 2105 | __func__, result); |
| @@ -2106,6 +2107,9 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred · 1 unmodified line | ||
| 2106 | 2107 | } |
| 2107 | 2108 | |
| 2108 | 2109 | result = -NFS4ERR_NXIO; |
| 2110 | + if (!locations->nlocations) | |
| 2111 | + goto out; | |
| 2112 | + | |
| 2109 | 2113 | if (!(locations->fattr.valid & NFS_ATTR_FATTR_V4_LOCATIONS)) { |
| 2110 | 2114 | dprintk("<-- %s: No fs_locations data, migration skipped\n", |
| 2111 | 2115 | __func__); |
| @@ -3533,6 +3533,42 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint · 3532 unmodified lines | ||
| 3533 | 3533 | return 0; |
| 3534 | 3534 | } |
| 3535 | 3535 | |
| 3536 | +static int decode_attr_case_insensitive(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | |
| 3537 | +{ | |
| 3538 | + __be32 *p; | |
| 3539 | + | |
| 3540 | + *res = 0; | |
| 3541 | + if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_INSENSITIVE - 1U))) | |
| 3542 | + return -EIO; | |
| 3543 | + if (likely(bitmap[0] & FATTR4_WORD0_CASE_INSENSITIVE)) { | |
| 3544 | + p = xdr_inline_decode(xdr, 4); | |
| 3545 | + if (unlikely(!p)) | |
| 3546 | + return -EIO; | |
| 3547 | + *res = be32_to_cpup(p); | |
| 3548 | + bitmap[0] &= ~FATTR4_WORD0_CASE_INSENSITIVE; | |
| 3549 | + } | |
| 3550 | + dprintk("%s: case_insensitive=%s\n", __func__, *res == 0 ? "false" : "true"); | |
| 3551 | + return 0; | |
| 3552 | +} | |
| 3553 | + | |
| 3554 | +static int decode_attr_case_preserving(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | |
| 3555 | +{ | |
| 3556 | + __be32 *p; | |
| 3557 | + | |
| 3558 | + *res = 0; | |
| 3559 | + if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_PRESERVING - 1U))) | |
| 3560 | + return -EIO; | |
| 3561 | + if (likely(bitmap[0] & FATTR4_WORD0_CASE_PRESERVING)) { | |
| 3562 | + p = xdr_inline_decode(xdr, 4); | |
| 3563 | + if (unlikely(!p)) | |
| 3564 | + return -EIO; | |
| 3565 | + *res = be32_to_cpup(p); | |
| 3566 | + bitmap[0] &= ~FATTR4_WORD0_CASE_PRESERVING; | |
| 3567 | + } | |
| 3568 | + dprintk("%s: case_preserving=%s\n", __func__, *res == 0 ? "false" : "true"); | |
| 3569 | + return 0; | |
| 3570 | +} | |
| 3571 | + | |
| 3536 | 3572 | static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) |
| 3537 | 3573 | { |
| 3538 | 3574 | __be32 *p; |
| @@ -3696,8 +3732,6 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st · 157 unmodified lines | ||
| 3696 | 3732 | if (unlikely(!p)) |
| 3697 | 3733 | goto out_eio; |
| 3698 | 3734 | n = be32_to_cpup(p); |
| 3699 | − if (n <= 0) | |
| 3700 | − goto out_eio; | |
| 3701 | 3735 | for (res->nlocations = 0; res->nlocations < n; res->nlocations++) { |
| 3702 | 3736 | u32 m; |
| 3703 | 3737 | struct nfs4_fs_location *loc; |
| @@ -4200,10 +4234,11 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, · 496 unmodified lines | ||
| 4200 | 4234 | } else |
| 4201 | 4235 | printk(KERN_WARNING "%s: label too long (%u)!\n", |
| 4202 | 4236 | __func__, len); |
| 4237 | + if (label && label->label) | |
| 4238 | + dprintk("%s: label=%.*s, len=%d, PI=%d, LFS=%d\n", | |
| 4239 | + __func__, label->len, (char *)label->label, | |
| 4240 | + label->len, label->pi, label->lfs); | |
| 4203 | 4241 | } |
| 4204 | − if (label && label->label) | |
| 4205 | − dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__, | |
| 4206 | − (char *)label->label, label->len, label->pi, label->lfs); | |
| 4207 | 4242 | return status; |
| 4208 | 4243 | } |
| 4209 | 4244 | |
| @@ -4412,6 +4447,10 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re · 202 unmodified lines | ||
| 4412 | 4447 | goto xdr_error; |
| 4413 | 4448 | if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0) |
| 4414 | 4449 | goto xdr_error; |
| 4450 | + if ((status = decode_attr_case_insensitive(xdr, bitmap, &res->case_insensitive)) != 0) | |
| 4451 | + goto xdr_error; | |
| 4452 | + if ((status = decode_attr_case_preserving(xdr, bitmap, &res->case_preserving)) != 0) | |
| 4453 | + goto xdr_error; | |
| 4415 | 4454 | if ((status = decode_attr_exclcreat_supported(xdr, bitmap, |
| 4416 | 4455 | res->exclcreat_bitmask)) != 0) |
| 4417 | 4456 | goto xdr_error; |
| @@ -142,10 +142,11 @@ static struct attribute *nfs_netns_client_attrs[] = { · 141 unmodified lines | ||
| 142 | 142 | &nfs_netns_client_id.attr, |
| 143 | 143 | NULL, |
| 144 | 144 | }; |
| 145 | +ATTRIBUTE_GROUPS(nfs_netns_client); | |
| 145 | 146 | |
| 146 | 147 | static struct kobj_type nfs_netns_client_type = { |
| 147 | 148 | .release = nfs_netns_client_release, |
| 148 | − .default_attrs = nfs_netns_client_attrs, | |
| 149 | + .default_groups = nfs_netns_client_groups, | |
| 149 | 150 | .sysfs_ops = &kobj_sysfs_ops, |
| 150 | 151 | .namespace = nfs_netns_client_namespace, |
| 151 | 152 | }; |
| @@ -1247,7 +1247,8 @@ static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry) · 1246 unmodified lines | ||
| 1247 | 1247 | clear_ncl(d_inode(dentry)); |
| 1248 | 1248 | dget(dentry); |
| 1249 | 1249 | ret = simple_unlink(dir, dentry); |
| 1250 | − d_delete(dentry); | |
| 1250 | + d_drop(dentry); | |
| 1251 | + fsnotify_unlink(dir, dentry); | |
| 1251 | 1252 | dput(dentry); |
| 1252 | 1253 | WARN_ON_ONCE(ret); |
| 1253 | 1254 | } |
| @@ -1338,8 +1339,8 @@ void nfsd_client_rmdir(struct dentry *dentry) · 84 unmodified lines | ||
| 1338 | 1339 | dget(dentry); |
| 1339 | 1340 | ret = simple_rmdir(dir, dentry); |
| 1340 | 1341 | WARN_ON_ONCE(ret); |
| 1342 | + d_drop(dentry); | |
| 1341 | 1343 | fsnotify_rmdir(dir, dentry); |
| 1342 | − d_delete(dentry); | |
| 1343 | 1344 | dput(dentry); |
| 1344 | 1345 | inode_unlock(dir); |
| 1345 | 1346 | } |
| @@ -158,7 +158,6 @@ static size_t fanotify_event_len(unsigned int info_mode, · 157 unmodified lines | ||
| 158 | 158 | struct fanotify_event *event) |
| 159 | 159 | { |
| 160 | 160 | size_t event_len = FAN_EVENT_METADATA_LEN; |
| 161 | − struct fanotify_info *info; | |
| 162 | 161 | int fh_len; |
| 163 | 162 | int dot_len = 0; |
| 164 | 163 | |
| @@ -168,8 +167,6 @@ static size_t fanotify_event_len(unsigned int info_mode, · 3 unmodified lines | ||
| 168 | 167 | if (fanotify_is_error_event(event->mask)) |
| 169 | 168 | event_len += FANOTIFY_ERROR_INFO_LEN; |
| 170 | 169 | |
| 171 | − info = fanotify_event_info(event); | |
| 172 | − | |
| 173 | 170 | if (fanotify_event_has_any_dir_fh(event)) { |
| 174 | 171 | event_len += fanotify_dir_name_info_len(event); |
| 175 | 172 | } else if ((info_mode & FAN_REPORT_NAME) && |
| @@ -661,17 +661,6 @@ static struct ctl_table ocfs2_nm_table[] = { · 660 unmodified lines | ||
| 661 | 661 | { } |
| 662 | 662 | }; |
| 663 | 663 | |
| 664 | −static struct ctl_table ocfs2_mod_table[] = { | |
| 665 | − { | |
| 666 | − .procname = "nm", | |
| 667 | − .data = NULL, | |
| 668 | − .maxlen = 0, | |
| 669 | − .mode = 0555, | |
| 670 | − .child = ocfs2_nm_table | |
| 671 | − }, | |
| 672 | − { } | |
| 673 | −}; | |
| 674 | − | |
| 675 | 664 | static struct ctl_table_header *ocfs2_table_header; |
| 676 | 665 | |
| 677 | 666 | /* |
| @@ -682,7 +671,7 @@ static int __init ocfs2_stack_glue_init(void) · 4 unmodified lines | ||
| 682 | 671 | { |
| 683 | 672 | strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB); |
| 684 | 673 | |
| 685 | − ocfs2_table_header = register_sysctl("fs/ocfs2", ocfs2_mod_table); | |
| 674 | + ocfs2_table_header = register_sysctl("fs/ocfs2/nm", ocfs2_nm_table); | |
| 686 | 675 | if (!ocfs2_table_header) { |
| 687 | 676 | printk(KERN_ERR |
| 688 | 677 | "ocfs2 stack glue: unable to register sysctl\n"); |
| @@ -1251,26 +1251,23 @@ static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, · 1250 unmodified lines | ||
| 1251 | 1251 | { |
| 1252 | 1252 | struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data; |
| 1253 | 1253 | struct journal_head *jh; |
| 1254 | − int ret = 1; | |
| 1254 | + int ret; | |
| 1255 | 1255 | |
| 1256 | 1256 | if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap)) |
| 1257 | 1257 | return 0; |
| 1258 | 1258 | |
| 1259 | − if (!buffer_jbd(bg_bh)) | |
| 1259 | + jh = jbd2_journal_grab_journal_head(bg_bh); | |
| 1260 | + if (!jh) | |
| 1260 | 1261 | return 1; |
| 1261 | 1262 | |
| 1262 | − jbd_lock_bh_journal_head(bg_bh); | |
| 1263 | − if (buffer_jbd(bg_bh)) { | |
| 1264 | − jh = bh2jh(bg_bh); | |
| 1265 | − spin_lock(&jh->b_state_lock); | |
| 1266 | − bg = (struct ocfs2_group_desc *) jh->b_committed_data; | |
| 1267 | − if (bg) | |
| 1268 | − ret = !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap); | |
| 1269 | − else | |
| 1270 | − ret = 1; | |
| 1271 | − spin_unlock(&jh->b_state_lock); | |
| 1272 | − } | |
| 1273 | − jbd_unlock_bh_journal_head(bg_bh); | |
| 1263 | + spin_lock(&jh->b_state_lock); | |
| 1264 | + bg = (struct ocfs2_group_desc *) jh->b_committed_data; | |
| 1265 | + if (bg) | |
| 1266 | + ret = !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap); | |
| 1267 | + else | |
| 1268 | + ret = 1; | |
| 1269 | + spin_unlock(&jh->b_state_lock); | |
| 1270 | + jbd2_journal_put_journal_head(jh); | |
| 1274 | 1271 | |
| 1275 | 1272 | return ret; |
| 1276 | 1273 | } |
| @@ -258,10 +258,6 @@ int udf_expand_file_adinicb(struct inode *inode) · 257 unmodified lines | ||
| 258 | 258 | char *kaddr; |
| 259 | 259 | struct udf_inode_info *iinfo = UDF_I(inode); |
| 260 | 260 | int err; |
| 261 | − struct writeback_control udf_wbc = { | |
| 262 | − .sync_mode = WB_SYNC_NONE, | |
| 263 | − .nr_to_write = 1, | |
| 264 | − }; | |
| 265 | 261 | |
| 266 | 262 | WARN_ON_ONCE(!inode_is_locked(inode)); |
| 267 | 263 | if (!iinfo->i_lenAlloc) { |
| @@ -305,8 +301,10 @@ int udf_expand_file_adinicb(struct inode *inode) · 37 unmodified lines | ||
| 305 | 301 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; |
| 306 | 302 | /* from now on we have normal address_space methods */ |
| 307 | 303 | inode->i_data.a_ops = &udf_aops; |
| 304 | + set_page_dirty(page); | |
| 305 | + unlock_page(page); | |
| 308 | 306 | up_write(&iinfo->i_data_sem); |
| 309 | − err = inode->i_data.a_ops->writepage(page, &udf_wbc); | |
| 307 | + err = filemap_fdatawrite(inode->i_mapping); | |
| 310 | 308 | if (err) { |
| 311 | 309 | /* Restore everything back so that we don't lose data... */ |
| 312 | 310 | lock_page(page); |
| @@ -317,6 +315,7 @@ int udf_expand_file_adinicb(struct inode *inode) · 4 unmodified lines | ||
| 317 | 315 | unlock_page(page); |
| 318 | 316 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; |
| 319 | 317 | inode->i_data.a_ops = &udf_adinicb_aops; |
| 318 | + iinfo->i_lenAlloc = inode->i_size; | |
| 320 | 319 | up_write(&iinfo->i_data_sem); |
| 321 | 320 | } |
| 322 | 321 | put_page(page); |
| @@ -1258,6 +1258,7 @@ unsigned long disk_start_io_acct(struct gendisk *disk, unsigned int sectors, · 1257 unmodified lines | ||
| 1258 | 1258 | void disk_end_io_acct(struct gendisk *disk, unsigned int op, |
| 1259 | 1259 | unsigned long start_time); |
| 1260 | 1260 | |
| 1261 | +void bio_start_io_acct_time(struct bio *bio, unsigned long start_time); | |
| 1261 | 1262 | unsigned long bio_start_io_acct(struct bio *bio); |
| 1262 | 1263 | void bio_end_io_acct_remapped(struct bio *bio, unsigned long start_time, |
| 1263 | 1264 | struct block_device *orig_bdev); |
| @@ -111,7 +111,7 @@ struct ethtool_link_ext_state_info { · 110 unmodified lines | ||
| 111 | 111 | enum ethtool_link_ext_substate_bad_signal_integrity bad_signal_integrity; |
| 112 | 112 | enum ethtool_link_ext_substate_cable_issue cable_issue; |
| 113 | 113 | enum ethtool_link_ext_substate_module module; |
| 114 | − u8 __link_ext_substate; | |
| 114 | + u32 __link_ext_substate; | |
| 115 | 115 | }; |
| 116 | 116 | }; |
| 117 | 117 | |
| @@ -224,6 +224,43 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, · 223 unmodified lines | ||
| 224 | 224 | dir, &new_dentry->d_name, 0); |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | +/* | |
| 228 | + * fsnotify_delete - @dentry was unlinked and unhashed | |
| 229 | + * | |
| 230 | + * Caller must make sure that dentry->d_name is stable. | |
| 231 | + * | |
| 232 | + * Note: unlike fsnotify_unlink(), we have to pass also the unlinked inode | |
| 233 | + * as this may be called after d_delete() and old_dentry may be negative. | |
| 234 | + */ | |
| 235 | +static inline void fsnotify_delete(struct inode *dir, struct inode *inode, | |
| 236 | + struct dentry *dentry) | |
| 237 | +{ | |
| 238 | + __u32 mask = FS_DELETE; | |
| 239 | + | |
| 240 | + if (S_ISDIR(inode->i_mode)) | |
| 241 | + mask |= FS_ISDIR; | |
| 242 | + | |
| 243 | + fsnotify_name(mask, inode, FSNOTIFY_EVENT_INODE, dir, &dentry->d_name, | |
| 244 | + 0); | |
| 245 | +} | |
| 246 | + | |
| 247 | +/** | |
| 248 | + * d_delete_notify - delete a dentry and call fsnotify_delete() | |
| 249 | + * @dentry: The dentry to delete | |
| 250 | + * | |
| 251 | + * This helper is used to guaranty that the unlinked inode cannot be found | |
| 252 | + * by lookup of this name after fsnotify_delete() event has been delivered. | |
| 253 | + */ | |
| 254 | +static inline void d_delete_notify(struct inode *dir, struct dentry *dentry) | |
| 255 | +{ | |
| 256 | + struct inode *inode = d_inode(dentry); | |
| 257 | + | |
| 258 | + ihold(inode); | |
| 259 | + d_delete(dentry); | |
| 260 | + fsnotify_delete(dir, inode, dentry); | |
| 261 | + iput(inode); | |
| 262 | +} | |
| 263 | + | |
| 227 | 264 | /* |
| 228 | 265 | * fsnotify_unlink - 'name' was unlinked |
| 229 | 266 | * |
| @@ -231,10 +268,10 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, · 1 unmodified line | ||
| 231 | 268 | */ |
| 232 | 269 | static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry) |
| 233 | 270 | { |
| 234 | − /* Expected to be called before d_delete() */ | |
| 235 | − WARN_ON_ONCE(d_is_negative(dentry)); | |
| 271 | + if (WARN_ON_ONCE(d_is_negative(dentry))) | |
| 272 | + return; | |
| 236 | 273 | |
| 237 | − fsnotify_dirent(dir, dentry, FS_DELETE); | |
| 274 | + fsnotify_delete(dir, d_inode(dentry), dentry); | |
| 238 | 275 | } |
| 239 | 276 | |
| 240 | 277 | /* |
| @@ -258,10 +295,10 @@ static inline void fsnotify_mkdir(struct inode *dir, struct dentry *dentry) · 17 unmodified lines | ||
| 258 | 295 | */ |
| 259 | 296 | static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry) |
| 260 | 297 | { |
| 261 | − /* Expected to be called before d_delete() */ | |
| 262 | − WARN_ON_ONCE(d_is_negative(dentry)); | |
| 298 | + if (WARN_ON_ONCE(d_is_negative(dentry))) | |
| 299 | + return; | |
| 263 | 300 | |
| 264 | − fsnotify_dirent(dir, dentry, FS_DELETE | FS_ISDIR); | |
| 301 | + fsnotify_delete(dir, d_inode(dentry), dentry); | |
| 265 | 302 | } |
| 266 | 303 | |
| 267 | 304 | /* |
| @@ -80,7 +80,7 @@ LSM_HOOK(int, 0, sb_clone_mnt_opts, const struct super_block *oldsb, · 79 unmodified lines | ||
| 80 | 80 | unsigned long *set_kern_flags) |
| 81 | 81 | LSM_HOOK(int, 0, move_mount, const struct path *from_path, |
| 82 | 82 | const struct path *to_path) |
| 83 | −LSM_HOOK(int, 0, dentry_init_security, struct dentry *dentry, | |
| 83 | +LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry, | |
| 84 | 84 | int mode, const struct qstr *name, const char **xattr_name, |
| 85 | 85 | void **ctx, u32 *ctxlen) |
| 86 | 86 | LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode, |
| @@ -1506,11 +1506,18 @@ static inline u8 page_kasan_tag(const struct page *page) · 1505 unmodified lines | ||
| 1506 | 1506 | |
| 1507 | 1507 | static inline void page_kasan_tag_set(struct page *page, u8 tag) |
| 1508 | 1508 | { |
| 1509 | − if (kasan_enabled()) { | |
| 1510 | − tag ^= 0xff; | |
| 1511 | − page->flags &= ~(KASAN_TAG_MASK << KASAN_TAG_PGSHIFT); | |
| 1512 | − page->flags |= (tag & KASAN_TAG_MASK) << KASAN_TAG_PGSHIFT; | |
| 1513 | − } | |
| 1509 | + unsigned long old_flags, flags; | |
| 1510 | + | |
| 1511 | + if (!kasan_enabled()) | |
| 1512 | + return; | |
| 1513 | + | |
| 1514 | + tag ^= 0xff; | |
| 1515 | + old_flags = READ_ONCE(page->flags); | |
| 1516 | + do { | |
| 1517 | + flags = old_flags; | |
| 1518 | + flags &= ~(KASAN_TAG_MASK << KASAN_TAG_PGSHIFT); | |
| 1519 | + flags |= (tag & KASAN_TAG_MASK) << KASAN_TAG_PGSHIFT; | |
| 1520 | + } while (unlikely(!try_cmpxchg(&page->flags, &old_flags, flags))); | |
| 1514 | 1521 | } |
| 1515 | 1522 | |
| 1516 | 1523 | static inline void page_kasan_tag_reset(struct page *page) |
| @@ -261,6 +261,7 @@ static_assert(sizeof(struct page) == sizeof(struct folio)); · 260 unmodified lines | ||
| 261 | 261 | static_assert(offsetof(struct page, pg) == offsetof(struct folio, fl)) |
| 262 | 262 | FOLIO_MATCH(flags, flags); |
| 263 | 263 | FOLIO_MATCH(lru, lru); |
| 264 | +FOLIO_MATCH(mapping, mapping); | |
| 264 | 265 | FOLIO_MATCH(compound_head, lru); |
| 265 | 266 | FOLIO_MATCH(index, index); |
| 266 | 267 | FOLIO_MATCH(private, private); |
| @@ -2548,6 +2548,7 @@ struct packet_type { · 2547 unmodified lines | ||
| 2548 | 2548 | struct net_device *); |
| 2549 | 2549 | bool (*id_match)(struct packet_type *ptype, |
| 2550 | 2550 | struct sock *sk); |
| 2551 | + struct net *af_packet_net; | |
| 2551 | 2552 | void *af_packet_priv; |
| 2552 | 2553 | struct list_head list; |
| 2553 | 2554 | }; |
| @@ -61,7 +61,9 @@ · 60 unmodified lines | ||
| 61 | 61 | struct nfs_access_entry { |
| 62 | 62 | struct rb_node rb_node; |
| 63 | 63 | struct list_head lru; |
| 64 | − const struct cred * cred; | |
| 64 | + kuid_t fsuid; | |
| 65 | + kgid_t fsgid; | |
| 66 | + struct group_info *group_info; | |
| 65 | 67 | __u32 mask; |
| 66 | 68 | struct rcu_head rcu_head; |
| 67 | 69 | }; |
| @@ -395,7 +397,7 @@ extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fa · 327 unmodified lines | ||
| 395 | 397 | extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr); |
| 396 | 398 | extern int nfs_getattr(struct user_namespace *, const struct path *, |
| 397 | 399 | struct kstat *, u32, unsigned int); |
| 398 | −extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); | |
| 400 | +extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *, const struct cred *); | |
| 399 | 401 | extern void nfs_access_set_mask(struct nfs_access_entry *, u32); |
| 400 | 402 | extern int nfs_permission(struct user_namespace *, struct inode *, int); |
| 401 | 403 | extern int nfs_open(struct inode *, struct file *); |
| @@ -532,8 +534,8 @@ extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, · 130 unmodified lines | ||
| 532 | 534 | struct nfs_fattr *fattr); |
| 533 | 535 | extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags); |
| 534 | 536 | extern void nfs_access_zap_cache(struct inode *inode); |
| 535 | −extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, | |
| 536 | − bool may_block); | |
| 537 | +extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred, | |
| 538 | + u32 *mask, bool may_block); | |
| 537 | 539 | |
| 538 | 540 | /* |
| 539 | 541 | * linux/fs/nfs/symlink.c |
| @@ -266,6 +266,8 @@ struct nfs_server { · 265 unmodified lines | ||
| 266 | 266 | #define NFS_CAP_ACLS (1U << 3) |
| 267 | 267 | #define NFS_CAP_ATOMIC_OPEN (1U << 4) |
| 268 | 268 | #define NFS_CAP_LGOPEN (1U << 5) |
| 269 | +#define NFS_CAP_CASE_INSENSITIVE (1U << 6) | |
| 270 | +#define NFS_CAP_CASE_PRESERVING (1U << 7) | |
| 269 | 271 | #define NFS_CAP_POSIX_LOCK (1U << 14) |
| 270 | 272 | #define NFS_CAP_UIDGID_NOMAP (1U << 15) |
| 271 | 273 | #define NFS_CAP_STATEID_NFSV41 (1U << 16) |
| @@ -282,5 +284,5 @@ struct nfs_server { · 10 unmodified lines | ||
| 282 | 284 | #define NFS_CAP_COPY_NOTIFY (1U << 27) |
| 283 | 285 | #define NFS_CAP_XATTR (1U << 28) |
| 284 | 286 | #define NFS_CAP_READ_PLUS (1U << 29) |
| 285 | − | |
| 287 | +#define NFS_CAP_FS_LOCATIONS (1U << 30) | |
| 286 | 288 | #endif |
| @@ -1194,6 +1194,8 @@ struct nfs4_server_caps_res { · 1193 unmodified lines | ||
| 1194 | 1194 | u32 has_links; |
| 1195 | 1195 | u32 has_symlinks; |
| 1196 | 1196 | u32 fh_expire_type; |
| 1197 | + u32 case_insensitive; | |
| 1198 | + u32 case_preserving; | |
| 1197 | 1199 | }; |
| 1198 | 1200 | |
| 1199 | 1201 | #define NFS4_PATHNAME_MAXCOMPONENTS 512 |
| @@ -1737,7 +1739,7 @@ struct nfs_rpc_ops { · 537 unmodified lines | ||
| 1737 | 1739 | struct nfs_fh *, struct nfs_fattr *); |
| 1738 | 1740 | int (*lookupp) (struct inode *, struct nfs_fh *, |
| 1739 | 1741 | struct nfs_fattr *); |
| 1740 | − int (*access) (struct inode *, struct nfs_access_entry *); | |
| 1742 | + int (*access) (struct inode *, struct nfs_access_entry *, const struct cred *); | |
| 1741 | 1743 | int (*readlink)(struct inode *, struct page *, unsigned int, |
| 1742 | 1744 | unsigned int); |
| 1743 | 1745 | int (*create) (struct inode *, struct dentry *, |
| @@ -1795,6 +1797,7 @@ struct nfs_rpc_ops { · 51 unmodified lines | ||
| 1795 | 1797 | struct nfs_server *(*create_server)(struct fs_context *); |
| 1796 | 1798 | struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, |
| 1797 | 1799 | struct nfs_fattr *, rpc_authflavor_t); |
| 1800 | + int (*discover_trunking)(struct nfs_server *, struct nfs_fh *); | |
| 1798 | 1801 | }; |
| 1799 | 1802 | |
| 1800 | 1803 | /* |
| @@ -693,18 +693,6 @@ struct perf_event { · 692 unmodified lines | ||
| 693 | 693 | u64 total_time_running; |
| 694 | 694 | u64 tstamp; |
| 695 | 695 | |
| 696 | − /* | |
| 697 | − * timestamp shadows the actual context timing but it can | |
| 698 | − * be safely used in NMI interrupt context. It reflects the | |
| 699 | − * context time as it was when the event was last scheduled in, | |
| 700 | − * or when ctx_sched_in failed to schedule the event because we | |
| 701 | − * run out of PMC. | |
| 702 | − * | |
| 703 | − * ctx_time already accounts for ctx->timestamp. Therefore to | |
| 704 | − * compute ctx_time for a sample, simply add perf_clock(). | |
| 705 | − */ | |
| 706 | − u64 shadow_ctx_time; | |
| 707 | − | |
| 708 | 696 | struct perf_event_attr attr; |
| 709 | 697 | u16 header_size; |
| 710 | 698 | u16 id_header_size; |
| @@ -852,6 +840,7 @@ struct perf_event_context { · 141 unmodified lines | ||
| 852 | 840 | */ |
| 853 | 841 | u64 time; |
| 854 | 842 | u64 timestamp; |
| 843 | + u64 timeoffset; | |
| 855 | 844 | |
| 856 | 845 | /* |
| 857 | 846 | * These fields let us detect when two contexts have both |
| @@ -934,6 +923,8 @@ struct bpf_perf_event_data_kern { · 76 unmodified lines | ||
| 934 | 923 | struct perf_cgroup_info { |
| 935 | 924 | u64 time; |
| 936 | 925 | u64 timestamp; |
| 926 | + u64 timeoffset; | |
| 927 | + int active; | |
| 937 | 928 | }; |
| 938 | 929 | |
| 939 | 930 | struct perf_cgroup { |
| @@ -86,4 +86,9 @@ extern struct pid_namespace *task_active_pid_ns(struct task_struct *tsk); · 85 unmodified lines | ||
| 86 | 86 | void pidhash_init(void); |
| 87 | 87 | void pid_idr_init(void); |
| 88 | 88 | |
| 89 | +static inline bool task_is_in_init_pid_ns(struct task_struct *tsk) | |
| 90 | +{ | |
| 91 | + return task_active_pid_ns(tsk) == &init_pid_ns; | |
| 92 | +} | |
| 93 | + | |
| 89 | 94 | #endif /* _LINUX_PID_NS_H */ |
| @@ -25,18 +25,17 @@ void psi_memstall_enter(unsigned long *flags); · 24 unmodified lines | ||
| 25 | 25 | void psi_memstall_leave(unsigned long *flags); |
| 26 | 26 | |
| 27 | 27 | int psi_show(struct seq_file *s, struct psi_group *group, enum psi_res res); |
| 28 | − | |
| 29 | −#ifdef CONFIG_CGROUPS | |
| 30 | −int psi_cgroup_alloc(struct cgroup *cgrp); | |
| 31 | −void psi_cgroup_free(struct cgroup *cgrp); | |
| 32 | −void cgroup_move_task(struct task_struct *p, struct css_set *to); | |
| 33 | − | |
| 34 | 28 | struct psi_trigger *psi_trigger_create(struct psi_group *group, |
| 35 | 29 | char *buf, size_t nbytes, enum psi_res res); |
| 36 | −void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *t); | |
| 30 | +void psi_trigger_destroy(struct psi_trigger *t); | |
| 37 | 31 | |
| 38 | 32 | __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file, |
| 39 | 33 | poll_table *wait); |
| 34 | + | |
| 35 | +#ifdef CONFIG_CGROUPS | |
| 36 | +int psi_cgroup_alloc(struct cgroup *cgrp); | |
| 37 | +void psi_cgroup_free(struct cgroup *cgrp); | |
| 38 | +void cgroup_move_task(struct task_struct *p, struct css_set *to); | |
| 40 | 39 | #endif |
| 41 | 40 | |
| 42 | 41 | #else /* CONFIG_PSI */ |
| @@ -141,9 +141,6 @@ struct psi_trigger { · 140 unmodified lines | ||
| 141 | 141 | * events to one per window |
| 142 | 142 | */ |
| 143 | 143 | u64 last_event_time; |
| 144 | − | |
| 145 | − /* Refcounting to prevent premature destruction */ | |
| 146 | − struct kref refcount; | |
| 147 | 144 | }; |
| 148 | 145 | |
| 149 | 146 | struct psi_group { |
| @@ -91,7 +91,7 @@ extern bool qid_valid(struct kqid qid); · 90 unmodified lines | ||
| 91 | 91 | * |
| 92 | 92 | * When there is no mapping defined for the user-namespace, type, |
| 93 | 93 | * qid tuple an invalid kqid is returned. Callers are expected to |
| 94 | − * test for and handle handle invalid kqids being returned. | |
| 94 | + * test for and handle invalid kqids being returned. | |
| 95 | 95 | * Invalid kqids may be tested for using qid_valid(). |
| 96 | 96 | */ |
| 97 | 97 | static inline struct kqid make_kqid(struct user_namespace *from, |
| @@ -619,10 +619,6 @@ struct sched_dl_entity { · 618 unmodified lines | ||
| 619 | 619 | * task has to wait for a replenishment to be performed at the |
| 620 | 620 | * next firing of dl_timer. |
| 621 | 621 | * |
| 622 | − * @dl_boosted tells if we are boosted due to DI. If so we are | |
| 623 | − * outside bandwidth enforcement mechanism (but only until we | |
| 624 | − * exit the critical section); | |
| 625 | − * | |
| 626 | 622 | * @dl_yielded tells if task gave up the CPU before consuming |
| 627 | 623 | * all its available runtime during the last job. |
| 628 | 624 | * |
| @@ -318,7 +318,7 @@ enum skb_drop_reason { · 317 unmodified lines | ||
| 318 | 318 | SKB_DROP_REASON_NO_SOCKET, |
| 319 | 319 | SKB_DROP_REASON_PKT_TOO_SMALL, |
| 320 | 320 | SKB_DROP_REASON_TCP_CSUM, |
| 321 | − SKB_DROP_REASON_TCP_FILTER, | |
| 321 | + SKB_DROP_REASON_SOCKET_FILTER, | |
| 322 | 322 | SKB_DROP_REASON_UDP_CSUM, |
| 323 | 323 | SKB_DROP_REASON_MAX, |
| 324 | 324 | }; |
| @@ -430,15 +430,7 @@ struct platform_hibernation_ops { · 429 unmodified lines | ||
| 430 | 430 | |
| 431 | 431 | #ifdef CONFIG_HIBERNATION |
| 432 | 432 | /* kernel/power/snapshot.c */ |
| 433 | −extern void __register_nosave_region(unsigned long b, unsigned long e, int km); | |
| 434 | −static inline void __init register_nosave_region(unsigned long b, unsigned long e) | |
| 435 | −{ | |
| 436 | − __register_nosave_region(b, e, 0); | |
| 437 | −} | |
| 438 | −static inline void __init register_nosave_region_late(unsigned long b, unsigned long e) | |
| 439 | −{ | |
| 440 | − __register_nosave_region(b, e, 1); | |
| 441 | −} | |
| 433 | +extern void register_nosave_region(unsigned long b, unsigned long e); | |
| 442 | 434 | extern int swsusp_page_is_forbidden(struct page *); |
| 443 | 435 | extern void swsusp_set_page_free(struct page *); |
| 444 | 436 | extern void swsusp_unset_page_free(struct page *); |
| @@ -458,7 +450,6 @@ int pfn_is_nosave(unsigned long pfn); · 13 unmodified lines | ||
| 458 | 450 | int hibernate_quiet_exec(int (*func)(void *data), void *data); |
| 459 | 451 | #else /* CONFIG_HIBERNATION */ |
| 460 | 452 | static inline void register_nosave_region(unsigned long b, unsigned long e) {} |
| 461 | −static inline void register_nosave_region_late(unsigned long b, unsigned long e) {} | |
| 462 | 453 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } |
| 463 | 454 | static inline void swsusp_set_page_free(struct page *p) {} |
| 464 | 455 | static inline void swsusp_unset_page_free(struct page *p) {} |
| @@ -265,7 +265,7 @@ static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * · 264 unmodified lines | ||
| 265 | 265 | return NULL; |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | −static inline struct sysctl_header *register_sysctl_mount_point(const char *path) | |
| 268 | +static inline struct ctl_table_header *register_sysctl_mount_point(const char *path) | |
| 269 | 269 | { |
| 270 | 270 | return NULL; |
| 271 | 271 | } |
| @@ -91,6 +91,12 @@ fwnode_usb_role_switch_get(struct fwnode_handle *node) · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | static inline void usb_role_switch_put(struct usb_role_switch *sw) { } |
| 93 | 93 | |
| 94 | +static inline struct usb_role_switch * | |
| 95 | +usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode) | |
| 96 | +{ | |
| 97 | + return NULL; | |
| 98 | +} | |
| 99 | + | |
| 94 | 100 | static inline struct usb_role_switch * |
| 95 | 101 | usb_role_switch_register(struct device *parent, |
| 96 | 102 | const struct usb_role_switch_desc *desc) |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | ||
| 6 | 6 | #define RTR_SOLICITATION_INTERVAL (4*HZ) |
| 7 | 7 | #define RTR_SOLICITATION_MAX_INTERVAL (3600*HZ) /* 1 hour */ |
| 8 | 8 | |
| 9 | +#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */ | |
| 10 | + | |
| 9 | 11 | #define TEMP_VALID_LIFETIME (7*86400) |
| 10 | 12 | #define TEMP_PREFERRED_LIFETIME (86400) |
| 11 | 13 | #define REGEN_MAX_RETRY (3) |
| @@ -346,7 +346,7 @@ static inline bool bond_uses_primary(struct bonding *bond) · 345 unmodified lines | ||
| 346 | 346 | |
| 347 | 347 | static inline struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond) |
| 348 | 348 | { |
| 349 | − struct slave *slave = rcu_dereference(bond->curr_active_slave); | |
| 349 | + struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave); | |
| 350 | 350 | |
| 351 | 351 | return bond_uses_primary(bond) && slave ? slave->dev : NULL; |
| 352 | 352 | } |
| @@ -525,19 +525,18 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb, · 524 unmodified lines | ||
| 525 | 525 | { |
| 526 | 526 | struct iphdr *iph = ip_hdr(skb); |
| 527 | 527 | |
| 528 | + /* We had many attacks based on IPID, use the private | |
| 529 | + * generator as much as we can. | |
| 530 | + */ | |
| 531 | + if (sk && inet_sk(sk)->inet_daddr) { | |
| 532 | + iph->id = htons(inet_sk(sk)->inet_id); | |
| 533 | + inet_sk(sk)->inet_id += segs; | |
| 534 | + return; | |
| 535 | + } | |
| 528 | 536 | if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { |
| 529 | − /* This is only to work around buggy Windows95/2000 | |
| 530 | − * VJ compression implementations. If the ID field | |
| 531 | − * does not change, they drop every other packet in | |
| 532 | − * a TCP stream using header compression. | |
| 533 | − */ | |
| 534 | − if (sk && inet_sk(sk)->inet_daddr) { | |
| 535 | − iph->id = htons(inet_sk(sk)->inet_id); | |
| 536 | − inet_sk(sk)->inet_id += segs; | |
| 537 | − } else { | |
| 538 | − iph->id = 0; | |
| 539 | − } | |
| 537 | + iph->id = 0; | |
| 540 | 538 | } else { |
| 539 | + /* Unfortunately we need the big hammer to get a suitable IPID */ | |
| 541 | 540 | __ip_select_ident(net, iph, segs); |
| 542 | 541 | } |
| 543 | 542 | } |
| @@ -282,7 +282,7 @@ static inline bool fib6_get_cookie_safe(const struct fib6_info *f6i, · 281 unmodified lines | ||
| 282 | 282 | fn = rcu_dereference(f6i->fib6_node); |
| 283 | 283 | |
| 284 | 284 | if (fn) { |
| 285 | − *cookie = fn->fn_sernum; | |
| 285 | + *cookie = READ_ONCE(fn->fn_sernum); | |
| 286 | 286 | /* pairs with smp_wmb() in __fib6_update_sernum_upto_root() */ |
| 287 | 287 | smp_rmb(); |
| 288 | 288 | status = true; |
| @@ -370,7 +370,7 @@ static inline struct neighbour *ip_neigh_gw4(struct net_device *dev, · 369 unmodified lines | ||
| 370 | 370 | { |
| 371 | 371 | struct neighbour *neigh; |
| 372 | 372 | |
| 373 | − neigh = __ipv4_neigh_lookup_noref(dev, daddr); | |
| 373 | + neigh = __ipv4_neigh_lookup_noref(dev, (__force u32)daddr); | |
| 374 | 374 | if (unlikely(!neigh)) |
| 375 | 375 | neigh = __neigh_create(&arp_tbl, &daddr, dev, false); |
| 376 | 376 | |
| @@ -1369,6 +1369,7 @@ static inline bool tcp_checksum_complete(struct sk_buff *skb) · 1368 unmodified lines | ||
| 1369 | 1369 | |
| 1370 | 1370 | bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb); |
| 1371 | 1371 | |
| 1372 | +#ifdef CONFIG_INET | |
| 1372 | 1373 | void __sk_defer_free_flush(struct sock *sk); |
| 1373 | 1374 | |
| 1374 | 1375 | static inline void sk_defer_free_flush(struct sock *sk) |
| @@ -1377,6 +1378,9 @@ static inline void sk_defer_free_flush(struct sock *sk) · 2 unmodified lines | ||
| 1377 | 1378 | return; |
| 1378 | 1379 | __sk_defer_free_flush(sk); |
| 1379 | 1380 | } |
| 1381 | +#else | |
| 1382 | +static inline void sk_defer_free_flush(struct sock *sk) {} | |
| 1383 | +#endif | |
| 1380 | 1384 | |
| 1381 | 1385 | int tcp_filter(struct sock *sk, struct sk_buff *skb); |
| 1382 | 1386 | void tcp_set_state(struct sock *sk, int state); |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | EM(SKB_DROP_REASON_NO_SOCKET, NO_SOCKET) \ |
| 15 | 15 | EM(SKB_DROP_REASON_PKT_TOO_SMALL, PKT_TOO_SMALL) \ |
| 16 | 16 | EM(SKB_DROP_REASON_TCP_CSUM, TCP_CSUM) \ |
| 17 | − EM(SKB_DROP_REASON_TCP_FILTER, TCP_FILTER) \ | |
| 17 | + EM(SKB_DROP_REASON_SOCKET_FILTER, SOCKET_FILTER) \ | |
| 18 | 18 | EM(SKB_DROP_REASON_UDP_CSUM, UDP_CSUM) \ |
| 19 | 19 | EMe(SKB_DROP_REASON_MAX, MAX) |
| 20 | 20 | |
| @@ -794,6 +794,9 @@ RPC_SHOW_SOCKET · 793 unmodified lines | ||
| 794 | 794 | |
| 795 | 795 | RPC_SHOW_SOCK |
| 796 | 796 | |
| 797 | + | |
| 798 | +#include <trace/events/net_probe_common.h> | |
| 799 | + | |
| 797 | 800 | /* |
| 798 | 801 | * Now redefine the EM() and EMe() macros to map the enums to the strings |
| 799 | 802 | * that will be printed in the output. |
| @@ -816,27 +819,32 @@ DECLARE_EVENT_CLASS(xs_socket_event, · 16 unmodified lines | ||
| 816 | 819 | __field(unsigned int, socket_state) |
| 817 | 820 | __field(unsigned int, sock_state) |
| 818 | 821 | __field(unsigned long long, ino) |
| 819 | − __string(dstaddr, | |
| 820 | − xprt->address_strings[RPC_DISPLAY_ADDR]) | |
| 821 | − __string(dstport, | |
| 822 | − xprt->address_strings[RPC_DISPLAY_PORT]) | |
| 822 | + __array(__u8, saddr, sizeof(struct sockaddr_in6)) | |
| 823 | + __array(__u8, daddr, sizeof(struct sockaddr_in6)) | |
| 823 | 824 | ), |
| 824 | 825 | |
| 825 | 826 | TP_fast_assign( |
| 826 | 827 | struct inode *inode = SOCK_INODE(socket); |
| 828 | + const struct sock *sk = socket->sk; | |
| 829 | + const struct inet_sock *inet = inet_sk(sk); | |
| 830 | + | |
| 831 | + memset(__entry->saddr, 0, sizeof(struct sockaddr_in6)); | |
| 832 | + memset(__entry->daddr, 0, sizeof(struct sockaddr_in6)); | |
| 833 | + | |
| 834 | + TP_STORE_ADDR_PORTS(__entry, inet, sk); | |
| 835 | + | |
| 827 | 836 | __entry->socket_state = socket->state; |
| 828 | 837 | __entry->sock_state = socket->sk->sk_state; |
| 829 | 838 | __entry->ino = (unsigned long long)inode->i_ino; |
| 830 | − __assign_str(dstaddr, | |
| 831 | − xprt->address_strings[RPC_DISPLAY_ADDR]); | |
| 832 | − __assign_str(dstport, | |
| 833 | − xprt->address_strings[RPC_DISPLAY_PORT]); | |
| 839 | + | |
| 834 | 840 | ), |
| 835 | 841 | |
| 836 | 842 | TP_printk( |
| 837 | − "socket:[%llu] dstaddr=%s/%s " | |
| 843 | + "socket:[%llu] srcaddr=%pISpc dstaddr=%pISpc " | |
| 838 | 844 | "state=%u (%s) sk_state=%u (%s)", |
| 839 | − __entry->ino, __get_str(dstaddr), __get_str(dstport), | |
| 845 | + __entry->ino, | |
| 846 | + __entry->saddr, | |
| 847 | + __entry->daddr, | |
| 840 | 848 | __entry->socket_state, |
| 841 | 849 | rpc_show_socket_state(__entry->socket_state), |
| 842 | 850 | __entry->sock_state, |
| @@ -866,29 +874,33 @@ DECLARE_EVENT_CLASS(xs_socket_event_done, · 23 unmodified lines | ||
| 866 | 874 | __field(unsigned int, socket_state) |
| 867 | 875 | __field(unsigned int, sock_state) |
| 868 | 876 | __field(unsigned long long, ino) |
| 869 | − __string(dstaddr, | |
| 870 | − xprt->address_strings[RPC_DISPLAY_ADDR]) | |
| 871 | − __string(dstport, | |
| 872 | − xprt->address_strings[RPC_DISPLAY_PORT]) | |
| 877 | + __array(__u8, saddr, sizeof(struct sockaddr_in6)) | |
| 878 | + __array(__u8, daddr, sizeof(struct sockaddr_in6)) | |
| 873 | 879 | ), |
| 874 | 880 | |
| 875 | 881 | TP_fast_assign( |
| 876 | 882 | struct inode *inode = SOCK_INODE(socket); |
| 883 | + const struct sock *sk = socket->sk; | |
| 884 | + const struct inet_sock *inet = inet_sk(sk); | |
| 885 | + | |
| 886 | + memset(__entry->saddr, 0, sizeof(struct sockaddr_in6)); | |
| 887 | + memset(__entry->daddr, 0, sizeof(struct sockaddr_in6)); | |
| 888 | + | |
| 889 | + TP_STORE_ADDR_PORTS(__entry, inet, sk); | |
| 890 | + | |
| 877 | 891 | __entry->socket_state = socket->state; |
| 878 | 892 | __entry->sock_state = socket->sk->sk_state; |
| 879 | 893 | __entry->ino = (unsigned long long)inode->i_ino; |
| 880 | 894 | __entry->error = error; |
| 881 | − __assign_str(dstaddr, | |
| 882 | − xprt->address_strings[RPC_DISPLAY_ADDR]); | |
| 883 | − __assign_str(dstport, | |
| 884 | − xprt->address_strings[RPC_DISPLAY_PORT]); | |
| 885 | 895 | ), |
| 886 | 896 | |
| 887 | 897 | TP_printk( |
| 888 | − "error=%d socket:[%llu] dstaddr=%s/%s " | |
| 898 | + "error=%d socket:[%llu] srcaddr=%pISpc dstaddr=%pISpc " | |
| 889 | 899 | "state=%u (%s) sk_state=%u (%s)", |
| 890 | 900 | __entry->error, |
| 891 | − __entry->ino, __get_str(dstaddr), __get_str(dstport), | |
| 901 | + __entry->ino, | |
| 902 | + __entry->saddr, | |
| 903 | + __entry->daddr, | |
| 892 | 904 | __entry->socket_state, |
| 893 | 905 | rpc_show_socket_state(__entry->socket_state), |
| 894 | 906 | __entry->sock_state, |
| @@ -953,7 +965,8 @@ TRACE_EVENT(rpc_socket_nospace, · 58 unmodified lines | ||
| 953 | 965 | { BIT(XPRT_REMOVE), "REMOVE" }, \ |
| 954 | 966 | { BIT(XPRT_CONGESTED), "CONGESTED" }, \ |
| 955 | 967 | { BIT(XPRT_CWND_WAIT), "CWND_WAIT" }, \ |
| 956 | − { BIT(XPRT_WRITE_SPACE), "WRITE_SPACE" }) | |
| 968 | + { BIT(XPRT_WRITE_SPACE), "WRITE_SPACE" }, \ | |
| 969 | + { BIT(XPRT_SND_IS_COOKIE), "SND_IS_COOKIE" }) | |
| 957 | 970 | |
| 958 | 971 | DECLARE_EVENT_CLASS(rpc_xprt_lifetime_class, |
| 959 | 972 | TP_PROTO( |
| @@ -1150,8 +1163,11 @@ DECLARE_EVENT_CLASS(xprt_writelock_event, · 190 unmodified lines | ||
| 1150 | 1163 | __entry->task_id = -1; |
| 1151 | 1164 | __entry->client_id = -1; |
| 1152 | 1165 | } |
| 1153 | − __entry->snd_task_id = xprt->snd_task ? | |
| 1154 | − xprt->snd_task->tk_pid : -1; | |
| 1166 | + if (xprt->snd_task && | |
| 1167 | + !test_bit(XPRT_SND_IS_COOKIE, &xprt->state)) | |
| 1168 | + __entry->snd_task_id = xprt->snd_task->tk_pid; | |
| 1169 | + else | |
| 1170 | + __entry->snd_task_id = -1; | |
| 1155 | 1171 | ), |
| 1156 | 1172 | |
| 1157 | 1173 | TP_printk(SUNRPC_TRACE_TASK_SPECIFIER |
| @@ -1196,8 +1212,12 @@ DECLARE_EVENT_CLASS(xprt_cong_event, · 38 unmodified lines | ||
| 1196 | 1212 | __entry->task_id = -1; |
| 1197 | 1213 | __entry->client_id = -1; |
| 1198 | 1214 | } |
| 1199 | − __entry->snd_task_id = xprt->snd_task ? | |
| 1200 | − xprt->snd_task->tk_pid : -1; | |
| 1215 | + if (xprt->snd_task && | |
| 1216 | + !test_bit(XPRT_SND_IS_COOKIE, &xprt->state)) | |
| 1217 | + __entry->snd_task_id = xprt->snd_task->tk_pid; | |
| 1218 | + else | |
| 1219 | + __entry->snd_task_id = -1; | |
| 1220 | + | |
| 1201 | 1221 | __entry->cong = xprt->cong; |
| 1202 | 1222 | __entry->cwnd = xprt->cwnd; |
| 1203 | 1223 | __entry->wait = test_bit(XPRT_CWND_WAIT, &xprt->state); |
| @@ -23,8 +23,9 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #undef __get_rel_dynamic_array |
| 25 | 25 | #define __get_rel_dynamic_array(field) \ |
| 26 | − ((void *)(&__entry->__rel_loc_##field) + \ | |
| 27 | − sizeof(__entry->__rel_loc_##field) + \ | |
| 26 | + ((void *)__entry + \ | |
| 27 | + offsetof(typeof(*__entry), __rel_loc_##field) + \ | |
| 28 | + sizeof(__entry->__rel_loc_##field) + \ | |
| 28 | 29 | (__entry->__rel_loc_##field & 0xffff)) |
| 29 | 30 | |
| 30 | 31 | #undef __get_rel_dynamic_array_len |
| @@ -128,7 +128,7 @@ TRACE_MAKE_SYSTEM_STR(); · 127 unmodified lines | ||
| 128 | 128 | struct trace_event_raw_##name { \ |
| 129 | 129 | struct trace_entry ent; \ |
| 130 | 130 | tstruct \ |
| 131 | − char __data[0]; \ | |
| 131 | + char __data[]; \ | |
| 132 | 132 | }; \ |
| 133 | 133 | \ |
| 134 | 134 | static struct trace_event_class event_class_##name; |
| @@ -318,9 +318,10 @@ TRACE_MAKE_SYSTEM_STR(); · 183 unmodified lines | ||
| 318 | 318 | #define __get_str(field) ((char *)__get_dynamic_array(field)) |
| 319 | 319 | |
| 320 | 320 | #undef __get_rel_dynamic_array |
| 321 | −#define __get_rel_dynamic_array(field) \ | |
| 322 | − ((void *)(&__entry->__rel_loc_##field) + \ | |
| 323 | − sizeof(__entry->__rel_loc_##field) + \ | |
| 321 | +#define __get_rel_dynamic_array(field) \ | |
| 322 | + ((void *)__entry + \ | |
| 323 | + offsetof(typeof(*__entry), __rel_loc_##field) + \ | |
| 324 | + sizeof(__entry->__rel_loc_##field) + \ | |
| 324 | 325 | (__entry->__rel_loc_##field & 0xffff)) |
| 325 | 326 | |
| 326 | 327 | #undef __get_rel_dynamic_array_len |
| @@ -0,0 +1,35 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | |
| 2 | + | |
| 3 | +#ifndef _UAPI_LINUX_CYCLADES_H | |
| 4 | +#define _UAPI_LINUX_CYCLADES_H | |
| 5 | + | |
| 6 | +#warning "Support for features provided by this header has been removed" | |
| 7 | +#warning "Please consider updating your code" | |
| 8 | + | |
| 9 | +struct cyclades_monitor { | |
| 10 | + unsigned long int_count; | |
| 11 | + unsigned long char_count; | |
| 12 | + unsigned long char_max; | |
| 13 | + unsigned long char_last; | |
| 14 | +}; | |
| 15 | + | |
| 16 | +#define CYGETMON 0x435901 | |
| 17 | +#define CYGETTHRESH 0x435902 | |
| 18 | +#define CYSETTHRESH 0x435903 | |
| 19 | +#define CYGETDEFTHRESH 0x435904 | |
| 20 | +#define CYSETDEFTHRESH 0x435905 | |
| 21 | +#define CYGETTIMEOUT 0x435906 | |
| 22 | +#define CYSETTIMEOUT 0x435907 | |
| 23 | +#define CYGETDEFTIMEOUT 0x435908 | |
| 24 | +#define CYSETDEFTIMEOUT 0x435909 | |
| 25 | +#define CYSETRFLOW 0x43590a | |
| 26 | +#define CYGETRFLOW 0x43590b | |
| 27 | +#define CYSETRTSDTR_INV 0x43590c | |
| 28 | +#define CYGETRTSDTR_INV 0x43590d | |
| 29 | +#define CYZSETPOLLCYCLE 0x43590e | |
| 30 | +#define CYZGETPOLLCYCLE 0x43590f | |
| 31 | +#define CYGETCD1400VER 0x435910 | |
| 32 | +#define CYSETWAIT 0x435912 | |
| 33 | +#define CYGETWAIT 0x435913 | |
| 34 | + | |
| 35 | +#endif /* _UAPI_LINUX_CYCLADES_H */ | |
| @@ -1133,6 +1133,7 @@ struct kvm_ppc_resize_hpt { · 1132 unmodified lines | ||
| 1133 | 1133 | #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206 |
| 1134 | 1134 | #define KVM_CAP_VM_GPA_BITS 207 |
| 1135 | 1135 | #define KVM_CAP_XSAVE2 208 |
| 1136 | +#define KVM_CAP_SYS_ATTRIBUTES 209 | |
| 1136 | 1137 | |
| 1137 | 1138 | #ifdef KVM_CAP_IRQ_ROUTING |
| 1138 | 1139 | |
| @@ -472,13 +472,14 @@ BPF_CALL_4(bpf_get_task_stack, struct task_struct *, task, void *, buf, · 471 unmodified lines | ||
| 472 | 472 | u32, size, u64, flags) |
| 473 | 473 | { |
| 474 | 474 | struct pt_regs *regs; |
| 475 | − long res; | |
| 475 | + long res = -EINVAL; | |
| 476 | 476 | |
| 477 | 477 | if (!try_get_task_stack(task)) |
| 478 | 478 | return -EFAULT; |
| 479 | 479 | |
| 480 | 480 | regs = task_pt_regs(task); |
| 481 | − res = __bpf_get_stack(regs, task, NULL, buf, size, flags); | |
| 481 | + if (regs) | |
| 482 | + res = __bpf_get_stack(regs, task, NULL, buf, size, flags); | |
| 482 | 483 | put_task_stack(task); |
| 483 | 484 | |
| 484 | 485 | return res; |
| @@ -3643,6 +3643,12 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, · 3642 unmodified lines | ||
| 3643 | 3643 | cgroup_get(cgrp); |
| 3644 | 3644 | cgroup_kn_unlock(of->kn); |
| 3645 | 3645 | |
| 3646 | + /* Allow only one trigger per file descriptor */ | |
| 3647 | + if (ctx->psi.trigger) { | |
| 3648 | + cgroup_put(cgrp); | |
| 3649 | + return -EBUSY; | |
| 3650 | + } | |
| 3651 | + | |
| 3646 | 3652 | psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi; |
| 3647 | 3653 | new = psi_trigger_create(psi, buf, nbytes, res); |
| 3648 | 3654 | if (IS_ERR(new)) { |
| @@ -3650,8 +3656,7 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, · 1 unmodified line | ||
| 3650 | 3656 | return PTR_ERR(new); |
| 3651 | 3657 | } |
| 3652 | 3658 | |
| 3653 | − psi_trigger_replace(&ctx->psi.trigger, new); | |
| 3654 | − | |
| 3659 | + smp_store_release(&ctx->psi.trigger, new); | |
| 3655 | 3660 | cgroup_put(cgrp); |
| 3656 | 3661 | |
| 3657 | 3662 | return nbytes; |
| @@ -3690,7 +3695,7 @@ static void cgroup_pressure_release(struct kernfs_open_file *of) · 32 unmodified lines | ||
| 3690 | 3695 | { |
| 3691 | 3696 | struct cgroup_file_ctx *ctx = of->priv; |
| 3692 | 3697 | |
| 3693 | − psi_trigger_replace(&ctx->psi.trigger, NULL); | |
| 3698 | + psi_trigger_destroy(ctx->psi.trigger); | |
| 3694 | 3699 | } |
| 3695 | 3700 | |
| 3696 | 3701 | bool cgroup_psi_enabled(void) |
| @@ -674,6 +674,23 @@ perf_event_set_state(struct perf_event *event, enum perf_event_state state) · 673 unmodified lines | ||
| 674 | 674 | WRITE_ONCE(event->state, state); |
| 675 | 675 | } |
| 676 | 676 | |
| 677 | +/* | |
| 678 | + * UP store-release, load-acquire | |
| 679 | + */ | |
| 680 | + | |
| 681 | +#define __store_release(ptr, val) \ | |
| 682 | +do { \ | |
| 683 | + barrier(); \ | |
| 684 | + WRITE_ONCE(*(ptr), (val)); \ | |
| 685 | +} while (0) | |
| 686 | + | |
| 687 | +#define __load_acquire(ptr) \ | |
| 688 | +({ \ | |
| 689 | + __unqual_scalar_typeof(*(ptr)) ___p = READ_ONCE(*(ptr)); \ | |
| 690 | + barrier(); \ | |
| 691 | + ___p; \ | |
| 692 | +}) | |
| 693 | + | |
| 677 | 694 | #ifdef CONFIG_CGROUP_PERF |
| 678 | 695 | |
| 679 | 696 | static inline bool |
| @@ -719,34 +736,51 @@ static inline u64 perf_cgroup_event_time(struct perf_event *event) · 39 unmodified lines | ||
| 719 | 736 | return t->time; |
| 720 | 737 | } |
| 721 | 738 | |
| 722 | −static inline void __update_cgrp_time(struct perf_cgroup *cgrp) | |
| 739 | +static inline u64 perf_cgroup_event_time_now(struct perf_event *event, u64 now) | |
| 723 | 740 | { |
| 724 | − struct perf_cgroup_info *info; | |
| 725 | − u64 now; | |
| 726 | − | |
| 727 | − now = perf_clock(); | |
| 741 | + struct perf_cgroup_info *t; | |
| 728 | 742 | |
| 729 | − info = this_cpu_ptr(cgrp->info); | |
| 743 | + t = per_cpu_ptr(event->cgrp->info, event->cpu); | |
| 744 | + if (!__load_acquire(&t->active)) | |
| 745 | + return t->time; | |
| 746 | + now += READ_ONCE(t->timeoffset); | |
| 747 | + return now; | |
| 748 | +} | |
| 730 | 749 | |
| 731 | − info->time += now - info->timestamp; | |
| 750 | +static inline void __update_cgrp_time(struct perf_cgroup_info *info, u64 now, bool adv) | |
| 751 | +{ | |
| 752 | + if (adv) | |
| 753 | + info->time += now - info->timestamp; | |
| 732 | 754 | info->timestamp = now; |
| 755 | + /* | |
| 756 | + * see update_context_time() | |
| 757 | + */ | |
| 758 | + WRITE_ONCE(info->timeoffset, info->time - info->timestamp); | |
| 733 | 759 | } |
| 734 | 760 | |
| 735 | −static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx) | |
| 761 | +static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx, bool final) | |
| 736 | 762 | { |
| 737 | 763 | struct perf_cgroup *cgrp = cpuctx->cgrp; |
| 738 | 764 | struct cgroup_subsys_state *css; |
| 765 | + struct perf_cgroup_info *info; | |
| 739 | 766 | |
| 740 | 767 | if (cgrp) { |
| 768 | + u64 now = perf_clock(); | |
| 769 | + | |
| 741 | 770 | for (css = &cgrp->css; css; css = css->parent) { |
| 742 | 771 | cgrp = container_of(css, struct perf_cgroup, css); |
| 743 | − __update_cgrp_time(cgrp); | |
| 772 | + info = this_cpu_ptr(cgrp->info); | |
| 773 | + | |
| 774 | + __update_cgrp_time(info, now, true); | |
| 775 | + if (final) | |
| 776 | + __store_release(&info->active, 0); | |
| 744 | 777 | } |
| 745 | 778 | } |
| 746 | 779 | } |
| 747 | 780 | |
| 748 | 781 | static inline void update_cgrp_time_from_event(struct perf_event *event) |
| 749 | 782 | { |
| 783 | + struct perf_cgroup_info *info; | |
| 750 | 784 | struct perf_cgroup *cgrp; |
| 751 | 785 | |
| 752 | 786 | /* |
| @@ -760,8 +794,10 @@ static inline void update_cgrp_time_from_event(struct perf_event *event) · 7 unmodified lines | ||
| 760 | 794 | /* |
| 761 | 795 | * Do not update time when cgroup is not active |
| 762 | 796 | */ |
| 763 | − if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup)) | |
| 764 | − __update_cgrp_time(event->cgrp); | |
| 797 | + if (cgroup_is_descendant(cgrp->css.cgroup, event->cgrp->css.cgroup)) { | |
| 798 | + info = this_cpu_ptr(event->cgrp->info); | |
| 799 | + __update_cgrp_time(info, perf_clock(), true); | |
| 800 | + } | |
| 765 | 801 | } |
| 766 | 802 | |
| 767 | 803 | static inline void |
| @@ -785,7 +821,8 @@ perf_cgroup_set_timestamp(struct task_struct *task, · 17 unmodified lines | ||
| 785 | 821 | for (css = &cgrp->css; css; css = css->parent) { |
| 786 | 822 | cgrp = container_of(css, struct perf_cgroup, css); |
| 787 | 823 | info = this_cpu_ptr(cgrp->info); |
| 788 | − info->timestamp = ctx->timestamp; | |
| 824 | + __update_cgrp_time(info, ctx->timestamp, false); | |
| 825 | + __store_release(&info->active, 1); | |
| 789 | 826 | } |
| 790 | 827 | } |
| 791 | 828 | |
| @@ -981,14 +1018,6 @@ out: · 189 unmodified lines | ||
| 981 | 1018 | return ret; |
| 982 | 1019 | } |
| 983 | 1020 | |
| 984 | −static inline void | |
| 985 | −perf_cgroup_set_shadow_time(struct perf_event *event, u64 now) | |
| 986 | −{ | |
| 987 | − struct perf_cgroup_info *t; | |
| 988 | − t = per_cpu_ptr(event->cgrp->info, event->cpu); | |
| 989 | − event->shadow_ctx_time = now - t->timestamp; | |
| 990 | −} | |
| 991 | − | |
| 992 | 1021 | static inline void |
| 993 | 1022 | perf_cgroup_event_enable(struct perf_event *event, struct perf_event_context *ctx) |
| 994 | 1023 | { |
| @@ -1066,7 +1095,8 @@ static inline void update_cgrp_time_from_event(struct perf_event *event) · 71 unmodified lines | ||
| 1066 | 1095 | { |
| 1067 | 1096 | } |
| 1068 | 1097 | |
| 1069 | −static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx) | |
| 1098 | +static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx, | |
| 1099 | + bool final) | |
| 1070 | 1100 | { |
| 1071 | 1101 | } |
| 1072 | 1102 | |
| @@ -1098,12 +1128,12 @@ perf_cgroup_switch(struct task_struct *task, struct task_struct *next) · 25 unmodified lines | ||
| 1098 | 1128 | { |
| 1099 | 1129 | } |
| 1100 | 1130 | |
| 1101 | −static inline void | |
| 1102 | −perf_cgroup_set_shadow_time(struct perf_event *event, u64 now) | |
| 1131 | +static inline u64 perf_cgroup_event_time(struct perf_event *event) | |
| 1103 | 1132 | { |
| 1133 | + return 0; | |
| 1104 | 1134 | } |
| 1105 | 1135 | |
| 1106 | −static inline u64 perf_cgroup_event_time(struct perf_event *event) | |
| 1136 | +static inline u64 perf_cgroup_event_time_now(struct perf_event *event, u64 now) | |
| 1107 | 1137 | { |
| 1108 | 1138 | return 0; |
| 1109 | 1139 | } |
| @@ -1525,22 +1555,59 @@ static void perf_unpin_context(struct perf_event_context *ctx) · 415 unmodified lines | ||
| 1525 | 1555 | /* |
| 1526 | 1556 | * Update the record of the current time in a context. |
| 1527 | 1557 | */ |
| 1528 | −static void update_context_time(struct perf_event_context *ctx) | |
| 1558 | +static void __update_context_time(struct perf_event_context *ctx, bool adv) | |
| 1529 | 1559 | { |
| 1530 | 1560 | u64 now = perf_clock(); |
| 1531 | 1561 | |
| 1532 | − ctx->time += now - ctx->timestamp; | |
| 1562 | + if (adv) | |
| 1563 | + ctx->time += now - ctx->timestamp; | |
| 1533 | 1564 | ctx->timestamp = now; |
| 1565 | + | |
| 1566 | + /* | |
| 1567 | + * The above: time' = time + (now - timestamp), can be re-arranged | |
| 1568 | + * into: time` = now + (time - timestamp), which gives a single value | |
| 1569 | + * offset to compute future time without locks on. | |
| 1570 | + * | |
| 1571 | + * See perf_event_time_now(), which can be used from NMI context where | |
| 1572 | + * it's (obviously) not possible to acquire ctx->lock in order to read | |
| 1573 | + * both the above values in a consistent manner. | |
| 1574 | + */ | |
| 1575 | + WRITE_ONCE(ctx->timeoffset, ctx->time - ctx->timestamp); | |
| 1576 | +} | |
| 1577 | + | |
| 1578 | +static void update_context_time(struct perf_event_context *ctx) | |
| 1579 | +{ | |
| 1580 | + __update_context_time(ctx, true); | |
| 1534 | 1581 | } |
| 1535 | 1582 | |
| 1536 | 1583 | static u64 perf_event_time(struct perf_event *event) |
| 1537 | 1584 | { |
| 1538 | 1585 | struct perf_event_context *ctx = event->ctx; |
| 1539 | 1586 | |
| 1587 | + if (unlikely(!ctx)) | |
| 1588 | + return 0; | |
| 1589 | + | |
| 1540 | 1590 | if (is_cgroup_event(event)) |
| 1541 | 1591 | return perf_cgroup_event_time(event); |
| 1542 | 1592 | |
| 1543 | − return ctx ? ctx->time : 0; | |
| 1593 | + return ctx->time; | |
| 1594 | +} | |
| 1595 | + | |
| 1596 | +static u64 perf_event_time_now(struct perf_event *event, u64 now) | |
| 1597 | +{ | |
| 1598 | + struct perf_event_context *ctx = event->ctx; | |
| 1599 | + | |
| 1600 | + if (unlikely(!ctx)) | |
| 1601 | + return 0; | |
| 1602 | + | |
| 1603 | + if (is_cgroup_event(event)) | |
| 1604 | + return perf_cgroup_event_time_now(event, now); | |
| 1605 | + | |
| 1606 | + if (!(__load_acquire(&ctx->is_active) & EVENT_TIME)) | |
| 1607 | + return ctx->time; | |
| 1608 | + | |
| 1609 | + now += READ_ONCE(ctx->timeoffset); | |
| 1610 | + return now; | |
| 1544 | 1611 | } |
| 1545 | 1612 | |
| 1546 | 1613 | static enum event_type_t get_event_type(struct perf_event *event) |
| @@ -2350,7 +2417,7 @@ __perf_remove_from_context(struct perf_event *event, · 803 unmodified lines | ||
| 2350 | 2417 | |
| 2351 | 2418 | if (ctx->is_active & EVENT_TIME) { |
| 2352 | 2419 | update_context_time(ctx); |
| 2353 | − update_cgrp_time_from_cpuctx(cpuctx); | |
| 2420 | + update_cgrp_time_from_cpuctx(cpuctx, false); | |
| 2354 | 2421 | } |
| 2355 | 2422 | |
| 2356 | 2423 | event_sched_out(event, cpuctx, ctx); |
| @@ -2361,6 +2428,9 @@ __perf_remove_from_context(struct perf_event *event, · 4 unmodified lines | ||
| 2361 | 2428 | list_del_event(event, ctx); |
| 2362 | 2429 | |
| 2363 | 2430 | if (!ctx->nr_events && ctx->is_active) { |
| 2431 | + if (ctx == &cpuctx->ctx) | |
| 2432 | + update_cgrp_time_from_cpuctx(cpuctx, true); | |
| 2433 | + | |
| 2364 | 2434 | ctx->is_active = 0; |
| 2365 | 2435 | ctx->rotate_necessary = 0; |
| 2366 | 2436 | if (ctx->task) { |
| @@ -2392,7 +2462,11 @@ static void perf_remove_from_context(struct perf_event *event, unsigned long fla · 25 unmodified lines | ||
| 2392 | 2462 | * event_function_call() user. |
| 2393 | 2463 | */ |
| 2394 | 2464 | raw_spin_lock_irq(&ctx->lock); |
| 2395 | − if (!ctx->is_active) { | |
| 2465 | + /* | |
| 2466 | + * Cgroup events are per-cpu events, and must IPI because of | |
| 2467 | + * cgrp_cpuctx_list. | |
| 2468 | + */ | |
| 2469 | + if (!ctx->is_active && !is_cgroup_event(event)) { | |
| 2396 | 2470 | __perf_remove_from_context(event, __get_cpu_context(ctx), |
| 2397 | 2471 | ctx, (void *)flags); |
| 2398 | 2472 | raw_spin_unlock_irq(&ctx->lock); |
| @@ -2482,40 +2556,6 @@ void perf_event_disable_inatomic(struct perf_event *event) · 83 unmodified lines | ||
| 2482 | 2556 | irq_work_queue(&event->pending); |
| 2483 | 2557 | } |
| 2484 | 2558 | |
| 2485 | −static void perf_set_shadow_time(struct perf_event *event, | |
| 2486 | − struct perf_event_context *ctx) | |
| 2487 | −{ | |
| 2488 | − /* | |
| 2489 | − * use the correct time source for the time snapshot | |
| 2490 | − * | |
| 2491 | − * We could get by without this by leveraging the | |
| 2492 | − * fact that to get to this function, the caller | |
| 2493 | − * has most likely already called update_context_time() | |
| 2494 | − * and update_cgrp_time_xx() and thus both timestamp | |
| 2495 | − * are identical (or very close). Given that tstamp is, | |
| 2496 | − * already adjusted for cgroup, we could say that: | |
| 2497 | − * tstamp - ctx->timestamp | |
| 2498 | − * is equivalent to | |
| 2499 | − * tstamp - cgrp->timestamp. | |
| 2500 | − * | |
| 2501 | − * Then, in perf_output_read(), the calculation would | |
| 2502 | − * work with no changes because: | |
| 2503 | − * - event is guaranteed scheduled in | |
| 2504 | − * - no scheduled out in between | |
| 2505 | − * - thus the timestamp would be the same | |
| 2506 | − * | |
| 2507 | − * But this is a bit hairy. | |
| 2508 | − * | |
| 2509 | − * So instead, we have an explicit cgroup call to remain | |
| 2510 | − * within the time source all along. We believe it | |
| 2511 | − * is cleaner and simpler to understand. | |
| 2512 | − */ | |
| 2513 | − if (is_cgroup_event(event)) | |
| 2514 | − perf_cgroup_set_shadow_time(event, event->tstamp); | |
| 2515 | − else | |
| 2516 | − event->shadow_ctx_time = event->tstamp - ctx->timestamp; | |
| 2517 | −} | |
| 2518 | − | |
| 2519 | 2559 | #define MAX_INTERRUPTS (~0ULL) |
| 2520 | 2560 | |
| 2521 | 2561 | static void perf_log_throttle(struct perf_event *event, int enable); |
| @@ -2556,8 +2596,6 @@ event_sched_in(struct perf_event *event, · 34 unmodified lines | ||
| 2556 | 2596 | |
| 2557 | 2597 | perf_pmu_disable(event->pmu); |
| 2558 | 2598 | |
| 2559 | − perf_set_shadow_time(event, ctx); | |
| 2560 | − | |
| 2561 | 2599 | perf_log_itrace_start(event); |
| 2562 | 2600 | |
| 2563 | 2601 | if (event->pmu->add(event, PERF_EF_START)) { |
| @@ -2861,11 +2899,14 @@ perf_install_in_context(struct perf_event_context *ctx, · 297 unmodified lines | ||
| 2861 | 2899 | * perf_event_attr::disabled events will not run and can be initialized |
| 2862 | 2900 | * without IPI. Except when this is the first event for the context, in |
| 2863 | 2901 | * that case we need the magic of the IPI to set ctx->is_active. |
| 2902 | + * Similarly, cgroup events for the context also needs the IPI to | |
| 2903 | + * manipulate the cgrp_cpuctx_list. | |
| 2864 | 2904 | * |
| 2865 | 2905 | * The IOC_ENABLE that is sure to follow the creation of a disabled |
| 2866 | 2906 | * event will issue the IPI and reprogram the hardware. |
| 2867 | 2907 | */ |
| 2868 | − if (__perf_effective_state(event) == PERF_EVENT_STATE_OFF && ctx->nr_events) { | |
| 2908 | + if (__perf_effective_state(event) == PERF_EVENT_STATE_OFF && | |
| 2909 | + ctx->nr_events && !is_cgroup_event(event)) { | |
| 2869 | 2910 | raw_spin_lock_irq(&ctx->lock); |
| 2870 | 2911 | if (ctx->task == TASK_TOMBSTONE) { |
| 2871 | 2912 | raw_spin_unlock_irq(&ctx->lock); |
| @@ -3251,16 +3292,6 @@ static void ctx_sched_out(struct perf_event_context *ctx, · 379 unmodified lines | ||
| 3251 | 3292 | return; |
| 3252 | 3293 | } |
| 3253 | 3294 | |
| 3254 | − ctx->is_active &= ~event_type; | |
| 3255 | − if (!(ctx->is_active & EVENT_ALL)) | |
| 3256 | − ctx->is_active = 0; | |
| 3257 | − | |
| 3258 | − if (ctx->task) { | |
| 3259 | − WARN_ON_ONCE(cpuctx->task_ctx != ctx); | |
| 3260 | − if (!ctx->is_active) | |
| 3261 | − cpuctx->task_ctx = NULL; | |
| 3262 | − } | |
| 3263 | − | |
| 3264 | 3295 | /* |
| 3265 | 3296 | * Always update time if it was set; not only when it changes. |
| 3266 | 3297 | * Otherwise we can 'forget' to update time for any but the last |
| @@ -3274,7 +3305,22 @@ static void ctx_sched_out(struct perf_event_context *ctx, · 7 unmodified lines | ||
| 3274 | 3305 | if (is_active & EVENT_TIME) { |
| 3275 | 3306 | /* update (and stop) ctx time */ |
| 3276 | 3307 | update_context_time(ctx); |
| 3277 | − update_cgrp_time_from_cpuctx(cpuctx); | |
| 3308 | + update_cgrp_time_from_cpuctx(cpuctx, ctx == &cpuctx->ctx); | |
| 3309 | + /* | |
| 3310 | + * CPU-release for the below ->is_active store, | |
| 3311 | + * see __load_acquire() in perf_event_time_now() | |
| 3312 | + */ | |
| 3313 | + barrier(); | |
| 3314 | + } | |
| 3315 | + | |
| 3316 | + ctx->is_active &= ~event_type; | |
| 3317 | + if (!(ctx->is_active & EVENT_ALL)) | |
| 3318 | + ctx->is_active = 0; | |
| 3319 | + | |
| 3320 | + if (ctx->task) { | |
| 3321 | + WARN_ON_ONCE(cpuctx->task_ctx != ctx); | |
| 3322 | + if (!ctx->is_active) | |
| 3323 | + cpuctx->task_ctx = NULL; | |
| 3278 | 3324 | } |
| 3279 | 3325 | |
| 3280 | 3326 | is_active ^= ctx->is_active; /* changed bits */ |
| @@ -3711,13 +3757,19 @@ static noinline int visit_groups_merge(struct perf_cpu_context *cpuctx, · 430 unmodified lines | ||
| 3711 | 3757 | return 0; |
| 3712 | 3758 | } |
| 3713 | 3759 | |
| 3760 | +/* | |
| 3761 | + * Because the userpage is strictly per-event (there is no concept of context, | |
| 3762 | + * so there cannot be a context indirection), every userpage must be updated | |
| 3763 | + * when context time starts :-( | |
| 3764 | + * | |
| 3765 | + * IOW, we must not miss EVENT_TIME edges. | |
| 3766 | + */ | |
| 3714 | 3767 | static inline bool event_update_userpage(struct perf_event *event) |
| 3715 | 3768 | { |
| 3716 | 3769 | if (likely(!atomic_read(&event->mmap_count))) |
| 3717 | 3770 | return false; |
| 3718 | 3771 | |
| 3719 | 3772 | perf_event_update_time(event); |
| 3720 | − perf_set_shadow_time(event, event->ctx); | |
| 3721 | 3773 | perf_event_update_userpage(event); |
| 3722 | 3774 | |
| 3723 | 3775 | return true; |
| @@ -3801,13 +3853,23 @@ ctx_sched_in(struct perf_event_context *ctx, · 77 unmodified lines | ||
| 3801 | 3853 | struct task_struct *task) |
| 3802 | 3854 | { |
| 3803 | 3855 | int is_active = ctx->is_active; |
| 3804 | − u64 now; | |
| 3805 | 3856 | |
| 3806 | 3857 | lockdep_assert_held(&ctx->lock); |
| 3807 | 3858 | |
| 3808 | 3859 | if (likely(!ctx->nr_events)) |
| 3809 | 3860 | return; |
| 3810 | 3861 | |
| 3862 | + if (is_active ^ EVENT_TIME) { | |
| 3863 | + /* start ctx time */ | |
| 3864 | + __update_context_time(ctx, false); | |
| 3865 | + perf_cgroup_set_timestamp(task, ctx); | |
| 3866 | + /* | |
| 3867 | + * CPU-release for the below ->is_active store, | |
| 3868 | + * see __load_acquire() in perf_event_time_now() | |
| 3869 | + */ | |
| 3870 | + barrier(); | |
| 3871 | + } | |
| 3872 | + | |
| 3811 | 3873 | ctx->is_active |= (event_type | EVENT_TIME); |
| 3812 | 3874 | if (ctx->task) { |
| 3813 | 3875 | if (!is_active) |
| @@ -3818,13 +3880,6 @@ ctx_sched_in(struct perf_event_context *ctx, · 4 unmodified lines | ||
| 3818 | 3880 | |
| 3819 | 3881 | is_active ^= ctx->is_active; /* changed bits */ |
| 3820 | 3882 | |
| 3821 | − if (is_active & EVENT_TIME) { | |
| 3822 | − /* start ctx time */ | |
| 3823 | − now = perf_clock(); | |
| 3824 | − ctx->timestamp = now; | |
| 3825 | − perf_cgroup_set_timestamp(task, ctx); | |
| 3826 | − } | |
| 3827 | − | |
| 3828 | 3883 | /* |
| 3829 | 3884 | * First go through the list and put on any pinned groups |
| 3830 | 3885 | * in order to give them the best chance of going on. |
| @@ -4418,6 +4473,18 @@ static inline u64 perf_event_count(struct perf_event *event) · 587 unmodified lines | ||
| 4418 | 4473 | return local64_read(&event->count) + atomic64_read(&event->child_count); |
| 4419 | 4474 | } |
| 4420 | 4475 | |
| 4476 | +static void calc_timer_values(struct perf_event *event, | |
| 4477 | + u64 *now, | |
| 4478 | + u64 *enabled, | |
| 4479 | + u64 *running) | |
| 4480 | +{ | |
| 4481 | + u64 ctx_time; | |
| 4482 | + | |
| 4483 | + *now = perf_clock(); | |
| 4484 | + ctx_time = perf_event_time_now(event, *now); | |
| 4485 | + __perf_update_times(event, ctx_time, enabled, running); | |
| 4486 | +} | |
| 4487 | + | |
| 4421 | 4488 | /* |
| 4422 | 4489 | * NMI-safe method to read a local event, that is an event that |
| 4423 | 4490 | * is: |
| @@ -4477,10 +4544,9 @@ int perf_event_read_local(struct perf_event *event, u64 *value, · 53 unmodified lines | ||
| 4477 | 4544 | |
| 4478 | 4545 | *value = local64_read(&event->count); |
| 4479 | 4546 | if (enabled || running) { |
| 4480 | − u64 now = event->shadow_ctx_time + perf_clock(); | |
| 4481 | − u64 __enabled, __running; | |
| 4547 | + u64 __enabled, __running, __now;; | |
| 4482 | 4548 | |
| 4483 | − __perf_update_times(event, now, &__enabled, &__running); | |
| 4549 | + calc_timer_values(event, &__now, &__enabled, &__running); | |
| 4484 | 4550 | if (enabled) |
| 4485 | 4551 | *enabled = __enabled; |
| 4486 | 4552 | if (running) |
| @@ -5802,18 +5868,6 @@ static int perf_event_index(struct perf_event *event) · 1315 unmodified lines | ||
| 5802 | 5868 | return event->pmu->event_idx(event); |
| 5803 | 5869 | } |
| 5804 | 5870 | |
| 5805 | −static void calc_timer_values(struct perf_event *event, | |
| 5806 | − u64 *now, | |
| 5807 | − u64 *enabled, | |
| 5808 | − u64 *running) | |
| 5809 | −{ | |
| 5810 | − u64 ctx_time; | |
| 5811 | − | |
| 5812 | − *now = perf_clock(); | |
| 5813 | − ctx_time = event->shadow_ctx_time + *now; | |
| 5814 | − __perf_update_times(event, ctx_time, enabled, running); | |
| 5815 | −} | |
| 5816 | − | |
| 5817 | 5871 | static void perf_event_init_userpage(struct perf_event *event) |
| 5818 | 5872 | { |
| 5819 | 5873 | struct perf_event_mmap_page *userpg; |
| @@ -5938,6 +5992,8 @@ static void ring_buffer_attach(struct perf_event *event, · 118 unmodified lines | ||
| 5938 | 5992 | struct perf_buffer *old_rb = NULL; |
| 5939 | 5993 | unsigned long flags; |
| 5940 | 5994 | |
| 5995 | + WARN_ON_ONCE(event->parent); | |
| 5996 | + | |
| 5941 | 5997 | if (event->rb) { |
| 5942 | 5998 | /* |
| 5943 | 5999 | * Should be impossible, we set this when removing |
| @@ -5995,6 +6051,9 @@ static void ring_buffer_wakeup(struct perf_event *event) · 51 unmodified lines | ||
| 5995 | 6051 | { |
| 5996 | 6052 | struct perf_buffer *rb; |
| 5997 | 6053 | |
| 6054 | + if (event->parent) | |
| 6055 | + event = event->parent; | |
| 6056 | + | |
| 5998 | 6057 | rcu_read_lock(); |
| 5999 | 6058 | rb = rcu_dereference(event->rb); |
| 6000 | 6059 | if (rb) { |
| @@ -6008,6 +6067,9 @@ struct perf_buffer *ring_buffer_get(struct perf_event *event) · 7 unmodified lines | ||
| 6008 | 6067 | { |
| 6009 | 6068 | struct perf_buffer *rb; |
| 6010 | 6069 | |
| 6070 | + if (event->parent) | |
| 6071 | + event = event->parent; | |
| 6072 | + | |
| 6011 | 6073 | rcu_read_lock(); |
| 6012 | 6074 | rb = rcu_dereference(event->rb); |
| 6013 | 6075 | if (rb) { |
| @@ -6353,7 +6415,6 @@ accounting: · 339 unmodified lines | ||
| 6353 | 6415 | ring_buffer_attach(event, rb); |
| 6354 | 6416 | |
| 6355 | 6417 | perf_event_update_time(event); |
| 6356 | − perf_set_shadow_time(event, event->ctx); | |
| 6357 | 6418 | perf_event_init_userpage(event); |
| 6358 | 6419 | perf_event_update_userpage(event); |
| 6359 | 6420 | } else { |
| @@ -6717,7 +6778,7 @@ static unsigned long perf_prepare_sample_aux(struct perf_event *event, · 357 unmodified lines | ||
| 6717 | 6778 | if (WARN_ON_ONCE(READ_ONCE(sampler->oncpu) != smp_processor_id())) |
| 6718 | 6779 | goto out; |
| 6719 | 6780 | |
| 6720 | − rb = ring_buffer_get(sampler->parent ? sampler->parent : sampler); | |
| 6781 | + rb = ring_buffer_get(sampler); | |
| 6721 | 6782 | if (!rb) |
| 6722 | 6783 | goto out; |
| 6723 | 6784 | |
| @@ -6783,7 +6844,7 @@ static void perf_aux_sample_output(struct perf_event *event, · 59 unmodified lines | ||
| 6783 | 6844 | if (WARN_ON_ONCE(!sampler || !data->aux_size)) |
| 6784 | 6845 | return; |
| 6785 | 6846 | |
| 6786 | − rb = ring_buffer_get(sampler->parent ? sampler->parent : sampler); | |
| 6847 | + rb = ring_buffer_get(sampler); | |
| 6787 | 6848 | if (!rb) |
| 6788 | 6849 | return; |
| 6789 | 6850 | |
| @@ -978,8 +978,7 @@ static void memory_bm_recycle(struct memory_bitmap *bm) · 977 unmodified lines | ||
| 978 | 978 | * Register a range of page frames the contents of which should not be saved |
| 979 | 979 | * during hibernation (to be used in the early initialization code). |
| 980 | 980 | */ |
| 981 | −void __init __register_nosave_region(unsigned long start_pfn, | |
| 982 | − unsigned long end_pfn, int use_kmalloc) | |
| 981 | +void __init register_nosave_region(unsigned long start_pfn, unsigned long end_pfn) | |
| 983 | 982 | { |
| 984 | 983 | struct nosave_region *region; |
| 985 | 984 | |
| @@ -995,18 +994,12 @@ void __init __register_nosave_region(unsigned long start_pfn, · 9 unmodified lines | ||
| 995 | 994 | goto Report; |
| 996 | 995 | } |
| 997 | 996 | } |
| 998 | − if (use_kmalloc) { | |
| 999 | − /* During init, this shouldn't fail */ | |
| 1000 | − region = kmalloc(sizeof(struct nosave_region), GFP_KERNEL); | |
| 1001 | − BUG_ON(!region); | |
| 1002 | − } else { | |
| 1003 | − /* This allocation cannot fail */ | |
| 1004 | − region = memblock_alloc(sizeof(struct nosave_region), | |
| 1005 | − SMP_CACHE_BYTES); | |
| 1006 | − if (!region) | |
| 1007 | − panic("%s: Failed to allocate %zu bytes\n", __func__, | |
| 1008 | − sizeof(struct nosave_region)); | |
| 1009 | − } | |
| 997 | + /* This allocation cannot fail */ | |
| 998 | + region = memblock_alloc(sizeof(struct nosave_region), | |
| 999 | + SMP_CACHE_BYTES); | |
| 1000 | + if (!region) | |
| 1001 | + panic("%s: Failed to allocate %zu bytes\n", __func__, | |
| 1002 | + sizeof(struct nosave_region)); | |
| 1010 | 1003 | region->start_pfn = start_pfn; |
| 1011 | 1004 | region->end_pfn = end_pfn; |
| 1012 | 1005 | list_add_tail(®ion->list, &nosave_regions); |
| @@ -39,23 +39,20 @@ ssize_t pm_show_wakelocks(char *buf, bool show_active) · 38 unmodified lines | ||
| 39 | 39 | { |
| 40 | 40 | struct rb_node *node; |
| 41 | 41 | struct wakelock *wl; |
| 42 | − char *str = buf; | |
| 43 | − char *end = buf + PAGE_SIZE; | |
| 42 | + int len = 0; | |
| 44 | 43 | |
| 45 | 44 | mutex_lock(&wakelocks_lock); |
| 46 | 45 | |
| 47 | 46 | for (node = rb_first(&wakelocks_tree); node; node = rb_next(node)) { |
| 48 | 47 | wl = rb_entry(node, struct wakelock, node); |
| 49 | 48 | if (wl->ws->active == show_active) |
| 50 | − str += scnprintf(str, end - str, "%s ", wl->name); | |
| 49 | + len += sysfs_emit_at(buf, len, "%s ", wl->name); | |
| 51 | 50 | } |
| 52 | − if (str > buf) | |
| 53 | − str--; | |
| 54 | 51 | |
| 55 | − str += scnprintf(str, end - str, "\n"); | |
| 52 | + len += sysfs_emit_at(buf, len, "\n"); | |
| 56 | 53 | |
| 57 | 54 | mutex_unlock(&wakelocks_lock); |
| 58 | − return (str - buf); | |
| 55 | + return len; | |
| 59 | 56 | } |
| 60 | 57 | |
| 61 | 58 | #if CONFIG_PM_WAKELOCKS_LIMIT > 0 |
| @@ -123,7 +123,7 @@ static struct rcu_tasks rt_name = \ · 122 unmodified lines | ||
| 123 | 123 | .call_func = call, \ |
| 124 | 124 | .rtpcpu = &rt_name ## __percpu, \ |
| 125 | 125 | .name = n, \ |
| 126 | − .percpu_enqueue_shift = ilog2(CONFIG_NR_CPUS), \ | |
| 126 | + .percpu_enqueue_shift = ilog2(CONFIG_NR_CPUS) + 1, \ | |
| 127 | 127 | .percpu_enqueue_lim = 1, \ |
| 128 | 128 | .percpu_dequeue_lim = 1, \ |
| 129 | 129 | .barrier_q_mutex = __MUTEX_INITIALIZER(rt_name.barrier_q_mutex), \ |
| @@ -216,6 +216,7 @@ static void cblist_init_generic(struct rcu_tasks *rtp) · 86 unmodified lines | ||
| 216 | 216 | int cpu; |
| 217 | 217 | unsigned long flags; |
| 218 | 218 | int lim; |
| 219 | + int shift; | |
| 219 | 220 | |
| 220 | 221 | raw_spin_lock_irqsave(&rtp->cbs_gbl_lock, flags); |
| 221 | 222 | if (rcu_task_enqueue_lim < 0) { |
| @@ -229,7 +230,10 @@ static void cblist_init_generic(struct rcu_tasks *rtp) · 7 unmodified lines | ||
| 229 | 230 | |
| 230 | 231 | if (lim > nr_cpu_ids) |
| 231 | 232 | lim = nr_cpu_ids; |
| 232 | − WRITE_ONCE(rtp->percpu_enqueue_shift, ilog2(nr_cpu_ids / lim)); | |
| 233 | + shift = ilog2(nr_cpu_ids / lim); | |
| 234 | + if (((nr_cpu_ids - 1) >> shift) >= lim) | |
| 235 | + shift++; | |
| 236 | + WRITE_ONCE(rtp->percpu_enqueue_shift, shift); | |
| 233 | 237 | WRITE_ONCE(rtp->percpu_dequeue_lim, lim); |
| 234 | 238 | smp_store_release(&rtp->percpu_enqueue_lim, lim); |
| 235 | 239 | for_each_possible_cpu(cpu) { |
| @@ -298,7 +302,7 @@ static void call_rcu_tasks_generic(struct rcu_head *rhp, rcu_callback_t func, · 62 unmodified lines | ||
| 298 | 302 | if (unlikely(needadjust)) { |
| 299 | 303 | raw_spin_lock_irqsave(&rtp->cbs_gbl_lock, flags); |
| 300 | 304 | if (rtp->percpu_enqueue_lim != nr_cpu_ids) { |
| 301 | − WRITE_ONCE(rtp->percpu_enqueue_shift, ilog2(nr_cpu_ids)); | |
| 305 | + WRITE_ONCE(rtp->percpu_enqueue_shift, ilog2(nr_cpu_ids) + 1); | |
| 302 | 306 | WRITE_ONCE(rtp->percpu_dequeue_lim, nr_cpu_ids); |
| 303 | 307 | smp_store_release(&rtp->percpu_enqueue_lim, nr_cpu_ids); |
| 304 | 308 | pr_info("Switching %s to per-CPU callback queuing.\n", rtp->name); |
| @@ -413,7 +417,7 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp) · 108 unmodified lines | ||
| 413 | 417 | if (rcu_task_cb_adjust && ncbs <= rcu_task_collapse_lim) { |
| 414 | 418 | raw_spin_lock_irqsave(&rtp->cbs_gbl_lock, flags); |
| 415 | 419 | if (rtp->percpu_enqueue_lim > 1) { |
| 416 | − WRITE_ONCE(rtp->percpu_enqueue_shift, ilog2(nr_cpu_ids)); | |
| 420 | + WRITE_ONCE(rtp->percpu_enqueue_shift, ilog2(nr_cpu_ids) + 1); | |
| 417 | 421 | smp_store_release(&rtp->percpu_enqueue_lim, 1); |
| 418 | 422 | rtp->percpu_dequeue_gpseq = get_state_synchronize_rcu(); |
| 419 | 423 | pr_info("Starting switch %s to CPU-0 callback queuing.\n", rtp->name); |
| @@ -5822,8 +5822,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) · 5821 unmodified lines | ||
| 5822 | 5822 | } |
| 5823 | 5823 | |
| 5824 | 5824 | if (schedstat_enabled() && rq->core->core_forceidle_count) { |
| 5825 | − if (cookie) | |
| 5826 | − rq->core->core_forceidle_start = rq_clock(rq->core); | |
| 5825 | + rq->core->core_forceidle_start = rq_clock(rq->core); | |
| 5827 | 5826 | rq->core->core_forceidle_occupation = occ; |
| 5828 | 5827 | } |
| 5829 | 5828 | |
| @@ -8219,9 +8218,7 @@ int __cond_resched_lock(spinlock_t *lock) · 2389 unmodified lines | ||
| 8219 | 8218 | |
| 8220 | 8219 | if (spin_needbreak(lock) || resched) { |
| 8221 | 8220 | spin_unlock(lock); |
| 8222 | − if (resched) | |
| 8223 | − preempt_schedule_common(); | |
| 8224 | − else | |
| 8221 | + if (!_cond_resched()) | |
| 8225 | 8222 | cpu_relax(); |
| 8226 | 8223 | ret = 1; |
| 8227 | 8224 | spin_lock(lock); |
| @@ -8239,9 +8236,7 @@ int __cond_resched_rwlock_read(rwlock_t *lock) · 11 unmodified lines | ||
| 8239 | 8236 | |
| 8240 | 8237 | if (rwlock_needbreak(lock) || resched) { |
| 8241 | 8238 | read_unlock(lock); |
| 8242 | − if (resched) | |
| 8243 | − preempt_schedule_common(); | |
| 8244 | − else | |
| 8239 | + if (!_cond_resched()) | |
| 8245 | 8240 | cpu_relax(); |
| 8246 | 8241 | ret = 1; |
| 8247 | 8242 | read_lock(lock); |
| @@ -8259,9 +8254,7 @@ int __cond_resched_rwlock_write(rwlock_t *lock) · 11 unmodified lines | ||
| 8259 | 8254 | |
| 8260 | 8255 | if (rwlock_needbreak(lock) || resched) { |
| 8261 | 8256 | write_unlock(lock); |
| 8262 | − if (resched) | |
| 8263 | − preempt_schedule_common(); | |
| 8264 | − else | |
| 8257 | + if (!_cond_resched()) | |
| 8265 | 8258 | cpu_relax(); |
| 8266 | 8259 | ret = 1; |
| 8267 | 8260 | write_lock(lock); |
| @@ -277,7 +277,7 @@ void __sched_core_account_forceidle(struct rq *rq) · 276 unmodified lines | ||
| 277 | 277 | rq_i = cpu_rq(i); |
| 278 | 278 | p = rq_i->core_pick ?: rq_i->curr; |
| 279 | 279 | |
| 280 | − if (!p->core_cookie) | |
| 280 | + if (p == rq_i->idle) | |
| 281 | 281 | continue; |
| 282 | 282 | |
| 283 | 283 | __schedstat_add(p->stats.core_forceidle_sum, delta); |
| @@ -3028,9 +3028,11 @@ enqueue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) · 3027 unmodified lines | ||
| 3028 | 3028 | static inline void |
| 3029 | 3029 | dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 3030 | 3030 | { |
| 3031 | − u32 divider = get_pelt_divider(&se->avg); | |
| 3032 | 3031 | sub_positive(&cfs_rq->avg.load_avg, se->avg.load_avg); |
| 3033 | − cfs_rq->avg.load_sum = cfs_rq->avg.load_avg * divider; | |
| 3032 | + sub_positive(&cfs_rq->avg.load_sum, se_weight(se) * se->avg.load_sum); | |
| 3033 | + /* See update_cfs_rq_load_avg() */ | |
| 3034 | + cfs_rq->avg.load_sum = max_t(u32, cfs_rq->avg.load_sum, | |
| 3035 | + cfs_rq->avg.load_avg * PELT_MIN_DIVIDER); | |
| 3034 | 3036 | } |
| 3035 | 3037 | #else |
| 3036 | 3038 | static inline void |
| @@ -3381,7 +3383,6 @@ void set_task_rq_fair(struct sched_entity *se, · 344 unmodified lines | ||
| 3381 | 3383 | se->avg.last_update_time = n_last_update_time; |
| 3382 | 3384 | } |
| 3383 | 3385 | |
| 3384 | − | |
| 3385 | 3386 | /* |
| 3386 | 3387 | * When on migration a sched_entity joins/leaves the PELT hierarchy, we need to |
| 3387 | 3388 | * propagate its contribution. The key to this propagation is the invariant |
| @@ -3449,15 +3450,14 @@ void set_task_rq_fair(struct sched_entity *se, · 61 unmodified lines | ||
| 3449 | 3450 | * XXX: only do this for the part of runnable > running ? |
| 3450 | 3451 | * |
| 3451 | 3452 | */ |
| 3452 | − | |
| 3453 | 3453 | static inline void |
| 3454 | 3454 | update_tg_cfs_util(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq *gcfs_rq) |
| 3455 | 3455 | { |
| 3456 | − long delta = gcfs_rq->avg.util_avg - se->avg.util_avg; | |
| 3457 | − u32 divider; | |
| 3456 | + long delta_sum, delta_avg = gcfs_rq->avg.util_avg - se->avg.util_avg; | |
| 3457 | + u32 new_sum, divider; | |
| 3458 | 3458 | |
| 3459 | 3459 | /* Nothing to update */ |
| 3460 | − if (!delta) | |
| 3460 | + if (!delta_avg) | |
| 3461 | 3461 | return; |
| 3462 | 3462 | |
| 3463 | 3463 | /* |
| @@ -3466,23 +3466,30 @@ update_tg_cfs_util(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq · 2 unmodified lines | ||
| 3466 | 3466 | */ |
| 3467 | 3467 | divider = get_pelt_divider(&cfs_rq->avg); |
| 3468 | 3468 | |
| 3469 | + | |
| 3469 | 3470 | /* Set new sched_entity's utilization */ |
| 3470 | 3471 | se->avg.util_avg = gcfs_rq->avg.util_avg; |
| 3471 | − se->avg.util_sum = se->avg.util_avg * divider; | |
| 3472 | + new_sum = se->avg.util_avg * divider; | |
| 3473 | + delta_sum = (long)new_sum - (long)se->avg.util_sum; | |
| 3474 | + se->avg.util_sum = new_sum; | |
| 3472 | 3475 | |
| 3473 | 3476 | /* Update parent cfs_rq utilization */ |
| 3474 | − add_positive(&cfs_rq->avg.util_avg, delta); | |
| 3475 | − cfs_rq->avg.util_sum = cfs_rq->avg.util_avg * divider; | |
| 3477 | + add_positive(&cfs_rq->avg.util_avg, delta_avg); | |
| 3478 | + add_positive(&cfs_rq->avg.util_sum, delta_sum); | |
| 3479 | + | |
| 3480 | + /* See update_cfs_rq_load_avg() */ | |
| 3481 | + cfs_rq->avg.util_sum = max_t(u32, cfs_rq->avg.util_sum, | |
| 3482 | + cfs_rq->avg.util_avg * PELT_MIN_DIVIDER); | |
| 3476 | 3483 | } |
| 3477 | 3484 | |
| 3478 | 3485 | static inline void |
| 3479 | 3486 | update_tg_cfs_runnable(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq *gcfs_rq) |
| 3480 | 3487 | { |
| 3481 | − long delta = gcfs_rq->avg.runnable_avg - se->avg.runnable_avg; | |
| 3482 | − u32 divider; | |
| 3488 | + long delta_sum, delta_avg = gcfs_rq->avg.runnable_avg - se->avg.runnable_avg; | |
| 3489 | + u32 new_sum, divider; | |
| 3483 | 3490 | |
| 3484 | 3491 | /* Nothing to update */ |
| 3485 | − if (!delta) | |
| 3492 | + if (!delta_avg) | |
| 3486 | 3493 | return; |
| 3487 | 3494 | |
| 3488 | 3495 | /* |
| @@ -3493,19 +3500,25 @@ update_tg_cfs_runnable(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cf · 4 unmodified lines | ||
| 3493 | 3500 | |
| 3494 | 3501 | /* Set new sched_entity's runnable */ |
| 3495 | 3502 | se->avg.runnable_avg = gcfs_rq->avg.runnable_avg; |
| 3496 | − se->avg.runnable_sum = se->avg.runnable_avg * divider; | |
| 3503 | + new_sum = se->avg.runnable_avg * divider; | |
| 3504 | + delta_sum = (long)new_sum - (long)se->avg.runnable_sum; | |
| 3505 | + se->avg.runnable_sum = new_sum; | |
| 3497 | 3506 | |
| 3498 | 3507 | /* Update parent cfs_rq runnable */ |
| 3499 | − add_positive(&cfs_rq->avg.runnable_avg, delta); | |
| 3500 | − cfs_rq->avg.runnable_sum = cfs_rq->avg.runnable_avg * divider; | |
| 3508 | + add_positive(&cfs_rq->avg.runnable_avg, delta_avg); | |
| 3509 | + add_positive(&cfs_rq->avg.runnable_sum, delta_sum); | |
| 3510 | + /* See update_cfs_rq_load_avg() */ | |
| 3511 | + cfs_rq->avg.runnable_sum = max_t(u32, cfs_rq->avg.runnable_sum, | |
| 3512 | + cfs_rq->avg.runnable_avg * PELT_MIN_DIVIDER); | |
| 3501 | 3513 | } |
| 3502 | 3514 | |
| 3503 | 3515 | static inline void |
| 3504 | 3516 | update_tg_cfs_load(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq *gcfs_rq) |
| 3505 | 3517 | { |
| 3506 | − long delta, running_sum, runnable_sum = gcfs_rq->prop_runnable_sum; | |
| 3518 | + long delta_avg, running_sum, runnable_sum = gcfs_rq->prop_runnable_sum; | |
| 3507 | 3519 | unsigned long load_avg; |
| 3508 | 3520 | u64 load_sum = 0; |
| 3521 | + s64 delta_sum; | |
| 3509 | 3522 | u32 divider; |
| 3510 | 3523 | |
| 3511 | 3524 | if (!runnable_sum) |
| @@ -3532,7 +3545,7 @@ update_tg_cfs_load(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq · 20 unmodified lines | ||
| 3532 | 3545 | * assuming all tasks are equally runnable. |
| 3533 | 3546 | */ |
| 3534 | 3547 | if (scale_load_down(gcfs_rq->load.weight)) { |
| 3535 | − load_sum = div_s64(gcfs_rq->avg.load_sum, | |
| 3548 | + load_sum = div_u64(gcfs_rq->avg.load_sum, | |
| 3536 | 3549 | scale_load_down(gcfs_rq->load.weight)); |
| 3537 | 3550 | } |
| 3538 | 3551 | |
| @@ -3549,19 +3562,22 @@ update_tg_cfs_load(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq · 10 unmodified lines | ||
| 3549 | 3562 | running_sum = se->avg.util_sum >> SCHED_CAPACITY_SHIFT; |
| 3550 | 3563 | runnable_sum = max(runnable_sum, running_sum); |
| 3551 | 3564 | |
| 3552 | − load_sum = (s64)se_weight(se) * runnable_sum; | |
| 3553 | − load_avg = div_s64(load_sum, divider); | |
| 3554 | − | |
| 3555 | − se->avg.load_sum = runnable_sum; | |
| 3565 | + load_sum = se_weight(se) * runnable_sum; | |
| 3566 | + load_avg = div_u64(load_sum, divider); | |
| 3556 | 3567 | |
| 3557 | − delta = load_avg - se->avg.load_avg; | |
| 3558 | − if (!delta) | |
| 3568 | + delta_avg = load_avg - se->avg.load_avg; | |
| 3569 | + if (!delta_avg) | |
| 3559 | 3570 | return; |
| 3560 | 3571 | |
| 3561 | − se->avg.load_avg = load_avg; | |
| 3572 | + delta_sum = load_sum - (s64)se_weight(se) * se->avg.load_sum; | |
| 3562 | 3573 | |
| 3563 | − add_positive(&cfs_rq->avg.load_avg, delta); | |
| 3564 | − cfs_rq->avg.load_sum = cfs_rq->avg.load_avg * divider; | |
| 3574 | + se->avg.load_sum = runnable_sum; | |
| 3575 | + se->avg.load_avg = load_avg; | |
| 3576 | + add_positive(&cfs_rq->avg.load_avg, delta_avg); | |
| 3577 | + add_positive(&cfs_rq->avg.load_sum, delta_sum); | |
| 3578 | + /* See update_cfs_rq_load_avg() */ | |
| 3579 | + cfs_rq->avg.load_sum = max_t(u32, cfs_rq->avg.load_sum, | |
| 3580 | + cfs_rq->avg.load_avg * PELT_MIN_DIVIDER); | |
| 3565 | 3581 | } |
| 3566 | 3582 | |
| 3567 | 3583 | static inline void add_tg_cfs_propagate(struct cfs_rq *cfs_rq, long runnable_sum) |
| @@ -3652,7 +3668,7 @@ static inline void add_tg_cfs_propagate(struct cfs_rq *cfs_rq, long runnable_sum · 84 unmodified lines | ||
| 3652 | 3668 | * |
| 3653 | 3669 | * cfs_rq->avg is used for task_h_load() and update_cfs_share() for example. |
| 3654 | 3670 | * |
| 3655 | − * Returns true if the load decayed or we removed load. | |
| 3671 | + * Return: true if the load decayed or we removed load. | |
| 3656 | 3672 | * |
| 3657 | 3673 | * Since both these conditions indicate a changed cfs_rq->avg.load we should |
| 3658 | 3674 | * call update_tg_load_avg() when this function returns true. |
| @@ -3677,15 +3693,32 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) · 18 unmodified lines | ||
| 3677 | 3693 | |
| 3678 | 3694 | r = removed_load; |
| 3679 | 3695 | sub_positive(&sa->load_avg, r); |
| 3680 | − sa->load_sum = sa->load_avg * divider; | |
| 3696 | + sub_positive(&sa->load_sum, r * divider); | |
| 3697 | + /* See sa->util_sum below */ | |
| 3698 | + sa->load_sum = max_t(u32, sa->load_sum, sa->load_avg * PELT_MIN_DIVIDER); | |
| 3681 | 3699 | |
| 3682 | 3700 | r = removed_util; |
| 3683 | 3701 | sub_positive(&sa->util_avg, r); |
| 3684 | − sa->util_sum = sa->util_avg * divider; | |
| 3702 | + sub_positive(&sa->util_sum, r * divider); | |
| 3703 | + /* | |
| 3704 | + * Because of rounding, se->util_sum might ends up being +1 more than | |
| 3705 | + * cfs->util_sum. Although this is not a problem by itself, detaching | |
| 3706 | + * a lot of tasks with the rounding problem between 2 updates of | |
| 3707 | + * util_avg (~1ms) can make cfs->util_sum becoming null whereas | |
| 3708 | + * cfs_util_avg is not. | |
| 3709 | + * Check that util_sum is still above its lower bound for the new | |
| 3710 | + * util_avg. Given that period_contrib might have moved since the last | |
| 3711 | + * sync, we are only sure that util_sum must be above or equal to | |
| 3712 | + * util_avg * minimum possible divider | |
| 3713 | + */ | |
| 3714 | + sa->util_sum = max_t(u32, sa->util_sum, sa->util_avg * PELT_MIN_DIVIDER); | |
| 3685 | 3715 | |
| 3686 | 3716 | r = removed_runnable; |
| 3687 | 3717 | sub_positive(&sa->runnable_avg, r); |
| 3688 | − sa->runnable_sum = sa->runnable_avg * divider; | |
| 3718 | + sub_positive(&sa->runnable_sum, r * divider); | |
| 3719 | + /* See sa->util_sum above */ | |
| 3720 | + sa->runnable_sum = max_t(u32, sa->runnable_sum, | |
| 3721 | + sa->runnable_avg * PELT_MIN_DIVIDER); | |
| 3689 | 3722 | |
| 3690 | 3723 | /* |
| 3691 | 3724 | * removed_runnable is the unweighted version of removed_load so we |
| @@ -3772,17 +3805,18 @@ static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s · 80 unmodified lines | ||
| 3772 | 3805 | */ |
| 3773 | 3806 | static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 3774 | 3807 | { |
| 3775 | − /* | |
| 3776 | − * cfs_rq->avg.period_contrib can be used for both cfs_rq and se. | |
| 3777 | − * See ___update_load_avg() for details. | |
| 3778 | − */ | |
| 3779 | − u32 divider = get_pelt_divider(&cfs_rq->avg); | |
| 3780 | − | |
| 3781 | 3808 | dequeue_load_avg(cfs_rq, se); |
| 3782 | 3809 | sub_positive(&cfs_rq->avg.util_avg, se->avg.util_avg); |
| 3783 | − cfs_rq->avg.util_sum = cfs_rq->avg.util_avg * divider; | |
| 3810 | + sub_positive(&cfs_rq->avg.util_sum, se->avg.util_sum); | |
| 3811 | + /* See update_cfs_rq_load_avg() */ | |
| 3812 | + cfs_rq->avg.util_sum = max_t(u32, cfs_rq->avg.util_sum, | |
| 3813 | + cfs_rq->avg.util_avg * PELT_MIN_DIVIDER); | |
| 3814 | + | |
| 3784 | 3815 | sub_positive(&cfs_rq->avg.runnable_avg, se->avg.runnable_avg); |
| 3785 | − cfs_rq->avg.runnable_sum = cfs_rq->avg.runnable_avg * divider; | |
| 3816 | + sub_positive(&cfs_rq->avg.runnable_sum, se->avg.runnable_sum); | |
| 3817 | + /* See update_cfs_rq_load_avg() */ | |
| 3818 | + cfs_rq->avg.runnable_sum = max_t(u32, cfs_rq->avg.runnable_sum, | |
| 3819 | + cfs_rq->avg.runnable_avg * PELT_MIN_DIVIDER); | |
| 3786 | 3820 | |
| 3787 | 3821 | add_tg_cfs_propagate(cfs_rq, -se->avg.load_sum); |
| 3788 | 3822 | |
| @@ -8539,6 +8573,8 @@ group_type group_classify(unsigned int imbalance_pct, · 4750 unmodified lines | ||
| 8539 | 8573 | * |
| 8540 | 8574 | * If @sg does not have SMT siblings, only pull tasks if all of the SMT siblings |
| 8541 | 8575 | * of @dst_cpu are idle and @sg has lower priority. |
| 8576 | + * | |
| 8577 | + * Return: true if @dst_cpu can pull tasks, false otherwise. | |
| 8542 | 8578 | */ |
| 8543 | 8579 | static bool asym_smt_can_pull_tasks(int dst_cpu, struct sd_lb_stats *sds, |
| 8544 | 8580 | struct sg_lb_stats *sgs, |
| @@ -8614,6 +8650,7 @@ sched_asym(struct lb_env *env, struct sd_lb_stats *sds, struct sg_lb_stats *sgs · 69 unmodified lines | ||
| 8614 | 8650 | /** |
| 8615 | 8651 | * update_sg_lb_stats - Update sched_group's statistics for load balancing. |
| 8616 | 8652 | * @env: The load balancing environment. |
| 8653 | + * @sds: Load-balancing data with statistics of the local group. | |
| 8617 | 8654 | * @group: sched_group whose statistics are to be updated. |
| 8618 | 8655 | * @sgs: variable to hold the statistics for this group. |
| 8619 | 8656 | * @sg_status: Holds flag indicating the status of the sched_group |
| @@ -9421,12 +9458,11 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s · 801 unmodified lines | ||
| 9421 | 9458 | /** |
| 9422 | 9459 | * find_busiest_group - Returns the busiest group within the sched_domain |
| 9423 | 9460 | * if there is an imbalance. |
| 9461 | + * @env: The load balancing environment. | |
| 9424 | 9462 | * |
| 9425 | 9463 | * Also calculates the amount of runnable load which should be moved |
| 9426 | 9464 | * to restore balance. |
| 9427 | 9465 | * |
| 9428 | − * @env: The load balancing environment. | |
| 9429 | − * | |
| 9430 | 9466 | * Return: - The busiest group if imbalance exists. |
| 9431 | 9467 | */ |
| 9432 | 9468 | static struct sched_group *find_busiest_group(struct lb_env *env) |
| @@ -147,11 +147,11 @@ · 146 unmodified lines | ||
| 147 | 147 | #endif |
| 148 | 148 | |
| 149 | 149 | #ifdef CONFIG_RSEQ |
| 150 | −#define MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ_BITMASK \ | |
| 150 | +#define MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK \ | |
| 151 | 151 | (MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ \ |
| 152 | − | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ_BITMASK) | |
| 152 | + | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ) | |
| 153 | 153 | #else |
| 154 | −#define MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ_BITMASK 0 | |
| 154 | +#define MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK 0 | |
| 155 | 155 | #endif |
| 156 | 156 | |
| 157 | 157 | #define MEMBARRIER_CMD_BITMASK \ |
| @@ -159,7 +159,8 @@ · 1 unmodified line | ||
| 159 | 159 | | MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED \ |
| 160 | 160 | | MEMBARRIER_CMD_PRIVATE_EXPEDITED \ |
| 161 | 161 | | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED \ |
| 162 | − | MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK) | |
| 162 | + | MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK \ | |
| 163 | + | MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK) | |
| 163 | 164 | |
| 164 | 165 | static void ipi_mb(void *info) |
| 165 | 166 | { |
| @@ -37,9 +37,11 @@ update_irq_load_avg(struct rq *rq, u64 running) · 36 unmodified lines | ||
| 37 | 37 | } |
| 38 | 38 | #endif |
| 39 | 39 | |
| 40 | +#define PELT_MIN_DIVIDER (LOAD_AVG_MAX - 1024) | |
| 41 | + | |
| 40 | 42 | static inline u32 get_pelt_divider(struct sched_avg *avg) |
| 41 | 43 | { |
| 42 | − return LOAD_AVG_MAX - 1024 + avg->period_contrib; | |
| 44 | + return PELT_MIN_DIVIDER + avg->period_contrib; | |
| 43 | 45 | } |
| 44 | 46 | |
| 45 | 47 | static inline void cfs_se_util_change(struct sched_avg *avg) |
| @@ -1082,44 +1082,6 @@ int psi_show(struct seq_file *m, struct psi_group *group, enum psi_res res) · 1081 unmodified lines | ||
| 1082 | 1082 | return 0; |
| 1083 | 1083 | } |
| 1084 | 1084 | |
| 1085 | −static int psi_io_show(struct seq_file *m, void *v) | |
| 1086 | −{ | |
| 1087 | − return psi_show(m, &psi_system, PSI_IO); | |
| 1088 | −} | |
| 1089 | − | |
| 1090 | −static int psi_memory_show(struct seq_file *m, void *v) | |
| 1091 | −{ | |
| 1092 | − return psi_show(m, &psi_system, PSI_MEM); | |
| 1093 | −} | |
| 1094 | − | |
| 1095 | −static int psi_cpu_show(struct seq_file *m, void *v) | |
| 1096 | −{ | |
| 1097 | − return psi_show(m, &psi_system, PSI_CPU); | |
| 1098 | −} | |
| 1099 | − | |
| 1100 | −static int psi_open(struct file *file, int (*psi_show)(struct seq_file *, void *)) | |
| 1101 | −{ | |
| 1102 | − if (file->f_mode & FMODE_WRITE && !capable(CAP_SYS_RESOURCE)) | |
| 1103 | − return -EPERM; | |
| 1104 | − | |
| 1105 | − return single_open(file, psi_show, NULL); | |
| 1106 | −} | |
| 1107 | − | |
| 1108 | −static int psi_io_open(struct inode *inode, struct file *file) | |
| 1109 | −{ | |
| 1110 | − return psi_open(file, psi_io_show); | |
| 1111 | −} | |
| 1112 | − | |
| 1113 | −static int psi_memory_open(struct inode *inode, struct file *file) | |
| 1114 | −{ | |
| 1115 | − return psi_open(file, psi_memory_show); | |
| 1116 | −} | |
| 1117 | − | |
| 1118 | −static int psi_cpu_open(struct inode *inode, struct file *file) | |
| 1119 | −{ | |
| 1120 | − return psi_open(file, psi_cpu_show); | |
| 1121 | −} | |
| 1122 | − | |
| 1123 | 1085 | struct psi_trigger *psi_trigger_create(struct psi_group *group, |
| 1124 | 1086 | char *buf, size_t nbytes, enum psi_res res) |
| 1125 | 1087 | { |
| @@ -1162,7 +1124,6 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, · 36 unmodified lines | ||
| 1162 | 1124 | t->event = 0; |
| 1163 | 1125 | t->last_event_time = 0; |
| 1164 | 1126 | init_waitqueue_head(&t->event_wait); |
| 1165 | − kref_init(&t->refcount); | |
| 1166 | 1127 | |
| 1167 | 1128 | mutex_lock(&group->trigger_lock); |
| 1168 | 1129 | |
| @@ -1191,15 +1152,19 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, · 22 unmodified lines | ||
| 1191 | 1152 | return t; |
| 1192 | 1153 | } |
| 1193 | 1154 | |
| 1194 | −static void psi_trigger_destroy(struct kref *ref) | |
| 1155 | +void psi_trigger_destroy(struct psi_trigger *t) | |
| 1195 | 1156 | { |
| 1196 | − struct psi_trigger *t = container_of(ref, struct psi_trigger, refcount); | |
| 1197 | − struct psi_group *group = t->group; | |
| 1157 | + struct psi_group *group; | |
| 1198 | 1158 | struct task_struct *task_to_destroy = NULL; |
| 1199 | 1159 | |
| 1200 | − if (static_branch_likely(&psi_disabled)) | |
| 1160 | + /* | |
| 1161 | + * We do not check psi_disabled since it might have been disabled after | |
| 1162 | + * the trigger got created. | |
| 1163 | + */ | |
| 1164 | + if (!t) | |
| 1201 | 1165 | return; |
| 1202 | 1166 | |
| 1167 | + group = t->group; | |
| 1203 | 1168 | /* |
| 1204 | 1169 | * Wakeup waiters to stop polling. Can happen if cgroup is deleted |
| 1205 | 1170 | * from under a polling process. |
| @@ -1235,9 +1200,9 @@ static void psi_trigger_destroy(struct kref *ref) · 29 unmodified lines | ||
| 1235 | 1200 | mutex_unlock(&group->trigger_lock); |
| 1236 | 1201 | |
| 1237 | 1202 | /* |
| 1238 | − * Wait for both *trigger_ptr from psi_trigger_replace and | |
| 1239 | − * poll_task RCUs to complete their read-side critical sections | |
| 1240 | − * before destroying the trigger and optionally the poll_task | |
| 1203 | + * Wait for psi_schedule_poll_work RCU to complete its read-side | |
| 1204 | + * critical section before destroying the trigger and optionally the | |
| 1205 | + * poll_task. | |
| 1241 | 1206 | */ |
| 1242 | 1207 | synchronize_rcu(); |
| 1243 | 1208 | /* |
| @@ -1254,18 +1219,6 @@ static void psi_trigger_destroy(struct kref *ref) · 10 unmodified lines | ||
| 1254 | 1219 | kfree(t); |
| 1255 | 1220 | } |
| 1256 | 1221 | |
| 1257 | −void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *new) | |
| 1258 | −{ | |
| 1259 | − struct psi_trigger *old = *trigger_ptr; | |
| 1260 | − | |
| 1261 | − if (static_branch_likely(&psi_disabled)) | |
| 1262 | − return; | |
| 1263 | − | |
| 1264 | − rcu_assign_pointer(*trigger_ptr, new); | |
| 1265 | − if (old) | |
| 1266 | − kref_put(&old->refcount, psi_trigger_destroy); | |
| 1267 | −} | |
| 1268 | − | |
| 1269 | 1222 | __poll_t psi_trigger_poll(void **trigger_ptr, |
| 1270 | 1223 | struct file *file, poll_table *wait) |
| 1271 | 1224 | { |
| @@ -1275,27 +1228,57 @@ __poll_t psi_trigger_poll(void **trigger_ptr, · 3 unmodified lines | ||
| 1275 | 1228 | if (static_branch_likely(&psi_disabled)) |
| 1276 | 1229 | return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; |
| 1277 | 1230 | |
| 1278 | − rcu_read_lock(); | |
| 1279 | − | |
| 1280 | − t = rcu_dereference(*(void __rcu __force **)trigger_ptr); | |
| 1281 | − if (!t) { | |
| 1282 | − rcu_read_unlock(); | |
| 1231 | + t = smp_load_acquire(trigger_ptr); | |
| 1232 | + if (!t) | |
| 1283 | 1233 | return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; |
| 1284 | − } | |
| 1285 | − kref_get(&t->refcount); | |
| 1286 | − | |
| 1287 | − rcu_read_unlock(); | |
| 1288 | 1234 | |
| 1289 | 1235 | poll_wait(file, &t->event_wait, wait); |
| 1290 | 1236 | |
| 1291 | 1237 | if (cmpxchg(&t->event, 1, 0) == 1) |
| 1292 | 1238 | ret |= EPOLLPRI; |
| 1293 | 1239 | |
| 1294 | − kref_put(&t->refcount, psi_trigger_destroy); | |
| 1295 | − | |
| 1296 | 1240 | return ret; |
| 1297 | 1241 | } |
| 1298 | 1242 | |
| 1243 | +#ifdef CONFIG_PROC_FS | |
| 1244 | +static int psi_io_show(struct seq_file *m, void *v) | |
| 1245 | +{ | |
| 1246 | + return psi_show(m, &psi_system, PSI_IO); | |
| 1247 | +} | |
| 1248 | + | |
| 1249 | +static int psi_memory_show(struct seq_file *m, void *v) | |
| 1250 | +{ | |
| 1251 | + return psi_show(m, &psi_system, PSI_MEM); | |
| 1252 | +} | |
| 1253 | + | |
| 1254 | +static int psi_cpu_show(struct seq_file *m, void *v) | |
| 1255 | +{ | |
| 1256 | + return psi_show(m, &psi_system, PSI_CPU); | |
| 1257 | +} | |
| 1258 | + | |
| 1259 | +static int psi_open(struct file *file, int (*psi_show)(struct seq_file *, void *)) | |
| 1260 | +{ | |
| 1261 | + if (file->f_mode & FMODE_WRITE && !capable(CAP_SYS_RESOURCE)) | |
| 1262 | + return -EPERM; | |
| 1263 | + | |
| 1264 | + return single_open(file, psi_show, NULL); | |
| 1265 | +} | |
| 1266 | + | |
| 1267 | +static int psi_io_open(struct inode *inode, struct file *file) | |
| 1268 | +{ | |
| 1269 | + return psi_open(file, psi_io_show); | |
| 1270 | +} | |
| 1271 | + | |
| 1272 | +static int psi_memory_open(struct inode *inode, struct file *file) | |
| 1273 | +{ | |
| 1274 | + return psi_open(file, psi_memory_show); | |
| 1275 | +} | |
| 1276 | + | |
| 1277 | +static int psi_cpu_open(struct inode *inode, struct file *file) | |
| 1278 | +{ | |
| 1279 | + return psi_open(file, psi_cpu_show); | |
| 1280 | +} | |
| 1281 | + | |
| 1299 | 1282 | static ssize_t psi_write(struct file *file, const char __user *user_buf, |
| 1300 | 1283 | size_t nbytes, enum psi_res res) |
| 1301 | 1284 | { |
| @@ -1316,14 +1299,24 @@ static ssize_t psi_write(struct file *file, const char __user *user_buf, · 14 unmodified lines | ||
| 1316 | 1299 | |
| 1317 | 1300 | buf[buf_size - 1] = '\0'; |
| 1318 | 1301 | |
| 1319 | − new = psi_trigger_create(&psi_system, buf, nbytes, res); | |
| 1320 | − if (IS_ERR(new)) | |
| 1321 | − return PTR_ERR(new); | |
| 1322 | − | |
| 1323 | 1302 | seq = file->private_data; |
| 1303 | + | |
| 1324 | 1304 | /* Take seq->lock to protect seq->private from concurrent writes */ |
| 1325 | 1305 | mutex_lock(&seq->lock); |
| 1326 | − psi_trigger_replace(&seq->private, new); | |
| 1306 | + | |
| 1307 | + /* Allow only one trigger per file descriptor */ | |
| 1308 | + if (seq->private) { | |
| 1309 | + mutex_unlock(&seq->lock); | |
| 1310 | + return -EBUSY; | |
| 1311 | + } | |
| 1312 | + | |
| 1313 | + new = psi_trigger_create(&psi_system, buf, nbytes, res); | |
| 1314 | + if (IS_ERR(new)) { | |
| 1315 | + mutex_unlock(&seq->lock); | |
| 1316 | + return PTR_ERR(new); | |
| 1317 | + } | |
| 1318 | + | |
| 1319 | + smp_store_release(&seq->private, new); | |
| 1327 | 1320 | mutex_unlock(&seq->lock); |
| 1328 | 1321 | |
| 1329 | 1322 | return nbytes; |
| @@ -1358,7 +1351,7 @@ static int psi_fop_release(struct inode *inode, struct file *file) · 28 unmodified lines | ||
| 1358 | 1351 | { |
| 1359 | 1352 | struct seq_file *seq = file->private_data; |
| 1360 | 1353 | |
| 1361 | − psi_trigger_replace(&seq->private, NULL); | |
| 1354 | + psi_trigger_destroy(seq->private); | |
| 1362 | 1355 | return single_release(inode, file); |
| 1363 | 1356 | } |
| 1364 | 1357 | |
| @@ -1400,3 +1393,5 @@ static int __init psi_proc_init(void) · 35 unmodified lines | ||
| 1400 | 1393 | return 0; |
| 1401 | 1394 | } |
| 1402 | 1395 | module_init(psi_proc_init); |
| 1396 | + | |
| 1397 | +#endif /* CONFIG_PROC_FS */ | |
| @@ -70,10 +70,16 @@ config HAVE_C_RECORDMCOUNT · 69 unmodified lines | ||
| 70 | 70 | help |
| 71 | 71 | C version of recordmcount available? |
| 72 | 72 | |
| 73 | +config HAVE_BUILDTIME_MCOUNT_SORT | |
| 74 | + bool | |
| 75 | + help | |
| 76 | + An architecture selects this if it sorts the mcount_loc section | |
| 77 | + at build time. | |
| 78 | + | |
| 73 | 79 | config BUILDTIME_MCOUNT_SORT |
| 74 | 80 | bool |
| 75 | 81 | default y |
| 76 | − depends on BUILDTIME_TABLE_SORT && !S390 | |
| 82 | + depends on HAVE_BUILDTIME_MCOUNT_SORT && DYNAMIC_FTRACE | |
| 77 | 83 | help |
| 78 | 84 | Sort the mcount_loc section at build time. |
| 79 | 85 | |
| @@ -7740,7 +7740,8 @@ static struct tracing_log_err *get_tracing_log_err(struct trace_array *tr) · 7739 unmodified lines | ||
| 7740 | 7740 | err = kzalloc(sizeof(*err), GFP_KERNEL); |
| 7741 | 7741 | if (!err) |
| 7742 | 7742 | err = ERR_PTR(-ENOMEM); |
| 7743 | − tr->n_err_log_entries++; | |
| 7743 | + else | |
| 7744 | + tr->n_err_log_entries++; | |
| 7744 | 7745 | |
| 7745 | 7746 | return err; |
| 7746 | 7747 | } |
| @@ -2503,6 +2503,8 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, · 2502 unmodified lines | ||
| 2503 | 2503 | (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS); |
| 2504 | 2504 | expr->fn = hist_field_unary_minus; |
| 2505 | 2505 | expr->operands[0] = operand1; |
| 2506 | + expr->size = operand1->size; | |
| 2507 | + expr->is_signed = operand1->is_signed; | |
| 2506 | 2508 | expr->operator = FIELD_OP_UNARY_MINUS; |
| 2507 | 2509 | expr->name = expr_str(expr, 0); |
| 2508 | 2510 | expr->type = kstrdup_const(operand1->type, GFP_KERNEL); |
| @@ -2719,6 +2721,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, · 210 unmodified lines | ||
| 2719 | 2721 | |
| 2720 | 2722 | /* The operand sizes should be the same, so just pick one */ |
| 2721 | 2723 | expr->size = operand1->size; |
| 2724 | + expr->is_signed = operand1->is_signed; | |
| 2722 | 2725 | |
| 2723 | 2726 | expr->operator = field_op; |
| 2724 | 2727 | expr->type = kstrdup_const(operand1->type, GFP_KERNEL); |
| @@ -3935,6 +3938,7 @@ static int trace_action_create(struct hist_trigger_data *hist_data, · 1210 unmodified lines | ||
| 3935 | 3938 | |
| 3936 | 3939 | var_ref_idx = find_var_ref_idx(hist_data, var_ref); |
| 3937 | 3940 | if (WARN_ON(var_ref_idx < 0)) { |
| 3941 | + kfree(p); | |
| 3938 | 3942 | ret = var_ref_idx; |
| 3939 | 3943 | goto err; |
| 3940 | 3944 | } |
| @@ -6163,7 +6167,9 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops, · 2222 unmodified lines | ||
| 6163 | 6167 | |
| 6164 | 6168 | lockdep_assert_held(&event_mutex); |
| 6165 | 6169 | |
| 6166 | − if (glob && strlen(glob)) { | |
| 6170 | + WARN_ON(!glob); | |
| 6171 | + | |
| 6172 | + if (strlen(glob)) { | |
| 6167 | 6173 | hist_err_clear(); |
| 6168 | 6174 | last_cmd_set(file, param); |
| 6169 | 6175 | } |
| @@ -6196,7 +6202,7 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops, · 26 unmodified lines | ||
| 6196 | 6202 | continue; |
| 6197 | 6203 | } |
| 6198 | 6204 | break; |
| 6199 | − } while (p); | |
| 6205 | + } while (1); | |
| 6200 | 6206 | |
| 6201 | 6207 | if (!p) |
| 6202 | 6208 | param = NULL; |
| @@ -190,6 +190,7 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) · 189 unmodified lines | ||
| 190 | 190 | kfree(new); |
| 191 | 191 | } else { |
| 192 | 192 | hlist_add_head(&new->node, hashent); |
| 193 | + get_user_ns(new->ns); | |
| 193 | 194 | spin_unlock_irq(&ucounts_lock); |
| 194 | 195 | return new; |
| 195 | 196 | } |
| @@ -210,6 +211,7 @@ void put_ucounts(struct ucounts *ucounts) · 14 unmodified lines | ||
| 210 | 211 | if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) { |
| 211 | 212 | hlist_del_init(&ucounts->node); |
| 212 | 213 | spin_unlock_irqrestore(&ucounts_lock, flags); |
| 214 | + put_user_ns(ucounts->ns); | |
| 213 | 215 | kfree(ucounts); |
| 214 | 216 | } |
| 215 | 217 | } |
| @@ -488,9 +488,13 @@ void sbitmap_queue_recalculate_wake_batch(struct sbitmap_queue *sbq, · 487 unmodified lines | ||
| 488 | 488 | unsigned int users) |
| 489 | 489 | { |
| 490 | 490 | unsigned int wake_batch; |
| 491 | + unsigned int min_batch; | |
| 492 | + unsigned int depth = (sbq->sb.depth + users - 1) / users; | |
| 491 | 493 | |
| 492 | − wake_batch = clamp_val((sbq->sb.depth + users - 1) / | |
| 493 | − users, 4, SBQ_WAKE_BATCH); | |
| 494 | + min_batch = sbq->sb.depth >= (4 * SBQ_WAIT_QUEUES) ? 4 : 1; | |
| 495 | + | |
| 496 | + wake_batch = clamp_val(depth / SBQ_WAIT_QUEUES, | |
| 497 | + min_batch, SBQ_WAKE_BATCH); | |
| 494 | 498 | __sbitmap_queue_update_wake_batch(sbq, wake_batch); |
| 495 | 499 | } |
| 496 | 500 | EXPORT_SYMBOL_GPL(sbitmap_queue_recalculate_wake_batch); |
| @@ -492,6 +492,7 @@ static void kmalloc_oob_in_memset(struct kunit *test) · 491 unmodified lines | ||
| 492 | 492 | ptr = kmalloc(size, GFP_KERNEL); |
| 493 | 493 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 494 | 494 | |
| 495 | + OPTIMIZER_HIDE_VAR(ptr); | |
| 495 | 496 | OPTIMIZER_HIDE_VAR(size); |
| 496 | 497 | KUNIT_EXPECT_KASAN_FAIL(test, |
| 497 | 498 | memset(ptr, 0, size + KASAN_GRANULE_SIZE)); |
| @@ -515,6 +516,7 @@ static void kmalloc_memmove_negative_size(struct kunit *test) · 17 unmodified lines | ||
| 515 | 516 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 516 | 517 | |
| 517 | 518 | memset((char *)ptr, 0, 64); |
| 519 | + OPTIMIZER_HIDE_VAR(ptr); | |
| 518 | 520 | OPTIMIZER_HIDE_VAR(invalid_size); |
| 519 | 521 | KUNIT_EXPECT_KASAN_FAIL(test, |
| 520 | 522 | memmove((char *)ptr, (char *)ptr + 4, invalid_size)); |
| @@ -531,6 +533,7 @@ static void kmalloc_memmove_invalid_size(struct kunit *test) · 10 unmodified lines | ||
| 531 | 533 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 532 | 534 | |
| 533 | 535 | memset((char *)ptr, 0, 64); |
| 536 | + OPTIMIZER_HIDE_VAR(ptr); | |
| 534 | 537 | KUNIT_EXPECT_KASAN_FAIL(test, |
| 535 | 538 | memmove((char *)ptr, (char *)ptr + 4, invalid_size)); |
| 536 | 539 | kfree(ptr); |
| @@ -893,6 +896,7 @@ static void kasan_memchr(struct kunit *test) · 356 unmodified lines | ||
| 893 | 896 | ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); |
| 894 | 897 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 895 | 898 | |
| 899 | + OPTIMIZER_HIDE_VAR(ptr); | |
| 896 | 900 | OPTIMIZER_HIDE_VAR(size); |
| 897 | 901 | KUNIT_EXPECT_KASAN_FAIL(test, |
| 898 | 902 | kasan_ptr_result = memchr(ptr, '1', size + 1)); |
| @@ -919,6 +923,7 @@ static void kasan_memcmp(struct kunit *test) · 20 unmodified lines | ||
| 919 | 923 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 920 | 924 | memset(arr, 0, sizeof(arr)); |
| 921 | 925 | |
| 926 | + OPTIMIZER_HIDE_VAR(ptr); | |
| 922 | 927 | OPTIMIZER_HIDE_VAR(size); |
| 923 | 928 | KUNIT_EXPECT_KASAN_FAIL(test, |
| 924 | 929 | kasan_int_result = memcmp(ptr, arr, size+1)); |
| @@ -1595,6 +1595,12 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags, · 1594 unmodified lines | ||
| 1595 | 1595 | goto out; |
| 1596 | 1596 | } |
| 1597 | 1597 | |
| 1598 | + /* | |
| 1599 | + * Pages instantiated by device-dax (not filesystem-dax) | |
| 1600 | + * may be compound pages. | |
| 1601 | + */ | |
| 1602 | + page = compound_head(page); | |
| 1603 | + | |
| 1598 | 1604 | /* |
| 1599 | 1605 | * Prevent the inode from being freed while we are interrogating |
| 1600 | 1606 | * the address_space, typically this would be handled by |
| @@ -560,10 +560,10 @@ static bool __allowed_ingress(const struct net_bridge *br, · 559 unmodified lines | ||
| 560 | 560 | !br_opt_get(br, BROPT_VLAN_STATS_ENABLED)) { |
| 561 | 561 | if (*state == BR_STATE_FORWARDING) { |
| 562 | 562 | *state = br_vlan_get_pvid_state(vg); |
| 563 | − return br_vlan_state_allowed(*state, true); | |
| 564 | − } else { | |
| 565 | − return true; | |
| 563 | + if (!br_vlan_state_allowed(*state, true)) | |
| 564 | + goto drop; | |
| 566 | 565 | } |
| 566 | + return true; | |
| 567 | 567 | } |
| 568 | 568 | } |
| 569 | 569 | v = br_vlan_find(vg, *vid); |
| @@ -2020,7 +2020,8 @@ static int br_vlan_rtm_dump(struct sk_buff *skb, struct netlink_callback *cb) · 1450 unmodified lines | ||
| 2020 | 2020 | goto out_err; |
| 2021 | 2021 | } |
| 2022 | 2022 | err = br_vlan_dump_dev(dev, skb, cb, dump_flags); |
| 2023 | − if (err && err != -EMSGSIZE) | |
| 2023 | + /* if the dump completed without an error we return 0 here */ | |
| 2024 | + if (err != -EMSGSIZE) | |
| 2024 | 2025 | goto out_err; |
| 2025 | 2026 | } else { |
| 2026 | 2027 | for_each_netdev_rcu(net, dev) { |
| @@ -190,12 +190,23 @@ static const struct seq_operations softnet_seq_ops = { · 189 unmodified lines | ||
| 190 | 190 | .show = softnet_seq_show, |
| 191 | 191 | }; |
| 192 | 192 | |
| 193 | −static void *ptype_get_idx(loff_t pos) | |
| 193 | +static void *ptype_get_idx(struct seq_file *seq, loff_t pos) | |
| 194 | 194 | { |
| 195 | + struct list_head *ptype_list = NULL; | |
| 195 | 196 | struct packet_type *pt = NULL; |
| 197 | + struct net_device *dev; | |
| 196 | 198 | loff_t i = 0; |
| 197 | 199 | int t; |
| 198 | 200 | |
| 201 | + for_each_netdev_rcu(seq_file_net(seq), dev) { | |
| 202 | + ptype_list = &dev->ptype_all; | |
| 203 | + list_for_each_entry_rcu(pt, ptype_list, list) { | |
| 204 | + if (i == pos) | |
| 205 | + return pt; | |
| 206 | + ++i; | |
| 207 | + } | |
| 208 | + } | |
| 209 | + | |
| 199 | 210 | list_for_each_entry_rcu(pt, &ptype_all, list) { |
| 200 | 211 | if (i == pos) |
| 201 | 212 | return pt; |
| @@ -216,22 +227,40 @@ static void *ptype_seq_start(struct seq_file *seq, loff_t *pos) · 14 unmodified lines | ||
| 216 | 227 | __acquires(RCU) |
| 217 | 228 | { |
| 218 | 229 | rcu_read_lock(); |
| 219 | − return *pos ? ptype_get_idx(*pos - 1) : SEQ_START_TOKEN; | |
| 230 | + return *pos ? ptype_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; | |
| 220 | 231 | } |
| 221 | 232 | |
| 222 | 233 | static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
| 223 | 234 | { |
| 235 | + struct net_device *dev; | |
| 224 | 236 | struct packet_type *pt; |
| 225 | 237 | struct list_head *nxt; |
| 226 | 238 | int hash; |
| 227 | 239 | |
| 228 | 240 | ++*pos; |
| 229 | 241 | if (v == SEQ_START_TOKEN) |
| 230 | − return ptype_get_idx(0); | |
| 242 | + return ptype_get_idx(seq, 0); | |
| 231 | 243 | |
| 232 | 244 | pt = v; |
| 233 | 245 | nxt = pt->list.next; |
| 246 | + if (pt->dev) { | |
| 247 | + if (nxt != &pt->dev->ptype_all) | |
| 248 | + goto found; | |
| 249 | + | |
| 250 | + dev = pt->dev; | |
| 251 | + for_each_netdev_continue_rcu(seq_file_net(seq), dev) { | |
| 252 | + if (!list_empty(&dev->ptype_all)) { | |
| 253 | + nxt = dev->ptype_all.next; | |
| 254 | + goto found; | |
| 255 | + } | |
| 256 | + } | |
| 257 | + | |
| 258 | + nxt = ptype_all.next; | |
| 259 | + goto ptype_all; | |
| 260 | + } | |
| 261 | + | |
| 234 | 262 | if (pt->type == htons(ETH_P_ALL)) { |
| 263 | +ptype_all: | |
| 235 | 264 | if (nxt != &ptype_all) |
| 236 | 265 | goto found; |
| 237 | 266 | hash = 0; |
| @@ -260,7 +289,8 @@ static int ptype_seq_show(struct seq_file *seq, void *v) · 22 unmodified lines | ||
| 260 | 289 | |
| 261 | 290 | if (v == SEQ_START_TOKEN) |
| 262 | 291 | seq_puts(seq, "Type Device Function\n"); |
| 263 | − else if (pt->dev == NULL || dev_net(pt->dev) == seq_file_net(seq)) { | |
| 292 | + else if ((!pt->af_packet_net || net_eq(pt->af_packet_net, seq_file_net(seq))) && | |
| 293 | + (!pt->dev || net_eq(dev_net(pt->dev), seq_file_net(seq)))) { | |
| 264 | 294 | if (pt->type == htons(ETH_P_ALL)) |
| 265 | 295 | seq_puts(seq, "ALL "); |
| 266 | 296 | else |
| @@ -162,12 +162,19 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk, · 161 unmodified lines | ||
| 162 | 162 | iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); |
| 163 | 163 | iph->saddr = saddr; |
| 164 | 164 | iph->protocol = sk->sk_protocol; |
| 165 | − if (ip_dont_fragment(sk, &rt->dst)) { | |
| 165 | + /* Do not bother generating IPID for small packets (eg SYNACK) */ | |
| 166 | + if (skb->len <= IPV4_MIN_MTU || ip_dont_fragment(sk, &rt->dst)) { | |
| 166 | 167 | iph->frag_off = htons(IP_DF); |
| 167 | 168 | iph->id = 0; |
| 168 | 169 | } else { |
| 169 | 170 | iph->frag_off = 0; |
| 170 | − __ip_select_ident(net, iph, 1); | |
| 171 | + /* TCP packets here are SYNACK with fat IPv4/TCP options. | |
| 172 | + * Avoid using the hashed IP ident generator. | |
| 173 | + */ | |
| 174 | + if (sk->sk_protocol == IPPROTO_TCP) | |
| 175 | + iph->id = (__force __be16)prandom_u32(); | |
| 176 | + else | |
| 177 | + __ip_select_ident(net, iph, 1); | |
| 171 | 178 | } |
| 172 | 179 | |
| 173 | 180 | if (opt && opt->opt.optlen) { |
| @@ -825,15 +832,24 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, · 651 unmodified lines | ||
| 825 | 832 | /* Everything is OK. Generate! */ |
| 826 | 833 | ip_fraglist_init(skb, iph, hlen, &iter); |
| 827 | 834 | |
| 828 | − if (iter.frag) | |
| 829 | − ip_options_fragment(iter.frag); | |
| 830 | − | |
| 831 | 835 | for (;;) { |
| 832 | 836 | /* Prepare header of the next frame, |
| 833 | 837 | * before previous one went down. */ |
| 834 | 838 | if (iter.frag) { |
| 839 | + bool first_frag = (iter.offset == 0); | |
| 840 | + | |
| 835 | 841 | IPCB(iter.frag)->flags = IPCB(skb)->flags; |
| 836 | 842 | ip_fraglist_prepare(skb, &iter); |
| 843 | + if (first_frag && IPCB(skb)->opt.optlen) { | |
| 844 | + /* ipcb->opt is not populated for frags | |
| 845 | + * coming from __ip_make_skb(), | |
| 846 | + * ip_options_fragment() needs optlen | |
| 847 | + */ | |
| 848 | + IPCB(iter.frag)->opt.optlen = | |
| 849 | + IPCB(skb)->opt.optlen; | |
| 850 | + ip_options_fragment(iter.frag); | |
| 851 | + ip_send_check(iter.iph); | |
| 852 | + } | |
| 837 | 853 | } |
| 838 | 854 | |
| 839 | 855 | skb->tstamp = tstamp; |
| @@ -220,7 +220,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) · 219 unmodified lines | ||
| 220 | 220 | continue; |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | − if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) | |
| 223 | + if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && | |
| 224 | + sk->sk_bound_dev_if != inet_sdif(skb)) | |
| 224 | 225 | continue; |
| 225 | 226 | |
| 226 | 227 | sock_hold(sk); |
| @@ -722,6 +722,7 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 721 unmodified lines | ||
| 722 | 722 | int ret = -EINVAL; |
| 723 | 723 | int chk_addr_ret; |
| 724 | 724 | |
| 725 | + lock_sock(sk); | |
| 725 | 726 | if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in)) |
| 726 | 727 | goto out; |
| 727 | 728 | |
| @@ -741,7 +742,9 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 13 unmodified lines | ||
| 741 | 742 | inet->inet_saddr = 0; /* Use device */ |
| 742 | 743 | sk_dst_reset(sk); |
| 743 | 744 | ret = 0; |
| 744 | −out: return ret; | |
| 745 | +out: | |
| 746 | + release_sock(sk); | |
| 747 | + return ret; | |
| 745 | 748 | } |
| 746 | 749 | |
| 747 | 750 | /* |
| @@ -842,6 +842,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, · 841 unmodified lines | ||
| 842 | 842 | } |
| 843 | 843 | |
| 844 | 844 | release_sock(sk); |
| 845 | + sk_defer_free_flush(sk); | |
| 845 | 846 | |
| 846 | 847 | if (spliced) |
| 847 | 848 | return spliced; |
| @@ -2095,7 +2095,7 @@ process: · 2094 unmodified lines | ||
| 2095 | 2095 | nf_reset_ct(skb); |
| 2096 | 2096 | |
| 2097 | 2097 | if (tcp_filter(sk, skb)) { |
| 2098 | − drop_reason = SKB_DROP_REASON_TCP_FILTER; | |
| 2098 | + drop_reason = SKB_DROP_REASON_SOCKET_FILTER; | |
| 2099 | 2099 | goto discard_and_relse; |
| 2100 | 2100 | } |
| 2101 | 2101 | th = (const struct tcphdr *)skb->data; |
| @@ -2589,7 +2589,7 @@ int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev, · 2588 unmodified lines | ||
| 2589 | 2589 | __u32 valid_lft, u32 prefered_lft) |
| 2590 | 2590 | { |
| 2591 | 2591 | struct inet6_ifaddr *ifp = ipv6_get_ifaddr(net, addr, dev, 1); |
| 2592 | − int create = 0; | |
| 2592 | + int create = 0, update_lft = 0; | |
| 2593 | 2593 | |
| 2594 | 2594 | if (!ifp && valid_lft) { |
| 2595 | 2595 | int max_addresses = in6_dev->cnf.max_addresses; |
| @@ -2633,19 +2633,32 @@ int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev, · 37 unmodified lines | ||
| 2633 | 2633 | unsigned long now; |
| 2634 | 2634 | u32 stored_lft; |
| 2635 | 2635 | |
| 2636 | − /* Update lifetime (RFC4862 5.5.3 e) | |
| 2637 | − * We deviate from RFC4862 by honoring all Valid Lifetimes to | |
| 2638 | − * improve the reaction of SLAAC to renumbering events | |
| 2639 | − * (draft-gont-6man-slaac-renum-06, Section 4.2) | |
| 2640 | − */ | |
| 2636 | + /* update lifetime (RFC2462 5.5.3 e) */ | |
| 2641 | 2637 | spin_lock_bh(&ifp->lock); |
| 2642 | 2638 | now = jiffies; |
| 2643 | 2639 | if (ifp->valid_lft > (now - ifp->tstamp) / HZ) |
| 2644 | 2640 | stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ; |
| 2645 | 2641 | else |
| 2646 | 2642 | stored_lft = 0; |
| 2647 | − | |
| 2648 | 2643 | if (!create && stored_lft) { |
| 2644 | + const u32 minimum_lft = min_t(u32, | |
| 2645 | + stored_lft, MIN_VALID_LIFETIME); | |
| 2646 | + valid_lft = max(valid_lft, minimum_lft); | |
| 2647 | + | |
| 2648 | + /* RFC4862 Section 5.5.3e: | |
| 2649 | + * "Note that the preferred lifetime of the | |
| 2650 | + * corresponding address is always reset to | |
| 2651 | + * the Preferred Lifetime in the received | |
| 2652 | + * Prefix Information option, regardless of | |
| 2653 | + * whether the valid lifetime is also reset or | |
| 2654 | + * ignored." | |
| 2655 | + * | |
| 2656 | + * So we should always update prefered_lft here. | |
| 2657 | + */ | |
| 2658 | + update_lft = 1; | |
| 2659 | + } | |
| 2660 | + | |
| 2661 | + if (update_lft) { | |
| 2649 | 2662 | ifp->valid_lft = valid_lft; |
| 2650 | 2663 | ifp->prefered_lft = prefered_lft; |
| 2651 | 2664 | ifp->tstamp = now; |
| @@ -112,7 +112,7 @@ void fib6_update_sernum(struct net *net, struct fib6_info *f6i) · 111 unmodified lines | ||
| 112 | 112 | fn = rcu_dereference_protected(f6i->fib6_node, |
| 113 | 113 | lockdep_is_held(&f6i->fib6_table->tb6_lock)); |
| 114 | 114 | if (fn) |
| 115 | − fn->fn_sernum = fib6_new_sernum(net); | |
| 115 | + WRITE_ONCE(fn->fn_sernum, fib6_new_sernum(net)); | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | /* |
| @@ -590,12 +590,13 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb, · 471 unmodified lines | ||
| 590 | 590 | spin_unlock_bh(&table->tb6_lock); |
| 591 | 591 | if (res > 0) { |
| 592 | 592 | cb->args[4] = 1; |
| 593 | − cb->args[5] = w->root->fn_sernum; | |
| 593 | + cb->args[5] = READ_ONCE(w->root->fn_sernum); | |
| 594 | 594 | } |
| 595 | 595 | } else { |
| 596 | − if (cb->args[5] != w->root->fn_sernum) { | |
| 596 | + int sernum = READ_ONCE(w->root->fn_sernum); | |
| 597 | + if (cb->args[5] != sernum) { | |
| 597 | 598 | /* Begin at the root if the tree changed */ |
| 598 | − cb->args[5] = w->root->fn_sernum; | |
| 599 | + cb->args[5] = sernum; | |
| 599 | 600 | w->state = FWS_INIT; |
| 600 | 601 | w->node = w->root; |
| 601 | 602 | w->skip = w->count; |
| @@ -1345,7 +1346,7 @@ static void __fib6_update_sernum_upto_root(struct fib6_info *rt, · 743 unmodified lines | ||
| 1345 | 1346 | /* paired with smp_rmb() in fib6_get_cookie_safe() */ |
| 1346 | 1347 | smp_wmb(); |
| 1347 | 1348 | while (fn) { |
| 1348 | − fn->fn_sernum = sernum; | |
| 1349 | + WRITE_ONCE(fn->fn_sernum, sernum); | |
| 1349 | 1350 | fn = rcu_dereference_protected(fn->parent, |
| 1350 | 1351 | lockdep_is_held(&rt->fib6_table->tb6_lock)); |
| 1351 | 1352 | } |
| @@ -2174,8 +2175,8 @@ static int fib6_clean_node(struct fib6_walker *w) · 822 unmodified lines | ||
| 2174 | 2175 | }; |
| 2175 | 2176 | |
| 2176 | 2177 | if (c->sernum != FIB6_NO_SERNUM_CHANGE && |
| 2177 | − w->node->fn_sernum != c->sernum) | |
| 2178 | − w->node->fn_sernum = c->sernum; | |
| 2178 | + READ_ONCE(w->node->fn_sernum) != c->sernum) | |
| 2179 | + WRITE_ONCE(w->node->fn_sernum, c->sernum); | |
| 2179 | 2180 | |
| 2180 | 2181 | if (!c->func) { |
| 2181 | 2182 | WARN_ON_ONCE(c->sernum == FIB6_NO_SERNUM_CHANGE); |
| @@ -2543,7 +2544,7 @@ static void ipv6_route_seq_setup_walk(struct ipv6_route_iter *iter, · 361 unmodified lines | ||
| 2543 | 2544 | iter->w.state = FWS_INIT; |
| 2544 | 2545 | iter->w.node = iter->w.root; |
| 2545 | 2546 | iter->w.args = iter; |
| 2546 | − iter->sernum = iter->w.root->fn_sernum; | |
| 2547 | + iter->sernum = READ_ONCE(iter->w.root->fn_sernum); | |
| 2547 | 2548 | INIT_LIST_HEAD(&iter->w.lh); |
| 2548 | 2549 | fib6_walker_link(net, &iter->w); |
| 2549 | 2550 | } |
| @@ -2571,8 +2572,10 @@ static struct fib6_table *ipv6_route_seq_next_table(struct fib6_table *tbl, · 21 unmodified lines | ||
| 2571 | 2572 | |
| 2572 | 2573 | static void ipv6_route_check_sernum(struct ipv6_route_iter *iter) |
| 2573 | 2574 | { |
| 2574 | − if (iter->sernum != iter->w.root->fn_sernum) { | |
| 2575 | − iter->sernum = iter->w.root->fn_sernum; | |
| 2575 | + int sernum = READ_ONCE(iter->w.root->fn_sernum); | |
| 2576 | + | |
| 2577 | + if (iter->sernum != sernum) { | |
| 2578 | + iter->sernum = sernum; | |
| 2576 | 2579 | iter->w.state = FWS_INIT; |
| 2577 | 2580 | iter->w.node = iter->w.root; |
| 2578 | 2581 | WARN_ON(iter->w.skip); |
| @@ -1036,14 +1036,14 @@ int ip6_tnl_xmit_ctl(struct ip6_tnl *t, · 1035 unmodified lines | ||
| 1036 | 1036 | |
| 1037 | 1037 | if (unlikely(!ipv6_chk_addr_and_flags(net, laddr, ldev, false, |
| 1038 | 1038 | 0, IFA_F_TENTATIVE))) |
| 1039 | − pr_warn("%s xmit: Local address not yet configured!\n", | |
| 1040 | − p->name); | |
| 1039 | + pr_warn_ratelimited("%s xmit: Local address not yet configured!\n", | |
| 1040 | + p->name); | |
| 1041 | 1041 | else if (!(p->flags & IP6_TNL_F_ALLOW_LOCAL_REMOTE) && |
| 1042 | 1042 | !ipv6_addr_is_multicast(raddr) && |
| 1043 | 1043 | unlikely(ipv6_chk_addr_and_flags(net, raddr, ldev, |
| 1044 | 1044 | true, 0, IFA_F_TENTATIVE))) |
| 1045 | − pr_warn("%s xmit: Routing loop! Remote address found on this node!\n", | |
| 1046 | − p->name); | |
| 1045 | + pr_warn_ratelimited("%s xmit: Routing loop! Remote address found on this node!\n", | |
| 1046 | + p->name); | |
| 1047 | 1047 | else |
| 1048 | 1048 | ret = 1; |
| 1049 | 1049 | rcu_read_unlock(); |
| @@ -2802,7 +2802,7 @@ static void ip6_link_failure(struct sk_buff *skb) · 2801 unmodified lines | ||
| 2802 | 2802 | if (from) { |
| 2803 | 2803 | fn = rcu_dereference(from->fib6_node); |
| 2804 | 2804 | if (fn && (rt->rt6i_flags & RTF_DEFAULT)) |
| 2805 | − fn->fn_sernum = -1; | |
| 2805 | + WRITE_ONCE(fn->fn_sernum, -1); | |
| 2806 | 2806 | } |
| 2807 | 2807 | } |
| 2808 | 2808 | rcu_read_unlock(); |
| @@ -478,6 +478,20 @@ __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id) · 477 unmodified lines | ||
| 478 | 478 | return NULL; |
| 479 | 479 | } |
| 480 | 480 | |
| 481 | +static struct mptcp_pm_addr_entry * | |
| 482 | +__lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info, | |
| 483 | + bool lookup_by_id) | |
| 484 | +{ | |
| 485 | + struct mptcp_pm_addr_entry *entry; | |
| 486 | + | |
| 487 | + list_for_each_entry(entry, &pernet->local_addr_list, list) { | |
| 488 | + if ((!lookup_by_id && addresses_equal(&entry->addr, info, true)) || | |
| 489 | + (lookup_by_id && entry->addr.id == info->id)) | |
| 490 | + return entry; | |
| 491 | + } | |
| 492 | + return NULL; | |
| 493 | +} | |
| 494 | + | |
| 481 | 495 | static int |
| 482 | 496 | lookup_id_by_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *addr) |
| 483 | 497 | { |
| @@ -777,7 +791,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk, · 293 unmodified lines | ||
| 777 | 791 | removed = true; |
| 778 | 792 | __MPTCP_INC_STATS(sock_net(sk), rm_type); |
| 779 | 793 | } |
| 780 | − __set_bit(rm_list->ids[1], msk->pm.id_avail_bitmap); | |
| 794 | + __set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap); | |
| 781 | 795 | if (!removed) |
| 782 | 796 | continue; |
| 783 | 797 | |
| @@ -1763,18 +1777,21 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info) · 979 unmodified lines | ||
| 1763 | 1777 | return -EOPNOTSUPP; |
| 1764 | 1778 | } |
| 1765 | 1779 | |
| 1766 | − list_for_each_entry(entry, &pernet->local_addr_list, list) { | |
| 1767 | − if ((!lookup_by_id && addresses_equal(&entry->addr, &addr.addr, true)) || | |
| 1768 | − (lookup_by_id && entry->addr.id == addr.addr.id)) { | |
| 1769 | − mptcp_nl_addr_backup(net, &entry->addr, bkup); | |
| 1770 | − | |
| 1771 | − if (bkup) | |
| 1772 | − entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP; | |
| 1773 | − else | |
| 1774 | − entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP; | |
| 1775 | − } | |
| 1780 | + spin_lock_bh(&pernet->lock); | |
| 1781 | + entry = __lookup_addr(pernet, &addr.addr, lookup_by_id); | |
| 1782 | + if (!entry) { | |
| 1783 | + spin_unlock_bh(&pernet->lock); | |
| 1784 | + return -EINVAL; | |
| 1776 | 1785 | } |
| 1777 | 1786 | |
| 1787 | + if (bkup) | |
| 1788 | + entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP; | |
| 1789 | + else | |
| 1790 | + entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP; | |
| 1791 | + addr = *entry; | |
| 1792 | + spin_unlock_bh(&pernet->lock); | |
| 1793 | + | |
| 1794 | + mptcp_nl_addr_backup(net, &addr.addr, bkup); | |
| 1778 | 1795 | return 0; |
| 1779 | 1796 | } |
| 1780 | 1797 | |
| @@ -408,7 +408,7 @@ DECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); · 407 unmodified lines | ||
| 408 | 408 | struct mptcp_subflow_context { |
| 409 | 409 | struct list_head node;/* conn_list of subflows */ |
| 410 | 410 | |
| 411 | − char reset_start[0]; | |
| 411 | + struct_group(reset, | |
| 412 | 412 | |
| 413 | 413 | unsigned long avg_pacing_rate; /* protected by msk socket lock */ |
| 414 | 414 | u64 local_key; |
| @@ -458,7 +458,7 @@ struct mptcp_subflow_context { · 43 unmodified lines | ||
| 458 | 458 | |
| 459 | 459 | long delegated_status; |
| 460 | 460 | |
| 461 | − char reset_end[0]; | |
| 461 | + ); | |
| 462 | 462 | |
| 463 | 463 | struct list_head delegated_node; /* link into delegated_action, protected by local BH */ |
| 464 | 464 | |
| @@ -494,7 +494,7 @@ mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow) · 29 unmodified lines | ||
| 494 | 494 | static inline void |
| 495 | 495 | mptcp_subflow_ctx_reset(struct mptcp_subflow_context *subflow) |
| 496 | 496 | { |
| 497 | − memset(subflow->reset_start, 0, subflow->reset_end - subflow->reset_start); | |
| 497 | + memset(&subflow->reset, 0, sizeof(subflow->reset)); | |
| 498 | 498 | subflow->request_mptcp = 1; |
| 499 | 499 | } |
| 500 | 500 | |
| @@ -1924,15 +1924,17 @@ repeat: · 1923 unmodified lines | ||
| 1924 | 1924 | pr_debug("nf_conntrack_in: Can't track with proto module\n"); |
| 1925 | 1925 | nf_ct_put(ct); |
| 1926 | 1926 | skb->_nfct = 0; |
| 1927 | − NF_CT_STAT_INC_ATOMIC(state->net, invalid); | |
| 1928 | − if (ret == -NF_DROP) | |
| 1929 | − NF_CT_STAT_INC_ATOMIC(state->net, drop); | |
| 1930 | 1927 | /* Special case: TCP tracker reports an attempt to reopen a |
| 1931 | 1928 | * closed/aborted connection. We have to go back and create a |
| 1932 | 1929 | * fresh conntrack. |
| 1933 | 1930 | */ |
| 1934 | 1931 | if (ret == -NF_REPEAT) |
| 1935 | 1932 | goto repeat; |
| 1933 | + | |
| 1934 | + NF_CT_STAT_INC_ATOMIC(state->net, invalid); | |
| 1935 | + if (ret == -NF_DROP) | |
| 1936 | + NF_CT_STAT_INC_ATOMIC(state->net, drop); | |
| 1937 | + | |
| 1936 | 1938 | ret = -ret; |
| 1937 | 1939 | goto out; |
| 1938 | 1940 | } |
| @@ -20,13 +20,14 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <net/netfilter/nf_conntrack_helper.h> |
| 21 | 21 | #include <net/netfilter/nf_conntrack_expect.h> |
| 22 | 22 | |
| 23 | +#define HELPER_NAME "netbios-ns" | |
| 23 | 24 | #define NMBD_PORT 137 |
| 24 | 25 | |
| 25 | 26 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
| 26 | 27 | MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); |
| 27 | 28 | MODULE_LICENSE("GPL"); |
| 28 | 29 | MODULE_ALIAS("ip_conntrack_netbios_ns"); |
| 29 | −MODULE_ALIAS_NFCT_HELPER("netbios_ns"); | |
| 30 | +MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); | |
| 30 | 31 | |
| 31 | 32 | static unsigned int timeout __read_mostly = 3; |
| 32 | 33 | module_param(timeout, uint, 0400); |
| @@ -44,7 +45,7 @@ static int netbios_ns_help(struct sk_buff *skb, unsigned int protoff, · 11 unmodified lines | ||
| 44 | 45 | } |
| 45 | 46 | |
| 46 | 47 | static struct nf_conntrack_helper helper __read_mostly = { |
| 47 | − .name = "netbios-ns", | |
| 48 | + .name = HELPER_NAME, | |
| 48 | 49 | .tuple.src.l3num = NFPROTO_IPV4, |
| 49 | 50 | .tuple.src.u.udp.port = cpu_to_be16(NMBD_PORT), |
| 50 | 51 | .tuple.dst.protonum = IPPROTO_UDP, |
| @@ -8264,14 +8264,12 @@ static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *cha · 8263 unmodified lines | ||
| 8264 | 8264 | void *data, *data_boundary; |
| 8265 | 8265 | struct nft_rule_dp *prule; |
| 8266 | 8266 | struct nft_rule *rule; |
| 8267 | − int i; | |
| 8268 | 8267 | |
| 8269 | 8268 | /* already handled or inactive chain? */ |
| 8270 | 8269 | if (chain->blob_next || !nft_is_active_next(net, chain)) |
| 8271 | 8270 | return 0; |
| 8272 | 8271 | |
| 8273 | 8272 | rule = list_entry(&chain->rules, struct nft_rule, list); |
| 8274 | − i = 0; | |
| 8275 | 8273 | |
| 8276 | 8274 | data_size = 0; |
| 8277 | 8275 | list_for_each_entry_continue(rule, &chain->rules, list) { |
| @@ -8301,7 +8299,7 @@ static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *cha · 23 unmodified lines | ||
| 8301 | 8299 | return -ENOMEM; |
| 8302 | 8300 | |
| 8303 | 8301 | size = 0; |
| 8304 | − track.last = last; | |
| 8302 | + track.last = nft_expr_last(rule); | |
| 8305 | 8303 | nft_rule_for_each_expr(expr, last, rule) { |
| 8306 | 8304 | track.cur = expr; |
| 8307 | 8305 | |
| @@ -62,6 +62,7 @@ static int nft_connlimit_do_init(const struct nft_ctx *ctx, · 61 unmodified lines | ||
| 62 | 62 | { |
| 63 | 63 | bool invert = false; |
| 64 | 64 | u32 flags, limit; |
| 65 | + int err; | |
| 65 | 66 | |
| 66 | 67 | if (!tb[NFTA_CONNLIMIT_COUNT]) |
| 67 | 68 | return -EINVAL; |
| @@ -84,7 +85,15 @@ static int nft_connlimit_do_init(const struct nft_ctx *ctx, · 16 unmodified lines | ||
| 84 | 85 | priv->limit = limit; |
| 85 | 86 | priv->invert = invert; |
| 86 | 87 | |
| 87 | − return nf_ct_netns_get(ctx->net, ctx->family); | |
| 88 | + err = nf_ct_netns_get(ctx->net, ctx->family); | |
| 89 | + if (err < 0) | |
| 90 | + goto err_netns; | |
| 91 | + | |
| 92 | + return 0; | |
| 93 | +err_netns: | |
| 94 | + kfree(priv->list); | |
| 95 | + | |
| 96 | + return err; | |
| 88 | 97 | } |
| 89 | 98 | |
| 90 | 99 | static void nft_connlimit_do_destroy(const struct nft_ctx *ctx, |
| @@ -1774,6 +1774,7 @@ static int fanout_add(struct sock *sk, struct fanout_args *args) · 1773 unmodified lines | ||
| 1774 | 1774 | match->prot_hook.dev = po->prot_hook.dev; |
| 1775 | 1775 | match->prot_hook.func = packet_rcv_fanout; |
| 1776 | 1776 | match->prot_hook.af_packet_priv = match; |
| 1777 | + match->prot_hook.af_packet_net = read_pnet(&match->net); | |
| 1777 | 1778 | match->prot_hook.id_match = match_fanout_group; |
| 1778 | 1779 | match->max_num_members = args->max_num_members; |
| 1779 | 1780 | list_add(&match->list, &fanout_list); |
| @@ -3353,6 +3354,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, · 1573 unmodified lines | ||
| 3353 | 3354 | po->prot_hook.func = packet_rcv_spkt; |
| 3354 | 3355 | |
| 3355 | 3356 | po->prot_hook.af_packet_priv = sk; |
| 3357 | + po->prot_hook.af_packet_net = sock_net(sk); | |
| 3356 | 3358 | |
| 3357 | 3359 | if (proto) { |
| 3358 | 3360 | po->prot_hook.type = proto; |
| @@ -157,7 +157,7 @@ static void rxrpc_congestion_timeout(struct rxrpc_call *call) · 156 unmodified lines | ||
| 157 | 157 | static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) |
| 158 | 158 | { |
| 159 | 159 | struct sk_buff *skb; |
| 160 | − unsigned long resend_at, rto_j; | |
| 160 | + unsigned long resend_at; | |
| 161 | 161 | rxrpc_seq_t cursor, seq, top; |
| 162 | 162 | ktime_t now, max_age, oldest, ack_ts; |
| 163 | 163 | int ix; |
| @@ -165,10 +165,8 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) · 1 unmodified line | ||
| 165 | 165 | |
| 166 | 166 | _enter("{%d,%d}", call->tx_hard_ack, call->tx_top); |
| 167 | 167 | |
| 168 | − rto_j = call->peer->rto_j; | |
| 169 | − | |
| 170 | 168 | now = ktime_get_real(); |
| 171 | − max_age = ktime_sub(now, jiffies_to_usecs(rto_j)); | |
| 169 | + max_age = ktime_sub(now, jiffies_to_usecs(call->peer->rto_j)); | |
| 172 | 170 | |
| 173 | 171 | spin_lock_bh(&call->lock); |
| 174 | 172 | |
| @@ -213,7 +211,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) · 38 unmodified lines | ||
| 213 | 211 | } |
| 214 | 212 | |
| 215 | 213 | resend_at = nsecs_to_jiffies(ktime_to_ns(ktime_sub(now, oldest))); |
| 216 | − resend_at += jiffies + rto_j; | |
| 214 | + resend_at += jiffies + rxrpc_get_rto_backoff(call->peer, retrans); | |
| 217 | 215 | WRITE_ONCE(call->resend_at, resend_at); |
| 218 | 216 | |
| 219 | 217 | if (unacked) |
| @@ -468,7 +468,7 @@ done: · 467 unmodified lines | ||
| 468 | 468 | if (call->peer->rtt_count > 1) { |
| 469 | 469 | unsigned long nowj = jiffies, ack_lost_at; |
| 470 | 470 | |
| 471 | − ack_lost_at = rxrpc_get_rto_backoff(call->peer, retrans); | |
| 471 | + ack_lost_at = rxrpc_get_rto_backoff(call->peer, false); | |
| 472 | 472 | ack_lost_at += nowj; |
| 473 | 473 | WRITE_ONCE(call->ack_lost_at, ack_lost_at); |
| 474 | 474 | rxrpc_reduce_call_timer(call, ack_lost_at, nowj, |
| @@ -1204,7 +1204,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, · 1203 unmodified lines | ||
| 1204 | 1204 | |
| 1205 | 1205 | err = -ENOENT; |
| 1206 | 1206 | if (!ops) { |
| 1207 | − NL_SET_ERR_MSG(extack, "Specified qdisc not found"); | |
| 1207 | + NL_SET_ERR_MSG(extack, "Specified qdisc kind is unknown"); | |
| 1208 | 1208 | goto err_out; |
| 1209 | 1209 | } |
| 1210 | 1210 | |
| @@ -1810,6 +1810,26 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, · 1809 unmodified lines | ||
| 1810 | 1810 | if (!hopt->rate.rate || !hopt->ceil.rate) |
| 1811 | 1811 | goto failure; |
| 1812 | 1812 | |
| 1813 | + if (q->offload) { | |
| 1814 | + /* Options not supported by the offload. */ | |
| 1815 | + if (hopt->rate.overhead || hopt->ceil.overhead) { | |
| 1816 | + NL_SET_ERR_MSG(extack, "HTB offload doesn't support the overhead parameter"); | |
| 1817 | + goto failure; | |
| 1818 | + } | |
| 1819 | + if (hopt->rate.mpu || hopt->ceil.mpu) { | |
| 1820 | + NL_SET_ERR_MSG(extack, "HTB offload doesn't support the mpu parameter"); | |
| 1821 | + goto failure; | |
| 1822 | + } | |
| 1823 | + if (hopt->quantum) { | |
| 1824 | + NL_SET_ERR_MSG(extack, "HTB offload doesn't support the quantum parameter"); | |
| 1825 | + goto failure; | |
| 1826 | + } | |
| 1827 | + if (hopt->prio) { | |
| 1828 | + NL_SET_ERR_MSG(extack, "HTB offload doesn't support the prio parameter"); | |
| 1829 | + goto failure; | |
| 1830 | + } | |
| 1831 | + } | |
| 1832 | + | |
| 1813 | 1833 | /* Keeping backward compatible with rate_table based iproute2 tc */ |
| 1814 | 1834 | if (hopt->rate.linklayer == TC_LINKLAYER_UNAWARE) |
| 1815 | 1835 | qdisc_put_rtab(qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB], |
| @@ -566,12 +566,17 @@ static void smc_stat_fallback(struct smc_sock *smc) · 565 unmodified lines | ||
| 566 | 566 | mutex_unlock(&net->smc.mutex_fback_rsn); |
| 567 | 567 | } |
| 568 | 568 | |
| 569 | −static void smc_switch_to_fallback(struct smc_sock *smc, int reason_code) | |
| 569 | +static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code) | |
| 570 | 570 | { |
| 571 | 571 | wait_queue_head_t *smc_wait = sk_sleep(&smc->sk); |
| 572 | − wait_queue_head_t *clc_wait = sk_sleep(smc->clcsock->sk); | |
| 572 | + wait_queue_head_t *clc_wait; | |
| 573 | 573 | unsigned long flags; |
| 574 | 574 | |
| 575 | + mutex_lock(&smc->clcsock_release_lock); | |
| 576 | + if (!smc->clcsock) { | |
| 577 | + mutex_unlock(&smc->clcsock_release_lock); | |
| 578 | + return -EBADF; | |
| 579 | + } | |
| 575 | 580 | smc->use_fallback = true; |
| 576 | 581 | smc->fallback_rsn = reason_code; |
| 577 | 582 | smc_stat_fallback(smc); |
| @@ -586,18 +591,30 @@ static void smc_switch_to_fallback(struct smc_sock *smc, int reason_code) · 8 unmodified lines | ||
| 586 | 591 | * smc socket->wq, which should be removed |
| 587 | 592 | * to clcsocket->wq during the fallback. |
| 588 | 593 | */ |
| 594 | + clc_wait = sk_sleep(smc->clcsock->sk); | |
| 589 | 595 | spin_lock_irqsave(&smc_wait->lock, flags); |
| 590 | 596 | spin_lock_nested(&clc_wait->lock, SINGLE_DEPTH_NESTING); |
| 591 | 597 | list_splice_init(&smc_wait->head, &clc_wait->head); |
| 592 | 598 | spin_unlock(&clc_wait->lock); |
| 593 | 599 | spin_unlock_irqrestore(&smc_wait->lock, flags); |
| 594 | 600 | } |
| 601 | + mutex_unlock(&smc->clcsock_release_lock); | |
| 602 | + return 0; | |
| 595 | 603 | } |
| 596 | 604 | |
| 597 | 605 | /* fall back during connect */ |
| 598 | 606 | static int smc_connect_fallback(struct smc_sock *smc, int reason_code) |
| 599 | 607 | { |
| 600 | − smc_switch_to_fallback(smc, reason_code); | |
| 608 | + struct net *net = sock_net(&smc->sk); | |
| 609 | + int rc = 0; | |
| 610 | + | |
| 611 | + rc = smc_switch_to_fallback(smc, reason_code); | |
| 612 | + if (rc) { /* fallback fails */ | |
| 613 | + this_cpu_inc(net->smc.smc_stats->clnt_hshake_err_cnt); | |
| 614 | + if (smc->sk.sk_state == SMC_INIT) | |
| 615 | + sock_put(&smc->sk); /* passive closing */ | |
| 616 | + return rc; | |
| 617 | + } | |
| 601 | 618 | smc_copy_sock_settings_to_clc(smc); |
| 602 | 619 | smc->connect_nonblock = 0; |
| 603 | 620 | if (smc->sk.sk_state == SMC_INIT) |
| @@ -1518,11 +1535,12 @@ static void smc_listen_decline(struct smc_sock *new_smc, int reason_code, · 914 unmodified lines | ||
| 1518 | 1535 | { |
| 1519 | 1536 | /* RDMA setup failed, switch back to TCP */ |
| 1520 | 1537 | smc_conn_abort(new_smc, local_first); |
| 1521 | − if (reason_code < 0) { /* error, no fallback possible */ | |
| 1538 | + if (reason_code < 0 || | |
| 1539 | + smc_switch_to_fallback(new_smc, reason_code)) { | |
| 1540 | + /* error, no fallback possible */ | |
| 1522 | 1541 | smc_listen_out_err(new_smc); |
| 1523 | 1542 | return; |
| 1524 | 1543 | } |
| 1525 | − smc_switch_to_fallback(new_smc, reason_code); | |
| 1526 | 1544 | if (reason_code && reason_code != SMC_CLC_DECL_PEERDECL) { |
| 1527 | 1545 | if (smc_clc_send_decline(new_smc, reason_code, version) < 0) { |
| 1528 | 1546 | smc_listen_out_err(new_smc); |
| @@ -1964,8 +1982,11 @@ static void smc_listen_work(struct work_struct *work) · 435 unmodified lines | ||
| 1964 | 1982 | |
| 1965 | 1983 | /* check if peer is smc capable */ |
| 1966 | 1984 | if (!tcp_sk(newclcsock->sk)->syn_smc) { |
| 1967 | − smc_switch_to_fallback(new_smc, SMC_CLC_DECL_PEERNOSMC); | |
| 1968 | − smc_listen_out_connected(new_smc); | |
| 1985 | + rc = smc_switch_to_fallback(new_smc, SMC_CLC_DECL_PEERNOSMC); | |
| 1986 | + if (rc) | |
| 1987 | + smc_listen_out_err(new_smc); | |
| 1988 | + else | |
| 1989 | + smc_listen_out_connected(new_smc); | |
| 1969 | 1990 | return; |
| 1970 | 1991 | } |
| 1971 | 1992 | |
| @@ -2254,7 +2275,9 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) · 282 unmodified lines | ||
| 2254 | 2275 | |
| 2255 | 2276 | if (msg->msg_flags & MSG_FASTOPEN) { |
| 2256 | 2277 | if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) { |
| 2257 | − smc_switch_to_fallback(smc, SMC_CLC_DECL_OPTUNSUPP); | |
| 2278 | + rc = smc_switch_to_fallback(smc, SMC_CLC_DECL_OPTUNSUPP); | |
| 2279 | + if (rc) | |
| 2280 | + goto out; | |
| 2258 | 2281 | } else { |
| 2259 | 2282 | rc = -EINVAL; |
| 2260 | 2283 | goto out; |
| @@ -2447,6 +2470,11 @@ static int smc_setsockopt(struct socket *sock, int level, int optname, · 186 unmodified lines | ||
| 2447 | 2470 | /* generic setsockopts reaching us here always apply to the |
| 2448 | 2471 | * CLC socket |
| 2449 | 2472 | */ |
| 2473 | + mutex_lock(&smc->clcsock_release_lock); | |
| 2474 | + if (!smc->clcsock) { | |
| 2475 | + mutex_unlock(&smc->clcsock_release_lock); | |
| 2476 | + return -EBADF; | |
| 2477 | + } | |
| 2450 | 2478 | if (unlikely(!smc->clcsock->ops->setsockopt)) |
| 2451 | 2479 | rc = -EOPNOTSUPP; |
| 2452 | 2480 | else |
| @@ -2456,6 +2484,7 @@ static int smc_setsockopt(struct socket *sock, int level, int optname, · 3 unmodified lines | ||
| 2456 | 2484 | sk->sk_err = smc->clcsock->sk->sk_err; |
| 2457 | 2485 | sk_error_report(sk); |
| 2458 | 2486 | } |
| 2487 | + mutex_unlock(&smc->clcsock_release_lock); | |
| 2459 | 2488 | |
| 2460 | 2489 | if (optlen < sizeof(int)) |
| 2461 | 2490 | return -EINVAL; |
| @@ -2472,7 +2501,7 @@ static int smc_setsockopt(struct socket *sock, int level, int optname, · 10 unmodified lines | ||
| 2472 | 2501 | case TCP_FASTOPEN_NO_COOKIE: |
| 2473 | 2502 | /* option not supported by SMC */ |
| 2474 | 2503 | if (sk->sk_state == SMC_INIT && !smc->connect_nonblock) { |
| 2475 | − smc_switch_to_fallback(smc, SMC_CLC_DECL_OPTUNSUPP); | |
| 2504 | + rc = smc_switch_to_fallback(smc, SMC_CLC_DECL_OPTUNSUPP); | |
| 2476 | 2505 | } else { |
| 2477 | 2506 | rc = -EINVAL; |
| 2478 | 2507 | } |
| @@ -2515,13 +2544,23 @@ static int smc_getsockopt(struct socket *sock, int level, int optname, · 36 unmodified lines | ||
| 2515 | 2544 | char __user *optval, int __user *optlen) |
| 2516 | 2545 | { |
| 2517 | 2546 | struct smc_sock *smc; |
| 2547 | + int rc; | |
| 2518 | 2548 | |
| 2519 | 2549 | smc = smc_sk(sock->sk); |
| 2550 | + mutex_lock(&smc->clcsock_release_lock); | |
| 2551 | + if (!smc->clcsock) { | |
| 2552 | + mutex_unlock(&smc->clcsock_release_lock); | |
| 2553 | + return -EBADF; | |
| 2554 | + } | |
| 2520 | 2555 | /* socket options apply to the CLC socket */ |
| 2521 | − if (unlikely(!smc->clcsock->ops->getsockopt)) | |
| 2556 | + if (unlikely(!smc->clcsock->ops->getsockopt)) { | |
| 2557 | + mutex_unlock(&smc->clcsock_release_lock); | |
| 2522 | 2558 | return -EOPNOTSUPP; |
| 2523 | − return smc->clcsock->ops->getsockopt(smc->clcsock, level, optname, | |
| 2524 | − optval, optlen); | |
| 2559 | + } | |
| 2560 | + rc = smc->clcsock->ops->getsockopt(smc->clcsock, level, optname, | |
| 2561 | + optval, optlen); | |
| 2562 | + mutex_unlock(&smc->clcsock_release_lock); | |
| 2563 | + return rc; | |
| 2525 | 2564 | } |
| 2526 | 2565 | |
| 2527 | 2566 | static int smc_ioctl(struct socket *sock, unsigned int cmd, |
| @@ -222,10 +222,8 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size, · 221 unmodified lines | ||
| 222 | 222 | if (ret) |
| 223 | 223 | return ret; |
| 224 | 224 | |
| 225 | − if (!ret) { | |
| 226 | − *buf_in = buf; | |
| 227 | − *body_size = toksize; | |
| 228 | − } | |
| 225 | + *buf_in = buf; | |
| 226 | + *body_size = toksize; | |
| 229 | 227 | |
| 230 | 228 | return ret; |
| 231 | 229 | } |
| @@ -2900,7 +2900,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, · 2899 unmodified lines | ||
| 2900 | 2900 | unsigned long connect_timeout; |
| 2901 | 2901 | unsigned long reconnect_timeout; |
| 2902 | 2902 | unsigned char resvport, reuseport; |
| 2903 | − int ret = 0; | |
| 2903 | + int ret = 0, ident; | |
| 2904 | 2904 | |
| 2905 | 2905 | rcu_read_lock(); |
| 2906 | 2906 | xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); |
| @@ -2914,8 +2914,11 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt, · 7 unmodified lines | ||
| 2914 | 2914 | reuseport = xprt->reuseport; |
| 2915 | 2915 | connect_timeout = xprt->connect_timeout; |
| 2916 | 2916 | reconnect_timeout = xprt->max_reconnect_timeout; |
| 2917 | + ident = xprt->xprt_class->ident; | |
| 2917 | 2918 | rcu_read_unlock(); |
| 2918 | 2919 | |
| 2920 | + if (!xprtargs->ident) | |
| 2921 | + xprtargs->ident = ident; | |
| 2919 | 2922 | xprt = xprt_create_transport(xprtargs); |
| 2920 | 2923 | if (IS_ERR(xprt)) { |
| 2921 | 2924 | ret = PTR_ERR(xprt); |
| @@ -600,9 +600,9 @@ static int __rpc_rmdir(struct inode *dir, struct dentry *dentry) · 599 unmodified lines | ||
| 600 | 600 | |
| 601 | 601 | dget(dentry); |
| 602 | 602 | ret = simple_rmdir(dir, dentry); |
| 603 | + d_drop(dentry); | |
| 603 | 604 | if (!ret) |
| 604 | 605 | fsnotify_rmdir(dir, dentry); |
| 605 | − d_delete(dentry); | |
| 606 | 606 | dput(dentry); |
| 607 | 607 | return ret; |
| 608 | 608 | } |
| @@ -613,9 +613,9 @@ static int __rpc_unlink(struct inode *dir, struct dentry *dentry) · 4 unmodified lines | ||
| 613 | 613 | |
| 614 | 614 | dget(dentry); |
| 615 | 615 | ret = simple_unlink(dir, dentry); |
| 616 | + d_drop(dentry); | |
| 616 | 617 | if (!ret) |
| 617 | 618 | fsnotify_unlink(dir, dentry); |
| 618 | − d_delete(dentry); | |
| 619 | 619 | dput(dentry); |
| 620 | 620 | return ret; |
| 621 | 621 | } |
| @@ -295,8 +295,10 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj, · 294 unmodified lines | ||
| 295 | 295 | online = 1; |
| 296 | 296 | else if (!strncmp(buf, "remove", 6)) |
| 297 | 297 | remove = 1; |
| 298 | − else | |
| 299 | − return -EINVAL; | |
| 298 | + else { | |
| 299 | + count = -EINVAL; | |
| 300 | + goto out_put; | |
| 301 | + } | |
| 300 | 302 | |
| 301 | 303 | if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE)) { |
| 302 | 304 | count = -EINTR; |
| @@ -307,25 +309,28 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj, · 4 unmodified lines | ||
| 307 | 309 | goto release_tasks; |
| 308 | 310 | } |
| 309 | 311 | if (offline) { |
| 310 | − set_bit(XPRT_OFFLINE, &xprt->state); | |
| 311 | − spin_lock(&xps->xps_lock); | |
| 312 | − xps->xps_nactive--; | |
| 313 | − spin_unlock(&xps->xps_lock); | |
| 312 | + if (!test_and_set_bit(XPRT_OFFLINE, &xprt->state)) { | |
| 313 | + spin_lock(&xps->xps_lock); | |
| 314 | + xps->xps_nactive--; | |
| 315 | + spin_unlock(&xps->xps_lock); | |
| 316 | + } | |
| 314 | 317 | } else if (online) { |
| 315 | − clear_bit(XPRT_OFFLINE, &xprt->state); | |
| 316 | − spin_lock(&xps->xps_lock); | |
| 317 | − xps->xps_nactive++; | |
| 318 | − spin_unlock(&xps->xps_lock); | |
| 318 | + if (test_and_clear_bit(XPRT_OFFLINE, &xprt->state)) { | |
| 319 | + spin_lock(&xps->xps_lock); | |
| 320 | + xps->xps_nactive++; | |
| 321 | + spin_unlock(&xps->xps_lock); | |
| 322 | + } | |
| 319 | 323 | } else if (remove) { |
| 320 | 324 | if (test_bit(XPRT_OFFLINE, &xprt->state)) { |
| 321 | − set_bit(XPRT_REMOVE, &xprt->state); | |
| 322 | − xprt_force_disconnect(xprt); | |
| 323 | − if (test_bit(XPRT_CONNECTED, &xprt->state)) { | |
| 324 | − if (!xprt->sending.qlen && | |
| 325 | − !xprt->pending.qlen && | |
| 326 | − !xprt->backlog.qlen && | |
| 327 | − !atomic_long_read(&xprt->queuelen)) | |
| 328 | − rpc_xprt_switch_remove_xprt(xps, xprt); | |
| 325 | + if (!test_and_set_bit(XPRT_REMOVE, &xprt->state)) { | |
| 326 | + xprt_force_disconnect(xprt); | |
| 327 | + if (test_bit(XPRT_CONNECTED, &xprt->state)) { | |
| 328 | + if (!xprt->sending.qlen && | |
| 329 | + !xprt->pending.qlen && | |
| 330 | + !xprt->backlog.qlen && | |
| 331 | + !atomic_long_read(&xprt->queuelen)) | |
| 332 | + rpc_xprt_switch_remove_xprt(xps, xprt); | |
| 333 | + } | |
| 329 | 334 | } |
| 330 | 335 | } else { |
| 331 | 336 | count = -EINVAL; |
| @@ -422,6 +427,7 @@ static struct attribute *rpc_sysfs_xprt_attrs[] = { · 90 unmodified lines | ||
| 422 | 427 | &rpc_sysfs_xprt_change_state.attr, |
| 423 | 428 | NULL, |
| 424 | 429 | }; |
| 430 | +ATTRIBUTE_GROUPS(rpc_sysfs_xprt); | |
| 425 | 431 | |
| 426 | 432 | static struct kobj_attribute rpc_sysfs_xprt_switch_info = |
| 427 | 433 | __ATTR(xprt_switch_info, 0444, rpc_sysfs_xprt_switch_info_show, NULL); |
| @@ -430,6 +436,7 @@ static struct attribute *rpc_sysfs_xprt_switch_attrs[] = { · 2 unmodified lines | ||
| 430 | 436 | &rpc_sysfs_xprt_switch_info.attr, |
| 431 | 437 | NULL, |
| 432 | 438 | }; |
| 439 | +ATTRIBUTE_GROUPS(rpc_sysfs_xprt_switch); | |
| 433 | 440 | |
| 434 | 441 | static struct kobj_type rpc_sysfs_client_type = { |
| 435 | 442 | .release = rpc_sysfs_client_release, |
| @@ -439,14 +446,14 @@ static struct kobj_type rpc_sysfs_client_type = { · 3 unmodified lines | ||
| 439 | 446 | |
| 440 | 447 | static struct kobj_type rpc_sysfs_xprt_switch_type = { |
| 441 | 448 | .release = rpc_sysfs_xprt_switch_release, |
| 442 | − .default_attrs = rpc_sysfs_xprt_switch_attrs, | |
| 449 | + .default_groups = rpc_sysfs_xprt_switch_groups, | |
| 443 | 450 | .sysfs_ops = &kobj_sysfs_ops, |
| 444 | 451 | .namespace = rpc_sysfs_xprt_switch_namespace, |
| 445 | 452 | }; |
| 446 | 453 | |
| 447 | 454 | static struct kobj_type rpc_sysfs_xprt_type = { |
| 448 | 455 | .release = rpc_sysfs_xprt_release, |
| 449 | − .default_attrs = rpc_sysfs_xprt_attrs, | |
| 456 | + .default_groups = rpc_sysfs_xprt_groups, | |
| 450 | 457 | .sysfs_ops = &kobj_sysfs_ops, |
| 451 | 458 | .namespace = rpc_sysfs_xprt_namespace, |
| 452 | 459 | }; |
| @@ -13,10 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | #include "xprt_rdma.h" |
| 14 | 14 | #include <trace/events/rpcrdma.h> |
| 15 | 15 | |
| 16 | −#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | |
| 17 | −# define RPCDBG_FACILITY RPCDBG_TRANS | |
| 18 | −#endif | |
| 19 | − | |
| 20 | 16 | #undef RPCRDMA_BACKCHANNEL_DEBUG |
| 21 | 17 | |
| 22 | 18 | /** |
| @@ -45,10 +45,6 @@ · 44 unmodified lines | ||
| 45 | 45 | #include "xprt_rdma.h" |
| 46 | 46 | #include <trace/events/rpcrdma.h> |
| 47 | 47 | |
| 48 | −#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | |
| 49 | −# define RPCDBG_FACILITY RPCDBG_TRANS | |
| 50 | −#endif | |
| 51 | − | |
| 52 | 48 | static void frwr_cid_init(struct rpcrdma_ep *ep, |
| 53 | 49 | struct rpcrdma_mr *mr) |
| 54 | 50 | { |
| @@ -54,10 +54,6 @@ · 53 unmodified lines | ||
| 54 | 54 | #include "xprt_rdma.h" |
| 55 | 55 | #include <trace/events/rpcrdma.h> |
| 56 | 56 | |
| 57 | −#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | |
| 58 | −# define RPCDBG_FACILITY RPCDBG_TRANS | |
| 59 | −#endif | |
| 60 | − | |
| 61 | 57 | /* Returns size of largest RPC-over-RDMA header in a Call message |
| 62 | 58 | * |
| 63 | 59 | * The largest Call header contains a full-size Read list and a |
| @@ -60,10 +60,6 @@ · 59 unmodified lines | ||
| 60 | 60 | #include "xprt_rdma.h" |
| 61 | 61 | #include <trace/events/rpcrdma.h> |
| 62 | 62 | |
| 63 | −#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | |
| 64 | −# define RPCDBG_FACILITY RPCDBG_TRANS | |
| 65 | −#endif | |
| 66 | − | |
| 67 | 63 | /* |
| 68 | 64 | * tunables |
| 69 | 65 | */ |
| @@ -63,17 +63,6 @@ · 62 unmodified lines | ||
| 63 | 63 | #include "xprt_rdma.h" |
| 64 | 64 | #include <trace/events/rpcrdma.h> |
| 65 | 65 | |
| 66 | −/* | |
| 67 | − * Globals/Macros | |
| 68 | − */ | |
| 69 | − | |
| 70 | −#if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | |
| 71 | −# define RPCDBG_FACILITY RPCDBG_TRANS | |
| 72 | −#endif | |
| 73 | − | |
| 74 | −/* | |
| 75 | − * internal functions | |
| 76 | − */ | |
| 77 | 66 | static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt); |
| 78 | 67 | static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt); |
| 79 | 68 | static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt, |
| @@ -274,8 +263,6 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) · 194 unmodified lines | ||
| 274 | 263 | ep->re_connect_status = -ENETUNREACH; |
| 275 | 264 | goto wake_connect_worker; |
| 276 | 265 | case RDMA_CM_EVENT_REJECTED: |
| 277 | − dprintk("rpcrdma: connection to %pISpc rejected: %s\n", | |
| 278 | − sap, rdma_reject_msg(id, event->status)); | |
| 279 | 266 | ep->re_connect_status = -ECONNREFUSED; |
| 280 | 267 | if (event->status == IB_CM_REJ_STALE_CONN) |
| 281 | 268 | ep->re_connect_status = -ENOTCONN; |
| @@ -291,8 +278,6 @@ disconnected: · 9 unmodified lines | ||
| 291 | 278 | break; |
| 292 | 279 | } |
| 293 | 280 | |
| 294 | − dprintk("RPC: %s: %pISpc on %s/frwr: %s\n", __func__, sap, | |
| 295 | − ep->re_id->device->name, rdma_event_msg(event->event)); | |
| 296 | 281 | return 0; |
| 297 | 282 | } |
| 298 | 283 | |
| @@ -419,14 +404,6 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt) · 120 unmodified lines | ||
| 419 | 404 | ep->re_attr.qp_type = IB_QPT_RC; |
| 420 | 405 | ep->re_attr.port_num = ~0; |
| 421 | 406 | |
| 422 | − dprintk("RPC: %s: requested max: dtos: send %d recv %d; " | |
| 423 | − "iovs: send %d recv %d\n", | |
| 424 | − __func__, | |
| 425 | − ep->re_attr.cap.max_send_wr, | |
| 426 | − ep->re_attr.cap.max_recv_wr, | |
| 427 | − ep->re_attr.cap.max_send_sge, | |
| 428 | − ep->re_attr.cap.max_recv_sge); | |
| 429 | − | |
| 430 | 407 | ep->re_send_batch = ep->re_max_requests >> 3; |
| 431 | 408 | ep->re_send_count = ep->re_send_batch; |
| 432 | 409 | init_waitqueue_head(&ep->re_connect_wait); |
| @@ -1910,7 +1910,7 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task) · 1909 unmodified lines | ||
| 1910 | 1910 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| 1911 | 1911 | int ret; |
| 1912 | 1912 | |
| 1913 | − if (RPC_IS_ASYNC(task)) { | |
| 1913 | + if (RPC_IS_ASYNC(task)) { | |
| 1914 | 1914 | /* |
| 1915 | 1915 | * We want the AF_LOCAL connect to be resolved in the |
| 1916 | 1916 | * filesystem namespace of the process making the rpc |
| @@ -25,7 +25,7 @@ HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include · 24 unmodified lines | ||
| 25 | 25 | HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED |
| 26 | 26 | endif |
| 27 | 27 | |
| 28 | −ifdef CONFIG_DYNAMIC_FTRACE | |
| 28 | +ifdef CONFIG_BUILDTIME_MCOUNT_SORT | |
| 29 | 29 | HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED |
| 30 | 30 | endif |
| 31 | 31 | |
| @@ -1048,8 +1048,19 @@ int security_dentry_init_security(struct dentry *dentry, int mode, · 1047 unmodified lines | ||
| 1048 | 1048 | const char **xattr_name, void **ctx, |
| 1049 | 1049 | u32 *ctxlen) |
| 1050 | 1050 | { |
| 1051 | − return call_int_hook(dentry_init_security, -EOPNOTSUPP, dentry, mode, | |
| 1052 | − name, xattr_name, ctx, ctxlen); | |
| 1051 | + struct security_hook_list *hp; | |
| 1052 | + int rc; | |
| 1053 | + | |
| 1054 | + /* | |
| 1055 | + * Only one module will provide a security context. | |
| 1056 | + */ | |
| 1057 | + hlist_for_each_entry(hp, &security_hook_heads.dentry_init_security, list) { | |
| 1058 | + rc = hp->hook.dentry_init_security(dentry, mode, name, | |
| 1059 | + xattr_name, ctx, ctxlen); | |
| 1060 | + if (rc != LSM_RET_DEFAULT(dentry_init_security)) | |
| 1061 | + return rc; | |
| 1062 | + } | |
| 1063 | + return LSM_RET_DEFAULT(dentry_init_security); | |
| 1053 | 1064 | } |
| 1054 | 1065 | EXPORT_SYMBOL(security_dentry_init_security); |
| 1055 | 1066 | |
| @@ -452,6 +452,9 @@ struct kvm_sync_regs { · 451 unmodified lines | ||
| 452 | 452 | |
| 453 | 453 | #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001 |
| 454 | 454 | |
| 455 | +/* attributes for system fd (group 0) */ | |
| 456 | +#define KVM_X86_XCOMP_GUEST_SUPP 0 | |
| 457 | + | |
| 455 | 458 | struct kvm_vmx_nested_state_data { |
| 456 | 459 | __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; |
| 457 | 460 | __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; |
| @@ -68,7 +68,7 @@ int handle__sched_switch(u64 *ctx) · 67 unmodified lines | ||
| 68 | 68 | */ |
| 69 | 69 | struct task_struct *prev = (struct task_struct *)ctx[1]; |
| 70 | 70 | struct task_struct *next = (struct task_struct *)ctx[2]; |
| 71 | − struct event event = {}; | |
| 71 | + struct runq_event event = {}; | |
| 72 | 72 | u64 *tsp, delta_us; |
| 73 | 73 | long state; |
| 74 | 74 | u32 pid; |
| @@ -100,7 +100,7 @@ static int bump_memlock_rlimit(void) · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | void handle_event(void *ctx, int cpu, void *data, __u32 data_sz) |
| 102 | 102 | { |
| 103 | − const struct event *e = data; | |
| 103 | + const struct runq_event *e = data; | |
| 104 | 104 | struct tm *tm; |
| 105 | 105 | char ts[32]; |
| 106 | 106 | time_t t; |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #define TASK_COMM_LEN 16 |
| 6 | 6 | |
| 7 | −struct event { | |
| 7 | +struct runq_event { | |
| 8 | 8 | char task[TASK_COMM_LEN]; |
| 9 | 9 | __u64 delta_us; |
| 10 | 10 | pid_t pid; |
| @@ -1133,6 +1133,7 @@ struct kvm_ppc_resize_hpt { · 1132 unmodified lines | ||
| 1133 | 1133 | #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206 |
| 1134 | 1134 | #define KVM_CAP_VM_GPA_BITS 207 |
| 1135 | 1135 | #define KVM_CAP_XSAVE2 208 |
| 1136 | +#define KVM_CAP_SYS_ATTRIBUTES 209 | |
| 1136 | 1137 | |
| 1137 | 1138 | #ifdef KVM_CAP_IRQ_ROUTING |
| 1138 | 1139 | |
| @@ -74,7 +74,7 @@ static inline unsigned long page_to_phys(struct page *page) · 73 unmodified lines | ||
| 74 | 74 | __UNIQUE_ID(min1_), __UNIQUE_ID(min2_), \ |
| 75 | 75 | x, y) |
| 76 | 76 | |
| 77 | −#define preemptible() (1) | |
| 77 | +#define pagefault_disabled() (0) | |
| 78 | 78 | |
| 79 | 79 | static inline void *kmap(struct page *page) |
| 80 | 80 | { |
| @@ -127,6 +127,7 @@ kmalloc_array(unsigned int n, unsigned int size, unsigned int flags) · 46 unmodified lines | ||
| 127 | 127 | #define kmemleak_free(a) |
| 128 | 128 | |
| 129 | 129 | #define PageSlab(p) (0) |
| 130 | +#define flush_dcache_page(p) | |
| 130 | 131 | |
| 131 | 132 | #define MAX_ERRNO 4095 |
| 132 | 133 | |
| @@ -261,7 +261,7 @@ static void ptrace_sve_fpsimd(pid_t child, const struct vec_type *type) · 260 unmodified lines | ||
| 261 | 261 | } |
| 262 | 262 | |
| 263 | 263 | ksft_test_result((sve->flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD, |
| 264 | − "Set FPSIMD registers via %s\n", type->name); | |
| 264 | + "Got FPSIMD registers via %s\n", type->name); | |
| 265 | 265 | if ((sve->flags & SVE_PT_REGS_MASK) != SVE_PT_REGS_FPSIMD) |
| 266 | 266 | goto out; |
| 267 | 267 | |
| @@ -557,7 +557,14 @@ static int do_parent(pid_t child) · 289 unmodified lines | ||
| 557 | 557 | } |
| 558 | 558 | |
| 559 | 559 | /* prctl() flags */ |
| 560 | − ptrace_set_get_inherit(child, &vec_types[i]); | |
| 560 | + if (getauxval(vec_types[i].hwcap_type) & vec_types[i].hwcap) { | |
| 561 | + ptrace_set_get_inherit(child, &vec_types[i]); | |
| 562 | + } else { | |
| 563 | + ksft_test_result_skip("%s SVE_PT_VL_INHERIT set\n", | |
| 564 | + vec_types[i].name); | |
| 565 | + ksft_test_result_skip("%s SVE_PT_VL_INHERIT cleared\n", | |
| 566 | + vec_types[i].name); | |
| 567 | + } | |
| 561 | 568 | |
| 562 | 569 | /* Step through every possible VQ */ |
| 563 | 570 | for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) { |
| @@ -85,6 +85,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/xen_vmcall_test · 84 unmodified lines | ||
| 85 | 85 | TEST_GEN_PROGS_x86_64 += x86_64/vmx_pi_mmio_test |
| 86 | 86 | TEST_GEN_PROGS_x86_64 += x86_64/sev_migrate_tests |
| 87 | 87 | TEST_GEN_PROGS_x86_64 += x86_64/amx_test |
| 88 | +TEST_GEN_PROGS_x86_64 += access_tracking_perf_test | |
| 88 | 89 | TEST_GEN_PROGS_x86_64 += demand_paging_test |
| 89 | 90 | TEST_GEN_PROGS_x86_64 += dirty_log_test |
| 90 | 91 | TEST_GEN_PROGS_x86_64 += dirty_log_perf_test |
| @@ -345,7 +345,6 @@ struct kvm_vm *vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr_vcpus, · 344 unmodified lines | ||
| 345 | 345 | * guest_code - The vCPU's entry point |
| 346 | 346 | */ |
| 347 | 347 | void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code); |
| 348 | −void vm_xsave_req_perm(void); | |
| 349 | 348 | |
| 350 | 349 | bool vm_is_unrestricted_guest(struct kvm_vm *vm); |
| 351 | 350 | |
| @@ -458,6 +458,7 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2, · 457 unmodified lines | ||
| 458 | 458 | struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void); |
| 459 | 459 | void vcpu_set_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid); |
| 460 | 460 | struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vm *vm, uint32_t vcpuid); |
| 461 | +void vm_xsave_req_perm(int bit); | |
| 461 | 462 | |
| 462 | 463 | enum x86_page_size { |
| 463 | 464 | X86_PAGE_SIZE_4K = 0, |
| @@ -393,13 +393,6 @@ struct kvm_vm *vm_create_with_vcpus(enum vm_guest_mode mode, uint32_t nr_vcpus, · 392 unmodified lines | ||
| 393 | 393 | struct kvm_vm *vm; |
| 394 | 394 | int i; |
| 395 | 395 | |
| 396 | −#ifdef __x86_64__ | |
| 397 | − /* | |
| 398 | − * Permission needs to be requested before KVM_SET_CPUID2. | |
| 399 | − */ | |
| 400 | − vm_xsave_req_perm(); | |
| 401 | −#endif | |
| 402 | − | |
| 403 | 396 | /* Force slot0 memory size not small than DEFAULT_GUEST_PHY_PAGES */ |
| 404 | 397 | if (slot0_mem_pages < DEFAULT_GUEST_PHY_PAGES) |
| 405 | 398 | slot0_mem_pages = DEFAULT_GUEST_PHY_PAGES; |
| @@ -665,16 +665,31 @@ static bool is_xfd_supported(void) · 664 unmodified lines | ||
| 665 | 665 | return !!(eax & CPUID_XFD_BIT); |
| 666 | 666 | } |
| 667 | 667 | |
| 668 | −void vm_xsave_req_perm(void) | |
| 668 | +void vm_xsave_req_perm(int bit) | |
| 669 | 669 | { |
| 670 | − unsigned long bitmask; | |
| 670 | + int kvm_fd; | |
| 671 | + u64 bitmask; | |
| 671 | 672 | long rc; |
| 673 | + struct kvm_device_attr attr = { | |
| 674 | + .group = 0, | |
| 675 | + .attr = KVM_X86_XCOMP_GUEST_SUPP, | |
| 676 | + .addr = (unsigned long) &bitmask | |
| 677 | + }; | |
| 678 | + | |
| 679 | + kvm_fd = open_kvm_dev_path_or_exit(); | |
| 680 | + rc = ioctl(kvm_fd, KVM_GET_DEVICE_ATTR, &attr); | |
| 681 | + close(kvm_fd); | |
| 682 | + if (rc == -1 && (errno == ENXIO || errno == EINVAL)) | |
| 683 | + exit(KSFT_SKIP); | |
| 684 | + TEST_ASSERT(rc == 0, "KVM_GET_DEVICE_ATTR(0, KVM_X86_XCOMP_GUEST_SUPP) error: %ld", rc); | |
| 685 | + if (!(bitmask & (1ULL << bit))) | |
| 686 | + exit(KSFT_SKIP); | |
| 672 | 687 | |
| 673 | 688 | if (!is_xfd_supported()) |
| 674 | − return; | |
| 689 | + exit(KSFT_SKIP); | |
| 690 | + | |
| 691 | + rc = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_GUEST_PERM, bit); | |
| 675 | 692 | |
| 676 | − rc = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_GUEST_PERM, | |
| 677 | − XSTATE_XTILE_DATA_BIT); | |
| 678 | 693 | /* |
| 679 | 694 | * The older kernel version(<5.15) can't support |
| 680 | 695 | * ARCH_REQ_XCOMP_GUEST_PERM and directly return. |
| @@ -684,7 +699,7 @@ void vm_xsave_req_perm(void) · 3 unmodified lines | ||
| 684 | 699 | |
| 685 | 700 | rc = syscall(SYS_arch_prctl, ARCH_GET_XCOMP_GUEST_PERM, &bitmask); |
| 686 | 701 | TEST_ASSERT(rc == 0, "prctl(ARCH_GET_XCOMP_GUEST_PERM) error: %ld", rc); |
| 687 | − TEST_ASSERT(bitmask & XFEATURE_XTILE_MASK, | |
| 702 | + TEST_ASSERT(bitmask & (1ULL << bit), | |
| 688 | 703 | "prctl(ARCH_REQ_XCOMP_GUEST_PERM) failure bitmask=0x%lx", |
| 689 | 704 | bitmask); |
| 690 | 705 | } |
| @@ -329,6 +329,8 @@ int main(int argc, char *argv[]) · 328 unmodified lines | ||
| 329 | 329 | u32 amx_offset; |
| 330 | 330 | int stage, ret; |
| 331 | 331 | |
| 332 | + vm_xsave_req_perm(XSTATE_XTILE_DATA_BIT); | |
| 333 | + | |
| 332 | 334 | /* Create VM */ |
| 333 | 335 | vm = vm_create_default(VCPU_ID, 0, guest_code); |
| 334 | 336 | |
| @@ -105,7 +105,6 @@ static void guest_code(void *arg) · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | if (cpu_has_svm()) { |
| 107 | 107 | run_guest(svm->vmcb, svm->vmcb_gpa); |
| 108 | − svm->vmcb->save.rip += 3; | |
| 109 | 108 | run_guest(svm->vmcb, svm->vmcb_gpa); |
| 110 | 109 | } else { |
| 111 | 110 | vmlaunch(); |
| @@ -240,11 +240,8 @@ static int check_ioam6_data(__u8 **p, struct ioam6_trace_hdr *ioam6h, · 239 unmodified lines | ||
| 240 | 240 | *p += sizeof(__u32); |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | − if (ioam6h->type.bit6) { | |
| 244 | − if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) | |
| 245 | − return 1; | |
| 243 | + if (ioam6h->type.bit6) | |
| 246 | 244 | *p += sizeof(__u32); |
| 247 | − } | |
| 248 | 245 | |
| 249 | 246 | if (ioam6h->type.bit7) { |
| 250 | 247 | if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) |
| @@ -75,6 +75,7 @@ init() · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | # let $ns2 reach any $ns1 address from any interface |
| 77 | 77 | ip -net "$ns2" route add default via 10.0.$i.1 dev ns2eth$i metric 10$i |
| 78 | + ip -net "$ns2" route add default via dead:beef:$i::1 dev ns2eth$i metric 10$i | |
| 78 | 79 | done |
| 79 | 80 | } |
| 80 | 81 | |
| @@ -1476,7 +1477,7 @@ ipv6_tests() · 1395 unmodified lines | ||
| 1476 | 1477 | reset |
| 1477 | 1478 | ip netns exec $ns1 ./pm_nl_ctl limits 0 1 |
| 1478 | 1479 | ip netns exec $ns2 ./pm_nl_ctl limits 0 1 |
| 1479 | − ip netns exec $ns2 ./pm_nl_ctl add dead:beef:3::2 flags subflow | |
| 1480 | + ip netns exec $ns2 ./pm_nl_ctl add dead:beef:3::2 dev ns2eth3 flags subflow | |
| 1480 | 1481 | run_tests $ns1 $ns2 dead:beef:1::1 0 0 0 slow |
| 1481 | 1482 | chk_join_nr "single subflow IPv6" 1 1 1 |
| 1482 | 1483 | |
| @@ -1511,7 +1512,7 @@ ipv6_tests() · 28 unmodified lines | ||
| 1511 | 1512 | ip netns exec $ns1 ./pm_nl_ctl limits 0 2 |
| 1512 | 1513 | ip netns exec $ns1 ./pm_nl_ctl add dead:beef:2::1 flags signal |
| 1513 | 1514 | ip netns exec $ns2 ./pm_nl_ctl limits 1 2 |
| 1514 | − ip netns exec $ns2 ./pm_nl_ctl add dead:beef:3::2 flags subflow | |
| 1515 | + ip netns exec $ns2 ./pm_nl_ctl add dead:beef:3::2 dev ns2eth3 flags subflow | |
| 1515 | 1516 | run_tests $ns1 $ns2 dead:beef:1::1 0 -1 -1 slow |
| 1516 | 1517 | chk_join_nr "remove subflow and signal IPv6" 2 2 2 |
| 1517 | 1518 | chk_add_nr 1 1 |
| @@ -1,11 +1,11 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | include ../scripts/Makefile.include |
| 3 | 3 | |
| 4 | −all: latency | |
| 4 | +all: latency rtla | |
| 5 | 5 | |
| 6 | −clean: latency_clean | |
| 6 | +clean: latency_clean rtla_clean | |
| 7 | 7 | |
| 8 | −install: latency_install | |
| 8 | +install: latency_install rtla_install | |
| 9 | 9 | |
| 10 | 10 | latency: |
| 11 | 11 | $(call descend,latency) |
| @@ -16,4 +16,14 @@ latency_install: · 4 unmodified lines | ||
| 16 | 16 | latency_clean: |
| 17 | 17 | $(call descend,latency,clean) |
| 18 | 18 | |
| 19 | −.PHONY: all install clean latency latency_install latency_clean | |
| 19 | +rtla: | |
| 20 | + $(call descend,rtla) | |
| 21 | + | |
| 22 | +rtla_install: | |
| 23 | + $(call descend,rtla,install) | |
| 24 | + | |
| 25 | +rtla_clean: | |
| 26 | + $(call descend,rtla,clean) | |
| 27 | + | |
| 28 | +.PHONY: all install clean latency latency_install latency_clean \ | |
| 29 | + rtla rtla_install rtla_clean | |
| @@ -59,7 +59,7 @@ endif · 58 unmodified lines | ||
| 59 | 59 | .PHONY: all |
| 60 | 60 | all: rtla |
| 61 | 61 | |
| 62 | −rtla: $(OBJ) doc | |
| 62 | +rtla: $(OBJ) | |
| 63 | 63 | $(CC) -o rtla $(LDFLAGS) $(OBJ) $(LIBS) |
| 64 | 64 | |
| 65 | 65 | static: $(OBJ) |
| @@ -28,6 +28,7 @@ no-header-test += linux/am437x-vpfe.h · 27 unmodified lines | ||
| 28 | 28 | no-header-test += linux/android/binder.h |
| 29 | 29 | no-header-test += linux/android/binderfs.h |
| 30 | 30 | no-header-test += linux/coda.h |
| 31 | +no-header-test += linux/cyclades.h | |
| 31 | 32 | no-header-test += linux/errqueue.h |
| 32 | 33 | no-header-test += linux/fsmap.h |
| 33 | 34 | no-header-test += linux/hdlc/ioctl.h |
| @@ -463,8 +463,8 @@ bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) · 462 unmodified lines | ||
| 463 | 463 | idx = srcu_read_lock(&kvm->irq_srcu); |
| 464 | 464 | gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); |
| 465 | 465 | if (gsi != -1) |
| 466 | − hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | |
| 467 | − link) | |
| 466 | + hlist_for_each_entry_srcu(kian, &kvm->irq_ack_notifier_list, | |
| 467 | + link, srcu_read_lock_held(&kvm->irq_srcu)) | |
| 468 | 468 | if (kian->gsi == gsi) { |
| 469 | 469 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 470 | 470 | return true; |
| @@ -480,8 +480,8 @@ void kvm_notify_acked_gsi(struct kvm *kvm, int gsi) · 9 unmodified lines | ||
| 480 | 480 | { |
| 481 | 481 | struct kvm_irq_ack_notifier *kian; |
| 482 | 482 | |
| 483 | − hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, | |
| 484 | − link) | |
| 483 | + hlist_for_each_entry_srcu(kian, &kvm->irq_ack_notifier_list, | |
| 484 | + link, srcu_read_lock_held(&kvm->irq_srcu)) | |
| 485 | 485 | if (kian->gsi == gsi) |
| 486 | 486 | kian->irq_acked(kian); |
| 487 | 487 | } |
| @@ -2248,7 +2248,6 @@ struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn · 2247 unmodified lines | ||
| 2248 | 2248 | |
| 2249 | 2249 | return NULL; |
| 2250 | 2250 | } |
| 2251 | −EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_memslot); | |
| 2252 | 2251 | |
| 2253 | 2252 | bool kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) |
| 2254 | 2253 | { |
| @@ -2463,9 +2462,8 @@ static int kvm_try_get_pfn(kvm_pfn_t pfn) · 208 unmodified lines | ||
| 2463 | 2462 | } |
| 2464 | 2463 | |
| 2465 | 2464 | static int hva_to_pfn_remapped(struct vm_area_struct *vma, |
| 2466 | − unsigned long addr, bool *async, | |
| 2467 | − bool write_fault, bool *writable, | |
| 2468 | − kvm_pfn_t *p_pfn) | |
| 2465 | + unsigned long addr, bool write_fault, | |
| 2466 | + bool *writable, kvm_pfn_t *p_pfn) | |
| 2469 | 2467 | { |
| 2470 | 2468 | kvm_pfn_t pfn; |
| 2471 | 2469 | pte_t *ptep; |
| @@ -2575,7 +2573,7 @@ retry: · 103 unmodified lines | ||
| 2575 | 2573 | if (vma == NULL) |
| 2576 | 2574 | pfn = KVM_PFN_ERR_FAULT; |
| 2577 | 2575 | else if (vma->vm_flags & (VM_IO | VM_PFNMAP)) { |
| 2578 | − r = hva_to_pfn_remapped(vma, addr, async, write_fault, writable, &pfn); | |
| 2576 | + r = hva_to_pfn_remapped(vma, addr, write_fault, writable, &pfn); | |
| 2579 | 2577 | if (r == -EAGAIN) |
| 2580 | 2578 | goto retry; |
| 2581 | 2579 | if (r < 0) |