We want the driver core fixes in here and this resolves a merge issue with drivers/base/dd.c
Unified · Split
| @@ -182,12 +182,15 @@ fix_padding · 181 unmodified lines | ||
| 182 | 182 | space-efficient. If this option is not present, large padding is |
| 183 | 183 | used - that is for compatibility with older kernels. |
| 184 | 184 | |
| 185 | − | |
| 186 | −The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can | |
| 187 | −be changed when reloading the target (load an inactive table and swap the | |
| 188 | −tables with suspend and resume). The other arguments should not be changed | |
| 189 | −when reloading the target because the layout of disk data depend on them | |
| 190 | −and the reloaded target would be non-functional. | |
| 185 | +allow_discards | |
| 186 | + Allow block discard requests (a.k.a. TRIM) for the integrity device. | |
| 187 | + Discards are only allowed to devices using internal hash. | |
| 188 | + | |
| 189 | +The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and | |
| 190 | +allow_discards can be changed when reloading the target (load an inactive | |
| 191 | +table and swap the tables with suspend and resume). The other arguments | |
| 192 | +should not be changed when reloading the target because the layout of disk | |
| 193 | +data depend on them and the reloaded target would be non-functional. | |
| 191 | 194 | |
| 192 | 195 | |
| 193 | 196 | The layout of the formatted block device: |
| @@ -22,9 +22,7 @@ properties: · 21 unmodified lines | ||
| 22 | 22 | const: socionext,uniphier-xdmac |
| 23 | 23 | |
| 24 | 24 | reg: |
| 25 | − items: | |
| 26 | − - description: XDMAC base register region (offset and length) | |
| 27 | − - description: XDMAC extension register region (offset and length) | |
| 25 | + maxItems: 1 | |
| 28 | 26 | |
| 29 | 27 | interrupts: |
| 30 | 28 | maxItems: 1 |
| @@ -49,12 +47,13 @@ required: · 18 unmodified lines | ||
| 49 | 47 | - reg |
| 50 | 48 | - interrupts |
| 51 | 49 | - "#dma-cells" |
| 50 | + - dma-channels | |
| 52 | 51 | |
| 53 | 52 | examples: |
| 54 | 53 | - | |
| 55 | 54 | xdmac: dma-controller@5fc10000 { |
| 56 | 55 | compatible = "socionext,uniphier-xdmac"; |
| 57 | − reg = <0x5fc10000 0x1000>, <0x5fc20000 0x800>; | |
| 56 | + reg = <0x5fc10000 0x5300>; | |
| 58 | 57 | interrupts = <0 188 4>; |
| 59 | 58 | #dma-cells = <2>; |
| 60 | 59 | dma-channels = <16>; |
| @@ -61,8 +61,8 @@ The ``ice`` driver reports the following versions · 60 unmodified lines | ||
| 61 | 61 | - running |
| 62 | 62 | - ICE OS Default Package |
| 63 | 63 | - The name of the DDP package that is active in the device. The DDP |
| 64 | − package is loaded by the driver during initialization. Each varation | |
| 65 | − of DDP package shall have a unique name. | |
| 64 | + package is loaded by the driver during initialization. Each | |
| 65 | + variation of the DDP package has a unique name. | |
| 66 | 66 | * - ``fw.app`` |
| 67 | 67 | - running |
| 68 | 68 | - 1.3.1.0 |
| @@ -28,3 +28,5 @@ KVM · 27 unmodified lines | ||
| 28 | 28 | arm/index |
| 29 | 29 | |
| 30 | 30 | devices/index |
| 31 | + | |
| 32 | + running-nested-guests | |
| @@ -0,0 +1,276 @@ | ||
| 1 | +============================== | |
| 2 | +Running nested guests with KVM | |
| 3 | +============================== | |
| 4 | + | |
| 5 | +A nested guest is the ability to run a guest inside another guest (it | |
| 6 | +can be KVM-based or a different hypervisor). The straightforward | |
| 7 | +example is a KVM guest that in turn runs on a KVM guest (the rest of | |
| 8 | +this document is built on this example):: | |
| 9 | + | |
| 10 | + .----------------. .----------------. | |
| 11 | + | | | | | |
| 12 | + | L2 | | L2 | | |
| 13 | + | (Nested Guest) | | (Nested Guest) | | |
| 14 | + | | | | | |
| 15 | + |----------------'--'----------------| | |
| 16 | + | | | |
| 17 | + | L1 (Guest Hypervisor) | | |
| 18 | + | KVM (/dev/kvm) | | |
| 19 | + | | | |
| 20 | + .------------------------------------------------------. | |
| 21 | + | L0 (Host Hypervisor) | | |
| 22 | + | KVM (/dev/kvm) | | |
| 23 | + |------------------------------------------------------| | |
| 24 | + | Hardware (with virtualization extensions) | | |
| 25 | + '------------------------------------------------------' | |
| 26 | + | |
| 27 | +Terminology: | |
| 28 | + | |
| 29 | +- L0 – level-0; the bare metal host, running KVM | |
| 30 | + | |
| 31 | +- L1 – level-1 guest; a VM running on L0; also called the "guest | |
| 32 | + hypervisor", as it itself is capable of running KVM. | |
| 33 | + | |
| 34 | +- L2 – level-2 guest; a VM running on L1, this is the "nested guest" | |
| 35 | + | |
| 36 | +.. note:: The above diagram is modelled after the x86 architecture; | |
| 37 | + s390x, ppc64 and other architectures are likely to have | |
| 38 | + a different design for nesting. | |
| 39 | + | |
| 40 | + For example, s390x always has an LPAR (LogicalPARtition) | |
| 41 | + hypervisor running on bare metal, adding another layer and | |
| 42 | + resulting in at least four levels in a nested setup — L0 (bare | |
| 43 | + metal, running the LPAR hypervisor), L1 (host hypervisor), L2 | |
| 44 | + (guest hypervisor), L3 (nested guest). | |
| 45 | + | |
| 46 | + This document will stick with the three-level terminology (L0, | |
| 47 | + L1, and L2) for all architectures; and will largely focus on | |
| 48 | + x86. | |
| 49 | + | |
| 50 | + | |
| 51 | +Use Cases | |
| 52 | +--------- | |
| 53 | + | |
| 54 | +There are several scenarios where nested KVM can be useful, to name a | |
| 55 | +few: | |
| 56 | + | |
| 57 | +- As a developer, you want to test your software on different operating | |
| 58 | + systems (OSes). Instead of renting multiple VMs from a Cloud | |
| 59 | + Provider, using nested KVM lets you rent a large enough "guest | |
| 60 | + hypervisor" (level-1 guest). This in turn allows you to create | |
| 61 | + multiple nested guests (level-2 guests), running different OSes, on | |
| 62 | + which you can develop and test your software. | |
| 63 | + | |
| 64 | +- Live migration of "guest hypervisors" and their nested guests, for | |
| 65 | + load balancing, disaster recovery, etc. | |
| 66 | + | |
| 67 | +- VM image creation tools (e.g. ``virt-install``, etc) often run | |
| 68 | + their own VM, and users expect these to work inside a VM. | |
| 69 | + | |
| 70 | +- Some OSes use virtualization internally for security (e.g. to let | |
| 71 | + applications run safely in isolation). | |
| 72 | + | |
| 73 | + | |
| 74 | +Enabling "nested" (x86) | |
| 75 | +----------------------- | |
| 76 | + | |
| 77 | +From Linux kernel v4.19 onwards, the ``nested`` KVM parameter is enabled | |
| 78 | +by default for Intel and AMD. (Though your Linux distribution might | |
| 79 | +override this default.) | |
| 80 | + | |
| 81 | +In case you are running a Linux kernel older than v4.19, to enable | |
| 82 | +nesting, set the ``nested`` KVM module parameter to ``Y`` or ``1``. To | |
| 83 | +persist this setting across reboots, you can add it in a config file, as | |
| 84 | +shown below: | |
| 85 | + | |
| 86 | +1. On the bare metal host (L0), list the kernel modules and ensure that | |
| 87 | + the KVM modules:: | |
| 88 | + | |
| 89 | + $ lsmod | grep -i kvm | |
| 90 | + kvm_intel 133627 0 | |
| 91 | + kvm 435079 1 kvm_intel | |
| 92 | + | |
| 93 | +2. Show information for ``kvm_intel`` module:: | |
| 94 | + | |
| 95 | + $ modinfo kvm_intel | grep -i nested | |
| 96 | + parm: nested:bool | |
| 97 | + | |
| 98 | +3. For the nested KVM configuration to persist across reboots, place the | |
| 99 | + below in ``/etc/modprobed/kvm_intel.conf`` (create the file if it | |
| 100 | + doesn't exist):: | |
| 101 | + | |
| 102 | + $ cat /etc/modprobe.d/kvm_intel.conf | |
| 103 | + options kvm-intel nested=y | |
| 104 | + | |
| 105 | +4. Unload and re-load the KVM Intel module:: | |
| 106 | + | |
| 107 | + $ sudo rmmod kvm-intel | |
| 108 | + $ sudo modprobe kvm-intel | |
| 109 | + | |
| 110 | +5. Verify if the ``nested`` parameter for KVM is enabled:: | |
| 111 | + | |
| 112 | + $ cat /sys/module/kvm_intel/parameters/nested | |
| 113 | + Y | |
| 114 | + | |
| 115 | +For AMD hosts, the process is the same as above, except that the module | |
| 116 | +name is ``kvm-amd``. | |
| 117 | + | |
| 118 | + | |
| 119 | +Additional nested-related kernel parameters (x86) | |
| 120 | +------------------------------------------------- | |
| 121 | + | |
| 122 | +If your hardware is sufficiently advanced (Intel Haswell processor or | |
| 123 | +higher, which has newer hardware virt extensions), the following | |
| 124 | +additional features will also be enabled by default: "Shadow VMCS | |
| 125 | +(Virtual Machine Control Structure)", APIC Virtualization on your bare | |
| 126 | +metal host (L0). Parameters for Intel hosts:: | |
| 127 | + | |
| 128 | + $ cat /sys/module/kvm_intel/parameters/enable_shadow_vmcs | |
| 129 | + Y | |
| 130 | + | |
| 131 | + $ cat /sys/module/kvm_intel/parameters/enable_apicv | |
| 132 | + Y | |
| 133 | + | |
| 134 | + $ cat /sys/module/kvm_intel/parameters/ept | |
| 135 | + Y | |
| 136 | + | |
| 137 | +.. note:: If you suspect your L2 (i.e. nested guest) is running slower, | |
| 138 | + ensure the above are enabled (particularly | |
| 139 | + ``enable_shadow_vmcs`` and ``ept``). | |
| 140 | + | |
| 141 | + | |
| 142 | +Starting a nested guest (x86) | |
| 143 | +----------------------------- | |
| 144 | + | |
| 145 | +Once your bare metal host (L0) is configured for nesting, you should be | |
| 146 | +able to start an L1 guest with:: | |
| 147 | + | |
| 148 | + $ qemu-kvm -cpu host [...] | |
| 149 | + | |
| 150 | +The above will pass through the host CPU's capabilities as-is to the | |
| 151 | +gues); or for better live migration compatibility, use a named CPU | |
| 152 | +model supported by QEMU. e.g.:: | |
| 153 | + | |
| 154 | + $ qemu-kvm -cpu Haswell-noTSX-IBRS,vmx=on | |
| 155 | + | |
| 156 | +then the guest hypervisor will subsequently be capable of running a | |
| 157 | +nested guest with accelerated KVM. | |
| 158 | + | |
| 159 | + | |
| 160 | +Enabling "nested" (s390x) | |
| 161 | +------------------------- | |
| 162 | + | |
| 163 | +1. On the host hypervisor (L0), enable the ``nested`` parameter on | |
| 164 | + s390x:: | |
| 165 | + | |
| 166 | + $ rmmod kvm | |
| 167 | + $ modprobe kvm nested=1 | |
| 168 | + | |
| 169 | +.. note:: On s390x, the kernel parameter ``hpage`` is mutually exclusive | |
| 170 | + with the ``nested`` paramter — i.e. to be able to enable | |
| 171 | + ``nested``, the ``hpage`` parameter *must* be disabled. | |
| 172 | + | |
| 173 | +2. The guest hypervisor (L1) must be provided with the ``sie`` CPU | |
| 174 | + feature — with QEMU, this can be done by using "host passthrough" | |
| 175 | + (via the command-line ``-cpu host``). | |
| 176 | + | |
| 177 | +3. Now the KVM module can be loaded in the L1 (guest hypervisor):: | |
| 178 | + | |
| 179 | + $ modprobe kvm | |
| 180 | + | |
| 181 | + | |
| 182 | +Live migration with nested KVM | |
| 183 | +------------------------------ | |
| 184 | + | |
| 185 | +Migrating an L1 guest, with a *live* nested guest in it, to another | |
| 186 | +bare metal host, works as of Linux kernel 5.3 and QEMU 4.2.0 for | |
| 187 | +Intel x86 systems, and even on older versions for s390x. | |
| 188 | + | |
| 189 | +On AMD systems, once an L1 guest has started an L2 guest, the L1 guest | |
| 190 | +should no longer be migrated or saved (refer to QEMU documentation on | |
| 191 | +"savevm"/"loadvm") until the L2 guest shuts down. Attempting to migrate | |
| 192 | +or save-and-load an L1 guest while an L2 guest is running will result in | |
| 193 | +undefined behavior. You might see a ``kernel BUG!`` entry in ``dmesg``, a | |
| 194 | +kernel 'oops', or an outright kernel panic. Such a migrated or loaded L1 | |
| 195 | +guest can no longer be considered stable or secure, and must be restarted. | |
| 196 | +Migrating an L1 guest merely configured to support nesting, while not | |
| 197 | +actually running L2 guests, is expected to function normally even on AMD | |
| 198 | +systems but may fail once guests are started. | |
| 199 | + | |
| 200 | +Migrating an L2 guest is always expected to succeed, so all the following | |
| 201 | +scenarios should work even on AMD systems: | |
| 202 | + | |
| 203 | +- Migrating a nested guest (L2) to another L1 guest on the *same* bare | |
| 204 | + metal host. | |
| 205 | + | |
| 206 | +- Migrating a nested guest (L2) to another L1 guest on a *different* | |
| 207 | + bare metal host. | |
| 208 | + | |
| 209 | +- Migrating a nested guest (L2) to a bare metal host. | |
| 210 | + | |
| 211 | +Reporting bugs from nested setups | |
| 212 | +----------------------------------- | |
| 213 | + | |
| 214 | +Debugging "nested" problems can involve sifting through log files across | |
| 215 | +L0, L1 and L2; this can result in tedious back-n-forth between the bug | |
| 216 | +reporter and the bug fixer. | |
| 217 | + | |
| 218 | +- Mention that you are in a "nested" setup. If you are running any kind | |
| 219 | + of "nesting" at all, say so. Unfortunately, this needs to be called | |
| 220 | + out because when reporting bugs, people tend to forget to even | |
| 221 | + *mention* that they're using nested virtualization. | |
| 222 | + | |
| 223 | +- Ensure you are actually running KVM on KVM. Sometimes people do not | |
| 224 | + have KVM enabled for their guest hypervisor (L1), which results in | |
| 225 | + them running with pure emulation or what QEMU calls it as "TCG", but | |
| 226 | + they think they're running nested KVM. Thus confusing "nested Virt" | |
| 227 | + (which could also mean, QEMU on KVM) with "nested KVM" (KVM on KVM). | |
| 228 | + | |
| 229 | +Information to collect (generic) | |
| 230 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 231 | + | |
| 232 | +The following is not an exhaustive list, but a very good starting point: | |
| 233 | + | |
| 234 | + - Kernel, libvirt, and QEMU version from L0 | |
| 235 | + | |
| 236 | + - Kernel, libvirt and QEMU version from L1 | |
| 237 | + | |
| 238 | + - QEMU command-line of L1 -- when using libvirt, you'll find it here: | |
| 239 | + ``/var/log/libvirt/qemu/instance.log`` | |
| 240 | + | |
| 241 | + - QEMU command-line of L2 -- as above, when using libvirt, get the | |
| 242 | + complete libvirt-generated QEMU command-line | |
| 243 | + | |
| 244 | + - ``cat /sys/cpuinfo`` from L0 | |
| 245 | + | |
| 246 | + - ``cat /sys/cpuinfo`` from L1 | |
| 247 | + | |
| 248 | + - ``lscpu`` from L0 | |
| 249 | + | |
| 250 | + - ``lscpu`` from L1 | |
| 251 | + | |
| 252 | + - Full ``dmesg`` output from L0 | |
| 253 | + | |
| 254 | + - Full ``dmesg`` output from L1 | |
| 255 | + | |
| 256 | +x86-specific info to collect | |
| 257 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 258 | + | |
| 259 | +Both the below commands, ``x86info`` and ``dmidecode``, should be | |
| 260 | +available on most Linux distributions with the same name: | |
| 261 | + | |
| 262 | + - Output of: ``x86info -a`` from L0 | |
| 263 | + | |
| 264 | + - Output of: ``x86info -a`` from L1 | |
| 265 | + | |
| 266 | + - Output of: ``dmidecode`` from L0 | |
| 267 | + | |
| 268 | + - Output of: ``dmidecode`` from L1 | |
| 269 | + | |
| 270 | +s390x-specific info to collect | |
| 271 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 272 | + | |
| 273 | +Along with the earlier mentioned generic details, the below is | |
| 274 | +also recommended: | |
| 275 | + | |
| 276 | + - ``/proc/sysinfo`` from L1; this will also include the info from L0 | |
| @@ -3657,7 +3657,7 @@ L: linux-btrfs@vger.kernel.org · 3656 unmodified lines | ||
| 3657 | 3657 | S: Maintained |
| 3658 | 3658 | W: http://btrfs.wiki.kernel.org/ |
| 3659 | 3659 | Q: http://patchwork.kernel.org/project/linux-btrfs/list/ |
| 3660 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git | |
| 3660 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git | |
| 3661 | 3661 | F: Documentation/filesystems/btrfs.rst |
| 3662 | 3662 | F: fs/btrfs/ |
| 3663 | 3663 | F: include/linux/btrfs* |
| @@ -3936,11 +3936,9 @@ F: arch/powerpc/platforms/cell/ · 272 unmodified lines | ||
| 3936 | 3936 | CEPH COMMON CODE (LIBCEPH) |
| 3937 | 3937 | M: Ilya Dryomov <idryomov@gmail.com> |
| 3938 | 3938 | M: Jeff Layton <jlayton@kernel.org> |
| 3939 | −M: Sage Weil <sage@redhat.com> | |
| 3940 | 3939 | L: ceph-devel@vger.kernel.org |
| 3941 | 3940 | S: Supported |
| 3942 | 3941 | W: http://ceph.com/ |
| 3943 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git | |
| 3944 | 3942 | T: git git://github.com/ceph/ceph-client.git |
| 3945 | 3943 | F: include/linux/ceph/ |
| 3946 | 3944 | F: include/linux/crush/ |
| @@ -3948,12 +3946,10 @@ F: net/ceph/ · 1 unmodified line | ||
| 3948 | 3946 | |
| 3949 | 3947 | CEPH DISTRIBUTED FILE SYSTEM CLIENT (CEPH) |
| 3950 | 3948 | M: Jeff Layton <jlayton@kernel.org> |
| 3951 | −M: Sage Weil <sage@redhat.com> | |
| 3952 | 3949 | M: Ilya Dryomov <idryomov@gmail.com> |
| 3953 | 3950 | L: ceph-devel@vger.kernel.org |
| 3954 | 3951 | S: Supported |
| 3955 | 3952 | W: http://ceph.com/ |
| 3956 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git | |
| 3957 | 3953 | T: git git://github.com/ceph/ceph-client.git |
| 3958 | 3954 | F: Documentation/filesystems/ceph.rst |
| 3959 | 3955 | F: fs/ceph/ |
| @@ -5935,9 +5931,9 @@ F: lib/dynamic_debug.c · 1975 unmodified lines | ||
| 5935 | 5931 | DYNAMIC INTERRUPT MODERATION |
| 5936 | 5932 | M: Tal Gilboa <talgi@mellanox.com> |
| 5937 | 5933 | S: Maintained |
| 5934 | +F: Documentation/networking/net_dim.rst | |
| 5938 | 5935 | F: include/linux/dim.h |
| 5939 | 5936 | F: lib/dim/ |
| 5940 | −F: Documentation/networking/net_dim.rst | |
| 5941 | 5937 | |
| 5942 | 5938 | DZ DECSTATION DZ11 SERIAL DRIVER |
| 5943 | 5939 | M: "Maciej W. Rozycki" <macro@linux-mips.org> |
| @@ -7119,9 +7115,10 @@ F: include/uapi/asm-generic/ · 1175 unmodified lines | ||
| 7119 | 7115 | |
| 7120 | 7116 | GENERIC PHY FRAMEWORK |
| 7121 | 7117 | M: Kishon Vijay Abraham I <kishon@ti.com> |
| 7118 | +M: Vinod Koul <vkoul@kernel.org> | |
| 7122 | 7119 | L: linux-kernel@vger.kernel.org |
| 7123 | 7120 | S: Supported |
| 7124 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git | |
| 7121 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git | |
| 7125 | 7122 | F: Documentation/devicetree/bindings/phy/ |
| 7126 | 7123 | F: drivers/phy/ |
| 7127 | 7124 | F: include/linux/phy/ |
| @@ -7746,11 +7743,6 @@ L: platform-driver-x86@vger.kernel.org · 618 unmodified lines | ||
| 7746 | 7743 | S: Orphan |
| 7747 | 7744 | F: drivers/platform/x86/tc1100-wmi.c |
| 7748 | 7745 | |
| 7749 | −HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series | |
| 7750 | −M: Jaroslav Kysela <perex@perex.cz> | |
| 7751 | −S: Obsolete | |
| 7752 | −F: drivers/staging/hp/hp100.* | |
| 7753 | − | |
| 7754 | 7746 | HPET: High Precision Event Timers driver |
| 7755 | 7747 | M: Clemens Ladisch <clemens@ladisch.de> |
| 7756 | 7748 | S: Maintained |
| @@ -14102,12 +14094,10 @@ F: drivers/media/radio/radio-tea5777.c · 6345 unmodified lines | ||
| 14102 | 14094 | |
| 14103 | 14095 | RADOS BLOCK DEVICE (RBD) |
| 14104 | 14096 | M: Ilya Dryomov <idryomov@gmail.com> |
| 14105 | −M: Sage Weil <sage@redhat.com> | |
| 14106 | 14097 | R: Dongsheng Yang <dongsheng.yang@easystack.cn> |
| 14107 | 14098 | L: ceph-devel@vger.kernel.org |
| 14108 | 14099 | S: Supported |
| 14109 | 14100 | W: http://ceph.com/ |
| 14110 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git | |
| 14111 | 14101 | T: git git://github.com/ceph/ceph-client.git |
| 14112 | 14102 | F: Documentation/ABI/testing/sysfs-bus-rbd |
| 14113 | 14103 | F: drivers/block/rbd.c |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 7 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc5 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -729,10 +729,6 @@ else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE · 720 unmodified lines | ||
| 729 | 729 | KBUILD_CFLAGS += -Os |
| 730 | 730 | endif |
| 731 | 731 | |
| 732 | −ifdef CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED | |
| 733 | −KBUILD_CFLAGS += -Wno-maybe-uninitialized | |
| 734 | −endif | |
| 735 | − | |
| 736 | 732 | # Tell gcc to never replace conditional load with a non-conditional one |
| 737 | 733 | KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) |
| 738 | 734 | KBUILD_CFLAGS += $(call cc-option,-fno-allow-store-data-races) |
| @@ -881,6 +877,17 @@ KBUILD_CFLAGS += -Wno-pointer-sign · 142 unmodified lines | ||
| 881 | 877 | # disable stringop warnings in gcc 8+ |
| 882 | 878 | KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) |
| 883 | 879 | |
| 880 | +# We'll want to enable this eventually, but it's not going away for 5.7 at least | |
| 881 | +KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) | |
| 882 | +KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) | |
| 883 | +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) | |
| 884 | + | |
| 885 | +# Another good warning that we'll want to enable eventually | |
| 886 | +KBUILD_CFLAGS += $(call cc-disable-warning, restrict) | |
| 887 | + | |
| 888 | +# Enabled with W=2, disabled by default as noisy | |
| 889 | +KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) | |
| 890 | + | |
| 884 | 891 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 885 | 892 | KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) |
| 886 | 893 | |
| @@ -91,9 +91,17 @@ void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, unsigned int bytes, · 90 unmodified lines | ||
| 91 | 91 | return; |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | − kernel_neon_begin(); | |
| 95 | − chacha_doneon(state, dst, src, bytes, nrounds); | |
| 96 | − kernel_neon_end(); | |
| 94 | + do { | |
| 95 | + unsigned int todo = min_t(unsigned int, bytes, SZ_4K); | |
| 96 | + | |
| 97 | + kernel_neon_begin(); | |
| 98 | + chacha_doneon(state, dst, src, todo, nrounds); | |
| 99 | + kernel_neon_end(); | |
| 100 | + | |
| 101 | + bytes -= todo; | |
| 102 | + src += todo; | |
| 103 | + dst += todo; | |
| 104 | + } while (bytes); | |
| 97 | 105 | } |
| 98 | 106 | EXPORT_SYMBOL(chacha_crypt_arch); |
| 99 | 107 | |
| @@ -30,7 +30,7 @@ static int nhpoly1305_neon_update(struct shash_desc *desc, · 29 unmodified lines | ||
| 30 | 30 | return crypto_nhpoly1305_update(desc, src, srclen); |
| 31 | 31 | |
| 32 | 32 | do { |
| 33 | − unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); | |
| 33 | + unsigned int n = min_t(unsigned int, srclen, SZ_4K); | |
| 34 | 34 | |
| 35 | 35 | kernel_neon_begin(); |
| 36 | 36 | crypto_nhpoly1305_update_helper(desc, src, n, _nh_neon); |
| @@ -160,13 +160,20 @@ void poly1305_update_arch(struct poly1305_desc_ctx *dctx, const u8 *src, · 159 unmodified lines | ||
| 160 | 160 | unsigned int len = round_down(nbytes, POLY1305_BLOCK_SIZE); |
| 161 | 161 | |
| 162 | 162 | if (static_branch_likely(&have_neon) && do_neon) { |
| 163 | − kernel_neon_begin(); | |
| 164 | − poly1305_blocks_neon(&dctx->h, src, len, 1); | |
| 165 | − kernel_neon_end(); | |
| 163 | + do { | |
| 164 | + unsigned int todo = min_t(unsigned int, len, SZ_4K); | |
| 165 | + | |
| 166 | + kernel_neon_begin(); | |
| 167 | + poly1305_blocks_neon(&dctx->h, src, todo, 1); | |
| 168 | + kernel_neon_end(); | |
| 169 | + | |
| 170 | + len -= todo; | |
| 171 | + src += todo; | |
| 172 | + } while (len); | |
| 166 | 173 | } else { |
| 167 | 174 | poly1305_blocks_arm(&dctx->h, src, len, 1); |
| 175 | + src += len; | |
| 168 | 176 | } |
| 169 | − src += len; | |
| 170 | 177 | nbytes %= POLY1305_BLOCK_SIZE; |
| 171 | 178 | } |
| 172 | 179 | |
| @@ -165,8 +165,13 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) · 164 unmodified lines | ||
| 165 | 165 | preempt_enable(); |
| 166 | 166 | #endif |
| 167 | 167 | |
| 168 | − if (!ret) | |
| 169 | − *oval = oldval; | |
| 168 | + /* | |
| 169 | + * Store unconditionally. If ret != 0 the extra store is the least | |
| 170 | + * of the worries but GCC cannot figure out that __futex_atomic_op() | |
| 171 | + * is either setting ret to -EFAULT or storing the old value in | |
| 172 | + * oldval which results in a uninitialized warning at the call site. | |
| 173 | + */ | |
| 174 | + *oval = oldval; | |
| 170 | 175 | |
| 171 | 176 | return ret; |
| 172 | 177 | } |
| @@ -87,9 +87,17 @@ void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, unsigned int bytes, · 86 unmodified lines | ||
| 87 | 87 | !crypto_simd_usable()) |
| 88 | 88 | return chacha_crypt_generic(state, dst, src, bytes, nrounds); |
| 89 | 89 | |
| 90 | − kernel_neon_begin(); | |
| 91 | − chacha_doneon(state, dst, src, bytes, nrounds); | |
| 92 | − kernel_neon_end(); | |
| 90 | + do { | |
| 91 | + unsigned int todo = min_t(unsigned int, bytes, SZ_4K); | |
| 92 | + | |
| 93 | + kernel_neon_begin(); | |
| 94 | + chacha_doneon(state, dst, src, todo, nrounds); | |
| 95 | + kernel_neon_end(); | |
| 96 | + | |
| 97 | + bytes -= todo; | |
| 98 | + src += todo; | |
| 99 | + dst += todo; | |
| 100 | + } while (bytes); | |
| 93 | 101 | } |
| 94 | 102 | EXPORT_SYMBOL(chacha_crypt_arch); |
| 95 | 103 | |
| @@ -30,7 +30,7 @@ static int nhpoly1305_neon_update(struct shash_desc *desc, · 29 unmodified lines | ||
| 30 | 30 | return crypto_nhpoly1305_update(desc, src, srclen); |
| 31 | 31 | |
| 32 | 32 | do { |
| 33 | − unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); | |
| 33 | + unsigned int n = min_t(unsigned int, srclen, SZ_4K); | |
| 34 | 34 | |
| 35 | 35 | kernel_neon_begin(); |
| 36 | 36 | crypto_nhpoly1305_update_helper(desc, src, n, _nh_neon); |
| @@ -143,13 +143,20 @@ void poly1305_update_arch(struct poly1305_desc_ctx *dctx, const u8 *src, · 142 unmodified lines | ||
| 143 | 143 | unsigned int len = round_down(nbytes, POLY1305_BLOCK_SIZE); |
| 144 | 144 | |
| 145 | 145 | if (static_branch_likely(&have_neon) && crypto_simd_usable()) { |
| 146 | − kernel_neon_begin(); | |
| 147 | − poly1305_blocks_neon(&dctx->h, src, len, 1); | |
| 148 | − kernel_neon_end(); | |
| 146 | + do { | |
| 147 | + unsigned int todo = min_t(unsigned int, len, SZ_4K); | |
| 148 | + | |
| 149 | + kernel_neon_begin(); | |
| 150 | + poly1305_blocks_neon(&dctx->h, src, todo, 1); | |
| 151 | + kernel_neon_end(); | |
| 152 | + | |
| 153 | + len -= todo; | |
| 154 | + src += todo; | |
| 155 | + } while (len); | |
| 149 | 156 | } else { |
| 150 | 157 | poly1305_blocks(&dctx->h, src, len, 1); |
| 158 | + src += len; | |
| 151 | 159 | } |
| 152 | − src += len; | |
| 153 | 160 | nbytes %= POLY1305_BLOCK_SIZE; |
| 154 | 161 | } |
| 155 | 162 | |
| @@ -32,7 +32,7 @@ UBSAN_SANITIZE := n · 31 unmodified lines | ||
| 32 | 32 | OBJECT_FILES_NON_STANDARD := y |
| 33 | 33 | KCOV_INSTRUMENT := n |
| 34 | 34 | |
| 35 | −CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny | |
| 35 | +CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -fasynchronous-unwind-tables | |
| 36 | 36 | |
| 37 | 37 | ifneq ($(c-gettimeofday-y),) |
| 38 | 38 | CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) |
| @@ -200,6 +200,13 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 199 unmodified lines | ||
| 200 | 200 | } |
| 201 | 201 | |
| 202 | 202 | memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id)); |
| 203 | + | |
| 204 | + if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) { | |
| 205 | + int i; | |
| 206 | + | |
| 207 | + for (i = 0; i < 16; i++) | |
| 208 | + *vcpu_reg32(vcpu, i) = (u32)*vcpu_reg32(vcpu, i); | |
| 209 | + } | |
| 203 | 210 | out: |
| 204 | 211 | return err; |
| 205 | 212 | } |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x) |
| 20 | 20 | #define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x) |
| 21 | +#define CPU_SP_EL0_OFFSET (CPU_XREG_OFFSET(30) + 8) | |
| 21 | 22 | |
| 22 | 23 | .text |
| 23 | 24 | .pushsection .hyp.text, "ax" |
| @@ -47,6 +48,16 @@ · 23 unmodified lines | ||
| 47 | 48 | ldp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)] |
| 48 | 49 | .endm |
| 49 | 50 | |
| 51 | +.macro save_sp_el0 ctxt, tmp | |
| 52 | + mrs \tmp, sp_el0 | |
| 53 | + str \tmp, [\ctxt, #CPU_SP_EL0_OFFSET] | |
| 54 | +.endm | |
| 55 | + | |
| 56 | +.macro restore_sp_el0 ctxt, tmp | |
| 57 | + ldr \tmp, [\ctxt, #CPU_SP_EL0_OFFSET] | |
| 58 | + msr sp_el0, \tmp | |
| 59 | +.endm | |
| 60 | + | |
| 50 | 61 | /* |
| 51 | 62 | * u64 __guest_enter(struct kvm_vcpu *vcpu, |
| 52 | 63 | * struct kvm_cpu_context *host_ctxt); |
| @@ -60,6 +71,9 @@ SYM_FUNC_START(__guest_enter) · 7 unmodified lines | ||
| 60 | 71 | // Store the host regs |
| 61 | 72 | save_callee_saved_regs x1 |
| 62 | 73 | |
| 74 | + // Save the host's sp_el0 | |
| 75 | + save_sp_el0 x1, x2 | |
| 76 | + | |
| 63 | 77 | // Now the host state is stored if we have a pending RAS SError it must |
| 64 | 78 | // affect the host. If any asynchronous exception is pending we defer |
| 65 | 79 | // the guest entry. The DSB isn't necessary before v8.2 as any SError |
| @@ -83,6 +97,9 @@ alternative_else_nop_endif · 17 unmodified lines | ||
| 83 | 97 | // when this feature is enabled for kernel code. |
| 84 | 98 | ptrauth_switch_to_guest x29, x0, x1, x2 |
| 85 | 99 | |
| 100 | + // Restore the guest's sp_el0 | |
| 101 | + restore_sp_el0 x29, x0 | |
| 102 | + | |
| 86 | 103 | // Restore guest regs x0-x17 |
| 87 | 104 | ldp x0, x1, [x29, #CPU_XREG_OFFSET(0)] |
| 88 | 105 | ldp x2, x3, [x29, #CPU_XREG_OFFSET(2)] |
| @@ -130,6 +147,9 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) · 41 unmodified lines | ||
| 130 | 147 | // Store the guest regs x18-x29, lr |
| 131 | 148 | save_callee_saved_regs x1 |
| 132 | 149 | |
| 150 | + // Store the guest's sp_el0 | |
| 151 | + save_sp_el0 x1, x2 | |
| 152 | + | |
| 133 | 153 | get_host_ctxt x2, x3 |
| 134 | 154 | |
| 135 | 155 | // Macro ptrauth_switch_to_guest format: |
| @@ -139,6 +159,9 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) · 3 unmodified lines | ||
| 139 | 159 | // when this feature is enabled for kernel code. |
| 140 | 160 | ptrauth_switch_to_host x1, x2, x3, x4, x5 |
| 141 | 161 | |
| 162 | + // Restore the hosts's sp_el0 | |
| 163 | + restore_sp_el0 x2, x3 | |
| 164 | + | |
| 142 | 165 | // Now restore the host regs |
| 143 | 166 | restore_callee_saved_regs x2 |
| 144 | 167 | |
| @@ -198,7 +198,6 @@ SYM_CODE_END(__hyp_panic) · 197 unmodified lines | ||
| 198 | 198 | .macro invalid_vector label, target = __hyp_panic |
| 199 | 199 | .align 2 |
| 200 | 200 | SYM_CODE_START(\label) |
| 201 | −\label: | |
| 202 | 201 | b \target |
| 203 | 202 | SYM_CODE_END(\label) |
| 204 | 203 | .endm |
| @@ -15,8 +15,9 @@ · 14 unmodified lines | ||
| 15 | 15 | /* |
| 16 | 16 | * Non-VHE: Both host and guest must save everything. |
| 17 | 17 | * |
| 18 | − * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and pstate, | |
| 19 | − * which are handled as part of the el2 return state) on every switch. | |
| 18 | + * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and | |
| 19 | + * pstate, which are handled as part of the el2 return state) on every | |
| 20 | + * switch (sp_el0 is being dealt with in the assembly code). | |
| 20 | 21 | * tpidr_el0 and tpidrro_el0 only need to be switched when going |
| 21 | 22 | * to host userspace or a different VCPU. EL1 registers only need to be |
| 22 | 23 | * switched when potentially going to run a different VCPU. The latter two |
| @@ -26,12 +27,6 @@ · 3 unmodified lines | ||
| 26 | 27 | static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) |
| 27 | 28 | { |
| 28 | 29 | ctxt->sys_regs[MDSCR_EL1] = read_sysreg(mdscr_el1); |
| 29 | − | |
| 30 | − /* | |
| 31 | − * The host arm64 Linux uses sp_el0 to point to 'current' and it must | |
| 32 | − * therefore be saved/restored on every entry/exit to/from the guest. | |
| 33 | − */ | |
| 34 | − ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); | |
| 35 | 30 | } |
| 36 | 31 | |
| 37 | 32 | static void __hyp_text __sysreg_save_user_state(struct kvm_cpu_context *ctxt) |
| @@ -99,12 +94,6 @@ NOKPROBE_SYMBOL(sysreg_save_guest_state_vhe); · 61 unmodified lines | ||
| 99 | 94 | static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt) |
| 100 | 95 | { |
| 101 | 96 | write_sysreg(ctxt->sys_regs[MDSCR_EL1], mdscr_el1); |
| 102 | − | |
| 103 | − /* | |
| 104 | − * The host arm64 Linux uses sp_el0 to point to 'current' and it must | |
| 105 | − * therefore be saved/restored on every entry/exit to/from the guest. | |
| 106 | − */ | |
| 107 | − write_sysreg(ctxt->gp_regs.regs.sp, sp_el0); | |
| 108 | 97 | } |
| 109 | 98 | |
| 110 | 99 | static void __hyp_text __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) |
| @@ -230,6 +230,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, · 229 unmodified lines | ||
| 230 | 230 | ptep = (pte_t *)pudp; |
| 231 | 231 | } else if (sz == (CONT_PTE_SIZE)) { |
| 232 | 232 | pmdp = pmd_alloc(mm, pudp, addr); |
| 233 | + if (!pmdp) | |
| 234 | + return NULL; | |
| 233 | 235 | |
| 234 | 236 | WARN_ON(addr & (sz - 1)); |
| 235 | 237 | /* |
| @@ -521,6 +521,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 520 unmodified lines | ||
| 521 | 521 | case KVM_CAP_IOEVENTFD: |
| 522 | 522 | case KVM_CAP_DEVICE_CTRL: |
| 523 | 523 | case KVM_CAP_IMMEDIATE_EXIT: |
| 524 | + case KVM_CAP_SET_GUEST_DEBUG: | |
| 524 | 525 | r = 1; |
| 525 | 526 | break; |
| 526 | 527 | case KVM_CAP_PPC_GUEST_DEBUG_SSTEP: |
| @@ -60,7 +60,7 @@ config RISCV · 59 unmodified lines | ||
| 60 | 60 | select ARCH_HAS_GIGANTIC_PAGE |
| 61 | 61 | select ARCH_HAS_SET_DIRECT_MAP |
| 62 | 62 | select ARCH_HAS_SET_MEMORY |
| 63 | − select ARCH_HAS_STRICT_KERNEL_RWX | |
| 63 | + select ARCH_HAS_STRICT_KERNEL_RWX if MMU | |
| 64 | 64 | select ARCH_WANT_HUGE_PMD_SHARE if 64BIT |
| 65 | 65 | select SPARSEMEM_STATIC if 32BIT |
| 66 | 66 | select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU |
| @@ -51,13 +51,10 @@ · 50 unmodified lines | ||
| 51 | 51 | #define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1)) |
| 52 | 52 | |
| 53 | 53 | /* Interrupt causes (minus the high bit) */ |
| 54 | −#define IRQ_U_SOFT 0 | |
| 55 | 54 | #define IRQ_S_SOFT 1 |
| 56 | 55 | #define IRQ_M_SOFT 3 |
| 57 | −#define IRQ_U_TIMER 4 | |
| 58 | 56 | #define IRQ_S_TIMER 5 |
| 59 | 57 | #define IRQ_M_TIMER 7 |
| 60 | −#define IRQ_U_EXT 8 | |
| 61 | 58 | #define IRQ_S_EXT 9 |
| 62 | 59 | #define IRQ_M_EXT 11 |
| 63 | 60 | |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #ifndef _ASM_RISCV_HWCAP_H |
| 9 | 9 | #define _ASM_RISCV_HWCAP_H |
| 10 | 10 | |
| 11 | +#include <linux/bits.h> | |
| 11 | 12 | #include <uapi/asm/hwcap.h> |
| 12 | 13 | |
| 13 | 14 | #ifndef __ASSEMBLY__ |
| @@ -22,6 +23,27 @@ enum { · 8 unmodified lines | ||
| 22 | 23 | }; |
| 23 | 24 | |
| 24 | 25 | extern unsigned long elf_hwcap; |
| 26 | + | |
| 27 | +#define RISCV_ISA_EXT_a ('a' - 'a') | |
| 28 | +#define RISCV_ISA_EXT_c ('c' - 'a') | |
| 29 | +#define RISCV_ISA_EXT_d ('d' - 'a') | |
| 30 | +#define RISCV_ISA_EXT_f ('f' - 'a') | |
| 31 | +#define RISCV_ISA_EXT_h ('h' - 'a') | |
| 32 | +#define RISCV_ISA_EXT_i ('i' - 'a') | |
| 33 | +#define RISCV_ISA_EXT_m ('m' - 'a') | |
| 34 | +#define RISCV_ISA_EXT_s ('s' - 'a') | |
| 35 | +#define RISCV_ISA_EXT_u ('u' - 'a') | |
| 36 | + | |
| 37 | +#define RISCV_ISA_EXT_MAX 64 | |
| 38 | + | |
| 39 | +unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap); | |
| 40 | + | |
| 41 | +#define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext) | |
| 42 | + | |
| 43 | +bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit); | |
| 44 | +#define riscv_isa_extension_available(isa_bitmap, ext) \ | |
| 45 | + __riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_##ext) | |
| 46 | + | |
| 25 | 47 | #endif |
| 26 | 48 | |
| 27 | 49 | #endif /* _ASM_RISCV_HWCAP_H */ |
| @@ -22,14 +22,6 @@ static inline int set_memory_x(unsigned long addr, int numpages) { return 0; } · 21 unmodified lines | ||
| 22 | 22 | static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; } |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | −#ifdef CONFIG_STRICT_KERNEL_RWX | |
| 26 | −void set_kernel_text_ro(void); | |
| 27 | −void set_kernel_text_rw(void); | |
| 28 | −#else | |
| 29 | −static inline void set_kernel_text_ro(void) { } | |
| 30 | −static inline void set_kernel_text_rw(void) { } | |
| 31 | −#endif | |
| 32 | − | |
| 33 | 25 | int set_direct_map_invalid_noflush(struct page *page); |
| 34 | 26 | int set_direct_map_default_noflush(struct page *page); |
| 35 | 27 | |
| @@ -15,8 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init; |
| 17 | 17 | |
| 18 | −void *__cpu_up_stack_pointer[NR_CPUS]; | |
| 19 | −void *__cpu_up_task_pointer[NR_CPUS]; | |
| 18 | +void *__cpu_up_stack_pointer[NR_CPUS] __section(.data); | |
| 19 | +void *__cpu_up_task_pointer[NR_CPUS] __section(.data); | |
| 20 | 20 | |
| 21 | 21 | extern const struct cpu_operations cpu_ops_sbi; |
| 22 | 22 | extern const struct cpu_operations cpu_ops_spinwait; |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * Copyright (C) 2017 SiFive |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | +#include <linux/bitmap.h> | |
| 9 | 10 | #include <linux/of.h> |
| 10 | 11 | #include <asm/processor.h> |
| 11 | 12 | #include <asm/hwcap.h> |
| @@ -13,15 +14,57 @@ · 1 unmodified line | ||
| 13 | 14 | #include <asm/switch_to.h> |
| 14 | 15 | |
| 15 | 16 | unsigned long elf_hwcap __read_mostly; |
| 17 | + | |
| 18 | +/* Host ISA bitmap */ | |
| 19 | +static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly; | |
| 20 | + | |
| 16 | 21 | #ifdef CONFIG_FPU |
| 17 | 22 | bool has_fpu __read_mostly; |
| 18 | 23 | #endif |
| 19 | 24 | |
| 25 | +/** | |
| 26 | + * riscv_isa_extension_base() - Get base extension word | |
| 27 | + * | |
| 28 | + * @isa_bitmap: ISA bitmap to use | |
| 29 | + * Return: base extension word as unsigned long value | |
| 30 | + * | |
| 31 | + * NOTE: If isa_bitmap is NULL then Host ISA bitmap will be used. | |
| 32 | + */ | |
| 33 | +unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap) | |
| 34 | +{ | |
| 35 | + if (!isa_bitmap) | |
| 36 | + return riscv_isa[0]; | |
| 37 | + return isa_bitmap[0]; | |
| 38 | +} | |
| 39 | +EXPORT_SYMBOL_GPL(riscv_isa_extension_base); | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * __riscv_isa_extension_available() - Check whether given extension | |
| 43 | + * is available or not | |
| 44 | + * | |
| 45 | + * @isa_bitmap: ISA bitmap to use | |
| 46 | + * @bit: bit position of the desired extension | |
| 47 | + * Return: true or false | |
| 48 | + * | |
| 49 | + * NOTE: If isa_bitmap is NULL then Host ISA bitmap will be used. | |
| 50 | + */ | |
| 51 | +bool __riscv_isa_extension_available(const unsigned long *isa_bitmap, int bit) | |
| 52 | +{ | |
| 53 | + const unsigned long *bmap = (isa_bitmap) ? isa_bitmap : riscv_isa; | |
| 54 | + | |
| 55 | + if (bit >= RISCV_ISA_EXT_MAX) | |
| 56 | + return false; | |
| 57 | + | |
| 58 | + return test_bit(bit, bmap) ? true : false; | |
| 59 | +} | |
| 60 | +EXPORT_SYMBOL_GPL(__riscv_isa_extension_available); | |
| 61 | + | |
| 20 | 62 | void riscv_fill_hwcap(void) |
| 21 | 63 | { |
| 22 | 64 | struct device_node *node; |
| 23 | 65 | const char *isa; |
| 24 | − size_t i; | |
| 66 | + char print_str[BITS_PER_LONG + 1]; | |
| 67 | + size_t i, j, isa_len; | |
| 25 | 68 | static unsigned long isa2hwcap[256] = {0}; |
| 26 | 69 | |
| 27 | 70 | isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; |
| @@ -33,8 +76,11 @@ void riscv_fill_hwcap(void) · 5 unmodified lines | ||
| 33 | 76 | |
| 34 | 77 | elf_hwcap = 0; |
| 35 | 78 | |
| 79 | + bitmap_zero(riscv_isa, RISCV_ISA_EXT_MAX); | |
| 80 | + | |
| 36 | 81 | for_each_of_cpu_node(node) { |
| 37 | 82 | unsigned long this_hwcap = 0; |
| 83 | + unsigned long this_isa = 0; | |
| 38 | 84 | |
| 39 | 85 | if (riscv_of_processor_hartid(node) < 0) |
| 40 | 86 | continue; |
| @@ -44,8 +90,24 @@ void riscv_fill_hwcap(void) · 3 unmodified lines | ||
| 44 | 90 | continue; |
| 45 | 91 | } |
| 46 | 92 | |
| 47 | − for (i = 0; i < strlen(isa); ++i) | |
| 93 | + i = 0; | |
| 94 | + isa_len = strlen(isa); | |
| 95 | +#if IS_ENABLED(CONFIG_32BIT) | |
| 96 | + if (!strncmp(isa, "rv32", 4)) | |
| 97 | + i += 4; | |
| 98 | +#elif IS_ENABLED(CONFIG_64BIT) | |
| 99 | + if (!strncmp(isa, "rv64", 4)) | |
| 100 | + i += 4; | |
| 101 | +#endif | |
| 102 | + for (; i < isa_len; ++i) { | |
| 48 | 103 | this_hwcap |= isa2hwcap[(unsigned char)(isa[i])]; |
| 104 | + /* | |
| 105 | + * TODO: X, Y and Z extension parsing for Host ISA | |
| 106 | + * bitmap will be added in-future. | |
| 107 | + */ | |
| 108 | + if ('a' <= isa[i] && isa[i] < 'x') | |
| 109 | + this_isa |= (1UL << (isa[i] - 'a')); | |
| 110 | + } | |
| 49 | 111 | |
| 50 | 112 | /* |
| 51 | 113 | * All "okay" hart should have same isa. Set HWCAP based on |
| @@ -56,6 +118,11 @@ void riscv_fill_hwcap(void) · 4 unmodified lines | ||
| 56 | 118 | elf_hwcap &= this_hwcap; |
| 57 | 119 | else |
| 58 | 120 | elf_hwcap = this_hwcap; |
| 121 | + | |
| 122 | + if (riscv_isa[0]) | |
| 123 | + riscv_isa[0] &= this_isa; | |
| 124 | + else | |
| 125 | + riscv_isa[0] = this_isa; | |
| 59 | 126 | } |
| 60 | 127 | |
| 61 | 128 | /* We don't support systems with F but without D, so mask those out |
| @@ -65,7 +132,17 @@ void riscv_fill_hwcap(void) · 3 unmodified lines | ||
| 65 | 132 | elf_hwcap &= ~COMPAT_HWCAP_ISA_F; |
| 66 | 133 | } |
| 67 | 134 | |
| 68 | − pr_info("elf_hwcap is 0x%lx\n", elf_hwcap); | |
| 135 | + memset(print_str, 0, sizeof(print_str)); | |
| 136 | + for (i = 0, j = 0; i < BITS_PER_LONG; i++) | |
| 137 | + if (riscv_isa[0] & BIT_MASK(i)) | |
| 138 | + print_str[j++] = (char)('a' + i); | |
| 139 | + pr_info("riscv: ISA extensions %s\n", print_str); | |
| 140 | + | |
| 141 | + memset(print_str, 0, sizeof(print_str)); | |
| 142 | + for (i = 0, j = 0; i < BITS_PER_LONG; i++) | |
| 143 | + if (elf_hwcap & BIT_MASK(i)) | |
| 144 | + print_str[j++] = (char)('a' + i); | |
| 145 | + pr_info("riscv: ELF capabilities %s\n", print_str); | |
| 69 | 146 | |
| 70 | 147 | #ifdef CONFIG_FPU |
| 71 | 148 | if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)) |
| @@ -102,7 +102,7 @@ void sbi_shutdown(void) · 101 unmodified lines | ||
| 102 | 102 | { |
| 103 | 103 | sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); |
| 104 | 104 | } |
| 105 | −EXPORT_SYMBOL(sbi_set_timer); | |
| 105 | +EXPORT_SYMBOL(sbi_shutdown); | |
| 106 | 106 | |
| 107 | 107 | /** |
| 108 | 108 | * sbi_clear_ipi() - Clear any pending IPIs for the calling hart. |
| @@ -113,7 +113,7 @@ void sbi_clear_ipi(void) · 4 unmodified lines | ||
| 113 | 113 | { |
| 114 | 114 | sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0); |
| 115 | 115 | } |
| 116 | −EXPORT_SYMBOL(sbi_shutdown); | |
| 116 | +EXPORT_SYMBOL(sbi_clear_ipi); | |
| 117 | 117 | |
| 118 | 118 | /** |
| 119 | 119 | * sbi_set_timer_v01() - Program the timer for next timer event. |
| @@ -167,6 +167,11 @@ static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, · 47 unmodified lines | ||
| 167 | 167 | |
| 168 | 168 | return result; |
| 169 | 169 | } |
| 170 | + | |
| 171 | +static void sbi_set_power_off(void) | |
| 172 | +{ | |
| 173 | + pm_power_off = sbi_shutdown; | |
| 174 | +} | |
| 170 | 175 | #else |
| 171 | 176 | static void __sbi_set_timer_v01(uint64_t stime_value) |
| 172 | 177 | { |
| @@ -191,6 +196,8 @@ static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, · 18 unmodified lines | ||
| 191 | 196 | |
| 192 | 197 | return 0; |
| 193 | 198 | } |
| 199 | + | |
| 200 | +static void sbi_set_power_off(void) {} | |
| 194 | 201 | #endif /* CONFIG_RISCV_SBI_V01 */ |
| 195 | 202 | |
| 196 | 203 | static void __sbi_set_timer_v02(uint64_t stime_value) |
| @@ -540,16 +547,12 @@ static inline long sbi_get_firmware_version(void) · 343 unmodified lines | ||
| 540 | 547 | return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION); |
| 541 | 548 | } |
| 542 | 549 | |
| 543 | −static void sbi_power_off(void) | |
| 544 | −{ | |
| 545 | − sbi_shutdown(); | |
| 546 | −} | |
| 547 | 550 | |
| 548 | 551 | int __init sbi_init(void) |
| 549 | 552 | { |
| 550 | 553 | int ret; |
| 551 | 554 | |
| 552 | − pm_power_off = sbi_power_off; | |
| 555 | + sbi_set_power_off(); | |
| 553 | 556 | ret = sbi_get_spec_version(); |
| 554 | 557 | if (ret > 0) |
| 555 | 558 | sbi_spec_version = ret; |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <linux/cpu.h> |
| 12 | 12 | #include <linux/interrupt.h> |
| 13 | +#include <linux/module.h> | |
| 13 | 14 | #include <linux/profile.h> |
| 14 | 15 | #include <linux/smp.h> |
| 15 | 16 | #include <linux/sched.h> |
| @@ -63,6 +64,7 @@ void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) · 47 unmodified lines | ||
| 63 | 64 | for_each_cpu(cpu, in) |
| 64 | 65 | cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); |
| 65 | 66 | } |
| 67 | +EXPORT_SYMBOL_GPL(riscv_cpuid_to_hartid_mask); | |
| 66 | 68 | |
| 67 | 69 | bool arch_match_cpu_phys_id(int cpu, u64 phys_id) |
| 68 | 70 | { |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/stacktrace.h> |
| 13 | 13 | #include <linux/ftrace.h> |
| 14 | 14 | |
| 15 | +register unsigned long sp_in_global __asm__("sp"); | |
| 16 | + | |
| 15 | 17 | #ifdef CONFIG_FRAME_POINTER |
| 16 | 18 | |
| 17 | 19 | struct stackframe { |
| @@ -19,8 +21,6 @@ struct stackframe { · 1 unmodified line | ||
| 19 | 21 | unsigned long ra; |
| 20 | 22 | }; |
| 21 | 23 | |
| 22 | −register unsigned long sp_in_global __asm__("sp"); | |
| 23 | − | |
| 24 | 24 | void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, |
| 25 | 25 | bool (*fn)(unsigned long, void *), void *arg) |
| 26 | 26 | { |
| @@ -12,7 +12,7 @@ vdso-syms += getcpu · 11 unmodified lines | ||
| 12 | 12 | vdso-syms += flush_icache |
| 13 | 13 | |
| 14 | 14 | # Files to link into the vdso |
| 15 | −obj-vdso = $(patsubst %, %.o, $(vdso-syms)) | |
| 15 | +obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o | |
| 16 | 16 | |
| 17 | 17 | # Build rules |
| 18 | 18 | targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds vdso-dummy.o |
| @@ -33,15 +33,15 @@ $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE · 14 unmodified lines | ||
| 33 | 33 | $(call if_changed,vdsold) |
| 34 | 34 | |
| 35 | 35 | # We also create a special relocatable object that should mirror the symbol |
| 36 | −# table and layout of the linked DSO. With ld -R we can then refer to | |
| 37 | −# these symbols in the kernel code rather than hand-coded addresses. | |
| 36 | +# table and layout of the linked DSO. With ld --just-symbols we can then | |
| 37 | +# refer to these symbols in the kernel code rather than hand-coded addresses. | |
| 38 | 38 | |
| 39 | 39 | SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ |
| 40 | 40 | -Wl,--build-id -Wl,--hash-style=both |
| 41 | 41 | $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE |
| 42 | 42 | $(call if_changed,vdsold) |
| 43 | 43 | |
| 44 | −LDFLAGS_vdso-syms.o := -r -R | |
| 44 | +LDFLAGS_vdso-syms.o := -r --just-symbols | |
| 45 | 45 | $(obj)/vdso-syms.o: $(obj)/vdso-dummy.o FORCE |
| 46 | 46 | $(call if_changed,ld) |
| 47 | 47 | |
| @@ -0,0 +1,12 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| 2 | +/* | |
| 3 | + * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. | |
| 4 | + * Here we can supply some information useful to userland. | |
| 5 | + */ | |
| 6 | + | |
| 7 | +#include <linux/elfnote.h> | |
| 8 | +#include <linux/version.h> | |
| 9 | + | |
| 10 | +ELFNOTE_START(Linux, 0, "a") | |
| 11 | + .long LINUX_VERSION_CODE | |
| 12 | +ELFNOTE_END | |
| @@ -150,7 +150,8 @@ void __init setup_bootmem(void) · 149 unmodified lines | ||
| 150 | 150 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| 151 | 151 | |
| 152 | 152 | set_max_mapnr(PFN_DOWN(mem_size)); |
| 153 | − max_low_pfn = PFN_DOWN(memblock_end_of_DRAM()); | |
| 153 | + max_pfn = PFN_DOWN(memblock_end_of_DRAM()); | |
| 154 | + max_low_pfn = max_pfn; | |
| 154 | 155 | |
| 155 | 156 | #ifdef CONFIG_BLK_DEV_INITRD |
| 156 | 157 | setup_initrd(); |
| @@ -501,22 +502,6 @@ static inline void setup_vm_final(void) · 344 unmodified lines | ||
| 501 | 502 | #endif /* CONFIG_MMU */ |
| 502 | 503 | |
| 503 | 504 | #ifdef CONFIG_STRICT_KERNEL_RWX |
| 504 | −void set_kernel_text_rw(void) | |
| 505 | −{ | |
| 506 | − unsigned long text_start = (unsigned long)_text; | |
| 507 | − unsigned long text_end = (unsigned long)_etext; | |
| 508 | − | |
| 509 | − set_memory_rw(text_start, (text_end - text_start) >> PAGE_SHIFT); | |
| 510 | −} | |
| 511 | − | |
| 512 | −void set_kernel_text_ro(void) | |
| 513 | −{ | |
| 514 | − unsigned long text_start = (unsigned long)_text; | |
| 515 | − unsigned long text_end = (unsigned long)_etext; | |
| 516 | − | |
| 517 | − set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT); | |
| 518 | −} | |
| 519 | − | |
| 520 | 505 | void mark_rodata_ro(void) |
| 521 | 506 | { |
| 522 | 507 | unsigned long text_start = (unsigned long)_text; |
| @@ -545,6 +545,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 544 unmodified lines | ||
| 545 | 545 | case KVM_CAP_S390_AIS: |
| 546 | 546 | case KVM_CAP_S390_AIS_MIGRATION: |
| 547 | 547 | case KVM_CAP_S390_VCPU_RESETS: |
| 548 | + case KVM_CAP_SET_GUEST_DEBUG: | |
| 548 | 549 | r = 1; |
| 549 | 550 | break; |
| 550 | 551 | case KVM_CAP_S390_HPAGE_1M: |
| @@ -626,10 +626,12 @@ static int handle_pqap(struct kvm_vcpu *vcpu) · 625 unmodified lines | ||
| 626 | 626 | * available for the guest are AQIC and TAPQ with the t bit set |
| 627 | 627 | * since we do not set IC.3 (FIII) we currently will only intercept |
| 628 | 628 | * the AQIC function code. |
| 629 | + * Note: running nested under z/VM can result in intercepts for other | |
| 630 | + * function codes, e.g. PQAP(QCI). We do not support this and bail out. | |
| 629 | 631 | */ |
| 630 | 632 | reg0 = vcpu->run->s.regs.gprs[0]; |
| 631 | 633 | fc = (reg0 >> 24) & 0xff; |
| 632 | − if (WARN_ON_ONCE(fc != 0x03)) | |
| 634 | + if (fc != 0x03) | |
| 633 | 635 | return -EOPNOTSUPP; |
| 634 | 636 | |
| 635 | 637 | /* PQAP instruction is allowed for guest kernel only */ |
| @@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void) · 63 unmodified lines | ||
| 64 | 64 | { |
| 65 | 65 | mm_segment_t old_fs; |
| 66 | 66 | unsigned long asce, cr; |
| 67 | + unsigned long flags; | |
| 67 | 68 | |
| 68 | 69 | old_fs = current->thread.mm_segment; |
| 69 | 70 | if (old_fs & 1) |
| 70 | 71 | return old_fs; |
| 72 | + /* protect against a concurrent page table upgrade */ | |
| 73 | + local_irq_save(flags); | |
| 71 | 74 | current->thread.mm_segment |= 1; |
| 72 | 75 | asce = S390_lowcore.kernel_asce; |
| 73 | 76 | if (likely(old_fs == USER_DS)) { |
| @@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void) · 9 unmodified lines | ||
| 83 | 86 | __ctl_load(asce, 7, 7); |
| 84 | 87 | set_cpu_flag(CIF_ASCE_SECONDARY); |
| 85 | 88 | } |
| 89 | + local_irq_restore(flags); | |
| 86 | 90 | return old_fs; |
| 87 | 91 | } |
| 88 | 92 | EXPORT_SYMBOL(enable_sacf_uaccess); |
| @@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg) · 69 unmodified lines | ||
| 70 | 70 | { |
| 71 | 71 | struct mm_struct *mm = arg; |
| 72 | 72 | |
| 73 | − if (current->active_mm == mm) | |
| 74 | − set_user_asce(mm); | |
| 73 | + /* we must change all active ASCEs to avoid the creation of new TLBs */ | |
| 74 | + if (current->active_mm == mm) { | |
| 75 | + S390_lowcore.user_asce = mm->context.asce; | |
| 76 | + if (current->thread.mm_segment == USER_DS) { | |
| 77 | + __ctl_load(S390_lowcore.user_asce, 1, 1); | |
| 78 | + /* Mark user-ASCE present in CR1 */ | |
| 79 | + clear_cpu_flag(CIF_ASCE_PRIMARY); | |
| 80 | + } | |
| 81 | + if (current->thread.mm_segment == USER_DS_SACF) { | |
| 82 | + __ctl_load(S390_lowcore.user_asce, 7, 7); | |
| 83 | + /* enable_sacf_uaccess does all or nothing */ | |
| 84 | + WARN_ON(!test_cpu_flag(CIF_ASCE_SECONDARY)); | |
| 85 | + } | |
| 86 | + } | |
| 75 | 87 | __tlb_flush_local(); |
| 76 | 88 | } |
| 77 | 89 | |
| @@ -32,16 +32,16 @@ void blake2s_compress_arch(struct blake2s_state *state, · 31 unmodified lines | ||
| 32 | 32 | const u32 inc) |
| 33 | 33 | { |
| 34 | 34 | /* SIMD disables preemption, so relax after processing each page. */ |
| 35 | − BUILD_BUG_ON(PAGE_SIZE / BLAKE2S_BLOCK_SIZE < 8); | |
| 35 | + BUILD_BUG_ON(SZ_4K / BLAKE2S_BLOCK_SIZE < 8); | |
| 36 | 36 | |
| 37 | 37 | if (!static_branch_likely(&blake2s_use_ssse3) || !crypto_simd_usable()) { |
| 38 | 38 | blake2s_compress_generic(state, block, nblocks, inc); |
| 39 | 39 | return; |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | − for (;;) { | |
| 42 | + do { | |
| 43 | 43 | const size_t blocks = min_t(size_t, nblocks, |
| 44 | − PAGE_SIZE / BLAKE2S_BLOCK_SIZE); | |
| 44 | + SZ_4K / BLAKE2S_BLOCK_SIZE); | |
| 45 | 45 | |
| 46 | 46 | kernel_fpu_begin(); |
| 47 | 47 | if (IS_ENABLED(CONFIG_AS_AVX512) && |
| @@ -52,10 +52,8 @@ void blake2s_compress_arch(struct blake2s_state *state, · 4 unmodified lines | ||
| 52 | 52 | kernel_fpu_end(); |
| 53 | 53 | |
| 54 | 54 | nblocks -= blocks; |
| 55 | − if (!nblocks) | |
| 56 | − break; | |
| 57 | 55 | block += blocks * BLAKE2S_BLOCK_SIZE; |
| 58 | − } | |
| 56 | + } while (nblocks); | |
| 59 | 57 | } |
| 60 | 58 | EXPORT_SYMBOL(blake2s_compress_arch); |
| 61 | 59 | |
| @@ -153,9 +153,17 @@ void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, unsigned int bytes, · 152 unmodified lines | ||
| 153 | 153 | bytes <= CHACHA_BLOCK_SIZE) |
| 154 | 154 | return chacha_crypt_generic(state, dst, src, bytes, nrounds); |
| 155 | 155 | |
| 156 | − kernel_fpu_begin(); | |
| 157 | − chacha_dosimd(state, dst, src, bytes, nrounds); | |
| 158 | − kernel_fpu_end(); | |
| 156 | + do { | |
| 157 | + unsigned int todo = min_t(unsigned int, bytes, SZ_4K); | |
| 158 | + | |
| 159 | + kernel_fpu_begin(); | |
| 160 | + chacha_dosimd(state, dst, src, todo, nrounds); | |
| 161 | + kernel_fpu_end(); | |
| 162 | + | |
| 163 | + bytes -= todo; | |
| 164 | + src += todo; | |
| 165 | + dst += todo; | |
| 166 | + } while (bytes); | |
| 159 | 167 | } |
| 160 | 168 | EXPORT_SYMBOL(chacha_crypt_arch); |
| 161 | 169 | |
| @@ -29,7 +29,7 @@ static int nhpoly1305_avx2_update(struct shash_desc *desc, · 28 unmodified lines | ||
| 29 | 29 | return crypto_nhpoly1305_update(desc, src, srclen); |
| 30 | 30 | |
| 31 | 31 | do { |
| 32 | − unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); | |
| 32 | + unsigned int n = min_t(unsigned int, srclen, SZ_4K); | |
| 33 | 33 | |
| 34 | 34 | kernel_fpu_begin(); |
| 35 | 35 | crypto_nhpoly1305_update_helper(desc, src, n, _nh_avx2); |
| @@ -29,7 +29,7 @@ static int nhpoly1305_sse2_update(struct shash_desc *desc, · 28 unmodified lines | ||
| 29 | 29 | return crypto_nhpoly1305_update(desc, src, srclen); |
| 30 | 30 | |
| 31 | 31 | do { |
| 32 | − unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); | |
| 32 | + unsigned int n = min_t(unsigned int, srclen, SZ_4K); | |
| 33 | 33 | |
| 34 | 34 | kernel_fpu_begin(); |
| 35 | 35 | crypto_nhpoly1305_update_helper(desc, src, n, _nh_sse2); |
| @@ -91,8 +91,8 @@ static void poly1305_simd_blocks(void *ctx, const u8 *inp, size_t len, · 90 unmodified lines | ||
| 91 | 91 | struct poly1305_arch_internal *state = ctx; |
| 92 | 92 | |
| 93 | 93 | /* SIMD disables preemption, so relax after processing each page. */ |
| 94 | − BUILD_BUG_ON(PAGE_SIZE < POLY1305_BLOCK_SIZE || | |
| 95 | − PAGE_SIZE % POLY1305_BLOCK_SIZE); | |
| 94 | + BUILD_BUG_ON(SZ_4K < POLY1305_BLOCK_SIZE || | |
| 95 | + SZ_4K % POLY1305_BLOCK_SIZE); | |
| 96 | 96 | |
| 97 | 97 | if (!static_branch_likely(&poly1305_use_avx) || |
| 98 | 98 | (len < (POLY1305_BLOCK_SIZE * 18) && !state->is_base2_26) || |
| @@ -102,8 +102,8 @@ static void poly1305_simd_blocks(void *ctx, const u8 *inp, size_t len, · 3 unmodified lines | ||
| 102 | 102 | return; |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | − for (;;) { | |
| 106 | − const size_t bytes = min_t(size_t, len, PAGE_SIZE); | |
| 105 | + do { | |
| 106 | + const size_t bytes = min_t(size_t, len, SZ_4K); | |
| 107 | 107 | |
| 108 | 108 | kernel_fpu_begin(); |
| 109 | 109 | if (IS_ENABLED(CONFIG_AS_AVX512) && static_branch_likely(&poly1305_use_avx512)) |
| @@ -113,11 +113,10 @@ static void poly1305_simd_blocks(void *ctx, const u8 *inp, size_t len, · 3 unmodified lines | ||
| 113 | 113 | else |
| 114 | 114 | poly1305_blocks_avx(ctx, inp, bytes, padbit); |
| 115 | 115 | kernel_fpu_end(); |
| 116 | + | |
| 116 | 117 | len -= bytes; |
| 117 | − if (!len) | |
| 118 | − break; | |
| 119 | 118 | inp += bytes; |
| 120 | − } | |
| 119 | + } while (len); | |
| 121 | 120 | } |
| 122 | 121 | |
| 123 | 122 | static void poly1305_simd_emit(void *ctx, u8 mac[POLY1305_DIGEST_SIZE], |
| @@ -98,13 +98,6 @@ For 32-bit we have the following conventions - kernel is built with · 97 unmodified lines | ||
| 98 | 98 | #define SIZEOF_PTREGS 21*8 |
| 99 | 99 | |
| 100 | 100 | .macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0 |
| 101 | − /* | |
| 102 | − * Push registers and sanitize registers of values that a | |
| 103 | − * speculation attack might otherwise want to exploit. The | |
| 104 | − * lower registers are likely clobbered well before they | |
| 105 | − * could be put to use in a speculative execution gadget. | |
| 106 | − * Interleave XOR with PUSH for better uop scheduling: | |
| 107 | − */ | |
| 108 | 101 | .if \save_ret |
| 109 | 102 | pushq %rsi /* pt_regs->si */ |
| 110 | 103 | movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */ |
| @@ -114,34 +107,43 @@ For 32-bit we have the following conventions - kernel is built with · 3 unmodified lines | ||
| 114 | 107 | pushq %rsi /* pt_regs->si */ |
| 115 | 108 | .endif |
| 116 | 109 | pushq \rdx /* pt_regs->dx */ |
| 117 | − xorl %edx, %edx /* nospec dx */ | |
| 118 | 110 | pushq %rcx /* pt_regs->cx */ |
| 119 | − xorl %ecx, %ecx /* nospec cx */ | |
| 120 | 111 | pushq \rax /* pt_regs->ax */ |
| 121 | 112 | pushq %r8 /* pt_regs->r8 */ |
| 122 | − xorl %r8d, %r8d /* nospec r8 */ | |
| 123 | 113 | pushq %r9 /* pt_regs->r9 */ |
| 124 | − xorl %r9d, %r9d /* nospec r9 */ | |
| 125 | 114 | pushq %r10 /* pt_regs->r10 */ |
| 126 | − xorl %r10d, %r10d /* nospec r10 */ | |
| 127 | 115 | pushq %r11 /* pt_regs->r11 */ |
| 128 | − xorl %r11d, %r11d /* nospec r11*/ | |
| 129 | 116 | pushq %rbx /* pt_regs->rbx */ |
| 130 | − xorl %ebx, %ebx /* nospec rbx*/ | |
| 131 | 117 | pushq %rbp /* pt_regs->rbp */ |
| 132 | − xorl %ebp, %ebp /* nospec rbp*/ | |
| 133 | 118 | pushq %r12 /* pt_regs->r12 */ |
| 134 | − xorl %r12d, %r12d /* nospec r12*/ | |
| 135 | 119 | pushq %r13 /* pt_regs->r13 */ |
| 136 | − xorl %r13d, %r13d /* nospec r13*/ | |
| 137 | 120 | pushq %r14 /* pt_regs->r14 */ |
| 138 | − xorl %r14d, %r14d /* nospec r14*/ | |
| 139 | 121 | pushq %r15 /* pt_regs->r15 */ |
| 140 | − xorl %r15d, %r15d /* nospec r15*/ | |
| 141 | 122 | UNWIND_HINT_REGS |
| 123 | + | |
| 142 | 124 | .if \save_ret |
| 143 | 125 | pushq %rsi /* return address on top of stack */ |
| 144 | 126 | .endif |
| 127 | + | |
| 128 | + /* | |
| 129 | + * Sanitize registers of values that a speculation attack might | |
| 130 | + * otherwise want to exploit. The lower registers are likely clobbered | |
| 131 | + * well before they could be put to use in a speculative execution | |
| 132 | + * gadget. | |
| 133 | + */ | |
| 134 | + xorl %edx, %edx /* nospec dx */ | |
| 135 | + xorl %ecx, %ecx /* nospec cx */ | |
| 136 | + xorl %r8d, %r8d /* nospec r8 */ | |
| 137 | + xorl %r9d, %r9d /* nospec r9 */ | |
| 138 | + xorl %r10d, %r10d /* nospec r10 */ | |
| 139 | + xorl %r11d, %r11d /* nospec r11 */ | |
| 140 | + xorl %ebx, %ebx /* nospec rbx */ | |
| 141 | + xorl %ebp, %ebp /* nospec rbp */ | |
| 142 | + xorl %r12d, %r12d /* nospec r12 */ | |
| 143 | + xorl %r13d, %r13d /* nospec r13 */ | |
| 144 | + xorl %r14d, %r14d /* nospec r14 */ | |
| 145 | + xorl %r15d, %r15d /* nospec r15 */ | |
| 146 | + | |
| 145 | 147 | .endm |
| 146 | 148 | |
| 147 | 149 | .macro POP_REGS pop_rdi=1 skip_r11rcx=0 |
| @@ -249,7 +249,6 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_hwframe, SYM_L_GLOBAL) · 248 unmodified lines | ||
| 249 | 249 | */ |
| 250 | 250 | syscall_return_via_sysret: |
| 251 | 251 | /* rcx and r11 are already restored (see code above) */ |
| 252 | − UNWIND_HINT_EMPTY | |
| 253 | 252 | POP_REGS pop_rdi=0 skip_r11rcx=1 |
| 254 | 253 | |
| 255 | 254 | /* |
| @@ -258,6 +257,7 @@ syscall_return_via_sysret: · 2 unmodified lines | ||
| 258 | 257 | */ |
| 259 | 258 | movq %rsp, %rdi |
| 260 | 259 | movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp |
| 260 | + UNWIND_HINT_EMPTY | |
| 261 | 261 | |
| 262 | 262 | pushq RSP-RDI(%rdi) /* RSP */ |
| 263 | 263 | pushq (%rdi) /* RDI */ |
| @@ -279,8 +279,7 @@ SYM_CODE_END(entry_SYSCALL_64) · 15 unmodified lines | ||
| 279 | 279 | * %rdi: prev task |
| 280 | 280 | * %rsi: next task |
| 281 | 281 | */ |
| 282 | −SYM_CODE_START(__switch_to_asm) | |
| 283 | − UNWIND_HINT_FUNC | |
| 282 | +SYM_FUNC_START(__switch_to_asm) | |
| 284 | 283 | /* |
| 285 | 284 | * Save callee-saved registers |
| 286 | 285 | * This must match the order in inactive_task_frame |
| @@ -321,7 +320,7 @@ SYM_CODE_START(__switch_to_asm) · 34 unmodified lines | ||
| 321 | 320 | popq %rbp |
| 322 | 321 | |
| 323 | 322 | jmp __switch_to |
| 324 | −SYM_CODE_END(__switch_to_asm) | |
| 323 | +SYM_FUNC_END(__switch_to_asm) | |
| 325 | 324 | |
| 326 | 325 | /* |
| 327 | 326 | * A newly forked process directly context switches into this address. |
| @@ -512,7 +511,7 @@ SYM_CODE_END(spurious_entries_start) · 184 unmodified lines | ||
| 512 | 511 | * +----------------------------------------------------+ |
| 513 | 512 | */ |
| 514 | 513 | SYM_CODE_START(interrupt_entry) |
| 515 | − UNWIND_HINT_FUNC | |
| 514 | + UNWIND_HINT_IRET_REGS offset=16 | |
| 516 | 515 | ASM_CLAC |
| 517 | 516 | cld |
| 518 | 517 | |
| @@ -544,9 +543,9 @@ SYM_CODE_START(interrupt_entry) · 25 unmodified lines | ||
| 544 | 543 | pushq 5*8(%rdi) /* regs->eflags */ |
| 545 | 544 | pushq 4*8(%rdi) /* regs->cs */ |
| 546 | 545 | pushq 3*8(%rdi) /* regs->ip */ |
| 546 | + UNWIND_HINT_IRET_REGS | |
| 547 | 547 | pushq 2*8(%rdi) /* regs->orig_ax */ |
| 548 | 548 | pushq 8(%rdi) /* return address */ |
| 549 | − UNWIND_HINT_FUNC | |
| 550 | 549 | |
| 551 | 550 | movq (%rdi), %rdi |
| 552 | 551 | jmp 2f |
| @@ -637,6 +636,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL) · 84 unmodified lines | ||
| 637 | 636 | */ |
| 638 | 637 | movq %rsp, %rdi |
| 639 | 638 | movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp |
| 639 | + UNWIND_HINT_EMPTY | |
| 640 | 640 | |
| 641 | 641 | /* Copy the IRET frame to the trampoline stack. */ |
| 642 | 642 | pushq 6*8(%rdi) /* SS */ |
| @@ -1739,7 +1739,7 @@ SYM_CODE_START(rewind_stack_do_exit) · 1096 unmodified lines | ||
| 1739 | 1739 | |
| 1740 | 1740 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rax |
| 1741 | 1741 | leaq -PTREGS_SIZE(%rax), %rsp |
| 1742 | − UNWIND_HINT_FUNC sp_offset=PTREGS_SIZE | |
| 1742 | + UNWIND_HINT_REGS | |
| 1743 | 1743 | |
| 1744 | 1744 | call do_exit |
| 1745 | 1745 | SYM_CODE_END(rewind_stack_do_exit) |
| @@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu) · 72 unmodified lines | ||
| 73 | 73 | struct page *pg; |
| 74 | 74 | |
| 75 | 75 | input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); |
| 76 | − pg = alloc_page(GFP_KERNEL); | |
| 76 | + /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */ | |
| 77 | + pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); | |
| 77 | 78 | if (unlikely(!pg)) |
| 78 | 79 | return -ENOMEM; |
| 79 | 80 | *input_arg = page_address(pg); |
| @@ -254,6 +255,7 @@ static int __init hv_pci_init(void) · 174 unmodified lines | ||
| 254 | 255 | static int hv_suspend(void) |
| 255 | 256 | { |
| 256 | 257 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 258 | + int ret; | |
| 257 | 259 | |
| 258 | 260 | /* |
| 259 | 261 | * Reset the hypercall page as it is going to be invalidated |
| @@ -270,12 +272,17 @@ static int hv_suspend(void) · 10 unmodified lines | ||
| 270 | 272 | hypercall_msr.enable = 0; |
| 271 | 273 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 272 | 274 | |
| 273 | − return 0; | |
| 275 | + ret = hv_cpu_die(0); | |
| 276 | + return ret; | |
| 274 | 277 | } |
| 275 | 278 | |
| 276 | 279 | static void hv_resume(void) |
| 277 | 280 | { |
| 278 | 281 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 282 | + int ret; | |
| 283 | + | |
| 284 | + ret = hv_cpu_init(0); | |
| 285 | + WARN_ON(ret); | |
| 279 | 286 | |
| 280 | 287 | /* Re-enable the hypercall page */ |
| 281 | 288 | rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| @@ -288,6 +295,7 @@ static void hv_resume(void) · 6 unmodified lines | ||
| 288 | 295 | hv_hypercall_pg_saved = NULL; |
| 289 | 296 | } |
| 290 | 297 | |
| 298 | +/* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */ | |
| 291 | 299 | static struct syscore_ops hv_syscore_ops = { |
| 292 | 300 | .suspend = hv_suspend, |
| 293 | 301 | .resume = hv_resume, |
| @@ -61,11 +61,12 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name · 60 unmodified lines | ||
| 61 | 61 | { |
| 62 | 62 | /* |
| 63 | 63 | * Compare the symbol name with the system call name. Skip the |
| 64 | − * "__x64_sys", "__ia32_sys" or simple "sys" prefix. | |
| 64 | + * "__x64_sys", "__ia32_sys", "__do_sys" or simple "sys" prefix. | |
| 65 | 65 | */ |
| 66 | 66 | return !strcmp(sym + 3, name + 3) || |
| 67 | 67 | (!strncmp(sym, "__x64_", 6) && !strcmp(sym + 9, name + 3)) || |
| 68 | − (!strncmp(sym, "__ia32_", 7) && !strcmp(sym + 10, name + 3)); | |
| 68 | + (!strncmp(sym, "__ia32_", 7) && !strcmp(sym + 10, name + 3)) || | |
| 69 | + (!strncmp(sym, "__do_sys", 8) && !strcmp(sym + 8, name + 3)); | |
| 69 | 70 | } |
| 70 | 71 | |
| 71 | 72 | #ifndef COMPILE_OFFSETS |
| @@ -1663,8 +1663,8 @@ void kvm_set_msi_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, · 1662 unmodified lines | ||
| 1663 | 1663 | static inline bool kvm_irq_is_postable(struct kvm_lapic_irq *irq) |
| 1664 | 1664 | { |
| 1665 | 1665 | /* We can only post Fixed and LowPrio IRQs */ |
| 1666 | − return (irq->delivery_mode == dest_Fixed || | |
| 1667 | − irq->delivery_mode == dest_LowestPrio); | |
| 1666 | + return (irq->delivery_mode == APIC_DM_FIXED || | |
| 1667 | + irq->delivery_mode == APIC_DM_LOWEST); | |
| 1668 | 1668 | } |
| 1669 | 1669 | |
| 1670 | 1670 | static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) |
| @@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)( · 34 unmodified lines | ||
| 35 | 35 | rdmsrl(HV_X64_MSR_SINT0 + int_num, val) |
| 36 | 36 | #define hv_set_synint_state(int_num, val) \ |
| 37 | 37 | wrmsrl(HV_X64_MSR_SINT0 + int_num, val) |
| 38 | +#define hv_recommend_using_aeoi() \ | |
| 39 | + (!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)) | |
| 38 | 40 | |
| 39 | 41 | #define hv_get_crash_ctl(val) \ |
| 40 | 42 | rdmsrl(HV_X64_MSR_CRASH_CTL, val) |
| @@ -19,7 +19,7 @@ struct unwind_state { · 18 unmodified lines | ||
| 19 | 19 | #if defined(CONFIG_UNWINDER_ORC) |
| 20 | 20 | bool signal, full_regs; |
| 21 | 21 | unsigned long sp, bp, ip; |
| 22 | − struct pt_regs *regs; | |
| 22 | + struct pt_regs *regs, *prev_regs; | |
| 23 | 23 | #elif defined(CONFIG_UNWINDER_FRAME_POINTER) |
| 24 | 24 | bool got_irq; |
| 25 | 25 | unsigned long *bp, *orig_sp, ip; |
| @@ -352,8 +352,6 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) · 351 unmodified lines | ||
| 352 | 352 | * According to Intel, MFENCE can do the serialization here. |
| 353 | 353 | */ |
| 354 | 354 | asm volatile("mfence" : : : "memory"); |
| 355 | − | |
| 356 | − printk_once(KERN_DEBUG "TSC deadline timer enabled\n"); | |
| 357 | 355 | return; |
| 358 | 356 | } |
| 359 | 357 | |
| @@ -546,7 +544,7 @@ static struct clock_event_device lapic_clockevent = { · 186 unmodified lines | ||
| 546 | 544 | }; |
| 547 | 545 | static DEFINE_PER_CPU(struct clock_event_device, lapic_events); |
| 548 | 546 | |
| 549 | −static u32 hsx_deadline_rev(void) | |
| 547 | +static __init u32 hsx_deadline_rev(void) | |
| 550 | 548 | { |
| 551 | 549 | switch (boot_cpu_data.x86_stepping) { |
| 552 | 550 | case 0x02: return 0x3a; /* EP */ |
| @@ -556,7 +554,7 @@ static u32 hsx_deadline_rev(void) · 3 unmodified lines | ||
| 556 | 554 | return ~0U; |
| 557 | 555 | } |
| 558 | 556 | |
| 559 | −static u32 bdx_deadline_rev(void) | |
| 557 | +static __init u32 bdx_deadline_rev(void) | |
| 560 | 558 | { |
| 561 | 559 | switch (boot_cpu_data.x86_stepping) { |
| 562 | 560 | case 0x02: return 0x00000011; |
| @@ -568,7 +566,7 @@ static u32 bdx_deadline_rev(void) · 5 unmodified lines | ||
| 568 | 566 | return ~0U; |
| 569 | 567 | } |
| 570 | 568 | |
| 571 | −static u32 skx_deadline_rev(void) | |
| 569 | +static __init u32 skx_deadline_rev(void) | |
| 572 | 570 | { |
| 573 | 571 | switch (boot_cpu_data.x86_stepping) { |
| 574 | 572 | case 0x03: return 0x01000136; |
| @@ -581,7 +579,7 @@ static u32 skx_deadline_rev(void) · 6 unmodified lines | ||
| 581 | 579 | return ~0U; |
| 582 | 580 | } |
| 583 | 581 | |
| 584 | −static const struct x86_cpu_id deadline_match[] = { | |
| 582 | +static const struct x86_cpu_id deadline_match[] __initconst = { | |
| 585 | 583 | X86_MATCH_INTEL_FAM6_MODEL( HASWELL_X, &hsx_deadline_rev), |
| 586 | 584 | X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020), |
| 587 | 585 | X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_D, &bdx_deadline_rev), |
| @@ -603,18 +601,19 @@ static const struct x86_cpu_id deadline_match[] = { · 15 unmodified lines | ||
| 603 | 601 | {}, |
| 604 | 602 | }; |
| 605 | 603 | |
| 606 | −static void apic_check_deadline_errata(void) | |
| 604 | +static __init bool apic_validate_deadline_timer(void) | |
| 607 | 605 | { |
| 608 | 606 | const struct x86_cpu_id *m; |
| 609 | 607 | u32 rev; |
| 610 | 608 | |
| 611 | − if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER) || | |
| 612 | − boot_cpu_has(X86_FEATURE_HYPERVISOR)) | |
| 613 | − return; | |
| 609 | + if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) | |
| 610 | + return false; | |
| 611 | + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) | |
| 612 | + return true; | |
| 614 | 613 | |
| 615 | 614 | m = x86_match_cpu(deadline_match); |
| 616 | 615 | if (!m) |
| 617 | − return; | |
| 616 | + return true; | |
| 618 | 617 | |
| 619 | 618 | /* |
| 620 | 619 | * Function pointers will have the MSB set due to address layout, |
| @@ -626,11 +625,12 @@ static void apic_check_deadline_errata(void) · 5 unmodified lines | ||
| 626 | 625 | rev = (u32)m->driver_data; |
| 627 | 626 | |
| 628 | 627 | if (boot_cpu_data.microcode >= rev) |
| 629 | − return; | |
| 628 | + return true; | |
| 630 | 629 | |
| 631 | 630 | setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); |
| 632 | 631 | pr_err(FW_BUG "TSC_DEADLINE disabled due to Errata; " |
| 633 | 632 | "please update microcode to version: 0x%x (or later)\n", rev); |
| 633 | + return false; | |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | /* |
| @@ -2092,7 +2092,8 @@ void __init init_apic_mappings(void) · 1455 unmodified lines | ||
| 2092 | 2092 | { |
| 2093 | 2093 | unsigned int new_apicid; |
| 2094 | 2094 | |
| 2095 | − apic_check_deadline_errata(); | |
| 2095 | + if (apic_validate_deadline_timer()) | |
| 2096 | + pr_debug("TSC deadline timer available\n"); | |
| 2096 | 2097 | |
| 2097 | 2098 | if (x2apic_mode) { |
| 2098 | 2099 | boot_cpu_physical_apicid = read_apic_id(); |
| @@ -183,7 +183,8 @@ recursion_check: · 182 unmodified lines | ||
| 183 | 183 | */ |
| 184 | 184 | if (visit_mask) { |
| 185 | 185 | if (*visit_mask & (1UL << info->type)) { |
| 186 | − printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); | |
| 186 | + if (task == current) | |
| 187 | + printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); | |
| 187 | 188 | goto unknown; |
| 188 | 189 | } |
| 189 | 190 | *visit_mask |= 1UL << info->type; |
| @@ -344,6 +344,9 @@ bad_address: · 343 unmodified lines | ||
| 344 | 344 | if (IS_ENABLED(CONFIG_X86_32)) |
| 345 | 345 | goto the_end; |
| 346 | 346 | |
| 347 | + if (state->task != current) | |
| 348 | + goto the_end; | |
| 349 | + | |
| 347 | 350 | if (state->regs) { |
| 348 | 351 | printk_deferred_once(KERN_WARNING |
| 349 | 352 | "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n", |
| @@ -8,19 +8,21 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <asm/orc_lookup.h> |
| 9 | 9 | |
| 10 | 10 | #define orc_warn(fmt, ...) \ |
| 11 | − printk_deferred_once(KERN_WARNING pr_fmt("WARNING: " fmt), ##__VA_ARGS__) | |
| 11 | + printk_deferred_once(KERN_WARNING "WARNING: " fmt, ##__VA_ARGS__) | |
| 12 | + | |
| 13 | +#define orc_warn_current(args...) \ | |
| 14 | +({ \ | |
| 15 | + if (state->task == current) \ | |
| 16 | + orc_warn(args); \ | |
| 17 | +}) | |
| 12 | 18 | |
| 13 | 19 | extern int __start_orc_unwind_ip[]; |
| 14 | 20 | extern int __stop_orc_unwind_ip[]; |
| 15 | 21 | extern struct orc_entry __start_orc_unwind[]; |
| 16 | 22 | extern struct orc_entry __stop_orc_unwind[]; |
| 17 | 23 | |
| 18 | −static DEFINE_MUTEX(sort_mutex); | |
| 19 | −int *cur_orc_ip_table = __start_orc_unwind_ip; | |
| 20 | −struct orc_entry *cur_orc_table = __start_orc_unwind; | |
| 21 | − | |
| 22 | −unsigned int lookup_num_blocks; | |
| 23 | −bool orc_init; | |
| 24 | +static bool orc_init __ro_after_init; | |
| 25 | +static unsigned int lookup_num_blocks __ro_after_init; | |
| 24 | 26 | |
| 25 | 27 | static inline unsigned long orc_ip(const int *ip) |
| 26 | 28 | { |
| @@ -142,9 +144,6 @@ static struct orc_entry *orc_find(unsigned long ip) · 115 unmodified lines | ||
| 142 | 144 | { |
| 143 | 145 | static struct orc_entry *orc; |
| 144 | 146 | |
| 145 | − if (!orc_init) | |
| 146 | − return NULL; | |
| 147 | − | |
| 148 | 147 | if (ip == 0) |
| 149 | 148 | return &null_orc_entry; |
| 150 | 149 | |
| @@ -189,6 +188,10 @@ static struct orc_entry *orc_find(unsigned long ip) · 38 unmodified lines | ||
| 189 | 188 | |
| 190 | 189 | #ifdef CONFIG_MODULES |
| 191 | 190 | |
| 191 | +static DEFINE_MUTEX(sort_mutex); | |
| 192 | +static int *cur_orc_ip_table = __start_orc_unwind_ip; | |
| 193 | +static struct orc_entry *cur_orc_table = __start_orc_unwind; | |
| 194 | + | |
| 192 | 195 | static void orc_sort_swap(void *_a, void *_b, int size) |
| 193 | 196 | { |
| 194 | 197 | struct orc_entry *orc_a, *orc_b; |
| @@ -381,9 +384,38 @@ static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr · 186 unmodified lines | ||
| 381 | 384 | return true; |
| 382 | 385 | } |
| 383 | 386 | |
| 387 | +/* | |
| 388 | + * If state->regs is non-NULL, and points to a full pt_regs, just get the reg | |
| 389 | + * value from state->regs. | |
| 390 | + * | |
| 391 | + * Otherwise, if state->regs just points to IRET regs, and the previous frame | |
| 392 | + * had full regs, it's safe to get the value from the previous regs. This can | |
| 393 | + * happen when early/late IRQ entry code gets interrupted by an NMI. | |
| 394 | + */ | |
| 395 | +static bool get_reg(struct unwind_state *state, unsigned int reg_off, | |
| 396 | + unsigned long *val) | |
| 397 | +{ | |
| 398 | + unsigned int reg = reg_off/8; | |
| 399 | + | |
| 400 | + if (!state->regs) | |
| 401 | + return false; | |
| 402 | + | |
| 403 | + if (state->full_regs) { | |
| 404 | + *val = ((unsigned long *)state->regs)[reg]; | |
| 405 | + return true; | |
| 406 | + } | |
| 407 | + | |
| 408 | + if (state->prev_regs) { | |
| 409 | + *val = ((unsigned long *)state->prev_regs)[reg]; | |
| 410 | + return true; | |
| 411 | + } | |
| 412 | + | |
| 413 | + return false; | |
| 414 | +} | |
| 415 | + | |
| 384 | 416 | bool unwind_next_frame(struct unwind_state *state) |
| 385 | 417 | { |
| 386 | − unsigned long ip_p, sp, orig_ip = state->ip, prev_sp = state->sp; | |
| 418 | + unsigned long ip_p, sp, tmp, orig_ip = state->ip, prev_sp = state->sp; | |
| 387 | 419 | enum stack_type prev_type = state->stack_info.type; |
| 388 | 420 | struct orc_entry *orc; |
| 389 | 421 | bool indirect = false; |
| @@ -445,43 +477,39 @@ bool unwind_next_frame(struct unwind_state *state) · 55 unmodified lines | ||
| 445 | 477 | break; |
| 446 | 478 | |
| 447 | 479 | case ORC_REG_R10: |
| 448 | − if (!state->regs || !state->full_regs) { | |
| 449 | − orc_warn("missing regs for base reg R10 at ip %pB\n", | |
| 450 | − (void *)state->ip); | |
| 480 | + if (!get_reg(state, offsetof(struct pt_regs, r10), &sp)) { | |
| 481 | + orc_warn_current("missing R10 value at %pB\n", | |
| 482 | + (void *)state->ip); | |
| 451 | 483 | goto err; |
| 452 | 484 | } |
| 453 | − sp = state->regs->r10; | |
| 454 | 485 | break; |
| 455 | 486 | |
| 456 | 487 | case ORC_REG_R13: |
| 457 | − if (!state->regs || !state->full_regs) { | |
| 458 | − orc_warn("missing regs for base reg R13 at ip %pB\n", | |
| 459 | − (void *)state->ip); | |
| 488 | + if (!get_reg(state, offsetof(struct pt_regs, r13), &sp)) { | |
| 489 | + orc_warn_current("missing R13 value at %pB\n", | |
| 490 | + (void *)state->ip); | |
| 460 | 491 | goto err; |
| 461 | 492 | } |
| 462 | − sp = state->regs->r13; | |
| 463 | 493 | break; |
| 464 | 494 | |
| 465 | 495 | case ORC_REG_DI: |
| 466 | − if (!state->regs || !state->full_regs) { | |
| 467 | − orc_warn("missing regs for base reg DI at ip %pB\n", | |
| 468 | − (void *)state->ip); | |
| 496 | + if (!get_reg(state, offsetof(struct pt_regs, di), &sp)) { | |
| 497 | + orc_warn_current("missing RDI value at %pB\n", | |
| 498 | + (void *)state->ip); | |
| 469 | 499 | goto err; |
| 470 | 500 | } |
| 471 | − sp = state->regs->di; | |
| 472 | 501 | break; |
| 473 | 502 | |
| 474 | 503 | case ORC_REG_DX: |
| 475 | − if (!state->regs || !state->full_regs) { | |
| 476 | − orc_warn("missing regs for base reg DX at ip %pB\n", | |
| 477 | − (void *)state->ip); | |
| 504 | + if (!get_reg(state, offsetof(struct pt_regs, dx), &sp)) { | |
| 505 | + orc_warn_current("missing DX value at %pB\n", | |
| 506 | + (void *)state->ip); | |
| 478 | 507 | goto err; |
| 479 | 508 | } |
| 480 | − sp = state->regs->dx; | |
| 481 | 509 | break; |
| 482 | 510 | |
| 483 | 511 | default: |
| 484 | − orc_warn("unknown SP base reg %d for ip %pB\n", | |
| 512 | + orc_warn("unknown SP base reg %d at %pB\n", | |
| 485 | 513 | orc->sp_reg, (void *)state->ip); |
| 486 | 514 | goto err; |
| 487 | 515 | } |
| @@ -504,44 +532,48 @@ bool unwind_next_frame(struct unwind_state *state) · 16 unmodified lines | ||
| 504 | 532 | |
| 505 | 533 | state->sp = sp; |
| 506 | 534 | state->regs = NULL; |
| 535 | + state->prev_regs = NULL; | |
| 507 | 536 | state->signal = false; |
| 508 | 537 | break; |
| 509 | 538 | |
| 510 | 539 | case ORC_TYPE_REGS: |
| 511 | 540 | if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) { |
| 512 | − orc_warn("can't dereference registers at %p for ip %pB\n", | |
| 513 | − (void *)sp, (void *)orig_ip); | |
| 541 | + orc_warn_current("can't access registers at %pB\n", | |
| 542 | + (void *)orig_ip); | |
| 514 | 543 | goto err; |
| 515 | 544 | } |
| 516 | 545 | |
| 517 | 546 | state->regs = (struct pt_regs *)sp; |
| 547 | + state->prev_regs = NULL; | |
| 518 | 548 | state->full_regs = true; |
| 519 | 549 | state->signal = true; |
| 520 | 550 | break; |
| 521 | 551 | |
| 522 | 552 | case ORC_TYPE_REGS_IRET: |
| 523 | 553 | if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) { |
| 524 | − orc_warn("can't dereference iret registers at %p for ip %pB\n", | |
| 525 | − (void *)sp, (void *)orig_ip); | |
| 554 | + orc_warn_current("can't access iret registers at %pB\n", | |
| 555 | + (void *)orig_ip); | |
| 526 | 556 | goto err; |
| 527 | 557 | } |
| 528 | 558 | |
| 559 | + if (state->full_regs) | |
| 560 | + state->prev_regs = state->regs; | |
| 529 | 561 | state->regs = (void *)sp - IRET_FRAME_OFFSET; |
| 530 | 562 | state->full_regs = false; |
| 531 | 563 | state->signal = true; |
| 532 | 564 | break; |
| 533 | 565 | |
| 534 | 566 | default: |
| 535 | − orc_warn("unknown .orc_unwind entry type %d for ip %pB\n", | |
| 567 | + orc_warn("unknown .orc_unwind entry type %d at %pB\n", | |
| 536 | 568 | orc->type, (void *)orig_ip); |
| 537 | − break; | |
| 569 | + goto err; | |
| 538 | 570 | } |
| 539 | 571 | |
| 540 | 572 | /* Find BP: */ |
| 541 | 573 | switch (orc->bp_reg) { |
| 542 | 574 | case ORC_REG_UNDEFINED: |
| 543 | − if (state->regs && state->full_regs) | |
| 544 | − state->bp = state->regs->bp; | |
| 575 | + if (get_reg(state, offsetof(struct pt_regs, bp), &tmp)) | |
| 576 | + state->bp = tmp; | |
| 545 | 577 | break; |
| 546 | 578 | |
| 547 | 579 | case ORC_REG_PREV_SP: |
| @@ -564,8 +596,8 @@ bool unwind_next_frame(struct unwind_state *state) · 16 unmodified lines | ||
| 564 | 596 | if (state->stack_info.type == prev_type && |
| 565 | 597 | on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) && |
| 566 | 598 | state->sp <= prev_sp) { |
| 567 | − orc_warn("stack going in the wrong direction? ip=%pB\n", | |
| 568 | − (void *)orig_ip); | |
| 599 | + orc_warn_current("stack going in the wrong direction? at %pB\n", | |
| 600 | + (void *)orig_ip); | |
| 569 | 601 | goto err; |
| 570 | 602 | } |
| 571 | 603 | |
| @@ -585,6 +617,9 @@ EXPORT_SYMBOL_GPL(unwind_next_frame); · 13 unmodified lines | ||
| 585 | 617 | void __unwind_start(struct unwind_state *state, struct task_struct *task, |
| 586 | 618 | struct pt_regs *regs, unsigned long *first_frame) |
| 587 | 619 | { |
| 620 | + if (!orc_init) | |
| 621 | + goto done; | |
| 622 | + | |
| 588 | 623 | memset(state, 0, sizeof(*state)); |
| 589 | 624 | state->task = task; |
| 590 | 625 | |
| @@ -651,7 +686,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, · 60 unmodified lines | ||
| 651 | 686 | /* Otherwise, skip ahead to the user-specified starting frame: */ |
| 652 | 687 | while (!unwind_done(state) && |
| 653 | 688 | (!on_stack(&state->stack_info, first_frame, sizeof(long)) || |
| 654 | − state->sp <= (unsigned long)first_frame)) | |
| 689 | + state->sp < (unsigned long)first_frame)) | |
| 655 | 690 | unwind_next_frame(state); |
| 656 | 691 | |
| 657 | 692 | return; |
| @@ -225,12 +225,12 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, · 224 unmodified lines | ||
| 225 | 225 | } |
| 226 | 226 | |
| 227 | 227 | /* |
| 228 | − * AMD SVM AVIC accelerate EOI write and do not trap, | |
| 229 | − * in-kernel IOAPIC will not be able to receive the EOI. | |
| 230 | − * In this case, we do lazy update of the pending EOI when | |
| 231 | − * trying to set IOAPIC irq. | |
| 228 | + * AMD SVM AVIC accelerate EOI write iff the interrupt is edge | |
| 229 | + * triggered, in which case the in-kernel IOAPIC will not be able | |
| 230 | + * to receive the EOI. In this case, we do a lazy update of the | |
| 231 | + * pending EOI when trying to set IOAPIC irq. | |
| 232 | 232 | */ |
| 233 | − if (kvm_apicv_activated(ioapic->kvm)) | |
| 233 | + if (edge && kvm_apicv_activated(ioapic->kvm)) | |
| 234 | 234 | ioapic_lazy_update_eoi(ioapic, irq); |
| 235 | 235 | |
| 236 | 236 | /* |
| @@ -345,7 +345,7 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr, · 344 unmodified lines | ||
| 345 | 345 | return NULL; |
| 346 | 346 | |
| 347 | 347 | /* Pin the user virtual address. */ |
| 348 | − npinned = get_user_pages_fast(uaddr, npages, FOLL_WRITE, pages); | |
| 348 | + npinned = get_user_pages_fast(uaddr, npages, write ? FOLL_WRITE : 0, pages); | |
| 349 | 349 | if (npinned != npages) { |
| 350 | 350 | pr_err("SEV: Failure locking %lu pages.\n", npages); |
| 351 | 351 | goto err; |
| @@ -1752,6 +1752,8 @@ static int db_interception(struct vcpu_svm *svm) · 1751 unmodified lines | ||
| 1752 | 1752 | if (svm->vcpu.guest_debug & |
| 1753 | 1753 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) { |
| 1754 | 1754 | kvm_run->exit_reason = KVM_EXIT_DEBUG; |
| 1755 | + kvm_run->debug.arch.dr6 = svm->vmcb->save.dr6; | |
| 1756 | + kvm_run->debug.arch.dr7 = svm->vmcb->save.dr7; | |
| 1755 | 1757 | kvm_run->debug.arch.pc = |
| 1756 | 1758 | svm->vmcb->save.cs.base + svm->vmcb->save.rip; |
| 1757 | 1759 | kvm_run->debug.arch.exception = DB_VECTOR; |
| @@ -5165,7 +5165,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) · 5164 unmodified lines | ||
| 5165 | 5165 | */ |
| 5166 | 5166 | break; |
| 5167 | 5167 | default: |
| 5168 | − BUG_ON(1); | |
| 5168 | + BUG(); | |
| 5169 | 5169 | break; |
| 5170 | 5170 | } |
| 5171 | 5171 | |
| @@ -82,6 +82,9 @@ SYM_FUNC_START(vmx_vmexit) · 81 unmodified lines | ||
| 82 | 82 | /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ |
| 83 | 83 | FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE |
| 84 | 84 | |
| 85 | + /* Clear RFLAGS.CF and RFLAGS.ZF to preserve VM-Exit, i.e. !VM-Fail. */ | |
| 86 | + or $1, %_ASM_AX | |
| 87 | + | |
| 85 | 88 | pop %_ASM_AX |
| 86 | 89 | .Lvmexit_skip_rsb: |
| 87 | 90 | #endif |
| @@ -926,19 +926,6 @@ EXPORT_SYMBOL_GPL(kvm_set_xcr); · 925 unmodified lines | ||
| 926 | 926 | __reserved_bits; \ |
| 927 | 927 | }) |
| 928 | 928 | |
| 929 | −static u64 kvm_host_cr4_reserved_bits(struct cpuinfo_x86 *c) | |
| 930 | −{ | |
| 931 | − u64 reserved_bits = __cr4_reserved_bits(cpu_has, c); | |
| 932 | − | |
| 933 | − if (kvm_cpu_cap_has(X86_FEATURE_LA57)) | |
| 934 | − reserved_bits &= ~X86_CR4_LA57; | |
| 935 | − | |
| 936 | − if (kvm_cpu_cap_has(X86_FEATURE_UMIP)) | |
| 937 | − reserved_bits &= ~X86_CR4_UMIP; | |
| 938 | − | |
| 939 | − return reserved_bits; | |
| 940 | −} | |
| 941 | − | |
| 942 | 929 | static int kvm_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) |
| 943 | 930 | { |
| 944 | 931 | if (cr4 & cr4_reserved_bits) |
| @@ -3385,6 +3372,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 2440 unmodified lines | ||
| 3385 | 3372 | case KVM_CAP_GET_MSR_FEATURES: |
| 3386 | 3373 | case KVM_CAP_MSR_PLATFORM_INFO: |
| 3387 | 3374 | case KVM_CAP_EXCEPTION_PAYLOAD: |
| 3375 | + case KVM_CAP_SET_GUEST_DEBUG: | |
| 3388 | 3376 | r = 1; |
| 3389 | 3377 | break; |
| 3390 | 3378 | case KVM_CAP_SYNC_REGS: |
| @@ -9675,7 +9663,9 @@ int kvm_arch_hardware_setup(void *opaque) · 6284 unmodified lines | ||
| 9675 | 9663 | if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES)) |
| 9676 | 9664 | supported_xss = 0; |
| 9677 | 9665 | |
| 9678 | − cr4_reserved_bits = kvm_host_cr4_reserved_bits(&boot_cpu_data); | |
| 9666 | +#define __kvm_cpu_cap_has(UNUSED_, f) kvm_cpu_cap_has(f) | |
| 9667 | + cr4_reserved_bits = __cr4_reserved_bits(__kvm_cpu_cap_has, UNUSED_); | |
| 9668 | +#undef __kvm_cpu_cap_has | |
| 9679 | 9669 | |
| 9680 | 9670 | if (kvm_has_tsc_control) { |
| 9681 | 9671 | /* |
| @@ -9707,7 +9697,8 @@ int kvm_arch_check_processor_compat(void *opaque) · 25 unmodified lines | ||
| 9707 | 9697 | |
| 9708 | 9698 | WARN_ON(!irqs_disabled()); |
| 9709 | 9699 | |
| 9710 | − if (kvm_host_cr4_reserved_bits(c) != cr4_reserved_bits) | |
| 9700 | + if (__cr4_reserved_bits(cpu_has, c) != | |
| 9701 | + __cr4_reserved_bits(cpu_has, &boot_cpu_data)) | |
| 9711 | 9702 | return -EIO; |
| 9712 | 9703 | |
| 9713 | 9704 | return ops->check_processor_compatibility(); |
| @@ -43,7 +43,8 @@ struct cpa_data { · 42 unmodified lines | ||
| 43 | 43 | unsigned long pfn; |
| 44 | 44 | unsigned int flags; |
| 45 | 45 | unsigned int force_split : 1, |
| 46 | − force_static_prot : 1; | |
| 46 | + force_static_prot : 1, | |
| 47 | + force_flush_all : 1; | |
| 47 | 48 | struct page **pages; |
| 48 | 49 | }; |
| 49 | 50 | |
| @@ -355,10 +356,10 @@ static void cpa_flush(struct cpa_data *data, int cache) · 305 unmodified lines | ||
| 355 | 356 | return; |
| 356 | 357 | } |
| 357 | 358 | |
| 358 | − if (cpa->numpages <= tlb_single_page_flush_ceiling) | |
| 359 | − on_each_cpu(__cpa_flush_tlb, cpa, 1); | |
| 360 | − else | |
| 359 | + if (cpa->force_flush_all || cpa->numpages > tlb_single_page_flush_ceiling) | |
| 361 | 360 | flush_tlb_all(); |
| 361 | + else | |
| 362 | + on_each_cpu(__cpa_flush_tlb, cpa, 1); | |
| 362 | 363 | |
| 363 | 364 | if (!cache) |
| 364 | 365 | return; |
| @@ -1598,6 +1599,8 @@ static int cpa_process_alias(struct cpa_data *cpa) · 1233 unmodified lines | ||
| 1598 | 1599 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); |
| 1599 | 1600 | alias_cpa.curpage = 0; |
| 1600 | 1601 | |
| 1602 | + cpa->force_flush_all = 1; | |
| 1603 | + | |
| 1601 | 1604 | ret = __change_page_attr_set_clr(&alias_cpa, 0); |
| 1602 | 1605 | if (ret) |
| 1603 | 1606 | return ret; |
| @@ -1618,6 +1621,7 @@ static int cpa_process_alias(struct cpa_data *cpa) · 14 unmodified lines | ||
| 1618 | 1621 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); |
| 1619 | 1622 | alias_cpa.curpage = 0; |
| 1620 | 1623 | |
| 1624 | + cpa->force_flush_all = 1; | |
| 1621 | 1625 | /* |
| 1622 | 1626 | * The high mapping range is imprecise, so ignore the |
| 1623 | 1627 | * return value. |
| @@ -123,6 +123,7 @@ · 122 unmodified lines | ||
| 123 | 123 | #include <linux/ioprio.h> |
| 124 | 124 | #include <linux/sbitmap.h> |
| 125 | 125 | #include <linux/delay.h> |
| 126 | +#include <linux/backing-dev.h> | |
| 126 | 127 | |
| 127 | 128 | #include "blk.h" |
| 128 | 129 | #include "blk-mq.h" |
| @@ -4976,8 +4977,9 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) · 4847 unmodified lines | ||
| 4976 | 4977 | ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); |
| 4977 | 4978 | switch (ioprio_class) { |
| 4978 | 4979 | default: |
| 4979 | − dev_err(bfqq->bfqd->queue->backing_dev_info->dev, | |
| 4980 | − "bfq: bad prio class %d\n", ioprio_class); | |
| 4980 | + pr_err("bdi %s: bfq: bad prio class %d\n", | |
| 4981 | + bdi_dev_name(bfqq->bfqd->queue->backing_dev_info), | |
| 4982 | + ioprio_class); | |
| 4981 | 4983 | /* fall through */ |
| 4982 | 4984 | case IOPRIO_CLASS_NONE: |
| 4983 | 4985 | /* |
| @@ -496,7 +496,7 @@ const char *blkg_dev_name(struct blkcg_gq *blkg) · 495 unmodified lines | ||
| 496 | 496 | { |
| 497 | 497 | /* some drivers (floppy) instantiate a queue w/o disk registered */ |
| 498 | 498 | if (blkg->q->backing_dev_info->dev) |
| 499 | − return dev_name(blkg->q->backing_dev_info->dev); | |
| 499 | + return bdi_dev_name(blkg->q->backing_dev_info); | |
| 500 | 500 | return NULL; |
| 501 | 501 | } |
| 502 | 502 | |
| @@ -466,7 +466,7 @@ struct ioc_gq { · 465 unmodified lines | ||
| 466 | 466 | */ |
| 467 | 467 | atomic64_t vtime; |
| 468 | 468 | atomic64_t done_vtime; |
| 469 | − atomic64_t abs_vdebt; | |
| 469 | + u64 abs_vdebt; | |
| 470 | 470 | u64 last_vtime; |
| 471 | 471 | |
| 472 | 472 | /* |
| @@ -1142,7 +1142,7 @@ static void iocg_kick_waitq(struct ioc_gq *iocg, struct ioc_now *now) · 669 unmodified lines | ||
| 1142 | 1142 | struct iocg_wake_ctx ctx = { .iocg = iocg }; |
| 1143 | 1143 | u64 margin_ns = (u64)(ioc->period_us * |
| 1144 | 1144 | WAITQ_TIMER_MARGIN_PCT / 100) * NSEC_PER_USEC; |
| 1145 | − u64 abs_vdebt, vdebt, vshortage, expires, oexpires; | |
| 1145 | + u64 vdebt, vshortage, expires, oexpires; | |
| 1146 | 1146 | s64 vbudget; |
| 1147 | 1147 | u32 hw_inuse; |
| 1148 | 1148 | |
| @@ -1152,18 +1152,15 @@ static void iocg_kick_waitq(struct ioc_gq *iocg, struct ioc_now *now) · 3 unmodified lines | ||
| 1152 | 1152 | vbudget = now->vnow - atomic64_read(&iocg->vtime); |
| 1153 | 1153 | |
| 1154 | 1154 | /* pay off debt */ |
| 1155 | − abs_vdebt = atomic64_read(&iocg->abs_vdebt); | |
| 1156 | − vdebt = abs_cost_to_cost(abs_vdebt, hw_inuse); | |
| 1155 | + vdebt = abs_cost_to_cost(iocg->abs_vdebt, hw_inuse); | |
| 1157 | 1156 | if (vdebt && vbudget > 0) { |
| 1158 | 1157 | u64 delta = min_t(u64, vbudget, vdebt); |
| 1159 | 1158 | u64 abs_delta = min(cost_to_abs_cost(delta, hw_inuse), |
| 1160 | − abs_vdebt); | |
| 1159 | + iocg->abs_vdebt); | |
| 1161 | 1160 | |
| 1162 | 1161 | atomic64_add(delta, &iocg->vtime); |
| 1163 | 1162 | atomic64_add(delta, &iocg->done_vtime); |
| 1164 | − atomic64_sub(abs_delta, &iocg->abs_vdebt); | |
| 1165 | − if (WARN_ON_ONCE(atomic64_read(&iocg->abs_vdebt) < 0)) | |
| 1166 | − atomic64_set(&iocg->abs_vdebt, 0); | |
| 1163 | + iocg->abs_vdebt -= abs_delta; | |
| 1167 | 1164 | } |
| 1168 | 1165 | |
| 1169 | 1166 | /* |
| @@ -1219,12 +1216,18 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now, u64 cost) · 49 unmodified lines | ||
| 1219 | 1216 | u64 expires, oexpires; |
| 1220 | 1217 | u32 hw_inuse; |
| 1221 | 1218 | |
| 1219 | + lockdep_assert_held(&iocg->waitq.lock); | |
| 1220 | + | |
| 1222 | 1221 | /* debt-adjust vtime */ |
| 1223 | 1222 | current_hweight(iocg, NULL, &hw_inuse); |
| 1224 | − vtime += abs_cost_to_cost(atomic64_read(&iocg->abs_vdebt), hw_inuse); | |
| 1223 | + vtime += abs_cost_to_cost(iocg->abs_vdebt, hw_inuse); | |
| 1225 | 1224 | |
| 1226 | − /* clear or maintain depending on the overage */ | |
| 1227 | − if (time_before_eq64(vtime, now->vnow)) { | |
| 1225 | + /* | |
| 1226 | + * Clear or maintain depending on the overage. Non-zero vdebt is what | |
| 1227 | + * guarantees that @iocg is online and future iocg_kick_delay() will | |
| 1228 | + * clear use_delay. Don't leave it on when there's no vdebt. | |
| 1229 | + */ | |
| 1230 | + if (!iocg->abs_vdebt || time_before_eq64(vtime, now->vnow)) { | |
| 1228 | 1231 | blkcg_clear_delay(blkg); |
| 1229 | 1232 | return false; |
| 1230 | 1233 | } |
| @@ -1258,9 +1261,12 @@ static enum hrtimer_restart iocg_delay_timer_fn(struct hrtimer *timer) · 27 unmodified lines | ||
| 1258 | 1261 | { |
| 1259 | 1262 | struct ioc_gq *iocg = container_of(timer, struct ioc_gq, delay_timer); |
| 1260 | 1263 | struct ioc_now now; |
| 1264 | + unsigned long flags; | |
| 1261 | 1265 | |
| 1266 | + spin_lock_irqsave(&iocg->waitq.lock, flags); | |
| 1262 | 1267 | ioc_now(iocg->ioc, &now); |
| 1263 | 1268 | iocg_kick_delay(iocg, &now, 0); |
| 1269 | + spin_unlock_irqrestore(&iocg->waitq.lock, flags); | |
| 1264 | 1270 | |
| 1265 | 1271 | return HRTIMER_NORESTART; |
| 1266 | 1272 | } |
| @@ -1368,14 +1374,13 @@ static void ioc_timer_fn(struct timer_list *timer) · 101 unmodified lines | ||
| 1368 | 1374 | * should have woken up in the last period and expire idle iocgs. |
| 1369 | 1375 | */ |
| 1370 | 1376 | list_for_each_entry_safe(iocg, tiocg, &ioc->active_iocgs, active_list) { |
| 1371 | − if (!waitqueue_active(&iocg->waitq) && | |
| 1372 | − !atomic64_read(&iocg->abs_vdebt) && !iocg_is_idle(iocg)) | |
| 1377 | + if (!waitqueue_active(&iocg->waitq) && iocg->abs_vdebt && | |
| 1378 | + !iocg_is_idle(iocg)) | |
| 1373 | 1379 | continue; |
| 1374 | 1380 | |
| 1375 | 1381 | spin_lock(&iocg->waitq.lock); |
| 1376 | 1382 | |
| 1377 | − if (waitqueue_active(&iocg->waitq) || | |
| 1378 | − atomic64_read(&iocg->abs_vdebt)) { | |
| 1383 | + if (waitqueue_active(&iocg->waitq) || iocg->abs_vdebt) { | |
| 1379 | 1384 | /* might be oversleeping vtime / hweight changes, kick */ |
| 1380 | 1385 | iocg_kick_waitq(iocg, &now); |
| 1381 | 1386 | iocg_kick_delay(iocg, &now, 0); |
| @@ -1718,28 +1723,49 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio) · 336 unmodified lines | ||
| 1718 | 1723 | * tests are racy but the races aren't systemic - we only miss once |
| 1719 | 1724 | * in a while which is fine. |
| 1720 | 1725 | */ |
| 1721 | − if (!waitqueue_active(&iocg->waitq) && | |
| 1722 | − !atomic64_read(&iocg->abs_vdebt) && | |
| 1726 | + if (!waitqueue_active(&iocg->waitq) && !iocg->abs_vdebt && | |
| 1723 | 1727 | time_before_eq64(vtime + cost, now.vnow)) { |
| 1724 | 1728 | iocg_commit_bio(iocg, bio, cost); |
| 1725 | 1729 | return; |
| 1726 | 1730 | } |
| 1727 | 1731 | |
| 1728 | 1732 | /* |
| 1729 | − * We're over budget. If @bio has to be issued regardless, | |
| 1730 | − * remember the abs_cost instead of advancing vtime. | |
| 1731 | − * iocg_kick_waitq() will pay off the debt before waking more IOs. | |
| 1733 | + * We activated above but w/o any synchronization. Deactivation is | |
| 1734 | + * synchronized with waitq.lock and we won't get deactivated as long | |
| 1735 | + * as we're waiting or has debt, so we're good if we're activated | |
| 1736 | + * here. In the unlikely case that we aren't, just issue the IO. | |
| 1737 | + */ | |
| 1738 | + spin_lock_irq(&iocg->waitq.lock); | |
| 1739 | + | |
| 1740 | + if (unlikely(list_empty(&iocg->active_list))) { | |
| 1741 | + spin_unlock_irq(&iocg->waitq.lock); | |
| 1742 | + iocg_commit_bio(iocg, bio, cost); | |
| 1743 | + return; | |
| 1744 | + } | |
| 1745 | + | |
| 1746 | + /* | |
| 1747 | + * We're over budget. If @bio has to be issued regardless, remember | |
| 1748 | + * the abs_cost instead of advancing vtime. iocg_kick_waitq() will pay | |
| 1749 | + * off the debt before waking more IOs. | |
| 1750 | + * | |
| 1732 | 1751 | * This way, the debt is continuously paid off each period with the |
| 1733 | − * actual budget available to the cgroup. If we just wound vtime, | |
| 1734 | − * we would incorrectly use the current hw_inuse for the entire | |
| 1735 | − * amount which, for example, can lead to the cgroup staying | |
| 1736 | − * blocked for a long time even with substantially raised hw_inuse. | |
| 1752 | + * actual budget available to the cgroup. If we just wound vtime, we | |
| 1753 | + * would incorrectly use the current hw_inuse for the entire amount | |
| 1754 | + * which, for example, can lead to the cgroup staying blocked for a | |
| 1755 | + * long time even with substantially raised hw_inuse. | |
| 1756 | + * | |
| 1757 | + * An iocg with vdebt should stay online so that the timer can keep | |
| 1758 | + * deducting its vdebt and [de]activate use_delay mechanism | |
| 1759 | + * accordingly. We don't want to race against the timer trying to | |
| 1760 | + * clear them and leave @iocg inactive w/ dangling use_delay heavily | |
| 1761 | + * penalizing the cgroup and its descendants. | |
| 1737 | 1762 | */ |
| 1738 | 1763 | if (bio_issue_as_root_blkg(bio) || fatal_signal_pending(current)) { |
| 1739 | − atomic64_add(abs_cost, &iocg->abs_vdebt); | |
| 1764 | + iocg->abs_vdebt += abs_cost; | |
| 1740 | 1765 | if (iocg_kick_delay(iocg, &now, cost)) |
| 1741 | 1766 | blkcg_schedule_throttle(rqos->q, |
| 1742 | 1767 | (bio->bi_opf & REQ_SWAP) == REQ_SWAP); |
| 1768 | + spin_unlock_irq(&iocg->waitq.lock); | |
| 1743 | 1769 | return; |
| 1744 | 1770 | } |
| 1745 | 1771 | |
| @@ -1756,20 +1782,6 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio) · 10 unmodified lines | ||
| 1756 | 1782 | * All waiters are on iocg->waitq and the wait states are |
| 1757 | 1783 | * synchronized using waitq.lock. |
| 1758 | 1784 | */ |
| 1759 | − spin_lock_irq(&iocg->waitq.lock); | |
| 1760 | − | |
| 1761 | − /* | |
| 1762 | − * We activated above but w/o any synchronization. Deactivation is | |
| 1763 | − * synchronized with waitq.lock and we won't get deactivated as | |
| 1764 | − * long as we're waiting, so we're good if we're activated here. | |
| 1765 | − * In the unlikely case that we are deactivated, just issue the IO. | |
| 1766 | − */ | |
| 1767 | − if (unlikely(list_empty(&iocg->active_list))) { | |
| 1768 | − spin_unlock_irq(&iocg->waitq.lock); | |
| 1769 | − iocg_commit_bio(iocg, bio, cost); | |
| 1770 | − return; | |
| 1771 | − } | |
| 1772 | − | |
| 1773 | 1785 | init_waitqueue_func_entry(&wait.wait, iocg_wake_fn); |
| 1774 | 1786 | wait.wait.private = current; |
| 1775 | 1787 | wait.bio = bio; |
| @@ -1801,6 +1813,7 @@ static void ioc_rqos_merge(struct rq_qos *rqos, struct request *rq, · 25 unmodified lines | ||
| 1801 | 1813 | struct ioc_now now; |
| 1802 | 1814 | u32 hw_inuse; |
| 1803 | 1815 | u64 abs_cost, cost; |
| 1816 | + unsigned long flags; | |
| 1804 | 1817 | |
| 1805 | 1818 | /* bypass if disabled or for root cgroup */ |
| 1806 | 1819 | if (!ioc->enabled || !iocg->level) |
| @@ -1820,15 +1833,28 @@ static void ioc_rqos_merge(struct rq_qos *rqos, struct request *rq, · 13 unmodified lines | ||
| 1820 | 1833 | iocg->cursor = bio_end; |
| 1821 | 1834 | |
| 1822 | 1835 | /* |
| 1823 | − * Charge if there's enough vtime budget and the existing request | |
| 1824 | − * has cost assigned. Otherwise, account it as debt. See debt | |
| 1825 | − * handling in ioc_rqos_throttle() for details. | |
| 1836 | + * Charge if there's enough vtime budget and the existing request has | |
| 1837 | + * cost assigned. | |
| 1826 | 1838 | */ |
| 1827 | 1839 | if (rq->bio && rq->bio->bi_iocost_cost && |
| 1828 | − time_before_eq64(atomic64_read(&iocg->vtime) + cost, now.vnow)) | |
| 1840 | + time_before_eq64(atomic64_read(&iocg->vtime) + cost, now.vnow)) { | |
| 1829 | 1841 | iocg_commit_bio(iocg, bio, cost); |
| 1830 | − else | |
| 1831 | − atomic64_add(abs_cost, &iocg->abs_vdebt); | |
| 1842 | + return; | |
| 1843 | + } | |
| 1844 | + | |
| 1845 | + /* | |
| 1846 | + * Otherwise, account it as debt if @iocg is online, which it should | |
| 1847 | + * be for the vast majority of cases. See debt handling in | |
| 1848 | + * ioc_rqos_throttle() for details. | |
| 1849 | + */ | |
| 1850 | + spin_lock_irqsave(&iocg->waitq.lock, flags); | |
| 1851 | + if (likely(!list_empty(&iocg->active_list))) { | |
| 1852 | + iocg->abs_vdebt += abs_cost; | |
| 1853 | + iocg_kick_delay(iocg, &now, cost); | |
| 1854 | + } else { | |
| 1855 | + iocg_commit_bio(iocg, bio, cost); | |
| 1856 | + } | |
| 1857 | + spin_unlock_irqrestore(&iocg->waitq.lock, flags); | |
| 1832 | 1858 | } |
| 1833 | 1859 | |
| 1834 | 1860 | static void ioc_rqos_done_bio(struct rq_qos *rqos, struct bio *bio) |
| @@ -1998,7 +2024,6 @@ static void ioc_pd_init(struct blkg_policy_data *pd) · 163 unmodified lines | ||
| 1998 | 2024 | iocg->ioc = ioc; |
| 1999 | 2025 | atomic64_set(&iocg->vtime, now.vnow); |
| 2000 | 2026 | atomic64_set(&iocg->done_vtime, now.vnow); |
| 2001 | − atomic64_set(&iocg->abs_vdebt, 0); | |
| 2002 | 2027 | atomic64_set(&iocg->active_period, atomic64_read(&ioc->cur_period)); |
| 2003 | 2028 | INIT_LIST_HEAD(&iocg->active_list); |
| 2004 | 2029 | iocg->hweight_active = HWEIGHT_WHOLE; |
| @@ -496,7 +496,7 @@ int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev) · 495 unmodified lines | ||
| 496 | 496 | |
| 497 | 497 | if (!disk_part_scan_enabled(disk)) |
| 498 | 498 | return 0; |
| 499 | − if (bdev->bd_part_count || bdev->bd_openers > 1) | |
| 499 | + if (bdev->bd_part_count) | |
| 500 | 500 | return -EBUSY; |
| 501 | 501 | res = invalidate_partition(disk, 0); |
| 502 | 502 | if (res) |
| @@ -287,7 +287,7 @@ static void exit_tfm(struct crypto_skcipher *tfm) · 286 unmodified lines | ||
| 287 | 287 | crypto_free_skcipher(ctx->child); |
| 288 | 288 | } |
| 289 | 289 | |
| 290 | −static void free(struct skcipher_instance *inst) | |
| 290 | +static void free_inst(struct skcipher_instance *inst) | |
| 291 | 291 | { |
| 292 | 292 | crypto_drop_skcipher(skcipher_instance_ctx(inst)); |
| 293 | 293 | kfree(inst); |
| @@ -400,12 +400,12 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb) · 106 unmodified lines | ||
| 400 | 400 | inst->alg.encrypt = encrypt; |
| 401 | 401 | inst->alg.decrypt = decrypt; |
| 402 | 402 | |
| 403 | − inst->free = free; | |
| 403 | + inst->free = free_inst; | |
| 404 | 404 | |
| 405 | 405 | err = skcipher_register_instance(tmpl, inst); |
| 406 | 406 | if (err) { |
| 407 | 407 | err_free_inst: |
| 408 | − free(inst); | |
| 408 | + free_inst(inst); | |
| 409 | 409 | } |
| 410 | 410 | return err; |
| 411 | 411 | } |
| @@ -322,7 +322,7 @@ static void exit_tfm(struct crypto_skcipher *tfm) · 321 unmodified lines | ||
| 322 | 322 | crypto_free_cipher(ctx->tweak); |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | −static void free(struct skcipher_instance *inst) | |
| 325 | +static void free_inst(struct skcipher_instance *inst) | |
| 326 | 326 | { |
| 327 | 327 | crypto_drop_skcipher(skcipher_instance_ctx(inst)); |
| 328 | 328 | kfree(inst); |
| @@ -434,12 +434,12 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb) · 105 unmodified lines | ||
| 434 | 434 | inst->alg.encrypt = encrypt; |
| 435 | 435 | inst->alg.decrypt = decrypt; |
| 436 | 436 | |
| 437 | − inst->free = free; | |
| 437 | + inst->free = free_inst; | |
| 438 | 438 | |
| 439 | 439 | err = skcipher_register_instance(tmpl, inst); |
| 440 | 440 | if (err) { |
| 441 | 441 | err_free_inst: |
| 442 | − free(inst); | |
| 442 | + free_inst(inst); | |
| 443 | 443 | } |
| 444 | 444 | return err; |
| 445 | 445 | } |
| @@ -273,13 +273,13 @@ int acpi_device_set_power(struct acpi_device *device, int state) · 272 unmodified lines | ||
| 273 | 273 | end: |
| 274 | 274 | if (result) { |
| 275 | 275 | dev_warn(&device->dev, "Failed to change power state to %s\n", |
| 276 | − acpi_power_state_string(state)); | |
| 276 | + acpi_power_state_string(target_state)); | |
| 277 | 277 | } else { |
| 278 | 278 | device->power.state = target_state; |
| 279 | 279 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 280 | 280 | "Device [%s] transitioned to %s\n", |
| 281 | 281 | device->pnp.bus_id, |
| 282 | − acpi_power_state_string(state))); | |
| 282 | + acpi_power_state_string(target_state))); | |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | return result; |
| @@ -645,6 +645,7 @@ static void amba_device_initialize(struct amba_device *dev, const char *name) · 644 unmodified lines | ||
| 645 | 645 | dev->dev.release = amba_device_release; |
| 646 | 646 | dev->dev.bus = &amba_bustype; |
| 647 | 647 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; |
| 648 | + dev->dev.dma_parms = &dev->dma_parms; | |
| 648 | 649 | dev->res.name = dev_name(&dev->dev); |
| 649 | 650 | } |
| 650 | 651 | |
| @@ -256,7 +256,8 @@ static int try_to_bring_up_master(struct master *master, · 255 unmodified lines | ||
| 256 | 256 | ret = master->ops->bind(master->dev); |
| 257 | 257 | if (ret < 0) { |
| 258 | 258 | devres_release_group(master->dev, NULL); |
| 259 | − dev_info(master->dev, "master bind failed: %d\n", ret); | |
| 259 | + if (ret != -EPROBE_DEFER) | |
| 260 | + dev_info(master->dev, "master bind failed: %d\n", ret); | |
| 260 | 261 | return ret; |
| 261 | 262 | } |
| 262 | 263 | |
| @@ -611,8 +612,9 @@ static int component_bind(struct component *component, struct master *master, · 348 unmodified lines | ||
| 611 | 612 | devres_release_group(component->dev, NULL); |
| 612 | 613 | devres_release_group(master->dev, NULL); |
| 613 | 614 | |
| 614 | − dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", | |
| 615 | − dev_name(component->dev), component->ops, ret); | |
| 615 | + if (ret != -EPROBE_DEFER) | |
| 616 | + dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", | |
| 617 | + dev_name(component->dev), component->ops, ret); | |
| 616 | 618 | } |
| 617 | 619 | |
| 618 | 620 | return ret; |
| @@ -2370,6 +2370,11 @@ u32 fw_devlink_get_flags(void) · 2369 unmodified lines | ||
| 2370 | 2370 | return fw_devlink_flags; |
| 2371 | 2371 | } |
| 2372 | 2372 | |
| 2373 | +static bool fw_devlink_is_permissive(void) | |
| 2374 | +{ | |
| 2375 | + return fw_devlink_flags == DL_FLAG_SYNC_STATE_ONLY; | |
| 2376 | +} | |
| 2377 | + | |
| 2373 | 2378 | /** |
| 2374 | 2379 | * device_add - add device to device hierarchy. |
| 2375 | 2380 | * @dev: device. |
| @@ -2524,7 +2529,7 @@ int device_add(struct device *dev) · 148 unmodified lines | ||
| 2524 | 2529 | if (fw_devlink_flags && is_fwnode_dev && |
| 2525 | 2530 | fwnode_has_op(dev->fwnode, add_links)) { |
| 2526 | 2531 | fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev); |
| 2527 | − if (fw_ret == -ENODEV) | |
| 2532 | + if (fw_ret == -ENODEV && !fw_devlink_is_permissive()) | |
| 2528 | 2533 | device_link_wait_for_mandatory_supplier(dev); |
| 2529 | 2534 | else if (fw_ret) |
| 2530 | 2535 | device_link_wait_for_optional_supplier(dev); |
| @@ -224,17 +224,9 @@ static int deferred_devs_show(struct seq_file *s, void *data) · 223 unmodified lines | ||
| 224 | 224 | } |
| 225 | 225 | DEFINE_SHOW_ATTRIBUTE(deferred_devs); |
| 226 | 226 | |
| 227 | −#ifdef CONFIG_MODULES | |
| 228 | −/* | |
| 229 | − * In the case of modules, set the default probe timeout to | |
| 230 | − * 30 seconds to give userland some time to load needed modules | |
| 231 | − */ | |
| 232 | −int driver_deferred_probe_timeout = 30; | |
| 233 | −#else | |
| 234 | −/* In the case of !modules, no probe timeout needed */ | |
| 235 | −int driver_deferred_probe_timeout = -1; | |
| 236 | −#endif | |
| 227 | +int driver_deferred_probe_timeout; | |
| 237 | 228 | EXPORT_SYMBOL_GPL(driver_deferred_probe_timeout); |
| 229 | +static DECLARE_WAIT_QUEUE_HEAD(probe_timeout_waitqueue); | |
| 238 | 230 | |
| 239 | 231 | static int __init deferred_probe_timeout_setup(char *str) |
| 240 | 232 | { |
| @@ -266,8 +258,8 @@ int driver_deferred_probe_check_state(struct device *dev) · 25 unmodified lines | ||
| 266 | 258 | return -ENODEV; |
| 267 | 259 | } |
| 268 | 260 | |
| 269 | − if (!driver_deferred_probe_timeout) { | |
| 270 | − dev_WARN(dev, "deferred probe timeout, ignoring dependency\n"); | |
| 261 | + if (!driver_deferred_probe_timeout && initcalls_done) { | |
| 262 | + dev_warn(dev, "deferred probe timeout, ignoring dependency\n"); | |
| 271 | 263 | return -ETIMEDOUT; |
| 272 | 264 | } |
| 273 | 265 | |
| @@ -284,6 +276,7 @@ static void deferred_probe_timeout_work_func(struct work_struct *work) · 10 unmodified lines | ||
| 284 | 276 | |
| 285 | 277 | list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe) |
| 286 | 278 | dev_info(private->device, "deferred probe pending\n"); |
| 279 | + wake_up(&probe_timeout_waitqueue); | |
| 287 | 280 | } |
| 288 | 281 | static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func); |
| 289 | 282 | |
| @@ -657,6 +650,9 @@ int driver_probe_done(void) · 367 unmodified lines | ||
| 657 | 650 | */ |
| 658 | 651 | void wait_for_device_probe(void) |
| 659 | 652 | { |
| 653 | + /* wait for probe timeout */ | |
| 654 | + wait_event(probe_timeout_waitqueue, !driver_deferred_probe_timeout); | |
| 655 | + | |
| 660 | 656 | /* wait for the deferred probe workqueue to finish */ |
| 661 | 657 | flush_work(&deferred_probe_work); |
| 662 | 658 | |
| @@ -380,6 +380,8 @@ struct platform_object { · 379 unmodified lines | ||
| 380 | 380 | */ |
| 381 | 381 | static void setup_pdev_dma_masks(struct platform_device *pdev) |
| 382 | 382 | { |
| 383 | + pdev->dev.dma_parms = &pdev->dma_parms; | |
| 384 | + | |
| 383 | 385 | if (!pdev->dev.coherent_dma_mask) |
| 384 | 386 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
| 385 | 387 | if (!pdev->dev.dma_mask) { |
| @@ -33,6 +33,15 @@ struct virtio_blk_vq { · 32 unmodified lines | ||
| 33 | 33 | } ____cacheline_aligned_in_smp; |
| 34 | 34 | |
| 35 | 35 | struct virtio_blk { |
| 36 | + /* | |
| 37 | + * This mutex must be held by anything that may run after | |
| 38 | + * virtblk_remove() sets vblk->vdev to NULL. | |
| 39 | + * | |
| 40 | + * blk-mq, virtqueue processing, and sysfs attribute code paths are | |
| 41 | + * shut down before vblk->vdev is set to NULL and therefore do not need | |
| 42 | + * to hold this mutex. | |
| 43 | + */ | |
| 44 | + struct mutex vdev_mutex; | |
| 36 | 45 | struct virtio_device *vdev; |
| 37 | 46 | |
| 38 | 47 | /* The disk structure for the kernel. */ |
| @@ -44,6 +53,13 @@ struct virtio_blk { · 5 unmodified lines | ||
| 44 | 53 | /* Process context for config space updates */ |
| 45 | 54 | struct work_struct config_work; |
| 46 | 55 | |
| 56 | + /* | |
| 57 | + * Tracks references from block_device_operations open/release and | |
| 58 | + * virtio_driver probe/remove so this object can be freed once no | |
| 59 | + * longer in use. | |
| 60 | + */ | |
| 61 | + refcount_t refs; | |
| 62 | + | |
| 47 | 63 | /* What host tells us, plus 2 for header & tailer. */ |
| 48 | 64 | unsigned int sg_elems; |
| 49 | 65 | |
| @@ -295,10 +311,55 @@ out: · 245 unmodified lines | ||
| 295 | 311 | return err; |
| 296 | 312 | } |
| 297 | 313 | |
| 314 | +static void virtblk_get(struct virtio_blk *vblk) | |
| 315 | +{ | |
| 316 | + refcount_inc(&vblk->refs); | |
| 317 | +} | |
| 318 | + | |
| 319 | +static void virtblk_put(struct virtio_blk *vblk) | |
| 320 | +{ | |
| 321 | + if (refcount_dec_and_test(&vblk->refs)) { | |
| 322 | + ida_simple_remove(&vd_index_ida, vblk->index); | |
| 323 | + mutex_destroy(&vblk->vdev_mutex); | |
| 324 | + kfree(vblk); | |
| 325 | + } | |
| 326 | +} | |
| 327 | + | |
| 328 | +static int virtblk_open(struct block_device *bd, fmode_t mode) | |
| 329 | +{ | |
| 330 | + struct virtio_blk *vblk = bd->bd_disk->private_data; | |
| 331 | + int ret = 0; | |
| 332 | + | |
| 333 | + mutex_lock(&vblk->vdev_mutex); | |
| 334 | + | |
| 335 | + if (vblk->vdev) | |
| 336 | + virtblk_get(vblk); | |
| 337 | + else | |
| 338 | + ret = -ENXIO; | |
| 339 | + | |
| 340 | + mutex_unlock(&vblk->vdev_mutex); | |
| 341 | + return ret; | |
| 342 | +} | |
| 343 | + | |
| 344 | +static void virtblk_release(struct gendisk *disk, fmode_t mode) | |
| 345 | +{ | |
| 346 | + struct virtio_blk *vblk = disk->private_data; | |
| 347 | + | |
| 348 | + virtblk_put(vblk); | |
| 349 | +} | |
| 350 | + | |
| 298 | 351 | /* We provide getgeo only to please some old bootloader/partitioning tools */ |
| 299 | 352 | static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) |
| 300 | 353 | { |
| 301 | 354 | struct virtio_blk *vblk = bd->bd_disk->private_data; |
| 355 | + int ret = 0; | |
| 356 | + | |
| 357 | + mutex_lock(&vblk->vdev_mutex); | |
| 358 | + | |
| 359 | + if (!vblk->vdev) { | |
| 360 | + ret = -ENXIO; | |
| 361 | + goto out; | |
| 362 | + } | |
| 302 | 363 | |
| 303 | 364 | /* see if the host passed in geometry config */ |
| 304 | 365 | if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_GEOMETRY)) { |
| @@ -314,11 +375,15 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) · 9 unmodified lines | ||
| 314 | 375 | geo->sectors = 1 << 5; |
| 315 | 376 | geo->cylinders = get_capacity(bd->bd_disk) >> 11; |
| 316 | 377 | } |
| 317 | − return 0; | |
| 378 | +out: | |
| 379 | + mutex_unlock(&vblk->vdev_mutex); | |
| 380 | + return ret; | |
| 318 | 381 | } |
| 319 | 382 | |
| 320 | 383 | static const struct block_device_operations virtblk_fops = { |
| 321 | 384 | .owner = THIS_MODULE, |
| 385 | + .open = virtblk_open, | |
| 386 | + .release = virtblk_release, | |
| 322 | 387 | .getgeo = virtblk_getgeo, |
| 323 | 388 | }; |
| 324 | 389 | |
| @@ -655,6 +720,10 @@ static int virtblk_probe(struct virtio_device *vdev) · 330 unmodified lines | ||
| 655 | 720 | goto out_free_index; |
| 656 | 721 | } |
| 657 | 722 | |
| 723 | + /* This reference is dropped in virtblk_remove(). */ | |
| 724 | + refcount_set(&vblk->refs, 1); | |
| 725 | + mutex_init(&vblk->vdev_mutex); | |
| 726 | + | |
| 658 | 727 | vblk->vdev = vdev; |
| 659 | 728 | vblk->sg_elems = sg_elems; |
| 660 | 729 | |
| @@ -820,8 +889,6 @@ out: · 159 unmodified lines | ||
| 820 | 889 | static void virtblk_remove(struct virtio_device *vdev) |
| 821 | 890 | { |
| 822 | 891 | struct virtio_blk *vblk = vdev->priv; |
| 823 | − int index = vblk->index; | |
| 824 | − int refc; | |
| 825 | 892 | |
| 826 | 893 | /* Make sure no work handler is accessing the device. */ |
| 827 | 894 | flush_work(&vblk->config_work); |
| @@ -831,18 +898,21 @@ static void virtblk_remove(struct virtio_device *vdev) · 3 unmodified lines | ||
| 831 | 898 | |
| 832 | 899 | blk_mq_free_tag_set(&vblk->tag_set); |
| 833 | 900 | |
| 901 | + mutex_lock(&vblk->vdev_mutex); | |
| 902 | + | |
| 834 | 903 | /* Stop all the virtqueues. */ |
| 835 | 904 | vdev->config->reset(vdev); |
| 836 | 905 | |
| 837 | − refc = kref_read(&disk_to_dev(vblk->disk)->kobj.kref); | |
| 906 | + /* Virtqueues are stopped, nothing can use vblk->vdev anymore. */ | |
| 907 | + vblk->vdev = NULL; | |
| 908 | + | |
| 838 | 909 | put_disk(vblk->disk); |
| 839 | 910 | vdev->config->del_vqs(vdev); |
| 840 | 911 | kfree(vblk->vqs); |
| 841 | − kfree(vblk); | |
| 842 | 912 | |
| 843 | − /* Only free device id if we don't have any users */ | |
| 844 | − if (refc == 1) | |
| 845 | − ida_simple_remove(&vd_index_ida, index); | |
| 913 | + mutex_unlock(&vblk->vdev_mutex); | |
| 914 | + | |
| 915 | + virtblk_put(vblk); | |
| 846 | 916 | } |
| 847 | 917 | |
| 848 | 918 | #ifdef CONFIG_PM_SLEEP |
| @@ -812,10 +812,9 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl, · 811 unmodified lines | ||
| 812 | 812 | if (!mhi_cntrl) |
| 813 | 813 | return -EINVAL; |
| 814 | 814 | |
| 815 | − if (!mhi_cntrl->runtime_get || !mhi_cntrl->runtime_put) | |
| 816 | − return -EINVAL; | |
| 817 | − | |
| 818 | − if (!mhi_cntrl->status_cb || !mhi_cntrl->link_status) | |
| 815 | + if (!mhi_cntrl->runtime_get || !mhi_cntrl->runtime_put || | |
| 816 | + !mhi_cntrl->status_cb || !mhi_cntrl->read_reg || | |
| 817 | + !mhi_cntrl->write_reg) | |
| 819 | 818 | return -EINVAL; |
| 820 | 819 | |
| 821 | 820 | ret = parse_config(mhi_cntrl, config); |
| @@ -11,9 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | extern struct bus_type mhi_bus_type; |
| 13 | 13 | |
| 14 | −/* MHI MMIO register mapping */ | |
| 15 | −#define PCI_INVALID_READ(val) (val == U32_MAX) | |
| 16 | − | |
| 17 | 14 | #define MHIREGLEN (0x0) |
| 18 | 15 | #define MHIREGLEN_MHIREGLEN_MASK (0xFFFFFFFF) |
| 19 | 16 | #define MHIREGLEN_MHIREGLEN_SHIFT (0) |
| @@ -18,16 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | int __must_check mhi_read_reg(struct mhi_controller *mhi_cntrl, |
| 19 | 19 | void __iomem *base, u32 offset, u32 *out) |
| 20 | 20 | { |
| 21 | − u32 tmp = readl(base + offset); | |
| 22 | − | |
| 23 | − /* If there is any unexpected value, query the link status */ | |
| 24 | − if (PCI_INVALID_READ(tmp) && | |
| 25 | − mhi_cntrl->link_status(mhi_cntrl)) | |
| 26 | − return -EIO; | |
| 27 | − | |
| 28 | − *out = tmp; | |
| 29 | − | |
| 30 | − return 0; | |
| 21 | + return mhi_cntrl->read_reg(mhi_cntrl, base + offset, out); | |
| 31 | 22 | } |
| 32 | 23 | |
| 33 | 24 | int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl, |
| @@ -49,7 +40,7 @@ int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl, · 15 unmodified lines | ||
| 49 | 40 | void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base, |
| 50 | 41 | u32 offset, u32 val) |
| 51 | 42 | { |
| 52 | − writel(val, base + offset); | |
| 43 | + mhi_cntrl->write_reg(mhi_cntrl, base + offset, val); | |
| 53 | 44 | } |
| 54 | 45 | |
| 55 | 46 | void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, |
| @@ -294,7 +285,7 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) · 238 unmodified lines | ||
| 294 | 285 | !(mhi_chan->ee_mask & BIT(mhi_cntrl->ee))) |
| 295 | 286 | continue; |
| 296 | 287 | mhi_dev = mhi_alloc_device(mhi_cntrl); |
| 297 | − if (!mhi_dev) | |
| 288 | + if (IS_ERR(mhi_dev)) | |
| 298 | 289 | return; |
| 299 | 290 | |
| 300 | 291 | mhi_dev->dev_type = MHI_DEVICE_XFER; |
| @@ -336,7 +327,8 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) · 35 unmodified lines | ||
| 336 | 327 | |
| 337 | 328 | /* Channel name is same for both UL and DL */ |
| 338 | 329 | mhi_dev->chan_name = mhi_chan->name; |
| 339 | − dev_set_name(&mhi_dev->dev, "%04x_%s", mhi_chan->chan, | |
| 330 | + dev_set_name(&mhi_dev->dev, "%s_%s", | |
| 331 | + dev_name(mhi_cntrl->cntrl_dev), | |
| 340 | 332 | mhi_dev->chan_name); |
| 341 | 333 | |
| 342 | 334 | /* Init wakeup source if available */ |
| @@ -902,7 +902,11 @@ int mhi_sync_power_up(struct mhi_controller *mhi_cntrl) · 901 unmodified lines | ||
| 902 | 902 | MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), |
| 903 | 903 | msecs_to_jiffies(mhi_cntrl->timeout_ms)); |
| 904 | 904 | |
| 905 | − return (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) ? 0 : -EIO; | |
| 905 | + ret = (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) ? 0 : -ETIMEDOUT; | |
| 906 | + if (ret) | |
| 907 | + mhi_power_down(mhi_cntrl, false); | |
| 908 | + | |
| 909 | + return ret; | |
| 906 | 910 | } |
| 907 | 911 | EXPORT_SYMBOL(mhi_sync_power_up); |
| 908 | 912 | |
| @@ -1059,7 +1059,7 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, · 1058 unmodified lines | ||
| 1059 | 1059 | |
| 1060 | 1060 | update_turbo_state(); |
| 1061 | 1061 | if (global.turbo_disabled) { |
| 1062 | − pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); | |
| 1062 | + pr_notice_once("Turbo disabled by BIOS or unavailable on processor\n"); | |
| 1063 | 1063 | mutex_unlock(&intel_pstate_limits_lock); |
| 1064 | 1064 | mutex_unlock(&intel_pstate_driver_lock); |
| 1065 | 1065 | return -EPERM; |
| @@ -963,10 +963,12 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 962 unmodified lines | ||
| 963 | 963 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); |
| 964 | 964 | struct aead_edesc *edesc; |
| 965 | 965 | int ecode = 0; |
| 966 | + bool has_bklog; | |
| 966 | 967 | |
| 967 | 968 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 968 | 969 | |
| 969 | 970 | edesc = rctx->edesc; |
| 971 | + has_bklog = edesc->bklog; | |
| 970 | 972 | |
| 971 | 973 | if (err) |
| 972 | 974 | ecode = caam_jr_strstatus(jrdev, err); |
| @@ -979,7 +981,7 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 6 unmodified lines | ||
| 979 | 981 | * If no backlog flag, the completion of the request is done |
| 980 | 982 | * by CAAM, not crypto engine. |
| 981 | 983 | */ |
| 982 | − if (!edesc->bklog) | |
| 984 | + if (!has_bklog) | |
| 983 | 985 | aead_request_complete(req, ecode); |
| 984 | 986 | else |
| 985 | 987 | crypto_finalize_aead_request(jrp->engine, req, ecode); |
| @@ -995,10 +997,12 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 9 unmodified lines | ||
| 995 | 997 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); |
| 996 | 998 | int ivsize = crypto_skcipher_ivsize(skcipher); |
| 997 | 999 | int ecode = 0; |
| 1000 | + bool has_bklog; | |
| 998 | 1001 | |
| 999 | 1002 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 1000 | 1003 | |
| 1001 | 1004 | edesc = rctx->edesc; |
| 1005 | + has_bklog = edesc->bklog; | |
| 1002 | 1006 | if (err) |
| 1003 | 1007 | ecode = caam_jr_strstatus(jrdev, err); |
| 1004 | 1008 | |
| @@ -1028,7 +1032,7 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 23 unmodified lines | ||
| 1028 | 1032 | * If no backlog flag, the completion of the request is done |
| 1029 | 1033 | * by CAAM, not crypto engine. |
| 1030 | 1034 | */ |
| 1031 | − if (!edesc->bklog) | |
| 1035 | + if (!has_bklog) | |
| 1032 | 1036 | skcipher_request_complete(req, ecode); |
| 1033 | 1037 | else |
| 1034 | 1038 | crypto_finalize_skcipher_request(jrp->engine, req, ecode); |
| @@ -1711,7 +1715,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, · 676 unmodified lines | ||
| 1711 | 1715 | |
| 1712 | 1716 | if (ivsize || mapped_dst_nents > 1) |
| 1713 | 1717 | sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx + |
| 1714 | − mapped_dst_nents); | |
| 1718 | + mapped_dst_nents - 1 + !!ivsize); | |
| 1715 | 1719 | |
| 1716 | 1720 | if (sec4_sg_bytes) { |
| 1717 | 1721 | edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, |
| @@ -583,10 +583,12 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err, · 582 unmodified lines | ||
| 583 | 583 | struct caam_hash_state *state = ahash_request_ctx(req); |
| 584 | 584 | struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); |
| 585 | 585 | int ecode = 0; |
| 586 | + bool has_bklog; | |
| 586 | 587 | |
| 587 | 588 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 588 | 589 | |
| 589 | 590 | edesc = state->edesc; |
| 591 | + has_bklog = edesc->bklog; | |
| 590 | 592 | |
| 591 | 593 | if (err) |
| 592 | 594 | ecode = caam_jr_strstatus(jrdev, err); |
| @@ -603,7 +605,7 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err, · 10 unmodified lines | ||
| 603 | 605 | * If no backlog flag, the completion of the request is done |
| 604 | 606 | * by CAAM, not crypto engine. |
| 605 | 607 | */ |
| 606 | − if (!edesc->bklog) | |
| 608 | + if (!has_bklog) | |
| 607 | 609 | req->base.complete(&req->base, ecode); |
| 608 | 610 | else |
| 609 | 611 | crypto_finalize_hash_request(jrp->engine, req, ecode); |
| @@ -632,10 +634,12 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err, · 22 unmodified lines | ||
| 632 | 634 | struct caam_hash_state *state = ahash_request_ctx(req); |
| 633 | 635 | int digestsize = crypto_ahash_digestsize(ahash); |
| 634 | 636 | int ecode = 0; |
| 637 | + bool has_bklog; | |
| 635 | 638 | |
| 636 | 639 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 637 | 640 | |
| 638 | 641 | edesc = state->edesc; |
| 642 | + has_bklog = edesc->bklog; | |
| 639 | 643 | if (err) |
| 640 | 644 | ecode = caam_jr_strstatus(jrdev, err); |
| 641 | 645 | |
| @@ -663,7 +667,7 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err, · 21 unmodified lines | ||
| 663 | 667 | * If no backlog flag, the completion of the request is done |
| 664 | 668 | * by CAAM, not crypto engine. |
| 665 | 669 | */ |
| 666 | − if (!edesc->bklog) | |
| 670 | + if (!has_bklog) | |
| 667 | 671 | req->base.complete(&req->base, ecode); |
| 668 | 672 | else |
| 669 | 673 | crypto_finalize_hash_request(jrp->engine, req, ecode); |
| @@ -121,11 +121,13 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context) · 120 unmodified lines | ||
| 121 | 121 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); |
| 122 | 122 | struct rsa_edesc *edesc; |
| 123 | 123 | int ecode = 0; |
| 124 | + bool has_bklog; | |
| 124 | 125 | |
| 125 | 126 | if (err) |
| 126 | 127 | ecode = caam_jr_strstatus(dev, err); |
| 127 | 128 | |
| 128 | 129 | edesc = req_ctx->edesc; |
| 130 | + has_bklog = edesc->bklog; | |
| 129 | 131 | |
| 130 | 132 | rsa_pub_unmap(dev, edesc, req); |
| 131 | 133 | rsa_io_unmap(dev, edesc, req); |
| @@ -135,7 +137,7 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context) · 3 unmodified lines | ||
| 135 | 137 | * If no backlog flag, the completion of the request is done |
| 136 | 138 | * by CAAM, not crypto engine. |
| 137 | 139 | */ |
| 138 | − if (!edesc->bklog) | |
| 140 | + if (!has_bklog) | |
| 139 | 141 | akcipher_request_complete(req, ecode); |
| 140 | 142 | else |
| 141 | 143 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); |
| @@ -152,11 +154,13 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err, · 10 unmodified lines | ||
| 152 | 154 | struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); |
| 153 | 155 | struct rsa_edesc *edesc; |
| 154 | 156 | int ecode = 0; |
| 157 | + bool has_bklog; | |
| 155 | 158 | |
| 156 | 159 | if (err) |
| 157 | 160 | ecode = caam_jr_strstatus(dev, err); |
| 158 | 161 | |
| 159 | 162 | edesc = req_ctx->edesc; |
| 163 | + has_bklog = edesc->bklog; | |
| 160 | 164 | |
| 161 | 165 | switch (key->priv_form) { |
| 162 | 166 | case FORM1: |
| @@ -176,7 +180,7 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err, · 13 unmodified lines | ||
| 176 | 180 | * If no backlog flag, the completion of the request is done |
| 177 | 181 | * by CAAM, not crypto engine. |
| 178 | 182 | */ |
| 179 | − if (!edesc->bklog) | |
| 183 | + if (!has_bklog) | |
| 180 | 184 | akcipher_request_complete(req, ecode); |
| 181 | 185 | else |
| 182 | 186 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); |
| @@ -673,41 +673,14 @@ int chcr_ktls_cpl_set_tcb_rpl(struct adapter *adap, unsigned char *input) · 672 unmodified lines | ||
| 673 | 673 | return 0; |
| 674 | 674 | } |
| 675 | 675 | |
| 676 | −/* | |
| 677 | − * chcr_write_cpl_set_tcb_ulp: update tcb values. | |
| 678 | − * TCB is responsible to create tcp headers, so all the related values | |
| 679 | − * should be correctly updated. | |
| 680 | − * @tx_info - driver specific tls info. | |
| 681 | − * @q - tx queue on which packet is going out. | |
| 682 | − * @tid - TCB identifier. | |
| 683 | − * @pos - current index where should we start writing. | |
| 684 | − * @word - TCB word. | |
| 685 | − * @mask - TCB word related mask. | |
| 686 | − * @val - TCB word related value. | |
| 687 | − * @reply - set 1 if looking for TP response. | |
| 688 | − * return - next position to write. | |
| 689 | − */ | |
| 690 | −static void *chcr_write_cpl_set_tcb_ulp(struct chcr_ktls_info *tx_info, | |
| 691 | − struct sge_eth_txq *q, u32 tid, | |
| 692 | − void *pos, u16 word, u64 mask, | |
| 676 | +static void *__chcr_write_cpl_set_tcb_ulp(struct chcr_ktls_info *tx_info, | |
| 677 | + u32 tid, void *pos, u16 word, u64 mask, | |
| 693 | 678 | u64 val, u32 reply) |
| 694 | 679 | { |
| 695 | 680 | struct cpl_set_tcb_field_core *cpl; |
| 696 | 681 | struct ulptx_idata *idata; |
| 697 | 682 | struct ulp_txpkt *txpkt; |
| 698 | − void *save_pos = NULL; | |
| 699 | − u8 buf[48] = {0}; | |
| 700 | − int left; | |
| 701 | 683 | |
| 702 | − left = (void *)q->q.stat - pos; | |
| 703 | − if (unlikely(left < CHCR_SET_TCB_FIELD_LEN)) { | |
| 704 | − if (!left) { | |
| 705 | − pos = q->q.desc; | |
| 706 | − } else { | |
| 707 | − save_pos = pos; | |
| 708 | − pos = buf; | |
| 709 | − } | |
| 710 | − } | |
| 711 | 684 | /* ULP_TXPKT */ |
| 712 | 685 | txpkt = pos; |
| 713 | 686 | txpkt->cmd_dest = htonl(ULPTX_CMD_V(ULP_TX_PKT) | ULP_TXPKT_DEST_V(0)); |
| @@ -732,18 +705,54 @@ static void *chcr_write_cpl_set_tcb_ulp(struct chcr_ktls_info *tx_info, · 18 unmodified lines | ||
| 732 | 705 | idata = (struct ulptx_idata *)(cpl + 1); |
| 733 | 706 | idata->cmd_more = htonl(ULPTX_CMD_V(ULP_TX_SC_NOOP)); |
| 734 | 707 | idata->len = htonl(0); |
| 708 | + pos = idata + 1; | |
| 735 | 709 | |
| 736 | − if (save_pos) { | |
| 737 | − pos = chcr_copy_to_txd(buf, &q->q, save_pos, | |
| 738 | − CHCR_SET_TCB_FIELD_LEN); | |
| 739 | − } else { | |
| 740 | − /* check again if we are at the end of the queue */ | |
| 741 | − if (left == CHCR_SET_TCB_FIELD_LEN) | |
| 710 | + return pos; | |
| 711 | +} | |
| 712 | + | |
| 713 | + | |
| 714 | +/* | |
| 715 | + * chcr_write_cpl_set_tcb_ulp: update tcb values. | |
| 716 | + * TCB is responsible to create tcp headers, so all the related values | |
| 717 | + * should be correctly updated. | |
| 718 | + * @tx_info - driver specific tls info. | |
| 719 | + * @q - tx queue on which packet is going out. | |
| 720 | + * @tid - TCB identifier. | |
| 721 | + * @pos - current index where should we start writing. | |
| 722 | + * @word - TCB word. | |
| 723 | + * @mask - TCB word related mask. | |
| 724 | + * @val - TCB word related value. | |
| 725 | + * @reply - set 1 if looking for TP response. | |
| 726 | + * return - next position to write. | |
| 727 | + */ | |
| 728 | +static void *chcr_write_cpl_set_tcb_ulp(struct chcr_ktls_info *tx_info, | |
| 729 | + struct sge_eth_txq *q, u32 tid, | |
| 730 | + void *pos, u16 word, u64 mask, | |
| 731 | + u64 val, u32 reply) | |
| 732 | +{ | |
| 733 | + int left = (void *)q->q.stat - pos; | |
| 734 | + | |
| 735 | + if (unlikely(left < CHCR_SET_TCB_FIELD_LEN)) { | |
| 736 | + if (!left) { | |
| 742 | 737 | pos = q->q.desc; |
| 743 | − else | |
| 744 | − pos = idata + 1; | |
| 738 | + } else { | |
| 739 | + u8 buf[48] = {0}; | |
| 740 | + | |
| 741 | + __chcr_write_cpl_set_tcb_ulp(tx_info, tid, buf, word, | |
| 742 | + mask, val, reply); | |
| 743 | + | |
| 744 | + return chcr_copy_to_txd(buf, &q->q, pos, | |
| 745 | + CHCR_SET_TCB_FIELD_LEN); | |
| 746 | + } | |
| 745 | 747 | } |
| 746 | 748 | |
| 749 | + pos = __chcr_write_cpl_set_tcb_ulp(tx_info, tid, pos, word, | |
| 750 | + mask, val, reply); | |
| 751 | + | |
| 752 | + /* check again if we are at the end of the queue */ | |
| 753 | + if (left == CHCR_SET_TCB_FIELD_LEN) | |
| 754 | + pos = q->q.desc; | |
| 755 | + | |
| 747 | 756 | return pos; |
| 748 | 757 | } |
| 749 | 758 | |
| @@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *file, · 387 unmodified lines | ||
| 388 | 388 | |
| 389 | 389 | return ret; |
| 390 | 390 | |
| 391 | − case DMA_BUF_SET_NAME: | |
| 391 | + case DMA_BUF_SET_NAME_A: | |
| 392 | + case DMA_BUF_SET_NAME_B: | |
| 392 | 393 | return dma_buf_set_name(dmabuf, (const char __user *)arg); |
| 393 | 394 | |
| 394 | 395 | default: |
| @@ -655,8 +656,8 @@ EXPORT_SYMBOL_GPL(dma_buf_put); · 260 unmodified lines | ||
| 655 | 656 | * calls attach() of dma_buf_ops to allow device-specific attach functionality |
| 656 | 657 | * @dmabuf: [in] buffer to attach device to. |
| 657 | 658 | * @dev: [in] device to be attached. |
| 658 | − * @importer_ops [in] importer operations for the attachment | |
| 659 | − * @importer_priv [in] importer private pointer for the attachment | |
| 659 | + * @importer_ops: [in] importer operations for the attachment | |
| 660 | + * @importer_priv: [in] importer private pointer for the attachment | |
| 660 | 661 | * |
| 661 | 662 | * Returns struct dma_buf_attachment pointer for this attachment. Attachments |
| 662 | 663 | * must be cleaned up by calling dma_buf_detach(). |
| @@ -241,7 +241,8 @@ config FSL_RAID · 240 unmodified lines | ||
| 241 | 241 | |
| 242 | 242 | config HISI_DMA |
| 243 | 243 | tristate "HiSilicon DMA Engine support" |
| 244 | − depends on ARM64 || (COMPILE_TEST && PCI_MSI) | |
| 244 | + depends on ARM64 || COMPILE_TEST | |
| 245 | + depends on PCI_MSI | |
| 245 | 246 | select DMA_ENGINE |
| 246 | 247 | select DMA_VIRTUAL_CHANNELS |
| 247 | 248 | help |
| @@ -232,10 +232,6 @@ static void chan_dev_release(struct device *dev) · 231 unmodified lines | ||
| 232 | 232 | struct dma_chan_dev *chan_dev; |
| 233 | 233 | |
| 234 | 234 | chan_dev = container_of(dev, typeof(*chan_dev), device); |
| 235 | − if (atomic_dec_and_test(chan_dev->idr_ref)) { | |
| 236 | − ida_free(&dma_ida, chan_dev->dev_id); | |
| 237 | − kfree(chan_dev->idr_ref); | |
| 238 | − } | |
| 239 | 235 | kfree(chan_dev); |
| 240 | 236 | } |
| 241 | 237 | |
| @@ -1043,27 +1039,9 @@ static int get_dma_id(struct dma_device *device) · 801 unmodified lines | ||
| 1043 | 1039 | } |
| 1044 | 1040 | |
| 1045 | 1041 | static int __dma_async_device_channel_register(struct dma_device *device, |
| 1046 | − struct dma_chan *chan, | |
| 1047 | − int chan_id) | |
| 1042 | + struct dma_chan *chan) | |
| 1048 | 1043 | { |
| 1049 | 1044 | int rc = 0; |
| 1050 | − int chancnt = device->chancnt; | |
| 1051 | − atomic_t *idr_ref; | |
| 1052 | − struct dma_chan *tchan; | |
| 1053 | − | |
| 1054 | − tchan = list_first_entry_or_null(&device->channels, | |
| 1055 | − struct dma_chan, device_node); | |
| 1056 | − if (!tchan) | |
| 1057 | − return -ENODEV; | |
| 1058 | − | |
| 1059 | − if (tchan->dev) { | |
| 1060 | − idr_ref = tchan->dev->idr_ref; | |
| 1061 | − } else { | |
| 1062 | − idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL); | |
| 1063 | − if (!idr_ref) | |
| 1064 | − return -ENOMEM; | |
| 1065 | − atomic_set(idr_ref, 0); | |
| 1066 | − } | |
| 1067 | 1045 | |
| 1068 | 1046 | chan->local = alloc_percpu(typeof(*chan->local)); |
| 1069 | 1047 | if (!chan->local) |
| @@ -1079,29 +1057,36 @@ static int __dma_async_device_channel_register(struct dma_device *device, · 9 unmodified lines | ||
| 1079 | 1057 | * When the chan_id is a negative value, we are dynamically adding |
| 1080 | 1058 | * the channel. Otherwise we are static enumerating. |
| 1081 | 1059 | */ |
| 1082 | − chan->chan_id = chan_id < 0 ? chancnt : chan_id; | |
| 1060 | + mutex_lock(&device->chan_mutex); | |
| 1061 | + chan->chan_id = ida_alloc(&device->chan_ida, GFP_KERNEL); | |
| 1062 | + mutex_unlock(&device->chan_mutex); | |
| 1063 | + if (chan->chan_id < 0) { | |
| 1064 | + pr_err("%s: unable to alloc ida for chan: %d\n", | |
| 1065 | + __func__, chan->chan_id); | |
| 1066 | + goto err_out; | |
| 1067 | + } | |
| 1068 | + | |
| 1083 | 1069 | chan->dev->device.class = &dma_devclass; |
| 1084 | 1070 | chan->dev->device.parent = device->dev; |
| 1085 | 1071 | chan->dev->chan = chan; |
| 1086 | − chan->dev->idr_ref = idr_ref; | |
| 1087 | 1072 | chan->dev->dev_id = device->dev_id; |
| 1088 | − atomic_inc(idr_ref); | |
| 1089 | 1073 | dev_set_name(&chan->dev->device, "dma%dchan%d", |
| 1090 | 1074 | device->dev_id, chan->chan_id); |
| 1091 | − | |
| 1092 | 1075 | rc = device_register(&chan->dev->device); |
| 1093 | 1076 | if (rc) |
| 1094 | − goto err_out; | |
| 1077 | + goto err_out_ida; | |
| 1095 | 1078 | chan->client_count = 0; |
| 1096 | − device->chancnt = chan->chan_id + 1; | |
| 1079 | + device->chancnt++; | |
| 1097 | 1080 | |
| 1098 | 1081 | return 0; |
| 1099 | 1082 | |
| 1083 | + err_out_ida: | |
| 1084 | + mutex_lock(&device->chan_mutex); | |
| 1085 | + ida_free(&device->chan_ida, chan->chan_id); | |
| 1086 | + mutex_unlock(&device->chan_mutex); | |
| 1100 | 1087 | err_out: |
| 1101 | 1088 | free_percpu(chan->local); |
| 1102 | 1089 | kfree(chan->dev); |
| 1103 | − if (atomic_dec_return(idr_ref) == 0) | |
| 1104 | − kfree(idr_ref); | |
| 1105 | 1090 | return rc; |
| 1106 | 1091 | } |
| 1107 | 1092 | |
| @@ -1110,7 +1095,7 @@ int dma_async_device_channel_register(struct dma_device *device, · 2 unmodified lines | ||
| 1110 | 1095 | { |
| 1111 | 1096 | int rc; |
| 1112 | 1097 | |
| 1113 | − rc = __dma_async_device_channel_register(device, chan, -1); | |
| 1098 | + rc = __dma_async_device_channel_register(device, chan); | |
| 1114 | 1099 | if (rc < 0) |
| 1115 | 1100 | return rc; |
| 1116 | 1101 | |
| @@ -1130,6 +1115,9 @@ static void __dma_async_device_channel_unregister(struct dma_device *device, · 13 unmodified lines | ||
| 1130 | 1115 | device->chancnt--; |
| 1131 | 1116 | chan->dev->chan = NULL; |
| 1132 | 1117 | mutex_unlock(&dma_list_mutex); |
| 1118 | + mutex_lock(&device->chan_mutex); | |
| 1119 | + ida_free(&device->chan_ida, chan->chan_id); | |
| 1120 | + mutex_unlock(&device->chan_mutex); | |
| 1133 | 1121 | device_unregister(&chan->dev->device); |
| 1134 | 1122 | free_percpu(chan->local); |
| 1135 | 1123 | } |
| @@ -1152,7 +1140,7 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_unregister); · 16 unmodified lines | ||
| 1152 | 1140 | */ |
| 1153 | 1141 | int dma_async_device_register(struct dma_device *device) |
| 1154 | 1142 | { |
| 1155 | − int rc, i = 0; | |
| 1143 | + int rc; | |
| 1156 | 1144 | struct dma_chan* chan; |
| 1157 | 1145 | |
| 1158 | 1146 | if (!device) |
| @@ -1257,9 +1245,12 @@ int dma_async_device_register(struct dma_device *device) · 98 unmodified lines | ||
| 1257 | 1245 | if (rc != 0) |
| 1258 | 1246 | return rc; |
| 1259 | 1247 | |
| 1248 | + mutex_init(&device->chan_mutex); | |
| 1249 | + ida_init(&device->chan_ida); | |
| 1250 | + | |
| 1260 | 1251 | /* represent channels in sysfs. Probably want devs too */ |
| 1261 | 1252 | list_for_each_entry(chan, &device->channels, device_node) { |
| 1262 | − rc = __dma_async_device_channel_register(device, chan, i++); | |
| 1253 | + rc = __dma_async_device_channel_register(device, chan); | |
| 1263 | 1254 | if (rc < 0) |
| 1264 | 1255 | goto err_out; |
| 1265 | 1256 | } |
| @@ -1334,6 +1325,7 @@ void dma_async_device_unregister(struct dma_device *device) · 68 unmodified lines | ||
| 1334 | 1325 | */ |
| 1335 | 1326 | dma_cap_set(DMA_PRIVATE, device->cap_mask); |
| 1336 | 1327 | dma_channel_rebalance(); |
| 1328 | + ida_free(&dma_ida, device->dev_id); | |
| 1337 | 1329 | dma_device_put(device); |
| 1338 | 1330 | mutex_unlock(&dma_list_mutex); |
| 1339 | 1331 | } |
| @@ -240,7 +240,7 @@ static bool is_threaded_test_run(struct dmatest_info *info) · 239 unmodified lines | ||
| 240 | 240 | struct dmatest_thread *thread; |
| 241 | 241 | |
| 242 | 242 | list_for_each_entry(thread, &dtc->threads, node) { |
| 243 | − if (!thread->done) | |
| 243 | + if (!thread->done && !thread->pending) | |
| 244 | 244 | return true; |
| 245 | 245 | } |
| 246 | 246 | } |
| @@ -662,8 +662,8 @@ static int dmatest_func(void *data) · 415 unmodified lines | ||
| 662 | 662 | flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; |
| 663 | 663 | |
| 664 | 664 | ktime = ktime_get(); |
| 665 | − while (!kthread_should_stop() | |
| 666 | − && !(params->iterations && total_tests >= params->iterations)) { | |
| 665 | + while (!(kthread_should_stop() || | |
| 666 | + (params->iterations && total_tests >= params->iterations))) { | |
| 667 | 667 | struct dma_async_tx_descriptor *tx = NULL; |
| 668 | 668 | struct dmaengine_unmap_data *um; |
| 669 | 669 | dma_addr_t *dsts; |
| @@ -363,6 +363,8 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) · 362 unmodified lines | ||
| 363 | 363 | gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, |
| 364 | 364 | size); |
| 365 | 365 | tdmac->desc_arr = NULL; |
| 366 | + if (tdmac->status == DMA_ERROR) | |
| 367 | + tdmac->status = DMA_COMPLETE; | |
| 366 | 368 | |
| 367 | 369 | return; |
| 368 | 370 | } |
| @@ -443,7 +445,8 @@ static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic( · 74 unmodified lines | ||
| 443 | 445 | if (!desc) |
| 444 | 446 | goto err_out; |
| 445 | 447 | |
| 446 | − mmp_tdma_config_write(chan, direction, &tdmac->slave_config); | |
| 448 | + if (mmp_tdma_config_write(chan, direction, &tdmac->slave_config)) | |
| 449 | + goto err_out; | |
| 447 | 450 | |
| 448 | 451 | while (buf < buf_len) { |
| 449 | 452 | desc = &tdmac->desc_arr[i]; |
| @@ -865,6 +865,7 @@ static int pch_dma_probe(struct pci_dev *pdev, · 864 unmodified lines | ||
| 865 | 865 | } |
| 866 | 866 | |
| 867 | 867 | pci_set_master(pdev); |
| 868 | + pd->dma.dev = &pdev->dev; | |
| 868 | 869 | |
| 869 | 870 | err = request_irq(pdev->irq, pd_irq, IRQF_SHARED, DRV_NAME, pd); |
| 870 | 871 | if (err) { |
| @@ -880,7 +881,6 @@ static int pch_dma_probe(struct pci_dev *pdev, · 9 unmodified lines | ||
| 880 | 881 | goto err_free_irq; |
| 881 | 882 | } |
| 882 | 883 | |
| 883 | − pd->dma.dev = &pdev->dev; | |
| 884 | 884 | |
| 885 | 885 | INIT_LIST_HEAD(&pd->dma.channels); |
| 886 | 886 | |
| @@ -816,6 +816,13 @@ static bool tegra_dma_eoc_interrupt_deasserted(struct tegra_dma_channel *tdc) · 815 unmodified lines | ||
| 816 | 816 | static void tegra_dma_synchronize(struct dma_chan *dc) |
| 817 | 817 | { |
| 818 | 818 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
| 819 | + int err; | |
| 820 | + | |
| 821 | + err = pm_runtime_get_sync(tdc->tdma->dev); | |
| 822 | + if (err < 0) { | |
| 823 | + dev_err(tdc2dev(tdc), "Failed to synchronize DMA: %d\n", err); | |
| 824 | + return; | |
| 825 | + } | |
| 819 | 826 | |
| 820 | 827 | /* |
| 821 | 828 | * CPU, which handles interrupt, could be busy in |
| @@ -825,6 +832,8 @@ static void tegra_dma_synchronize(struct dma_chan *dc) · 3 unmodified lines | ||
| 825 | 832 | wait_event(tdc->wq, tegra_dma_eoc_interrupt_deasserted(tdc)); |
| 826 | 833 | |
| 827 | 834 | tasklet_kill(&tdc->tasklet); |
| 835 | + | |
| 836 | + pm_runtime_put(tdc->tdma->dev); | |
| 828 | 837 | } |
| 829 | 838 | |
| 830 | 839 | static unsigned int tegra_dma_sg_bytes_xferred(struct tegra_dma_channel *tdc, |
| @@ -27,6 +27,7 @@ struct psil_endpoint_config *psil_get_ep_config(u32 thread_id) · 26 unmodified lines | ||
| 27 | 27 | soc_ep_map = &j721e_ep_map; |
| 28 | 28 | } else { |
| 29 | 29 | pr_err("PSIL: No compatible machine found for map\n"); |
| 30 | + mutex_unlock(&ep_map_mutex); | |
| 30 | 31 | return ERR_PTR(-ENOTSUPP); |
| 31 | 32 | } |
| 32 | 33 | pr_debug("%s: Using map for %s\n", __func__, soc_ep_map->name); |
| @@ -1230,16 +1230,16 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan, · 1229 unmodified lines | ||
| 1230 | 1230 | return ret; |
| 1231 | 1231 | |
| 1232 | 1232 | spin_lock_irqsave(&chan->lock, flags); |
| 1233 | − | |
| 1234 | − desc = list_last_entry(&chan->active_list, | |
| 1235 | − struct xilinx_dma_tx_descriptor, node); | |
| 1236 | − /* | |
| 1237 | − * VDMA and simple mode do not support residue reporting, so the | |
| 1238 | − * residue field will always be 0. | |
| 1239 | − */ | |
| 1240 | − if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) | |
| 1241 | − residue = xilinx_dma_get_residue(chan, desc); | |
| 1242 | − | |
| 1233 | + if (!list_empty(&chan->active_list)) { | |
| 1234 | + desc = list_last_entry(&chan->active_list, | |
| 1235 | + struct xilinx_dma_tx_descriptor, node); | |
| 1236 | + /* | |
| 1237 | + * VDMA and simple mode do not support residue reporting, so the | |
| 1238 | + * residue field will always be 0. | |
| 1239 | + */ | |
| 1240 | + if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) | |
| 1241 | + residue = xilinx_dma_get_residue(chan, desc); | |
| 1242 | + } | |
| 1243 | 1243 | spin_unlock_irqrestore(&chan->lock, flags); |
| 1244 | 1244 | |
| 1245 | 1245 | dma_set_residue(txstate, residue); |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | int efi_tpm_final_log_size; |
| 17 | 17 | EXPORT_SYMBOL(efi_tpm_final_log_size); |
| 18 | 18 | |
| 19 | −static int tpm2_calc_event_log_size(void *data, int count, void *size_info) | |
| 19 | +static int __init tpm2_calc_event_log_size(void *data, int count, void *size_info) | |
| 20 | 20 | { |
| 21 | 21 | struct tcg_pcr_event2_head *header; |
| 22 | 22 | int event_size, size = 0; |
| @@ -3372,15 +3372,12 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) · 3371 unmodified lines | ||
| 3372 | 3372 | } |
| 3373 | 3373 | } |
| 3374 | 3374 | |
| 3375 | − amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); | |
| 3376 | − amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); | |
| 3377 | − | |
| 3378 | − amdgpu_amdkfd_suspend(adev, !fbcon); | |
| 3379 | − | |
| 3380 | 3375 | amdgpu_ras_suspend(adev); |
| 3381 | 3376 | |
| 3382 | 3377 | r = amdgpu_device_ip_suspend_phase1(adev); |
| 3383 | 3378 | |
| 3379 | + amdgpu_amdkfd_suspend(adev, !fbcon); | |
| 3380 | + | |
| 3384 | 3381 | /* evict vram memory */ |
| 3385 | 3382 | amdgpu_bo_evict_vram(adev); |
| 3386 | 3383 | |
| @@ -85,9 +85,10 @@ · 84 unmodified lines | ||
| 85 | 85 | * - 3.34.0 - Non-DC can flip correctly between buffers with different pitches |
| 86 | 86 | * - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask |
| 87 | 87 | * - 3.36.0 - Allow reading more status registers on si/cik |
| 88 | + * - 3.37.0 - L2 is invalidated before SDMA IBs, needed for correctness | |
| 88 | 89 | */ |
| 89 | 90 | #define KMS_DRIVER_MAJOR 3 |
| 90 | −#define KMS_DRIVER_MINOR 36 | |
| 91 | +#define KMS_DRIVER_MINOR 37 | |
| 91 | 92 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 92 | 93 | |
| 93 | 94 | int amdgpu_vram_limit = 0; |
| @@ -73,6 +73,22 @@ · 72 unmodified lines | ||
| 73 | 73 | #define SDMA_OP_AQL_COPY 0 |
| 74 | 74 | #define SDMA_OP_AQL_BARRIER_OR 0 |
| 75 | 75 | |
| 76 | +#define SDMA_GCR_RANGE_IS_PA (1 << 18) | |
| 77 | +#define SDMA_GCR_SEQ(x) (((x) & 0x3) << 16) | |
| 78 | +#define SDMA_GCR_GL2_WB (1 << 15) | |
| 79 | +#define SDMA_GCR_GL2_INV (1 << 14) | |
| 80 | +#define SDMA_GCR_GL2_DISCARD (1 << 13) | |
| 81 | +#define SDMA_GCR_GL2_RANGE(x) (((x) & 0x3) << 11) | |
| 82 | +#define SDMA_GCR_GL2_US (1 << 10) | |
| 83 | +#define SDMA_GCR_GL1_INV (1 << 9) | |
| 84 | +#define SDMA_GCR_GLV_INV (1 << 8) | |
| 85 | +#define SDMA_GCR_GLK_INV (1 << 7) | |
| 86 | +#define SDMA_GCR_GLK_WB (1 << 6) | |
| 87 | +#define SDMA_GCR_GLM_INV (1 << 5) | |
| 88 | +#define SDMA_GCR_GLM_WB (1 << 4) | |
| 89 | +#define SDMA_GCR_GL1_RANGE(x) (((x) & 0x3) << 2) | |
| 90 | +#define SDMA_GCR_GLI_INV(x) (((x) & 0x3) << 0) | |
| 91 | + | |
| 76 | 92 | /*define for op field*/ |
| 77 | 93 | #define SDMA_PKT_HEADER_op_offset 0 |
| 78 | 94 | #define SDMA_PKT_HEADER_op_mask 0x000000FF |
| @@ -382,6 +382,18 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring, · 381 unmodified lines | ||
| 382 | 382 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); |
| 383 | 383 | uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid); |
| 384 | 384 | |
| 385 | + /* Invalidate L2, because if we don't do it, we might get stale cache | |
| 386 | + * lines from previous IBs. | |
| 387 | + */ | |
| 388 | + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ)); | |
| 389 | + amdgpu_ring_write(ring, 0); | |
| 390 | + amdgpu_ring_write(ring, (SDMA_GCR_GL2_INV | | |
| 391 | + SDMA_GCR_GL2_WB | | |
| 392 | + SDMA_GCR_GLM_INV | | |
| 393 | + SDMA_GCR_GLM_WB) << 16); | |
| 394 | + amdgpu_ring_write(ring, 0xffffff80); | |
| 395 | + amdgpu_ring_write(ring, 0xffff); | |
| 396 | + | |
| 385 | 397 | /* An IB packet must end on a 8 DW boundary--the next dword |
| 386 | 398 | * must be on a 8-dword boundary. Our IB packet below is 6 |
| 387 | 399 | * dwords long, thus add x number of NOPs, such that, in |
| @@ -1595,7 +1607,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = { · 1207 unmodified lines | ||
| 1595 | 1607 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + |
| 1596 | 1608 | SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 + |
| 1597 | 1609 | 10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */ |
| 1598 | − .emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */ | |
| 1610 | + .emit_ib_size = 5 + 7 + 6, /* sdma_v5_0_ring_emit_ib */ | |
| 1599 | 1611 | .emit_ib = sdma_v5_0_ring_emit_ib, |
| 1600 | 1612 | .emit_fence = sdma_v5_0_ring_emit_fence, |
| 1601 | 1613 | .emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync, |
| @@ -2008,17 +2008,22 @@ void amdgpu_dm_update_connector_after_detect( · 2007 unmodified lines | ||
| 2008 | 2008 | dc_sink_retain(aconnector->dc_sink); |
| 2009 | 2009 | if (sink->dc_edid.length == 0) { |
| 2010 | 2010 | aconnector->edid = NULL; |
| 2011 | − drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux); | |
| 2011 | + if (aconnector->dc_link->aux_mode) { | |
| 2012 | + drm_dp_cec_unset_edid( | |
| 2013 | + &aconnector->dm_dp_aux.aux); | |
| 2014 | + } | |
| 2012 | 2015 | } else { |
| 2013 | 2016 | aconnector->edid = |
| 2014 | − (struct edid *) sink->dc_edid.raw_edid; | |
| 2015 | − | |
| 2017 | + (struct edid *)sink->dc_edid.raw_edid; | |
| 2016 | 2018 | |
| 2017 | 2019 | drm_connector_update_edid_property(connector, |
| 2018 | − aconnector->edid); | |
| 2019 | − drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, | |
| 2020 | − aconnector->edid); | |
| 2020 | + aconnector->edid); | |
| 2021 | + | |
| 2022 | + if (aconnector->dc_link->aux_mode) | |
| 2023 | + drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, | |
| 2024 | + aconnector->edid); | |
| 2021 | 2025 | } |
| 2026 | + | |
| 2022 | 2027 | amdgpu_dm_update_freesync_caps(connector, aconnector->edid); |
| 2023 | 2028 | update_connector_ext_caps(aconnector); |
| 2024 | 2029 | } else { |
| @@ -3340,7 +3345,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 1315 unmodified lines | ||
| 3340 | 3345 | const union dc_tiling_info *tiling_info, |
| 3341 | 3346 | const uint64_t info, |
| 3342 | 3347 | struct dc_plane_dcc_param *dcc, |
| 3343 | − struct dc_plane_address *address) | |
| 3348 | + struct dc_plane_address *address, | |
| 3349 | + bool force_disable_dcc) | |
| 3344 | 3350 | { |
| 3345 | 3351 | struct dc *dc = adev->dm.dc; |
| 3346 | 3352 | struct dc_dcc_surface_param input; |
| @@ -3352,6 +3358,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 5 unmodified lines | ||
| 3352 | 3358 | memset(&input, 0, sizeof(input)); |
| 3353 | 3359 | memset(&output, 0, sizeof(output)); |
| 3354 | 3360 | |
| 3361 | + if (force_disable_dcc) | |
| 3362 | + return 0; | |
| 3363 | + | |
| 3355 | 3364 | if (!offset) |
| 3356 | 3365 | return 0; |
| 3357 | 3366 | |
| @@ -3401,7 +3410,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 43 unmodified lines | ||
| 3401 | 3410 | union dc_tiling_info *tiling_info, |
| 3402 | 3411 | struct plane_size *plane_size, |
| 3403 | 3412 | struct dc_plane_dcc_param *dcc, |
| 3404 | − struct dc_plane_address *address) | |
| 3413 | + struct dc_plane_address *address, | |
| 3414 | + bool force_disable_dcc) | |
| 3405 | 3415 | { |
| 3406 | 3416 | const struct drm_framebuffer *fb = &afb->base; |
| 3407 | 3417 | int ret; |
| @@ -3507,7 +3517,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 99 unmodified lines | ||
| 3507 | 3517 | |
| 3508 | 3518 | ret = fill_plane_dcc_attributes(adev, afb, format, rotation, |
| 3509 | 3519 | plane_size, tiling_info, |
| 3510 | − tiling_flags, dcc, address); | |
| 3520 | + tiling_flags, dcc, address, | |
| 3521 | + force_disable_dcc); | |
| 3511 | 3522 | if (ret) |
| 3512 | 3523 | return ret; |
| 3513 | 3524 | } |
| @@ -3599,7 +3610,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, · 85 unmodified lines | ||
| 3599 | 3610 | const struct drm_plane_state *plane_state, |
| 3600 | 3611 | const uint64_t tiling_flags, |
| 3601 | 3612 | struct dc_plane_info *plane_info, |
| 3602 | − struct dc_plane_address *address) | |
| 3613 | + struct dc_plane_address *address, | |
| 3614 | + bool force_disable_dcc) | |
| 3603 | 3615 | { |
| 3604 | 3616 | const struct drm_framebuffer *fb = plane_state->fb; |
| 3605 | 3617 | const struct amdgpu_framebuffer *afb = |
| @@ -3681,7 +3693,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, · 75 unmodified lines | ||
| 3681 | 3693 | plane_info->rotation, tiling_flags, |
| 3682 | 3694 | &plane_info->tiling_info, |
| 3683 | 3695 | &plane_info->plane_size, |
| 3684 | − &plane_info->dcc, address); | |
| 3696 | + &plane_info->dcc, address, | |
| 3697 | + force_disable_dcc); | |
| 3685 | 3698 | if (ret) |
| 3686 | 3699 | return ret; |
| 3687 | 3700 | |
| @@ -3704,6 +3717,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 16 unmodified lines | ||
| 3704 | 3717 | struct dc_plane_info plane_info; |
| 3705 | 3718 | uint64_t tiling_flags; |
| 3706 | 3719 | int ret; |
| 3720 | + bool force_disable_dcc = false; | |
| 3707 | 3721 | |
| 3708 | 3722 | ret = fill_dc_scaling_info(plane_state, &scaling_info); |
| 3709 | 3723 | if (ret) |
| @@ -3718,9 +3732,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 8 unmodified lines | ||
| 3718 | 3732 | if (ret) |
| 3719 | 3733 | return ret; |
| 3720 | 3734 | |
| 3735 | + force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; | |
| 3721 | 3736 | ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, |
| 3722 | 3737 | &plane_info, |
| 3723 | − &dc_plane_state->address); | |
| 3738 | + &dc_plane_state->address, | |
| 3739 | + force_disable_dcc); | |
| 3724 | 3740 | if (ret) |
| 3725 | 3741 | return ret; |
| 3726 | 3742 | |
| @@ -5342,6 +5358,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 1615 unmodified lines | ||
| 5342 | 5358 | uint64_t tiling_flags; |
| 5343 | 5359 | uint32_t domain; |
| 5344 | 5360 | int r; |
| 5361 | + bool force_disable_dcc = false; | |
| 5345 | 5362 | |
| 5346 | 5363 | dm_plane_state_old = to_dm_plane_state(plane->state); |
| 5347 | 5364 | dm_plane_state_new = to_dm_plane_state(new_state); |
| @@ -5400,11 +5417,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 52 unmodified lines | ||
| 5400 | 5417 | dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { |
| 5401 | 5418 | struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; |
| 5402 | 5419 | |
| 5420 | + force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; | |
| 5403 | 5421 | fill_plane_buffer_attributes( |
| 5404 | 5422 | adev, afb, plane_state->format, plane_state->rotation, |
| 5405 | 5423 | tiling_flags, &plane_state->tiling_info, |
| 5406 | 5424 | &plane_state->plane_size, &plane_state->dcc, |
| 5407 | − &plane_state->address); | |
| 5425 | + &plane_state->address, | |
| 5426 | + force_disable_dcc); | |
| 5408 | 5427 | } |
| 5409 | 5428 | |
| 5410 | 5429 | return 0; |
| @@ -6676,7 +6695,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 1265 unmodified lines | ||
| 6676 | 6695 | fill_dc_plane_info_and_addr( |
| 6677 | 6696 | dm->adev, new_plane_state, tiling_flags, |
| 6678 | 6697 | &bundle->plane_infos[planes_count], |
| 6679 | − &bundle->flip_addrs[planes_count].address); | |
| 6698 | + &bundle->flip_addrs[planes_count].address, | |
| 6699 | + false); | |
| 6700 | + | |
| 6701 | + DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", | |
| 6702 | + new_plane_state->plane->index, | |
| 6703 | + bundle->plane_infos[planes_count].dcc.enable); | |
| 6680 | 6704 | |
| 6681 | 6705 | bundle->surface_updates[planes_count].plane_info = |
| 6682 | 6706 | &bundle->plane_infos[planes_count]; |
| @@ -8096,7 +8120,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, · 1413 unmodified lines | ||
| 8096 | 8120 | ret = fill_dc_plane_info_and_addr( |
| 8097 | 8121 | dm->adev, new_plane_state, tiling_flags, |
| 8098 | 8122 | plane_info, |
| 8099 | − &flip_addr->address); | |
| 8123 | + &flip_addr->address, | |
| 8124 | + false); | |
| 8100 | 8125 | if (ret) |
| 8101 | 8126 | goto cleanup; |
| 8102 | 8127 | |
| @@ -834,11 +834,10 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) · 833 unmodified lines | ||
| 834 | 834 | static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context) |
| 835 | 835 | { |
| 836 | 836 | int i; |
| 837 | − int count = 0; | |
| 838 | − struct pipe_ctx *pipe; | |
| 839 | 837 | PERF_TRACE(); |
| 840 | 838 | for (i = 0; i < MAX_PIPES; i++) { |
| 841 | − pipe = &context->res_ctx.pipe_ctx[i]; | |
| 839 | + int count = 0; | |
| 840 | + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; | |
| 842 | 841 | |
| 843 | 842 | if (!pipe->plane_state) |
| 844 | 843 | continue; |
| @@ -2908,6 +2908,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd · 2907 unmodified lines | ||
| 2908 | 2908 | sizeof(hpd_irq_dpcd_data), |
| 2909 | 2909 | "Status: "); |
| 2910 | 2910 | |
| 2911 | + for (i = 0; i < MAX_PIPES; i++) { | |
| 2912 | + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2913 | + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) | |
| 2914 | + link->dc->hwss.blank_stream(pipe_ctx); | |
| 2915 | + } | |
| 2916 | + | |
| 2911 | 2917 | for (i = 0; i < MAX_PIPES; i++) { |
| 2912 | 2918 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2913 | 2919 | if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) |
| @@ -2927,6 +2933,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd · 13 unmodified lines | ||
| 2927 | 2933 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) |
| 2928 | 2934 | dc_link_reallocate_mst_payload(link); |
| 2929 | 2935 | |
| 2936 | + for (i = 0; i < MAX_PIPES; i++) { | |
| 2937 | + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; | |
| 2938 | + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) | |
| 2939 | + link->dc->hwss.unblank_stream(pipe_ctx, &previous_link_settings); | |
| 2940 | + } | |
| 2941 | + | |
| 2930 | 2942 | status = false; |
| 2931 | 2943 | if (out_link_loss) |
| 2932 | 2944 | *out_link_loss = true; |
| @@ -4227,6 +4239,21 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) · 1294 unmodified lines | ||
| 4227 | 4239 | void dpcd_set_source_specific_data(struct dc_link *link) |
| 4228 | 4240 | { |
| 4229 | 4241 | const uint32_t post_oui_delay = 30; // 30ms |
| 4242 | + uint8_t dspc = 0; | |
| 4243 | + enum dc_status ret = DC_ERROR_UNEXPECTED; | |
| 4244 | + | |
| 4245 | + ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc, | |
| 4246 | + sizeof(dspc)); | |
| 4247 | + | |
| 4248 | + if (ret != DC_OK) { | |
| 4249 | + DC_LOG_ERROR("Error in DP aux read transaction," | |
| 4250 | + " not writing source specific data\n"); | |
| 4251 | + return; | |
| 4252 | + } | |
| 4253 | + | |
| 4254 | + /* Return if OUI unsupported */ | |
| 4255 | + if (!(dspc & DP_OUI_SUPPORT)) | |
| 4256 | + return; | |
| 4230 | 4257 | |
| 4231 | 4258 | if (!link->dc->vendor_signature.is_valid) { |
| 4232 | 4259 | struct dpcd_amd_signature amd_signature; |
| @@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status( · 230 unmodified lines | ||
| 231 | 231 | return dc_stream_get_status_from_state(dc->current_state, stream); |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | −static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc) | |
| 235 | −{ | |
| 236 | −#if defined(CONFIG_DRM_AMD_DC_DCN) | |
| 237 | − unsigned int vupdate_line; | |
| 238 | − unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos; | |
| 239 | − struct dc_stream_state *stream = pipe_ctx->stream; | |
| 240 | − unsigned int us_per_line; | |
| 241 | − | |
| 242 | − if (stream->ctx->asic_id.chip_family == FAMILY_RV && | |
| 243 | − ASICREV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) { | |
| 244 | − | |
| 245 | − vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); | |
| 246 | − if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos)) | |
| 247 | − return; | |
| 248 | − | |
| 249 | − if (vpos >= vupdate_line) | |
| 250 | − return; | |
| 251 | − | |
| 252 | − us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz; | |
| 253 | − lines_to_vupdate = vupdate_line - vpos; | |
| 254 | − us_to_vupdate = lines_to_vupdate * us_per_line; | |
| 255 | − | |
| 256 | − /* 70 us is a conservative estimate of cursor update time*/ | |
| 257 | − if (us_to_vupdate < 70) | |
| 258 | − udelay(us_to_vupdate); | |
| 259 | − } | |
| 260 | −#endif | |
| 261 | −} | |
| 262 | 234 | |
| 263 | 235 | /** |
| 264 | 236 | * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address |
| @@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes( · 33 unmodified lines | ||
| 298 | 270 | |
| 299 | 271 | if (!pipe_to_program) { |
| 300 | 272 | pipe_to_program = pipe_ctx; |
| 301 | − | |
| 302 | − delay_cursor_until_vupdate(pipe_ctx, dc); | |
| 303 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, true); | |
| 273 | + dc->hwss.cursor_lock(dc, pipe_to_program, true); | |
| 304 | 274 | } |
| 305 | 275 | |
| 306 | 276 | dc->hwss.set_cursor_attribute(pipe_ctx); |
| @@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes( · 2 unmodified lines | ||
| 309 | 279 | } |
| 310 | 280 | |
| 311 | 281 | if (pipe_to_program) |
| 312 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, false); | |
| 282 | + dc->hwss.cursor_lock(dc, pipe_to_program, false); | |
| 313 | 283 | |
| 314 | 284 | return true; |
| 315 | 285 | } |
| @@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position( · 33 unmodified lines | ||
| 349 | 319 | |
| 350 | 320 | if (!pipe_to_program) { |
| 351 | 321 | pipe_to_program = pipe_ctx; |
| 352 | − | |
| 353 | − delay_cursor_until_vupdate(pipe_ctx, dc); | |
| 354 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, true); | |
| 322 | + dc->hwss.cursor_lock(dc, pipe_to_program, true); | |
| 355 | 323 | } |
| 356 | 324 | |
| 357 | 325 | dc->hwss.set_cursor_position(pipe_ctx); |
| 358 | 326 | } |
| 359 | 327 | |
| 360 | 328 | if (pipe_to_program) |
| 361 | − dc->hwss.pipe_control_lock(dc, pipe_to_program, false); | |
| 329 | + dc->hwss.cursor_lock(dc, pipe_to_program, false); | |
| 362 | 330 | |
| 363 | 331 | return true; |
| 364 | 332 | } |
| @@ -2757,6 +2757,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { · 2756 unmodified lines | ||
| 2757 | 2757 | .disable_plane = dce110_power_down_fe, |
| 2758 | 2758 | .pipe_control_lock = dce_pipe_control_lock, |
| 2759 | 2759 | .interdependent_update_lock = NULL, |
| 2760 | + .cursor_lock = dce_pipe_control_lock, | |
| 2760 | 2761 | .prepare_bandwidth = dce110_prepare_bandwidth, |
| 2761 | 2762 | .optimize_bandwidth = dce110_optimize_bandwidth, |
| 2762 | 2763 | .set_drr = set_drr, |
| @@ -1625,6 +1625,16 @@ void dcn10_pipe_control_lock( · 1624 unmodified lines | ||
| 1625 | 1625 | hws->funcs.verify_allow_pstate_change_high(dc); |
| 1626 | 1626 | } |
| 1627 | 1627 | |
| 1628 | +void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) | |
| 1629 | +{ | |
| 1630 | + /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ | |
| 1631 | + if (!pipe || pipe->top_pipe) | |
| 1632 | + return; | |
| 1633 | + | |
| 1634 | + dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, | |
| 1635 | + pipe->stream_res.opp->inst, lock); | |
| 1636 | +} | |
| 1637 | + | |
| 1628 | 1638 | static bool wait_for_reset_trigger_to_occur( |
| 1629 | 1639 | struct dc_context *dc_ctx, |
| 1630 | 1640 | struct timing_generator *tg) |
| @@ -49,6 +49,7 @@ void dcn10_pipe_control_lock( · 48 unmodified lines | ||
| 49 | 49 | struct dc *dc, |
| 50 | 50 | struct pipe_ctx *pipe, |
| 51 | 51 | bool lock); |
| 52 | +void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock); | |
| 52 | 53 | void dcn10_blank_pixel_data( |
| 53 | 54 | struct dc *dc, |
| 54 | 55 | struct pipe_ctx *pipe_ctx, |
| @@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { · 49 unmodified lines | ||
| 50 | 50 | .disable_audio_stream = dce110_disable_audio_stream, |
| 51 | 51 | .disable_plane = dcn10_disable_plane, |
| 52 | 52 | .pipe_control_lock = dcn10_pipe_control_lock, |
| 53 | + .cursor_lock = dcn10_cursor_lock, | |
| 53 | 54 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 54 | 55 | .prepare_bandwidth = dcn10_prepare_bandwidth, |
| 55 | 56 | .optimize_bandwidth = dcn10_optimize_bandwidth, |
| @@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane( · 222 unmodified lines | ||
| 223 | 223 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id); |
| 224 | 224 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id); |
| 225 | 225 | |
| 226 | + /* Configure VUPDATE lock set for this MPCC to map to the OPP */ | |
| 227 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id); | |
| 228 | + | |
| 226 | 229 | /* update mpc tree mux setting */ |
| 227 | 230 | if (tree->opp_list == insert_above_mpcc) { |
| 228 | 231 | /* insert the toppest mpcc */ |
| @@ -318,6 +321,7 @@ void mpc1_remove_mpcc( · 89 unmodified lines | ||
| 318 | 321 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 319 | 322 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 320 | 323 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 324 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 321 | 325 | |
| 322 | 326 | /* mark this mpcc as not in use */ |
| 323 | 327 | mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); |
| @@ -328,6 +332,7 @@ void mpc1_remove_mpcc( · 4 unmodified lines | ||
| 328 | 332 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 329 | 333 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 330 | 334 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 335 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 331 | 336 | } |
| 332 | 337 | } |
| 333 | 338 | |
| @@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc) · 27 unmodified lines | ||
| 361 | 366 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 362 | 367 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 363 | 368 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 369 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 364 | 370 | |
| 365 | 371 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); |
| 366 | 372 | } |
| @@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id) · 14 unmodified lines | ||
| 381 | 387 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 382 | 388 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 383 | 389 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 390 | + REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | |
| 384 | 391 | |
| 385 | 392 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); |
| 386 | 393 | |
| @@ -453,6 +460,13 @@ void mpc1_read_mpcc_state( · 66 unmodified lines | ||
| 453 | 460 | MPCC_BUSY, &s->busy); |
| 454 | 461 | } |
| 455 | 462 | |
| 463 | +void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock) | |
| 464 | +{ | |
| 465 | + struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); | |
| 466 | + | |
| 467 | + REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0); | |
| 468 | +} | |
| 469 | + | |
| 456 | 470 | static const struct mpc_funcs dcn10_mpc_funcs = { |
| 457 | 471 | .read_mpcc_state = mpc1_read_mpcc_state, |
| 458 | 472 | .insert_plane = mpc1_insert_plane, |
| @@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = { · 5 unmodified lines | ||
| 464 | 478 | .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect, |
| 465 | 479 | .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, |
| 466 | 480 | .update_blending = mpc1_update_blending, |
| 481 | + .cursor_lock = mpc1_cursor_lock, | |
| 467 | 482 | .set_denorm = NULL, |
| 468 | 483 | .set_denorm_clamp = NULL, |
| 469 | 484 | .set_output_csc = NULL, |
| @@ -39,11 +39,12 @@ · 38 unmodified lines | ||
| 39 | 39 | SRII(MPCC_BG_G_Y, MPCC, inst),\ |
| 40 | 40 | SRII(MPCC_BG_R_CR, MPCC, inst),\ |
| 41 | 41 | SRII(MPCC_BG_B_CB, MPCC, inst),\ |
| 42 | − SRII(MPCC_BG_B_CB, MPCC, inst),\ | |
| 43 | − SRII(MPCC_SM_CONTROL, MPCC, inst) | |
| 42 | + SRII(MPCC_SM_CONTROL, MPCC, inst),\ | |
| 43 | + SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst) | |
| 44 | 44 | |
| 45 | 45 | #define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ |
| 46 | − SRII(MUX, MPC_OUT, inst) | |
| 46 | + SRII(MUX, MPC_OUT, inst),\ | |
| 47 | + VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst) | |
| 47 | 48 | |
| 48 | 49 | #define MPC_COMMON_REG_VARIABLE_LIST \ |
| 49 | 50 | uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ |
| @@ -55,7 +56,9 @@ · 5 unmodified lines | ||
| 55 | 56 | uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ |
| 56 | 57 | uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ |
| 57 | 58 | uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \ |
| 58 | − uint32_t MUX[MAX_OPP]; | |
| 59 | + uint32_t MUX[MAX_OPP]; \ | |
| 60 | + uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \ | |
| 61 | + uint32_t CUR[MAX_OPP]; | |
| 59 | 62 | |
| 60 | 63 | #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ |
| 61 | 64 | SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ |
| @@ -78,7 +81,8 @@ · 16 unmodified lines | ||
| 78 | 81 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\ |
| 79 | 82 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\ |
| 80 | 83 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\ |
| 81 | − SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh) | |
| 84 | + SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\ | |
| 85 | + SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh) | |
| 82 | 86 | |
| 83 | 87 | #define MPC_REG_FIELD_LIST(type) \ |
| 84 | 88 | type MPCC_TOP_SEL;\ |
| @@ -101,7 +105,9 @@ · 16 unmodified lines | ||
| 101 | 105 | type MPCC_SM_FIELD_ALT;\ |
| 102 | 106 | type MPCC_SM_FORCE_NEXT_FRAME_POL;\ |
| 103 | 107 | type MPCC_SM_FORCE_NEXT_TOP_POL;\ |
| 104 | − type MPC_OUT_MUX; | |
| 108 | + type MPC_OUT_MUX;\ | |
| 109 | + type MPCC_UPDATE_LOCK_SEL;\ | |
| 110 | + type CUR_VUPDATE_LOCK_SET; | |
| 105 | 111 | |
| 106 | 112 | struct dcn_mpc_registers { |
| 107 | 113 | MPC_COMMON_REG_VARIABLE_LIST |
| @@ -192,4 +198,6 @@ void mpc1_read_mpcc_state( · 84 unmodified lines | ||
| 192 | 198 | int mpcc_inst, |
| 193 | 199 | struct mpcc_state *s); |
| 194 | 200 | |
| 201 | +void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock); | |
| 202 | + | |
| 195 | 203 | #endif |
| @@ -181,6 +181,14 @@ enum dcn10_clk_src_array_id { · 180 unmodified lines | ||
| 181 | 181 | .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 182 | 182 | mm ## block ## id ## _ ## reg_name |
| 183 | 183 | |
| 184 | +#define VUPDATE_SRII(reg_name, block, id)\ | |
| 185 | + .reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \ | |
| 186 | + mm ## reg_name ## 0 ## _ ## block ## id | |
| 187 | + | |
| 188 | +/* set field/register/bitfield name */ | |
| 189 | +#define SFRB(field_name, reg_name, bitfield, post_fix)\ | |
| 190 | + .field_name = reg_name ## __ ## bitfield ## post_fix | |
| 191 | + | |
| 184 | 192 | /* NBIO */ |
| 185 | 193 | #define NBIO_BASE_INNER(seg) \ |
| 186 | 194 | NBIF_BASE__INST0_SEG ## seg |
| @@ -419,11 +427,13 @@ static const struct dcn_mpc_registers mpc_regs = { · 232 unmodified lines | ||
| 419 | 427 | }; |
| 420 | 428 | |
| 421 | 429 | static const struct dcn_mpc_shift mpc_shift = { |
| 422 | − MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) | |
| 430 | + MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\ | |
| 431 | + SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT) | |
| 423 | 432 | }; |
| 424 | 433 | |
| 425 | 434 | static const struct dcn_mpc_mask mpc_mask = { |
| 426 | − MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK), | |
| 435 | + MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\ | |
| 436 | + SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK) | |
| 427 | 437 | }; |
| 428 | 438 | |
| 429 | 439 | #define tg_regs(id)\ |
| @@ -2294,7 +2294,8 @@ void dcn20_fpga_init_hw(struct dc *dc) · 2293 unmodified lines | ||
| 2294 | 2294 | |
| 2295 | 2295 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2); |
| 2296 | 2296 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); |
| 2297 | − REG_WRITE(REFCLK_CNTL, 0); | |
| 2297 | + if (REG(REFCLK_CNTL)) | |
| 2298 | + REG_WRITE(REFCLK_CNTL, 0); | |
| 2298 | 2299 | // |
| 2299 | 2300 | |
| 2300 | 2301 | |
| @@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 51 unmodified lines | ||
| 52 | 52 | .disable_plane = dcn20_disable_plane, |
| 53 | 53 | .pipe_control_lock = dcn20_pipe_control_lock, |
| 54 | 54 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 55 | + .cursor_lock = dcn10_cursor_lock, | |
| 55 | 56 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 56 | 57 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 57 | 58 | .update_bandwidth = dcn20_update_bandwidth, |
| @@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = { · 544 unmodified lines | ||
| 545 | 545 | .mpc_init = mpc1_mpc_init, |
| 546 | 546 | .mpc_init_single_inst = mpc1_mpc_init_single_inst, |
| 547 | 547 | .update_blending = mpc2_update_blending, |
| 548 | + .cursor_lock = mpc1_cursor_lock, | |
| 548 | 549 | .get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp, |
| 549 | 550 | .wait_for_idle = mpc2_assert_idle_mpcc, |
| 550 | 551 | .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, |
| @@ -179,7 +179,8 @@ · 178 unmodified lines | ||
| 179 | 179 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\ |
| 180 | 180 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\ |
| 181 | 181 | SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\ |
| 182 | − SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh) | |
| 182 | + SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\ | |
| 183 | + SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) | |
| 183 | 184 | |
| 184 | 185 | /* |
| 185 | 186 | * DCN2 MPC_OCSC debug status register: |
| @@ -508,6 +508,10 @@ enum dcn20_clk_src_array_id { · 507 unmodified lines | ||
| 508 | 508 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 509 | 509 | mm ## block ## id ## _ ## reg_name |
| 510 | 510 | |
| 511 | +#define VUPDATE_SRII(reg_name, block, id)\ | |
| 512 | + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ | |
| 513 | + mm ## reg_name ## _ ## block ## id | |
| 514 | + | |
| 511 | 515 | /* NBIO */ |
| 512 | 516 | #define NBIO_BASE_INNER(seg) \ |
| 513 | 517 | NBIO_BASE__INST0_SEG ## seg |
| @@ -3064,25 +3068,32 @@ validate_out: · 2550 unmodified lines | ||
| 3064 | 3068 | return out; |
| 3065 | 3069 | } |
| 3066 | 3070 | |
| 3067 | − | |
| 3068 | −bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, | |
| 3069 | − bool fast_validate) | |
| 3071 | +/* | |
| 3072 | + * This must be noinline to ensure anything that deals with FP registers | |
| 3073 | + * is contained within this call; previously our compiling with hard-float | |
| 3074 | + * would result in fp instructions being emitted outside of the boundaries | |
| 3075 | + * of the DC_FP_START/END macros, which makes sense as the compiler has no | |
| 3076 | + * idea about what is wrapped and what is not | |
| 3077 | + * | |
| 3078 | + * This is largely just a workaround to avoid breakage introduced with 5.6, | |
| 3079 | + * ideally all fp-using code should be moved into its own file, only that | |
| 3080 | + * should be compiled with hard-float, and all code exported from there | |
| 3081 | + * should be strictly wrapped with DC_FP_START/END | |
| 3082 | + */ | |
| 3083 | +static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc, | |
| 3084 | + struct dc_state *context, bool fast_validate) | |
| 3070 | 3085 | { |
| 3071 | 3086 | bool voltage_supported = false; |
| 3072 | 3087 | bool full_pstate_supported = false; |
| 3073 | 3088 | bool dummy_pstate_supported = false; |
| 3074 | 3089 | double p_state_latency_us; |
| 3075 | 3090 | |
| 3076 | − DC_FP_START(); | |
| 3077 | 3091 | p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us; |
| 3078 | 3092 | context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support = |
| 3079 | 3093 | dc->debug.disable_dram_clock_change_vactive_support; |
| 3080 | 3094 | |
| 3081 | 3095 | if (fast_validate) { |
| 3082 | − voltage_supported = dcn20_validate_bandwidth_internal(dc, context, true); | |
| 3083 | − | |
| 3084 | − DC_FP_END(); | |
| 3085 | − return voltage_supported; | |
| 3096 | + return dcn20_validate_bandwidth_internal(dc, context, true); | |
| 3086 | 3097 | } |
| 3087 | 3098 | |
| 3088 | 3099 | // Best case, we support full UCLK switch latency |
| @@ -3111,7 +3122,15 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, · 22 unmodified lines | ||
| 3111 | 3122 | |
| 3112 | 3123 | restore_dml_state: |
| 3113 | 3124 | context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us; |
| 3125 | + return voltage_supported; | |
| 3126 | +} | |
| 3114 | 3127 | |
| 3128 | +bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, | |
| 3129 | + bool fast_validate) | |
| 3130 | +{ | |
| 3131 | + bool voltage_supported = false; | |
| 3132 | + DC_FP_START(); | |
| 3133 | + voltage_supported = dcn20_validate_bandwidth_fp(dc, context, fast_validate); | |
| 3115 | 3134 | DC_FP_END(); |
| 3116 | 3135 | return voltage_supported; |
| 3117 | 3136 | } |
| @@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 52 unmodified lines | ||
| 53 | 53 | .disable_plane = dcn20_disable_plane, |
| 54 | 54 | .pipe_control_lock = dcn20_pipe_control_lock, |
| 55 | 55 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 56 | + .cursor_lock = dcn10_cursor_lock, | |
| 56 | 57 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 57 | 58 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 58 | 59 | .update_bandwidth = dcn20_update_bandwidth, |
| @@ -284,7 +284,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 283 unmodified lines | ||
| 284 | 284 | .dram_channel_width_bytes = 4, |
| 285 | 285 | .fabric_datapath_to_dcn_data_return_bytes = 32, |
| 286 | 286 | .dcn_downspread_percent = 0.5, |
| 287 | − .downspread_percent = 0.5, | |
| 287 | + .downspread_percent = 0.38, | |
| 288 | 288 | .dram_page_open_time_ns = 50.0, |
| 289 | 289 | .dram_rw_turnaround_time_ns = 17.5, |
| 290 | 290 | .dram_return_buffer_per_channel_bytes = 8192, |
| @@ -340,6 +340,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 49 unmodified lines | ||
| 340 | 340 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 341 | 341 | mm ## block ## id ## _ ## reg_name |
| 342 | 342 | |
| 343 | +#define VUPDATE_SRII(reg_name, block, id)\ | |
| 344 | + .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ | |
| 345 | + mm ## reg_name ## _ ## block ## id | |
| 346 | + | |
| 343 | 347 | /* NBIO */ |
| 344 | 348 | #define NBIO_BASE_INNER(seg) \ |
| 345 | 349 | NBIF0_BASE__INST0_SEG ## seg |
| @@ -1374,64 +1378,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 1028 unmodified lines | ||
| 1374 | 1378 | { |
| 1375 | 1379 | struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); |
| 1376 | 1380 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
| 1377 | − unsigned int i, j, k; | |
| 1378 | − int closest_clk_lvl; | |
| 1381 | + struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; | |
| 1382 | + unsigned int i, j, closest_clk_lvl; | |
| 1379 | 1383 | |
| 1380 | 1384 | // Default clock levels are used for diags, which may lead to overclocking. |
| 1381 | − if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) { | |
| 1385 | + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { | |
| 1382 | 1386 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; |
| 1383 | 1387 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; |
| 1384 | 1388 | dcn2_1_soc.num_chans = bw_params->num_channels; |
| 1385 | 1389 | |
| 1386 | − /* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */ | |
| 1387 | − dcn2_1_soc.clock_limits[0].state = 0; | |
| 1388 | − dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz; | |
| 1389 | − dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz; | |
| 1390 | − dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz; | |
| 1391 | − dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2; | |
| 1392 | − | |
| 1393 | − /* | |
| 1394 | − * Other levels: find closest DCN clocks that fit the given clock limit using dcfclk | |
| 1395 | − * as indicator | |
| 1396 | − */ | |
| 1397 | − | |
| 1398 | − closest_clk_lvl = -1; | |
| 1399 | − /* index currently being filled */ | |
| 1400 | − k = 1; | |
| 1401 | − for (i = 1; i < clk_table->num_entries; i++) { | |
| 1402 | − /* loop backwards, skip duplicate state*/ | |
| 1403 | − for (j = dcn2_1_soc.num_states - 1; j >= k; j--) { | |
| 1390 | + ASSERT(clk_table->num_entries); | |
| 1391 | + for (i = 0; i < clk_table->num_entries; i++) { | |
| 1392 | + /* loop backwards*/ | |
| 1393 | + for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { | |
| 1404 | 1394 | if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { |
| 1405 | 1395 | closest_clk_lvl = j; |
| 1406 | 1396 | break; |
| 1407 | 1397 | } |
| 1408 | 1398 | } |
| 1409 | 1399 | |
| 1410 | − /* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/ | |
| 1411 | − if (closest_clk_lvl != -1) { | |
| 1412 | − dcn2_1_soc.clock_limits[k].state = i; | |
| 1413 | − dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; | |
| 1414 | − dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; | |
| 1415 | − dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz; | |
| 1416 | − dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; | |
| 1417 | − | |
| 1418 | − dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; | |
| 1419 | − dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | |
| 1420 | − dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; | |
| 1421 | − dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; | |
| 1422 | − dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; | |
| 1423 | − dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; | |
| 1424 | − dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; | |
| 1425 | − k++; | |
| 1426 | − } | |
| 1400 | + clock_limits[i].state = i; | |
| 1401 | + clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; | |
| 1402 | + clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; | |
| 1403 | + clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; | |
| 1404 | + clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; | |
| 1405 | + | |
| 1406 | + clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; | |
| 1407 | + clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | |
| 1408 | + clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; | |
| 1409 | + clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; | |
| 1410 | + clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; | |
| 1411 | + clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; | |
| 1412 | + clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; | |
| 1413 | + } | |
| 1414 | + for (i = 0; i < clk_table->num_entries; i++) | |
| 1415 | + dcn2_1_soc.clock_limits[i] = clock_limits[i]; | |
| 1416 | + if (clk_table->num_entries) { | |
| 1417 | + dcn2_1_soc.num_states = clk_table->num_entries; | |
| 1418 | + /* duplicate last level */ | |
| 1419 | + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | |
| 1420 | + dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | |
| 1427 | 1421 | } |
| 1428 | − dcn2_1_soc.num_states = k; | |
| 1429 | 1422 | } |
| 1430 | 1423 | |
| 1431 | − /* duplicate last level */ | |
| 1432 | − dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | |
| 1433 | − dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | |
| 1434 | − | |
| 1435 | 1424 | dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); |
| 1436 | 1425 | } |
| 1437 | 1426 | |
| @@ -1200,7 +1200,7 @@ static void dml_rq_dlg_get_dlg_params( · 1199 unmodified lines | ||
| 1200 | 1200 | min_hratio_fact_l = 1.0; |
| 1201 | 1201 | min_hratio_fact_c = 1.0; |
| 1202 | 1202 | |
| 1203 | − if (htaps_l <= 1) | |
| 1203 | + if (hratio_l <= 1) | |
| 1204 | 1204 | min_hratio_fact_l = 2.0; |
| 1205 | 1205 | else if (htaps_l <= 6) { |
| 1206 | 1206 | if ((hratio_l * 2.0) > 4.0) |
| @@ -1216,7 +1216,7 @@ static void dml_rq_dlg_get_dlg_params( · 9 unmodified lines | ||
| 1216 | 1216 | |
| 1217 | 1217 | hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz; |
| 1218 | 1218 | |
| 1219 | − if (htaps_c <= 1) | |
| 1219 | + if (hratio_c <= 1) | |
| 1220 | 1220 | min_hratio_fact_c = 2.0; |
| 1221 | 1221 | else if (htaps_c <= 6) { |
| 1222 | 1222 | if ((hratio_c * 2.0) > 4.0) |
| @@ -1522,8 +1522,8 @@ static void dml_rq_dlg_get_dlg_params( · 299 unmodified lines | ||
| 1522 | 1522 | |
| 1523 | 1523 | disp_dlg_regs->refcyc_per_vm_group_vblank = get_refcyc_per_vm_group_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; |
| 1524 | 1524 | disp_dlg_regs->refcyc_per_vm_group_flip = get_refcyc_per_vm_group_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; |
| 1525 | − disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; | |
| 1526 | − disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz; | |
| 1525 | + disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10); | |
| 1526 | + disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10); | |
| 1527 | 1527 | |
| 1528 | 1528 | // Clamp to max for now |
| 1529 | 1529 | if (disp_dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int)dml_pow(2, 23)) |
| @@ -210,6 +210,22 @@ struct mpc_funcs { · 209 unmodified lines | ||
| 210 | 210 | struct mpcc_blnd_cfg *blnd_cfg, |
| 211 | 211 | int mpcc_id); |
| 212 | 212 | |
| 213 | + /* | |
| 214 | + * Lock cursor updates for the specified OPP. | |
| 215 | + * OPP defines the set of MPCC that are locked together for cursor. | |
| 216 | + * | |
| 217 | + * Parameters: | |
| 218 | + * [in] mpc - MPC context. | |
| 219 | + * [in] opp_id - The OPP to lock cursor updates on | |
| 220 | + * [in] lock - lock/unlock the OPP | |
| 221 | + * | |
| 222 | + * Return: void | |
| 223 | + */ | |
| 224 | + void (*cursor_lock)( | |
| 225 | + struct mpc *mpc, | |
| 226 | + int opp_id, | |
| 227 | + bool lock); | |
| 228 | + | |
| 213 | 229 | struct mpcc* (*get_mpcc_for_dpp)( |
| 214 | 230 | struct mpc_tree *tree, |
| 215 | 231 | int dpp_id); |
| @@ -86,6 +86,7 @@ struct hw_sequencer_funcs { · 85 unmodified lines | ||
| 86 | 86 | struct dc_state *context, bool lock); |
| 87 | 87 | void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx, |
| 88 | 88 | bool flip_immediate); |
| 89 | + void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock); | |
| 89 | 90 | |
| 90 | 91 | /* Timing Related */ |
| 91 | 92 | void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, |
| @@ -108,7 +108,7 @@ · 107 unmodified lines | ||
| 108 | 108 | #define ASSERT(expr) ASSERT_CRITICAL(expr) |
| 109 | 109 | |
| 110 | 110 | #else |
| 111 | −#define ASSERT(expr) WARN_ON(!(expr)) | |
| 111 | +#define ASSERT(expr) WARN_ON_ONCE(!(expr)) | |
| 112 | 112 | #endif |
| 113 | 113 | |
| 114 | 114 | #define BREAK_TO_DEBUGGER() ASSERT(0) |
| @@ -1435,7 +1435,8 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap) · 1434 unmodified lines | ||
| 1435 | 1435 | if (!hwmgr) |
| 1436 | 1436 | return -EINVAL; |
| 1437 | 1437 | |
| 1438 | − if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_capability) | |
| 1438 | + if (!(hwmgr->not_vf && amdgpu_dpm) || | |
| 1439 | + !hwmgr->hwmgr_func->get_asic_baco_capability) | |
| 1439 | 1440 | return 0; |
| 1440 | 1441 | |
| 1441 | 1442 | mutex_lock(&hwmgr->smu_lock); |
| @@ -1452,8 +1453,7 @@ static int pp_get_asic_baco_state(void *handle, int *state) · 10 unmodified lines | ||
| 1452 | 1453 | if (!hwmgr) |
| 1453 | 1454 | return -EINVAL; |
| 1454 | 1455 | |
| 1455 | − if (!(hwmgr->not_vf && amdgpu_dpm) || | |
| 1456 | − !hwmgr->hwmgr_func->get_asic_baco_state) | |
| 1456 | + if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_state) | |
| 1457 | 1457 | return 0; |
| 1458 | 1458 | |
| 1459 | 1459 | mutex_lock(&hwmgr->smu_lock); |
| @@ -1470,7 +1470,8 @@ static int pp_set_asic_baco_state(void *handle, int state) · 10 unmodified lines | ||
| 1470 | 1470 | if (!hwmgr) |
| 1471 | 1471 | return -EINVAL; |
| 1472 | 1472 | |
| 1473 | − if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_asic_baco_state) | |
| 1473 | + if (!(hwmgr->not_vf && amdgpu_dpm) || | |
| 1474 | + !hwmgr->hwmgr_func->set_asic_baco_state) | |
| 1474 | 1475 | return 0; |
| 1475 | 1476 | |
| 1476 | 1477 | mutex_lock(&hwmgr->smu_lock); |
| @@ -3442,8 +3442,12 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, · 3441 unmodified lines | ||
| 3442 | 3442 | drm_dp_queue_down_tx(mgr, txmsg); |
| 3443 | 3443 | |
| 3444 | 3444 | ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); |
| 3445 | − if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) | |
| 3446 | − ret = -EIO; | |
| 3445 | + if (ret > 0) { | |
| 3446 | + if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) | |
| 3447 | + ret = -EIO; | |
| 3448 | + else | |
| 3449 | + ret = size; | |
| 3450 | + } | |
| 3447 | 3451 | |
| 3448 | 3452 | kfree(txmsg); |
| 3449 | 3453 | fail_put: |
| @@ -5111,7 +5111,7 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d · 5110 unmodified lines | ||
| 5111 | 5111 | struct drm_display_mode *mode; |
| 5112 | 5112 | unsigned pixel_clock = (timings->pixel_clock[0] | |
| 5113 | 5113 | (timings->pixel_clock[1] << 8) | |
| 5114 | − (timings->pixel_clock[2] << 16)); | |
| 5114 | + (timings->pixel_clock[2] << 16)) + 1; | |
| 5115 | 5115 | unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1; |
| 5116 | 5116 | unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1; |
| 5117 | 5117 | unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1; |
| @@ -241,8 +241,12 @@ static int drm_hdcp_request_srm(struct drm_device *drm_dev, · 240 unmodified lines | ||
| 241 | 241 | |
| 242 | 242 | ret = request_firmware_direct(&fw, (const char *)fw_name, |
| 243 | 243 | drm_dev->dev); |
| 244 | − if (ret < 0) | |
| 244 | + if (ret < 0) { | |
| 245 | + *revoked_ksv_cnt = 0; | |
| 246 | + *revoked_ksv_list = NULL; | |
| 247 | + ret = 0; | |
| 245 | 248 | goto exit; |
| 249 | + } | |
| 246 | 250 | |
| 247 | 251 | if (fw->size && fw->data) |
| 248 | 252 | ret = drm_hdcp_srm_update(fw->data, fw->size, revoked_ksv_list, |
| @@ -287,6 +291,8 @@ int drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs, · 38 unmodified lines | ||
| 287 | 291 | |
| 288 | 292 | ret = drm_hdcp_request_srm(drm_dev, &revoked_ksv_list, |
| 289 | 293 | &revoked_ksv_cnt); |
| 294 | + if (ret) | |
| 295 | + return ret; | |
| 290 | 296 | |
| 291 | 297 | /* revoked_ksv_cnt will be zero when above function failed */ |
| 292 | 298 | for (i = 0; i < revoked_ksv_cnt; i++) |
| @@ -182,21 +182,35 @@ i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj, · 181 unmodified lines | ||
| 182 | 182 | int tiling_mode, unsigned int stride) |
| 183 | 183 | { |
| 184 | 184 | struct i915_ggtt *ggtt = &to_i915(obj->base.dev)->ggtt; |
| 185 | − struct i915_vma *vma; | |
| 185 | + struct i915_vma *vma, *vn; | |
| 186 | + LIST_HEAD(unbind); | |
| 186 | 187 | int ret = 0; |
| 187 | 188 | |
| 188 | 189 | if (tiling_mode == I915_TILING_NONE) |
| 189 | 190 | return 0; |
| 190 | 191 | |
| 191 | 192 | mutex_lock(&ggtt->vm.mutex); |
| 193 | + | |
| 194 | + spin_lock(&obj->vma.lock); | |
| 192 | 195 | for_each_ggtt_vma(vma, obj) { |
| 196 | + GEM_BUG_ON(vma->vm != &ggtt->vm); | |
| 197 | + | |
| 193 | 198 | if (i915_vma_fence_prepare(vma, tiling_mode, stride)) |
| 194 | 199 | continue; |
| 195 | 200 | |
| 201 | + list_move(&vma->vm_link, &unbind); | |
| 202 | + } | |
| 203 | + spin_unlock(&obj->vma.lock); | |
| 204 | + | |
| 205 | + list_for_each_entry_safe(vma, vn, &unbind, vm_link) { | |
| 196 | 206 | ret = __i915_vma_unbind(vma); |
| 197 | − if (ret) | |
| 207 | + if (ret) { | |
| 208 | + /* Restore the remaining vma on an error */ | |
| 209 | + list_splice(&unbind, &ggtt->vm.bound_list); | |
| 198 | 210 | break; |
| 211 | + } | |
| 199 | 212 | } |
| 213 | + | |
| 200 | 214 | mutex_unlock(&ggtt->vm.mutex); |
| 201 | 215 | |
| 202 | 216 | return ret; |
| @@ -268,6 +282,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 65 unmodified lines | ||
| 268 | 282 | } |
| 269 | 283 | mutex_unlock(&obj->mm.lock); |
| 270 | 284 | |
| 285 | + spin_lock(&obj->vma.lock); | |
| 271 | 286 | for_each_ggtt_vma(vma, obj) { |
| 272 | 287 | vma->fence_size = |
| 273 | 288 | i915_gem_fence_size(i915, vma->size, tiling, stride); |
| @@ -278,6 +293,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 4 unmodified lines | ||
| 278 | 293 | if (vma->fence) |
| 279 | 294 | vma->fence->dirty = true; |
| 280 | 295 | } |
| 296 | + spin_unlock(&obj->vma.lock); | |
| 281 | 297 | |
| 282 | 298 | obj->tiling_and_stride = tiling | stride; |
| 283 | 299 | i915_gem_object_unlock(obj); |
| @@ -1477,8 +1477,10 @@ static int igt_ppgtt_pin_update(void *arg) · 1476 unmodified lines | ||
| 1477 | 1477 | unsigned int page_size = BIT(first); |
| 1478 | 1478 | |
| 1479 | 1479 | obj = i915_gem_object_create_internal(dev_priv, page_size); |
| 1480 | − if (IS_ERR(obj)) | |
| 1481 | − return PTR_ERR(obj); | |
| 1480 | + if (IS_ERR(obj)) { | |
| 1481 | + err = PTR_ERR(obj); | |
| 1482 | + goto out_vm; | |
| 1483 | + } | |
| 1482 | 1484 | |
| 1483 | 1485 | vma = i915_vma_instance(obj, vm, NULL); |
| 1484 | 1486 | if (IS_ERR(vma)) { |
| @@ -1531,8 +1533,10 @@ static int igt_ppgtt_pin_update(void *arg) · 46 unmodified lines | ||
| 1531 | 1533 | } |
| 1532 | 1534 | |
| 1533 | 1535 | obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE); |
| 1534 | − if (IS_ERR(obj)) | |
| 1535 | − return PTR_ERR(obj); | |
| 1536 | + if (IS_ERR(obj)) { | |
| 1537 | + err = PTR_ERR(obj); | |
| 1538 | + goto out_vm; | |
| 1539 | + } | |
| 1536 | 1540 | |
| 1537 | 1541 | vma = i915_vma_instance(obj, vm, NULL); |
| 1538 | 1542 | if (IS_ERR(vma)) { |
| @@ -521,6 +521,8 @@ int intel_timeline_read_hwsp(struct i915_request *from, · 520 unmodified lines | ||
| 521 | 521 | |
| 522 | 522 | rcu_read_lock(); |
| 523 | 523 | cl = rcu_dereference(from->hwsp_cacheline); |
| 524 | + if (i915_request_completed(from)) /* confirm cacheline is valid */ | |
| 525 | + goto unlock; | |
| 524 | 526 | if (unlikely(!i915_active_acquire_if_busy(&cl->active))) |
| 525 | 527 | goto unlock; /* seqno wrapped and completed! */ |
| 526 | 528 | if (unlikely(i915_request_completed(from))) |
| @@ -3358,7 +3358,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 3357 unmodified lines | ||
| 3358 | 3358 | { |
| 3359 | 3359 | struct intel_uncore *uncore = &dev_priv->uncore; |
| 3360 | 3360 | |
| 3361 | − u32 de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; | |
| 3361 | + u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | | |
| 3362 | + GEN8_PIPE_CDCLK_CRC_DONE; | |
| 3362 | 3363 | u32 de_pipe_enables; |
| 3363 | 3364 | u32 de_port_masked = GEN8_AUX_CHANNEL_A; |
| 3364 | 3365 | u32 de_port_enables; |
| @@ -3369,13 +3370,10 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 4 unmodified lines | ||
| 3369 | 3370 | de_misc_masked |= GEN8_DE_MISC_GSE; |
| 3370 | 3371 | |
| 3371 | 3372 | if (INTEL_GEN(dev_priv) >= 9) { |
| 3372 | − de_pipe_masked |= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; | |
| 3373 | 3373 | de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | |
| 3374 | 3374 | GEN9_AUX_CHANNEL_D; |
| 3375 | 3375 | if (IS_GEN9_LP(dev_priv)) |
| 3376 | 3376 | de_port_masked |= BXT_DE_PORT_GMBUS; |
| 3377 | − } else { | |
| 3378 | − de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | |
| 3379 | 3377 | } |
| 3380 | 3378 | |
| 3381 | 3379 | if (INTEL_GEN(dev_priv) >= 11) |
| @@ -158,16 +158,18 @@ vma_create(struct drm_i915_gem_object *obj, · 157 unmodified lines | ||
| 158 | 158 | |
| 159 | 159 | GEM_BUG_ON(!IS_ALIGNED(vma->size, I915_GTT_PAGE_SIZE)); |
| 160 | 160 | |
| 161 | + spin_lock(&obj->vma.lock); | |
| 162 | + | |
| 161 | 163 | if (i915_is_ggtt(vm)) { |
| 162 | 164 | if (unlikely(overflows_type(vma->size, u32))) |
| 163 | − goto err_vma; | |
| 165 | + goto err_unlock; | |
| 164 | 166 | |
| 165 | 167 | vma->fence_size = i915_gem_fence_size(vm->i915, vma->size, |
| 166 | 168 | i915_gem_object_get_tiling(obj), |
| 167 | 169 | i915_gem_object_get_stride(obj)); |
| 168 | 170 | if (unlikely(vma->fence_size < vma->size || /* overflow */ |
| 169 | 171 | vma->fence_size > vm->total)) |
| 170 | − goto err_vma; | |
| 172 | + goto err_unlock; | |
| 171 | 173 | |
| 172 | 174 | GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I915_GTT_MIN_ALIGNMENT)); |
| 173 | 175 | |
| @@ -179,8 +181,6 @@ vma_create(struct drm_i915_gem_object *obj, · 5 unmodified lines | ||
| 179 | 181 | __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma)); |
| 180 | 182 | } |
| 181 | 183 | |
| 182 | − spin_lock(&obj->vma.lock); | |
| 183 | − | |
| 184 | 184 | rb = NULL; |
| 185 | 185 | p = &obj->vma.tree.rb_node; |
| 186 | 186 | while (*p) { |
| @@ -225,6 +225,8 @@ vma_create(struct drm_i915_gem_object *obj, · 38 unmodified lines | ||
| 225 | 225 | |
| 226 | 226 | return vma; |
| 227 | 227 | |
| 228 | +err_unlock: | |
| 229 | + spin_unlock(&obj->vma.lock); | |
| 228 | 230 | err_vma: |
| 229 | 231 | i915_vma_free(vma); |
| 230 | 232 | return ERR_PTR(-E2BIG); |
| @@ -843,6 +843,7 @@ static const struct of_device_id ingenic_drm_of_match[] = { · 842 unmodified lines | ||
| 843 | 843 | { .compatible = "ingenic,jz4770-lcd", .data = &jz4770_soc_info }, |
| 844 | 844 | { /* sentinel */ }, |
| 845 | 845 | }; |
| 846 | +MODULE_DEVICE_TABLE(of, ingenic_drm_of_match); | |
| 846 | 847 | |
| 847 | 848 | static struct platform_driver ingenic_drm_driver = { |
| 848 | 849 | .driver = { |
| @@ -480,9 +480,10 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, · 479 unmodified lines | ||
| 480 | 480 | return ret; |
| 481 | 481 | |
| 482 | 482 | ret = qxl_release_reserve_list(release, true); |
| 483 | − if (ret) | |
| 483 | + if (ret) { | |
| 484 | + qxl_release_free(qdev, release); | |
| 484 | 485 | return ret; |
| 485 | − | |
| 486 | + } | |
| 486 | 487 | cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); |
| 487 | 488 | cmd->type = QXL_SURFACE_CMD_CREATE; |
| 488 | 489 | cmd->flags = QXL_SURF_FLAG_KEEP_DATA; |
| @@ -499,8 +500,8 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, · 10 unmodified lines | ||
| 499 | 500 | /* no need to add a release to the fence for this surface bo, |
| 500 | 501 | since it is only released when we ask to destroy the surface |
| 501 | 502 | and it would never signal otherwise */ |
| 502 | − qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 503 | 503 | qxl_release_fence_buffer_objects(release); |
| 504 | + qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 504 | 505 | |
| 505 | 506 | surf->hw_surf_alloc = true; |
| 506 | 507 | spin_lock(&qdev->surf_id_idr_lock); |
| @@ -542,9 +543,8 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev, · 35 unmodified lines | ||
| 542 | 543 | cmd->surface_id = id; |
| 543 | 544 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 544 | 545 | |
| 545 | − qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 546 | − | |
| 547 | 546 | qxl_release_fence_buffer_objects(release); |
| 547 | + qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | |
| 548 | 548 | |
| 549 | 549 | return 0; |
| 550 | 550 | } |
| @@ -510,8 +510,8 @@ static int qxl_primary_apply_cursor(struct drm_plane *plane) · 509 unmodified lines | ||
| 510 | 510 | cmd->u.set.visible = 1; |
| 511 | 511 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 512 | 512 | |
| 513 | − qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 514 | 513 | qxl_release_fence_buffer_objects(release); |
| 514 | + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 515 | 515 | |
| 516 | 516 | return ret; |
| 517 | 517 | |
| @@ -652,8 +652,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, · 134 unmodified lines | ||
| 652 | 652 | cmd->u.position.y = plane->state->crtc_y + fb->hot_y; |
| 653 | 653 | |
| 654 | 654 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 655 | − qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 656 | 655 | qxl_release_fence_buffer_objects(release); |
| 656 | + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 657 | 657 | |
| 658 | 658 | if (old_cursor_bo != NULL) |
| 659 | 659 | qxl_bo_unpin(old_cursor_bo); |
| @@ -700,8 +700,8 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane, · 40 unmodified lines | ||
| 700 | 700 | cmd->type = QXL_CURSOR_HIDE; |
| 701 | 701 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 702 | 702 | |
| 703 | − qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 704 | 703 | qxl_release_fence_buffer_objects(release); |
| 704 | + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | |
| 705 | 705 | } |
| 706 | 706 | |
| 707 | 707 | static void qxl_update_dumb_head(struct qxl_device *qdev, |
| @@ -209,9 +209,10 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, · 208 unmodified lines | ||
| 209 | 209 | goto out_release_backoff; |
| 210 | 210 | |
| 211 | 211 | rects = drawable_set_clipping(qdev, num_clips, clips_bo); |
| 212 | − if (!rects) | |
| 212 | + if (!rects) { | |
| 213 | + ret = -EINVAL; | |
| 213 | 214 | goto out_release_backoff; |
| 214 | − | |
| 215 | + } | |
| 215 | 216 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
| 216 | 217 | |
| 217 | 218 | drawable->clip.type = SPICE_CLIP_TYPE_RECTS; |
| @@ -242,8 +243,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, · 24 unmodified lines | ||
| 242 | 243 | } |
| 243 | 244 | qxl_bo_kunmap(clips_bo); |
| 244 | 245 | |
| 245 | − qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | |
| 246 | 246 | qxl_release_fence_buffer_objects(release); |
| 247 | + qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | |
| 247 | 248 | |
| 248 | 249 | out_release_backoff: |
| 249 | 250 | if (ret) |
| @@ -212,7 +212,8 @@ qxl_image_init_helper(struct qxl_device *qdev, · 211 unmodified lines | ||
| 212 | 212 | break; |
| 213 | 213 | default: |
| 214 | 214 | DRM_ERROR("unsupported image bit depth\n"); |
| 215 | − return -EINVAL; /* TODO: cleanup */ | |
| 215 | + qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr); | |
| 216 | + return -EINVAL; | |
| 216 | 217 | } |
| 217 | 218 | image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN; |
| 218 | 219 | image->u.bitmap.x = width; |
| @@ -261,11 +261,8 @@ static int qxl_process_single_command(struct qxl_device *qdev, · 260 unmodified lines | ||
| 261 | 261 | apply_surf_reloc(qdev, &reloc_info[i]); |
| 262 | 262 | } |
| 263 | 263 | |
| 264 | + qxl_release_fence_buffer_objects(release); | |
| 264 | 265 | ret = qxl_push_command_ring_release(qdev, release, cmd->type, true); |
| 265 | − if (ret) | |
| 266 | − qxl_release_backoff_reserve_list(release); | |
| 267 | − else | |
| 268 | − qxl_release_fence_buffer_objects(release); | |
| 269 | 266 | |
| 270 | 267 | out_free_bos: |
| 271 | 268 | out_free_release: |
| @@ -717,7 +717,7 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder) · 716 unmodified lines | ||
| 717 | 717 | struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; |
| 718 | 718 | struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder); |
| 719 | 719 | struct mipi_dsi_device *device = dsi->device; |
| 720 | − union phy_configure_opts opts = { 0 }; | |
| 720 | + union phy_configure_opts opts = { }; | |
| 721 | 721 | struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy; |
| 722 | 722 | u16 delay; |
| 723 | 723 | int err; |
| @@ -221,6 +221,7 @@ struct virtio_gpu_fpriv { · 220 unmodified lines | ||
| 221 | 221 | /* virtio_ioctl.c */ |
| 222 | 222 | #define DRM_VIRTIO_NUM_IOCTLS 10 |
| 223 | 223 | extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; |
| 224 | +void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file); | |
| 224 | 225 | |
| 225 | 226 | /* virtio_kms.c */ |
| 226 | 227 | int virtio_gpu_init(struct drm_device *dev); |
| @@ -39,6 +39,9 @@ int virtio_gpu_gem_create(struct drm_file *file, · 38 unmodified lines | ||
| 39 | 39 | int ret; |
| 40 | 40 | u32 handle; |
| 41 | 41 | |
| 42 | + if (vgdev->has_virgl_3d) | |
| 43 | + virtio_gpu_create_context(dev, file); | |
| 44 | + | |
| 42 | 45 | ret = virtio_gpu_object_create(vgdev, params, &obj, NULL); |
| 43 | 46 | if (ret < 0) |
| 44 | 47 | return ret; |
| @@ -34,8 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | #include "virtgpu_drv.h" |
| 36 | 36 | |
| 37 | −static void virtio_gpu_create_context(struct drm_device *dev, | |
| 38 | − struct drm_file *file) | |
| 37 | +void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file) | |
| 39 | 38 | { |
| 40 | 39 | struct virtio_gpu_device *vgdev = dev->dev_private; |
| 41 | 40 | struct virtio_gpu_fpriv *vfpriv = file->driver_priv; |
| @@ -53,14 +53,6 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) · 52 unmodified lines | ||
| 53 | 53 | events_clear, &events_clear); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | −static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev, | |
| 57 | − uint32_t ctx_id) | |
| 58 | −{ | |
| 59 | − virtio_gpu_cmd_context_destroy(vgdev, ctx_id); | |
| 60 | − virtio_gpu_notify(vgdev); | |
| 61 | − ida_free(&vgdev->ctx_id_ida, ctx_id - 1); | |
| 62 | −} | |
| 63 | − | |
| 64 | 56 | static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq, |
| 65 | 57 | void (*work_func)(struct work_struct *work)) |
| 66 | 58 | { |
| @@ -275,14 +267,17 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) · 208 unmodified lines | ||
| 275 | 267 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file) |
| 276 | 268 | { |
| 277 | 269 | struct virtio_gpu_device *vgdev = dev->dev_private; |
| 278 | − struct virtio_gpu_fpriv *vfpriv; | |
| 270 | + struct virtio_gpu_fpriv *vfpriv = file->driver_priv; | |
| 279 | 271 | |
| 280 | 272 | if (!vgdev->has_virgl_3d) |
| 281 | 273 | return; |
| 282 | 274 | |
| 283 | − vfpriv = file->driver_priv; | |
| 275 | + if (vfpriv->context_created) { | |
| 276 | + virtio_gpu_cmd_context_destroy(vgdev, vfpriv->ctx_id); | |
| 277 | + virtio_gpu_notify(vgdev); | |
| 278 | + } | |
| 284 | 279 | |
| 285 | − virtio_gpu_context_destroy(vgdev, vfpriv->ctx_id); | |
| 280 | + ida_free(&vgdev->ctx_id_ida, vfpriv->ctx_id - 1); | |
| 286 | 281 | mutex_destroy(&vfpriv->context_lock); |
| 287 | 282 | kfree(vfpriv); |
| 288 | 283 | file->driver_priv = NULL; |
| @@ -1155,6 +1155,7 @@ config HID_ALPS · 1154 unmodified lines | ||
| 1155 | 1155 | config HID_MCP2221 |
| 1156 | 1156 | tristate "Microchip MCP2221 HID USB-to-I2C/SMbus host support" |
| 1157 | 1157 | depends on USB_HID && I2C |
| 1158 | + depends on GPIOLIB | |
| 1158 | 1159 | ---help--- |
| 1159 | 1160 | Provides I2C and SMBUS host adapter functionality over USB-HID |
| 1160 | 1161 | through MCP2221 device. |
| @@ -802,6 +802,7 @@ static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id) · 801 unmodified lines | ||
| 802 | 802 | break; |
| 803 | 803 | case HID_DEVICE_ID_ALPS_U1_DUAL: |
| 804 | 804 | case HID_DEVICE_ID_ALPS_U1: |
| 805 | + case HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY: | |
| 805 | 806 | data->dev_type = U1; |
| 806 | 807 | break; |
| 807 | 808 | default: |
| @@ -79,10 +79,10 @@ · 78 unmodified lines | ||
| 79 | 79 | #define HID_DEVICE_ID_ALPS_U1_DUAL_PTP 0x121F |
| 80 | 80 | #define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP 0x1220 |
| 81 | 81 | #define HID_DEVICE_ID_ALPS_U1 0x1215 |
| 82 | +#define HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY 0x121E | |
| 82 | 83 | #define HID_DEVICE_ID_ALPS_T4_BTNLESS 0x120C |
| 83 | 84 | #define HID_DEVICE_ID_ALPS_1222 0x1222 |
| 84 | 85 | |
| 85 | − | |
| 86 | 86 | #define USB_VENDOR_ID_AMI 0x046b |
| 87 | 87 | #define USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE 0xff10 |
| 88 | 88 | |
| @@ -385,6 +385,7 @@ · 296 unmodified lines | ||
| 385 | 385 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 |
| 386 | 386 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 |
| 387 | 387 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 |
| 388 | +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002 0xc002 | |
| 388 | 389 | |
| 389 | 390 | #define USB_VENDOR_ID_ELAN 0x04f3 |
| 390 | 391 | #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 |
| @@ -759,6 +760,7 @@ · 368 unmodified lines | ||
| 759 | 760 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 |
| 760 | 761 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 |
| 761 | 762 | #define USB_DEVICE_ID_LOGITECH_G15_LCD 0xc222 |
| 763 | +#define USB_DEVICE_ID_LOGITECH_G11 0xc225 | |
| 762 | 764 | #define USB_DEVICE_ID_LOGITECH_G15_V2_LCD 0xc227 |
| 763 | 765 | #define USB_DEVICE_ID_LOGITECH_G510 0xc22d |
| 764 | 766 | #define USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO 0xc22e |
| @@ -1097,6 +1099,9 @@ · 332 unmodified lines | ||
| 1097 | 1099 | #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 |
| 1098 | 1100 | #define USB_DEVICE_ID_SYMBOL_SCANNER_3 0x1200 |
| 1099 | 1101 | |
| 1102 | +#define I2C_VENDOR_ID_SYNAPTICS 0x06cb | |
| 1103 | +#define I2C_PRODUCT_ID_SYNAPTICS_SYNA2393 0x7a13 | |
| 1104 | + | |
| 1100 | 1105 | #define USB_VENDOR_ID_SYNAPTICS 0x06cb |
| 1101 | 1106 | #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 |
| 1102 | 1107 | #define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 |
| @@ -1111,6 +1116,7 @@ · 8 unmodified lines | ||
| 1111 | 1116 | #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 |
| 1112 | 1117 | #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 |
| 1113 | 1118 | #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 |
| 1119 | +#define USB_DEVICE_ID_SYNAPTICS_DELL_K12A 0x2819 | |
| 1114 | 1120 | #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968 |
| 1115 | 1121 | #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 |
| 1116 | 1122 | #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7 |
| @@ -872,6 +872,10 @@ error_hw_stop: · 871 unmodified lines | ||
| 872 | 872 | } |
| 873 | 873 | |
| 874 | 874 | static const struct hid_device_id lg_g15_devices[] = { |
| 875 | + /* The G11 is a G15 without the LCD, treat it as a G15 */ | |
| 876 | + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | |
| 877 | + USB_DEVICE_ID_LOGITECH_G11), | |
| 878 | + .driver_data = LG_G15 }, | |
| 875 | 879 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 876 | 880 | USB_DEVICE_ID_LOGITECH_G15_LCD), |
| 877 | 881 | .driver_data = LG_G15 }, |
| @@ -1922,6 +1922,9 @@ static const struct hid_device_id mt_devices[] = { · 1921 unmodified lines | ||
| 1922 | 1922 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
| 1923 | 1923 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
| 1924 | 1924 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, |
| 1925 | + { .driver_data = MT_CLS_EGALAX, | |
| 1926 | + MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | |
| 1927 | + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002) }, | |
| 1925 | 1928 | |
| 1926 | 1929 | /* Elitegroup panel */ |
| 1927 | 1930 | { .driver_data = MT_CLS_SERIAL, |
| @@ -163,6 +163,7 @@ static const struct hid_device_id hid_quirks[] = { · 162 unmodified lines | ||
| 163 | 163 | { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2), HID_QUIRK_NO_INIT_REPORTS }, |
| 164 | 164 | { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD), HID_QUIRK_NO_INIT_REPORTS }, |
| 165 | 165 | { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103), HID_QUIRK_NO_INIT_REPORTS }, |
| 166 | + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K12A), HID_QUIRK_NO_INIT_REPORTS }, | |
| 166 | 167 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD), HID_QUIRK_BADPAD }, |
| 167 | 168 | { HID_USB_DEVICE(USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS), HID_QUIRK_MULTI_INPUT }, |
| 168 | 169 | { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882), HID_QUIRK_NOGET }, |
| @@ -177,6 +177,8 @@ static const struct i2c_hid_quirks { · 176 unmodified lines | ||
| 177 | 177 | I2C_HID_QUIRK_BOGUS_IRQ }, |
| 178 | 178 | { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, |
| 179 | 179 | I2C_HID_QUIRK_RESET_ON_RESUME }, |
| 180 | + { I2C_VENDOR_ID_SYNAPTICS, I2C_PRODUCT_ID_SYNAPTICS_SYNA2393, | |
| 181 | + I2C_HID_QUIRK_RESET_ON_RESUME }, | |
| 180 | 182 | { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, |
| 181 | 183 | I2C_HID_QUIRK_BAD_INPUT_SIZE }, |
| 182 | 184 | { 0, 0 } |
| @@ -682,16 +682,21 @@ static int usbhid_open(struct hid_device *hid) · 681 unmodified lines | ||
| 682 | 682 | struct usbhid_device *usbhid = hid->driver_data; |
| 683 | 683 | int res; |
| 684 | 684 | |
| 685 | + mutex_lock(&usbhid->mutex); | |
| 686 | + | |
| 685 | 687 | set_bit(HID_OPENED, &usbhid->iofl); |
| 686 | 688 | |
| 687 | − if (hid->quirks & HID_QUIRK_ALWAYS_POLL) | |
| 688 | − return 0; | |
| 689 | + if (hid->quirks & HID_QUIRK_ALWAYS_POLL) { | |
| 690 | + res = 0; | |
| 691 | + goto Done; | |
| 692 | + } | |
| 689 | 693 | |
| 690 | 694 | res = usb_autopm_get_interface(usbhid->intf); |
| 691 | 695 | /* the device must be awake to reliably request remote wakeup */ |
| 692 | 696 | if (res < 0) { |
| 693 | 697 | clear_bit(HID_OPENED, &usbhid->iofl); |
| 694 | − return -EIO; | |
| 698 | + res = -EIO; | |
| 699 | + goto Done; | |
| 695 | 700 | } |
| 696 | 701 | |
| 697 | 702 | usbhid->intf->needs_remote_wakeup = 1; |
| @@ -725,6 +730,9 @@ static int usbhid_open(struct hid_device *hid) · 27 unmodified lines | ||
| 725 | 730 | msleep(50); |
| 726 | 731 | |
| 727 | 732 | clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); |
| 733 | + | |
| 734 | + Done: | |
| 735 | + mutex_unlock(&usbhid->mutex); | |
| 728 | 736 | return res; |
| 729 | 737 | } |
| 730 | 738 | |
| @@ -732,6 +740,8 @@ static void usbhid_close(struct hid_device *hid) · 1 unmodified line | ||
| 732 | 740 | { |
| 733 | 741 | struct usbhid_device *usbhid = hid->driver_data; |
| 734 | 742 | |
| 743 | + mutex_lock(&usbhid->mutex); | |
| 744 | + | |
| 735 | 745 | /* |
| 736 | 746 | * Make sure we don't restart data acquisition due to |
| 737 | 747 | * a resumption we no longer care about by avoiding racing |
| @@ -743,12 +753,13 @@ static void usbhid_close(struct hid_device *hid) · 5 unmodified lines | ||
| 743 | 753 | clear_bit(HID_IN_POLLING, &usbhid->iofl); |
| 744 | 754 | spin_unlock_irq(&usbhid->lock); |
| 745 | 755 | |
| 746 | − if (hid->quirks & HID_QUIRK_ALWAYS_POLL) | |
| 747 | − return; | |
| 756 | + if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) { | |
| 757 | + hid_cancel_delayed_stuff(usbhid); | |
| 758 | + usb_kill_urb(usbhid->urbin); | |
| 759 | + usbhid->intf->needs_remote_wakeup = 0; | |
| 760 | + } | |
| 748 | 761 | |
| 749 | − hid_cancel_delayed_stuff(usbhid); | |
| 750 | − usb_kill_urb(usbhid->urbin); | |
| 751 | − usbhid->intf->needs_remote_wakeup = 0; | |
| 762 | + mutex_unlock(&usbhid->mutex); | |
| 752 | 763 | } |
| 753 | 764 | |
| 754 | 765 | /* |
| @@ -1057,6 +1068,8 @@ static int usbhid_start(struct hid_device *hid) · 302 unmodified lines | ||
| 1057 | 1068 | unsigned int n, insize = 0; |
| 1058 | 1069 | int ret; |
| 1059 | 1070 | |
| 1071 | + mutex_lock(&usbhid->mutex); | |
| 1072 | + | |
| 1060 | 1073 | clear_bit(HID_DISCONNECTED, &usbhid->iofl); |
| 1061 | 1074 | |
| 1062 | 1075 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; |
| @@ -1177,6 +1190,8 @@ static int usbhid_start(struct hid_device *hid) · 114 unmodified lines | ||
| 1177 | 1190 | usbhid_set_leds(hid); |
| 1178 | 1191 | device_set_wakeup_enable(&dev->dev, 1); |
| 1179 | 1192 | } |
| 1193 | + | |
| 1194 | + mutex_unlock(&usbhid->mutex); | |
| 1180 | 1195 | return 0; |
| 1181 | 1196 | |
| 1182 | 1197 | fail: |
| @@ -1187,6 +1202,7 @@ fail: · 4 unmodified lines | ||
| 1187 | 1202 | usbhid->urbout = NULL; |
| 1188 | 1203 | usbhid->urbctrl = NULL; |
| 1189 | 1204 | hid_free_buffers(dev, hid); |
| 1205 | + mutex_unlock(&usbhid->mutex); | |
| 1190 | 1206 | return ret; |
| 1191 | 1207 | } |
| 1192 | 1208 | |
| @@ -1202,6 +1218,8 @@ static void usbhid_stop(struct hid_device *hid) · 9 unmodified lines | ||
| 1202 | 1218 | usbhid->intf->needs_remote_wakeup = 0; |
| 1203 | 1219 | } |
| 1204 | 1220 | |
| 1221 | + mutex_lock(&usbhid->mutex); | |
| 1222 | + | |
| 1205 | 1223 | clear_bit(HID_STARTED, &usbhid->iofl); |
| 1206 | 1224 | spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */ |
| 1207 | 1225 | set_bit(HID_DISCONNECTED, &usbhid->iofl); |
| @@ -1222,6 +1240,8 @@ static void usbhid_stop(struct hid_device *hid) · 14 unmodified lines | ||
| 1222 | 1240 | usbhid->urbout = NULL; |
| 1223 | 1241 | |
| 1224 | 1242 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
| 1243 | + | |
| 1244 | + mutex_unlock(&usbhid->mutex); | |
| 1225 | 1245 | } |
| 1226 | 1246 | |
| 1227 | 1247 | static int usbhid_power(struct hid_device *hid, int lvl) |
| @@ -1382,6 +1402,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * · 154 unmodified lines | ||
| 1382 | 1402 | INIT_WORK(&usbhid->reset_work, hid_reset); |
| 1383 | 1403 | timer_setup(&usbhid->io_retry, hid_retry_timeout, 0); |
| 1384 | 1404 | spin_lock_init(&usbhid->lock); |
| 1405 | + mutex_init(&usbhid->mutex); | |
| 1385 | 1406 | |
| 1386 | 1407 | ret = hid_add_device(hid); |
| 1387 | 1408 | if (ret) { |
| @@ -80,6 +80,7 @@ struct usbhid_device { · 79 unmodified lines | ||
| 80 | 80 | dma_addr_t outbuf_dma; /* Output buffer dma */ |
| 81 | 81 | unsigned long last_out; /* record of last output for timeouts */ |
| 82 | 82 | |
| 83 | + struct mutex mutex; /* start/stop/open/close */ | |
| 83 | 84 | spinlock_t lock; /* fifo spinlock */ |
| 84 | 85 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ |
| 85 | 86 | struct timer_list io_retry; /* Retry timer */ |
| @@ -319,9 +319,11 @@ static void wacom_feature_mapping(struct hid_device *hdev, · 318 unmodified lines | ||
| 319 | 319 | data[0] = field->report->id; |
| 320 | 320 | ret = wacom_get_report(hdev, HID_FEATURE_REPORT, |
| 321 | 321 | data, n, WAC_CMD_RETRIES); |
| 322 | − if (ret == n) { | |
| 322 | + if (ret == n && features->type == HID_GENERIC) { | |
| 323 | 323 | ret = hid_report_raw_event(hdev, |
| 324 | 324 | HID_FEATURE_REPORT, data, n, 0); |
| 325 | + } else if (ret == 2 && features->type != HID_GENERIC) { | |
| 326 | + features->touch_max = data[1]; | |
| 325 | 327 | } else { |
| 326 | 328 | features->touch_max = 16; |
| 327 | 329 | hid_warn(hdev, "wacom_feature_mapping: " |
| @@ -1427,11 +1427,13 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom) · 1426 unmodified lines | ||
| 1427 | 1427 | { |
| 1428 | 1428 | struct input_dev *pad_input = wacom->pad_input; |
| 1429 | 1429 | unsigned char *data = wacom->data; |
| 1430 | + int nbuttons = wacom->features.numbered_buttons; | |
| 1430 | 1431 | |
| 1431 | − int buttons = data[282] | ((data[281] & 0x40) << 2); | |
| 1432 | + int expresskeys = data[282]; | |
| 1433 | + int center = (data[281] & 0x40) >> 6; | |
| 1432 | 1434 | int ring = data[285] & 0x7F; |
| 1433 | 1435 | bool ringstatus = data[285] & 0x80; |
| 1434 | − bool prox = buttons || ringstatus; | |
| 1436 | + bool prox = expresskeys || center || ringstatus; | |
| 1435 | 1437 | |
| 1436 | 1438 | /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ |
| 1437 | 1439 | ring = 71 - ring; |
| @@ -1439,7 +1441,8 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom) · 1 unmodified line | ||
| 1439 | 1441 | if (ring > 71) |
| 1440 | 1442 | ring -= 72; |
| 1441 | 1443 | |
| 1442 | − wacom_report_numbered_buttons(pad_input, 9, buttons); | |
| 1444 | + wacom_report_numbered_buttons(pad_input, nbuttons, | |
| 1445 | + expresskeys | (center << (nbuttons - 1))); | |
| 1443 | 1446 | |
| 1444 | 1447 | input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); |
| 1445 | 1448 | |
| @@ -2637,9 +2640,25 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, · 1191 unmodified lines | ||
| 2637 | 2640 | case HID_DG_TIPSWITCH: |
| 2638 | 2641 | hid_data->last_slot_field = equivalent_usage; |
| 2639 | 2642 | break; |
| 2643 | + case HID_DG_CONTACTCOUNT: | |
| 2644 | + hid_data->cc_report = report->id; | |
| 2645 | + hid_data->cc_index = i; | |
| 2646 | + hid_data->cc_value_index = j; | |
| 2647 | + break; | |
| 2640 | 2648 | } |
| 2641 | 2649 | } |
| 2642 | 2650 | } |
| 2651 | + | |
| 2652 | + if (hid_data->cc_report != 0 && | |
| 2653 | + hid_data->cc_index >= 0) { | |
| 2654 | + struct hid_field *field = report->field[hid_data->cc_index]; | |
| 2655 | + int value = field->value[hid_data->cc_value_index]; | |
| 2656 | + if (value) | |
| 2657 | + hid_data->num_expected = value; | |
| 2658 | + } | |
| 2659 | + else { | |
| 2660 | + hid_data->num_expected = wacom_wac->features.touch_max; | |
| 2661 | + } | |
| 2643 | 2662 | } |
| 2644 | 2663 | |
| 2645 | 2664 | static void wacom_wac_finger_report(struct hid_device *hdev, |
| @@ -2649,7 +2668,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev, · 3 unmodified lines | ||
| 2649 | 2668 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
| 2650 | 2669 | struct input_dev *input = wacom_wac->touch_input; |
| 2651 | 2670 | unsigned touch_max = wacom_wac->features.touch_max; |
| 2652 | − struct hid_data *hid_data = &wacom_wac->hid_data; | |
| 2653 | 2671 | |
| 2654 | 2672 | /* If more packets of data are expected, give us a chance to |
| 2655 | 2673 | * process them rather than immediately syncing a partial |
| @@ -2663,7 +2681,6 @@ static void wacom_wac_finger_report(struct hid_device *hdev, · 7 unmodified lines | ||
| 2663 | 2681 | |
| 2664 | 2682 | input_sync(input); |
| 2665 | 2683 | wacom_wac->hid_data.num_received = 0; |
| 2666 | − hid_data->num_expected = 0; | |
| 2667 | 2684 | |
| 2668 | 2685 | /* keep touch state for pen event */ |
| 2669 | 2686 | wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac); |
| @@ -2738,73 +2755,12 @@ static void wacom_report_events(struct hid_device *hdev, · 68 unmodified lines | ||
| 2738 | 2755 | } |
| 2739 | 2756 | } |
| 2740 | 2757 | |
| 2741 | −static void wacom_set_num_expected(struct hid_device *hdev, | |
| 2742 | − struct hid_report *report, | |
| 2743 | − int collection_index, | |
| 2744 | − struct hid_field *field, | |
| 2745 | − int field_index) | |
| 2746 | −{ | |
| 2747 | − struct wacom *wacom = hid_get_drvdata(hdev); | |
| 2748 | − struct wacom_wac *wacom_wac = &wacom->wacom_wac; | |
| 2749 | − struct hid_data *hid_data = &wacom_wac->hid_data; | |
| 2750 | − unsigned int original_collection_level = | |
| 2751 | − hdev->collection[collection_index].level; | |
| 2752 | − bool end_collection = false; | |
| 2753 | − int i; | |
| 2754 | − | |
| 2755 | − if (hid_data->num_expected) | |
| 2756 | − return; | |
| 2757 | − | |
| 2758 | − // find the contact count value for this segment | |
| 2759 | − for (i = field_index; i < report->maxfield && !end_collection; i++) { | |
| 2760 | − struct hid_field *field = report->field[i]; | |
| 2761 | − unsigned int field_level = | |
| 2762 | − hdev->collection[field->usage[0].collection_index].level; | |
| 2763 | − unsigned int j; | |
| 2764 | − | |
| 2765 | − if (field_level != original_collection_level) | |
| 2766 | − continue; | |
| 2767 | − | |
| 2768 | − for (j = 0; j < field->maxusage; j++) { | |
| 2769 | − struct hid_usage *usage = &field->usage[j]; | |
| 2770 | − | |
| 2771 | − if (usage->collection_index != collection_index) { | |
| 2772 | − end_collection = true; | |
| 2773 | − break; | |
| 2774 | − } | |
| 2775 | − if (wacom_equivalent_usage(usage->hid) == HID_DG_CONTACTCOUNT) { | |
| 2776 | − hid_data->cc_report = report->id; | |
| 2777 | − hid_data->cc_index = i; | |
| 2778 | − hid_data->cc_value_index = j; | |
| 2779 | − | |
| 2780 | − if (hid_data->cc_report != 0 && | |
| 2781 | − hid_data->cc_index >= 0) { | |
| 2782 | − | |
| 2783 | − struct hid_field *field = | |
| 2784 | − report->field[hid_data->cc_index]; | |
| 2785 | − int value = | |
| 2786 | − field->value[hid_data->cc_value_index]; | |
| 2787 | − | |
| 2788 | − if (value) | |
| 2789 | − hid_data->num_expected = value; | |
| 2790 | − } | |
| 2791 | − } | |
| 2792 | − } | |
| 2793 | − } | |
| 2794 | − | |
| 2795 | − if (hid_data->cc_report == 0 || hid_data->cc_index < 0) | |
| 2796 | − hid_data->num_expected = wacom_wac->features.touch_max; | |
| 2797 | −} | |
| 2798 | − | |
| 2799 | 2758 | static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report, |
| 2800 | 2759 | int collection_index, struct hid_field *field, |
| 2801 | 2760 | int field_index) |
| 2802 | 2761 | { |
| 2803 | 2762 | struct wacom *wacom = hid_get_drvdata(hdev); |
| 2804 | 2763 | |
| 2805 | − if (WACOM_FINGER_FIELD(field)) | |
| 2806 | − wacom_set_num_expected(hdev, report, collection_index, field, | |
| 2807 | − field_index); | |
| 2808 | 2764 | wacom_report_events(hdev, report, collection_index, field_index); |
| 2809 | 2765 | |
| 2810 | 2766 | /* |
| @@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu) · 183 unmodified lines | ||
| 184 | 184 | |
| 185 | 185 | shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR; |
| 186 | 186 | shared_sint.masked = false; |
| 187 | − if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED) | |
| 188 | − shared_sint.auto_eoi = false; | |
| 189 | − else | |
| 190 | − shared_sint.auto_eoi = true; | |
| 191 | − | |
| 187 | + shared_sint.auto_eoi = hv_recommend_using_aeoi(); | |
| 192 | 188 | hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); |
| 193 | 189 | |
| 194 | 190 | /* Enable the global synic bit */ |
| @@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request, · 285 unmodified lines | ||
| 286 | 286 | __field(int, ret) |
| 287 | 287 | ), |
| 288 | 288 | TP_fast_assign( |
| 289 | − memcpy(__entry->guest_id, &msg->guest_endpoint_id.b, 16); | |
| 290 | − memcpy(__entry->host_id, &msg->host_service_id.b, 16); | |
| 289 | + export_guid(__entry->guest_id, &msg->guest_endpoint_id); | |
| 290 | + export_guid(__entry->host_id, &msg->host_service_id); | |
| 291 | 291 | __entry->ret = ret; |
| 292 | 292 | ), |
| 293 | 293 | TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, " |
| @@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device) · 977 unmodified lines | ||
| 978 | 978 | |
| 979 | 979 | return drv->resume(dev); |
| 980 | 980 | } |
| 981 | +#else | |
| 982 | +#define vmbus_suspend NULL | |
| 983 | +#define vmbus_resume NULL | |
| 981 | 984 | #endif /* CONFIG_PM_SLEEP */ |
| 982 | 985 | |
| 983 | 986 | /* |
| @@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device) · 13 unmodified lines | ||
| 997 | 1000 | } |
| 998 | 1001 | |
| 999 | 1002 | /* |
| 1000 | − * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than | |
| 1001 | − * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm. | |
| 1003 | + * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm. | |
| 1004 | + * | |
| 1005 | + * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we | |
| 1006 | + * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there | |
| 1007 | + * is no way to wake up a Generation-2 VM. | |
| 1008 | + * | |
| 1009 | + * The other 4 ops are for hibernation. | |
| 1002 | 1010 | */ |
| 1011 | + | |
| 1003 | 1012 | static const struct dev_pm_ops vmbus_pm = { |
| 1004 | − SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume) | |
| 1013 | + .suspend_noirq = NULL, | |
| 1014 | + .resume_noirq = NULL, | |
| 1015 | + .freeze_noirq = vmbus_suspend, | |
| 1016 | + .thaw_noirq = vmbus_resume, | |
| 1017 | + .poweroff_noirq = vmbus_suspend, | |
| 1018 | + .restore_noirq = vmbus_resume, | |
| 1005 | 1019 | }; |
| 1006 | 1020 | |
| 1007 | 1021 | /* The one and only one */ |
| @@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev) · 1273 unmodified lines | ||
| 2281 | 2295 | |
| 2282 | 2296 | return 0; |
| 2283 | 2297 | } |
| 2298 | +#else | |
| 2299 | +#define vmbus_bus_suspend NULL | |
| 2300 | +#define vmbus_bus_resume NULL | |
| 2284 | 2301 | #endif /* CONFIG_PM_SLEEP */ |
| 2285 | 2302 | |
| 2286 | 2303 | static const struct acpi_device_id vmbus_acpi_device_ids[] = { |
| @@ -2291,16 +2308,24 @@ static const struct acpi_device_id vmbus_acpi_device_ids[] = { · 4 unmodified lines | ||
| 2291 | 2308 | MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); |
| 2292 | 2309 | |
| 2293 | 2310 | /* |
| 2294 | − * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than | |
| 2295 | − * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the | |
| 2296 | − * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the | |
| 2297 | − * pci "noirq" restore callback runs before "non-noirq" callbacks (see | |
| 2311 | + * Note: we must use the "no_irq" ops, otherwise hibernation can not work with | |
| 2312 | + * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in | |
| 2313 | + * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see | |
| 2298 | 2314 | * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() -> |
| 2299 | 2315 | * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's |
| 2300 | − * resume callback must also run via the "noirq" callbacks. | |
| 2316 | + * resume callback must also run via the "noirq" ops. | |
| 2317 | + * | |
| 2318 | + * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment | |
| 2319 | + * earlier in this file before vmbus_pm. | |
| 2301 | 2320 | */ |
| 2321 | + | |
| 2302 | 2322 | static const struct dev_pm_ops vmbus_bus_pm = { |
| 2303 | − SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume) | |
| 2323 | + .suspend_noirq = NULL, | |
| 2324 | + .resume_noirq = NULL, | |
| 2325 | + .freeze_noirq = vmbus_bus_suspend, | |
| 2326 | + .thaw_noirq = vmbus_bus_resume, | |
| 2327 | + .poweroff_noirq = vmbus_bus_suspend, | |
| 2328 | + .restore_noirq = vmbus_bus_resume | |
| 2304 | 2329 | }; |
| 2305 | 2330 | |
| 2306 | 2331 | static struct acpi_driver vmbus_acpi_driver = { |
| @@ -349,12 +349,12 @@ static int amd_mp2_pci_probe(struct pci_dev *pci_dev, · 348 unmodified lines | ||
| 349 | 349 | if (!privdata) |
| 350 | 350 | return -ENOMEM; |
| 351 | 351 | |
| 352 | + privdata->pci_dev = pci_dev; | |
| 352 | 353 | rc = amd_mp2_pci_init(privdata, pci_dev); |
| 353 | 354 | if (rc) |
| 354 | 355 | return rc; |
| 355 | 356 | |
| 356 | 357 | mutex_init(&privdata->c2p_lock); |
| 357 | − privdata->pci_dev = pci_dev; | |
| 358 | 358 | |
| 359 | 359 | pm_runtime_set_autosuspend_delay(&pci_dev->dev, 1000); |
| 360 | 360 | pm_runtime_use_autosuspend(&pci_dev->dev); |
| @@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) · 602 unmodified lines | ||
| 603 | 603 | /* Ack all interrupts except for Rx done */ |
| 604 | 604 | writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE, |
| 605 | 605 | bus->base + ASPEED_I2C_INTR_STS_REG); |
| 606 | + readl(bus->base + ASPEED_I2C_INTR_STS_REG); | |
| 606 | 607 | irq_remaining = irq_received; |
| 607 | 608 | |
| 608 | 609 | #if IS_ENABLED(CONFIG_I2C_SLAVE) |
| @@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) · 36 unmodified lines | ||
| 645 | 646 | irq_received, irq_handled); |
| 646 | 647 | |
| 647 | 648 | /* Ack Rx done */ |
| 648 | − if (irq_received & ASPEED_I2CD_INTR_RX_DONE) | |
| 649 | + if (irq_received & ASPEED_I2CD_INTR_RX_DONE) { | |
| 649 | 650 | writel(ASPEED_I2CD_INTR_RX_DONE, |
| 650 | 651 | bus->base + ASPEED_I2C_INTR_STS_REG); |
| 652 | + readl(bus->base + ASPEED_I2C_INTR_STS_REG); | |
| 653 | + } | |
| 651 | 654 | spin_unlock(&bus->lock); |
| 652 | 655 | return irq_remaining ? IRQ_NONE : IRQ_HANDLED; |
| 653 | 656 | } |
| @@ -360,6 +360,9 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, · 359 unmodified lines | ||
| 360 | 360 | value = (u8)((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK); |
| 361 | 361 | i2c_slave_event(iproc_i2c->slave, |
| 362 | 362 | I2C_SLAVE_WRITE_RECEIVED, &value); |
| 363 | + if (rx_status == I2C_SLAVE_RX_END) | |
| 364 | + i2c_slave_event(iproc_i2c->slave, | |
| 365 | + I2C_SLAVE_STOP, &value); | |
| 363 | 366 | } |
| 364 | 367 | } else if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { |
| 365 | 368 | /* Master read other than start */ |
| @@ -996,13 +996,14 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev, · 995 unmodified lines | ||
| 996 | 996 | do { |
| 997 | 997 | u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS); |
| 998 | 998 | |
| 999 | − if (status) | |
| 999 | + if (status) { | |
| 1000 | 1000 | tegra_i2c_isr(i2c_dev->irq, i2c_dev); |
| 1001 | 1001 | |
| 1002 | − if (completion_done(complete)) { | |
| 1003 | − s64 delta = ktime_ms_delta(ktimeout, ktime); | |
| 1002 | + if (completion_done(complete)) { | |
| 1003 | + s64 delta = ktime_ms_delta(ktimeout, ktime); | |
| 1004 | 1004 | |
| 1005 | − return msecs_to_jiffies(delta) ?: 1; | |
| 1005 | + return msecs_to_jiffies(delta) ?: 1; | |
| 1006 | + } | |
| 1006 | 1007 | } |
| 1007 | 1008 | |
| 1008 | 1009 | ktime = ktime_get(); |
| @@ -1029,18 +1030,14 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev, · 20 unmodified lines | ||
| 1029 | 1030 | disable_irq(i2c_dev->irq); |
| 1030 | 1031 | |
| 1031 | 1032 | /* |
| 1032 | − * Under some rare circumstances (like running KASAN + | |
| 1033 | − * NFS root) CPU, which handles interrupt, may stuck in | |
| 1034 | − * uninterruptible state for a significant time. In this | |
| 1035 | − * case we will get timeout if I2C transfer is running on | |
| 1036 | − * a sibling CPU, despite of IRQ being raised. | |
| 1037 | − * | |
| 1038 | − * In order to handle this rare condition, the IRQ status | |
| 1039 | − * needs to be checked after timeout. | |
| 1033 | + * There is a chance that completion may happen after IRQ | |
| 1034 | + * synchronization, which is done by disable_irq(). | |
| 1040 | 1035 | */ |
| 1041 | − if (ret == 0) | |
| 1042 | − ret = tegra_i2c_poll_completion_timeout(i2c_dev, | |
| 1043 | − complete, 0); | |
| 1036 | + if (ret == 0 && completion_done(complete)) { | |
| 1037 | + dev_warn(i2c_dev->dev, | |
| 1038 | + "completion done after timeout\n"); | |
| 1039 | + ret = 1; | |
| 1040 | + } | |
| 1044 | 1041 | } |
| 1045 | 1042 | |
| 1046 | 1043 | return ret; |
| @@ -1219,15 +1216,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, · 172 unmodified lines | ||
| 1219 | 1216 | time_left = tegra_i2c_wait_completion_timeout( |
| 1220 | 1217 | i2c_dev, &i2c_dev->dma_complete, xfer_time); |
| 1221 | 1218 | |
| 1222 | − /* | |
| 1223 | − * Synchronize DMA first, since dmaengine_terminate_sync() | |
| 1224 | − * performs synchronization after the transfer's termination | |
| 1225 | − * and we want to get a completion if transfer succeeded. | |
| 1226 | − */ | |
| 1227 | − dmaengine_synchronize(i2c_dev->msg_read ? | |
| 1228 | − i2c_dev->rx_dma_chan : | |
| 1229 | − i2c_dev->tx_dma_chan); | |
| 1230 | − | |
| 1231 | 1219 | dmaengine_terminate_sync(i2c_dev->msg_read ? |
| 1232 | 1220 | i2c_dev->rx_dma_chan : |
| 1233 | 1221 | i2c_dev->tx_dma_chan); |
| @@ -862,7 +862,7 @@ static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device, · 861 unmodified lines | ||
| 862 | 862 | |
| 863 | 863 | ret = xa_alloc_cyclic_irq(&cm.local_id_table, &id, NULL, xa_limit_32b, |
| 864 | 864 | &cm.local_id_next, GFP_KERNEL); |
| 865 | − if (ret) | |
| 865 | + if (ret < 0) | |
| 866 | 866 | goto error; |
| 867 | 867 | cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; |
| 868 | 868 | |
| @@ -1828,11 +1828,9 @@ static void cm_format_mra(struct cm_mra_msg *mra_msg, · 959 unmodified lines | ||
| 1828 | 1828 | |
| 1829 | 1829 | static void cm_format_rej(struct cm_rej_msg *rej_msg, |
| 1830 | 1830 | struct cm_id_private *cm_id_priv, |
| 1831 | − enum ib_cm_rej_reason reason, | |
| 1832 | − void *ari, | |
| 1833 | − u8 ari_length, | |
| 1834 | − const void *private_data, | |
| 1835 | − u8 private_data_len) | |
| 1831 | + enum ib_cm_rej_reason reason, void *ari, | |
| 1832 | + u8 ari_length, const void *private_data, | |
| 1833 | + u8 private_data_len, enum ib_cm_state state) | |
| 1836 | 1834 | { |
| 1837 | 1835 | lockdep_assert_held(&cm_id_priv->lock); |
| 1838 | 1836 | |
| @@ -1840,7 +1838,7 @@ static void cm_format_rej(struct cm_rej_msg *rej_msg, · 1 unmodified line | ||
| 1840 | 1838 | IBA_SET(CM_REJ_REMOTE_COMM_ID, rej_msg, |
| 1841 | 1839 | be32_to_cpu(cm_id_priv->id.remote_id)); |
| 1842 | 1840 | |
| 1843 | − switch(cm_id_priv->id.state) { | |
| 1841 | + switch (state) { | |
| 1844 | 1842 | case IB_CM_REQ_RCVD: |
| 1845 | 1843 | IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, be32_to_cpu(0)); |
| 1846 | 1844 | IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REQ); |
| @@ -1905,8 +1903,9 @@ static void cm_dup_req_handler(struct cm_work *work, · 58 unmodified lines | ||
| 1905 | 1903 | cm_id_priv->private_data_len); |
| 1906 | 1904 | break; |
| 1907 | 1905 | case IB_CM_TIMEWAIT: |
| 1908 | − cm_format_rej((struct cm_rej_msg *) msg->mad, cm_id_priv, | |
| 1909 | − IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0); | |
| 1906 | + cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, | |
| 1907 | + IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0, | |
| 1908 | + IB_CM_TIMEWAIT); | |
| 1910 | 1909 | break; |
| 1911 | 1910 | default: |
| 1912 | 1911 | goto unlock; |
| @@ -2904,6 +2903,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 991 unmodified lines | ||
| 2904 | 2903 | u8 ari_length, const void *private_data, |
| 2905 | 2904 | u8 private_data_len) |
| 2906 | 2905 | { |
| 2906 | + enum ib_cm_state state = cm_id_priv->id.state; | |
| 2907 | 2907 | struct ib_mad_send_buf *msg; |
| 2908 | 2908 | int ret; |
| 2909 | 2909 | |
| @@ -2913,7 +2913,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 3 unmodified lines | ||
| 2913 | 2913 | (ari && ari_length > IB_CM_REJ_ARI_LENGTH)) |
| 2914 | 2914 | return -EINVAL; |
| 2915 | 2915 | |
| 2916 | − switch (cm_id_priv->id.state) { | |
| 2916 | + switch (state) { | |
| 2917 | 2917 | case IB_CM_REQ_SENT: |
| 2918 | 2918 | case IB_CM_MRA_REQ_RCVD: |
| 2919 | 2919 | case IB_CM_REQ_RCVD: |
| @@ -2925,7 +2925,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 5 unmodified lines | ||
| 2925 | 2925 | if (ret) |
| 2926 | 2926 | return ret; |
| 2927 | 2927 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
| 2928 | − ari, ari_length, private_data, private_data_len); | |
| 2928 | + ari, ari_length, private_data, private_data_len, | |
| 2929 | + state); | |
| 2929 | 2930 | break; |
| 2930 | 2931 | case IB_CM_REP_SENT: |
| 2931 | 2932 | case IB_CM_MRA_REP_RCVD: |
| @@ -2934,7 +2935,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 2 unmodified lines | ||
| 2934 | 2935 | if (ret) |
| 2935 | 2936 | return ret; |
| 2936 | 2937 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
| 2937 | − ari, ari_length, private_data, private_data_len); | |
| 2938 | + ari, ari_length, private_data, private_data_len, | |
| 2939 | + state); | |
| 2938 | 2940 | break; |
| 2939 | 2941 | default: |
| 2940 | 2942 | pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__, |
| @@ -360,7 +360,7 @@ lookup_get_fd_uobject(const struct uverbs_api_object *obj, · 359 unmodified lines | ||
| 360 | 360 | * uverbs_uobject_fd_release(), and the caller is expected to ensure |
| 361 | 361 | * that release is never done while a call to lookup is possible. |
| 362 | 362 | */ |
| 363 | − if (f->f_op != fd_type->fops) { | |
| 363 | + if (f->f_op != fd_type->fops || uobject->ufile != ufile) { | |
| 364 | 364 | fput(f); |
| 365 | 365 | return ERR_PTR(-EBADF); |
| 366 | 366 | } |
| @@ -474,16 +474,15 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj, · 107 unmodified lines | ||
| 474 | 474 | filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL, |
| 475 | 475 | fd_type->flags); |
| 476 | 476 | if (IS_ERR(filp)) { |
| 477 | + uverbs_uobject_put(uobj); | |
| 477 | 478 | uobj = ERR_CAST(filp); |
| 478 | − goto err_uobj; | |
| 479 | + goto err_fd; | |
| 479 | 480 | } |
| 480 | 481 | uobj->object = filp; |
| 481 | 482 | |
| 482 | 483 | uobj->id = new_fd; |
| 483 | 484 | return uobj; |
| 484 | 485 | |
| 485 | −err_uobj: | |
| 486 | − uverbs_uobject_put(uobj); | |
| 487 | 486 | err_fd: |
| 488 | 487 | put_unused_fd(new_fd); |
| 489 | 488 | return uobj; |
| @@ -679,7 +678,6 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj, · 189 unmodified lines | ||
| 679 | 678 | enum rdma_lookup_mode mode) |
| 680 | 679 | { |
| 681 | 680 | assert_uverbs_usecnt(uobj, mode); |
| 682 | − uobj->uapi_object->type_class->lookup_put(uobj, mode); | |
| 683 | 681 | /* |
| 684 | 682 | * In order to unlock an object, either decrease its usecnt for |
| 685 | 683 | * read access or zero it in case of exclusive access. See |
| @@ -696,6 +694,7 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj, · 10 unmodified lines | ||
| 696 | 694 | break; |
| 697 | 695 | } |
| 698 | 696 | |
| 697 | + uobj->uapi_object->type_class->lookup_put(uobj, mode); | |
| 699 | 698 | /* Pairs with the kref obtained by type->lookup_get */ |
| 700 | 699 | uverbs_uobject_put(uobj); |
| 701 | 700 | } |
| @@ -820,6 +820,10 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile) · 819 unmodified lines | ||
| 820 | 820 | ret = mmget_not_zero(mm); |
| 821 | 821 | if (!ret) { |
| 822 | 822 | list_del_init(&priv->list); |
| 823 | + if (priv->entry) { | |
| 824 | + rdma_user_mmap_entry_put(priv->entry); | |
| 825 | + priv->entry = NULL; | |
| 826 | + } | |
| 823 | 827 | mm = NULL; |
| 824 | 828 | continue; |
| 825 | 829 | } |
| @@ -1046,7 +1046,7 @@ i40iw_sc_query_rdma_features(struct i40iw_sc_cqp *cqp, · 1045 unmodified lines | ||
| 1046 | 1046 | u64 header; |
| 1047 | 1047 | |
| 1048 | 1048 | wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch); |
| 1049 | − if (wqe) | |
| 1049 | + if (!wqe) | |
| 1050 | 1050 | return I40IW_ERR_RING_FULL; |
| 1051 | 1051 | |
| 1052 | 1052 | set_64bit_val(wqe, 32, feat_mem->pa); |
| @@ -1499,8 +1499,9 @@ static int __mlx4_ib_create_default_rules( · 1498 unmodified lines | ||
| 1499 | 1499 | int i; |
| 1500 | 1500 | |
| 1501 | 1501 | for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) { |
| 1502 | + union ib_flow_spec ib_spec = {}; | |
| 1502 | 1503 | int ret; |
| 1503 | − union ib_flow_spec ib_spec; | |
| 1504 | + | |
| 1504 | 1505 | switch (pdefault_rules->rules_create_list[i]) { |
| 1505 | 1506 | case 0: |
| 1506 | 1507 | /* no rule */ |
| @@ -5558,7 +5558,9 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev, · 5557 unmodified lines | ||
| 5558 | 5558 | rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f); |
| 5559 | 5559 | rdma_ah_set_static_rate(ah_attr, |
| 5560 | 5560 | path->static_rate ? path->static_rate - 5 : 0); |
| 5561 | − if (path->grh_mlid & (1 << 7)) { | |
| 5561 | + | |
| 5562 | + if (path->grh_mlid & (1 << 7) || | |
| 5563 | + ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { | |
| 5562 | 5564 | u32 tc_fl = be32_to_cpu(path->tclass_flowlabel); |
| 5563 | 5565 | |
| 5564 | 5566 | rdma_ah_set_grh(ah_attr, NULL, |
| @@ -248,8 +248,8 @@ int rvt_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, · 247 unmodified lines | ||
| 248 | 248 | */ |
| 249 | 249 | if (udata && udata->outlen >= sizeof(__u64)) { |
| 250 | 250 | cq->ip = rvt_create_mmap_info(rdi, sz, udata, u_wc); |
| 251 | − if (!cq->ip) { | |
| 252 | − err = -ENOMEM; | |
| 251 | + if (IS_ERR(cq->ip)) { | |
| 252 | + err = PTR_ERR(cq->ip); | |
| 253 | 253 | goto bail_wc; |
| 254 | 254 | } |
| 255 | 255 | |
| @@ -154,7 +154,7 @@ done: · 153 unmodified lines | ||
| 154 | 154 | * @udata: user data (must be valid!) |
| 155 | 155 | * @obj: opaque pointer to a cq, wq etc |
| 156 | 156 | * |
| 157 | − * Return: rvt_mmap struct on success | |
| 157 | + * Return: rvt_mmap struct on success, ERR_PTR on failure | |
| 158 | 158 | */ |
| 159 | 159 | struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, |
| 160 | 160 | struct ib_udata *udata, void *obj) |
| @@ -166,7 +166,7 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, · 5 unmodified lines | ||
| 166 | 166 | |
| 167 | 167 | ip = kmalloc_node(sizeof(*ip), GFP_KERNEL, rdi->dparms.node); |
| 168 | 168 | if (!ip) |
| 169 | − return ip; | |
| 169 | + return ERR_PTR(-ENOMEM); | |
| 170 | 170 | |
| 171 | 171 | size = PAGE_ALIGN(size); |
| 172 | 172 | |
| @@ -1244,8 +1244,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, · 1243 unmodified lines | ||
| 1244 | 1244 | |
| 1245 | 1245 | qp->ip = rvt_create_mmap_info(rdi, s, udata, |
| 1246 | 1246 | qp->r_rq.wq); |
| 1247 | − if (!qp->ip) { | |
| 1248 | − ret = ERR_PTR(-ENOMEM); | |
| 1247 | + if (IS_ERR(qp->ip)) { | |
| 1248 | + ret = ERR_CAST(qp->ip); | |
| 1249 | 1249 | goto bail_qpn; |
| 1250 | 1250 | } |
| 1251 | 1251 | |
| @@ -111,8 +111,8 @@ int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr, · 110 unmodified lines | ||
| 111 | 111 | u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz; |
| 112 | 112 | |
| 113 | 113 | srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq); |
| 114 | − if (!srq->ip) { | |
| 115 | − ret = -ENOMEM; | |
| 114 | + if (IS_ERR(srq->ip)) { | |
| 115 | + ret = PTR_ERR(srq->ip); | |
| 116 | 116 | goto bail_wq; |
| 117 | 117 | } |
| 118 | 118 | |
| @@ -920,20 +920,27 @@ static int siw_fastreg_mr(struct ib_pd *pd, struct siw_sqe *sqe) · 919 unmodified lines | ||
| 920 | 920 | { |
| 921 | 921 | struct ib_mr *base_mr = (struct ib_mr *)(uintptr_t)sqe->base_mr; |
| 922 | 922 | struct siw_device *sdev = to_siw_dev(pd->device); |
| 923 | − struct siw_mem *mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); | |
| 923 | + struct siw_mem *mem; | |
| 924 | 924 | int rv = 0; |
| 925 | 925 | |
| 926 | 926 | siw_dbg_pd(pd, "STag 0x%08x\n", sqe->rkey); |
| 927 | 927 | |
| 928 | − if (unlikely(!mem || !base_mr)) { | |
| 928 | + if (unlikely(!base_mr)) { | |
| 929 | 929 | pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); |
| 930 | 930 | return -EINVAL; |
| 931 | 931 | } |
| 932 | + | |
| 932 | 933 | if (unlikely(base_mr->rkey >> 8 != sqe->rkey >> 8)) { |
| 933 | 934 | pr_warn("siw: fastreg: STag 0x%08x: bad MR\n", sqe->rkey); |
| 934 | − rv = -EINVAL; | |
| 935 | − goto out; | |
| 935 | + return -EINVAL; | |
| 936 | 936 | } |
| 937 | + | |
| 938 | + mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); | |
| 939 | + if (unlikely(!mem)) { | |
| 940 | + pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); | |
| 941 | + return -EINVAL; | |
| 942 | + } | |
| 943 | + | |
| 937 | 944 | if (unlikely(mem->pd != pd)) { |
| 938 | 945 | pr_warn("siw: fastreg: PD mismatch\n"); |
| 939 | 946 | rv = -EINVAL; |
| @@ -78,7 +78,7 @@ static struct qcom_icc_node *sdm845_osm_l3_nodes[] = { · 77 unmodified lines | ||
| 78 | 78 | [SLAVE_OSM_L3] = &sdm845_osm_l3, |
| 79 | 79 | }; |
| 80 | 80 | |
| 81 | −const static struct qcom_icc_desc sdm845_icc_osm_l3 = { | |
| 81 | +static const struct qcom_icc_desc sdm845_icc_osm_l3 = { | |
| 82 | 82 | .nodes = sdm845_osm_l3_nodes, |
| 83 | 83 | .num_nodes = ARRAY_SIZE(sdm845_osm_l3_nodes), |
| 84 | 84 | }; |
| @@ -91,7 +91,7 @@ static struct qcom_icc_node *sc7180_osm_l3_nodes[] = { · 6 unmodified lines | ||
| 91 | 91 | [SLAVE_OSM_L3] = &sc7180_osm_l3, |
| 92 | 92 | }; |
| 93 | 93 | |
| 94 | −const static struct qcom_icc_desc sc7180_icc_osm_l3 = { | |
| 94 | +static const struct qcom_icc_desc sc7180_icc_osm_l3 = { | |
| 95 | 95 | .nodes = sc7180_osm_l3_nodes, |
| 96 | 96 | .num_nodes = ARRAY_SIZE(sc7180_osm_l3_nodes), |
| 97 | 97 | }; |
| @@ -192,7 +192,7 @@ static struct qcom_icc_node *aggre1_noc_nodes[] = { · 191 unmodified lines | ||
| 192 | 192 | [SLAVE_ANOC_PCIE_A1NOC_SNOC] = &qns_pcie_a1noc_snoc, |
| 193 | 193 | }; |
| 194 | 194 | |
| 195 | −const static struct qcom_icc_desc sdm845_aggre1_noc = { | |
| 195 | +static const struct qcom_icc_desc sdm845_aggre1_noc = { | |
| 196 | 196 | .nodes = aggre1_noc_nodes, |
| 197 | 197 | .num_nodes = ARRAY_SIZE(aggre1_noc_nodes), |
| 198 | 198 | .bcms = aggre1_noc_bcms, |
| @@ -220,7 +220,7 @@ static struct qcom_icc_node *aggre2_noc_nodes[] = { · 21 unmodified lines | ||
| 220 | 220 | [SLAVE_SERVICE_A2NOC] = &srvc_aggre2_noc, |
| 221 | 221 | }; |
| 222 | 222 | |
| 223 | −const static struct qcom_icc_desc sdm845_aggre2_noc = { | |
| 223 | +static const struct qcom_icc_desc sdm845_aggre2_noc = { | |
| 224 | 224 | .nodes = aggre2_noc_nodes, |
| 225 | 225 | .num_nodes = ARRAY_SIZE(aggre2_noc_nodes), |
| 226 | 226 | .bcms = aggre2_noc_bcms, |
| @@ -281,7 +281,7 @@ static struct qcom_icc_node *config_noc_nodes[] = { · 54 unmodified lines | ||
| 281 | 281 | [SLAVE_SERVICE_CNOC] = &srvc_cnoc, |
| 282 | 282 | }; |
| 283 | 283 | |
| 284 | −const static struct qcom_icc_desc sdm845_config_noc = { | |
| 284 | +static const struct qcom_icc_desc sdm845_config_noc = { | |
| 285 | 285 | .nodes = config_noc_nodes, |
| 286 | 286 | .num_nodes = ARRAY_SIZE(config_noc_nodes), |
| 287 | 287 | .bcms = config_noc_bcms, |
| @@ -297,7 +297,7 @@ static struct qcom_icc_node *dc_noc_nodes[] = { · 9 unmodified lines | ||
| 297 | 297 | [SLAVE_MEM_NOC_CFG] = &qhs_memnoc, |
| 298 | 298 | }; |
| 299 | 299 | |
| 300 | −const static struct qcom_icc_desc sdm845_dc_noc = { | |
| 300 | +static const struct qcom_icc_desc sdm845_dc_noc = { | |
| 301 | 301 | .nodes = dc_noc_nodes, |
| 302 | 302 | .num_nodes = ARRAY_SIZE(dc_noc_nodes), |
| 303 | 303 | .bcms = dc_noc_bcms, |
| @@ -315,7 +315,7 @@ static struct qcom_icc_node *gladiator_noc_nodes[] = { · 11 unmodified lines | ||
| 315 | 315 | [SLAVE_SERVICE_GNOC] = &srvc_gnoc, |
| 316 | 316 | }; |
| 317 | 317 | |
| 318 | −const static struct qcom_icc_desc sdm845_gladiator_noc = { | |
| 318 | +static const struct qcom_icc_desc sdm845_gladiator_noc = { | |
| 319 | 319 | .nodes = gladiator_noc_nodes, |
| 320 | 320 | .num_nodes = ARRAY_SIZE(gladiator_noc_nodes), |
| 321 | 321 | .bcms = gladiator_noc_bcms, |
| @@ -350,7 +350,7 @@ static struct qcom_icc_node *mem_noc_nodes[] = { · 28 unmodified lines | ||
| 350 | 350 | [SLAVE_EBI1] = &ebi, |
| 351 | 351 | }; |
| 352 | 352 | |
| 353 | −const static struct qcom_icc_desc sdm845_mem_noc = { | |
| 353 | +static const struct qcom_icc_desc sdm845_mem_noc = { | |
| 354 | 354 | .nodes = mem_noc_nodes, |
| 355 | 355 | .num_nodes = ARRAY_SIZE(mem_noc_nodes), |
| 356 | 356 | .bcms = mem_noc_bcms, |
| @@ -384,7 +384,7 @@ static struct qcom_icc_node *mmss_noc_nodes[] = { · 27 unmodified lines | ||
| 384 | 384 | [SLAVE_CAMNOC_UNCOMP] = &qns_camnoc_uncomp, |
| 385 | 385 | }; |
| 386 | 386 | |
| 387 | −const static struct qcom_icc_desc sdm845_mmss_noc = { | |
| 387 | +static const struct qcom_icc_desc sdm845_mmss_noc = { | |
| 388 | 388 | .nodes = mmss_noc_nodes, |
| 389 | 389 | .num_nodes = ARRAY_SIZE(mmss_noc_nodes), |
| 390 | 390 | .bcms = mmss_noc_bcms, |
| @@ -430,7 +430,7 @@ static struct qcom_icc_node *system_noc_nodes[] = { · 39 unmodified lines | ||
| 430 | 430 | [SLAVE_TCU] = &xs_sys_tcu_cfg, |
| 431 | 431 | }; |
| 432 | 432 | |
| 433 | −const static struct qcom_icc_desc sdm845_system_noc = { | |
| 433 | +static const struct qcom_icc_desc sdm845_system_noc = { | |
| 434 | 434 | .nodes = system_noc_nodes, |
| 435 | 435 | .num_nodes = ARRAY_SIZE(system_noc_nodes), |
| 436 | 436 | .bcms = system_noc_bcms, |
| @@ -362,7 +362,7 @@ config IPMMU_VMSA · 361 unmodified lines | ||
| 362 | 362 | |
| 363 | 363 | config SPAPR_TCE_IOMMU |
| 364 | 364 | bool "sPAPR TCE IOMMU Support" |
| 365 | − depends on PPC_POWERNV || PPC_PSERIES || (PPC && COMPILE_TEST) | |
| 365 | + depends on PPC_POWERNV || PPC_PSERIES | |
| 366 | 366 | select IOMMU_API |
| 367 | 367 | help |
| 368 | 368 | Enables bits of IOMMU API required by VFIO. The iommu_ops |
| @@ -457,7 +457,7 @@ config S390_AP_IOMMU · 88 unmodified lines | ||
| 457 | 457 | |
| 458 | 458 | config MTK_IOMMU |
| 459 | 459 | bool "MTK IOMMU Support" |
| 460 | − depends on ARM || ARM64 || COMPILE_TEST | |
| 460 | + depends on HAS_DMA | |
| 461 | 461 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 462 | 462 | select ARM_DMA_USE_IOMMU |
| 463 | 463 | select IOMMU_API |
| @@ -101,6 +101,8 @@ struct kmem_cache *amd_iommu_irq_cache; · 100 unmodified lines | ||
| 101 | 101 | static void update_domain(struct protection_domain *domain); |
| 102 | 102 | static int protection_domain_init(struct protection_domain *domain); |
| 103 | 103 | static void detach_device(struct device *dev); |
| 104 | +static void update_and_flush_device_table(struct protection_domain *domain, | |
| 105 | + struct domain_pgtable *pgtable); | |
| 104 | 106 | |
| 105 | 107 | /**************************************************************************** |
| 106 | 108 | * |
| @@ -151,6 +153,26 @@ static struct protection_domain *to_pdomain(struct iommu_domain *dom) · 44 unmodified lines | ||
| 151 | 153 | return container_of(dom, struct protection_domain, domain); |
| 152 | 154 | } |
| 153 | 155 | |
| 156 | +static void amd_iommu_domain_get_pgtable(struct protection_domain *domain, | |
| 157 | + struct domain_pgtable *pgtable) | |
| 158 | +{ | |
| 159 | + u64 pt_root = atomic64_read(&domain->pt_root); | |
| 160 | + | |
| 161 | + pgtable->root = (u64 *)(pt_root & PAGE_MASK); | |
| 162 | + pgtable->mode = pt_root & 7; /* lowest 3 bits encode pgtable mode */ | |
| 163 | +} | |
| 164 | + | |
| 165 | +static u64 amd_iommu_domain_encode_pgtable(u64 *root, int mode) | |
| 166 | +{ | |
| 167 | + u64 pt_root; | |
| 168 | + | |
| 169 | + /* lowest 3 bits encode pgtable mode */ | |
| 170 | + pt_root = mode & 7; | |
| 171 | + pt_root |= (u64)root; | |
| 172 | + | |
| 173 | + return pt_root; | |
| 174 | +} | |
| 175 | + | |
| 154 | 176 | static struct iommu_dev_data *alloc_dev_data(u16 devid) |
| 155 | 177 | { |
| 156 | 178 | struct iommu_dev_data *dev_data; |
| @@ -1397,13 +1419,18 @@ static struct page *free_sub_pt(unsigned long root, int mode, · 1240 unmodified lines | ||
| 1397 | 1419 | |
| 1398 | 1420 | static void free_pagetable(struct protection_domain *domain) |
| 1399 | 1421 | { |
| 1400 | − unsigned long root = (unsigned long)domain->pt_root; | |
| 1422 | + struct domain_pgtable pgtable; | |
| 1401 | 1423 | struct page *freelist = NULL; |
| 1424 | + unsigned long root; | |
| 1402 | 1425 | |
| 1403 | − BUG_ON(domain->mode < PAGE_MODE_NONE || | |
| 1404 | − domain->mode > PAGE_MODE_6_LEVEL); | |
| 1426 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 1427 | + atomic64_set(&domain->pt_root, 0); | |
| 1405 | 1428 | |
| 1406 | − freelist = free_sub_pt(root, domain->mode, freelist); | |
| 1429 | + BUG_ON(pgtable.mode < PAGE_MODE_NONE || | |
| 1430 | + pgtable.mode > PAGE_MODE_6_LEVEL); | |
| 1431 | + | |
| 1432 | + root = (unsigned long)pgtable.root; | |
| 1433 | + freelist = free_sub_pt(root, pgtable.mode, freelist); | |
| 1407 | 1434 | |
| 1408 | 1435 | free_page_list(freelist); |
| 1409 | 1436 | } |
| @@ -1417,24 +1444,39 @@ static bool increase_address_space(struct protection_domain *domain, · 7 unmodified lines | ||
| 1417 | 1444 | unsigned long address, |
| 1418 | 1445 | gfp_t gfp) |
| 1419 | 1446 | { |
| 1447 | + struct domain_pgtable pgtable; | |
| 1420 | 1448 | unsigned long flags; |
| 1421 | − bool ret = false; | |
| 1422 | − u64 *pte; | |
| 1449 | + bool ret = true; | |
| 1450 | + u64 *pte, root; | |
| 1423 | 1451 | |
| 1424 | 1452 | spin_lock_irqsave(&domain->lock, flags); |
| 1425 | 1453 | |
| 1426 | − if (address <= PM_LEVEL_SIZE(domain->mode) || | |
| 1427 | − WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) | |
| 1454 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 1455 | + | |
| 1456 | + if (address <= PM_LEVEL_SIZE(pgtable.mode)) | |
| 1457 | + goto out; | |
| 1458 | + | |
| 1459 | + ret = false; | |
| 1460 | + if (WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL)) | |
| 1428 | 1461 | goto out; |
| 1429 | 1462 | |
| 1430 | 1463 | pte = (void *)get_zeroed_page(gfp); |
| 1431 | 1464 | if (!pte) |
| 1432 | 1465 | goto out; |
| 1433 | 1466 | |
| 1434 | − *pte = PM_LEVEL_PDE(domain->mode, | |
| 1435 | − iommu_virt_to_phys(domain->pt_root)); | |
| 1436 | − domain->pt_root = pte; | |
| 1437 | − domain->mode += 1; | |
| 1467 | + *pte = PM_LEVEL_PDE(pgtable.mode, iommu_virt_to_phys(pgtable.root)); | |
| 1468 | + | |
| 1469 | + pgtable.root = pte; | |
| 1470 | + pgtable.mode += 1; | |
| 1471 | + update_and_flush_device_table(domain, &pgtable); | |
| 1472 | + domain_flush_complete(domain); | |
| 1473 | + | |
| 1474 | + /* | |
| 1475 | + * Device Table needs to be updated and flushed before the new root can | |
| 1476 | + * be published. | |
| 1477 | + */ | |
| 1478 | + root = amd_iommu_domain_encode_pgtable(pte, pgtable.mode); | |
| 1479 | + atomic64_set(&domain->pt_root, root); | |
| 1438 | 1480 | |
| 1439 | 1481 | ret = true; |
| 1440 | 1482 | |
| @@ -1451,16 +1493,29 @@ static u64 *alloc_pte(struct protection_domain *domain, · 10 unmodified lines | ||
| 1451 | 1493 | gfp_t gfp, |
| 1452 | 1494 | bool *updated) |
| 1453 | 1495 | { |
| 1496 | + struct domain_pgtable pgtable; | |
| 1454 | 1497 | int level, end_lvl; |
| 1455 | 1498 | u64 *pte, *page; |
| 1456 | 1499 | |
| 1457 | 1500 | BUG_ON(!is_power_of_2(page_size)); |
| 1458 | 1501 | |
| 1459 | − while (address > PM_LEVEL_SIZE(domain->mode)) | |
| 1460 | − *updated = increase_address_space(domain, address, gfp) || *updated; | |
| 1502 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 1503 | + | |
| 1504 | + while (address > PM_LEVEL_SIZE(pgtable.mode)) { | |
| 1505 | + /* | |
| 1506 | + * Return an error if there is no memory to update the | |
| 1507 | + * page-table. | |
| 1508 | + */ | |
| 1509 | + if (!increase_address_space(domain, address, gfp)) | |
| 1510 | + return NULL; | |
| 1511 | + | |
| 1512 | + /* Read new values to check if update was successful */ | |
| 1513 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 1514 | + } | |
| 1515 | + | |
| 1461 | 1516 | |
| 1462 | − level = domain->mode - 1; | |
| 1463 | − pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; | |
| 1517 | + level = pgtable.mode - 1; | |
| 1518 | + pte = &pgtable.root[PM_LEVEL_INDEX(level, address)]; | |
| 1464 | 1519 | address = PAGE_SIZE_ALIGN(address, page_size); |
| 1465 | 1520 | end_lvl = PAGE_SIZE_LEVEL(page_size); |
| 1466 | 1521 | |
| @@ -1536,16 +1591,19 @@ static u64 *fetch_pte(struct protection_domain *domain, · 69 unmodified lines | ||
| 1536 | 1591 | unsigned long address, |
| 1537 | 1592 | unsigned long *page_size) |
| 1538 | 1593 | { |
| 1594 | + struct domain_pgtable pgtable; | |
| 1539 | 1595 | int level; |
| 1540 | 1596 | u64 *pte; |
| 1541 | 1597 | |
| 1542 | 1598 | *page_size = 0; |
| 1543 | 1599 | |
| 1544 | − if (address > PM_LEVEL_SIZE(domain->mode)) | |
| 1600 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 1601 | + | |
| 1602 | + if (address > PM_LEVEL_SIZE(pgtable.mode)) | |
| 1545 | 1603 | return NULL; |
| 1546 | 1604 | |
| 1547 | − level = domain->mode - 1; | |
| 1548 | − pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; | |
| 1605 | + level = pgtable.mode - 1; | |
| 1606 | + pte = &pgtable.root[PM_LEVEL_INDEX(level, address)]; | |
| 1549 | 1607 | *page_size = PTE_LEVEL_PAGE_SIZE(level); |
| 1550 | 1608 | |
| 1551 | 1609 | while (level > 0) { |
| @@ -1660,7 +1718,13 @@ out: · 108 unmodified lines | ||
| 1660 | 1718 | unsigned long flags; |
| 1661 | 1719 | |
| 1662 | 1720 | spin_lock_irqsave(&dom->lock, flags); |
| 1663 | − update_domain(dom); | |
| 1721 | + /* | |
| 1722 | + * Flush domain TLB(s) and wait for completion. Any Device-Table | |
| 1723 | + * Updates and flushing already happened in | |
| 1724 | + * increase_address_space(). | |
| 1725 | + */ | |
| 1726 | + domain_flush_tlb_pde(dom); | |
| 1727 | + domain_flush_complete(dom); | |
| 1664 | 1728 | spin_unlock_irqrestore(&dom->lock, flags); |
| 1665 | 1729 | } |
| 1666 | 1730 | |
| @@ -1806,6 +1870,7 @@ static void dma_ops_domain_free(struct protection_domain *domain) · 139 unmodified lines | ||
| 1806 | 1870 | static struct protection_domain *dma_ops_domain_alloc(void) |
| 1807 | 1871 | { |
| 1808 | 1872 | struct protection_domain *domain; |
| 1873 | + u64 *pt_root, root; | |
| 1809 | 1874 | |
| 1810 | 1875 | domain = kzalloc(sizeof(struct protection_domain), GFP_KERNEL); |
| 1811 | 1876 | if (!domain) |
| @@ -1814,12 +1879,14 @@ static struct protection_domain *dma_ops_domain_alloc(void) · 2 unmodified lines | ||
| 1814 | 1879 | if (protection_domain_init(domain)) |
| 1815 | 1880 | goto free_domain; |
| 1816 | 1881 | |
| 1817 | − domain->mode = PAGE_MODE_3_LEVEL; | |
| 1818 | − domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); | |
| 1819 | − domain->flags = PD_DMA_OPS_MASK; | |
| 1820 | − if (!domain->pt_root) | |
| 1882 | + pt_root = (void *)get_zeroed_page(GFP_KERNEL); | |
| 1883 | + if (!pt_root) | |
| 1821 | 1884 | goto free_domain; |
| 1822 | 1885 | |
| 1886 | + root = amd_iommu_domain_encode_pgtable(pt_root, PAGE_MODE_3_LEVEL); | |
| 1887 | + atomic64_set(&domain->pt_root, root); | |
| 1888 | + domain->flags = PD_DMA_OPS_MASK; | |
| 1889 | + | |
| 1823 | 1890 | if (iommu_get_dma_cookie(&domain->domain) == -ENOMEM) |
| 1824 | 1891 | goto free_domain; |
| 1825 | 1892 | |
| @@ -1841,16 +1908,17 @@ static bool dma_ops_domain(struct protection_domain *domain) · 15 unmodified lines | ||
| 1841 | 1908 | } |
| 1842 | 1909 | |
| 1843 | 1910 | static void set_dte_entry(u16 devid, struct protection_domain *domain, |
| 1911 | + struct domain_pgtable *pgtable, | |
| 1844 | 1912 | bool ats, bool ppr) |
| 1845 | 1913 | { |
| 1846 | 1914 | u64 pte_root = 0; |
| 1847 | 1915 | u64 flags = 0; |
| 1848 | 1916 | u32 old_domid; |
| 1849 | 1917 | |
| 1850 | − if (domain->mode != PAGE_MODE_NONE) | |
| 1851 | − pte_root = iommu_virt_to_phys(domain->pt_root); | |
| 1918 | + if (pgtable->mode != PAGE_MODE_NONE) | |
| 1919 | + pte_root = iommu_virt_to_phys(pgtable->root); | |
| 1852 | 1920 | |
| 1853 | − pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | |
| 1921 | + pte_root |= (pgtable->mode & DEV_ENTRY_MODE_MASK) | |
| 1854 | 1922 | << DEV_ENTRY_MODE_SHIFT; |
| 1855 | 1923 | pte_root |= DTE_FLAG_IR | DTE_FLAG_IW | DTE_FLAG_V | DTE_FLAG_TV; |
| 1856 | 1924 | |
| @@ -1923,6 +1991,7 @@ static void clear_dte_entry(u16 devid) · 66 unmodified lines | ||
| 1923 | 1991 | static void do_attach(struct iommu_dev_data *dev_data, |
| 1924 | 1992 | struct protection_domain *domain) |
| 1925 | 1993 | { |
| 1994 | + struct domain_pgtable pgtable; | |
| 1926 | 1995 | struct amd_iommu *iommu; |
| 1927 | 1996 | bool ats; |
| 1928 | 1997 | |
| @@ -1938,7 +2007,9 @@ static void do_attach(struct iommu_dev_data *dev_data, · 9 unmodified lines | ||
| 1938 | 2007 | domain->dev_cnt += 1; |
| 1939 | 2008 | |
| 1940 | 2009 | /* Update device table */ |
| 1941 | − set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2); | |
| 2010 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 2011 | + set_dte_entry(dev_data->devid, domain, &pgtable, | |
| 2012 | + ats, dev_data->iommu_v2); | |
| 1942 | 2013 | clone_aliases(dev_data->pdev); |
| 1943 | 2014 | |
| 1944 | 2015 | device_flush_dte(dev_data); |
| @@ -2249,23 +2320,36 @@ static int amd_iommu_domain_get_attr(struct iommu_domain *domain, · 304 unmodified lines | ||
| 2249 | 2320 | * |
| 2250 | 2321 | *****************************************************************************/ |
| 2251 | 2322 | |
| 2252 | −static void update_device_table(struct protection_domain *domain) | |
| 2323 | +static void update_device_table(struct protection_domain *domain, | |
| 2324 | + struct domain_pgtable *pgtable) | |
| 2253 | 2325 | { |
| 2254 | 2326 | struct iommu_dev_data *dev_data; |
| 2255 | 2327 | |
| 2256 | 2328 | list_for_each_entry(dev_data, &domain->dev_list, list) { |
| 2257 | − set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled, | |
| 2258 | − dev_data->iommu_v2); | |
| 2329 | + set_dte_entry(dev_data->devid, domain, pgtable, | |
| 2330 | + dev_data->ats.enabled, dev_data->iommu_v2); | |
| 2259 | 2331 | clone_aliases(dev_data->pdev); |
| 2260 | 2332 | } |
| 2261 | 2333 | } |
| 2262 | 2334 | |
| 2335 | +static void update_and_flush_device_table(struct protection_domain *domain, | |
| 2336 | + struct domain_pgtable *pgtable) | |
| 2337 | +{ | |
| 2338 | + update_device_table(domain, pgtable); | |
| 2339 | + domain_flush_devices(domain); | |
| 2340 | +} | |
| 2341 | + | |
| 2263 | 2342 | static void update_domain(struct protection_domain *domain) |
| 2264 | 2343 | { |
| 2265 | − update_device_table(domain); | |
| 2344 | + struct domain_pgtable pgtable; | |
| 2266 | 2345 | |
| 2267 | − domain_flush_devices(domain); | |
| 2346 | + /* Update device table */ | |
| 2347 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 2348 | + update_and_flush_device_table(domain, &pgtable); | |
| 2349 | + | |
| 2350 | + /* Flush domain TLB(s) and wait for completion */ | |
| 2268 | 2351 | domain_flush_tlb_pde(domain); |
| 2352 | + domain_flush_complete(domain); | |
| 2269 | 2353 | } |
| 2270 | 2354 | |
| 2271 | 2355 | int __init amd_iommu_init_api(void) |
| @@ -2375,6 +2459,7 @@ out_err: · 103 unmodified lines | ||
| 2375 | 2459 | static struct iommu_domain *amd_iommu_domain_alloc(unsigned type) |
| 2376 | 2460 | { |
| 2377 | 2461 | struct protection_domain *pdomain; |
| 2462 | + u64 *pt_root, root; | |
| 2378 | 2463 | |
| 2379 | 2464 | switch (type) { |
| 2380 | 2465 | case IOMMU_DOMAIN_UNMANAGED: |
| @@ -2382,13 +2467,15 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned type) · 1 unmodified line | ||
| 2382 | 2467 | if (!pdomain) |
| 2383 | 2468 | return NULL; |
| 2384 | 2469 | |
| 2385 | − pdomain->mode = PAGE_MODE_3_LEVEL; | |
| 2386 | − pdomain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); | |
| 2387 | − if (!pdomain->pt_root) { | |
| 2470 | + pt_root = (void *)get_zeroed_page(GFP_KERNEL); | |
| 2471 | + if (!pt_root) { | |
| 2388 | 2472 | protection_domain_free(pdomain); |
| 2389 | 2473 | return NULL; |
| 2390 | 2474 | } |
| 2391 | 2475 | |
| 2476 | + root = amd_iommu_domain_encode_pgtable(pt_root, PAGE_MODE_3_LEVEL); | |
| 2477 | + atomic64_set(&pdomain->pt_root, root); | |
| 2478 | + | |
| 2392 | 2479 | pdomain->domain.geometry.aperture_start = 0; |
| 2393 | 2480 | pdomain->domain.geometry.aperture_end = ~0ULL; |
| 2394 | 2481 | pdomain->domain.geometry.force_aperture = true; |
| @@ -2406,7 +2493,7 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned type) · 11 unmodified lines | ||
| 2406 | 2493 | if (!pdomain) |
| 2407 | 2494 | return NULL; |
| 2408 | 2495 | |
| 2409 | − pdomain->mode = PAGE_MODE_NONE; | |
| 2496 | + atomic64_set(&pdomain->pt_root, PAGE_MODE_NONE); | |
| 2410 | 2497 | break; |
| 2411 | 2498 | default: |
| 2412 | 2499 | return NULL; |
| @@ -2418,6 +2505,7 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned type) · 5 unmodified lines | ||
| 2418 | 2505 | static void amd_iommu_domain_free(struct iommu_domain *dom) |
| 2419 | 2506 | { |
| 2420 | 2507 | struct protection_domain *domain; |
| 2508 | + struct domain_pgtable pgtable; | |
| 2421 | 2509 | |
| 2422 | 2510 | domain = to_pdomain(dom); |
| 2423 | 2511 | |
| @@ -2435,7 +2523,9 @@ static void amd_iommu_domain_free(struct iommu_domain *dom) · 11 unmodified lines | ||
| 2435 | 2523 | dma_ops_domain_free(domain); |
| 2436 | 2524 | break; |
| 2437 | 2525 | default: |
| 2438 | − if (domain->mode != PAGE_MODE_NONE) | |
| 2526 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 2527 | + | |
| 2528 | + if (pgtable.mode != PAGE_MODE_NONE) | |
| 2439 | 2529 | free_pagetable(domain); |
| 2440 | 2530 | |
| 2441 | 2531 | if (domain->flags & PD_IOMMUV2_MASK) |
| @@ -2518,10 +2608,12 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, · 76 unmodified lines | ||
| 2518 | 2608 | gfp_t gfp) |
| 2519 | 2609 | { |
| 2520 | 2610 | struct protection_domain *domain = to_pdomain(dom); |
| 2611 | + struct domain_pgtable pgtable; | |
| 2521 | 2612 | int prot = 0; |
| 2522 | 2613 | int ret; |
| 2523 | 2614 | |
| 2524 | − if (domain->mode == PAGE_MODE_NONE) | |
| 2615 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 2616 | + if (pgtable.mode == PAGE_MODE_NONE) | |
| 2525 | 2617 | return -EINVAL; |
| 2526 | 2618 | |
| 2527 | 2619 | if (iommu_prot & IOMMU_READ) |
| @@ -2541,8 +2633,10 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, · 13 unmodified lines | ||
| 2541 | 2633 | struct iommu_iotlb_gather *gather) |
| 2542 | 2634 | { |
| 2543 | 2635 | struct protection_domain *domain = to_pdomain(dom); |
| 2636 | + struct domain_pgtable pgtable; | |
| 2544 | 2637 | |
| 2545 | − if (domain->mode == PAGE_MODE_NONE) | |
| 2638 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 2639 | + if (pgtable.mode == PAGE_MODE_NONE) | |
| 2546 | 2640 | return 0; |
| 2547 | 2641 | |
| 2548 | 2642 | return iommu_unmap_page(domain, iova, page_size); |
| @@ -2553,9 +2647,11 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, · 4 unmodified lines | ||
| 2553 | 2647 | { |
| 2554 | 2648 | struct protection_domain *domain = to_pdomain(dom); |
| 2555 | 2649 | unsigned long offset_mask, pte_pgsize; |
| 2650 | + struct domain_pgtable pgtable; | |
| 2556 | 2651 | u64 *pte, __pte; |
| 2557 | 2652 | |
| 2558 | − if (domain->mode == PAGE_MODE_NONE) | |
| 2653 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 2654 | + if (pgtable.mode == PAGE_MODE_NONE) | |
| 2559 | 2655 | return iova; |
| 2560 | 2656 | |
| 2561 | 2657 | pte = fetch_pte(domain, iova, &pte_pgsize); |
| @@ -2708,16 +2804,26 @@ EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier); · 146 unmodified lines | ||
| 2708 | 2804 | void amd_iommu_domain_direct_map(struct iommu_domain *dom) |
| 2709 | 2805 | { |
| 2710 | 2806 | struct protection_domain *domain = to_pdomain(dom); |
| 2807 | + struct domain_pgtable pgtable; | |
| 2711 | 2808 | unsigned long flags; |
| 2809 | + u64 pt_root; | |
| 2712 | 2810 | |
| 2713 | 2811 | spin_lock_irqsave(&domain->lock, flags); |
| 2714 | 2812 | |
| 2813 | + /* First save pgtable configuration*/ | |
| 2814 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 2815 | + | |
| 2715 | 2816 | /* Update data structure */ |
| 2716 | − domain->mode = PAGE_MODE_NONE; | |
| 2817 | + pt_root = amd_iommu_domain_encode_pgtable(NULL, PAGE_MODE_NONE); | |
| 2818 | + atomic64_set(&domain->pt_root, pt_root); | |
| 2717 | 2819 | |
| 2718 | 2820 | /* Make changes visible to IOMMUs */ |
| 2719 | 2821 | update_domain(domain); |
| 2720 | 2822 | |
| 2823 | + /* Restore old pgtable in domain->ptroot to free page-table */ | |
| 2824 | + pt_root = amd_iommu_domain_encode_pgtable(pgtable.root, pgtable.mode); | |
| 2825 | + atomic64_set(&domain->pt_root, pt_root); | |
| 2826 | + | |
| 2721 | 2827 | /* Page-table is not visible to IOMMU anymore, so free it */ |
| 2722 | 2828 | free_pagetable(domain); |
| 2723 | 2829 | |
| @@ -2908,9 +3014,11 @@ static u64 *__get_gcr3_pte(u64 *root, int level, int pasid, bool alloc) · 184 unmodified lines | ||
| 2908 | 3014 | static int __set_gcr3(struct protection_domain *domain, int pasid, |
| 2909 | 3015 | unsigned long cr3) |
| 2910 | 3016 | { |
| 3017 | + struct domain_pgtable pgtable; | |
| 2911 | 3018 | u64 *pte; |
| 2912 | 3019 | |
| 2913 | − if (domain->mode != PAGE_MODE_NONE) | |
| 3020 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 3021 | + if (pgtable.mode != PAGE_MODE_NONE) | |
| 2914 | 3022 | return -EINVAL; |
| 2915 | 3023 | |
| 2916 | 3024 | pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, true); |
| @@ -2924,9 +3032,11 @@ static int __set_gcr3(struct protection_domain *domain, int pasid, · 7 unmodified lines | ||
| 2924 | 3032 | |
| 2925 | 3033 | static int __clear_gcr3(struct protection_domain *domain, int pasid) |
| 2926 | 3034 | { |
| 3035 | + struct domain_pgtable pgtable; | |
| 2927 | 3036 | u64 *pte; |
| 2928 | 3037 | |
| 2929 | − if (domain->mode != PAGE_MODE_NONE) | |
| 3038 | + amd_iommu_domain_get_pgtable(domain, &pgtable); | |
| 3039 | + if (pgtable.mode != PAGE_MODE_NONE) | |
| 2930 | 3040 | return -EINVAL; |
| 2931 | 3041 | |
| 2932 | 3042 | pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, false); |
| @@ -2936,7 +2936,7 @@ static int __init parse_amd_iommu_intr(char *str) · 2935 unmodified lines | ||
| 2936 | 2936 | { |
| 2937 | 2937 | for (; *str; ++str) { |
| 2938 | 2938 | if (strncmp(str, "legacy", 6) == 0) { |
| 2939 | − amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; | |
| 2939 | + amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA; | |
| 2940 | 2940 | break; |
| 2941 | 2941 | } |
| 2942 | 2942 | if (strncmp(str, "vapic", 5) == 0) { |
| @@ -468,8 +468,7 @@ struct protection_domain { · 467 unmodified lines | ||
| 468 | 468 | iommu core code */ |
| 469 | 469 | spinlock_t lock; /* mostly used to lock the page table*/ |
| 470 | 470 | u16 id; /* the domain id written to the device table */ |
| 471 | − int mode; /* paging mode (0-6 levels) */ | |
| 472 | − u64 *pt_root; /* page table root pointer */ | |
| 471 | + atomic64_t pt_root; /* pgtable root and pgtable mode */ | |
| 473 | 472 | int glx; /* Number of levels for GCR3 table */ |
| 474 | 473 | u64 *gcr3_tbl; /* Guest CR3 table */ |
| 475 | 474 | unsigned long flags; /* flags to find out type of domain */ |
| @@ -477,6 +476,12 @@ struct protection_domain { · 1 unmodified line | ||
| 477 | 476 | unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */ |
| 478 | 477 | }; |
| 479 | 478 | |
| 479 | +/* For decocded pt_root */ | |
| 480 | +struct domain_pgtable { | |
| 481 | + int mode; | |
| 482 | + u64 *root; | |
| 483 | +}; | |
| 484 | + | |
| 480 | 485 | /* |
| 481 | 486 | * Structure where we save information about one hardware AMD IOMMU in the |
| 482 | 487 | * system. |
| @@ -371,11 +371,11 @@ int dmar_disabled = 0; · 370 unmodified lines | ||
| 371 | 371 | int dmar_disabled = 1; |
| 372 | 372 | #endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */ |
| 373 | 373 | |
| 374 | −#ifdef INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON | |
| 374 | +#ifdef CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON | |
| 375 | 375 | int intel_iommu_sm = 1; |
| 376 | 376 | #else |
| 377 | 377 | int intel_iommu_sm; |
| 378 | −#endif /* INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */ | |
| 378 | +#endif /* CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */ | |
| 379 | 379 | |
| 380 | 380 | int intel_iommu_enabled = 0; |
| 381 | 381 | EXPORT_SYMBOL_GPL(intel_iommu_enabled); |
| @@ -170,6 +170,7 @@ static struct dev_iommu *dev_iommu_get(struct device *dev) · 169 unmodified lines | ||
| 170 | 170 | |
| 171 | 171 | static void dev_iommu_free(struct device *dev) |
| 172 | 172 | { |
| 173 | + iommu_fwspec_free(dev); | |
| 173 | 174 | kfree(dev->iommu); |
| 174 | 175 | dev->iommu = NULL; |
| 175 | 176 | } |
| @@ -1428,7 +1429,7 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev) · 1252 unmodified lines | ||
| 1428 | 1429 | |
| 1429 | 1430 | return group; |
| 1430 | 1431 | } |
| 1431 | −EXPORT_SYMBOL(iommu_group_get_for_dev); | |
| 1432 | +EXPORT_SYMBOL_GPL(iommu_group_get_for_dev); | |
| 1432 | 1433 | |
| 1433 | 1434 | struct iommu_domain *iommu_group_default_domain(struct iommu_group *group) |
| 1434 | 1435 | { |
| @@ -824,8 +824,11 @@ static int qcom_iommu_device_probe(struct platform_device *pdev) · 823 unmodified lines | ||
| 824 | 824 | qcom_iommu->dev = dev; |
| 825 | 825 | |
| 826 | 826 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 827 | − if (res) | |
| 827 | + if (res) { | |
| 828 | 828 | qcom_iommu->local_base = devm_ioremap_resource(dev, res); |
| 829 | + if (IS_ERR(qcom_iommu->local_base)) | |
| 830 | + return PTR_ERR(qcom_iommu->local_base); | |
| 831 | + } | |
| 829 | 832 | |
| 830 | 833 | qcom_iommu->iface_clk = devm_clk_get(dev, "iface"); |
| 831 | 834 | if (IS_ERR(qcom_iommu->iface_clk)) { |
| @@ -453,7 +453,7 @@ static int viommu_add_resv_mem(struct viommu_endpoint *vdev, · 452 unmodified lines | ||
| 453 | 453 | if (!region) |
| 454 | 454 | return -ENOMEM; |
| 455 | 455 | |
| 456 | − list_add(&vdev->resv_regions, ®ion->list); | |
| 456 | + list_add(®ion->list, &vdev->resv_regions); | |
| 457 | 457 | return 0; |
| 458 | 458 | } |
| 459 | 459 | |
| @@ -585,10 +585,12 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) · 584 unmodified lines | ||
| 585 | 585 | |
| 586 | 586 | /* Do we need to select a new pgpath? */ |
| 587 | 587 | pgpath = READ_ONCE(m->current_pgpath); |
| 588 | − queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | |
| 589 | − if (!pgpath || !queue_io) | |
| 588 | + if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) | |
| 590 | 589 | pgpath = choose_pgpath(m, bio->bi_iter.bi_size); |
| 591 | 590 | |
| 591 | + /* MPATHF_QUEUE_IO might have been cleared by choose_pgpath. */ | |
| 592 | + queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | |
| 593 | + | |
| 592 | 594 | if ((pgpath && queue_io) || |
| 593 | 595 | (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) { |
| 594 | 596 | /* Queue for the daemon to resubmit */ |
| @@ -435,7 +435,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, · 434 unmodified lines | ||
| 435 | 435 | fio->level++; |
| 436 | 436 | |
| 437 | 437 | if (type == DM_VERITY_BLOCK_TYPE_METADATA) |
| 438 | − block += v->data_blocks; | |
| 438 | + block = block - v->hash_start + v->data_blocks; | |
| 439 | 439 | |
| 440 | 440 | /* |
| 441 | 441 | * For RS(M, N), the continuous FEC data is divided into blocks of N |
| @@ -931,6 +931,24 @@ static int writecache_alloc_entries(struct dm_writecache *wc) · 930 unmodified lines | ||
| 931 | 931 | return 0; |
| 932 | 932 | } |
| 933 | 933 | |
| 934 | +static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors) | |
| 935 | +{ | |
| 936 | + struct dm_io_region region; | |
| 937 | + struct dm_io_request req; | |
| 938 | + | |
| 939 | + region.bdev = wc->ssd_dev->bdev; | |
| 940 | + region.sector = wc->start_sector; | |
| 941 | + region.count = n_sectors; | |
| 942 | + req.bi_op = REQ_OP_READ; | |
| 943 | + req.bi_op_flags = REQ_SYNC; | |
| 944 | + req.mem.type = DM_IO_VMA; | |
| 945 | + req.mem.ptr.vma = (char *)wc->memory_map; | |
| 946 | + req.client = wc->dm_io; | |
| 947 | + req.notify.fn = NULL; | |
| 948 | + | |
| 949 | + return dm_io(&req, 1, ®ion, NULL); | |
| 950 | +} | |
| 951 | + | |
| 934 | 952 | static void writecache_resume(struct dm_target *ti) |
| 935 | 953 | { |
| 936 | 954 | struct dm_writecache *wc = ti->private; |
| @@ -941,8 +959,18 @@ static void writecache_resume(struct dm_target *ti) · 4 unmodified lines | ||
| 941 | 959 | |
| 942 | 960 | wc_lock(wc); |
| 943 | 961 | |
| 944 | − if (WC_MODE_PMEM(wc)) | |
| 962 | + if (WC_MODE_PMEM(wc)) { | |
| 945 | 963 | persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size); |
| 964 | + } else { | |
| 965 | + r = writecache_read_metadata(wc, wc->metadata_sectors); | |
| 966 | + if (r) { | |
| 967 | + size_t sb_entries_offset; | |
| 968 | + writecache_error(wc, r, "unable to read metadata: %d", r); | |
| 969 | + sb_entries_offset = offsetof(struct wc_memory_superblock, entries); | |
| 970 | + memset((char *)wc->memory_map + sb_entries_offset, -1, | |
| 971 | + (wc->metadata_sectors << SECTOR_SHIFT) - sb_entries_offset); | |
| 972 | + } | |
| 973 | + } | |
| 946 | 974 | |
| 947 | 975 | wc->tree = RB_ROOT; |
| 948 | 976 | INIT_LIST_HEAD(&wc->lru); |
| @@ -2102,6 +2130,12 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) · 1153 unmodified lines | ||
| 2102 | 2130 | ti->error = "Invalid block size"; |
| 2103 | 2131 | goto bad; |
| 2104 | 2132 | } |
| 2133 | + if (wc->block_size < bdev_logical_block_size(wc->dev->bdev) || | |
| 2134 | + wc->block_size < bdev_logical_block_size(wc->ssd_dev->bdev)) { | |
| 2135 | + r = -EINVAL; | |
| 2136 | + ti->error = "Block size is smaller than device logical block size"; | |
| 2137 | + goto bad; | |
| 2138 | + } | |
| 2105 | 2139 | wc->block_size_bits = __ffs(wc->block_size); |
| 2106 | 2140 | |
| 2107 | 2141 | wc->max_writeback_jobs = MAX_WRITEBACK_JOBS; |
| @@ -2200,8 +2234,6 @@ invalid_optional: · 92 unmodified lines | ||
| 2200 | 2234 | goto bad; |
| 2201 | 2235 | } |
| 2202 | 2236 | } else { |
| 2203 | − struct dm_io_region region; | |
| 2204 | − struct dm_io_request req; | |
| 2205 | 2237 | size_t n_blocks, n_metadata_blocks; |
| 2206 | 2238 | uint64_t n_bitmap_bits; |
| 2207 | 2239 | |
| @@ -2258,19 +2290,9 @@ invalid_optional: · 50 unmodified lines | ||
| 2258 | 2290 | goto bad; |
| 2259 | 2291 | } |
| 2260 | 2292 | |
| 2261 | − region.bdev = wc->ssd_dev->bdev; | |
| 2262 | − region.sector = wc->start_sector; | |
| 2263 | − region.count = wc->metadata_sectors; | |
| 2264 | − req.bi_op = REQ_OP_READ; | |
| 2265 | − req.bi_op_flags = REQ_SYNC; | |
| 2266 | − req.mem.type = DM_IO_VMA; | |
| 2267 | − req.mem.ptr.vma = (char *)wc->memory_map; | |
| 2268 | − req.client = wc->dm_io; | |
| 2269 | − req.notify.fn = NULL; | |
| 2270 | − | |
| 2271 | − r = dm_io(&req, 1, ®ion, NULL); | |
| 2293 | + r = writecache_read_metadata(wc, wc->block_size >> SECTOR_SHIFT); | |
| 2272 | 2294 | if (r) { |
| 2273 | − ti->error = "Unable to read metadata"; | |
| 2295 | + ti->error = "Unable to read first block of metadata"; | |
| 2274 | 2296 | goto bad; |
| 2275 | 2297 | } |
| 2276 | 2298 | } |
| @@ -1465,6 +1465,13 @@ static const struct mei_cfg mei_me_pch12_cfg = { · 1464 unmodified lines | ||
| 1465 | 1465 | MEI_CFG_DMA_128, |
| 1466 | 1466 | }; |
| 1467 | 1467 | |
| 1468 | +/* LBG with quirk for SPS Firmware exclusion */ | |
| 1469 | +static const struct mei_cfg mei_me_pch12_sps_cfg = { | |
| 1470 | + MEI_CFG_PCH8_HFS, | |
| 1471 | + MEI_CFG_FW_VER_SUPP, | |
| 1472 | + MEI_CFG_FW_SPS, | |
| 1473 | +}; | |
| 1474 | + | |
| 1468 | 1475 | /* Tiger Lake and newer devices */ |
| 1469 | 1476 | static const struct mei_cfg mei_me_pch15_cfg = { |
| 1470 | 1477 | MEI_CFG_PCH8_HFS, |
| @@ -1487,6 +1494,7 @@ static const struct mei_cfg *const mei_cfg_list[] = { · 16 unmodified lines | ||
| 1487 | 1494 | [MEI_ME_PCH8_CFG] = &mei_me_pch8_cfg, |
| 1488 | 1495 | [MEI_ME_PCH8_SPS_CFG] = &mei_me_pch8_sps_cfg, |
| 1489 | 1496 | [MEI_ME_PCH12_CFG] = &mei_me_pch12_cfg, |
| 1497 | + [MEI_ME_PCH12_SPS_CFG] = &mei_me_pch12_sps_cfg, | |
| 1490 | 1498 | [MEI_ME_PCH15_CFG] = &mei_me_pch15_cfg, |
| 1491 | 1499 | }; |
| 1492 | 1500 | |
| @@ -80,6 +80,9 @@ struct mei_me_hw { · 79 unmodified lines | ||
| 80 | 80 | * servers platforms with quirk for |
| 81 | 81 | * SPS firmware exclusion. |
| 82 | 82 | * @MEI_ME_PCH12_CFG: Platform Controller Hub Gen12 and newer |
| 83 | + * @MEI_ME_PCH12_SPS_CFG: Platform Controller Hub Gen12 and newer | |
| 84 | + * servers platforms with quirk for | |
| 85 | + * SPS firmware exclusion. | |
| 83 | 86 | * @MEI_ME_PCH15_CFG: Platform Controller Hub Gen15 and newer |
| 84 | 87 | * @MEI_ME_NUM_CFG: Upper Sentinel. |
| 85 | 88 | */ |
| @@ -93,6 +96,7 @@ enum mei_cfg_idx { · 7 unmodified lines | ||
| 93 | 96 | MEI_ME_PCH8_CFG, |
| 94 | 97 | MEI_ME_PCH8_SPS_CFG, |
| 95 | 98 | MEI_ME_PCH12_CFG, |
| 99 | + MEI_ME_PCH12_SPS_CFG, | |
| 96 | 100 | MEI_ME_PCH15_CFG, |
| 97 | 101 | MEI_ME_NUM_CFG, |
| 98 | 102 | }; |
| @@ -70,7 +70,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 69 unmodified lines | ||
| 70 | 70 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)}, |
| 71 | 71 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_CFG)}, |
| 72 | 72 | {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_CFG)}, |
| 73 | − {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_CFG)}, | |
| 73 | + {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_SPS_CFG)}, | |
| 74 | 74 | |
| 75 | 75 | {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, MEI_ME_PCH8_CFG)}, |
| 76 | 76 | {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, MEI_ME_PCH8_CFG)}, |
| @@ -878,7 +878,7 @@ static int mmc_send_hpi_cmd(struct mmc_card *card) · 877 unmodified lines | ||
| 878 | 878 | * Issued High Priority Interrupt, and check for card status |
| 879 | 879 | * until out-of prg-state. |
| 880 | 880 | */ |
| 881 | −int mmc_interrupt_hpi(struct mmc_card *card) | |
| 881 | +static int mmc_interrupt_hpi(struct mmc_card *card) | |
| 882 | 882 | { |
| 883 | 883 | int err; |
| 884 | 884 | u32 status; |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/delay.h> |
| 6 | 6 | #include <linux/highmem.h> |
| 7 | 7 | #include <linux/io.h> |
| 8 | +#include <linux/iopoll.h> | |
| 8 | 9 | #include <linux/module.h> |
| 9 | 10 | #include <linux/dma-mapping.h> |
| 10 | 11 | #include <linux/slab.h> |
| @@ -349,12 +350,16 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) · 338 unmodified lines | ||
| 349 | 350 | /* CQHCI is idle and should halt immediately, so set a small timeout */ |
| 350 | 351 | #define CQHCI_OFF_TIMEOUT 100 |
| 351 | 352 | |
| 353 | +static u32 cqhci_read_ctl(struct cqhci_host *cq_host) | |
| 354 | +{ | |
| 355 | + return cqhci_readl(cq_host, CQHCI_CTL); | |
| 356 | +} | |
| 357 | + | |
| 352 | 358 | static void cqhci_off(struct mmc_host *mmc) |
| 353 | 359 | { |
| 354 | 360 | struct cqhci_host *cq_host = mmc->cqe_private; |
| 355 | − ktime_t timeout; | |
| 356 | − bool timed_out; | |
| 357 | 361 | u32 reg; |
| 362 | + int err; | |
| 358 | 363 | |
| 359 | 364 | if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt) |
| 360 | 365 | return; |
| @@ -364,15 +369,9 @@ static void cqhci_off(struct mmc_host *mmc) · 3 unmodified lines | ||
| 364 | 369 | |
| 365 | 370 | cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL); |
| 366 | 371 | |
| 367 | − timeout = ktime_add_us(ktime_get(), CQHCI_OFF_TIMEOUT); | |
| 368 | − while (1) { | |
| 369 | − timed_out = ktime_compare(ktime_get(), timeout) > 0; | |
| 370 | − reg = cqhci_readl(cq_host, CQHCI_CTL); | |
| 371 | − if ((reg & CQHCI_HALT) || timed_out) | |
| 372 | − break; | |
| 373 | − } | |
| 374 | − | |
| 375 | − if (timed_out) | |
| 372 | + err = readx_poll_timeout(cqhci_read_ctl, cq_host, reg, | |
| 373 | + reg & CQHCI_HALT, 0, CQHCI_OFF_TIMEOUT); | |
| 374 | + if (err < 0) | |
| 376 | 375 | pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc)); |
| 377 | 376 | else |
| 378 | 377 | pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc)); |
| @@ -357,14 +357,6 @@ static void meson_mx_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) · 356 unmodified lines | ||
| 357 | 357 | meson_mx_mmc_start_cmd(mmc, mrq->cmd); |
| 358 | 358 | } |
| 359 | 359 | |
| 360 | −static int meson_mx_mmc_card_busy(struct mmc_host *mmc) | |
| 361 | −{ | |
| 362 | − struct meson_mx_mmc_host *host = mmc_priv(mmc); | |
| 363 | − u32 irqc = readl(host->base + MESON_MX_SDIO_IRQC); | |
| 364 | − | |
| 365 | − return !!(irqc & MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK); | |
| 366 | −} | |
| 367 | − | |
| 368 | 360 | static void meson_mx_mmc_read_response(struct mmc_host *mmc, |
| 369 | 361 | struct mmc_command *cmd) |
| 370 | 362 | { |
| @@ -506,7 +498,6 @@ static void meson_mx_mmc_timeout(struct timer_list *t) · 135 unmodified lines | ||
| 506 | 498 | static struct mmc_host_ops meson_mx_mmc_ops = { |
| 507 | 499 | .request = meson_mx_mmc_request, |
| 508 | 500 | .set_ios = meson_mx_mmc_set_ios, |
| 509 | − .card_busy = meson_mx_mmc_card_busy, | |
| 510 | 501 | .get_cd = mmc_gpio_get_cd, |
| 511 | 502 | .get_ro = mmc_gpio_get_ro, |
| 512 | 503 | }; |
| @@ -570,7 +561,7 @@ static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host) · 57 unmodified lines | ||
| 570 | 561 | mmc->f_max = clk_round_rate(host->cfg_div_clk, |
| 571 | 562 | clk_get_rate(host->parent_clk)); |
| 572 | 563 | |
| 573 | − mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; | |
| 564 | + mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY; | |
| 574 | 565 | mmc->ops = &meson_mx_mmc_ops; |
| 575 | 566 | |
| 576 | 567 | ret = mmc_of_parse(mmc); |
| @@ -2087,6 +2087,8 @@ static int sdhci_msm_probe(struct platform_device *pdev) · 2086 unmodified lines | ||
| 2087 | 2087 | goto clk_disable; |
| 2088 | 2088 | } |
| 2089 | 2089 | |
| 2090 | + msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; | |
| 2091 | + | |
| 2090 | 2092 | pm_runtime_get_noresume(&pdev->dev); |
| 2091 | 2093 | pm_runtime_set_active(&pdev->dev); |
| 2092 | 2094 | pm_runtime_enable(&pdev->dev); |
| @@ -601,6 +601,9 @@ static int intel_select_drive_strength(struct mmc_card *card, · 600 unmodified lines | ||
| 601 | 601 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
| 602 | 602 | struct intel_host *intel_host = sdhci_pci_priv(slot); |
| 603 | 603 | |
| 604 | + if (!(mmc_driver_type_mask(intel_host->drv_strength) & card_drv)) | |
| 605 | + return 0; | |
| 606 | + | |
| 604 | 607 | return intel_host->drv_strength; |
| 605 | 608 | } |
| 606 | 609 | |
| @@ -235,6 +235,16 @@ static void xenon_voltage_switch(struct sdhci_host *host) · 234 unmodified lines | ||
| 235 | 235 | { |
| 236 | 236 | /* Wait for 5ms after set 1.8V signal enable bit */ |
| 237 | 237 | usleep_range(5000, 5500); |
| 238 | + | |
| 239 | + /* | |
| 240 | + * For some reason the controller's Host Control2 register reports | |
| 241 | + * the bit representing 1.8V signaling as 0 when read after it was | |
| 242 | + * written as 1. Subsequent read reports 1. | |
| 243 | + * | |
| 244 | + * Since this may cause some issues, do an empty read of the Host | |
| 245 | + * Control2 register here to circumvent this. | |
| 246 | + */ | |
| 247 | + sdhci_readw(host, SDHCI_HOST_CONTROL2); | |
| 238 | 248 | } |
| 239 | 249 | |
| 240 | 250 | static const struct sdhci_ops sdhci_xenon_ops = { |
| @@ -1483,7 +1483,7 @@ static void __exit most_exit(void) · 1482 unmodified lines | ||
| 1483 | 1483 | ida_destroy(&mdev_id); |
| 1484 | 1484 | } |
| 1485 | 1485 | |
| 1486 | −module_init(most_init); | |
| 1486 | +subsys_initcall(most_init); | |
| 1487 | 1487 | module_exit(most_exit); |
| 1488 | 1488 | MODULE_LICENSE("GPL"); |
| 1489 | 1489 | MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>"); |
| @@ -24,8 +24,8 @@ config NET_DSA_MV88E6XXX_PTP · 23 unmodified lines | ||
| 24 | 24 | bool "PTP support for Marvell 88E6xxx" |
| 25 | 25 | default n |
| 26 | 26 | depends on NET_DSA_MV88E6XXX_GLOBAL2 |
| 27 | + depends on PTP_1588_CLOCK | |
| 27 | 28 | imply NETWORK_PHY_TIMESTAMPING |
| 28 | − imply PTP_1588_CLOCK | |
| 29 | 29 | help |
| 30 | 30 | Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch |
| 31 | 31 | chips that support it. |
| @@ -3962,7 +3962,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = { · 3961 unmodified lines | ||
| 3962 | 3962 | .serdes_get_stats = mv88e6390_serdes_get_stats, |
| 3963 | 3963 | .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, |
| 3964 | 3964 | .serdes_get_regs = mv88e6390_serdes_get_regs, |
| 3965 | − .phylink_validate = mv88e6390_phylink_validate, | |
| 3966 | 3965 | .gpio_ops = &mv88e6352_gpio_ops, |
| 3967 | 3966 | .phylink_validate = mv88e6390_phylink_validate, |
| 3968 | 3967 | }; |
| @@ -4021,7 +4020,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = { · 52 unmodified lines | ||
| 4021 | 4020 | .serdes_get_stats = mv88e6390_serdes_get_stats, |
| 4022 | 4021 | .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, |
| 4023 | 4022 | .serdes_get_regs = mv88e6390_serdes_get_regs, |
| 4024 | − .phylink_validate = mv88e6390_phylink_validate, | |
| 4025 | 4023 | .gpio_ops = &mv88e6352_gpio_ops, |
| 4026 | 4024 | .phylink_validate = mv88e6390x_phylink_validate, |
| 4027 | 4025 | }; |
| @@ -4079,7 +4077,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = { · 51 unmodified lines | ||
| 4079 | 4077 | .serdes_get_stats = mv88e6390_serdes_get_stats, |
| 4080 | 4078 | .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, |
| 4081 | 4079 | .serdes_get_regs = mv88e6390_serdes_get_regs, |
| 4082 | − .phylink_validate = mv88e6390_phylink_validate, | |
| 4083 | 4080 | .avb_ops = &mv88e6390_avb_ops, |
| 4084 | 4081 | .ptp_ops = &mv88e6352_ptp_ops, |
| 4085 | 4082 | .phylink_validate = mv88e6390_phylink_validate, |
| @@ -4235,7 +4232,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = { · 149 unmodified lines | ||
| 4235 | 4232 | .serdes_get_stats = mv88e6390_serdes_get_stats, |
| 4236 | 4233 | .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, |
| 4237 | 4234 | .serdes_get_regs = mv88e6390_serdes_get_regs, |
| 4238 | − .phylink_validate = mv88e6390_phylink_validate, | |
| 4239 | 4235 | .gpio_ops = &mv88e6352_gpio_ops, |
| 4240 | 4236 | .avb_ops = &mv88e6390_avb_ops, |
| 4241 | 4237 | .ptp_ops = &mv88e6352_ptp_ops, |
| @@ -400,6 +400,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) · 399 unmodified lines | ||
| 400 | 400 | ocelot->stats_layout = felix->info->stats_layout; |
| 401 | 401 | ocelot->num_stats = felix->info->num_stats; |
| 402 | 402 | ocelot->shared_queue_sz = felix->info->shared_queue_sz; |
| 403 | + ocelot->num_mact_rows = felix->info->num_mact_rows; | |
| 403 | 404 | ocelot->vcap_is2_keys = felix->info->vcap_is2_keys; |
| 404 | 405 | ocelot->vcap_is2_actions= felix->info->vcap_is2_actions; |
| 405 | 406 | ocelot->vcap = felix->info->vcap; |
| @@ -15,6 +15,7 @@ struct felix_info { · 14 unmodified lines | ||
| 15 | 15 | const u32 *const *map; |
| 16 | 16 | const struct ocelot_ops *ops; |
| 17 | 17 | int shared_queue_sz; |
| 18 | + int num_mact_rows; | |
| 18 | 19 | const struct ocelot_stat_layout *stats_layout; |
| 19 | 20 | unsigned int num_stats; |
| 20 | 21 | int num_ports; |
| @@ -1220,6 +1220,7 @@ struct felix_info felix_info_vsc9959 = { · 1219 unmodified lines | ||
| 1220 | 1220 | .vcap_is2_actions = vsc9959_vcap_is2_actions, |
| 1221 | 1221 | .vcap = vsc9959_vcap_props, |
| 1222 | 1222 | .shared_queue_sz = 128 * 1024, |
| 1223 | + .num_mact_rows = 2048, | |
| 1223 | 1224 | .num_ports = 6, |
| 1224 | 1225 | .switch_pci_bar = 4, |
| 1225 | 1226 | .imdio_pci_bar = 0, |
| @@ -20,6 +20,7 @@ tristate "NXP SJA1105 Ethernet switch family support" · 19 unmodified lines | ||
| 20 | 20 | config NET_DSA_SJA1105_PTP |
| 21 | 21 | bool "Support for the PTP clock on the NXP SJA1105 Ethernet switch" |
| 22 | 22 | depends on NET_DSA_SJA1105 |
| 23 | + depends on PTP_1588_CLOCK | |
| 23 | 24 | help |
| 24 | 25 | This enables support for timestamping and PTP clock manipulations in |
| 25 | 26 | the SJA1105 DSA driver. |
| @@ -16,14 +16,15 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | /* PTPSYNCTS has no interrupt or update mechanism, because the intended |
| 18 | 18 | * hardware use case is for the timestamp to be collected synchronously, |
| 19 | − * immediately after the CAS_MASTER SJA1105 switch has triggered a CASSYNC | |
| 20 | − * pulse on the PTP_CLK pin. When used as a generic extts source, it needs | |
| 21 | − * polling and a comparison with the old value. The polling interval is just | |
| 22 | − * the Nyquist rate of a canonical PPS input (e.g. from a GPS module). | |
| 23 | − * Anything of higher frequency than 1 Hz will be lost, since there is no | |
| 24 | − * timestamp FIFO. | |
| 19 | + * immediately after the CAS_MASTER SJA1105 switch has performed a CASSYNC | |
| 20 | + * one-shot toggle (no return to level) on the PTP_CLK pin. When used as a | |
| 21 | + * generic extts source, the PTPSYNCTS register needs polling and a comparison | |
| 22 | + * with the old value. The polling interval is configured as the Nyquist rate | |
| 23 | + * of a signal with 50% duty cycle and 1Hz frequency, which is sadly all that | |
| 24 | + * this hardware can do (but may be enough for some setups). Anything of higher | |
| 25 | + * frequency than 1 Hz will be lost, since there is no timestamp FIFO. | |
| 25 | 26 | */ |
| 26 | −#define SJA1105_EXTTS_INTERVAL (HZ / 2) | |
| 27 | +#define SJA1105_EXTTS_INTERVAL (HZ / 4) | |
| 27 | 28 | |
| 28 | 29 | /* This range is actually +/- SJA1105_MAX_ADJ_PPB |
| 29 | 30 | * divided by 1000 (ppb -> ppm) and with a 16-bit |
| @@ -754,7 +755,16 @@ static int sja1105_extts_enable(struct sja1105_private *priv, · 724 unmodified lines | ||
| 754 | 755 | return -EOPNOTSUPP; |
| 755 | 756 | |
| 756 | 757 | /* Reject requests with unsupported flags */ |
| 757 | − if (extts->flags) | |
| 758 | + if (extts->flags & ~(PTP_ENABLE_FEATURE | | |
| 759 | + PTP_RISING_EDGE | | |
| 760 | + PTP_FALLING_EDGE | | |
| 761 | + PTP_STRICT_FLAGS)) | |
| 762 | + return -EOPNOTSUPP; | |
| 763 | + | |
| 764 | + /* We can only enable time stamping on both edges, sadly. */ | |
| 765 | + if ((extts->flags & PTP_STRICT_FLAGS) && | |
| 766 | + (extts->flags & PTP_ENABLE_FEATURE) && | |
| 767 | + (extts->flags & PTP_EXTTS_EDGES) != PTP_EXTTS_EDGES) | |
| 758 | 768 | return -EOPNOTSUPP; |
| 759 | 769 | |
| 760 | 770 | rc = sja1105_change_ptp_clk_pin_func(priv, PTP_PF_EXTTS); |
| @@ -69,7 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | * 16kB. |
| 70 | 70 | */ |
| 71 | 71 | #if PAGE_SIZE > SZ_16K |
| 72 | −#define ENA_PAGE_SIZE SZ_16K | |
| 72 | +#define ENA_PAGE_SIZE (_AC(SZ_16K, UL)) | |
| 73 | 73 | #else |
| 74 | 74 | #define ENA_PAGE_SIZE PAGE_SIZE |
| 75 | 75 | #endif |
| @@ -57,7 +57,7 @@ static const struct aq_board_revision_s hw_atl_boards[] = { · 56 unmodified lines | ||
| 57 | 57 | { AQ_DEVICE_ID_D108, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc108, }, |
| 58 | 58 | { AQ_DEVICE_ID_D109, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc109, }, |
| 59 | 59 | |
| 60 | − { AQ_DEVICE_ID_AQC100, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107, }, | |
| 60 | + { AQ_DEVICE_ID_AQC100, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc100, }, | |
| 61 | 61 | { AQ_DEVICE_ID_AQC107, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107, }, |
| 62 | 62 | { AQ_DEVICE_ID_AQC108, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc108, }, |
| 63 | 63 | { AQ_DEVICE_ID_AQC109, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc109, }, |
| @@ -172,6 +172,7 @@ static int bgmac_probe(struct platform_device *pdev) · 171 unmodified lines | ||
| 172 | 172 | { |
| 173 | 173 | struct device_node *np = pdev->dev.of_node; |
| 174 | 174 | struct bgmac *bgmac; |
| 175 | + struct resource *regs; | |
| 175 | 176 | const u8 *mac_addr; |
| 176 | 177 | |
| 177 | 178 | bgmac = bgmac_alloc(&pdev->dev); |
| @@ -206,16 +207,21 @@ static int bgmac_probe(struct platform_device *pdev) · 28 unmodified lines | ||
| 206 | 207 | if (IS_ERR(bgmac->plat.base)) |
| 207 | 208 | return PTR_ERR(bgmac->plat.base); |
| 208 | 209 | |
| 209 | − bgmac->plat.idm_base = | |
| 210 | − devm_platform_ioremap_resource_byname(pdev, "idm_base"); | |
| 211 | − if (IS_ERR(bgmac->plat.idm_base)) | |
| 212 | − return PTR_ERR(bgmac->plat.idm_base); | |
| 213 | − bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK; | |
| 210 | + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base"); | |
| 211 | + if (regs) { | |
| 212 | + bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs); | |
| 213 | + if (IS_ERR(bgmac->plat.idm_base)) | |
| 214 | + return PTR_ERR(bgmac->plat.idm_base); | |
| 215 | + bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK; | |
| 216 | + } | |
| 214 | 217 | |
| 215 | − bgmac->plat.nicpm_base = | |
| 216 | − devm_platform_ioremap_resource_byname(pdev, "nicpm_base"); | |
| 217 | − if (IS_ERR(bgmac->plat.nicpm_base)) | |
| 218 | − return PTR_ERR(bgmac->plat.nicpm_base); | |
| 218 | + regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); | |
| 219 | + if (regs) { | |
| 220 | + bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev, | |
| 221 | + regs); | |
| 222 | + if (IS_ERR(bgmac->plat.nicpm_base)) | |
| 223 | + return PTR_ERR(bgmac->plat.nicpm_base); | |
| 224 | + } | |
| 219 | 225 | |
| 220 | 226 | bgmac->read = platform_bgmac_read; |
| 221 | 227 | bgmac->write = platform_bgmac_write; |
| @@ -6642,7 +6642,7 @@ static int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp, · 6641 unmodified lines | ||
| 6642 | 6642 | int rc; |
| 6643 | 6643 | |
| 6644 | 6644 | if (!mem_size) |
| 6645 | − return 0; | |
| 6645 | + return -EINVAL; | |
| 6646 | 6646 | |
| 6647 | 6647 | ctx_pg->nr_pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE); |
| 6648 | 6648 | if (ctx_pg->nr_pages > MAX_CTX_TOTAL_PAGES) { |
| @@ -9780,6 +9780,7 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev, · 3131 unmodified lines | ||
| 9780 | 9780 | netdev_features_t features) |
| 9781 | 9781 | { |
| 9782 | 9782 | struct bnxt *bp = netdev_priv(dev); |
| 9783 | + netdev_features_t vlan_features; | |
| 9783 | 9784 | |
| 9784 | 9785 | if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp)) |
| 9785 | 9786 | features &= ~NETIF_F_NTUPLE; |
| @@ -9796,12 +9797,14 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev, · 10 unmodified lines | ||
| 9796 | 9797 | /* Both CTAG and STAG VLAN accelaration on the RX side have to be |
| 9797 | 9798 | * turned on or off together. |
| 9798 | 9799 | */ |
| 9799 | − if ((features & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) != | |
| 9800 | − (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) { | |
| 9800 | + vlan_features = features & (NETIF_F_HW_VLAN_CTAG_RX | | |
| 9801 | + NETIF_F_HW_VLAN_STAG_RX); | |
| 9802 | + if (vlan_features != (NETIF_F_HW_VLAN_CTAG_RX | | |
| 9803 | + NETIF_F_HW_VLAN_STAG_RX)) { | |
| 9801 | 9804 | if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) |
| 9802 | 9805 | features &= ~(NETIF_F_HW_VLAN_CTAG_RX | |
| 9803 | 9806 | NETIF_F_HW_VLAN_STAG_RX); |
| 9804 | − else | |
| 9807 | + else if (vlan_features) | |
| 9805 | 9808 | features |= NETIF_F_HW_VLAN_CTAG_RX | |
| 9806 | 9809 | NETIF_F_HW_VLAN_STAG_RX; |
| 9807 | 9810 | } |
| @@ -12212,12 +12215,15 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) · 2404 unmodified lines | ||
| 12212 | 12215 | bnxt_ulp_start(bp, err); |
| 12213 | 12216 | } |
| 12214 | 12217 | |
| 12215 | − if (result != PCI_ERS_RESULT_RECOVERED && netif_running(netdev)) | |
| 12216 | − dev_close(netdev); | |
| 12218 | + if (result != PCI_ERS_RESULT_RECOVERED) { | |
| 12219 | + if (netif_running(netdev)) | |
| 12220 | + dev_close(netdev); | |
| 12221 | + pci_disable_device(pdev); | |
| 12222 | + } | |
| 12217 | 12223 | |
| 12218 | 12224 | rtnl_unlock(); |
| 12219 | 12225 | |
| 12220 | − return PCI_ERS_RESULT_RECOVERED; | |
| 12226 | + return result; | |
| 12221 | 12227 | } |
| 12222 | 12228 | |
| 12223 | 12229 | /** |
| @@ -1066,7 +1066,6 @@ struct bnxt_vf_info { · 1065 unmodified lines | ||
| 1066 | 1066 | #define BNXT_VF_LINK_FORCED 0x4 |
| 1067 | 1067 | #define BNXT_VF_LINK_UP 0x8 |
| 1068 | 1068 | #define BNXT_VF_TRUST 0x10 |
| 1069 | − u32 func_flags; /* func cfg flags */ | |
| 1070 | 1069 | u32 min_tx_rate; |
| 1071 | 1070 | u32 max_tx_rate; |
| 1072 | 1071 | void *hwrm_cmd_req_addr; |
| @@ -43,7 +43,7 @@ static inline void bnxt_link_bp_to_dl(struct bnxt *bp, struct devlink *dl) · 42 unmodified lines | ||
| 43 | 43 | #define BNXT_NVM_CFG_VER_BITS 24 |
| 44 | 44 | #define BNXT_NVM_CFG_VER_BYTES 4 |
| 45 | 45 | |
| 46 | −#define BNXT_MSIX_VEC_MAX 1280 | |
| 46 | +#define BNXT_MSIX_VEC_MAX 512 | |
| 47 | 47 | #define BNXT_MSIX_VEC_MIN_MAX 128 |
| 48 | 48 | |
| 49 | 49 | enum bnxt_nvm_dir_type { |
| @@ -85,11 +85,10 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting) · 84 unmodified lines | ||
| 85 | 85 | if (old_setting == setting) |
| 86 | 86 | return 0; |
| 87 | 87 | |
| 88 | − func_flags = vf->func_flags; | |
| 89 | 88 | if (setting) |
| 90 | − func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE; | |
| 89 | + func_flags = FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE; | |
| 91 | 90 | else |
| 92 | − func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE; | |
| 91 | + func_flags = FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE; | |
| 93 | 92 | /*TODO: if the driver supports VLAN filter on guest VLAN, |
| 94 | 93 | * the spoof check should also include vlan anti-spoofing |
| 95 | 94 | */ |
| @@ -98,7 +97,6 @@ int bnxt_set_vf_spoofchk(struct net_device *dev, int vf_id, bool setting) · 2 unmodified lines | ||
| 98 | 97 | req.flags = cpu_to_le32(func_flags); |
| 99 | 98 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 100 | 99 | if (!rc) { |
| 101 | − vf->func_flags = func_flags; | |
| 102 | 100 | if (setting) |
| 103 | 101 | vf->flags |= BNXT_VF_SPOOFCHK; |
| 104 | 102 | else |
| @@ -228,7 +226,6 @@ int bnxt_set_vf_mac(struct net_device *dev, int vf_id, u8 *mac) · 123 unmodified lines | ||
| 228 | 226 | memcpy(vf->mac_addr, mac, ETH_ALEN); |
| 229 | 227 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); |
| 230 | 228 | req.fid = cpu_to_le16(vf->fw_fid); |
| 231 | − req.flags = cpu_to_le32(vf->func_flags); | |
| 232 | 229 | req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR); |
| 233 | 230 | memcpy(req.dflt_mac_addr, mac, ETH_ALEN); |
| 234 | 231 | return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| @@ -266,7 +263,6 @@ int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos, · 31 unmodified lines | ||
| 266 | 263 | |
| 267 | 264 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); |
| 268 | 265 | req.fid = cpu_to_le16(vf->fw_fid); |
| 269 | − req.flags = cpu_to_le32(vf->func_flags); | |
| 270 | 266 | req.dflt_vlan = cpu_to_le16(vlan_tag); |
| 271 | 267 | req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_VLAN); |
| 272 | 268 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| @@ -305,7 +301,6 @@ int bnxt_set_vf_bw(struct net_device *dev, int vf_id, int min_tx_rate, · 32 unmodified lines | ||
| 305 | 301 | return 0; |
| 306 | 302 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); |
| 307 | 303 | req.fid = cpu_to_le16(vf->fw_fid); |
| 308 | − req.flags = cpu_to_le32(vf->func_flags); | |
| 309 | 304 | req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_MAX_BW); |
| 310 | 305 | req.max_bw = cpu_to_le32(max_tx_rate); |
| 311 | 306 | req.enables |= cpu_to_le32(FUNC_CFG_REQ_ENABLES_MIN_BW); |
| @@ -477,7 +472,6 @@ static void __bnxt_set_vf_params(struct bnxt *bp, int vf_id) · 165 unmodified lines | ||
| 477 | 472 | vf = &bp->pf.vf[vf_id]; |
| 478 | 473 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); |
| 479 | 474 | req.fid = cpu_to_le16(vf->fw_fid); |
| 480 | − req.flags = cpu_to_le32(vf->func_flags); | |
| 481 | 475 | |
| 482 | 476 | if (is_valid_ether_addr(vf->mac_addr)) { |
| 483 | 477 | req.enables |= cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR); |
| @@ -35,8 +35,8 @@ config MACB · 34 unmodified lines | ||
| 35 | 35 | config MACB_USE_HWSTAMP |
| 36 | 36 | bool "Use IEEE 1588 hwstamp" |
| 37 | 37 | depends on MACB |
| 38 | + depends on PTP_1588_CLOCK | |
| 38 | 39 | default y |
| 39 | − imply PTP_1588_CLOCK | |
| 40 | 40 | ---help--- |
| 41 | 41 | Enable IEEE 1588 Precision Time Protocol (PTP) support for MACB. |
| 42 | 42 | |
| @@ -334,8 +334,10 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) · 333 unmodified lines | ||
| 334 | 334 | int status; |
| 335 | 335 | |
| 336 | 336 | status = pm_runtime_get_sync(&bp->pdev->dev); |
| 337 | − if (status < 0) | |
| 337 | + if (status < 0) { | |
| 338 | + pm_runtime_put_noidle(&bp->pdev->dev); | |
| 338 | 339 | goto mdio_pm_exit; |
| 340 | + } | |
| 339 | 341 | |
| 340 | 342 | status = macb_mdio_wait_for_idle(bp); |
| 341 | 343 | if (status < 0) |
| @@ -386,8 +388,10 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, · 44 unmodified lines | ||
| 386 | 388 | int status; |
| 387 | 389 | |
| 388 | 390 | status = pm_runtime_get_sync(&bp->pdev->dev); |
| 389 | − if (status < 0) | |
| 391 | + if (status < 0) { | |
| 392 | + pm_runtime_put_noidle(&bp->pdev->dev); | |
| 390 | 393 | goto mdio_pm_exit; |
| 394 | + } | |
| 391 | 395 | |
| 392 | 396 | status = macb_mdio_wait_for_idle(bp); |
| 393 | 397 | if (status < 0) |
| @@ -3816,8 +3820,10 @@ static int at91ether_open(struct net_device *dev) · 3422 unmodified lines | ||
| 3816 | 3820 | int ret; |
| 3817 | 3821 | |
| 3818 | 3822 | ret = pm_runtime_get_sync(&lp->pdev->dev); |
| 3819 | − if (ret < 0) | |
| 3823 | + if (ret < 0) { | |
| 3824 | + pm_runtime_put_noidle(&lp->pdev->dev); | |
| 3820 | 3825 | return ret; |
| 3826 | + } | |
| 3821 | 3827 | |
| 3822 | 3828 | /* Clear internal statistics */ |
| 3823 | 3829 | ctl = macb_readl(lp, NCR); |
| @@ -4172,15 +4178,9 @@ static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk, · 348 unmodified lines | ||
| 4172 | 4178 | |
| 4173 | 4179 | static int fu540_c000_init(struct platform_device *pdev) |
| 4174 | 4180 | { |
| 4175 | − struct resource *res; | |
| 4176 | − | |
| 4177 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | |
| 4178 | − if (!res) | |
| 4179 | − return -ENODEV; | |
| 4180 | − | |
| 4181 | − mgmt->reg = ioremap(res->start, resource_size(res)); | |
| 4182 | − if (!mgmt->reg) | |
| 4183 | − return -ENOMEM; | |
| 4181 | + mgmt->reg = devm_platform_ioremap_resource(pdev, 1); | |
| 4182 | + if (IS_ERR(mgmt->reg)) | |
| 4183 | + return PTR_ERR(mgmt->reg); | |
| 4184 | 4184 | |
| 4185 | 4185 | return macb_init(pdev); |
| 4186 | 4186 | } |
| @@ -54,7 +54,7 @@ config THUNDER_NIC_RGX · 53 unmodified lines | ||
| 54 | 54 | config CAVIUM_PTP |
| 55 | 55 | tristate "Cavium PTP coprocessor as PTP clock" |
| 56 | 56 | depends on 64BIT && PCI |
| 57 | − imply PTP_1588_CLOCK | |
| 57 | + depends on PTP_1588_CLOCK | |
| 58 | 58 | ---help--- |
| 59 | 59 | This driver adds support for the Precision Time Protocol Clocks and |
| 60 | 60 | Timestamping coprocessor (PTP) found on Cavium processors. |
| @@ -2207,6 +2207,9 @@ static void ethofld_hard_xmit(struct net_device *dev, · 2206 unmodified lines | ||
| 2207 | 2207 | if (unlikely(skip_eotx_wr)) { |
| 2208 | 2208 | start = (u64 *)wr; |
| 2209 | 2209 | eosw_txq->state = next_state; |
| 2210 | + eosw_txq->cred -= wrlen16; | |
| 2211 | + eosw_txq->ncompl++; | |
| 2212 | + eosw_txq->last_compl = 0; | |
| 2210 | 2213 | goto write_wr_headers; |
| 2211 | 2214 | } |
| 2212 | 2215 | |
| @@ -2365,6 +2368,34 @@ netdev_tx_t t4_start_xmit(struct sk_buff *skb, struct net_device *dev) · 152 unmodified lines | ||
| 2365 | 2368 | return cxgb4_eth_xmit(skb, dev); |
| 2366 | 2369 | } |
| 2367 | 2370 | |
| 2371 | +static void eosw_txq_flush_pending_skbs(struct sge_eosw_txq *eosw_txq) | |
| 2372 | +{ | |
| 2373 | + int pktcount = eosw_txq->pidx - eosw_txq->last_pidx; | |
| 2374 | + int pidx = eosw_txq->pidx; | |
| 2375 | + struct sk_buff *skb; | |
| 2376 | + | |
| 2377 | + if (!pktcount) | |
| 2378 | + return; | |
| 2379 | + | |
| 2380 | + if (pktcount < 0) | |
| 2381 | + pktcount += eosw_txq->ndesc; | |
| 2382 | + | |
| 2383 | + while (pktcount--) { | |
| 2384 | + pidx--; | |
| 2385 | + if (pidx < 0) | |
| 2386 | + pidx += eosw_txq->ndesc; | |
| 2387 | + | |
| 2388 | + skb = eosw_txq->desc[pidx].skb; | |
| 2389 | + if (skb) { | |
| 2390 | + dev_consume_skb_any(skb); | |
| 2391 | + eosw_txq->desc[pidx].skb = NULL; | |
| 2392 | + eosw_txq->inuse--; | |
| 2393 | + } | |
| 2394 | + } | |
| 2395 | + | |
| 2396 | + eosw_txq->pidx = eosw_txq->last_pidx + 1; | |
| 2397 | +} | |
| 2398 | + | |
| 2368 | 2399 | /** |
| 2369 | 2400 | * cxgb4_ethofld_send_flowc - Send ETHOFLD flowc request to bind eotid to tc. |
| 2370 | 2401 | * @dev - netdevice |
| @@ -2440,9 +2471,11 @@ int cxgb4_ethofld_send_flowc(struct net_device *dev, u32 eotid, u32 tc) · 69 unmodified lines | ||
| 2440 | 2471 | FW_FLOWC_MNEM_EOSTATE_CLOSING : |
| 2441 | 2472 | FW_FLOWC_MNEM_EOSTATE_ESTABLISHED); |
| 2442 | 2473 | |
| 2443 | − eosw_txq->cred -= len16; | |
| 2444 | − eosw_txq->ncompl++; | |
| 2445 | − eosw_txq->last_compl = 0; | |
| 2474 | + /* Free up any pending skbs to ensure there's room for | |
| 2475 | + * termination FLOWC. | |
| 2476 | + */ | |
| 2477 | + if (tc == FW_SCHED_CLS_NONE) | |
| 2478 | + eosw_txq_flush_pending_skbs(eosw_txq); | |
| 2446 | 2479 | |
| 2447 | 2480 | ret = eosw_txq_enqueue(eosw_txq, skb); |
| 2448 | 2481 | if (ret) { |
| @@ -2695,6 +2728,7 @@ static void ofldtxq_stop(struct sge_uld_txq *q, struct fw_wr_hdr *wr) · 246 unmodified lines | ||
| 2695 | 2728 | * is ever running at a time ... |
| 2696 | 2729 | */ |
| 2697 | 2730 | static void service_ofldq(struct sge_uld_txq *q) |
| 2731 | + __must_hold(&q->sendq.lock) | |
| 2698 | 2732 | { |
| 2699 | 2733 | u64 *pos, *before, *end; |
| 2700 | 2734 | int credits; |
| @@ -74,8 +74,8 @@ err_pci_mem_reg: · 73 unmodified lines | ||
| 74 | 74 | pci_disable_device(pdev); |
| 75 | 75 | err_pci_enable: |
| 76 | 76 | err_mdiobus_alloc: |
| 77 | − iounmap(port_regs); | |
| 78 | 77 | err_hw_alloc: |
| 78 | + iounmap(port_regs); | |
| 79 | 79 | err_ioremap: |
| 80 | 80 | return err; |
| 81 | 81 | } |
| @@ -2189,7 +2189,8 @@ static void __ibmvnic_reset(struct work_struct *work) · 2188 unmodified lines | ||
| 2189 | 2189 | rc = do_hard_reset(adapter, rwi, reset_state); |
| 2190 | 2190 | rtnl_unlock(); |
| 2191 | 2191 | } |
| 2192 | − } else { | |
| 2192 | + } else if (!(rwi->reset_reason == VNIC_RESET_FATAL && | |
| 2193 | + adapter->from_passive_init)) { | |
| 2193 | 2194 | rc = do_reset(adapter, rwi, reset_state); |
| 2194 | 2195 | } |
| 2195 | 2196 | kfree(rwi); |
| @@ -1428,6 +1428,9 @@ int mvpp2_ethtool_cls_rule_del(struct mvpp2_port *port, · 1427 unmodified lines | ||
| 1428 | 1428 | struct mvpp2_ethtool_fs *efs; |
| 1429 | 1429 | int ret; |
| 1430 | 1430 | |
| 1431 | + if (info->fs.location >= MVPP2_N_RFS_ENTRIES_PER_FLOW) | |
| 1432 | + return -EINVAL; | |
| 1433 | + | |
| 1431 | 1434 | efs = port->rfs_rules[info->fs.location]; |
| 1432 | 1435 | if (!efs) |
| 1433 | 1436 | return -EINVAL; |
| @@ -4329,6 +4329,8 @@ static int mvpp2_ethtool_get_rxfh_context(struct net_device *dev, u32 *indir, · 4328 unmodified lines | ||
| 4329 | 4329 | |
| 4330 | 4330 | if (!mvpp22_rss_is_supported()) |
| 4331 | 4331 | return -EOPNOTSUPP; |
| 4332 | + if (rss_context >= MVPP22_N_RSS_TABLES) | |
| 4333 | + return -EINVAL; | |
| 4332 | 4334 | |
| 4333 | 4335 | if (hfunc) |
| 4334 | 4336 | *hfunc = ETH_RSS_HASH_CRC32; |
| @@ -2550,6 +2550,7 @@ static int mlx4_allocate_default_counters(struct mlx4_dev *dev) · 2549 unmodified lines | ||
| 2550 | 2550 | |
| 2551 | 2551 | if (!err || err == -ENOSPC) { |
| 2552 | 2552 | priv->def_counter[port] = idx; |
| 2553 | + err = 0; | |
| 2553 | 2554 | } else if (err == -ENOENT) { |
| 2554 | 2555 | err = 0; |
| 2555 | 2556 | continue; |
| @@ -2600,7 +2601,8 @@ int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx, u8 usage) · 44 unmodified lines | ||
| 2600 | 2601 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); |
| 2601 | 2602 | if (!err) |
| 2602 | 2603 | *idx = get_param_l(&out_param); |
| 2603 | − | |
| 2604 | + if (WARN_ON(err == -ENOSPC)) | |
| 2605 | + err = -EINVAL; | |
| 2604 | 2606 | return err; |
| 2605 | 2607 | } |
| 2606 | 2608 | return __mlx4_counter_alloc(dev, idx); |
| @@ -888,7 +888,6 @@ static void cmd_work_handler(struct work_struct *work) · 887 unmodified lines | ||
| 888 | 888 | } |
| 889 | 889 | |
| 890 | 890 | cmd->ent_arr[ent->idx] = ent; |
| 891 | − set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); | |
| 892 | 891 | lay = get_inst(cmd, ent->idx); |
| 893 | 892 | ent->lay = lay; |
| 894 | 893 | memset(lay, 0, sizeof(*lay)); |
| @@ -910,6 +909,7 @@ static void cmd_work_handler(struct work_struct *work) · 15 unmodified lines | ||
| 910 | 909 | |
| 911 | 910 | if (ent->callback) |
| 912 | 911 | schedule_delayed_work(&ent->cb_timeout_work, cb_timeout); |
| 912 | + set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); | |
| 913 | 913 | |
| 914 | 914 | /* Skip sending command to fw if internal error */ |
| 915 | 915 | if (pci_channel_offline(dev->pdev) || |
| @@ -922,6 +922,10 @@ static void cmd_work_handler(struct work_struct *work) · 6 unmodified lines | ||
| 922 | 922 | MLX5_SET(mbox_out, ent->out, syndrome, drv_synd); |
| 923 | 923 | |
| 924 | 924 | mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); |
| 925 | + /* no doorbell, no need to keep the entry */ | |
| 926 | + free_ent(cmd, ent->idx); | |
| 927 | + if (ent->callback) | |
| 928 | + free_cmd(ent); | |
| 925 | 929 | return; |
| 926 | 930 | } |
| 927 | 931 | |
| @@ -1773,19 +1773,14 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv) · 1772 unmodified lines | ||
| 1773 | 1773 | |
| 1774 | 1774 | static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv) |
| 1775 | 1775 | { |
| 1776 | − int err = mlx5e_init_rep_rx(priv); | |
| 1777 | − | |
| 1778 | − if (err) | |
| 1779 | − return err; | |
| 1780 | − | |
| 1781 | 1776 | mlx5e_create_q_counters(priv); |
| 1782 | − return 0; | |
| 1777 | + return mlx5e_init_rep_rx(priv); | |
| 1783 | 1778 | } |
| 1784 | 1779 | |
| 1785 | 1780 | static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv) |
| 1786 | 1781 | { |
| 1787 | − mlx5e_destroy_q_counters(priv); | |
| 1788 | 1782 | mlx5e_cleanup_rep_rx(priv); |
| 1783 | + mlx5e_destroy_q_counters(priv); | |
| 1789 | 1784 | } |
| 1790 | 1785 | |
| 1791 | 1786 | static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv) |
| @@ -1550,9 +1550,9 @@ static int esw_create_restore_table(struct mlx5_eswitch *esw) · 1549 unmodified lines | ||
| 1550 | 1550 | MLX5_FLOW_NAMESPACE_KERNEL, 1, |
| 1551 | 1551 | modact); |
| 1552 | 1552 | if (IS_ERR(mod_hdr)) { |
| 1553 | + err = PTR_ERR(mod_hdr); | |
| 1553 | 1554 | esw_warn(dev, "Failed to create restore mod header, err: %d\n", |
| 1554 | 1555 | err); |
| 1555 | − err = PTR_ERR(mod_hdr); | |
| 1556 | 1556 | goto err_mod_hdr; |
| 1557 | 1557 | } |
| 1558 | 1558 | |
| @@ -2219,10 +2219,12 @@ static int esw_offloads_steering_init(struct mlx5_eswitch *esw) · 660 unmodified lines | ||
| 2219 | 2219 | total_vports = num_vfs + MLX5_SPECIAL_VPORTS(esw->dev); |
| 2220 | 2220 | |
| 2221 | 2221 | memset(&esw->fdb_table.offloads, 0, sizeof(struct offloads_fdb)); |
| 2222 | + mutex_init(&esw->fdb_table.offloads.vports.lock); | |
| 2223 | + hash_init(esw->fdb_table.offloads.vports.table); | |
| 2222 | 2224 | |
| 2223 | 2225 | err = esw_create_uplink_offloads_acl_tables(esw); |
| 2224 | 2226 | if (err) |
| 2225 | − return err; | |
| 2227 | + goto create_acl_err; | |
| 2226 | 2228 | |
| 2227 | 2229 | err = esw_create_offloads_table(esw, total_vports); |
| 2228 | 2230 | if (err) |
| @@ -2240,9 +2242,6 @@ static int esw_offloads_steering_init(struct mlx5_eswitch *esw) · 11 unmodified lines | ||
| 2240 | 2242 | if (err) |
| 2241 | 2243 | goto create_fg_err; |
| 2242 | 2244 | |
| 2243 | − mutex_init(&esw->fdb_table.offloads.vports.lock); | |
| 2244 | − hash_init(esw->fdb_table.offloads.vports.table); | |
| 2245 | − | |
| 2246 | 2245 | return 0; |
| 2247 | 2246 | |
| 2248 | 2247 | create_fg_err: |
| @@ -2253,18 +2252,19 @@ create_restore_err: · 4 unmodified lines | ||
| 2253 | 2252 | esw_destroy_offloads_table(esw); |
| 2254 | 2253 | create_offloads_err: |
| 2255 | 2254 | esw_destroy_uplink_offloads_acl_tables(esw); |
| 2256 | − | |
| 2255 | +create_acl_err: | |
| 2256 | + mutex_destroy(&esw->fdb_table.offloads.vports.lock); | |
| 2257 | 2257 | return err; |
| 2258 | 2258 | } |
| 2259 | 2259 | |
| 2260 | 2260 | static void esw_offloads_steering_cleanup(struct mlx5_eswitch *esw) |
| 2261 | 2261 | { |
| 2262 | − mutex_destroy(&esw->fdb_table.offloads.vports.lock); | |
| 2263 | 2262 | esw_destroy_vport_rx_group(esw); |
| 2264 | 2263 | esw_destroy_offloads_fdb_tables(esw); |
| 2265 | 2264 | esw_destroy_restore_table(esw); |
| 2266 | 2265 | esw_destroy_offloads_table(esw); |
| 2267 | 2266 | esw_destroy_uplink_offloads_acl_tables(esw); |
| 2267 | + mutex_destroy(&esw->fdb_table.offloads.vports.lock); | |
| 2268 | 2268 | } |
| 2269 | 2269 | |
| 2270 | 2270 | static void |
| @@ -2377,9 +2377,9 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) · 106 unmodified lines | ||
| 2377 | 2377 | err_vports: |
| 2378 | 2378 | esw_offloads_unload_rep(esw, MLX5_VPORT_UPLINK); |
| 2379 | 2379 | err_uplink: |
| 2380 | − esw_set_passing_vport_metadata(esw, false); | |
| 2381 | −err_steering_init: | |
| 2382 | 2380 | esw_offloads_steering_cleanup(esw); |
| 2381 | +err_steering_init: | |
| 2382 | + esw_set_passing_vport_metadata(esw, false); | |
| 2383 | 2383 | err_vport_metadata: |
| 2384 | 2384 | mlx5_rdma_disable_roce(esw->dev); |
| 2385 | 2385 | mutex_destroy(&esw->offloads.termtbl_mutex); |
| @@ -695,6 +695,12 @@ static void dr_cq_event(struct mlx5_core_cq *mcq, · 694 unmodified lines | ||
| 695 | 695 | pr_info("CQ event %u on CQ #%u\n", event, mcq->cqn); |
| 696 | 696 | } |
| 697 | 697 | |
| 698 | +static void dr_cq_complete(struct mlx5_core_cq *mcq, | |
| 699 | + struct mlx5_eqe *eqe) | |
| 700 | +{ | |
| 701 | + pr_err("CQ completion CQ: #%u\n", mcq->cqn); | |
| 702 | +} | |
| 703 | + | |
| 698 | 704 | static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, |
| 699 | 705 | struct mlx5_uars_page *uar, |
| 700 | 706 | size_t ncqe) |
| @@ -756,6 +762,7 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, · 55 unmodified lines | ||
| 756 | 762 | mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, pas); |
| 757 | 763 | |
| 758 | 764 | cq->mcq.event = dr_cq_event; |
| 765 | + cq->mcq.comp = dr_cq_complete; | |
| 759 | 766 | |
| 760 | 767 | err = mlx5_core_create_cq(mdev, &cq->mcq, in, inlen, out, sizeof(out)); |
| 761 | 768 | kvfree(in); |
| @@ -767,7 +774,12 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, · 5 unmodified lines | ||
| 767 | 774 | cq->mcq.set_ci_db = cq->wq_ctrl.db.db; |
| 768 | 775 | cq->mcq.arm_db = cq->wq_ctrl.db.db + 1; |
| 769 | 776 | *cq->mcq.set_ci_db = 0; |
| 770 | − *cq->mcq.arm_db = 0; | |
| 777 | + | |
| 778 | + /* set no-zero value, in order to avoid the HW to run db-recovery on | |
| 779 | + * CQ that used in polling mode. | |
| 780 | + */ | |
| 781 | + *cq->mcq.arm_db = cpu_to_be32(2 << 28); | |
| 782 | + | |
| 771 | 783 | cq->mcq.vector = 0; |
| 772 | 784 | cq->mcq.irqn = irqn; |
| 773 | 785 | cq->mcq.uar = uar; |
| @@ -986,8 +986,9 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp, · 985 unmodified lines | ||
| 986 | 986 | unsigned int priority, |
| 987 | 987 | struct mlxsw_afk_element_usage *elusage) |
| 988 | 988 | { |
| 989 | + struct mlxsw_sp_acl_tcam_vchunk *vchunk, *vchunk2; | |
| 989 | 990 | struct mlxsw_sp_acl_tcam_vregion *vregion; |
| 990 | − struct mlxsw_sp_acl_tcam_vchunk *vchunk; | |
| 991 | + struct list_head *pos; | |
| 991 | 992 | int err; |
| 992 | 993 | |
| 993 | 994 | if (priority == MLXSW_SP_ACL_TCAM_CATCHALL_PRIO) |
| @@ -1025,7 +1026,14 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp, · 31 unmodified lines | ||
| 1025 | 1026 | } |
| 1026 | 1027 | |
| 1027 | 1028 | mlxsw_sp_acl_tcam_rehash_ctx_vregion_changed(vregion); |
| 1028 | − list_add_tail(&vchunk->list, &vregion->vchunk_list); | |
| 1029 | + | |
| 1030 | + /* Position the vchunk inside the list according to priority */ | |
| 1031 | + list_for_each(pos, &vregion->vchunk_list) { | |
| 1032 | + vchunk2 = list_entry(pos, typeof(*vchunk2), list); | |
| 1033 | + if (vchunk2->priority > priority) | |
| 1034 | + break; | |
| 1035 | + } | |
| 1036 | + list_add_tail(&vchunk->list, pos); | |
| 1029 | 1037 | mutex_unlock(&vregion->lock); |
| 1030 | 1038 | |
| 1031 | 1039 | return vchunk; |
| @@ -36,7 +36,8 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, · 35 unmodified lines | ||
| 36 | 36 | err = mlxsw_sp_acl_rulei_act_count(mlxsw_sp, rulei, extack); |
| 37 | 37 | if (err) |
| 38 | 38 | return err; |
| 39 | − } else if (act->hw_stats != FLOW_ACTION_HW_STATS_DISABLED) { | |
| 39 | + } else if (act->hw_stats != FLOW_ACTION_HW_STATS_DISABLED && | |
| 40 | + act->hw_stats != FLOW_ACTION_HW_STATS_DONT_CARE) { | |
| 40 | 41 | NL_SET_ERR_MSG_MOD(extack, "Unsupported action HW stats type"); |
| 41 | 42 | return -EOPNOTSUPP; |
| 42 | 43 | } |
| @@ -564,7 +564,7 @@ static int moxart_remove(struct platform_device *pdev) · 563 unmodified lines | ||
| 564 | 564 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 565 | 565 | |
| 566 | 566 | unregister_netdev(ndev); |
| 567 | − free_irq(ndev->irq, ndev); | |
| 567 | + devm_free_irq(&pdev->dev, ndev->irq, ndev); | |
| 568 | 568 | moxart_mac_free_memory(ndev); |
| 569 | 569 | free_netdev(ndev); |
| 570 | 570 | |
| @@ -1031,10 +1031,8 @@ int ocelot_fdb_dump(struct ocelot *ocelot, int port, · 1030 unmodified lines | ||
| 1031 | 1031 | { |
| 1032 | 1032 | int i, j; |
| 1033 | 1033 | |
| 1034 | − /* Loop through all the mac tables entries. There are 1024 rows of 4 | |
| 1035 | − * entries. | |
| 1036 | − */ | |
| 1037 | − for (i = 0; i < 1024; i++) { | |
| 1034 | + /* Loop through all the mac tables entries. */ | |
| 1035 | + for (i = 0; i < ocelot->num_mact_rows; i++) { | |
| 1038 | 1036 | for (j = 0; j < 4; j++) { |
| 1039 | 1037 | struct ocelot_mact_entry entry; |
| 1040 | 1038 | bool is_static; |
| @@ -1453,8 +1451,15 @@ static void ocelot_port_attr_stp_state_set(struct ocelot *ocelot, int port, · 412 unmodified lines | ||
| 1453 | 1451 | |
| 1454 | 1452 | void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) |
| 1455 | 1453 | { |
| 1456 | − ocelot_write(ocelot, ANA_AUTOAGE_AGE_PERIOD(msecs / 2), | |
| 1457 | − ANA_AUTOAGE); | |
| 1454 | + unsigned int age_period = ANA_AUTOAGE_AGE_PERIOD(msecs / 2000); | |
| 1455 | + | |
| 1456 | + /* Setting AGE_PERIOD to zero effectively disables automatic aging, | |
| 1457 | + * which is clearly not what our intention is. So avoid that. | |
| 1458 | + */ | |
| 1459 | + if (!age_period) | |
| 1460 | + age_period = 1; | |
| 1461 | + | |
| 1462 | + ocelot_rmw(ocelot, age_period, ANA_AUTOAGE_AGE_PERIOD_M, ANA_AUTOAGE); | |
| 1458 | 1463 | } |
| 1459 | 1464 | EXPORT_SYMBOL(ocelot_set_ageing_time); |
| 1460 | 1465 | |
| @@ -431,6 +431,7 @@ int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops) · 430 unmodified lines | ||
| 431 | 431 | ocelot->stats_layout = ocelot_stats_layout; |
| 432 | 432 | ocelot->num_stats = ARRAY_SIZE(ocelot_stats_layout); |
| 433 | 433 | ocelot->shared_queue_sz = 224 * 1024; |
| 434 | + ocelot->num_mact_rows = 1024; | |
| 434 | 435 | ocelot->ops = ops; |
| 435 | 436 | |
| 436 | 437 | ret = ocelot_regfields_init(ocelot, ocelot_regfields); |
| @@ -208,11 +208,13 @@ static int jazz_sonic_probe(struct platform_device *pdev) · 207 unmodified lines | ||
| 208 | 208 | |
| 209 | 209 | err = register_netdev(dev); |
| 210 | 210 | if (err) |
| 211 | − goto out1; | |
| 211 | + goto undo_probe1; | |
| 212 | 212 | |
| 213 | 213 | return 0; |
| 214 | 214 | |
| 215 | −out1: | |
| 215 | +undo_probe1: | |
| 216 | + dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | |
| 217 | + lp->descriptors, lp->descriptors_laddr); | |
| 216 | 218 | release_mem_region(dev->base_addr, SONIC_MEM_SIZE); |
| 217 | 219 | out: |
| 218 | 220 | free_netdev(dev); |
| @@ -283,6 +283,7 @@ nfp_abm_vnic_set_mac(struct nfp_pf *pf, struct nfp_abm *abm, struct nfp_net *nn, · 282 unmodified lines | ||
| 283 | 283 | if (!nfp_nsp_has_hwinfo_lookup(nsp)) { |
| 284 | 284 | nfp_warn(pf->cpp, "NSP doesn't support PF MAC generation\n"); |
| 285 | 285 | eth_hw_addr_random(nn->dp.netdev); |
| 286 | + nfp_nsp_close(nsp); | |
| 286 | 287 | return; |
| 287 | 288 | } |
| 288 | 289 | |
| @@ -170,8 +170,7 @@ void ionic_debugfs_add_qcq(struct ionic_lif *lif, struct ionic_qcq *qcq) · 169 unmodified lines | ||
| 170 | 170 | debugfs_create_x64("base_pa", 0400, cq_dentry, &cq->base_pa); |
| 171 | 171 | debugfs_create_u32("num_descs", 0400, cq_dentry, &cq->num_descs); |
| 172 | 172 | debugfs_create_u32("desc_size", 0400, cq_dentry, &cq->desc_size); |
| 173 | − debugfs_create_u8("done_color", 0400, cq_dentry, | |
| 174 | − (u8 *)&cq->done_color); | |
| 173 | + debugfs_create_bool("done_color", 0400, cq_dentry, &cq->done_color); | |
| 175 | 174 | |
| 176 | 175 | debugfs_create_file("tail", 0400, cq_dentry, cq, &cq_tail_fops); |
| 177 | 176 | |
| @@ -2101,6 +2101,7 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif) · 2100 unmodified lines | ||
| 2101 | 2101 | ionic_txrx_free(lif); |
| 2102 | 2102 | } |
| 2103 | 2103 | ionic_lifs_deinit(ionic); |
| 2104 | + ionic_reset(ionic); | |
| 2104 | 2105 | ionic_qcqs_free(lif); |
| 2105 | 2106 | |
| 2106 | 2107 | dev_info(ionic->dev, "FW Down: LIFs stopped\n"); |
| @@ -2116,6 +2117,7 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif) · 9 unmodified lines | ||
| 2116 | 2117 | |
| 2117 | 2118 | dev_info(ionic->dev, "FW Up: restarting LIFs\n"); |
| 2118 | 2119 | |
| 2120 | + ionic_init_devinfo(ionic); | |
| 2119 | 2121 | err = ionic_qcqs_alloc(lif); |
| 2120 | 2122 | if (err) |
| 2121 | 2123 | goto err_out; |
| @@ -2549,8 +2551,6 @@ int ionic_lifs_register(struct ionic *ionic) · 427 unmodified lines | ||
| 2549 | 2551 | dev_err(ionic->dev, "Cannot register net device, aborting\n"); |
| 2550 | 2552 | return err; |
| 2551 | 2553 | } |
| 2552 | − | |
| 2553 | − ionic_link_status_check_request(ionic->master_lif); | |
| 2554 | 2554 | ionic->master_lif->registered = true; |
| 2555 | 2555 | |
| 2556 | 2556 | return 0; |
| @@ -624,7 +624,7 @@ int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, · 623 unmodified lines | ||
| 624 | 624 | total_offset += offset; |
| 625 | 625 | } |
| 626 | 626 | |
| 627 | − total_ctr = cfg->ctr[0] + cfg->ctr[1] * 1000000000; | |
| 627 | + total_ctr = cfg->ctr[0] + cfg->ctr[1] * 1000000000ULL; | |
| 628 | 628 | total_ctr += total_offset; |
| 629 | 629 | |
| 630 | 630 | ctr_low = do_div(total_ctr, 1000000000); |
| @@ -4060,7 +4060,7 @@ static int stmmac_set_features(struct net_device *netdev, · 4059 unmodified lines | ||
| 4060 | 4060 | /** |
| 4061 | 4061 | * stmmac_interrupt - main ISR |
| 4062 | 4062 | * @irq: interrupt number. |
| 4063 | − * @dev_id: to pass the net device pointer. | |
| 4063 | + * @dev_id: to pass the net device pointer (must be valid). | |
| 4064 | 4064 | * Description: this is the main driver interrupt service routine. |
| 4065 | 4065 | * It can call: |
| 4066 | 4066 | * o DMA service routine (to manage incoming frame reception and transmission |
| @@ -4084,11 +4084,6 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) · 17 unmodified lines | ||
| 4084 | 4084 | if (priv->irq_wake) |
| 4085 | 4085 | pm_wakeup_event(priv->device, 0); |
| 4086 | 4086 | |
| 4087 | − if (unlikely(!dev)) { | |
| 4088 | − netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); | |
| 4089 | − return IRQ_NONE; | |
| 4090 | − } | |
| 4091 | − | |
| 4092 | 4087 | /* Check if adapter is up */ |
| 4093 | 4088 | if (test_bit(STMMAC_DOWN, &priv->state)) |
| 4094 | 4089 | return IRQ_HANDLED; |
| @@ -4991,7 +4986,7 @@ int stmmac_dvr_probe(struct device *device, · 896 unmodified lines | ||
| 4991 | 4986 | priv->plat->bsp_priv); |
| 4992 | 4987 | |
| 4993 | 4988 | if (ret < 0) |
| 4994 | − return ret; | |
| 4989 | + goto error_serdes_powerup; | |
| 4995 | 4990 | } |
| 4996 | 4991 | |
| 4997 | 4992 | #ifdef CONFIG_DEBUG_FS |
| @@ -5000,6 +4995,8 @@ int stmmac_dvr_probe(struct device *device, · 2 unmodified lines | ||
| 5000 | 4995 | |
| 5001 | 4996 | return ret; |
| 5002 | 4997 | |
| 4998 | +error_serdes_powerup: | |
| 4999 | + unregister_netdev(ndev); | |
| 5003 | 5000 | error_netdev_register: |
| 5004 | 5001 | phylink_destroy(priv->phylink); |
| 5005 | 5002 | error_phy_setup: |
| @@ -90,9 +90,8 @@ config TI_CPTS · 89 unmodified lines | ||
| 90 | 90 | config TI_CPTS_MOD |
| 91 | 91 | tristate |
| 92 | 92 | depends on TI_CPTS |
| 93 | + depends on PTP_1588_CLOCK | |
| 93 | 94 | default y if TI_CPSW=y || TI_KEYSTONE_NETCP=y || TI_CPSW_SWITCHDEV=y |
| 94 | − select NET_PTP_CLASSIFY | |
| 95 | − imply PTP_1588_CLOCK | |
| 96 | 95 | default m |
| 97 | 96 | |
| 98 | 97 | config TI_K3_AM65_CPSW_NUSS |
| @@ -1719,7 +1719,8 @@ static int am65_cpsw_nuss_ndev_add_napi_2g(struct am65_cpsw_common *common) · 1718 unmodified lines | ||
| 1719 | 1719 | |
| 1720 | 1720 | ret = devm_request_irq(dev, tx_chn->irq, |
| 1721 | 1721 | am65_cpsw_nuss_tx_irq, |
| 1722 | − 0, tx_chn->tx_chn_name, tx_chn); | |
| 1722 | + IRQF_TRIGGER_HIGH, | |
| 1723 | + tx_chn->tx_chn_name, tx_chn); | |
| 1723 | 1724 | if (ret) { |
| 1724 | 1725 | dev_err(dev, "failure requesting tx%u irq %u, %d\n", |
| 1725 | 1726 | tx_chn->id, tx_chn->irq, ret); |
| @@ -1744,7 +1745,7 @@ static int am65_cpsw_nuss_ndev_reg_2g(struct am65_cpsw_common *common) · 18 unmodified lines | ||
| 1744 | 1745 | |
| 1745 | 1746 | ret = devm_request_irq(dev, common->rx_chns.irq, |
| 1746 | 1747 | am65_cpsw_nuss_rx_irq, |
| 1747 | − 0, dev_name(dev), common); | |
| 1748 | + IRQF_TRIGGER_HIGH, dev_name(dev), common); | |
| 1748 | 1749 | if (ret) { |
| 1749 | 1750 | dev_err(dev, "failure requesting rx irq %u, %d\n", |
| 1750 | 1751 | common->rx_chns.irq, ret); |
| @@ -643,7 +643,7 @@ static int tc_mii_probe(struct net_device *dev) · 642 unmodified lines | ||
| 643 | 643 | linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mask); |
| 644 | 644 | linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); |
| 645 | 645 | } |
| 646 | − linkmode_and(phydev->supported, phydev->supported, mask); | |
| 646 | + linkmode_andnot(phydev->supported, phydev->supported, mask); | |
| 647 | 647 | linkmode_copy(phydev->advertising, phydev->supported); |
| 648 | 648 | |
| 649 | 649 | lp->link = 0; |
| @@ -1169,11 +1169,11 @@ out_unlock: · 1168 unmodified lines | ||
| 1169 | 1169 | static struct genl_family gtp_genl_family; |
| 1170 | 1170 | |
| 1171 | 1171 | static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq, |
| 1172 | − u32 type, struct pdp_ctx *pctx) | |
| 1172 | + int flags, u32 type, struct pdp_ctx *pctx) | |
| 1173 | 1173 | { |
| 1174 | 1174 | void *genlh; |
| 1175 | 1175 | |
| 1176 | − genlh = genlmsg_put(skb, snd_portid, snd_seq, >p_genl_family, 0, | |
| 1176 | + genlh = genlmsg_put(skb, snd_portid, snd_seq, >p_genl_family, flags, | |
| 1177 | 1177 | type); |
| 1178 | 1178 | if (genlh == NULL) |
| 1179 | 1179 | goto nlmsg_failure; |
| @@ -1227,8 +1227,8 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info) · 47 unmodified lines | ||
| 1227 | 1227 | goto err_unlock; |
| 1228 | 1228 | } |
| 1229 | 1229 | |
| 1230 | − err = gtp_genl_fill_info(skb2, NETLINK_CB(skb).portid, | |
| 1231 | − info->snd_seq, info->nlhdr->nlmsg_type, pctx); | |
| 1230 | + err = gtp_genl_fill_info(skb2, NETLINK_CB(skb).portid, info->snd_seq, | |
| 1231 | + 0, info->nlhdr->nlmsg_type, pctx); | |
| 1232 | 1232 | if (err < 0) |
| 1233 | 1233 | goto err_unlock_free; |
| 1234 | 1234 | |
| @@ -1271,6 +1271,7 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb, · 36 unmodified lines | ||
| 1271 | 1271 | gtp_genl_fill_info(skb, |
| 1272 | 1272 | NETLINK_CB(cb->skb).portid, |
| 1273 | 1273 | cb->nlh->nlmsg_seq, |
| 1274 | + NLM_F_MULTI, | |
| 1274 | 1275 | cb->nlh->nlmsg_type, pctx)) { |
| 1275 | 1276 | cb->args[0] = i; |
| 1276 | 1277 | cb->args[1] = j; |
| @@ -707,7 +707,8 @@ no_memory: · 706 unmodified lines | ||
| 707 | 707 | goto drop; |
| 708 | 708 | } |
| 709 | 709 | |
| 710 | −static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |
| 710 | +static netdev_tx_t netvsc_start_xmit(struct sk_buff *skb, | |
| 711 | + struct net_device *ndev) | |
| 711 | 712 | { |
| 712 | 713 | return netvsc_xmit(skb, ndev, false); |
| 713 | 714 | } |
| @@ -1041,6 +1041,7 @@ static void gsi_isr_gp_int1(struct gsi *gsi) · 1040 unmodified lines | ||
| 1041 | 1041 | |
| 1042 | 1042 | complete(&gsi->completion); |
| 1043 | 1043 | } |
| 1044 | + | |
| 1044 | 1045 | /* Inter-EE interrupt handler */ |
| 1045 | 1046 | static void gsi_isr_glob_ee(struct gsi *gsi) |
| 1046 | 1047 | { |
| @@ -1493,6 +1494,12 @@ static int gsi_generic_command(struct gsi *gsi, u32 channel_id, · 446 unmodified lines | ||
| 1493 | 1494 | struct completion *completion = &gsi->completion; |
| 1494 | 1495 | u32 val; |
| 1495 | 1496 | |
| 1497 | + /* First zero the result code field */ | |
| 1498 | + val = ioread32(gsi->virt + GSI_CNTXT_SCRATCH_0_OFFSET); | |
| 1499 | + val &= ~GENERIC_EE_RESULT_FMASK; | |
| 1500 | + iowrite32(val, gsi->virt + GSI_CNTXT_SCRATCH_0_OFFSET); | |
| 1501 | + | |
| 1502 | + /* Now issue the command */ | |
| 1496 | 1503 | val = u32_encode_bits(opcode, GENERIC_OPCODE_FMASK); |
| 1497 | 1504 | val |= u32_encode_bits(channel_id, GENERIC_CHID_FMASK); |
| 1498 | 1505 | val |= u32_encode_bits(GSI_EE_MODEM, GENERIC_EE_FMASK); |
| @@ -1798,9 +1805,9 @@ static int gsi_channel_init_one(struct gsi *gsi, · 299 unmodified lines | ||
| 1798 | 1805 | |
| 1799 | 1806 | /* Worst case we need an event for every outstanding TRE */ |
| 1800 | 1807 | if (data->channel.tre_count > data->channel.event_count) { |
| 1801 | − dev_warn(gsi->dev, "channel %u limited to %u TREs\n", | |
| 1802 | − data->channel_id, data->channel.tre_count); | |
| 1803 | 1808 | tre_count = data->channel.event_count; |
| 1809 | + dev_warn(gsi->dev, "channel %u limited to %u TREs\n", | |
| 1810 | + data->channel_id, tre_count); | |
| 1804 | 1811 | } else { |
| 1805 | 1812 | tre_count = data->channel.tre_count; |
| 1806 | 1813 | } |
| @@ -410,6 +410,8 @@ · 409 unmodified lines | ||
| 410 | 410 | #define INTER_EE_RESULT_FMASK GENMASK(2, 0) |
| 411 | 411 | #define GENERIC_EE_RESULT_FMASK GENMASK(7, 5) |
| 412 | 412 | #define GENERIC_EE_SUCCESS_FVAL 1 |
| 413 | +#define GENERIC_EE_INCORRECT_DIRECTION_FVAL 3 | |
| 414 | +#define GENERIC_EE_INCORRECT_CHANNEL_FVAL 5 | |
| 413 | 415 | #define GENERIC_EE_NO_RESOURCES_FVAL 7 |
| 414 | 416 | #define USB_MAX_PACKET_FMASK GENMASK(15, 15) /* 0: HS; 1: SS */ |
| 415 | 417 | #define MHI_BASE_CHANNEL_FMASK GENMASK(31, 24) |
| @@ -1283,7 +1283,7 @@ static int ipa_endpoint_stop_rx_dma(struct ipa *ipa) · 1282 unmodified lines | ||
| 1283 | 1283 | */ |
| 1284 | 1284 | int ipa_endpoint_stop(struct ipa_endpoint *endpoint) |
| 1285 | 1285 | { |
| 1286 | − u32 retries = endpoint->toward_ipa ? 0 : IPA_ENDPOINT_STOP_RX_RETRIES; | |
| 1286 | + u32 retries = IPA_ENDPOINT_STOP_RX_RETRIES; | |
| 1287 | 1287 | int ret; |
| 1288 | 1288 | |
| 1289 | 1289 | do { |
| @@ -1291,12 +1291,9 @@ int ipa_endpoint_stop(struct ipa_endpoint *endpoint) · 1 unmodified line | ||
| 1291 | 1291 | struct gsi *gsi = &ipa->gsi; |
| 1292 | 1292 | |
| 1293 | 1293 | ret = gsi_channel_stop(gsi, endpoint->channel_id); |
| 1294 | − if (ret != -EAGAIN) | |
| 1294 | + if (ret != -EAGAIN || endpoint->toward_ipa) | |
| 1295 | 1295 | break; |
| 1296 | 1296 | |
| 1297 | − if (endpoint->toward_ipa) | |
| 1298 | − continue; | |
| 1299 | − | |
| 1300 | 1297 | /* For IPA v3.5.1, send a DMA read task and check again */ |
| 1301 | 1298 | if (ipa->version == IPA_VERSION_3_5_1) { |
| 1302 | 1299 | ret = ipa_endpoint_stop_rx_dma(ipa); |
| @@ -1305,7 +1305,8 @@ static struct crypto_aead *macsec_alloc_tfm(char *key, int key_len, int icv_len) · 1304 unmodified lines | ||
| 1305 | 1305 | struct crypto_aead *tfm; |
| 1306 | 1306 | int ret; |
| 1307 | 1307 | |
| 1308 | − tfm = crypto_alloc_aead("gcm(aes)", 0, 0); | |
| 1308 | + /* Pick a sync gcm(aes) cipher to ensure order is preserved. */ | |
| 1309 | + tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); | |
| 1309 | 1310 | |
| 1310 | 1311 | if (IS_ERR(tfm)) |
| 1311 | 1312 | return tfm; |
| @@ -2640,11 +2641,12 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info) · 1328 unmodified lines | ||
| 2640 | 2641 | if (ret) |
| 2641 | 2642 | goto rollback; |
| 2642 | 2643 | |
| 2643 | − rtnl_unlock(); | |
| 2644 | 2644 | /* Force features update, since they are different for SW MACSec and |
| 2645 | 2645 | * HW offloading cases. |
| 2646 | 2646 | */ |
| 2647 | 2647 | netdev_update_features(dev); |
| 2648 | + | |
| 2649 | + rtnl_unlock(); | |
| 2648 | 2650 | return 0; |
| 2649 | 2651 | |
| 2650 | 2652 | rollback: |
| @@ -1120,7 +1120,7 @@ static struct dp83640_clock *dp83640_clock_get_bus(struct mii_bus *bus) · 1119 unmodified lines | ||
| 1120 | 1120 | goto out; |
| 1121 | 1121 | } |
| 1122 | 1122 | dp83640_clock_init(clock, bus); |
| 1123 | − list_add_tail(&phyter_clocks, &clock->list); | |
| 1123 | + list_add_tail(&clock->list, &phyter_clocks); | |
| 1124 | 1124 | out: |
| 1125 | 1125 | mutex_unlock(&phyter_clocks_lock); |
| 1126 | 1126 | |
| @@ -137,19 +137,18 @@ static int dp83822_set_wol(struct phy_device *phydev, · 136 unmodified lines | ||
| 137 | 137 | value &= ~DP83822_WOL_SECURE_ON; |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | − value |= (DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL | | |
| 141 | − DP83822_WOL_CLR_INDICATION); | |
| 142 | − phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, | |
| 143 | − value); | |
| 140 | + /* Clear any pending WoL interrupt */ | |
| 141 | + phy_read(phydev, MII_DP83822_MISR2); | |
| 142 | + | |
| 143 | + value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL | | |
| 144 | + DP83822_WOL_CLR_INDICATION; | |
| 145 | + | |
| 146 | + return phy_write_mmd(phydev, DP83822_DEVADDR, | |
| 147 | + MII_DP83822_WOL_CFG, value); | |
| 144 | 148 | } else { |
| 145 | − value = phy_read_mmd(phydev, DP83822_DEVADDR, | |
| 146 | − MII_DP83822_WOL_CFG); | |
| 147 | − value &= ~DP83822_WOL_EN; | |
| 148 | − phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, | |
| 149 | − value); | |
| 149 | + return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, | |
| 150 | + MII_DP83822_WOL_CFG, DP83822_WOL_EN); | |
| 150 | 151 | } |
| 151 | − | |
| 152 | − return 0; | |
| 153 | 152 | } |
| 154 | 153 | |
| 155 | 154 | static void dp83822_get_wol(struct phy_device *phydev, |
| @@ -258,12 +257,11 @@ static int dp83822_config_intr(struct phy_device *phydev) · 102 unmodified lines | ||
| 258 | 257 | |
| 259 | 258 | static int dp83822_config_init(struct phy_device *phydev) |
| 260 | 259 | { |
| 261 | − int value; | |
| 262 | − | |
| 263 | − value = DP83822_WOL_MAGIC_EN | DP83822_WOL_SECURE_ON | DP83822_WOL_EN; | |
| 260 | + int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | | |
| 261 | + DP83822_WOL_SECURE_ON; | |
| 264 | 262 | |
| 265 | − return phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, | |
| 266 | − value); | |
| 263 | + return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, | |
| 264 | + MII_DP83822_WOL_CFG, value); | |
| 267 | 265 | } |
| 268 | 266 | |
| 269 | 267 | static int dp83822_phy_reset(struct phy_device *phydev) |
| @@ -139,16 +139,19 @@ static int dp83811_set_wol(struct phy_device *phydev, · 138 unmodified lines | ||
| 139 | 139 | value &= ~DP83811_WOL_SECURE_ON; |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | − value |= (DP83811_WOL_EN | DP83811_WOL_INDICATION_SEL | | |
| 143 | − DP83811_WOL_CLR_INDICATION); | |
| 144 | − phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG, | |
| 145 | − value); | |
| 142 | + /* Clear any pending WoL interrupt */ | |
| 143 | + phy_read(phydev, MII_DP83811_INT_STAT1); | |
| 144 | + | |
| 145 | + value |= DP83811_WOL_EN | DP83811_WOL_INDICATION_SEL | | |
| 146 | + DP83811_WOL_CLR_INDICATION; | |
| 147 | + | |
| 148 | + return phy_write_mmd(phydev, DP83811_DEVADDR, | |
| 149 | + MII_DP83811_WOL_CFG, value); | |
| 146 | 150 | } else { |
| 147 | − phy_clear_bits_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG, | |
| 148 | − DP83811_WOL_EN); | |
| 151 | + return phy_clear_bits_mmd(phydev, DP83811_DEVADDR, | |
| 152 | + MII_DP83811_WOL_CFG, DP83811_WOL_EN); | |
| 149 | 153 | } |
| 150 | 154 | |
| 151 | − return 0; | |
| 152 | 155 | } |
| 153 | 156 | |
| 154 | 157 | static void dp83811_get_wol(struct phy_device *phydev, |
| @@ -292,8 +295,8 @@ static int dp83811_config_init(struct phy_device *phydev) · 137 unmodified lines | ||
| 292 | 295 | |
| 293 | 296 | value = DP83811_WOL_MAGIC_EN | DP83811_WOL_SECURE_ON | DP83811_WOL_EN; |
| 294 | 297 | |
| 295 | − return phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG, | |
| 296 | − value); | |
| 298 | + return phy_clear_bits_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG, | |
| 299 | + value); | |
| 297 | 300 | } |
| 298 | 301 | |
| 299 | 302 | static int dp83811_phy_reset(struct phy_device *phydev) |
| @@ -66,6 +66,9 @@ enum { · 65 unmodified lines | ||
| 66 | 66 | MV_PCS_CSSR1_SPD2_2500 = 0x0004, |
| 67 | 67 | MV_PCS_CSSR1_SPD2_10000 = 0x0000, |
| 68 | 68 | |
| 69 | + /* Temperature read register (88E2110 only) */ | |
| 70 | + MV_PCS_TEMP = 0x8042, | |
| 71 | + | |
| 69 | 72 | /* These registers appear at 0x800X and 0xa00X - the 0xa00X control |
| 70 | 73 | * registers appear to set themselves to the 0x800X when AN is |
| 71 | 74 | * restarted, but status registers appear readable from either. |
| @@ -77,6 +80,7 @@ enum { · 5 unmodified lines | ||
| 77 | 80 | MV_V2_PORT_CTRL = 0xf001, |
| 78 | 81 | MV_V2_PORT_CTRL_SWRST = BIT(15), |
| 79 | 82 | MV_V2_PORT_CTRL_PWRDOWN = BIT(11), |
| 83 | + /* Temperature control/read registers (88X3310 only) */ | |
| 80 | 84 | MV_V2_TEMP_CTRL = 0xf08a, |
| 81 | 85 | MV_V2_TEMP_CTRL_MASK = 0xc000, |
| 82 | 86 | MV_V2_TEMP_CTRL_SAMPLE = 0x0000, |
| @@ -104,6 +108,24 @@ static umode_t mv3310_hwmon_is_visible(const void *data, · 21 unmodified lines | ||
| 104 | 108 | return 0; |
| 105 | 109 | } |
| 106 | 110 | |
| 111 | +static int mv3310_hwmon_read_temp_reg(struct phy_device *phydev) | |
| 112 | +{ | |
| 113 | + return phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP); | |
| 114 | +} | |
| 115 | + | |
| 116 | +static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev) | |
| 117 | +{ | |
| 118 | + return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP); | |
| 119 | +} | |
| 120 | + | |
| 121 | +static int mv10g_hwmon_read_temp_reg(struct phy_device *phydev) | |
| 122 | +{ | |
| 123 | + if (phydev->drv->phy_id == MARVELL_PHY_ID_88X3310) | |
| 124 | + return mv3310_hwmon_read_temp_reg(phydev); | |
| 125 | + else /* MARVELL_PHY_ID_88E2110 */ | |
| 126 | + return mv2110_hwmon_read_temp_reg(phydev); | |
| 127 | +} | |
| 128 | + | |
| 107 | 129 | static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type, |
| 108 | 130 | u32 attr, int channel, long *value) |
| 109 | 131 | { |
| @@ -116,7 +138,7 @@ static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type, · 6 unmodified lines | ||
| 116 | 138 | } |
| 117 | 139 | |
| 118 | 140 | if (type == hwmon_temp && attr == hwmon_temp_input) { |
| 119 | − temp = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP); | |
| 141 | + temp = mv10g_hwmon_read_temp_reg(phydev); | |
| 120 | 142 | if (temp < 0) |
| 121 | 143 | return temp; |
| 122 | 144 | |
| @@ -169,6 +191,9 @@ static int mv3310_hwmon_config(struct phy_device *phydev, bool enable) · 46 unmodified lines | ||
| 169 | 191 | u16 val; |
| 170 | 192 | int ret; |
| 171 | 193 | |
| 194 | + if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310) | |
| 195 | + return 0; | |
| 196 | + | |
| 172 | 197 | ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP, |
| 173 | 198 | MV_V2_TEMP_UNKNOWN); |
| 174 | 199 | if (ret < 0) |
| @@ -1359,6 +1359,7 @@ static const struct usb_device_id products[] = { · 1358 unmodified lines | ||
| 1359 | 1359 | {QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ |
| 1360 | 1360 | {QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */ |
| 1361 | 1361 | {QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */ |
| 1362 | + {QMI_FIXED_INTF(0x413c, 0x81cc, 8)}, /* Dell Wireless 5816e */ | |
| 1362 | 1363 | {QMI_FIXED_INTF(0x413c, 0x81d7, 0)}, /* Dell Wireless 5821e */ |
| 1363 | 1364 | {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e preproduction config */ |
| 1364 | 1365 | {QMI_FIXED_INTF(0x413c, 0x81e0, 0)}, /* Dell Wireless 5821e with eSIM support*/ |
| @@ -35,8 +35,10 @@ int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function, · 34 unmodified lines | ||
| 35 | 35 | if (multicore) { |
| 36 | 36 | queue->worker = wg_packet_percpu_multicore_worker_alloc( |
| 37 | 37 | function, queue); |
| 38 | − if (!queue->worker) | |
| 38 | + if (!queue->worker) { | |
| 39 | + ptr_ring_cleanup(&queue->ring, NULL); | |
| 39 | 40 | return -ENOMEM; |
| 41 | + } | |
| 40 | 42 | } else { |
| 41 | 43 | INIT_WORK(&queue->work, function); |
| 42 | 44 | } |
| @@ -226,21 +226,20 @@ void wg_packet_handshake_receive_worker(struct work_struct *work) · 225 unmodified lines | ||
| 226 | 226 | static void keep_key_fresh(struct wg_peer *peer) |
| 227 | 227 | { |
| 228 | 228 | struct noise_keypair *keypair; |
| 229 | − bool send = false; | |
| 229 | + bool send; | |
| 230 | 230 | |
| 231 | 231 | if (peer->sent_lastminute_handshake) |
| 232 | 232 | return; |
| 233 | 233 | |
| 234 | 234 | rcu_read_lock_bh(); |
| 235 | 235 | keypair = rcu_dereference_bh(peer->keypairs.current_keypair); |
| 236 | − if (likely(keypair && READ_ONCE(keypair->sending.is_valid)) && | |
| 237 | − keypair->i_am_the_initiator && | |
| 238 | − unlikely(wg_birthdate_has_expired(keypair->sending.birthdate, | |
| 239 | − REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT))) | |
| 240 | − send = true; | |
| 236 | + send = keypair && READ_ONCE(keypair->sending.is_valid) && | |
| 237 | + keypair->i_am_the_initiator && | |
| 238 | + wg_birthdate_has_expired(keypair->sending.birthdate, | |
| 239 | + REJECT_AFTER_TIME - KEEPALIVE_TIMEOUT - REKEY_TIMEOUT); | |
| 241 | 240 | rcu_read_unlock_bh(); |
| 242 | 241 | |
| 243 | − if (send) { | |
| 242 | + if (unlikely(send)) { | |
| 244 | 243 | peer->sent_lastminute_handshake = true; |
| 245 | 244 | wg_packet_send_queued_handshake_initiation(peer, false); |
| 246 | 245 | } |
| @@ -393,13 +392,11 @@ static void wg_packet_consume_data_done(struct wg_peer *peer, · 146 unmodified lines | ||
| 393 | 392 | len = ntohs(ip_hdr(skb)->tot_len); |
| 394 | 393 | if (unlikely(len < sizeof(struct iphdr))) |
| 395 | 394 | goto dishonest_packet_size; |
| 396 | − if (INET_ECN_is_ce(PACKET_CB(skb)->ds)) | |
| 397 | − IP_ECN_set_ce(ip_hdr(skb)); | |
| 395 | + INET_ECN_decapsulate(skb, PACKET_CB(skb)->ds, ip_hdr(skb)->tos); | |
| 398 | 396 | } else if (skb->protocol == htons(ETH_P_IPV6)) { |
| 399 | 397 | len = ntohs(ipv6_hdr(skb)->payload_len) + |
| 400 | 398 | sizeof(struct ipv6hdr); |
| 401 | − if (INET_ECN_is_ce(PACKET_CB(skb)->ds)) | |
| 402 | − IP6_ECN_set_ce(skb, ipv6_hdr(skb)); | |
| 399 | + INET_ECN_decapsulate(skb, PACKET_CB(skb)->ds, ipv6_get_dsfield(ipv6_hdr(skb))); | |
| 403 | 400 | } else { |
| 404 | 401 | goto dishonest_packet_type; |
| 405 | 402 | } |
| @@ -518,6 +515,8 @@ void wg_packet_decrypt_worker(struct work_struct *work) · 112 unmodified lines | ||
| 518 | 515 | &PACKET_CB(skb)->keypair->receiving)) ? |
| 519 | 516 | PACKET_STATE_CRYPTED : PACKET_STATE_DEAD; |
| 520 | 517 | wg_queue_enqueue_per_peer_napi(skb, state); |
| 518 | + if (need_resched()) | |
| 519 | + cond_resched(); | |
| 521 | 520 | } |
| 522 | 521 | } |
| 523 | 522 | |
| @@ -120,9 +120,9 @@ bool __init wg_ratelimiter_selftest(void) · 119 unmodified lines | ||
| 120 | 120 | enum { TRIALS_BEFORE_GIVING_UP = 5000 }; |
| 121 | 121 | bool success = false; |
| 122 | 122 | int test = 0, trials; |
| 123 | − struct sk_buff *skb4, *skb6; | |
| 123 | + struct sk_buff *skb4, *skb6 = NULL; | |
| 124 | 124 | struct iphdr *hdr4; |
| 125 | − struct ipv6hdr *hdr6; | |
| 125 | + struct ipv6hdr *hdr6 = NULL; | |
| 126 | 126 | |
| 127 | 127 | if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN)) |
| 128 | 128 | return true; |
| @@ -124,20 +124,17 @@ void wg_packet_send_handshake_cookie(struct wg_device *wg, · 123 unmodified lines | ||
| 124 | 124 | static void keep_key_fresh(struct wg_peer *peer) |
| 125 | 125 | { |
| 126 | 126 | struct noise_keypair *keypair; |
| 127 | − bool send = false; | |
| 127 | + bool send; | |
| 128 | 128 | |
| 129 | 129 | rcu_read_lock_bh(); |
| 130 | 130 | keypair = rcu_dereference_bh(peer->keypairs.current_keypair); |
| 131 | − if (likely(keypair && READ_ONCE(keypair->sending.is_valid)) && | |
| 132 | − (unlikely(atomic64_read(&keypair->sending.counter.counter) > | |
| 133 | − REKEY_AFTER_MESSAGES) || | |
| 134 | − (keypair->i_am_the_initiator && | |
| 135 | − unlikely(wg_birthdate_has_expired(keypair->sending.birthdate, | |
| 136 | − REKEY_AFTER_TIME))))) | |
| 137 | − send = true; | |
| 131 | + send = keypair && READ_ONCE(keypair->sending.is_valid) && | |
| 132 | + (atomic64_read(&keypair->sending.counter.counter) > REKEY_AFTER_MESSAGES || | |
| 133 | + (keypair->i_am_the_initiator && | |
| 134 | + wg_birthdate_has_expired(keypair->sending.birthdate, REKEY_AFTER_TIME))); | |
| 138 | 135 | rcu_read_unlock_bh(); |
| 139 | 136 | |
| 140 | − if (send) | |
| 137 | + if (unlikely(send)) | |
| 141 | 138 | wg_packet_send_queued_handshake_initiation(peer, false); |
| 142 | 139 | } |
| 143 | 140 | |
| @@ -281,6 +278,8 @@ void wg_packet_tx_worker(struct work_struct *work) · 137 unmodified lines | ||
| 281 | 278 | |
| 282 | 279 | wg_noise_keypair_put(keypair, false); |
| 283 | 280 | wg_peer_put(peer); |
| 281 | + if (need_resched()) | |
| 282 | + cond_resched(); | |
| 284 | 283 | } |
| 285 | 284 | } |
| 286 | 285 | |
| @@ -304,7 +303,8 @@ void wg_packet_encrypt_worker(struct work_struct *work) · 17 unmodified lines | ||
| 304 | 303 | } |
| 305 | 304 | wg_queue_enqueue_per_peer(&PACKET_PEER(first)->tx_queue, first, |
| 306 | 305 | state); |
| 307 | − | |
| 306 | + if (need_resched()) | |
| 307 | + cond_resched(); | |
| 308 | 308 | } |
| 309 | 309 | } |
| 310 | 310 | |
| @@ -76,12 +76,6 @@ static int send4(struct wg_device *wg, struct sk_buff *skb, · 75 unmodified lines | ||
| 76 | 76 | net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", |
| 77 | 77 | wg->dev->name, &endpoint->addr, ret); |
| 78 | 78 | goto err; |
| 79 | − } else if (unlikely(rt->dst.dev == skb->dev)) { | |
| 80 | − ip_rt_put(rt); | |
| 81 | − ret = -ELOOP; | |
| 82 | − net_dbg_ratelimited("%s: Avoiding routing loop to %pISpfsc\n", | |
| 83 | − wg->dev->name, &endpoint->addr); | |
| 84 | − goto err; | |
| 85 | 79 | } |
| 86 | 80 | if (cache) |
| 87 | 81 | dst_cache_set_ip4(cache, &rt->dst, fl.saddr); |
| @@ -149,12 +143,6 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, · 61 unmodified lines | ||
| 149 | 143 | net_dbg_ratelimited("%s: No route to %pISpfsc, error %d\n", |
| 150 | 144 | wg->dev->name, &endpoint->addr, ret); |
| 151 | 145 | goto err; |
| 152 | − } else if (unlikely(dst->dev == skb->dev)) { | |
| 153 | − dst_release(dst); | |
| 154 | − ret = -ELOOP; | |
| 155 | − net_dbg_ratelimited("%s: Avoiding routing loop to %pISpfsc\n", | |
| 156 | − wg->dev->name, &endpoint->addr); | |
| 157 | − goto err; | |
| 158 | 146 | } |
| 159 | 147 | if (cache) |
| 160 | 148 | dst_cache_set_ip6(cache, dst, &fl.saddr); |
| @@ -1110,7 +1110,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid, · 1109 unmodified lines | ||
| 1110 | 1110 | * Don't treat an error as fatal, as we potentially already |
| 1111 | 1111 | * have a NGUID or EUI-64. |
| 1112 | 1112 | */ |
| 1113 | − if (status > 0) | |
| 1113 | + if (status > 0 && !(status & NVME_SC_DNR)) | |
| 1114 | 1114 | status = 0; |
| 1115 | 1115 | goto free_data; |
| 1116 | 1116 | } |
| @@ -3642,6 +3642,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) · 2525 unmodified lines | ||
| 3642 | 3642 | |
| 3643 | 3643 | return; |
| 3644 | 3644 | out_put_disk: |
| 3645 | + /* prevent double queue cleanup */ | |
| 3646 | + ns->disk->queue = NULL; | |
| 3645 | 3647 | put_disk(ns->disk); |
| 3646 | 3648 | out_unlink_ns: |
| 3647 | 3649 | mutex_lock(&ctrl->subsys->lock); |
| @@ -973,9 +973,13 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) · 972 unmodified lines | ||
| 973 | 973 | |
| 974 | 974 | static inline void nvme_update_cq_head(struct nvme_queue *nvmeq) |
| 975 | 975 | { |
| 976 | − if (++nvmeq->cq_head == nvmeq->q_depth) { | |
| 976 | + u16 tmp = nvmeq->cq_head + 1; | |
| 977 | + | |
| 978 | + if (tmp == nvmeq->q_depth) { | |
| 977 | 979 | nvmeq->cq_head = 0; |
| 978 | 980 | nvmeq->cq_phase ^= 1; |
| 981 | + } else { | |
| 982 | + nvmeq->cq_head = tmp; | |
| 979 | 983 | } |
| 980 | 984 | } |
| 981 | 985 | |
| @@ -815,6 +815,13 @@ static const struct of_device_id qusb2_phy_of_match_table[] = { · 814 unmodified lines | ||
| 815 | 815 | }, { |
| 816 | 816 | .compatible = "qcom,msm8998-qusb2-phy", |
| 817 | 817 | .data = &msm8998_phy_cfg, |
| 818 | + }, { | |
| 819 | + /* | |
| 820 | + * Deprecated. Only here to support legacy device | |
| 821 | + * trees that didn't include "qcom,qusb2-v2-phy" | |
| 822 | + */ | |
| 823 | + .compatible = "qcom,sdm845-qusb2-phy", | |
| 824 | + .data = &qusb2_v2_phy_cfg, | |
| 818 | 825 | }, { |
| 819 | 826 | .compatible = "qcom,qusb2-v2-phy", |
| 820 | 827 | .data = &qusb2_v2_phy_cfg, |
| @@ -160,18 +160,11 @@ static int qcom_snps_hsphy_power_on(struct phy *phy) · 159 unmodified lines | ||
| 160 | 160 | ret = regulator_bulk_enable(VREG_NUM, priv->vregs); |
| 161 | 161 | if (ret) |
| 162 | 162 | return ret; |
| 163 | − ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); | |
| 164 | − if (ret) | |
| 165 | − goto err_disable_regulator; | |
| 163 | + | |
| 166 | 164 | qcom_snps_hsphy_disable_hv_interrupts(priv); |
| 167 | 165 | qcom_snps_hsphy_exit_retention(priv); |
| 168 | 166 | |
| 169 | 167 | return 0; |
| 170 | − | |
| 171 | −err_disable_regulator: | |
| 172 | − regulator_bulk_disable(VREG_NUM, priv->vregs); | |
| 173 | − | |
| 174 | − return ret; | |
| 175 | 168 | } |
| 176 | 169 | |
| 177 | 170 | static int qcom_snps_hsphy_power_off(struct phy *phy) |
| @@ -180,7 +173,6 @@ static int qcom_snps_hsphy_power_off(struct phy *phy) · 2 unmodified lines | ||
| 180 | 173 | |
| 181 | 174 | qcom_snps_hsphy_enter_retention(priv); |
| 182 | 175 | qcom_snps_hsphy_enable_hv_interrupts(priv); |
| 183 | − clk_bulk_disable_unprepare(priv->num_clks, priv->clks); | |
| 184 | 176 | regulator_bulk_disable(VREG_NUM, priv->vregs); |
| 185 | 177 | |
| 186 | 178 | return 0; |
| @@ -266,21 +258,39 @@ static int qcom_snps_hsphy_init(struct phy *phy) · 79 unmodified lines | ||
| 266 | 258 | struct hsphy_priv *priv = phy_get_drvdata(phy); |
| 267 | 259 | int ret; |
| 268 | 260 | |
| 269 | − ret = qcom_snps_hsphy_reset(priv); | |
| 261 | + ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); | |
| 270 | 262 | if (ret) |
| 271 | 263 | return ret; |
| 272 | 264 | |
| 265 | + ret = qcom_snps_hsphy_reset(priv); | |
| 266 | + if (ret) | |
| 267 | + goto disable_clocks; | |
| 268 | + | |
| 273 | 269 | qcom_snps_hsphy_init_sequence(priv); |
| 274 | 270 | |
| 275 | 271 | ret = qcom_snps_hsphy_por_reset(priv); |
| 276 | 272 | if (ret) |
| 277 | − return ret; | |
| 273 | + goto disable_clocks; | |
| 274 | + | |
| 275 | + return 0; | |
| 276 | + | |
| 277 | +disable_clocks: | |
| 278 | + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); | |
| 279 | + return ret; | |
| 280 | +} | |
| 281 | + | |
| 282 | +static int qcom_snps_hsphy_exit(struct phy *phy) | |
| 283 | +{ | |
| 284 | + struct hsphy_priv *priv = phy_get_drvdata(phy); | |
| 285 | + | |
| 286 | + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); | |
| 278 | 287 | |
| 279 | 288 | return 0; |
| 280 | 289 | } |
| 281 | 290 | |
| 282 | 291 | static const struct phy_ops qcom_snps_hsphy_ops = { |
| 283 | 292 | .init = qcom_snps_hsphy_init, |
| 293 | + .exit = qcom_snps_hsphy_exit, | |
| 284 | 294 | .power_on = qcom_snps_hsphy_power_on, |
| 285 | 295 | .power_off = qcom_snps_hsphy_power_off, |
| 286 | 296 | .set_mode = qcom_snps_hsphy_set_mode, |
| @@ -52,28 +52,15 @@ static int cros_ec_sensorhub_register(struct device *dev, · 51 unmodified lines | ||
| 52 | 52 | int sensor_type[MOTIONSENSE_TYPE_MAX] = { 0 }; |
| 53 | 53 | struct cros_ec_command *msg = sensorhub->msg; |
| 54 | 54 | struct cros_ec_dev *ec = sensorhub->ec; |
| 55 | − int ret, i, sensor_num; | |
| 55 | + int ret, i; | |
| 56 | 56 | char *name; |
| 57 | 57 | |
| 58 | − sensor_num = cros_ec_get_sensor_count(ec); | |
| 59 | − if (sensor_num < 0) { | |
| 60 | − dev_err(dev, | |
| 61 | − "Unable to retrieve sensor information (err:%d)\n", | |
| 62 | − sensor_num); | |
| 63 | − return sensor_num; | |
| 64 | − } | |
| 65 | − | |
| 66 | − sensorhub->sensor_num = sensor_num; | |
| 67 | − if (sensor_num == 0) { | |
| 68 | − dev_err(dev, "Zero sensors reported.\n"); | |
| 69 | − return -EINVAL; | |
| 70 | − } | |
| 71 | 58 | |
| 72 | 59 | msg->version = 1; |
| 73 | 60 | msg->insize = sizeof(struct ec_response_motion_sense); |
| 74 | 61 | msg->outsize = sizeof(struct ec_params_motion_sense); |
| 75 | 62 | |
| 76 | − for (i = 0; i < sensor_num; i++) { | |
| 63 | + for (i = 0; i < sensorhub->sensor_num; i++) { | |
| 77 | 64 | sensorhub->params->cmd = MOTIONSENSE_CMD_INFO; |
| 78 | 65 | sensorhub->params->info.sensor_num = i; |
| 79 | 66 | |
| @@ -140,8 +127,7 @@ static int cros_ec_sensorhub_probe(struct platform_device *pdev) · 60 unmodified lines | ||
| 140 | 127 | struct cros_ec_dev *ec = dev_get_drvdata(dev->parent); |
| 141 | 128 | struct cros_ec_sensorhub *data; |
| 142 | 129 | struct cros_ec_command *msg; |
| 143 | − int ret; | |
| 144 | − int i; | |
| 130 | + int ret, i, sensor_num; | |
| 145 | 131 | |
| 146 | 132 | msg = devm_kzalloc(dev, sizeof(struct cros_ec_command) + |
| 147 | 133 | max((u16)sizeof(struct ec_params_motion_sense), |
| @@ -166,10 +152,52 @@ static int cros_ec_sensorhub_probe(struct platform_device *pdev) · 18 unmodified lines | ||
| 166 | 152 | dev_set_drvdata(dev, data); |
| 167 | 153 | |
| 168 | 154 | /* Check whether this EC is a sensor hub. */ |
| 169 | − if (cros_ec_check_features(data->ec, EC_FEATURE_MOTION_SENSE)) { | |
| 155 | + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) { | |
| 156 | + sensor_num = cros_ec_get_sensor_count(ec); | |
| 157 | + if (sensor_num < 0) { | |
| 158 | + dev_err(dev, | |
| 159 | + "Unable to retrieve sensor information (err:%d)\n", | |
| 160 | + sensor_num); | |
| 161 | + return sensor_num; | |
| 162 | + } | |
| 163 | + if (sensor_num == 0) { | |
| 164 | + dev_err(dev, "Zero sensors reported.\n"); | |
| 165 | + return -EINVAL; | |
| 166 | + } | |
| 167 | + data->sensor_num = sensor_num; | |
| 168 | + | |
| 169 | + /* | |
| 170 | + * Prepare the ring handler before enumering the | |
| 171 | + * sensors. | |
| 172 | + */ | |
| 173 | + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { | |
| 174 | + ret = cros_ec_sensorhub_ring_allocate(data); | |
| 175 | + if (ret) | |
| 176 | + return ret; | |
| 177 | + } | |
| 178 | + | |
| 179 | + /* Enumerate the sensors.*/ | |
| 170 | 180 | ret = cros_ec_sensorhub_register(dev, data); |
| 171 | 181 | if (ret) |
| 172 | 182 | return ret; |
| 183 | + | |
| 184 | + /* | |
| 185 | + * When the EC does not have a FIFO, the sensors will query | |
| 186 | + * their data themselves via sysfs or a software trigger. | |
| 187 | + */ | |
| 188 | + if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { | |
| 189 | + ret = cros_ec_sensorhub_ring_add(data); | |
| 190 | + if (ret) | |
| 191 | + return ret; | |
| 192 | + /* | |
| 193 | + * The msg and its data is not under the control of the | |
| 194 | + * ring handler. | |
| 195 | + */ | |
| 196 | + return devm_add_action_or_reset(dev, | |
| 197 | + cros_ec_sensorhub_ring_remove, | |
| 198 | + data); | |
| 199 | + } | |
| 200 | + | |
| 173 | 201 | } else { |
| 174 | 202 | /* |
| 175 | 203 | * If the device has sensors but does not claim to |
| @@ -184,22 +212,6 @@ static int cros_ec_sensorhub_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 184 | 212 | } |
| 185 | 213 | } |
| 186 | 214 | |
| 187 | − /* | |
| 188 | − * If the EC does not have a FIFO, the sensors will query their data | |
| 189 | − * themselves via sysfs or a software trigger. | |
| 190 | − */ | |
| 191 | − if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) { | |
| 192 | − ret = cros_ec_sensorhub_ring_add(data); | |
| 193 | − if (ret) | |
| 194 | − return ret; | |
| 195 | − /* | |
| 196 | − * The msg and its data is not under the control of the ring | |
| 197 | − * handler. | |
| 198 | − */ | |
| 199 | − return devm_add_action_or_reset(dev, | |
| 200 | − cros_ec_sensorhub_ring_remove, | |
| 201 | − data); | |
| 202 | − } | |
| 203 | 215 | |
| 204 | 216 | return 0; |
| 205 | 217 | } |
| @@ -957,17 +957,15 @@ static int cros_ec_sensorhub_event(struct notifier_block *nb, · 956 unmodified lines | ||
| 957 | 957 | } |
| 958 | 958 | |
| 959 | 959 | /** |
| 960 | − * cros_ec_sensorhub_ring_add() - Add the FIFO functionality if the EC | |
| 961 | − * supports it. | |
| 960 | + * cros_ec_sensorhub_ring_allocate() - Prepare the FIFO functionality if the EC | |
| 961 | + * supports it. | |
| 962 | 962 | * |
| 963 | 963 | * @sensorhub : Sensor Hub object. |
| 964 | 964 | * |
| 965 | 965 | * Return: 0 on success. |
| 966 | 966 | */ |
| 967 | −int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub) | |
| 967 | +int cros_ec_sensorhub_ring_allocate(struct cros_ec_sensorhub *sensorhub) | |
| 968 | 968 | { |
| 969 | − struct cros_ec_dev *ec = sensorhub->ec; | |
| 970 | − int ret; | |
| 971 | 969 | int fifo_info_length = |
| 972 | 970 | sizeof(struct ec_response_motion_sense_fifo_info) + |
| 973 | 971 | sizeof(u16) * sensorhub->sensor_num; |
| @@ -978,6 +976,49 @@ int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub) · 4 unmodified lines | ||
| 978 | 976 | if (!sensorhub->fifo_info) |
| 979 | 977 | return -ENOMEM; |
| 980 | 978 | |
| 979 | + /* | |
| 980 | + * Allocate the callback area based on the number of sensors. | |
| 981 | + * Add one for the sensor ring. | |
| 982 | + */ | |
| 983 | + sensorhub->push_data = devm_kcalloc(sensorhub->dev, | |
| 984 | + sensorhub->sensor_num, | |
| 985 | + sizeof(*sensorhub->push_data), | |
| 986 | + GFP_KERNEL); | |
| 987 | + if (!sensorhub->push_data) | |
| 988 | + return -ENOMEM; | |
| 989 | + | |
| 990 | + sensorhub->tight_timestamps = cros_ec_check_features( | |
| 991 | + sensorhub->ec, | |
| 992 | + EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS); | |
| 993 | + | |
| 994 | + if (sensorhub->tight_timestamps) { | |
| 995 | + sensorhub->batch_state = devm_kcalloc(sensorhub->dev, | |
| 996 | + sensorhub->sensor_num, | |
| 997 | + sizeof(*sensorhub->batch_state), | |
| 998 | + GFP_KERNEL); | |
| 999 | + if (!sensorhub->batch_state) | |
| 1000 | + return -ENOMEM; | |
| 1001 | + } | |
| 1002 | + | |
| 1003 | + return 0; | |
| 1004 | +} | |
| 1005 | + | |
| 1006 | +/** | |
| 1007 | + * cros_ec_sensorhub_ring_add() - Add the FIFO functionality if the EC | |
| 1008 | + * supports it. | |
| 1009 | + * | |
| 1010 | + * @sensorhub : Sensor Hub object. | |
| 1011 | + * | |
| 1012 | + * Return: 0 on success. | |
| 1013 | + */ | |
| 1014 | +int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub) | |
| 1015 | +{ | |
| 1016 | + struct cros_ec_dev *ec = sensorhub->ec; | |
| 1017 | + int ret; | |
| 1018 | + int fifo_info_length = | |
| 1019 | + sizeof(struct ec_response_motion_sense_fifo_info) + | |
| 1020 | + sizeof(u16) * sensorhub->sensor_num; | |
| 1021 | + | |
| 981 | 1022 | /* Retrieve FIFO information */ |
| 982 | 1023 | sensorhub->msg->version = 2; |
| 983 | 1024 | sensorhub->params->cmd = MOTIONSENSE_CMD_FIFO_INFO; |
| @@ -998,31 +1039,9 @@ int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub) · 14 unmodified lines | ||
| 998 | 1039 | if (!sensorhub->ring) |
| 999 | 1040 | return -ENOMEM; |
| 1000 | 1041 | |
| 1001 | − /* | |
| 1002 | − * Allocate the callback area based on the number of sensors. | |
| 1003 | − */ | |
| 1004 | − sensorhub->push_data = devm_kcalloc( | |
| 1005 | − sensorhub->dev, sensorhub->sensor_num, | |
| 1006 | − sizeof(*sensorhub->push_data), | |
| 1007 | − GFP_KERNEL); | |
| 1008 | − if (!sensorhub->push_data) | |
| 1009 | − return -ENOMEM; | |
| 1010 | − | |
| 1011 | 1042 | sensorhub->fifo_timestamp[CROS_EC_SENSOR_LAST_TS] = |
| 1012 | 1043 | cros_ec_get_time_ns(); |
| 1013 | 1044 | |
| 1014 | − sensorhub->tight_timestamps = cros_ec_check_features( | |
| 1015 | − ec, EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS); | |
| 1016 | − | |
| 1017 | − if (sensorhub->tight_timestamps) { | |
| 1018 | − sensorhub->batch_state = devm_kcalloc(sensorhub->dev, | |
| 1019 | − sensorhub->sensor_num, | |
| 1020 | − sizeof(*sensorhub->batch_state), | |
| 1021 | − GFP_KERNEL); | |
| 1022 | − if (!sensorhub->batch_state) | |
| 1023 | − return -ENOMEM; | |
| 1024 | − } | |
| 1025 | − | |
| 1026 | 1045 | /* Register the notifier that will act as a top half interrupt. */ |
| 1027 | 1046 | sensorhub->notifier.notifier_call = cros_ec_sensorhub_event; |
| 1028 | 1047 | ret = blocking_notifier_chain_register(&ec->ec_dev->event_notifier, |
| @@ -515,9 +515,33 @@ static struct asus_wmi_driver asus_nb_wmi_driver = { · 514 unmodified lines | ||
| 515 | 515 | .detect_quirks = asus_nb_wmi_quirks, |
| 516 | 516 | }; |
| 517 | 517 | |
| 518 | +static const struct dmi_system_id asus_nb_wmi_blacklist[] __initconst = { | |
| 519 | + { | |
| 520 | + /* | |
| 521 | + * asus-nb-wm adds no functionality. The T100TA has a detachable | |
| 522 | + * USB kbd, so no hotkeys and it has no WMI rfkill; and loading | |
| 523 | + * asus-nb-wm causes the camera LED to turn and _stay_ on. | |
| 524 | + */ | |
| 525 | + .matches = { | |
| 526 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 527 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), | |
| 528 | + }, | |
| 529 | + }, | |
| 530 | + { | |
| 531 | + /* The Asus T200TA has the same issue as the T100TA */ | |
| 532 | + .matches = { | |
| 533 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 534 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T200TA"), | |
| 535 | + }, | |
| 536 | + }, | |
| 537 | + {} /* Terminating entry */ | |
| 538 | +}; | |
| 518 | 539 | |
| 519 | 540 | static int __init asus_nb_wmi_init(void) |
| 520 | 541 | { |
| 542 | + if (dmi_check_system(asus_nb_wmi_blacklist)) | |
| 543 | + return -ENODEV; | |
| 544 | + | |
| 521 | 545 | return asus_wmi_register_driver(&asus_nb_wmi_driver); |
| 522 | 546 | } |
| 523 | 547 | |
| @@ -53,7 +53,7 @@ static int uncore_max_entries __read_mostly; · 52 unmodified lines | ||
| 53 | 53 | /* Storage for uncore data for all instances */ |
| 54 | 54 | static struct uncore_data *uncore_instances; |
| 55 | 55 | /* Root of the all uncore sysfs kobjs */ |
| 56 | −struct kobject *uncore_root_kobj; | |
| 56 | +static struct kobject *uncore_root_kobj; | |
| 57 | 57 | /* Stores the CPU mask of the target CPUs to use during uncore read/write */ |
| 58 | 58 | static cpumask_t uncore_cpu_mask; |
| 59 | 59 | /* CPU online callback register instance */ |
| @@ -255,7 +255,7 @@ static const struct pmc_bit_map *ext_cnp_pfear_map[] = { · 254 unmodified lines | ||
| 255 | 255 | }; |
| 256 | 256 | |
| 257 | 257 | static const struct pmc_bit_map icl_pfear_map[] = { |
| 258 | − /* Ice Lake generation onwards only */ | |
| 258 | + /* Ice Lake and Jasper Lake generation onwards only */ | |
| 259 | 259 | {"RES_65", BIT(0)}, |
| 260 | 260 | {"RES_66", BIT(1)}, |
| 261 | 261 | {"RES_67", BIT(2)}, |
| @@ -274,7 +274,7 @@ static const struct pmc_bit_map *ext_icl_pfear_map[] = { · 12 unmodified lines | ||
| 274 | 274 | }; |
| 275 | 275 | |
| 276 | 276 | static const struct pmc_bit_map tgl_pfear_map[] = { |
| 277 | − /* Tiger Lake, Elkhart Lake and Jasper Lake generation onwards only */ | |
| 277 | + /* Tiger Lake and Elkhart Lake generation onwards only */ | |
| 278 | 278 | {"PSF9", BIT(0)}, |
| 279 | 279 | {"RES_66", BIT(1)}, |
| 280 | 280 | {"RES_67", BIT(2)}, |
| @@ -692,7 +692,6 @@ static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct device *dev, · 411 unmodified lines | ||
| 692 | 692 | kfree(lpm_regs); |
| 693 | 693 | } |
| 694 | 694 | |
| 695 | −#if IS_ENABLED(CONFIG_DEBUG_FS) | |
| 696 | 695 | static bool slps0_dbg_latch; |
| 697 | 696 | |
| 698 | 697 | static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset) |
| @@ -1133,15 +1132,6 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev) · 434 unmodified lines | ||
| 1133 | 1132 | &pmc_core_substate_l_sts_regs_fops); |
| 1134 | 1133 | } |
| 1135 | 1134 | } |
| 1136 | −#else | |
| 1137 | −static inline void pmc_core_dbgfs_register(struct pmc_dev *pmcdev) | |
| 1138 | −{ | |
| 1139 | −} | |
| 1140 | − | |
| 1141 | −static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) | |
| 1142 | −{ | |
| 1143 | −} | |
| 1144 | −#endif /* CONFIG_DEBUG_FS */ | |
| 1145 | 1135 | |
| 1146 | 1136 | static const struct x86_cpu_id intel_pmc_core_ids[] = { |
| 1147 | 1137 | X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &spt_reg_map), |
| @@ -1156,7 +1146,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = { · 8 unmodified lines | ||
| 1156 | 1146 | X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &tgl_reg_map), |
| 1157 | 1147 | X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &tgl_reg_map), |
| 1158 | 1148 | X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, &tgl_reg_map), |
| 1159 | − X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &tgl_reg_map), | |
| 1149 | + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &icl_reg_map), | |
| 1160 | 1150 | {} |
| 1161 | 1151 | }; |
| 1162 | 1152 | |
| @@ -1260,13 +1250,11 @@ static int pmc_core_remove(struct platform_device *pdev) · 97 unmodified lines | ||
| 1260 | 1250 | return 0; |
| 1261 | 1251 | } |
| 1262 | 1252 | |
| 1263 | −#ifdef CONFIG_PM_SLEEP | |
| 1264 | − | |
| 1265 | 1253 | static bool warn_on_s0ix_failures; |
| 1266 | 1254 | module_param(warn_on_s0ix_failures, bool, 0644); |
| 1267 | 1255 | MODULE_PARM_DESC(warn_on_s0ix_failures, "Check and warn for S0ix failures"); |
| 1268 | 1256 | |
| 1269 | −static int pmc_core_suspend(struct device *dev) | |
| 1257 | +static __maybe_unused int pmc_core_suspend(struct device *dev) | |
| 1270 | 1258 | { |
| 1271 | 1259 | struct pmc_dev *pmcdev = dev_get_drvdata(dev); |
| 1272 | 1260 | |
| @@ -1318,7 +1306,7 @@ static inline bool pmc_core_is_s0ix_failed(struct pmc_dev *pmcdev) · 45 unmodified lines | ||
| 1318 | 1306 | return false; |
| 1319 | 1307 | } |
| 1320 | 1308 | |
| 1321 | −static int pmc_core_resume(struct device *dev) | |
| 1309 | +static __maybe_unused int pmc_core_resume(struct device *dev) | |
| 1322 | 1310 | { |
| 1323 | 1311 | struct pmc_dev *pmcdev = dev_get_drvdata(dev); |
| 1324 | 1312 | const struct pmc_bit_map **maps = pmcdev->map->lpm_sts; |
| @@ -1348,8 +1336,6 @@ static int pmc_core_resume(struct device *dev) · 23 unmodified lines | ||
| 1348 | 1336 | return 0; |
| 1349 | 1337 | } |
| 1350 | 1338 | |
| 1351 | −#endif | |
| 1352 | − | |
| 1353 | 1339 | static const struct dev_pm_ops pmc_core_pm_ops = { |
| 1354 | 1340 | SET_LATE_SYSTEM_SLEEP_PM_OPS(pmc_core_suspend, pmc_core_resume) |
| 1355 | 1341 | }; |
| @@ -282,9 +282,7 @@ struct pmc_dev { · 281 unmodified lines | ||
| 282 | 282 | u32 base_addr; |
| 283 | 283 | void __iomem *regbase; |
| 284 | 284 | const struct pmc_reg_map *map; |
| 285 | −#if IS_ENABLED(CONFIG_DEBUG_FS) | |
| 286 | 285 | struct dentry *dbgfs_dir; |
| 287 | −#endif /* CONFIG_DEBUG_FS */ | |
| 288 | 286 | int pmc_xram_read_bit; |
| 289 | 287 | struct mutex lock; /* generic mutex lock for PMC Core */ |
| 290 | 288 | |
| @@ -522,8 +522,8 @@ static int mshw0011_probe(struct i2c_client *client) · 521 unmodified lines | ||
| 522 | 522 | strlcpy(board_info.type, "MSHW0011-bat0", I2C_NAME_SIZE); |
| 523 | 523 | |
| 524 | 524 | bat0 = i2c_acpi_new_device(dev, 1, &board_info); |
| 525 | − if (!bat0) | |
| 526 | − return -ENOMEM; | |
| 525 | + if (IS_ERR(bat0)) | |
| 526 | + return PTR_ERR(bat0); | |
| 527 | 527 | |
| 528 | 528 | data->bat0 = bat0; |
| 529 | 529 | i2c_set_clientdata(bat0, data); |
| @@ -9548,7 +9548,7 @@ static ssize_t tpacpi_battery_store(int what, · 9547 unmodified lines | ||
| 9548 | 9548 | if (!battery_info.batteries[battery].start_support) |
| 9549 | 9549 | return -ENODEV; |
| 9550 | 9550 | /* valid values are [0, 99] */ |
| 9551 | − if (value < 0 || value > 99) | |
| 9551 | + if (value > 99) | |
| 9552 | 9552 | return -EINVAL; |
| 9553 | 9553 | if (value > battery_info.batteries[battery].charge_stop) |
| 9554 | 9554 | return -EINVAL; |
| @@ -23,7 +23,7 @@ struct xiaomi_wmi { · 22 unmodified lines | ||
| 23 | 23 | unsigned int key_code; |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | −int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) | |
| 26 | +static int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) | |
| 27 | 27 | { |
| 28 | 28 | struct xiaomi_wmi *data; |
| 29 | 29 | |
| @@ -48,7 +48,7 @@ int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) · 18 unmodified lines | ||
| 48 | 48 | return input_register_device(data->input_dev); |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | −void xiaomi_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy) | |
| 51 | +static void xiaomi_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy) | |
| 52 | 52 | { |
| 53 | 53 | struct xiaomi_wmi *data; |
| 54 | 54 | |
| @@ -5754,10 +5754,6 @@ static DECLARE_DELAYED_WORK(regulator_init_complete_work, · 5753 unmodified lines | ||
| 5754 | 5754 | |
| 5755 | 5755 | static int __init regulator_init_complete(void) |
| 5756 | 5756 | { |
| 5757 | − int delay = driver_deferred_probe_timeout; | |
| 5758 | − | |
| 5759 | − if (delay < 0) | |
| 5760 | − delay = 0; | |
| 5761 | 5757 | /* |
| 5762 | 5758 | * Since DT doesn't provide an idiomatic mechanism for |
| 5763 | 5759 | * enabling full constraints and since it's much more natural |
| @@ -5768,17 +5764,18 @@ static int __init regulator_init_complete(void) · 4 unmodified lines | ||
| 5768 | 5764 | has_full_constraints = true; |
| 5769 | 5765 | |
| 5770 | 5766 | /* |
| 5771 | − * If driver_deferred_probe_timeout is set, we punt | |
| 5772 | − * completion for that many seconds since systems like | |
| 5773 | − * distros will load many drivers from userspace so consumers | |
| 5774 | − * might not always be ready yet, this is particularly an | |
| 5775 | − * issue with laptops where this might bounce the display off | |
| 5776 | − * then on. Ideally we'd get a notification from userspace | |
| 5777 | − * when this happens but we don't so just wait a bit and hope | |
| 5778 | − * we waited long enough. It'd be better if we'd only do | |
| 5779 | − * this on systems that need it. | |
| 5767 | + * We punt completion for an arbitrary amount of time since | |
| 5768 | + * systems like distros will load many drivers from userspace | |
| 5769 | + * so consumers might not always be ready yet, this is | |
| 5770 | + * particularly an issue with laptops where this might bounce | |
| 5771 | + * the display off then on. Ideally we'd get a notification | |
| 5772 | + * from userspace when this happens but we don't so just wait | |
| 5773 | + * a bit and hope we waited long enough. It'd be better if | |
| 5774 | + * we'd only do this on systems that need it, and a kernel | |
| 5775 | + * command line option might be useful. | |
| 5780 | 5776 | */ |
| 5781 | − schedule_delayed_work(®ulator_init_complete_work, delay * HZ); | |
| 5777 | + schedule_delayed_work(®ulator_init_complete_work, | |
| 5778 | + msecs_to_jiffies(30000)); | |
| 5782 | 5779 | |
| 5783 | 5780 | return 0; |
| 5784 | 5781 | } |
| @@ -6717,17 +6717,17 @@ int qeth_stop(struct net_device *dev) · 6716 unmodified lines | ||
| 6717 | 6717 | unsigned int i; |
| 6718 | 6718 | |
| 6719 | 6719 | /* Quiesce the NAPI instances: */ |
| 6720 | − qeth_for_each_output_queue(card, queue, i) { | |
| 6720 | + qeth_for_each_output_queue(card, queue, i) | |
| 6721 | 6721 | napi_disable(&queue->napi); |
| 6722 | − del_timer_sync(&queue->timer); | |
| 6723 | − } | |
| 6724 | 6722 | |
| 6725 | 6723 | /* Stop .ndo_start_xmit, might still access queue->napi. */ |
| 6726 | 6724 | netif_tx_disable(dev); |
| 6727 | 6725 | |
| 6728 | − /* Queues may get re-allocated, so remove the NAPIs here. */ | |
| 6729 | − qeth_for_each_output_queue(card, queue, i) | |
| 6726 | + qeth_for_each_output_queue(card, queue, i) { | |
| 6727 | + del_timer_sync(&queue->timer); | |
| 6728 | + /* Queues may get re-allocated, so remove the NAPIs. */ | |
| 6730 | 6729 | netif_napi_del(&queue->napi); |
| 6730 | + } | |
| 6731 | 6731 | } else { |
| 6732 | 6732 | netif_tx_disable(dev); |
| 6733 | 6733 | } |
| @@ -3640,6 +3640,11 @@ static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *tgt) · 3639 unmodified lines | ||
| 3640 | 3640 | struct ibmvfc_host *vhost = tgt->vhost; |
| 3641 | 3641 | struct ibmvfc_event *evt; |
| 3642 | 3642 | |
| 3643 | + if (!vhost->logged_in) { | |
| 3644 | + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); | |
| 3645 | + return; | |
| 3646 | + } | |
| 3647 | + | |
| 3643 | 3648 | if (vhost->discovery_threads >= disc_threads) |
| 3644 | 3649 | return; |
| 3645 | 3650 | |
| @@ -2320,16 +2320,12 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) · 2319 unmodified lines | ||
| 2320 | 2320 | static int ibmvscsi_remove(struct vio_dev *vdev) |
| 2321 | 2321 | { |
| 2322 | 2322 | struct ibmvscsi_host_data *hostdata = dev_get_drvdata(&vdev->dev); |
| 2323 | − unsigned long flags; | |
| 2324 | 2323 | |
| 2325 | 2324 | srp_remove_host(hostdata->host); |
| 2326 | 2325 | scsi_remove_host(hostdata->host); |
| 2327 | 2326 | |
| 2328 | 2327 | purge_requests(hostdata, DID_ERROR); |
| 2329 | − | |
| 2330 | − spin_lock_irqsave(hostdata->host->host_lock, flags); | |
| 2331 | 2328 | release_event_pool(&hostdata->pool, hostdata); |
| 2332 | − spin_unlock_irqrestore(hostdata->host->host_lock, flags); | |
| 2333 | 2329 | |
| 2334 | 2330 | ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, |
| 2335 | 2331 | max_events); |
| @@ -3031,11 +3031,11 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) · 3030 unmodified lines | ||
| 3031 | 3031 | test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) |
| 3032 | 3032 | msleep(1000); |
| 3033 | 3033 | |
| 3034 | − qla_nvme_delete(vha); | |
| 3035 | 3034 | |
| 3036 | 3035 | qla24xx_disable_vp(vha); |
| 3037 | 3036 | qla2x00_wait_for_sess_deletion(vha); |
| 3038 | 3037 | |
| 3038 | + qla_nvme_delete(vha); | |
| 3039 | 3039 | vha->flags.delete_progress = 1; |
| 3040 | 3040 | |
| 3041 | 3041 | qlt_remove_target(ha, vha); |
| @@ -3153,7 +3153,7 @@ qla24xx_abort_command(srb_t *sp) · 3152 unmodified lines | ||
| 3153 | 3153 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, |
| 3154 | 3154 | "Entered %s.\n", __func__); |
| 3155 | 3155 | |
| 3156 | − if (vha->flags.qpairs_available && sp->qpair) | |
| 3156 | + if (sp->qpair) | |
| 3157 | 3157 | req = sp->qpair->req; |
| 3158 | 3158 | else |
| 3159 | 3159 | return QLA_FUNCTION_FAILED; |
| @@ -3732,6 +3732,13 @@ qla2x00_remove_one(struct pci_dev *pdev) · 3731 unmodified lines | ||
| 3732 | 3732 | } |
| 3733 | 3733 | qla2x00_wait_for_hba_ready(base_vha); |
| 3734 | 3734 | |
| 3735 | + /* | |
| 3736 | + * if UNLOADING flag is already set, then continue unload, | |
| 3737 | + * where it was set first. | |
| 3738 | + */ | |
| 3739 | + if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 3740 | + return; | |
| 3741 | + | |
| 3735 | 3742 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
| 3736 | 3743 | IS_QLA28XX(ha)) { |
| 3737 | 3744 | if (ha->flags.fw_started) |
| @@ -3750,15 +3757,6 @@ qla2x00_remove_one(struct pci_dev *pdev) · 12 unmodified lines | ||
| 3750 | 3757 | |
| 3751 | 3758 | qla2x00_wait_for_sess_deletion(base_vha); |
| 3752 | 3759 | |
| 3753 | − /* | |
| 3754 | − * if UNLOAD flag is already set, then continue unload, | |
| 3755 | − * where it was set first. | |
| 3756 | − */ | |
| 3757 | − if (test_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 3758 | − return; | |
| 3759 | − | |
| 3760 | − set_bit(UNLOADING, &base_vha->dpc_flags); | |
| 3761 | − | |
| 3762 | 3760 | qla_nvme_delete(base_vha); |
| 3763 | 3761 | |
| 3764 | 3762 | dma_free_coherent(&ha->pdev->dev, |
| @@ -4864,6 +4862,9 @@ qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type) · 1099 unmodified lines | ||
| 4864 | 4862 | struct qla_work_evt *e; |
| 4865 | 4863 | uint8_t bail; |
| 4866 | 4864 | |
| 4865 | + if (test_bit(UNLOADING, &vha->dpc_flags)) | |
| 4866 | + return NULL; | |
| 4867 | + | |
| 4867 | 4868 | QLA_VHA_MARK_BUSY(vha, bail); |
| 4868 | 4869 | if (bail) |
| 4869 | 4870 | return NULL; |
| @@ -6628,13 +6629,6 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) · 1758 unmodified lines | ||
| 6628 | 6629 | struct pci_dev *pdev = ha->pdev; |
| 6629 | 6630 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
| 6630 | 6631 | |
| 6631 | − /* | |
| 6632 | − * if UNLOAD flag is already set, then continue unload, | |
| 6633 | − * where it was set first. | |
| 6634 | − */ | |
| 6635 | − if (test_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 6636 | − return; | |
| 6637 | − | |
| 6638 | 6632 | ql_log(ql_log_warn, base_vha, 0x015b, |
| 6639 | 6633 | "Disabling adapter.\n"); |
| 6640 | 6634 | |
| @@ -6645,9 +6639,14 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) · 4 unmodified lines | ||
| 6645 | 6639 | return; |
| 6646 | 6640 | } |
| 6647 | 6641 | |
| 6648 | − qla2x00_wait_for_sess_deletion(base_vha); | |
| 6642 | + /* | |
| 6643 | + * if UNLOADING flag is already set, then continue unload, | |
| 6644 | + * where it was set first. | |
| 6645 | + */ | |
| 6646 | + if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) | |
| 6647 | + return; | |
| 6649 | 6648 | |
| 6650 | − set_bit(UNLOADING, &base_vha->dpc_flags); | |
| 6649 | + qla2x00_wait_for_sess_deletion(base_vha); | |
| 6651 | 6650 | |
| 6652 | 6651 | qla2x00_delete_all_vps(ha, base_vha); |
| 6653 | 6652 | |
| @@ -2284,6 +2284,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) · 2283 unmodified lines | ||
| 2284 | 2284 | switch (oldstate) { |
| 2285 | 2285 | case SDEV_RUNNING: |
| 2286 | 2286 | case SDEV_CREATED_BLOCK: |
| 2287 | + case SDEV_QUIESCE: | |
| 2287 | 2288 | case SDEV_OFFLINE: |
| 2288 | 2289 | break; |
| 2289 | 2290 | default: |
| @@ -925,6 +925,10 @@ do_map_region(const struct gasket_dev *gasket_dev, struct vm_area_struct *vma, · 924 unmodified lines | ||
| 925 | 925 | gasket_get_bar_index(gasket_dev, |
| 926 | 926 | (vma->vm_pgoff << PAGE_SHIFT) + |
| 927 | 927 | driver_desc->legacy_mmap_address_offset); |
| 928 | + | |
| 929 | + if (bar_index < 0) | |
| 930 | + return DO_MAP_REGION_INVALID; | |
| 931 | + | |
| 928 | 932 | phys_base = gasket_dev->bar_data[bar_index].phys_base + phys_offset; |
| 929 | 933 | while (mapped_bytes < map_length) { |
| 930 | 934 | /* |
| @@ -30,5 +30,4 @@ Now the TODOs: · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | Please send any patches to: |
| 32 | 32 | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| 33 | −Wolfram Sang <wsa@the-dreams.de> | |
| 34 | 33 | Linux Driver Project Developer List <driverdev-devel@linuxdriverproject.org> |
| @@ -432,7 +432,7 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) · 431 unmodified lines | ||
| 432 | 432 | target_to_linux_sector(dev, cmd->t_task_lba), |
| 433 | 433 | target_to_linux_sector(dev, |
| 434 | 434 | sbc_get_write_same_sectors(cmd)), |
| 435 | − GFP_KERNEL, false); | |
| 435 | + GFP_KERNEL, BLKDEV_ZERO_NOUNMAP); | |
| 436 | 436 | if (ret) |
| 437 | 437 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 438 | 438 | |
| @@ -182,6 +182,9 @@ static int usb4_switch_op(struct tb_switch *sw, u16 opcode, u8 *status) · 181 unmodified lines | ||
| 182 | 182 | return ret; |
| 183 | 183 | |
| 184 | 184 | ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_26, 1); |
| 185 | + if (ret) | |
| 186 | + return ret; | |
| 187 | + | |
| 185 | 188 | if (val & ROUTER_CS_26_ONS) |
| 186 | 189 | return -EOPNOTSUPP; |
| 187 | 190 | |
| @@ -88,7 +88,7 @@ config HVC_DCC · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | config HVC_RISCV_SBI |
| 90 | 90 | bool "RISC-V SBI console support" |
| 91 | − depends on RISCV_SBI | |
| 91 | + depends on RISCV_SBI_V01 | |
| 92 | 92 | select HVC_DRIVER |
| 93 | 93 | help |
| 94 | 94 | This enables support for console output via RISC-V SBI calls, which |
| @@ -86,7 +86,7 @@ config SERIAL_EARLYCON_ARM_SEMIHOST · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | config SERIAL_EARLYCON_RISCV_SBI |
| 88 | 88 | bool "Early console using RISC-V SBI" |
| 89 | − depends on RISCV_SBI | |
| 89 | + depends on RISCV_SBI_V01 | |
| 90 | 90 | select SERIAL_CORE |
| 91 | 91 | select SERIAL_CORE_CONSOLE |
| 92 | 92 | select SERIAL_EARLYCON |
| @@ -843,10 +843,8 @@ static int bcm_uart_probe(struct platform_device *pdev) · 842 unmodified lines | ||
| 843 | 843 | if (IS_ERR(clk) && pdev->dev.of_node) |
| 844 | 844 | clk = of_clk_get(pdev->dev.of_node, 0); |
| 845 | 845 | |
| 846 | − if (IS_ERR(clk)) { | |
| 847 | − clk_put(clk); | |
| 846 | + if (IS_ERR(clk)) | |
| 848 | 847 | return -ENODEV; |
| 849 | − } | |
| 850 | 848 | |
| 851 | 849 | port->iotype = UPIO_MEM; |
| 852 | 850 | port->irq = res_irq->start; |
| @@ -1459,6 +1459,7 @@ static int cdns_uart_probe(struct platform_device *pdev) · 1458 unmodified lines | ||
| 1459 | 1459 | cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS; |
| 1460 | 1460 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
| 1461 | 1461 | cdns_uart_uart_driver.cons = &cdns_uart_console; |
| 1462 | + cdns_uart_console.index = id; | |
| 1462 | 1463 | #endif |
| 1463 | 1464 | |
| 1464 | 1465 | rc = uart_register_driver(&cdns_uart_uart_driver); |
| @@ -365,9 +365,14 @@ static struct uni_screen *vc_uniscr_alloc(unsigned int cols, unsigned int rows) · 364 unmodified lines | ||
| 365 | 365 | return uniscr; |
| 366 | 366 | } |
| 367 | 367 | |
| 368 | +static void vc_uniscr_free(struct uni_screen *uniscr) | |
| 369 | +{ | |
| 370 | + vfree(uniscr); | |
| 371 | +} | |
| 372 | + | |
| 368 | 373 | static void vc_uniscr_set(struct vc_data *vc, struct uni_screen *new_uniscr) |
| 369 | 374 | { |
| 370 | − vfree(vc->vc_uni_screen); | |
| 375 | + vc_uniscr_free(vc->vc_uni_screen); | |
| 371 | 376 | vc->vc_uni_screen = new_uniscr; |
| 372 | 377 | } |
| 373 | 378 | |
| @@ -1230,7 +1235,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, · 856 unmodified lines | ||
| 1230 | 1235 | err = resize_screen(vc, new_cols, new_rows, user); |
| 1231 | 1236 | if (err) { |
| 1232 | 1237 | kfree(newscreen); |
| 1233 | − kfree(new_uniscr); | |
| 1238 | + vc_uniscr_free(new_uniscr); | |
| 1234 | 1239 | return err; |
| 1235 | 1240 | } |
| 1236 | 1241 | |
| @@ -114,7 +114,7 @@ static int ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) · 113 unmodified lines | ||
| 114 | 114 | hw_write_id_reg(ci, HS_PHY_GENCONFIG_2, |
| 115 | 115 | HS_PHY_ULPI_TX_PKT_EN_CLR_FIX, 0); |
| 116 | 116 | |
| 117 | − if (!IS_ERR(ci->platdata->vbus_extcon.edev)) { | |
| 117 | + if (!IS_ERR(ci->platdata->vbus_extcon.edev) || ci->role_switch) { | |
| 118 | 118 | hw_write_id_reg(ci, HS_PHY_GENCONFIG_2, |
| 119 | 119 | HS_PHY_SESS_VLD_CTRL_EN, |
| 120 | 120 | HS_PHY_SESS_VLD_CTRL_EN); |
| @@ -217,6 +217,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) · 216 unmodified lines | ||
| 217 | 217 | { |
| 218 | 218 | struct usb_memory *usbm = NULL; |
| 219 | 219 | struct usb_dev_state *ps = file->private_data; |
| 220 | + struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus); | |
| 220 | 221 | size_t size = vma->vm_end - vma->vm_start; |
| 221 | 222 | void *mem; |
| 222 | 223 | unsigned long flags; |
| @@ -250,9 +251,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) · 27 unmodified lines | ||
| 250 | 251 | usbm->vma_use_count = 1; |
| 251 | 252 | INIT_LIST_HEAD(&usbm->memlist); |
| 252 | 253 | |
| 253 | − if (remap_pfn_range(vma, vma->vm_start, | |
| 254 | − virt_to_phys(usbm->mem) >> PAGE_SHIFT, | |
| 255 | − size, vma->vm_page_prot) < 0) { | |
| 254 | + if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) { | |
| 256 | 255 | dec_usb_memory_use_count(usbm, &usbm->vma_use_count); |
| 257 | 256 | return -EAGAIN; |
| 258 | 257 | } |
| @@ -1144,11 +1144,11 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, · 1143 unmodified lines | ||
| 1144 | 1144 | |
| 1145 | 1145 | if (usb_endpoint_out(epaddr)) { |
| 1146 | 1146 | ep = dev->ep_out[epnum]; |
| 1147 | − if (reset_hardware) | |
| 1147 | + if (reset_hardware && epnum != 0) | |
| 1148 | 1148 | dev->ep_out[epnum] = NULL; |
| 1149 | 1149 | } else { |
| 1150 | 1150 | ep = dev->ep_in[epnum]; |
| 1151 | − if (reset_hardware) | |
| 1151 | + if (reset_hardware && epnum != 0) | |
| 1152 | 1152 | dev->ep_in[epnum] = NULL; |
| 1153 | 1153 | } |
| 1154 | 1154 | if (ep) { |
| @@ -1138,8 +1138,8 @@ static void garmin_read_process(struct garmin_data *garmin_data_p, · 1137 unmodified lines | ||
| 1138 | 1138 | send it directly to the tty port */ |
| 1139 | 1139 | if (garmin_data_p->flags & FLAGS_QUEUING) { |
| 1140 | 1140 | pkt_add(garmin_data_p, data, data_length); |
| 1141 | − } else if (bulk_data || | |
| 1142 | − getLayerId(data) == GARMIN_LAYERID_APPL) { | |
| 1141 | + } else if (bulk_data || (data_length >= sizeof(u32) && | |
| 1142 | + getLayerId(data) == GARMIN_LAYERID_APPL)) { | |
| 1143 | 1143 | |
| 1144 | 1144 | spin_lock_irqsave(&garmin_data_p->lock, flags); |
| 1145 | 1145 | garmin_data_p->flags |= APP_RESP_SEEN; |
| @@ -173,6 +173,7 @@ static const struct usb_device_id id_table[] = { · 172 unmodified lines | ||
| 173 | 173 | {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ |
| 174 | 174 | {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ |
| 175 | 175 | {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ |
| 176 | + {DEVICE_SWI(0x413c, 0x81cc)}, /* Dell Wireless 5816e */ | |
| 176 | 177 | {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ |
| 177 | 178 | {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ |
| 178 | 179 | {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ |
| @@ -28,6 +28,13 @@ · 27 unmodified lines | ||
| 28 | 28 | * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org> |
| 29 | 29 | */ |
| 30 | 30 | |
| 31 | +/* Reported-by: Julian Groß <julian.g@posteo.de> */ | |
| 32 | +UNUSUAL_DEV(0x059f, 0x105f, 0x0000, 0x9999, | |
| 33 | + "LaCie", | |
| 34 | + "2Big Quadra USB3", | |
| 35 | + USB_SC_DEVICE, USB_PR_DEVICE, NULL, | |
| 36 | + US_FL_NO_REPORT_OPCODES), | |
| 37 | + | |
| 31 | 38 | /* |
| 32 | 39 | * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI |
| 33 | 40 | * commands in UAS mode. Observed with the 1.28 firmware; are there others? |
| @@ -157,6 +157,10 @@ pmc_usb_mux_dp(struct pmc_usb_port *port, struct typec_mux_state *state) · 156 unmodified lines | ||
| 157 | 157 | req.mode_data |= (state->mode - TYPEC_STATE_MODAL) << |
| 158 | 158 | PMC_USB_ALTMODE_DP_MODE_SHIFT; |
| 159 | 159 | |
| 160 | + if (data->status & DP_STATUS_HPD_STATE) | |
| 161 | + req.mode_data |= PMC_USB_DP_HPD_LVL << | |
| 162 | + PMC_USB_ALTMODE_DP_MODE_SHIFT; | |
| 163 | + | |
| 160 | 164 | return pmc_usb_command(port, (void *)&req, sizeof(req)); |
| 161 | 165 | } |
| 162 | 166 | |
| @@ -298,11 +302,11 @@ static int pmc_usb_register_port(struct pmc_usb *pmc, int index, · 135 unmodified lines | ||
| 298 | 302 | struct typec_mux_desc mux_desc = { }; |
| 299 | 303 | int ret; |
| 300 | 304 | |
| 301 | − ret = fwnode_property_read_u8(fwnode, "usb2-port", &port->usb2_port); | |
| 305 | + ret = fwnode_property_read_u8(fwnode, "usb2-port-number", &port->usb2_port); | |
| 302 | 306 | if (ret) |
| 303 | 307 | return ret; |
| 304 | 308 | |
| 305 | − ret = fwnode_property_read_u8(fwnode, "usb3-port", &port->usb3_port); | |
| 309 | + ret = fwnode_property_read_u8(fwnode, "usb3-port-number", &port->usb3_port); | |
| 306 | 310 | if (ret) |
| 307 | 311 | return ret; |
| 308 | 312 | |
| @@ -342,8 +342,8 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, · 341 unmodified lines | ||
| 342 | 342 | vma = find_vma_intersection(mm, vaddr, vaddr + 1); |
| 343 | 343 | |
| 344 | 344 | if (vma && vma->vm_flags & VM_PFNMAP) { |
| 345 | − *pfn = ((vaddr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; | |
| 346 | − if (is_invalid_reserved_pfn(*pfn)) | |
| 345 | + if (!follow_pfn(vma, vaddr, pfn) && | |
| 346 | + is_invalid_reserved_pfn(*pfn)) | |
| 347 | 347 | ret = 0; |
| 348 | 348 | } |
| 349 | 349 | done: |
| @@ -555,7 +555,7 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data, · 205 unmodified lines | ||
| 555 | 555 | continue; |
| 556 | 556 | } |
| 557 | 557 | |
| 558 | − remote_vaddr = dma->vaddr + iova - dma->iova; | |
| 558 | + remote_vaddr = dma->vaddr + (iova - dma->iova); | |
| 559 | 559 | ret = vfio_pin_page_external(dma, remote_vaddr, &phys_pfn[i], |
| 560 | 560 | do_accounting); |
| 561 | 561 | if (ret) |
| @@ -2345,10 +2345,10 @@ static int vfio_iommu_type1_dma_rw_chunk(struct vfio_iommu *iommu, · 1783 unmodified lines | ||
| 2345 | 2345 | vaddr = dma->vaddr + offset; |
| 2346 | 2346 | |
| 2347 | 2347 | if (write) |
| 2348 | − *copied = __copy_to_user((void __user *)vaddr, data, | |
| 2348 | + *copied = copy_to_user((void __user *)vaddr, data, | |
| 2349 | 2349 | count) ? 0 : count; |
| 2350 | 2350 | else |
| 2351 | − *copied = __copy_from_user(data, (void __user *)vaddr, | |
| 2351 | + *copied = copy_from_user(data, (void __user *)vaddr, | |
| 2352 | 2352 | count) ? 0 : count; |
| 2353 | 2353 | if (kthread) |
| 2354 | 2354 | unuse_mm(mm); |
| @@ -181,14 +181,14 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, · 180 unmodified lines | ||
| 181 | 181 | break; |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | − vhost_add_used(vq, head, sizeof(pkt->hdr) + payload_len); | |
| 185 | − added = true; | |
| 186 | − | |
| 187 | − /* Deliver to monitoring devices all correctly transmitted | |
| 188 | − * packets. | |
| 184 | + /* Deliver to monitoring devices all packets that we | |
| 185 | + * will transmit. | |
| 189 | 186 | */ |
| 190 | 187 | virtio_transport_deliver_tap_pkt(pkt); |
| 191 | 188 | |
| 189 | + vhost_add_used(vq, head, sizeof(pkt->hdr) + payload_len); | |
| 190 | + added = true; | |
| 191 | + | |
| 192 | 192 | pkt->off += payload_len; |
| 193 | 193 | total_len += payload_len; |
| 194 | 194 | |
| @@ -196,6 +196,12 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, · 1 unmodified line | ||
| 196 | 196 | * to send it with the next available buffer. |
| 197 | 197 | */ |
| 198 | 198 | if (pkt->off < pkt->len) { |
| 199 | + /* We are queueing the same virtio_vsock_pkt to handle | |
| 200 | + * the remaining bytes, and we want to deliver it | |
| 201 | + * to monitoring devices in the next iteration. | |
| 202 | + */ | |
| 203 | + pkt->tap_delivered = false; | |
| 204 | + | |
| 199 | 205 | spin_lock_bh(&vsock->send_pkt_list_lock); |
| 200 | 206 | list_add(&pkt->list, &vsock->send_pkt_list); |
| 201 | 207 | spin_unlock_bh(&vsock->send_pkt_list_lock); |
| @@ -543,6 +549,11 @@ static int vhost_vsock_start(struct vhost_vsock *vsock) · 341 unmodified lines | ||
| 543 | 549 | mutex_unlock(&vq->mutex); |
| 544 | 550 | } |
| 545 | 551 | |
| 552 | + /* Some packets may have been queued before the device was started, | |
| 553 | + * let's kick the send worker to send them. | |
| 554 | + */ | |
| 555 | + vhost_work_queue(&vsock->dev, &vsock->send_pkt_work); | |
| 556 | + | |
| 546 | 557 | mutex_unlock(&vsock->dev.mutex); |
| 547 | 558 | return 0; |
| 548 | 559 | |
| @@ -391,7 +391,7 @@ static int is_shared_data_backref(struct preftrees *preftrees, u64 bytenr) · 390 unmodified lines | ||
| 391 | 391 | struct rb_node **p = &preftrees->direct.root.rb_root.rb_node; |
| 392 | 392 | struct rb_node *parent = NULL; |
| 393 | 393 | struct prelim_ref *ref = NULL; |
| 394 | − struct prelim_ref target = {0}; | |
| 394 | + struct prelim_ref target = {}; | |
| 395 | 395 | int result; |
| 396 | 396 | |
| 397 | 397 | target.parent = bytenr; |
| @@ -916,7 +916,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 915 unmodified lines | ||
| 916 | 916 | path = btrfs_alloc_path(); |
| 917 | 917 | if (!path) { |
| 918 | 918 | ret = -ENOMEM; |
| 919 | − goto out; | |
| 919 | + goto out_put_group; | |
| 920 | 920 | } |
| 921 | 921 | |
| 922 | 922 | /* |
| @@ -954,7 +954,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 31 unmodified lines | ||
| 954 | 954 | ret = btrfs_orphan_add(trans, BTRFS_I(inode)); |
| 955 | 955 | if (ret) { |
| 956 | 956 | btrfs_add_delayed_iput(inode); |
| 957 | − goto out; | |
| 957 | + goto out_put_group; | |
| 958 | 958 | } |
| 959 | 959 | clear_nlink(inode); |
| 960 | 960 | /* One for the block groups ref */ |
| @@ -977,13 +977,13 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 16 unmodified lines | ||
| 977 | 977 | |
| 978 | 978 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); |
| 979 | 979 | if (ret < 0) |
| 980 | − goto out; | |
| 980 | + goto out_put_group; | |
| 981 | 981 | if (ret > 0) |
| 982 | 982 | btrfs_release_path(path); |
| 983 | 983 | if (ret == 0) { |
| 984 | 984 | ret = btrfs_del_item(trans, tree_root, path); |
| 985 | 985 | if (ret) |
| 986 | − goto out; | |
| 986 | + goto out_put_group; | |
| 987 | 987 | btrfs_release_path(path); |
| 988 | 988 | } |
| 989 | 989 | |
| @@ -1102,9 +1102,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 112 unmodified lines | ||
| 1102 | 1102 | |
| 1103 | 1103 | ret = remove_block_group_free_space(trans, block_group); |
| 1104 | 1104 | if (ret) |
| 1105 | − goto out; | |
| 1105 | + goto out_put_group; | |
| 1106 | 1106 | |
| 1107 | − btrfs_put_block_group(block_group); | |
| 1107 | + /* Once for the block groups rbtree */ | |
| 1108 | 1108 | btrfs_put_block_group(block_group); |
| 1109 | 1109 | |
| 1110 | 1110 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| @@ -1127,6 +1127,10 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 16 unmodified lines | ||
| 1127 | 1127 | /* once for the tree */ |
| 1128 | 1128 | free_extent_map(em); |
| 1129 | 1129 | } |
| 1130 | + | |
| 1131 | +out_put_group: | |
| 1132 | + /* Once for the lookup reference */ | |
| 1133 | + btrfs_put_block_group(block_group); | |
| 1130 | 1134 | out: |
| 1131 | 1135 | if (remove_rsv) |
| 1132 | 1136 | btrfs_delayed_refs_rsv_release(fs_info, 1); |
| @@ -1288,11 +1292,15 @@ static bool clean_pinned_extents(struct btrfs_trans_handle *trans, · 155 unmodified lines | ||
| 1288 | 1292 | if (ret) |
| 1289 | 1293 | goto err; |
| 1290 | 1294 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); |
| 1295 | + if (prev_trans) | |
| 1296 | + btrfs_put_transaction(prev_trans); | |
| 1291 | 1297 | |
| 1292 | 1298 | return true; |
| 1293 | 1299 | |
| 1294 | 1300 | err: |
| 1295 | 1301 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); |
| 1302 | + if (prev_trans) | |
| 1303 | + btrfs_put_transaction(prev_trans); | |
| 1296 | 1304 | btrfs_dec_block_group_ro(bg); |
| 1297 | 1305 | return false; |
| 1298 | 1306 | } |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | |
| 3 | 3 | #ifndef BTRFS_DISCARD_H |
| 4 | 4 | #define BTRFS_DISCARD_H |
| @@ -2036,9 +2036,6 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info) · 2035 unmodified lines | ||
| 2036 | 2036 | for (i = 0; i < ret; i++) |
| 2037 | 2037 | btrfs_drop_and_free_fs_root(fs_info, gang[i]); |
| 2038 | 2038 | } |
| 2039 | − | |
| 2040 | − if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) | |
| 2041 | − btrfs_free_log_root_tree(NULL, fs_info); | |
| 2042 | 2039 | } |
| 2043 | 2040 | |
| 2044 | 2041 | static void btrfs_init_scrub(struct btrfs_fs_info *fs_info) |
| @@ -3888,7 +3885,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, · 1843 unmodified lines | ||
| 3888 | 3885 | spin_unlock(&fs_info->fs_roots_radix_lock); |
| 3889 | 3886 | |
| 3890 | 3887 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { |
| 3891 | − btrfs_free_log(NULL, root); | |
| 3888 | + ASSERT(root->log_root == NULL); | |
| 3892 | 3889 | if (root->reloc_root) { |
| 3893 | 3890 | btrfs_put_root(root->reloc_root); |
| 3894 | 3891 | root->reloc_root = NULL; |
| @@ -4211,6 +4208,36 @@ static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) · 316 unmodified lines | ||
| 4211 | 4208 | up_write(&fs_info->cleanup_work_sem); |
| 4212 | 4209 | } |
| 4213 | 4210 | |
| 4211 | +static void btrfs_drop_all_logs(struct btrfs_fs_info *fs_info) | |
| 4212 | +{ | |
| 4213 | + struct btrfs_root *gang[8]; | |
| 4214 | + u64 root_objectid = 0; | |
| 4215 | + int ret; | |
| 4216 | + | |
| 4217 | + spin_lock(&fs_info->fs_roots_radix_lock); | |
| 4218 | + while ((ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, | |
| 4219 | + (void **)gang, root_objectid, | |
| 4220 | + ARRAY_SIZE(gang))) != 0) { | |
| 4221 | + int i; | |
| 4222 | + | |
| 4223 | + for (i = 0; i < ret; i++) | |
| 4224 | + gang[i] = btrfs_grab_root(gang[i]); | |
| 4225 | + spin_unlock(&fs_info->fs_roots_radix_lock); | |
| 4226 | + | |
| 4227 | + for (i = 0; i < ret; i++) { | |
| 4228 | + if (!gang[i]) | |
| 4229 | + continue; | |
| 4230 | + root_objectid = gang[i]->root_key.objectid; | |
| 4231 | + btrfs_free_log(NULL, gang[i]); | |
| 4232 | + btrfs_put_root(gang[i]); | |
| 4233 | + } | |
| 4234 | + root_objectid++; | |
| 4235 | + spin_lock(&fs_info->fs_roots_radix_lock); | |
| 4236 | + } | |
| 4237 | + spin_unlock(&fs_info->fs_roots_radix_lock); | |
| 4238 | + btrfs_free_log_root_tree(NULL, fs_info); | |
| 4239 | +} | |
| 4240 | + | |
| 4214 | 4241 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) |
| 4215 | 4242 | { |
| 4216 | 4243 | struct btrfs_ordered_extent *ordered; |
| @@ -4603,6 +4630,7 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info) · 386 unmodified lines | ||
| 4603 | 4630 | btrfs_destroy_delayed_inodes(fs_info); |
| 4604 | 4631 | btrfs_assert_delayed_root_empty(fs_info); |
| 4605 | 4632 | btrfs_destroy_all_delalloc_inodes(fs_info); |
| 4633 | + btrfs_drop_all_logs(fs_info); | |
| 4606 | 4634 | mutex_unlock(&fs_info->transaction_kthread_mutex); |
| 4607 | 4635 | |
| 4608 | 4636 | return 0; |
| @@ -4559,6 +4559,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) · 4558 unmodified lines | ||
| 4559 | 4559 | if (IS_ERR(fs_root)) { |
| 4560 | 4560 | err = PTR_ERR(fs_root); |
| 4561 | 4561 | list_add_tail(&reloc_root->root_list, &reloc_roots); |
| 4562 | + btrfs_end_transaction(trans); | |
| 4562 | 4563 | goto out_unset; |
| 4563 | 4564 | } |
| 4564 | 4565 | |
| @@ -662,10 +662,19 @@ again: · 661 unmodified lines | ||
| 662 | 662 | } |
| 663 | 663 | |
| 664 | 664 | got_it: |
| 665 | − btrfs_record_root_in_trans(h, root); | |
| 666 | − | |
| 667 | 665 | if (!current->journal_info) |
| 668 | 666 | current->journal_info = h; |
| 667 | + | |
| 668 | + /* | |
| 669 | + * btrfs_record_root_in_trans() needs to alloc new extents, and may | |
| 670 | + * call btrfs_join_transaction() while we're also starting a | |
| 671 | + * transaction. | |
| 672 | + * | |
| 673 | + * Thus it need to be called after current->journal_info initialized, | |
| 674 | + * or we can deadlock. | |
| 675 | + */ | |
| 676 | + btrfs_record_root_in_trans(h, root); | |
| 677 | + | |
| 669 | 678 | return h; |
| 670 | 679 | |
| 671 | 680 | join_fail: |
| @@ -4226,6 +4226,9 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 4225 unmodified lines | ||
| 4226 | 4226 | const u64 ino = btrfs_ino(inode); |
| 4227 | 4227 | struct btrfs_path *dst_path = NULL; |
| 4228 | 4228 | bool dropped_extents = false; |
| 4229 | + u64 truncate_offset = i_size; | |
| 4230 | + struct extent_buffer *leaf; | |
| 4231 | + int slot; | |
| 4229 | 4232 | int ins_nr = 0; |
| 4230 | 4233 | int start_slot; |
| 4231 | 4234 | int ret; |
| @@ -4240,9 +4243,43 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 8 unmodified lines | ||
| 4240 | 4243 | if (ret < 0) |
| 4241 | 4244 | goto out; |
| 4242 | 4245 | |
| 4246 | + /* | |
| 4247 | + * We must check if there is a prealloc extent that starts before the | |
| 4248 | + * i_size and crosses the i_size boundary. This is to ensure later we | |
| 4249 | + * truncate down to the end of that extent and not to the i_size, as | |
| 4250 | + * otherwise we end up losing part of the prealloc extent after a log | |
| 4251 | + * replay and with an implicit hole if there is another prealloc extent | |
| 4252 | + * that starts at an offset beyond i_size. | |
| 4253 | + */ | |
| 4254 | + ret = btrfs_previous_item(root, path, ino, BTRFS_EXTENT_DATA_KEY); | |
| 4255 | + if (ret < 0) | |
| 4256 | + goto out; | |
| 4257 | + | |
| 4258 | + if (ret == 0) { | |
| 4259 | + struct btrfs_file_extent_item *ei; | |
| 4260 | + | |
| 4261 | + leaf = path->nodes[0]; | |
| 4262 | + slot = path->slots[0]; | |
| 4263 | + ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | |
| 4264 | + | |
| 4265 | + if (btrfs_file_extent_type(leaf, ei) == | |
| 4266 | + BTRFS_FILE_EXTENT_PREALLOC) { | |
| 4267 | + u64 extent_end; | |
| 4268 | + | |
| 4269 | + btrfs_item_key_to_cpu(leaf, &key, slot); | |
| 4270 | + extent_end = key.offset + | |
| 4271 | + btrfs_file_extent_num_bytes(leaf, ei); | |
| 4272 | + | |
| 4273 | + if (extent_end > i_size) | |
| 4274 | + truncate_offset = extent_end; | |
| 4275 | + } | |
| 4276 | + } else { | |
| 4277 | + ret = 0; | |
| 4278 | + } | |
| 4279 | + | |
| 4243 | 4280 | while (true) { |
| 4244 | − struct extent_buffer *leaf = path->nodes[0]; | |
| 4245 | − int slot = path->slots[0]; | |
| 4281 | + leaf = path->nodes[0]; | |
| 4282 | + slot = path->slots[0]; | |
| 4246 | 4283 | |
| 4247 | 4284 | if (slot >= btrfs_header_nritems(leaf)) { |
| 4248 | 4285 | if (ins_nr > 0) { |
| @@ -4280,7 +4317,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 31 unmodified lines | ||
| 4280 | 4317 | ret = btrfs_truncate_inode_items(trans, |
| 4281 | 4318 | root->log_root, |
| 4282 | 4319 | &inode->vfs_inode, |
| 4283 | − i_size, | |
| 4320 | + truncate_offset, | |
| 4284 | 4321 | BTRFS_EXTENT_DATA_KEY); |
| 4285 | 4322 | } while (ret == -EAGAIN); |
| 4286 | 4323 | if (ret) |
| @@ -2749,7 +2749,7 @@ int ceph_try_get_caps(struct inode *inode, int need, int want, · 2748 unmodified lines | ||
| 2749 | 2749 | |
| 2750 | 2750 | ret = try_get_cap_refs(inode, need, want, 0, flags, got); |
| 2751 | 2751 | /* three special error codes */ |
| 2752 | − if (ret == -EAGAIN || ret == -EFBIG || ret == -EAGAIN) | |
| 2752 | + if (ret == -EAGAIN || ret == -EFBIG || ret == -ESTALE) | |
| 2753 | 2753 | ret = 0; |
| 2754 | 2754 | return ret; |
| 2755 | 2755 | } |
| @@ -3746,6 +3746,7 @@ retry: · 990 unmodified lines | ||
| 3746 | 3746 | WARN_ON(1); |
| 3747 | 3747 | tsession = NULL; |
| 3748 | 3748 | target = -1; |
| 3749 | + mutex_lock(&session->s_mutex); | |
| 3749 | 3750 | } |
| 3750 | 3751 | goto retry; |
| 3751 | 3752 | |
| @@ -271,7 +271,7 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc) · 270 unmodified lines | ||
| 271 | 271 | &congestion_kb_fops); |
| 272 | 272 | |
| 273 | 273 | snprintf(name, sizeof(name), "../../bdi/%s", |
| 274 | − dev_name(fsc->sb->s_bdi->dev)); | |
| 274 | + bdi_dev_name(fsc->sb->s_bdi)); | |
| 275 | 275 | fsc->debugfs_bdi = |
| 276 | 276 | debugfs_create_symlink("bdi", |
| 277 | 277 | fsc->client->debugfs_dir, |
| @@ -3251,8 +3251,7 @@ static void handle_session(struct ceph_mds_session *session, · 3250 unmodified lines | ||
| 3251 | 3251 | void *end = p + msg->front.iov_len; |
| 3252 | 3252 | struct ceph_mds_session_head *h; |
| 3253 | 3253 | u32 op; |
| 3254 | − u64 seq; | |
| 3255 | − unsigned long features = 0; | |
| 3254 | + u64 seq, features = 0; | |
| 3256 | 3255 | int wake = 0; |
| 3257 | 3256 | bool blacklisted = false; |
| 3258 | 3257 | |
| @@ -3271,9 +3270,8 @@ static void handle_session(struct ceph_mds_session *session, · 12 unmodified lines | ||
| 3271 | 3270 | goto bad; |
| 3272 | 3271 | /* version >= 3, feature bits */ |
| 3273 | 3272 | ceph_decode_32_safe(&p, end, len, bad); |
| 3274 | − ceph_decode_need(&p, end, len, bad); | |
| 3275 | − memcpy(&features, p, min_t(size_t, len, sizeof(features))); | |
| 3276 | − p += len; | |
| 3273 | + ceph_decode_64_safe(&p, end, features, bad); | |
| 3274 | + p += len - sizeof(features); | |
| 3277 | 3275 | } |
| 3278 | 3276 | |
| 3279 | 3277 | mutex_lock(&mdsc->mutex); |
| @@ -159,8 +159,8 @@ static struct inode *lookup_quotarealm_inode(struct ceph_mds_client *mdsc, · 158 unmodified lines | ||
| 159 | 159 | } |
| 160 | 160 | |
| 161 | 161 | if (IS_ERR(in)) { |
| 162 | − pr_warn("Can't lookup inode %llx (err: %ld)\n", | |
| 163 | − realm->ino, PTR_ERR(in)); | |
| 162 | + dout("Can't lookup inode %llx (err: %ld)\n", | |
| 163 | + realm->ino, PTR_ERR(in)); | |
| 164 | 164 | qri->timeout = jiffies + msecs_to_jiffies(60 * 1000); /* XXX */ |
| 165 | 165 | } else { |
| 166 | 166 | qri->timeout = 0; |
| @@ -1519,6 +1519,7 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) · 1518 unmodified lines | ||
| 1519 | 1519 | spin_lock(&configfs_dirent_lock); |
| 1520 | 1520 | configfs_detach_rollback(dentry); |
| 1521 | 1521 | spin_unlock(&configfs_dirent_lock); |
| 1522 | + config_item_put(parent_item); | |
| 1522 | 1523 | return -EINTR; |
| 1523 | 1524 | } |
| 1524 | 1525 | frag->frag_dead = true; |
| @@ -788,6 +788,14 @@ void do_coredump(const kernel_siginfo_t *siginfo) · 787 unmodified lines | ||
| 788 | 788 | if (displaced) |
| 789 | 789 | put_files_struct(displaced); |
| 790 | 790 | if (!dump_interrupted()) { |
| 791 | + /* | |
| 792 | + * umh disabled with CONFIG_STATIC_USERMODEHELPER_PATH="" would | |
| 793 | + * have this set to NULL. | |
| 794 | + */ | |
| 795 | + if (!cprm.file) { | |
| 796 | + pr_info("Core dump to |%s disabled\n", cn.corename); | |
| 797 | + goto close_fail; | |
| 798 | + } | |
| 791 | 799 | file_start_write(cprm.file); |
| 792 | 800 | core_dumped = binfmt->core_dump(&cprm); |
| 793 | 801 | file_end_write(cprm.file); |
| @@ -1171,6 +1171,10 @@ static inline bool chain_epi_lockless(struct epitem *epi) · 1170 unmodified lines | ||
| 1171 | 1171 | { |
| 1172 | 1172 | struct eventpoll *ep = epi->ep; |
| 1173 | 1173 | |
| 1174 | + /* Fast preliminary check */ | |
| 1175 | + if (epi->next != EP_UNACTIVE_PTR) | |
| 1176 | + return false; | |
| 1177 | + | |
| 1174 | 1178 | /* Check that the same epi has not been just chained from another CPU */ |
| 1175 | 1179 | if (cmpxchg(&epi->next, EP_UNACTIVE_PTR, NULL) != EP_UNACTIVE_PTR) |
| 1176 | 1180 | return false; |
| @@ -1237,16 +1241,12 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v · 60 unmodified lines | ||
| 1237 | 1241 | * chained in ep->ovflist and requeued later on. |
| 1238 | 1242 | */ |
| 1239 | 1243 | if (READ_ONCE(ep->ovflist) != EP_UNACTIVE_PTR) { |
| 1240 | − if (epi->next == EP_UNACTIVE_PTR && | |
| 1241 | − chain_epi_lockless(epi)) | |
| 1244 | + if (chain_epi_lockless(epi)) | |
| 1245 | + ep_pm_stay_awake_rcu(epi); | |
| 1246 | + } else if (!ep_is_linked(epi)) { | |
| 1247 | + /* In the usual case, add event to ready list. */ | |
| 1248 | + if (list_add_tail_lockless(&epi->rdllink, &ep->rdllist)) | |
| 1242 | 1249 | ep_pm_stay_awake_rcu(epi); |
| 1243 | − goto out_unlock; | |
| 1244 | − } | |
| 1245 | − | |
| 1246 | − /* If this file is already in the ready list we exit soon */ | |
| 1247 | − if (!ep_is_linked(epi) && | |
| 1248 | − list_add_tail_lockless(&epi->rdllink, &ep->rdllist)) { | |
| 1249 | − ep_pm_stay_awake_rcu(epi); | |
| 1250 | 1250 | } |
| 1251 | 1251 | |
| 1252 | 1252 | /* |
| @@ -1822,7 +1822,6 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, · 569 unmodified lines | ||
| 1822 | 1822 | { |
| 1823 | 1823 | int res = 0, eavail, timed_out = 0; |
| 1824 | 1824 | u64 slack = 0; |
| 1825 | − bool waiter = false; | |
| 1826 | 1825 | wait_queue_entry_t wait; |
| 1827 | 1826 | ktime_t expires, *to = NULL; |
| 1828 | 1827 | |
| @@ -1867,21 +1866,23 @@ fetch_events: · 38 unmodified lines | ||
| 1867 | 1866 | */ |
| 1868 | 1867 | ep_reset_busy_poll_napi_id(ep); |
| 1869 | 1868 | |
| 1870 | − /* | |
| 1871 | − * We don't have any available event to return to the caller. We need | |
| 1872 | − * to sleep here, and we will be woken by ep_poll_callback() when events | |
| 1873 | − * become available. | |
| 1874 | − */ | |
| 1875 | − if (!waiter) { | |
| 1876 | − waiter = true; | |
| 1877 | − init_waitqueue_entry(&wait, current); | |
| 1878 | − | |
| 1869 | + do { | |
| 1870 | + /* | |
| 1871 | + * Internally init_wait() uses autoremove_wake_function(), | |
| 1872 | + * thus wait entry is removed from the wait queue on each | |
| 1873 | + * wakeup. Why it is important? In case of several waiters | |
| 1874 | + * each new wakeup will hit the next waiter, giving it the | |
| 1875 | + * chance to harvest new event. Otherwise wakeup can be | |
| 1876 | + * lost. This is also good performance-wise, because on | |
| 1877 | + * normal wakeup path no need to call __remove_wait_queue() | |
| 1878 | + * explicitly, thus ep->lock is not taken, which halts the | |
| 1879 | + * event delivery. | |
| 1880 | + */ | |
| 1881 | + init_wait(&wait); | |
| 1879 | 1882 | write_lock_irq(&ep->lock); |
| 1880 | 1883 | __add_wait_queue_exclusive(&ep->wq, &wait); |
| 1881 | 1884 | write_unlock_irq(&ep->lock); |
| 1882 | − } | |
| 1883 | 1885 | |
| 1884 | − for (;;) { | |
| 1885 | 1886 | /* |
| 1886 | 1887 | * We don't want to sleep if the ep_poll_callback() sends us |
| 1887 | 1888 | * a wakeup in between. That's why we set the task state |
| @@ -1911,10 +1912,20 @@ fetch_events: · 23 unmodified lines | ||
| 1911 | 1912 | timed_out = 1; |
| 1912 | 1913 | break; |
| 1913 | 1914 | } |
| 1914 | − } | |
| 1915 | + | |
| 1916 | + /* We were woken up, thus go and try to harvest some events */ | |
| 1917 | + eavail = 1; | |
| 1918 | + | |
| 1919 | + } while (0); | |
| 1915 | 1920 | |
| 1916 | 1921 | __set_current_state(TASK_RUNNING); |
| 1917 | 1922 | |
| 1923 | + if (!list_empty_careful(&wait.entry)) { | |
| 1924 | + write_lock_irq(&ep->lock); | |
| 1925 | + __remove_wait_queue(&ep->wq, &wait); | |
| 1926 | + write_unlock_irq(&ep->lock); | |
| 1927 | + } | |
| 1928 | + | |
| 1918 | 1929 | send_events: |
| 1919 | 1930 | /* |
| 1920 | 1931 | * Try to transfer events to user space. In case we get 0 events and |
| @@ -1925,12 +1936,6 @@ send_events: · 4 unmodified lines | ||
| 1925 | 1936 | !(res = ep_send_events(ep, events, maxevents)) && !timed_out) |
| 1926 | 1937 | goto fetch_events; |
| 1927 | 1938 | |
| 1928 | − if (waiter) { | |
| 1929 | − write_lock_irq(&ep->lock); | |
| 1930 | − __remove_wait_queue(&ep->wq, &wait); | |
| 1931 | − write_unlock_irq(&ep->lock); | |
| 1932 | − } | |
| 1933 | − | |
| 1934 | 1939 | return res; |
| 1935 | 1940 | } |
| 1936 | 1941 | |
| @@ -524,6 +524,7 @@ enum { · 523 unmodified lines | ||
| 524 | 524 | REQ_F_OVERFLOW_BIT, |
| 525 | 525 | REQ_F_POLLED_BIT, |
| 526 | 526 | REQ_F_BUFFER_SELECTED_BIT, |
| 527 | + REQ_F_NO_FILE_TABLE_BIT, | |
| 527 | 528 | |
| 528 | 529 | /* not a real bit, just to check we're not overflowing the space */ |
| 529 | 530 | __REQ_F_LAST_BIT, |
| @@ -577,6 +578,8 @@ enum { · 47 unmodified lines | ||
| 577 | 578 | REQ_F_POLLED = BIT(REQ_F_POLLED_BIT), |
| 578 | 579 | /* buffer already selected */ |
| 579 | 580 | REQ_F_BUFFER_SELECTED = BIT(REQ_F_BUFFER_SELECTED_BIT), |
| 581 | + /* doesn't need file table for this request */ | |
| 582 | + REQ_F_NO_FILE_TABLE = BIT(REQ_F_NO_FILE_TABLE_BIT), | |
| 580 | 583 | }; |
| 581 | 584 | |
| 582 | 585 | struct async_poll { |
| @@ -677,8 +680,6 @@ struct io_op_def { · 94 unmodified lines | ||
| 677 | 680 | unsigned needs_mm : 1; |
| 678 | 681 | /* needs req->file assigned */ |
| 679 | 682 | unsigned needs_file : 1; |
| 680 | − /* needs req->file assigned IFF fd is >= 0 */ | |
| 681 | − unsigned fd_non_neg : 1; | |
| 682 | 683 | /* hash wq insertion if file is a regular file */ |
| 683 | 684 | unsigned hash_reg_file : 1; |
| 684 | 685 | /* unbound wq insertion if file is a non-regular file */ |
| @@ -781,8 +782,6 @@ static const struct io_op_def io_op_defs[] = { · 96 unmodified lines | ||
| 781 | 782 | .needs_file = 1, |
| 782 | 783 | }, |
| 783 | 784 | [IORING_OP_OPENAT] = { |
| 784 | − .needs_file = 1, | |
| 785 | − .fd_non_neg = 1, | |
| 786 | 785 | .file_table = 1, |
| 787 | 786 | .needs_fs = 1, |
| 788 | 787 | }, |
| @@ -796,9 +795,8 @@ static const struct io_op_def io_op_defs[] = { · 7 unmodified lines | ||
| 796 | 795 | }, |
| 797 | 796 | [IORING_OP_STATX] = { |
| 798 | 797 | .needs_mm = 1, |
| 799 | − .needs_file = 1, | |
| 800 | − .fd_non_neg = 1, | |
| 801 | 798 | .needs_fs = 1, |
| 799 | + .file_table = 1, | |
| 802 | 800 | }, |
| 803 | 801 | [IORING_OP_READ] = { |
| 804 | 802 | .needs_mm = 1, |
| @@ -833,8 +831,6 @@ static const struct io_op_def io_op_defs[] = { · 28 unmodified lines | ||
| 833 | 831 | .buffer_select = 1, |
| 834 | 832 | }, |
| 835 | 833 | [IORING_OP_OPENAT2] = { |
| 836 | − .needs_file = 1, | |
| 837 | − .fd_non_neg = 1, | |
| 838 | 834 | .file_table = 1, |
| 839 | 835 | .needs_fs = 1, |
| 840 | 836 | }, |
| @@ -1291,7 +1287,7 @@ static struct io_kiocb *io_get_fallback_req(struct io_ring_ctx *ctx) · 450 unmodified lines | ||
| 1291 | 1287 | struct io_kiocb *req; |
| 1292 | 1288 | |
| 1293 | 1289 | req = ctx->fallback_req; |
| 1294 | − if (!test_and_set_bit_lock(0, (unsigned long *) ctx->fallback_req)) | |
| 1290 | + if (!test_and_set_bit_lock(0, (unsigned long *) &ctx->fallback_req)) | |
| 1295 | 1291 | return req; |
| 1296 | 1292 | |
| 1297 | 1293 | return NULL; |
| @@ -1378,7 +1374,7 @@ static void __io_free_req(struct io_kiocb *req) · 80 unmodified lines | ||
| 1378 | 1374 | if (likely(!io_is_fallback_req(req))) |
| 1379 | 1375 | kmem_cache_free(req_cachep, req); |
| 1380 | 1376 | else |
| 1381 | − clear_bit_unlock(0, (unsigned long *) req->ctx->fallback_req); | |
| 1377 | + clear_bit_unlock(0, (unsigned long *) &req->ctx->fallback_req); | |
| 1382 | 1378 | } |
| 1383 | 1379 | |
| 1384 | 1380 | struct req_batch { |
| @@ -2034,7 +2030,7 @@ static struct file *__io_file_get(struct io_submit_state *state, int fd) · 649 unmodified lines | ||
| 2034 | 2030 | * any file. For now, just ensure that anything potentially problematic is done |
| 2035 | 2031 | * inline. |
| 2036 | 2032 | */ |
| 2037 | −static bool io_file_supports_async(struct file *file) | |
| 2033 | +static bool io_file_supports_async(struct file *file, int rw) | |
| 2038 | 2034 | { |
| 2039 | 2035 | umode_t mode = file_inode(file)->i_mode; |
| 2040 | 2036 | |
| @@ -2043,7 +2039,13 @@ static bool io_file_supports_async(struct file *file) · 2 unmodified lines | ||
| 2043 | 2039 | if (S_ISREG(mode) && file->f_op != &io_uring_fops) |
| 2044 | 2040 | return true; |
| 2045 | 2041 | |
| 2046 | − return false; | |
| 2042 | + if (!(file->f_mode & FMODE_NOWAIT)) | |
| 2043 | + return false; | |
| 2044 | + | |
| 2045 | + if (rw == READ) | |
| 2046 | + return file->f_op->read_iter != NULL; | |
| 2047 | + | |
| 2048 | + return file->f_op->write_iter != NULL; | |
| 2047 | 2049 | } |
| 2048 | 2050 | |
| 2049 | 2051 | static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| @@ -2571,7 +2573,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) · 521 unmodified lines | ||
| 2571 | 2573 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 2572 | 2574 | * we know to async punt it even if it was opened O_NONBLOCK |
| 2573 | 2575 | */ |
| 2574 | − if (force_nonblock && !io_file_supports_async(req->file)) | |
| 2576 | + if (force_nonblock && !io_file_supports_async(req->file, READ)) | |
| 2575 | 2577 | goto copy_iov; |
| 2576 | 2578 | |
| 2577 | 2579 | iov_count = iov_iter_count(&iter); |
| @@ -2594,7 +2596,8 @@ copy_iov: · 16 unmodified lines | ||
| 2594 | 2596 | if (ret) |
| 2595 | 2597 | goto out_free; |
| 2596 | 2598 | /* any defer here is final, must blocking retry */ |
| 2597 | − if (!(req->flags & REQ_F_NOWAIT)) | |
| 2599 | + if (!(req->flags & REQ_F_NOWAIT) && | |
| 2600 | + !file_can_poll(req->file)) | |
| 2598 | 2601 | req->flags |= REQ_F_MUST_PUNT; |
| 2599 | 2602 | return -EAGAIN; |
| 2600 | 2603 | } |
| @@ -2662,7 +2665,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock) · 61 unmodified lines | ||
| 2662 | 2665 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 2663 | 2666 | * we know to async punt it even if it was opened O_NONBLOCK |
| 2664 | 2667 | */ |
| 2665 | − if (force_nonblock && !io_file_supports_async(req->file)) | |
| 2668 | + if (force_nonblock && !io_file_supports_async(req->file, WRITE)) | |
| 2666 | 2669 | goto copy_iov; |
| 2667 | 2670 | |
| 2668 | 2671 | /* file path doesn't support NOWAIT for non-direct_IO */ |
| @@ -2716,7 +2719,8 @@ copy_iov: · 47 unmodified lines | ||
| 2716 | 2719 | if (ret) |
| 2717 | 2720 | goto out_free; |
| 2718 | 2721 | /* any defer here is final, must blocking retry */ |
| 2719 | − req->flags |= REQ_F_MUST_PUNT; | |
| 2722 | + if (!file_can_poll(req->file)) | |
| 2723 | + req->flags |= REQ_F_MUST_PUNT; | |
| 2720 | 2724 | return -EAGAIN; |
| 2721 | 2725 | } |
| 2722 | 2726 | } |
| @@ -2756,15 +2760,6 @@ static int io_splice_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 33 unmodified lines | ||
| 2756 | 2760 | return 0; |
| 2757 | 2761 | } |
| 2758 | 2762 | |
| 2759 | −static bool io_splice_punt(struct file *file) | |
| 2760 | −{ | |
| 2761 | − if (get_pipe_info(file)) | |
| 2762 | − return false; | |
| 2763 | − if (!io_file_supports_async(file)) | |
| 2764 | − return true; | |
| 2765 | − return !(file->f_flags & O_NONBLOCK); | |
| 2766 | −} | |
| 2767 | − | |
| 2768 | 2763 | static int io_splice(struct io_kiocb *req, bool force_nonblock) |
| 2769 | 2764 | { |
| 2770 | 2765 | struct io_splice *sp = &req->splice; |
| @@ -2774,11 +2769,8 @@ static int io_splice(struct io_kiocb *req, bool force_nonblock) · 3 unmodified lines | ||
| 2774 | 2769 | loff_t *poff_in, *poff_out; |
| 2775 | 2770 | long ret; |
| 2776 | 2771 | |
| 2777 | − if (force_nonblock) { | |
| 2778 | − if (io_splice_punt(in) || io_splice_punt(out)) | |
| 2779 | − return -EAGAIN; | |
| 2780 | − flags |= SPLICE_F_NONBLOCK; | |
| 2781 | − } | |
| 2772 | + if (force_nonblock) | |
| 2773 | + return -EAGAIN; | |
| 2782 | 2774 | |
| 2783 | 2775 | poff_in = (sp->off_in == -1) ? NULL : &sp->off_in; |
| 2784 | 2776 | poff_out = (sp->off_out == -1) ? NULL : &sp->off_out; |
| @@ -3355,8 +3347,12 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock) · 570 unmodified lines | ||
| 3355 | 3347 | struct kstat stat; |
| 3356 | 3348 | int ret; |
| 3357 | 3349 | |
| 3358 | − if (force_nonblock) | |
| 3350 | + if (force_nonblock) { | |
| 3351 | + /* only need file table for an actual valid fd */ | |
| 3352 | + if (ctx->dfd == -1 || ctx->dfd == AT_FDCWD) | |
| 3353 | + req->flags |= REQ_F_NO_FILE_TABLE; | |
| 3359 | 3354 | return -EAGAIN; |
| 3355 | + } | |
| 3360 | 3356 | |
| 3361 | 3357 | if (vfs_stat_set_lookup_flags(&lookup_flags, ctx->how.flags)) |
| 3362 | 3358 | return -EINVAL; |
| @@ -3502,7 +3498,7 @@ static void io_sync_file_range_finish(struct io_wq_work **workptr) · 139 unmodified lines | ||
| 3502 | 3498 | if (io_req_cancelled(req)) |
| 3503 | 3499 | return; |
| 3504 | 3500 | __io_sync_file_range(req); |
| 3505 | − io_put_req(req); /* put submission ref */ | |
| 3501 | + io_steal_work(req, workptr); | |
| 3506 | 3502 | } |
| 3507 | 3503 | |
| 3508 | 3504 | static int io_sync_file_range(struct io_kiocb *req, bool force_nonblock) |
| @@ -5015,7 +5011,7 @@ static int io_req_defer(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 1506 unmodified lines | ||
| 5015 | 5011 | int ret; |
| 5016 | 5012 | |
| 5017 | 5013 | /* Still need defer if there is pending req in defer list. */ |
| 5018 | − if (!req_need_defer(req) && list_empty(&ctx->defer_list)) | |
| 5014 | + if (!req_need_defer(req) && list_empty_careful(&ctx->defer_list)) | |
| 5019 | 5015 | return 0; |
| 5020 | 5016 | |
| 5021 | 5017 | if (!req->io && io_alloc_async_ctx(req)) |
| @@ -5364,15 +5360,6 @@ static void io_wq_submit_work(struct io_wq_work **workptr) · 342 unmodified lines | ||
| 5364 | 5360 | io_steal_work(req, workptr); |
| 5365 | 5361 | } |
| 5366 | 5362 | |
| 5367 | −static int io_req_needs_file(struct io_kiocb *req, int fd) | |
| 5368 | −{ | |
| 5369 | − if (!io_op_defs[req->opcode].needs_file) | |
| 5370 | − return 0; | |
| 5371 | − if ((fd == -1 || fd == AT_FDCWD) && io_op_defs[req->opcode].fd_non_neg) | |
| 5372 | − return 0; | |
| 5373 | − return 1; | |
| 5374 | −} | |
| 5375 | − | |
| 5376 | 5363 | static inline struct file *io_file_from_index(struct io_ring_ctx *ctx, |
| 5377 | 5364 | int index) |
| 5378 | 5365 | { |
| @@ -5410,14 +5397,11 @@ static int io_file_get(struct io_submit_state *state, struct io_kiocb *req, · 31 unmodified lines | ||
| 5410 | 5397 | } |
| 5411 | 5398 | |
| 5412 | 5399 | static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req, |
| 5413 | − int fd, unsigned int flags) | |
| 5400 | + int fd) | |
| 5414 | 5401 | { |
| 5415 | 5402 | bool fixed; |
| 5416 | 5403 | |
| 5417 | − if (!io_req_needs_file(req, fd)) | |
| 5418 | − return 0; | |
| 5419 | − | |
| 5420 | − fixed = (flags & IOSQE_FIXED_FILE); | |
| 5404 | + fixed = (req->flags & REQ_F_FIXED_FILE) != 0; | |
| 5421 | 5405 | if (unlikely(!fixed && req->needs_fixed_file)) |
| 5422 | 5406 | return -EBADF; |
| 5423 | 5407 | |
| @@ -5429,7 +5413,7 @@ static int io_grab_files(struct io_kiocb *req) · 5 unmodified lines | ||
| 5429 | 5413 | int ret = -EBADF; |
| 5430 | 5414 | struct io_ring_ctx *ctx = req->ctx; |
| 5431 | 5415 | |
| 5432 | − if (req->work.files) | |
| 5416 | + if (req->work.files || (req->flags & REQ_F_NO_FILE_TABLE)) | |
| 5433 | 5417 | return 0; |
| 5434 | 5418 | if (!ctx->ring_file) |
| 5435 | 5419 | return -EBADF; |
| @@ -5794,7 +5778,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, · 358 unmodified lines | ||
| 5794 | 5778 | struct io_submit_state *state, bool async) |
| 5795 | 5779 | { |
| 5796 | 5780 | unsigned int sqe_flags; |
| 5797 | − int id, fd; | |
| 5781 | + int id; | |
| 5798 | 5782 | |
| 5799 | 5783 | /* |
| 5800 | 5784 | * All io need record the previous position, if LINK vs DARIN, |
| @@ -5846,8 +5830,10 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, · 45 unmodified lines | ||
| 5846 | 5830 | IOSQE_ASYNC | IOSQE_FIXED_FILE | |
| 5847 | 5831 | IOSQE_BUFFER_SELECT | IOSQE_IO_LINK); |
| 5848 | 5832 | |
| 5849 | − fd = READ_ONCE(sqe->fd); | |
| 5850 | − return io_req_set_file(state, req, fd, sqe_flags); | |
| 5833 | + if (!io_op_defs[req->opcode].needs_file) | |
| 5834 | + return 0; | |
| 5835 | + | |
| 5836 | + return io_req_set_file(state, req, READ_ONCE(sqe->fd)); | |
| 5851 | 5837 | } |
| 5852 | 5838 | |
| 5853 | 5839 | static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, |
| @@ -7327,7 +7313,7 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) · 1473 unmodified lines | ||
| 7327 | 7313 | * it could cause shutdown to hang. |
| 7328 | 7314 | */ |
| 7329 | 7315 | while (ctx->sqo_thread && !wq_has_sleeper(&ctx->sqo_wait)) |
| 7330 | − cpu_relax(); | |
| 7316 | + cond_resched(); | |
| 7331 | 7317 | |
| 7332 | 7318 | io_kill_timeouts(ctx); |
| 7333 | 7319 | io_poll_remove_all(ctx); |
| @@ -7356,11 +7342,9 @@ static int io_uring_release(struct inode *inode, struct file *file) · 22 unmodified lines | ||
| 7356 | 7342 | static void io_uring_cancel_files(struct io_ring_ctx *ctx, |
| 7357 | 7343 | struct files_struct *files) |
| 7358 | 7344 | { |
| 7359 | − struct io_kiocb *req; | |
| 7360 | − DEFINE_WAIT(wait); | |
| 7361 | − | |
| 7362 | 7345 | while (!list_empty_careful(&ctx->inflight_list)) { |
| 7363 | − struct io_kiocb *cancel_req = NULL; | |
| 7346 | + struct io_kiocb *cancel_req = NULL, *req; | |
| 7347 | + DEFINE_WAIT(wait); | |
| 7364 | 7348 | |
| 7365 | 7349 | spin_lock_irq(&ctx->inflight_lock); |
| 7366 | 7350 | list_for_each_entry(req, &ctx->inflight_list, inflight_entry) { |
| @@ -7400,6 +7384,7 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, · 33 unmodified lines | ||
| 7400 | 7384 | */ |
| 7401 | 7385 | if (refcount_sub_and_test(2, &cancel_req->refs)) { |
| 7402 | 7386 | io_put_req(cancel_req); |
| 7387 | + finish_wait(&ctx->inflight_wait, &wait); | |
| 7403 | 7388 | continue; |
| 7404 | 7389 | } |
| 7405 | 7390 | } |
| @@ -7407,8 +7392,8 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, · 1 unmodified line | ||
| 7407 | 7392 | io_wq_cancel_work(ctx->io_wq, &cancel_req->work); |
| 7408 | 7393 | io_put_req(cancel_req); |
| 7409 | 7394 | schedule(); |
| 7395 | + finish_wait(&ctx->inflight_wait, &wait); | |
| 7410 | 7396 | } |
| 7411 | − finish_wait(&ctx->inflight_wait, &wait); | |
| 7412 | 7397 | } |
| 7413 | 7398 | |
| 7414 | 7399 | static int io_uring_flush(struct file *file, void *data) |
| @@ -7757,7 +7742,8 @@ err: · 342 unmodified lines | ||
| 7757 | 7742 | return ret; |
| 7758 | 7743 | } |
| 7759 | 7744 | |
| 7760 | −static int io_uring_create(unsigned entries, struct io_uring_params *p) | |
| 7745 | +static int io_uring_create(unsigned entries, struct io_uring_params *p, | |
| 7746 | + struct io_uring_params __user *params) | |
| 7761 | 7747 | { |
| 7762 | 7748 | struct user_struct *user = NULL; |
| 7763 | 7749 | struct io_ring_ctx *ctx; |
| @@ -7849,6 +7835,14 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p) · 85 unmodified lines | ||
| 7849 | 7835 | p->cq_off.overflow = offsetof(struct io_rings, cq_overflow); |
| 7850 | 7836 | p->cq_off.cqes = offsetof(struct io_rings, cqes); |
| 7851 | 7837 | |
| 7838 | + p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP | | |
| 7839 | + IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS | | |
| 7840 | + IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL; | |
| 7841 | + | |
| 7842 | + if (copy_to_user(params, p, sizeof(*p))) { | |
| 7843 | + ret = -EFAULT; | |
| 7844 | + goto err; | |
| 7845 | + } | |
| 7852 | 7846 | /* |
| 7853 | 7847 | * Install ring fd as the very last thing, so we don't risk someone |
| 7854 | 7848 | * having closed it before we finish setup |
| @@ -7857,9 +7851,6 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p) · 2 unmodified lines | ||
| 7857 | 7851 | if (ret < 0) |
| 7858 | 7852 | goto err; |
| 7859 | 7853 | |
| 7860 | − p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP | | |
| 7861 | − IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS | | |
| 7862 | − IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL; | |
| 7863 | 7854 | trace_io_uring_create(ret, ctx, p->sq_entries, p->cq_entries, p->flags); |
| 7864 | 7855 | return ret; |
| 7865 | 7856 | err: |
| @@ -7875,7 +7866,6 @@ err: · 9 unmodified lines | ||
| 7875 | 7866 | static long io_uring_setup(u32 entries, struct io_uring_params __user *params) |
| 7876 | 7867 | { |
| 7877 | 7868 | struct io_uring_params p; |
| 7878 | − long ret; | |
| 7879 | 7869 | int i; |
| 7880 | 7870 | |
| 7881 | 7871 | if (copy_from_user(&p, params, sizeof(p))) |
| @@ -7890,14 +7880,7 @@ static long io_uring_setup(u32 entries, struct io_uring_params __user *params) · 8 unmodified lines | ||
| 7890 | 7880 | IORING_SETUP_CLAMP | IORING_SETUP_ATTACH_WQ)) |
| 7891 | 7881 | return -EINVAL; |
| 7892 | 7882 | |
| 7893 | − ret = io_uring_create(entries, &p); | |
| 7894 | − if (ret < 0) | |
| 7895 | − return ret; | |
| 7896 | − | |
| 7897 | − if (copy_to_user(params, &p, sizeof(p))) | |
| 7898 | − return -EFAULT; | |
| 7899 | − | |
| 7900 | − return ret; | |
| 7883 | + return io_uring_create(entries, &p, params); | |
| 7901 | 7884 | } |
| 7902 | 7885 | |
| 7903 | 7886 | SYSCALL_DEFINE2(io_uring_setup, u32, entries, |
| @@ -55,6 +55,7 @@ EXPORT_SYMBOL(vfs_ioctl); · 54 unmodified lines | ||
| 55 | 55 | static int ioctl_fibmap(struct file *filp, int __user *p) |
| 56 | 56 | { |
| 57 | 57 | struct inode *inode = file_inode(filp); |
| 58 | + struct super_block *sb = inode->i_sb; | |
| 58 | 59 | int error, ur_block; |
| 59 | 60 | sector_t block; |
| 60 | 61 | |
| @@ -71,6 +72,13 @@ static int ioctl_fibmap(struct file *filp, int __user *p) · 10 unmodified lines | ||
| 71 | 72 | block = ur_block; |
| 72 | 73 | error = bmap(inode, &block); |
| 73 | 74 | |
| 75 | + if (block > INT_MAX) { | |
| 76 | + error = -ERANGE; | |
| 77 | + pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n", | |
| 78 | + current->comm, task_pid_nr(current), | |
| 79 | + sb->s_id, filp); | |
| 80 | + } | |
| 81 | + | |
| 74 | 82 | if (error) |
| 75 | 83 | ur_block = 0; |
| 76 | 84 | else |
| @@ -117,10 +117,7 @@ iomap_bmap_actor(struct inode *inode, loff_t pos, loff_t length, · 116 unmodified lines | ||
| 117 | 117 | |
| 118 | 118 | if (iomap->type == IOMAP_MAPPED) { |
| 119 | 119 | addr = (pos - iomap->offset + iomap->addr) >> inode->i_blkbits; |
| 120 | − if (addr > INT_MAX) | |
| 121 | − WARN(1, "would truncate bmap result\n"); | |
| 122 | − else | |
| 123 | − *bno = addr; | |
| 120 | + *bno = addr; | |
| 124 | 121 | } |
| 125 | 122 | return 0; |
| 126 | 123 | } |
| @@ -253,37 +253,45 @@ int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, · 252 unmodified lines | ||
| 253 | 253 | |
| 254 | 254 | int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
| 255 | 255 | { |
| 256 | − struct posix_acl *alloc = NULL, *dfacl = NULL; | |
| 256 | + struct posix_acl *orig = acl, *dfacl = NULL, *alloc; | |
| 257 | 257 | int status; |
| 258 | 258 | |
| 259 | 259 | if (S_ISDIR(inode->i_mode)) { |
| 260 | 260 | switch(type) { |
| 261 | 261 | case ACL_TYPE_ACCESS: |
| 262 | − alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT); | |
| 262 | + alloc = get_acl(inode, ACL_TYPE_DEFAULT); | |
| 263 | 263 | if (IS_ERR(alloc)) |
| 264 | 264 | goto fail; |
| 265 | + dfacl = alloc; | |
| 265 | 266 | break; |
| 266 | 267 | |
| 267 | 268 | case ACL_TYPE_DEFAULT: |
| 268 | − dfacl = acl; | |
| 269 | − alloc = acl = get_acl(inode, ACL_TYPE_ACCESS); | |
| 269 | + alloc = get_acl(inode, ACL_TYPE_ACCESS); | |
| 270 | 270 | if (IS_ERR(alloc)) |
| 271 | 271 | goto fail; |
| 272 | + dfacl = acl; | |
| 273 | + acl = alloc; | |
| 272 | 274 | break; |
| 273 | 275 | } |
| 274 | 276 | } |
| 275 | 277 | |
| 276 | 278 | if (acl == NULL) { |
| 277 | − alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); | |
| 279 | + alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); | |
| 278 | 280 | if (IS_ERR(alloc)) |
| 279 | 281 | goto fail; |
| 282 | + acl = alloc; | |
| 280 | 283 | } |
| 281 | 284 | status = __nfs3_proc_setacls(inode, acl, dfacl); |
| 282 | − posix_acl_release(alloc); | |
| 285 | +out: | |
| 286 | + if (acl != orig) | |
| 287 | + posix_acl_release(acl); | |
| 288 | + if (dfacl != orig) | |
| 289 | + posix_acl_release(dfacl); | |
| 283 | 290 | return status; |
| 284 | 291 | |
| 285 | 292 | fail: |
| 286 | − return PTR_ERR(alloc); | |
| 293 | + status = PTR_ERR(alloc); | |
| 294 | + goto out; | |
| 287 | 295 | } |
| 288 | 296 | |
| 289 | 297 | const struct xattr_handler *nfs3_xattr_handlers[] = { |
| @@ -7891,6 +7891,7 @@ static void · 7890 unmodified lines | ||
| 7891 | 7891 | nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) |
| 7892 | 7892 | { |
| 7893 | 7893 | struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp; |
| 7894 | + struct nfs41_bind_conn_to_session_res *res = task->tk_msg.rpc_resp; | |
| 7894 | 7895 | struct nfs_client *clp = args->client; |
| 7895 | 7896 | |
| 7896 | 7897 | switch (task->tk_status) { |
| @@ -7899,6 +7900,12 @@ nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) · 2 unmodified lines | ||
| 7899 | 7900 | nfs4_schedule_session_recovery(clp->cl_session, |
| 7900 | 7901 | task->tk_status); |
| 7901 | 7902 | } |
| 7903 | + if (args->dir == NFS4_CDFC4_FORE_OR_BOTH && | |
| 7904 | + res->dir != NFS4_CDFS4_BOTH) { | |
| 7905 | + rpc_task_close_connection(task); | |
| 7906 | + if (args->retries++ < MAX_BIND_CONN_TO_SESSION_RETRIES) | |
| 7907 | + rpc_restart_call(task); | |
| 7908 | + } | |
| 7902 | 7909 | } |
| 7903 | 7910 | |
| 7904 | 7911 | static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = { |
| @@ -7921,6 +7928,7 @@ int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt, · 16 unmodified lines | ||
| 7921 | 7928 | struct nfs41_bind_conn_to_session_args args = { |
| 7922 | 7929 | .client = clp, |
| 7923 | 7930 | .dir = NFS4_CDFC4_FORE_OR_BOTH, |
| 7931 | + .retries = 0, | |
| 7924 | 7932 | }; |
| 7925 | 7933 | struct nfs41_bind_conn_to_session_res res; |
| 7926 | 7934 | struct rpc_message msg = { |
| @@ -9191,8 +9199,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout) · 1264 unmodified lines | ||
| 9191 | 9199 | nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0); |
| 9192 | 9200 | |
| 9193 | 9201 | task = rpc_run_task(&task_setup_data); |
| 9194 | − if (IS_ERR(task)) | |
| 9195 | − return ERR_CAST(task); | |
| 9202 | + | |
| 9196 | 9203 | status = rpc_wait_for_completion_task(task); |
| 9197 | 9204 | if (status != 0) |
| 9198 | 9205 | goto out; |
| @@ -1332,13 +1332,15 @@ _pnfs_return_layout(struct inode *ino) · 1331 unmodified lines | ||
| 1332 | 1332 | !valid_layout) { |
| 1333 | 1333 | spin_unlock(&ino->i_lock); |
| 1334 | 1334 | dprintk("NFS: %s no layout segments to return\n", __func__); |
| 1335 | − goto out_put_layout_hdr; | |
| 1335 | + goto out_wait_layoutreturn; | |
| 1336 | 1336 | } |
| 1337 | 1337 | |
| 1338 | 1338 | send = pnfs_prepare_layoutreturn(lo, &stateid, &cred, NULL); |
| 1339 | 1339 | spin_unlock(&ino->i_lock); |
| 1340 | 1340 | if (send) |
| 1341 | 1341 | status = pnfs_send_layoutreturn(lo, &stateid, &cred, IOMODE_ANY, true); |
| 1342 | +out_wait_layoutreturn: | |
| 1343 | + wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN, TASK_UNINTERRUPTIBLE); | |
| 1342 | 1344 | out_put_layout_hdr: |
| 1343 | 1345 | pnfs_free_lseg_list(&tmp_list); |
| 1344 | 1346 | pnfs_put_layout_hdr(lo); |
| @@ -1456,18 +1458,15 @@ retry: · 111 unmodified lines | ||
| 1456 | 1458 | /* lo ref dropped in pnfs_roc_release() */ |
| 1457 | 1459 | layoutreturn = pnfs_prepare_layoutreturn(lo, &stateid, &lc_cred, &iomode); |
| 1458 | 1460 | /* If the creds don't match, we can't compound the layoutreturn */ |
| 1459 | − if (!layoutreturn) | |
| 1461 | + if (!layoutreturn || cred_fscmp(cred, lc_cred) != 0) | |
| 1460 | 1462 | goto out_noroc; |
| 1461 | − if (cred_fscmp(cred, lc_cred) != 0) | |
| 1462 | − goto out_noroc_put_cred; | |
| 1463 | 1463 | |
| 1464 | 1464 | roc = layoutreturn; |
| 1465 | 1465 | pnfs_init_layoutreturn_args(args, lo, &stateid, iomode); |
| 1466 | 1466 | res->lrs_present = 0; |
| 1467 | 1467 | layoutreturn = false; |
| 1468 | − | |
| 1469 | −out_noroc_put_cred: | |
| 1470 | 1468 | put_cred(lc_cred); |
| 1469 | + | |
| 1471 | 1470 | out_noroc: |
| 1472 | 1471 | spin_unlock(&ino->i_lock); |
| 1473 | 1472 | rcu_read_unlock(); |
| @@ -185,7 +185,7 @@ static int __nfs_list_for_each_server(struct list_head *head, · 184 unmodified lines | ||
| 185 | 185 | |
| 186 | 186 | rcu_read_lock(); |
| 187 | 187 | list_for_each_entry_rcu(server, head, client_link) { |
| 188 | − if (!nfs_sb_active(server->super)) | |
| 188 | + if (!(server->super && nfs_sb_active(server->super))) | |
| 189 | 189 | continue; |
| 190 | 190 | rcu_read_unlock(); |
| 191 | 191 | if (last) |
| @@ -275,7 +275,6 @@ static ssize_t dlmfs_file_write(struct file *filp, · 274 unmodified lines | ||
| 275 | 275 | loff_t *ppos) |
| 276 | 276 | { |
| 277 | 277 | int bytes_left; |
| 278 | − ssize_t writelen; | |
| 279 | 278 | char *lvb_buf; |
| 280 | 279 | struct inode *inode = file_inode(filp); |
| 281 | 280 | |
| @@ -285,32 +284,30 @@ static ssize_t dlmfs_file_write(struct file *filp, · 3 unmodified lines | ||
| 285 | 284 | if (*ppos >= i_size_read(inode)) |
| 286 | 285 | return -ENOSPC; |
| 287 | 286 | |
| 287 | + /* don't write past the lvb */ | |
| 288 | + if (count > i_size_read(inode) - *ppos) | |
| 289 | + count = i_size_read(inode) - *ppos; | |
| 290 | + | |
| 288 | 291 | if (!count) |
| 289 | 292 | return 0; |
| 290 | 293 | |
| 291 | 294 | if (!access_ok(buf, count)) |
| 292 | 295 | return -EFAULT; |
| 293 | 296 | |
| 294 | − /* don't write past the lvb */ | |
| 295 | − if ((count + *ppos) > i_size_read(inode)) | |
| 296 | − writelen = i_size_read(inode) - *ppos; | |
| 297 | − else | |
| 298 | − writelen = count - *ppos; | |
| 299 | − | |
| 300 | − lvb_buf = kmalloc(writelen, GFP_NOFS); | |
| 297 | + lvb_buf = kmalloc(count, GFP_NOFS); | |
| 301 | 298 | if (!lvb_buf) |
| 302 | 299 | return -ENOMEM; |
| 303 | 300 | |
| 304 | − bytes_left = copy_from_user(lvb_buf, buf, writelen); | |
| 305 | − writelen -= bytes_left; | |
| 306 | − if (writelen) | |
| 307 | − user_dlm_write_lvb(inode, lvb_buf, writelen); | |
| 301 | + bytes_left = copy_from_user(lvb_buf, buf, count); | |
| 302 | + count -= bytes_left; | |
| 303 | + if (count) | |
| 304 | + user_dlm_write_lvb(inode, lvb_buf, count); | |
| 308 | 305 | |
| 309 | 306 | kfree(lvb_buf); |
| 310 | 307 | |
| 311 | − *ppos = *ppos + writelen; | |
| 312 | − mlog(0, "wrote %zd bytes\n", writelen); | |
| 313 | − return writelen; | |
| 308 | + *ppos = *ppos + count; | |
| 309 | + mlog(0, "wrote %zu bytes\n", count); | |
| 310 | + return count; | |
| 314 | 311 | } |
| 315 | 312 | |
| 316 | 313 | static void dlmfs_init_once(void *foo) |
| @@ -261,14 +261,13 @@ static int propagate_one(struct mount *m) · 260 unmodified lines | ||
| 261 | 261 | child = copy_tree(last_source, last_source->mnt.mnt_root, type); |
| 262 | 262 | if (IS_ERR(child)) |
| 263 | 263 | return PTR_ERR(child); |
| 264 | + read_seqlock_excl(&mount_lock); | |
| 264 | 265 | mnt_set_mountpoint(m, mp, child); |
| 266 | + if (m->mnt_master != dest_master) | |
| 267 | + SET_MNT_MARK(m->mnt_master); | |
| 268 | + read_sequnlock_excl(&mount_lock); | |
| 265 | 269 | last_dest = m; |
| 266 | 270 | last_source = child; |
| 267 | − if (m->mnt_master != dest_master) { | |
| 268 | − read_seqlock_excl(&mount_lock); | |
| 269 | − SET_MNT_MARK(m->mnt_master); | |
| 270 | − read_sequnlock_excl(&mount_lock); | |
| 271 | − } | |
| 272 | 271 | hlist_add_head(&child->mnt_hash, list); |
| 273 | 272 | return count_mounts(m->mnt_ns, child); |
| 274 | 273 | } |
| @@ -1118,6 +1118,10 @@ long do_splice(struct file *in, loff_t __user *off_in, · 1117 unmodified lines | ||
| 1118 | 1118 | loff_t offset; |
| 1119 | 1119 | long ret; |
| 1120 | 1120 | |
| 1121 | + if (unlikely(!(in->f_mode & FMODE_READ) || | |
| 1122 | + !(out->f_mode & FMODE_WRITE))) | |
| 1123 | + return -EBADF; | |
| 1124 | + | |
| 1121 | 1125 | ipipe = get_pipe_info(in); |
| 1122 | 1126 | opipe = get_pipe_info(out); |
| 1123 | 1127 | |
| @@ -1125,12 +1129,6 @@ long do_splice(struct file *in, loff_t __user *off_in, · 1 unmodified line | ||
| 1125 | 1129 | if (off_in || off_out) |
| 1126 | 1130 | return -ESPIPE; |
| 1127 | 1131 | |
| 1128 | − if (!(in->f_mode & FMODE_READ)) | |
| 1129 | − return -EBADF; | |
| 1130 | − | |
| 1131 | − if (!(out->f_mode & FMODE_WRITE)) | |
| 1132 | − return -EBADF; | |
| 1133 | − | |
| 1134 | 1132 | /* Splicing to self would be fun, but... */ |
| 1135 | 1133 | if (ipipe == opipe) |
| 1136 | 1134 | return -EINVAL; |
| @@ -1153,9 +1151,6 @@ long do_splice(struct file *in, loff_t __user *off_in, · 16 unmodified lines | ||
| 1153 | 1151 | offset = out->f_pos; |
| 1154 | 1152 | } |
| 1155 | 1153 | |
| 1156 | − if (unlikely(!(out->f_mode & FMODE_WRITE))) | |
| 1157 | − return -EBADF; | |
| 1158 | − | |
| 1159 | 1154 | if (unlikely(out->f_flags & O_APPEND)) |
| 1160 | 1155 | return -EINVAL; |
| 1161 | 1156 | |
| @@ -1440,15 +1435,11 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, · 278 unmodified lines | ||
| 1440 | 1435 | error = -EBADF; |
| 1441 | 1436 | in = fdget(fd_in); |
| 1442 | 1437 | if (in.file) { |
| 1443 | − if (in.file->f_mode & FMODE_READ) { | |
| 1444 | − out = fdget(fd_out); | |
| 1445 | − if (out.file) { | |
| 1446 | − if (out.file->f_mode & FMODE_WRITE) | |
| 1447 | − error = do_splice(in.file, off_in, | |
| 1448 | − out.file, off_out, | |
| 1449 | − len, flags); | |
| 1450 | − fdput(out); | |
| 1451 | − } | |
| 1438 | + out = fdget(fd_out); | |
| 1439 | + if (out.file) { | |
| 1440 | + error = do_splice(in.file, off_in, out.file, off_out, | |
| 1441 | + len, flags); | |
| 1442 | + fdput(out); | |
| 1452 | 1443 | } |
| 1453 | 1444 | fdput(in); |
| 1454 | 1445 | } |
| @@ -1770,6 +1761,10 @@ static long do_tee(struct file *in, struct file *out, size_t len, · 315 unmodified lines | ||
| 1770 | 1761 | struct pipe_inode_info *opipe = get_pipe_info(out); |
| 1771 | 1762 | int ret = -EINVAL; |
| 1772 | 1763 | |
| 1764 | + if (unlikely(!(in->f_mode & FMODE_READ) || | |
| 1765 | + !(out->f_mode & FMODE_WRITE))) | |
| 1766 | + return -EBADF; | |
| 1767 | + | |
| 1773 | 1768 | /* |
| 1774 | 1769 | * Duplicate the contents of ipipe to opipe without actually |
| 1775 | 1770 | * copying the data. |
| @@ -1795,7 +1790,7 @@ static long do_tee(struct file *in, struct file *out, size_t len, · 19 unmodified lines | ||
| 1795 | 1790 | |
| 1796 | 1791 | SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) |
| 1797 | 1792 | { |
| 1798 | − struct fd in; | |
| 1793 | + struct fd in, out; | |
| 1799 | 1794 | int error; |
| 1800 | 1795 | |
| 1801 | 1796 | if (unlikely(flags & ~SPLICE_F_ALL)) |
| @@ -1807,14 +1802,10 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) · 5 unmodified lines | ||
| 1807 | 1802 | error = -EBADF; |
| 1808 | 1803 | in = fdget(fdin); |
| 1809 | 1804 | if (in.file) { |
| 1810 | − if (in.file->f_mode & FMODE_READ) { | |
| 1811 | − struct fd out = fdget(fdout); | |
| 1812 | − if (out.file) { | |
| 1813 | − if (out.file->f_mode & FMODE_WRITE) | |
| 1814 | − error = do_tee(in.file, out.file, | |
| 1815 | − len, flags); | |
| 1816 | − fdput(out); | |
| 1817 | − } | |
| 1805 | + out = fdget(fdout); | |
| 1806 | + if (out.file) { | |
| 1807 | + error = do_tee(in.file, out.file, len, flags); | |
| 1808 | + fdput(out); | |
| 1818 | 1809 | } |
| 1819 | 1810 | fdput(in); |
| 1820 | 1811 | } |
| @@ -1302,8 +1302,8 @@ int get_tree_bdev(struct fs_context *fc, · 1301 unmodified lines | ||
| 1302 | 1302 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
| 1303 | 1303 | if (bdev->bd_fsfreeze_count > 0) { |
| 1304 | 1304 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 1305 | − blkdev_put(bdev, mode); | |
| 1306 | 1305 | warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev); |
| 1306 | + blkdev_put(bdev, mode); | |
| 1307 | 1307 | return -EBUSY; |
| 1308 | 1308 | } |
| 1309 | 1309 | |
| @@ -164,7 +164,7 @@ static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc) · 163 unmodified lines | ||
| 164 | 164 | goto fail_free; |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | − err = super_setup_bdi_name(sb, "vboxsf-%s.%d", fc->source, sbi->bdi_id); | |
| 167 | + err = super_setup_bdi_name(sb, "vboxsf-%d", sbi->bdi_id); | |
| 168 | 168 | if (err) |
| 169 | 169 | goto fail_free; |
| 170 | 170 | |
| @@ -65,6 +65,7 @@ struct amba_device { · 64 unmodified lines | ||
| 65 | 65 | struct device dev; |
| 66 | 66 | struct resource res; |
| 67 | 67 | struct clk *pclk; |
| 68 | + struct device_dma_parameters dma_parms; | |
| 68 | 69 | unsigned int periphid; |
| 69 | 70 | unsigned int cid; |
| 70 | 71 | struct amba_cs_uci_id uci; |
| @@ -219,6 +219,7 @@ struct backing_dev_info { · 218 unmodified lines | ||
| 219 | 219 | wait_queue_head_t wb_waitq; |
| 220 | 220 | |
| 221 | 221 | struct device *dev; |
| 222 | + char dev_name[64]; | |
| 222 | 223 | struct device *owner; |
| 223 | 224 | |
| 224 | 225 | struct timer_list laptop_mode_wb_timer; |
| @@ -505,13 +505,6 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi) · 504 unmodified lines | ||
| 505 | 505 | (1 << WB_async_congested)); |
| 506 | 506 | } |
| 507 | 507 | |
| 508 | −extern const char *bdi_unknown_name; | |
| 509 | − | |
| 510 | −static inline const char *bdi_dev_name(struct backing_dev_info *bdi) | |
| 511 | −{ | |
| 512 | − if (!bdi || !bdi->dev) | |
| 513 | − return bdi_unknown_name; | |
| 514 | − return dev_name(bdi->dev); | |
| 515 | −} | |
| 508 | +const char *bdi_dev_name(struct backing_dev_info *bdi); | |
| 516 | 509 | |
| 517 | 510 | #endif /* _LINUX_BACKING_DEV_H */ |
| @@ -329,13 +329,12 @@ struct dma_buf { · 328 unmodified lines | ||
| 329 | 329 | |
| 330 | 330 | /** |
| 331 | 331 | * struct dma_buf_attach_ops - importer operations for an attachment |
| 332 | − * @move_notify: [optional] notification that the DMA-buf is moving | |
| 333 | 332 | * |
| 334 | 333 | * Attachment operations implemented by the importer. |
| 335 | 334 | */ |
| 336 | 335 | struct dma_buf_attach_ops { |
| 337 | 336 | /** |
| 338 | − * @move_notify | |
| 337 | + * @move_notify: [optional] notification that the DMA-buf is moving | |
| 339 | 338 | * |
| 340 | 339 | * If this callback is provided the framework can avoid pinning the |
| 341 | 340 | * backing store while mappings exists. |
| @@ -83,9 +83,9 @@ enum dma_transfer_direction { · 82 unmodified lines | ||
| 83 | 83 | /** |
| 84 | 84 | * Interleaved Transfer Request |
| 85 | 85 | * ---------------------------- |
| 86 | − * A chunk is collection of contiguous bytes to be transfered. | |
| 86 | + * A chunk is collection of contiguous bytes to be transferred. | |
| 87 | 87 | * The gap(in bytes) between two chunks is called inter-chunk-gap(ICG). |
| 88 | − * ICGs may or maynot change between chunks. | |
| 88 | + * ICGs may or may not change between chunks. | |
| 89 | 89 | * A FRAME is the smallest series of contiguous {chunk,icg} pairs, |
| 90 | 90 | * that when repeated an integral number of times, specifies the transfer. |
| 91 | 91 | * A transfer template is specification of a Frame, the number of times |
| @@ -341,13 +341,11 @@ struct dma_chan { · 249 unmodified lines | ||
| 341 | 341 | * @chan: driver channel device |
| 342 | 342 | * @device: sysfs device |
| 343 | 343 | * @dev_id: parent dma_device dev_id |
| 344 | − * @idr_ref: reference count to gate release of dma_device dev_id | |
| 345 | 344 | */ |
| 346 | 345 | struct dma_chan_dev { |
| 347 | 346 | struct dma_chan *chan; |
| 348 | 347 | struct device device; |
| 349 | 348 | int dev_id; |
| 350 | − atomic_t *idr_ref; | |
| 351 | 349 | }; |
| 352 | 350 | |
| 353 | 351 | /** |
| @@ -835,6 +833,8 @@ struct dma_device { · 481 unmodified lines | ||
| 835 | 833 | int dev_id; |
| 836 | 834 | struct device *dev; |
| 837 | 835 | struct module *owner; |
| 836 | + struct ida chan_ida; | |
| 837 | + struct mutex chan_mutex; /* to protect chan_ida */ | |
| 838 | 838 | |
| 839 | 839 | u32 src_addr_widths; |
| 840 | 840 | u32 dst_addr_widths; |
| @@ -1069,7 +1069,7 @@ static inline int dmaengine_terminate_all(struct dma_chan *chan) · 228 unmodified lines | ||
| 1069 | 1069 | * dmaengine_synchronize() needs to be called before it is safe to free |
| 1070 | 1070 | * any memory that is accessed by previously submitted descriptors or before |
| 1071 | 1071 | * freeing any resources accessed from within the completion callback of any |
| 1072 | − * perviously submitted descriptors. | |
| 1072 | + * previously submitted descriptors. | |
| 1073 | 1073 | * |
| 1074 | 1074 | * This function can be called from atomic context as well as from within a |
| 1075 | 1075 | * complete callback of a descriptor submitted on the same channel. |
| @@ -1091,7 +1091,7 @@ static inline int dmaengine_terminate_async(struct dma_chan *chan) · 15 unmodified lines | ||
| 1091 | 1091 | * |
| 1092 | 1092 | * Synchronizes to the DMA channel termination to the current context. When this |
| 1093 | 1093 | * function returns it is guaranteed that all transfers for previously issued |
| 1094 | − * descriptors have stopped and and it is safe to free the memory assoicated | |
| 1094 | + * descriptors have stopped and it is safe to free the memory associated | |
| 1095 | 1095 | * with them. Furthermore it is guaranteed that all complete callback functions |
| 1096 | 1096 | * for a previously submitted descriptor have finished running and it is safe to |
| 1097 | 1097 | * free resources accessed from within the complete callbacks. |
| @@ -983,7 +983,7 @@ struct file_handle { · 982 unmodified lines | ||
| 983 | 983 | __u32 handle_bytes; |
| 984 | 984 | int handle_type; |
| 985 | 985 | /* file identifier */ |
| 986 | − unsigned char f_handle[0]; | |
| 986 | + unsigned char f_handle[]; | |
| 987 | 987 | }; |
| 988 | 988 | |
| 989 | 989 | static inline struct file *get_file(struct file *f) |
| @@ -55,7 +55,7 @@ LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, struct linux_binprm *bprm) · 54 unmodified lines | ||
| 55 | 55 | LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, struct linux_binprm *bprm) |
| 56 | 56 | LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc, |
| 57 | 57 | struct fs_context *src_sc) |
| 58 | −LSM_HOOK(int, 0, fs_context_parse_param, struct fs_context *fc, | |
| 58 | +LSM_HOOK(int, -ENOPARAM, fs_context_parse_param, struct fs_context *fc, | |
| 59 | 59 | struct fs_parameter *param) |
| 60 | 60 | LSM_HOOK(int, 0, sb_alloc_security, struct super_block *sb) |
| 61 | 61 | LSM_HOOK(void, LSM_RET_VOID, sb_free_security, struct super_block *sb) |
| @@ -53,9 +53,9 @@ enum mhi_callback { · 52 unmodified lines | ||
| 53 | 53 | * @MHI_CHAIN: Linked transfer |
| 54 | 54 | */ |
| 55 | 55 | enum mhi_flags { |
| 56 | − MHI_EOB, | |
| 57 | − MHI_EOT, | |
| 58 | − MHI_CHAIN, | |
| 56 | + MHI_EOB = BIT(0), | |
| 57 | + MHI_EOT = BIT(1), | |
| 58 | + MHI_CHAIN = BIT(2), | |
| 59 | 59 | }; |
| 60 | 60 | |
| 61 | 61 | /** |
| @@ -335,14 +335,15 @@ struct mhi_controller_config { · 273 unmodified lines | ||
| 335 | 335 | * @syserr_worker: System error worker |
| 336 | 336 | * @state_event: State change event |
| 337 | 337 | * @status_cb: CB function to notify power states of the device (required) |
| 338 | − * @link_status: CB function to query link status of the device (required) | |
| 339 | 338 | * @wake_get: CB function to assert device wake (optional) |
| 340 | 339 | * @wake_put: CB function to de-assert device wake (optional) |
| 341 | 340 | * @wake_toggle: CB function to assert and de-assert device wake (optional) |
| 342 | 341 | * @runtime_get: CB function to controller runtime resume (required) |
| 343 | − * @runtimet_put: CB function to decrement pm usage (required) | |
| 342 | + * @runtime_put: CB function to decrement pm usage (required) | |
| 344 | 343 | * @map_single: CB function to create TRE buffer |
| 345 | 344 | * @unmap_single: CB function to destroy TRE buffer |
| 345 | + * @read_reg: Read a MHI register via the physical link (required) | |
| 346 | + * @write_reg: Write a MHI register via the physical link (required) | |
| 346 | 347 | * @buffer_len: Bounce buffer length |
| 347 | 348 | * @bounce_buf: Use of bounce buffer |
| 348 | 349 | * @fbc_download: MHI host needs to do complete image transfer (optional) |
| @@ -417,7 +418,6 @@ struct mhi_controller { · 68 unmodified lines | ||
| 417 | 418 | |
| 418 | 419 | void (*status_cb)(struct mhi_controller *mhi_cntrl, |
| 419 | 420 | enum mhi_callback cb); |
| 420 | − int (*link_status)(struct mhi_controller *mhi_cntrl); | |
| 421 | 421 | void (*wake_get)(struct mhi_controller *mhi_cntrl, bool override); |
| 422 | 422 | void (*wake_put)(struct mhi_controller *mhi_cntrl, bool override); |
| 423 | 423 | void (*wake_toggle)(struct mhi_controller *mhi_cntrl); |
| @@ -427,6 +427,10 @@ struct mhi_controller { · 3 unmodified lines | ||
| 427 | 427 | struct mhi_buf_info *buf); |
| 428 | 428 | void (*unmap_single)(struct mhi_controller *mhi_cntrl, |
| 429 | 429 | struct mhi_buf_info *buf); |
| 430 | + int (*read_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr, | |
| 431 | + u32 *out); | |
| 432 | + void (*write_reg)(struct mhi_controller *mhi_cntrl, void __iomem *addr, | |
| 433 | + u32 val); | |
| 430 | 434 | |
| 431 | 435 | size_t buffer_len; |
| 432 | 436 | bool bounce_buf; |
| @@ -1317,11 +1317,13 @@ struct nfs41_impl_id { · 1316 unmodified lines | ||
| 1317 | 1317 | struct nfstime4 date; |
| 1318 | 1318 | }; |
| 1319 | 1319 | |
| 1320 | +#define MAX_BIND_CONN_TO_SESSION_RETRIES 3 | |
| 1320 | 1321 | struct nfs41_bind_conn_to_session_args { |
| 1321 | 1322 | struct nfs_client *client; |
| 1322 | 1323 | struct nfs4_sessionid sessionid; |
| 1323 | 1324 | u32 dir; |
| 1324 | 1325 | bool use_conn_in_rdma_mode; |
| 1326 | + int retries; | |
| 1325 | 1327 | }; |
| 1326 | 1328 | |
| 1327 | 1329 | struct nfs41_bind_conn_to_session_res { |
| @@ -185,6 +185,7 @@ int cros_ec_sensorhub_register_push_data(struct cros_ec_sensorhub *sensorhub, · 184 unmodified lines | ||
| 185 | 185 | void cros_ec_sensorhub_unregister_push_data(struct cros_ec_sensorhub *sensorhub, |
| 186 | 186 | u8 sensor_num); |
| 187 | 187 | |
| 188 | +int cros_ec_sensorhub_ring_allocate(struct cros_ec_sensorhub *sensorhub); | |
| 188 | 189 | int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub); |
| 189 | 190 | void cros_ec_sensorhub_ring_remove(void *arg); |
| 190 | 191 | int cros_ec_sensorhub_ring_fifo_enable(struct cros_ec_sensorhub *sensorhub, |
| @@ -25,6 +25,7 @@ struct platform_device { · 24 unmodified lines | ||
| 25 | 25 | bool id_auto; |
| 26 | 26 | struct device dev; |
| 27 | 27 | u64 platform_dma_mask; |
| 28 | + struct device_dma_parameters dma_parms; | |
| 28 | 29 | u32 num_resources; |
| 29 | 30 | struct resource *resource; |
| 30 | 31 | |
| @@ -71,7 +71,13 @@ struct rpc_clnt { · 70 unmodified lines | ||
| 71 | 71 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
| 72 | 72 | struct dentry *cl_debugfs; /* debugfs directory */ |
| 73 | 73 | #endif |
| 74 | − struct rpc_xprt_iter cl_xpi; | |
| 74 | + /* cl_work is only needed after cl_xpi is no longer used, | |
| 75 | + * and that are of similar size | |
| 76 | + */ | |
| 77 | + union { | |
| 78 | + struct rpc_xprt_iter cl_xpi; | |
| 79 | + struct work_struct cl_work; | |
| 80 | + }; | |
| 75 | 81 | const struct cred *cl_cred; |
| 76 | 82 | }; |
| 77 | 83 | |
| @@ -236,4 +242,9 @@ static inline int rpc_reply_expected(struct rpc_task *task) · 158 unmodified lines | ||
| 236 | 242 | (task->tk_msg.rpc_proc->p_decode != NULL); |
| 237 | 243 | } |
| 238 | 244 | |
| 245 | +static inline void rpc_task_close_connection(struct rpc_task *task) | |
| 246 | +{ | |
| 247 | + if (task->tk_xprt) | |
| 248 | + xprt_force_disconnect(task->tk_xprt); | |
| 249 | +} | |
| 239 | 250 | #endif /* _LINUX_SUNRPC_CLNT_H */ |
| @@ -78,47 +78,6 @@ struct tcp_sack_block { · 77 unmodified lines | ||
| 78 | 78 | #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ |
| 79 | 79 | #define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/ |
| 80 | 80 | |
| 81 | −#if IS_ENABLED(CONFIG_MPTCP) | |
| 82 | −struct mptcp_options_received { | |
| 83 | − u64 sndr_key; | |
| 84 | − u64 rcvr_key; | |
| 85 | − u64 data_ack; | |
| 86 | − u64 data_seq; | |
| 87 | − u32 subflow_seq; | |
| 88 | − u16 data_len; | |
| 89 | − u16 mp_capable : 1, | |
| 90 | − mp_join : 1, | |
| 91 | − dss : 1, | |
| 92 | − add_addr : 1, | |
| 93 | − rm_addr : 1, | |
| 94 | − family : 4, | |
| 95 | − echo : 1, | |
| 96 | − backup : 1; | |
| 97 | − u32 token; | |
| 98 | − u32 nonce; | |
| 99 | − u64 thmac; | |
| 100 | − u8 hmac[20]; | |
| 101 | − u8 join_id; | |
| 102 | − u8 use_map:1, | |
| 103 | − dsn64:1, | |
| 104 | − data_fin:1, | |
| 105 | − use_ack:1, | |
| 106 | − ack64:1, | |
| 107 | − mpc_map:1, | |
| 108 | − __unused:2; | |
| 109 | − u8 addr_id; | |
| 110 | − u8 rm_id; | |
| 111 | − union { | |
| 112 | − struct in_addr addr; | |
| 113 | −#if IS_ENABLED(CONFIG_MPTCP_IPV6) | |
| 114 | − struct in6_addr addr6; | |
| 115 | −#endif | |
| 116 | − }; | |
| 117 | − u64 ahmac; | |
| 118 | − u16 port; | |
| 119 | −}; | |
| 120 | −#endif | |
| 121 | − | |
| 122 | 81 | struct tcp_options_received { |
| 123 | 82 | /* PAWS/RTTM data */ |
| 124 | 83 | int ts_recent_stamp;/* Time we stored ts_recent (for aging) */ |
| @@ -136,9 +95,6 @@ struct tcp_options_received { · 11 unmodified lines | ||
| 136 | 95 | u8 num_sacks; /* Number of SACK blocks */ |
| 137 | 96 | u16 user_mss; /* mss requested by user in ioctl */ |
| 138 | 97 | u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ |
| 139 | −#if IS_ENABLED(CONFIG_MPTCP) | |
| 140 | − struct mptcp_options_received mptcp; | |
| 141 | −#endif | |
| 142 | 98 | }; |
| 143 | 99 | |
| 144 | 100 | static inline void tcp_clear_options(struct tcp_options_received *rx_opt) |
| @@ -148,13 +104,6 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt) · 3 unmodified lines | ||
| 148 | 104 | #if IS_ENABLED(CONFIG_SMC) |
| 149 | 105 | rx_opt->smc_ok = 0; |
| 150 | 106 | #endif |
| 151 | −#if IS_ENABLED(CONFIG_MPTCP) | |
| 152 | − rx_opt->mptcp.mp_capable = 0; | |
| 153 | − rx_opt->mptcp.mp_join = 0; | |
| 154 | − rx_opt->mptcp.add_addr = 0; | |
| 155 | − rx_opt->mptcp.rm_addr = 0; | |
| 156 | − rx_opt->mptcp.dss = 0; | |
| 157 | −#endif | |
| 158 | 107 | } |
| 159 | 108 | |
| 160 | 109 | /* This is the max number of SACKS that we'll generate and process. It's safe |
| @@ -66,7 +66,7 @@ struct tty_buffer { · 65 unmodified lines | ||
| 66 | 66 | int read; |
| 67 | 67 | int flags; |
| 68 | 68 | /* Data points here */ |
| 69 | − unsigned long data[0]; | |
| 69 | + unsigned long data[]; | |
| 70 | 70 | }; |
| 71 | 71 | |
| 72 | 72 | /* Values for .flags field of tty_buffer */ |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | #define _LINUX_VIRTIO_NET_H |
| 4 | 4 | |
| 5 | 5 | #include <linux/if_vlan.h> |
| 6 | +#include <uapi/linux/tcp.h> | |
| 7 | +#include <uapi/linux/udp.h> | |
| 6 | 8 | #include <uapi/linux/virtio_net.h> |
| 7 | 9 | |
| 8 | 10 | static inline int virtio_net_hdr_set_proto(struct sk_buff *skb, |
| @@ -28,17 +30,25 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, · 19 unmodified lines | ||
| 28 | 30 | bool little_endian) |
| 29 | 31 | { |
| 30 | 32 | unsigned int gso_type = 0; |
| 33 | + unsigned int thlen = 0; | |
| 34 | + unsigned int ip_proto; | |
| 31 | 35 | |
| 32 | 36 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
| 33 | 37 | switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { |
| 34 | 38 | case VIRTIO_NET_HDR_GSO_TCPV4: |
| 35 | 39 | gso_type = SKB_GSO_TCPV4; |
| 40 | + ip_proto = IPPROTO_TCP; | |
| 41 | + thlen = sizeof(struct tcphdr); | |
| 36 | 42 | break; |
| 37 | 43 | case VIRTIO_NET_HDR_GSO_TCPV6: |
| 38 | 44 | gso_type = SKB_GSO_TCPV6; |
| 45 | + ip_proto = IPPROTO_TCP; | |
| 46 | + thlen = sizeof(struct tcphdr); | |
| 39 | 47 | break; |
| 40 | 48 | case VIRTIO_NET_HDR_GSO_UDP: |
| 41 | 49 | gso_type = SKB_GSO_UDP; |
| 50 | + ip_proto = IPPROTO_UDP; | |
| 51 | + thlen = sizeof(struct udphdr); | |
| 42 | 52 | break; |
| 43 | 53 | default: |
| 44 | 54 | return -EINVAL; |
| @@ -57,16 +67,22 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, · 12 unmodified lines | ||
| 57 | 67 | |
| 58 | 68 | if (!skb_partial_csum_set(skb, start, off)) |
| 59 | 69 | return -EINVAL; |
| 70 | + | |
| 71 | + if (skb_transport_offset(skb) + thlen > skb_headlen(skb)) | |
| 72 | + return -EINVAL; | |
| 60 | 73 | } else { |
| 61 | 74 | /* gso packets without NEEDS_CSUM do not set transport_offset. |
| 62 | 75 | * probe and drop if does not match one of the above types. |
| 63 | 76 | */ |
| 64 | 77 | if (gso_type && skb->network_header) { |
| 78 | + struct flow_keys_basic keys; | |
| 79 | + | |
| 65 | 80 | if (!skb->protocol) |
| 66 | 81 | virtio_net_hdr_set_proto(skb, hdr); |
| 67 | 82 | retry: |
| 68 | − skb_probe_transport_header(skb); | |
| 69 | − if (!skb_transport_header_was_set(skb)) { | |
| 83 | + if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, | |
| 84 | + NULL, 0, 0, 0, | |
| 85 | + 0)) { | |
| 70 | 86 | /* UFO does not specify ipv4 or 6: try both */ |
| 71 | 87 | if (gso_type & SKB_GSO_UDP && |
| 72 | 88 | skb->protocol == htons(ETH_P_IP)) { |
| @@ -75,6 +91,12 @@ retry: · 2 unmodified lines | ||
| 75 | 91 | } |
| 76 | 92 | return -EINVAL; |
| 77 | 93 | } |
| 94 | + | |
| 95 | + if (keys.control.thoff + thlen > skb_headlen(skb) || | |
| 96 | + keys.basic.ip_proto != ip_proto) | |
| 97 | + return -EINVAL; | |
| 98 | + | |
| 99 | + skb_set_transport_header(skb, keys.control.thoff); | |
| 78 | 100 | } |
| 79 | 101 | } |
| 80 | 102 | |
| @@ -48,6 +48,7 @@ struct virtio_vsock_pkt { · 47 unmodified lines | ||
| 48 | 48 | u32 len; |
| 49 | 49 | u32 off; |
| 50 | 50 | bool reply; |
| 51 | + bool tap_delivered; | |
| 51 | 52 | }; |
| 52 | 53 | |
| 53 | 54 | struct virtio_vsock_pkt_info { |
| @@ -166,15 +166,18 @@ enum flow_action_mangle_base { · 165 unmodified lines | ||
| 166 | 166 | enum flow_action_hw_stats_bit { |
| 167 | 167 | FLOW_ACTION_HW_STATS_IMMEDIATE_BIT, |
| 168 | 168 | FLOW_ACTION_HW_STATS_DELAYED_BIT, |
| 169 | + FLOW_ACTION_HW_STATS_DISABLED_BIT, | |
| 169 | 170 | }; |
| 170 | 171 | |
| 171 | 172 | enum flow_action_hw_stats { |
| 172 | − FLOW_ACTION_HW_STATS_DISABLED = 0, | |
| 173 | + FLOW_ACTION_HW_STATS_DONT_CARE = 0, | |
| 173 | 174 | FLOW_ACTION_HW_STATS_IMMEDIATE = |
| 174 | 175 | BIT(FLOW_ACTION_HW_STATS_IMMEDIATE_BIT), |
| 175 | 176 | FLOW_ACTION_HW_STATS_DELAYED = BIT(FLOW_ACTION_HW_STATS_DELAYED_BIT), |
| 176 | 177 | FLOW_ACTION_HW_STATS_ANY = FLOW_ACTION_HW_STATS_IMMEDIATE | |
| 177 | 178 | FLOW_ACTION_HW_STATS_DELAYED, |
| 179 | + FLOW_ACTION_HW_STATS_DISABLED = | |
| 180 | + BIT(FLOW_ACTION_HW_STATS_DISABLED_BIT), | |
| 178 | 181 | }; |
| 179 | 182 | |
| 180 | 183 | typedef void (*action_destr)(void *priv); |
| @@ -325,7 +328,11 @@ __flow_action_hw_stats_check(const struct flow_action *action, · 144 unmodified lines | ||
| 325 | 328 | return true; |
| 326 | 329 | if (!flow_action_mixed_hw_stats_check(action, extack)) |
| 327 | 330 | return false; |
| 331 | + | |
| 328 | 332 | action_entry = flow_action_first_entry_get(action); |
| 333 | + if (action_entry->hw_stats == FLOW_ACTION_HW_STATS_DONT_CARE) | |
| 334 | + return true; | |
| 335 | + | |
| 329 | 336 | if (!check_allow_bit && |
| 330 | 337 | action_entry->hw_stats != FLOW_ACTION_HW_STATS_ANY) { |
| 331 | 338 | NL_SET_ERR_MSG_MOD(extack, "Driver supports only default HW stats type \"any\""); |
| @@ -99,6 +99,20 @@ static inline int IP_ECN_set_ce(struct iphdr *iph) · 98 unmodified lines | ||
| 99 | 99 | return 1; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | +static inline int IP_ECN_set_ect1(struct iphdr *iph) | |
| 103 | +{ | |
| 104 | + u32 check = (__force u32)iph->check; | |
| 105 | + | |
| 106 | + if ((iph->tos & INET_ECN_MASK) != INET_ECN_ECT_0) | |
| 107 | + return 0; | |
| 108 | + | |
| 109 | + check += (__force u16)htons(0x100); | |
| 110 | + | |
| 111 | + iph->check = (__force __sum16)(check + (check>=0xFFFF)); | |
| 112 | + iph->tos ^= INET_ECN_MASK; | |
| 113 | + return 1; | |
| 114 | +} | |
| 115 | + | |
| 102 | 116 | static inline void IP_ECN_clear(struct iphdr *iph) |
| 103 | 117 | { |
| 104 | 118 | iph->tos &= ~INET_ECN_MASK; |
| @@ -134,6 +148,22 @@ static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph) · 29 unmodified lines | ||
| 134 | 148 | return 1; |
| 135 | 149 | } |
| 136 | 150 | |
| 151 | +static inline int IP6_ECN_set_ect1(struct sk_buff *skb, struct ipv6hdr *iph) | |
| 152 | +{ | |
| 153 | + __be32 from, to; | |
| 154 | + | |
| 155 | + if ((ipv6_get_dsfield(iph) & INET_ECN_MASK) != INET_ECN_ECT_0) | |
| 156 | + return 0; | |
| 157 | + | |
| 158 | + from = *(__be32 *)iph; | |
| 159 | + to = from ^ htonl(INET_ECN_MASK << 20); | |
| 160 | + *(__be32 *)iph = to; | |
| 161 | + if (skb->ip_summed == CHECKSUM_COMPLETE) | |
| 162 | + skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from), | |
| 163 | + (__force __wsum)to); | |
| 164 | + return 1; | |
| 165 | +} | |
| 166 | + | |
| 137 | 167 | static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner) |
| 138 | 168 | { |
| 139 | 169 | dscp &= ~INET_ECN_MASK; |
| @@ -159,6 +189,25 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) · 19 unmodified lines | ||
| 159 | 189 | return 0; |
| 160 | 190 | } |
| 161 | 191 | |
| 192 | +static inline int INET_ECN_set_ect1(struct sk_buff *skb) | |
| 193 | +{ | |
| 194 | + switch (skb->protocol) { | |
| 195 | + case cpu_to_be16(ETH_P_IP): | |
| 196 | + if (skb_network_header(skb) + sizeof(struct iphdr) <= | |
| 197 | + skb_tail_pointer(skb)) | |
| 198 | + return IP_ECN_set_ect1(ip_hdr(skb)); | |
| 199 | + break; | |
| 200 | + | |
| 201 | + case cpu_to_be16(ETH_P_IPV6): | |
| 202 | + if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= | |
| 203 | + skb_tail_pointer(skb)) | |
| 204 | + return IP6_ECN_set_ect1(skb, ipv6_hdr(skb)); | |
| 205 | + break; | |
| 206 | + } | |
| 207 | + | |
| 208 | + return 0; | |
| 209 | +} | |
| 210 | + | |
| 162 | 211 | /* |
| 163 | 212 | * RFC 6040 4.2 |
| 164 | 213 | * To decapsulate the inner header at the tunnel egress, a compliant |
| @@ -208,8 +257,12 @@ static inline int INET_ECN_decapsulate(struct sk_buff *skb, · 43 unmodified lines | ||
| 208 | 257 | int rc; |
| 209 | 258 | |
| 210 | 259 | rc = __INET_ECN_decapsulate(outer, inner, &set_ce); |
| 211 | − if (!rc && set_ce) | |
| 212 | − INET_ECN_set_ce(skb); | |
| 260 | + if (!rc) { | |
| 261 | + if (set_ce) | |
| 262 | + INET_ECN_set_ce(skb); | |
| 263 | + else if ((outer & INET_ECN_MASK) == INET_ECN_ECT_1) | |
| 264 | + INET_ECN_set_ect1(skb); | |
| 265 | + } | |
| 213 | 266 | |
| 214 | 267 | return rc; |
| 215 | 268 | } |
| @@ -203,6 +203,7 @@ struct fib6_info { · 202 unmodified lines | ||
| 203 | 203 | struct rt6_info { |
| 204 | 204 | struct dst_entry dst; |
| 205 | 205 | struct fib6_info __rcu *from; |
| 206 | + int sernum; | |
| 206 | 207 | |
| 207 | 208 | struct rt6key rt6i_dst; |
| 208 | 209 | struct rt6key rt6i_src; |
| @@ -291,6 +292,9 @@ static inline u32 rt6_get_cookie(const struct rt6_info *rt) · 82 unmodified lines | ||
| 291 | 292 | struct fib6_info *from; |
| 292 | 293 | u32 cookie = 0; |
| 293 | 294 | |
| 295 | + if (rt->sernum) | |
| 296 | + return rt->sernum; | |
| 297 | + | |
| 294 | 298 | rcu_read_lock(); |
| 295 | 299 | |
| 296 | 300 | from = rcu_dereference(rt->from); |
| @@ -68,11 +68,8 @@ static inline bool rsk_is_mptcp(const struct request_sock *req) · 67 unmodified lines | ||
| 68 | 68 | return tcp_rsk(req)->is_mptcp; |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | −void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, | |
| 72 | − int opsize, struct tcp_options_received *opt_rx); | |
| 73 | 71 | bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, |
| 74 | 72 | unsigned int *size, struct mptcp_out_options *opts); |
| 75 | −void mptcp_rcv_synsent(struct sock *sk); | |
| 76 | 73 | bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, |
| 77 | 74 | struct mptcp_out_options *opts); |
| 78 | 75 | bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, |
| @@ -437,6 +437,13 @@ static inline int rt_genid_ipv4(const struct net *net) · 436 unmodified lines | ||
| 437 | 437 | return atomic_read(&net->ipv4.rt_genid); |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | +#if IS_ENABLED(CONFIG_IPV6) | |
| 441 | +static inline int rt_genid_ipv6(const struct net *net) | |
| 442 | +{ | |
| 443 | + return atomic_read(&net->ipv6.fib6_sernum); | |
| 444 | +} | |
| 445 | +#endif | |
| 446 | + | |
| 440 | 447 | static inline void rt_genid_bump_ipv4(struct net *net) |
| 441 | 448 | { |
| 442 | 449 | atomic_inc(&net->ipv4.rt_genid); |
| @@ -407,6 +407,7 @@ struct tcf_block { · 406 unmodified lines | ||
| 407 | 407 | struct mutex lock; |
| 408 | 408 | struct list_head chain_list; |
| 409 | 409 | u32 index; /* block index for shared blocks */ |
| 410 | + u32 classid; /* which class this block belongs to */ | |
| 410 | 411 | refcount_t refcnt; |
| 411 | 412 | struct net *net; |
| 412 | 413 | struct Qdisc *q; |
| @@ -502,6 +502,7 @@ struct ocelot { · 501 unmodified lines | ||
| 502 | 502 | unsigned int num_stats; |
| 503 | 503 | |
| 504 | 504 | int shared_queue_sz; |
| 505 | + int num_mact_rows; | |
| 505 | 506 | |
| 506 | 507 | struct net_device *hw_bridge_dev; |
| 507 | 508 | u16 bridge_mask; |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | * |
| 25 | 25 | * @pid: Put 0 for global total, while positive pid for process total. |
| 26 | 26 | * |
| 27 | − * @size: Virtual size of the allocation in bytes. | |
| 27 | + * @size: Size of the allocation in bytes. | |
| 28 | 28 | * |
| 29 | 29 | */ |
| 30 | 30 | TRACE_EVENT(gpu_mem_total, |
| @@ -692,11 +692,10 @@ TRACE_EVENT(xprtrdma_prepsend_failed, · 691 unmodified lines | ||
| 692 | 692 | |
| 693 | 693 | TRACE_EVENT(xprtrdma_post_send, |
| 694 | 694 | TP_PROTO( |
| 695 | − const struct rpcrdma_req *req, | |
| 696 | − int status | |
| 695 | + const struct rpcrdma_req *req | |
| 697 | 696 | ), |
| 698 | 697 | |
| 699 | − TP_ARGS(req, status), | |
| 698 | + TP_ARGS(req), | |
| 700 | 699 | |
| 701 | 700 | TP_STRUCT__entry( |
| 702 | 701 | __field(const void *, req) |
| @@ -705,7 +704,6 @@ TRACE_EVENT(xprtrdma_post_send, · 2 unmodified lines | ||
| 705 | 704 | __field(unsigned int, client_id) |
| 706 | 705 | __field(int, num_sge) |
| 707 | 706 | __field(int, signaled) |
| 708 | − __field(int, status) | |
| 709 | 707 | ), |
| 710 | 708 | |
| 711 | 709 | TP_fast_assign( |
| @@ -718,15 +716,13 @@ TRACE_EVENT(xprtrdma_post_send, · 6 unmodified lines | ||
| 718 | 716 | __entry->sc = req->rl_sendctx; |
| 719 | 717 | __entry->num_sge = req->rl_wr.num_sge; |
| 720 | 718 | __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED; |
| 721 | − __entry->status = status; | |
| 722 | 719 | ), |
| 723 | 720 | |
| 724 | − TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %sstatus=%d", | |
| 721 | + TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %s", | |
| 725 | 722 | __entry->task_id, __entry->client_id, |
| 726 | 723 | __entry->req, __entry->sc, __entry->num_sge, |
| 727 | 724 | (__entry->num_sge == 1 ? "" : "s"), |
| 728 | − (__entry->signaled ? "signaled " : ""), | |
| 729 | − __entry->status | |
| 725 | + (__entry->signaled ? "signaled" : "") | |
| 730 | 726 | ) |
| 731 | 727 | ); |
| 732 | 728 | |
| @@ -33,7 +33,7 @@ TRACE_EVENT(wbt_stat, · 32 unmodified lines | ||
| 33 | 33 | ), |
| 34 | 34 | |
| 35 | 35 | TP_fast_assign( |
| 36 | − strlcpy(__entry->name, dev_name(bdi->dev), | |
| 36 | + strlcpy(__entry->name, bdi_dev_name(bdi), | |
| 37 | 37 | ARRAY_SIZE(__entry->name)); |
| 38 | 38 | __entry->rmean = stat[0].mean; |
| 39 | 39 | __entry->rmin = stat[0].min; |
| @@ -68,7 +68,7 @@ TRACE_EVENT(wbt_lat, · 28 unmodified lines | ||
| 68 | 68 | ), |
| 69 | 69 | |
| 70 | 70 | TP_fast_assign( |
| 71 | − strlcpy(__entry->name, dev_name(bdi->dev), | |
| 71 | + strlcpy(__entry->name, bdi_dev_name(bdi), | |
| 72 | 72 | ARRAY_SIZE(__entry->name)); |
| 73 | 73 | __entry->lat = div_u64(lat, 1000); |
| 74 | 74 | ), |
| @@ -105,7 +105,7 @@ TRACE_EVENT(wbt_step, · 30 unmodified lines | ||
| 105 | 105 | ), |
| 106 | 106 | |
| 107 | 107 | TP_fast_assign( |
| 108 | − strlcpy(__entry->name, dev_name(bdi->dev), | |
| 108 | + strlcpy(__entry->name, bdi_dev_name(bdi), | |
| 109 | 109 | ARRAY_SIZE(__entry->name)); |
| 110 | 110 | __entry->msg = msg; |
| 111 | 111 | __entry->step = step; |
| @@ -141,7 +141,7 @@ TRACE_EVENT(wbt_timer, · 29 unmodified lines | ||
| 141 | 141 | ), |
| 142 | 142 | |
| 143 | 143 | TP_fast_assign( |
| 144 | − strlcpy(__entry->name, dev_name(bdi->dev), | |
| 144 | + strlcpy(__entry->name, bdi_dev_name(bdi), | |
| 145 | 145 | ARRAY_SIZE(__entry->name)); |
| 146 | 146 | __entry->status = status; |
| 147 | 147 | __entry->step = step; |
| @@ -346,6 +346,10 @@ struct drm_amdgpu_gem_userptr { · 345 unmodified lines | ||
| 346 | 346 | #define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF |
| 347 | 347 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43 |
| 348 | 348 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1 |
| 349 | +#define AMDGPU_TILING_DCC_INDEPENDENT_128B_SHIFT 44 | |
| 350 | +#define AMDGPU_TILING_DCC_INDEPENDENT_128B_MASK 0x1 | |
| 351 | +#define AMDGPU_TILING_SCANOUT_SHIFT 63 | |
| 352 | +#define AMDGPU_TILING_SCANOUT_MASK 0x1 | |
| 349 | 353 | |
| 350 | 354 | /* Set/Get helpers for tiling flags. */ |
| 351 | 355 | #define AMDGPU_TILING_SET(field, value) \ |
| @@ -73,7 +73,7 @@ struct bpf_insn { · 72 unmodified lines | ||
| 73 | 73 | /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ |
| 74 | 74 | struct bpf_lpm_trie_key { |
| 75 | 75 | __u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ |
| 76 | − __u8 data[]; /* Arbitrary size */ | |
| 76 | + __u8 data[0]; /* Arbitrary size */ | |
| 77 | 77 | }; |
| 78 | 78 | |
| 79 | 79 | struct bpf_cgroup_storage_key { |
| @@ -45,13 +45,13 @@ struct dlm_lock_params { · 44 unmodified lines | ||
| 45 | 45 | void __user *bastaddr; |
| 46 | 46 | struct dlm_lksb __user *lksb; |
| 47 | 47 | char lvb[DLM_USER_LVB_LEN]; |
| 48 | − char name[]; | |
| 48 | + char name[0]; | |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | 51 | struct dlm_lspace_params { |
| 52 | 52 | __u32 flags; |
| 53 | 53 | __u32 minor; |
| 54 | − char name[]; | |
| 54 | + char name[0]; | |
| 55 | 55 | }; |
| 56 | 56 | |
| 57 | 57 | struct dlm_purge_params { |
| @@ -39,6 +39,12 @@ struct dma_buf_sync { · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define DMA_BUF_BASE 'b' |
| 41 | 41 | #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) |
| 42 | + | |
| 43 | +/* 32/64bitness of this uapi was botched in android, there's no difference | |
| 44 | + * between them in actual uapi, they're just different numbers. | |
| 45 | + */ | |
| 42 | 46 | #define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *) |
| 47 | +#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32) | |
| 48 | +#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64) | |
| 43 | 49 | |
| 44 | 50 | #endif |
| @@ -34,7 +34,7 @@ struct fiemap { · 33 unmodified lines | ||
| 34 | 34 | __u32 fm_mapped_extents;/* number of extents that were mapped (out) */ |
| 35 | 35 | __u32 fm_extent_count; /* size of fm_extents array (in) */ |
| 36 | 36 | __u32 fm_reserved; |
| 37 | − struct fiemap_extent fm_extents[]; /* array of mapped extents (out) */ | |
| 37 | + struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */ | |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | #define FIEMAP_MAX_OFFSET (~0ULL) |
| @@ -119,8 +119,8 @@ enum hv_fcopy_op { · 118 unmodified lines | ||
| 119 | 119 | |
| 120 | 120 | struct hv_fcopy_hdr { |
| 121 | 121 | __u32 operation; |
| 122 | − uuid_le service_id0; /* currently unused */ | |
| 123 | − uuid_le service_id1; /* currently unused */ | |
| 122 | + __u8 service_id0[16]; /* currently unused */ | |
| 123 | + __u8 service_id1[16]; /* currently unused */ | |
| 124 | 124 | } __attribute__((packed)); |
| 125 | 125 | |
| 126 | 126 | #define OVER_WRITE 0x1 |
| @@ -60,7 +60,7 @@ struct arc_rfc1201 { · 59 unmodified lines | ||
| 60 | 60 | __u8 proto; /* protocol ID field - varies */ |
| 61 | 61 | __u8 split_flag; /* for use with split packets */ |
| 62 | 62 | __be16 sequence; /* sequence number */ |
| 63 | − __u8 payload[]; /* space remaining in packet (504 bytes)*/ | |
| 63 | + __u8 payload[0]; /* space remaining in packet (504 bytes)*/ | |
| 64 | 64 | }; |
| 65 | 65 | #define RFC1201_HDR_SIZE 4 |
| 66 | 66 | |
| @@ -69,7 +69,7 @@ struct arc_rfc1201 { · 2 unmodified lines | ||
| 69 | 69 | */ |
| 70 | 70 | struct arc_rfc1051 { |
| 71 | 71 | __u8 proto; /* ARC_P_RFC1051_ARP/RFC1051_IP */ |
| 72 | − __u8 payload[]; /* 507 bytes */ | |
| 72 | + __u8 payload[0]; /* 507 bytes */ | |
| 73 | 73 | }; |
| 74 | 74 | #define RFC1051_HDR_SIZE 1 |
| 75 | 75 | |
| @@ -80,7 +80,7 @@ struct arc_rfc1051 { · 4 unmodified lines | ||
| 80 | 80 | struct arc_eth_encap { |
| 81 | 81 | __u8 proto; /* Always ARC_P_ETHER */ |
| 82 | 82 | struct ethhdr eth; /* standard ethernet header (yuck!) */ |
| 83 | − __u8 payload[]; /* 493 bytes */ | |
| 83 | + __u8 payload[0]; /* 493 bytes */ | |
| 84 | 84 | }; |
| 85 | 85 | #define ETH_ENCAP_HDR_SIZE 14 |
| 86 | 86 | |
| @@ -57,7 +57,7 @@ struct mmc_ioc_cmd { · 56 unmodified lines | ||
| 57 | 57 | */ |
| 58 | 58 | struct mmc_ioc_multi_cmd { |
| 59 | 59 | __u64 num_of_cmds; |
| 60 | − struct mmc_ioc_cmd cmds[]; | |
| 60 | + struct mmc_ioc_cmd cmds[0]; | |
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | 63 | #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) |
| @@ -29,12 +29,12 @@ struct net_dm_config_entry { · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | struct net_dm_config_msg { |
| 31 | 31 | __u32 entries; |
| 32 | − struct net_dm_config_entry options[]; | |
| 32 | + struct net_dm_config_entry options[0]; | |
| 33 | 33 | }; |
| 34 | 34 | |
| 35 | 35 | struct net_dm_alert_msg { |
| 36 | 36 | __u32 entries; |
| 37 | − struct net_dm_drop_point points[]; | |
| 37 | + struct net_dm_drop_point points[0]; | |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | struct net_dm_user_msg { |
| @@ -40,7 +40,7 @@ struct ebt_mac_wormhash_tuple { · 39 unmodified lines | ||
| 40 | 40 | struct ebt_mac_wormhash { |
| 41 | 41 | int table[257]; |
| 42 | 42 | int poolsize; |
| 43 | − struct ebt_mac_wormhash_tuple pool[]; | |
| 43 | + struct ebt_mac_wormhash_tuple pool[0]; | |
| 44 | 44 | }; |
| 45 | 45 | |
| 46 | 46 | #define ebt_mac_wormhash_size(x) ((x) ? sizeof(struct ebt_mac_wormhash) \ |
| @@ -209,7 +209,7 @@ struct fc_bsg_host_vendor { · 208 unmodified lines | ||
| 209 | 209 | __u64 vendor_id; |
| 210 | 210 | |
| 211 | 211 | /* start of vendor command area */ |
| 212 | − __u32 vendor_cmd[]; | |
| 212 | + __u32 vendor_cmd[0]; | |
| 213 | 213 | }; |
| 214 | 214 | |
| 215 | 215 | /* Response: |
| @@ -39,22 +39,6 @@ config TOOLS_SUPPORT_RELR · 38 unmodified lines | ||
| 39 | 39 | config CC_HAS_ASM_INLINE |
| 40 | 40 | def_bool $(success,echo 'void foo(void) { asm inline (""); }' | $(CC) -x c - -c -o /dev/null) |
| 41 | 41 | |
| 42 | −config CC_HAS_WARN_MAYBE_UNINITIALIZED | |
| 43 | − def_bool $(cc-option,-Wmaybe-uninitialized) | |
| 44 | − help | |
| 45 | − GCC >= 4.7 supports this option. | |
| 46 | − | |
| 47 | −config CC_DISABLE_WARN_MAYBE_UNINITIALIZED | |
| 48 | − bool | |
| 49 | − depends on CC_HAS_WARN_MAYBE_UNINITIALIZED | |
| 50 | − default CC_IS_GCC && GCC_VERSION < 40900 # unreliable for GCC < 4.9 | |
| 51 | − help | |
| 52 | − GCC's -Wmaybe-uninitialized is not reliable by definition. | |
| 53 | − Lots of false positive warnings are produced in some cases. | |
| 54 | − | |
| 55 | − If this option is enabled, -Wno-maybe-uninitialzed is passed | |
| 56 | − to the compiler to suppress maybe-uninitialized warnings. | |
| 57 | − | |
| 58 | 42 | config CONSTRUCTORS |
| 59 | 43 | bool |
| 60 | 44 | depends on !UML |
| @@ -1257,14 +1241,12 @@ config CC_OPTIMIZE_FOR_PERFORMANCE · 1196 unmodified lines | ||
| 1257 | 1241 | config CC_OPTIMIZE_FOR_PERFORMANCE_O3 |
| 1258 | 1242 | bool "Optimize more for performance (-O3)" |
| 1259 | 1243 | depends on ARC |
| 1260 | − imply CC_DISABLE_WARN_MAYBE_UNINITIALIZED # avoid false positives | |
| 1261 | 1244 | help |
| 1262 | 1245 | Choosing this option will pass "-O3" to your compiler to optimize |
| 1263 | 1246 | the kernel yet more for performance. |
| 1264 | 1247 | |
| 1265 | 1248 | config CC_OPTIMIZE_FOR_SIZE |
| 1266 | 1249 | bool "Optimize for size (-Os)" |
| 1267 | − imply CC_DISABLE_WARN_MAYBE_UNINITIALIZED # avoid false positives | |
| 1268 | 1250 | help |
| 1269 | 1251 | Choosing this option will pass "-Os" to your compiler resulting |
| 1270 | 1252 | in a smaller kernel. |
| @@ -542,7 +542,7 @@ void __weak free_initrd_mem(unsigned long start, unsigned long end) · 541 unmodified lines | ||
| 542 | 542 | } |
| 543 | 543 | |
| 544 | 544 | #ifdef CONFIG_KEXEC_CORE |
| 545 | −static bool kexec_free_initrd(void) | |
| 545 | +static bool __init kexec_free_initrd(void) | |
| 546 | 546 | { |
| 547 | 547 | unsigned long crashk_start = (unsigned long)__va(crashk_res.start); |
| 548 | 548 | unsigned long crashk_end = (unsigned long)__va(crashk_res.end); |
| @@ -257,6 +257,47 @@ static int __init loglevel(char *str) · 256 unmodified lines | ||
| 257 | 257 | |
| 258 | 258 | early_param("loglevel", loglevel); |
| 259 | 259 | |
| 260 | +#ifdef CONFIG_BLK_DEV_INITRD | |
| 261 | +static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum) | |
| 262 | +{ | |
| 263 | + u32 size, csum; | |
| 264 | + char *data; | |
| 265 | + u32 *hdr; | |
| 266 | + | |
| 267 | + if (!initrd_end) | |
| 268 | + return NULL; | |
| 269 | + | |
| 270 | + data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN; | |
| 271 | + if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN)) | |
| 272 | + return NULL; | |
| 273 | + | |
| 274 | + hdr = (u32 *)(data - 8); | |
| 275 | + size = hdr[0]; | |
| 276 | + csum = hdr[1]; | |
| 277 | + | |
| 278 | + data = ((void *)hdr) - size; | |
| 279 | + if ((unsigned long)data < initrd_start) { | |
| 280 | + pr_err("bootconfig size %d is greater than initrd size %ld\n", | |
| 281 | + size, initrd_end - initrd_start); | |
| 282 | + return NULL; | |
| 283 | + } | |
| 284 | + | |
| 285 | + /* Remove bootconfig from initramfs/initrd */ | |
| 286 | + initrd_end = (unsigned long)data; | |
| 287 | + if (_size) | |
| 288 | + *_size = size; | |
| 289 | + if (_csum) | |
| 290 | + *_csum = csum; | |
| 291 | + | |
| 292 | + return data; | |
| 293 | +} | |
| 294 | +#else | |
| 295 | +static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum) | |
| 296 | +{ | |
| 297 | + return NULL; | |
| 298 | +} | |
| 299 | +#endif | |
| 300 | + | |
| 260 | 301 | #ifdef CONFIG_BOOT_CONFIG |
| 261 | 302 | |
| 262 | 303 | char xbc_namebuf[XBC_KEYLEN_MAX] __initdata; |
| @@ -357,9 +398,12 @@ static void __init setup_boot_config(const char *cmdline) · 94 unmodified lines | ||
| 357 | 398 | int pos; |
| 358 | 399 | u32 size, csum; |
| 359 | 400 | char *data, *copy; |
| 360 | − u32 *hdr; | |
| 361 | 401 | int ret; |
| 362 | 402 | |
| 403 | + data = get_boot_config_from_initrd(&size, &csum); | |
| 404 | + if (!data) | |
| 405 | + goto not_found; | |
| 406 | + | |
| 363 | 407 | strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); |
| 364 | 408 | parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, |
| 365 | 409 | bootconfig_params); |
| @@ -367,27 +411,12 @@ static void __init setup_boot_config(const char *cmdline) · 1 unmodified line | ||
| 367 | 411 | if (!bootconfig_found) |
| 368 | 412 | return; |
| 369 | 413 | |
| 370 | − if (!initrd_end) | |
| 371 | − goto not_found; | |
| 372 | − | |
| 373 | − data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN; | |
| 374 | − if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN)) | |
| 375 | − goto not_found; | |
| 376 | − | |
| 377 | − hdr = (u32 *)(data - 8); | |
| 378 | − size = hdr[0]; | |
| 379 | − csum = hdr[1]; | |
| 380 | − | |
| 381 | 414 | if (size >= XBC_DATA_MAX) { |
| 382 | 415 | pr_err("bootconfig size %d greater than max size %d\n", |
| 383 | 416 | size, XBC_DATA_MAX); |
| 384 | 417 | return; |
| 385 | 418 | } |
| 386 | 419 | |
| 387 | − data = ((void *)hdr) - size; | |
| 388 | − if ((unsigned long)data < initrd_start) | |
| 389 | − goto not_found; | |
| 390 | − | |
| 391 | 420 | if (boot_config_checksum((unsigned char *)data, size) != csum) { |
| 392 | 421 | pr_err("bootconfig checksum failed\n"); |
| 393 | 422 | return; |
| @@ -420,8 +449,14 @@ static void __init setup_boot_config(const char *cmdline) · 26 unmodified lines | ||
| 420 | 449 | not_found: |
| 421 | 450 | pr_err("'bootconfig' found on command line, but no bootconfig found\n"); |
| 422 | 451 | } |
| 452 | + | |
| 423 | 453 | #else |
| 424 | −#define setup_boot_config(cmdline) do { } while (0) | |
| 454 | + | |
| 455 | +static void __init setup_boot_config(const char *cmdline) | |
| 456 | +{ | |
| 457 | + /* Remove bootconfig data from initrd */ | |
| 458 | + get_boot_config_from_initrd(NULL, NULL); | |
| 459 | +} | |
| 425 | 460 | |
| 426 | 461 | static int __init warn_bootconfig(char *str) |
| 427 | 462 | { |
| @@ -142,6 +142,7 @@ struct mqueue_inode_info { · 141 unmodified lines | ||
| 142 | 142 | |
| 143 | 143 | struct sigevent notify; |
| 144 | 144 | struct pid *notify_owner; |
| 145 | + u32 notify_self_exec_id; | |
| 145 | 146 | struct user_namespace *notify_user_ns; |
| 146 | 147 | struct user_struct *user; /* user who created, for accounting */ |
| 147 | 148 | struct sock *notify_sock; |
| @@ -773,28 +774,44 @@ static void __do_notify(struct mqueue_inode_info *info) · 625 unmodified lines | ||
| 773 | 774 | * synchronously. */ |
| 774 | 775 | if (info->notify_owner && |
| 775 | 776 | info->attr.mq_curmsgs == 1) { |
| 776 | − struct kernel_siginfo sig_i; | |
| 777 | 777 | switch (info->notify.sigev_notify) { |
| 778 | 778 | case SIGEV_NONE: |
| 779 | 779 | break; |
| 780 | − case SIGEV_SIGNAL: | |
| 781 | − /* sends signal */ | |
| 780 | + case SIGEV_SIGNAL: { | |
| 781 | + struct kernel_siginfo sig_i; | |
| 782 | + struct task_struct *task; | |
| 783 | + | |
| 784 | + /* do_mq_notify() accepts sigev_signo == 0, why?? */ | |
| 785 | + if (!info->notify.sigev_signo) | |
| 786 | + break; | |
| 782 | 787 | |
| 783 | 788 | clear_siginfo(&sig_i); |
| 784 | 789 | sig_i.si_signo = info->notify.sigev_signo; |
| 785 | 790 | sig_i.si_errno = 0; |
| 786 | 791 | sig_i.si_code = SI_MESGQ; |
| 787 | 792 | sig_i.si_value = info->notify.sigev_value; |
| 788 | − /* map current pid/uid into info->owner's namespaces */ | |
| 789 | 793 | rcu_read_lock(); |
| 794 | + /* map current pid/uid into info->owner's namespaces */ | |
| 790 | 795 | sig_i.si_pid = task_tgid_nr_ns(current, |
| 791 | 796 | ns_of_pid(info->notify_owner)); |
| 792 | − sig_i.si_uid = from_kuid_munged(info->notify_user_ns, current_uid()); | |
| 797 | + sig_i.si_uid = from_kuid_munged(info->notify_user_ns, | |
| 798 | + current_uid()); | |
| 799 | + /* | |
| 800 | + * We can't use kill_pid_info(), this signal should | |
| 801 | + * bypass check_kill_permission(). It is from kernel | |
| 802 | + * but si_fromuser() can't know this. | |
| 803 | + * We do check the self_exec_id, to avoid sending | |
| 804 | + * signals to programs that don't expect them. | |
| 805 | + */ | |
| 806 | + task = pid_task(info->notify_owner, PIDTYPE_TGID); | |
| 807 | + if (task && task->self_exec_id == | |
| 808 | + info->notify_self_exec_id) { | |
| 809 | + do_send_sig_info(info->notify.sigev_signo, | |
| 810 | + &sig_i, task, PIDTYPE_TGID); | |
| 811 | + } | |
| 793 | 812 | rcu_read_unlock(); |
| 794 | − | |
| 795 | − kill_pid_info(info->notify.sigev_signo, | |
| 796 | − &sig_i, info->notify_owner); | |
| 797 | 813 | break; |
| 814 | + } | |
| 798 | 815 | case SIGEV_THREAD: |
| 799 | 816 | set_cookie(info->notify_cookie, NOTIFY_WOKENUP); |
| 800 | 817 | netlink_sendskb(info->notify_sock, info->notify_cookie); |
| @@ -1383,6 +1400,7 @@ retry: · 582 unmodified lines | ||
| 1383 | 1400 | info->notify.sigev_signo = notification->sigev_signo; |
| 1384 | 1401 | info->notify.sigev_value = notification->sigev_value; |
| 1385 | 1402 | info->notify.sigev_notify = SIGEV_SIGNAL; |
| 1403 | + info->notify_self_exec_id = current->self_exec_id; | |
| 1386 | 1404 | break; |
| 1387 | 1405 | } |
| 1388 | 1406 | |
| @@ -740,8 +740,8 @@ static const struct file_operations kcov_fops = { · 739 unmodified lines | ||
| 740 | 740 | * kcov_remote_handle() with KCOV_SUBSYSTEM_COMMON as the subsystem id and an |
| 741 | 741 | * arbitrary 4-byte non-zero number as the instance id). This common handle |
| 742 | 742 | * then gets saved into the task_struct of the process that issued the |
| 743 | − * KCOV_REMOTE_ENABLE ioctl. When this proccess issues system calls that spawn | |
| 744 | − * kernel threads, the common handle must be retrived via kcov_common_handle() | |
| 743 | + * KCOV_REMOTE_ENABLE ioctl. When this process issues system calls that spawn | |
| 744 | + * kernel threads, the common handle must be retrieved via kcov_common_handle() | |
| 745 | 745 | * and passed to the spawned threads via custom annotations. Those kernel |
| 746 | 746 | * threads must in turn be annotated with kcov_remote_start(common_handle) and |
| 747 | 747 | * kcov_remote_stop(). All of the threads that are spawned by the same process |
| @@ -898,6 +898,13 @@ static int software_resume(void) · 897 unmodified lines | ||
| 898 | 898 | error = freeze_processes(); |
| 899 | 899 | if (error) |
| 900 | 900 | goto Close_Finish; |
| 901 | + | |
| 902 | + error = freeze_kernel_threads(); | |
| 903 | + if (error) { | |
| 904 | + thaw_processes(); | |
| 905 | + goto Close_Finish; | |
| 906 | + } | |
| 907 | + | |
| 901 | 908 | error = load_image_and_restore(); |
| 902 | 909 | thaw_processes(); |
| 903 | 910 | Finish: |
| @@ -466,7 +466,6 @@ config PROFILE_ANNOTATED_BRANCHES · 465 unmodified lines | ||
| 466 | 466 | config PROFILE_ALL_BRANCHES |
| 467 | 467 | bool "Profile all if conditionals" if !FORTIFY_SOURCE |
| 468 | 468 | select TRACE_BRANCH_PROFILING |
| 469 | − imply CC_DISABLE_WARN_MAYBE_UNINITIALIZED # avoid false positives | |
| 470 | 469 | help |
| 471 | 470 | This tracer profiles all branch conditions. Every if () |
| 472 | 471 | taken in the kernel is recorded whether it hit or miss. |
| @@ -113,22 +113,42 @@ static int preemptirq_delay_run(void *data) · 112 unmodified lines | ||
| 113 | 113 | |
| 114 | 114 | for (i = 0; i < s; i++) |
| 115 | 115 | (testfuncs[i])(i); |
| 116 | + | |
| 117 | + set_current_state(TASK_INTERRUPTIBLE); | |
| 118 | + while (!kthread_should_stop()) { | |
| 119 | + schedule(); | |
| 120 | + set_current_state(TASK_INTERRUPTIBLE); | |
| 121 | + } | |
| 122 | + | |
| 123 | + __set_current_state(TASK_RUNNING); | |
| 124 | + | |
| 116 | 125 | return 0; |
| 117 | 126 | } |
| 118 | 127 | |
| 119 | −static struct task_struct *preemptirq_start_test(void) | |
| 128 | +static int preemptirq_run_test(void) | |
| 120 | 129 | { |
| 130 | + struct task_struct *task; | |
| 131 | + | |
| 121 | 132 | char task_name[50]; |
| 122 | 133 | |
| 123 | 134 | snprintf(task_name, sizeof(task_name), "%s_test", test_mode); |
| 124 | − return kthread_run(preemptirq_delay_run, NULL, task_name); | |
| 135 | + task = kthread_run(preemptirq_delay_run, NULL, task_name); | |
| 136 | + if (IS_ERR(task)) | |
| 137 | + return PTR_ERR(task); | |
| 138 | + if (task) | |
| 139 | + kthread_stop(task); | |
| 140 | + return 0; | |
| 125 | 141 | } |
| 126 | 142 | |
| 127 | 143 | |
| 128 | 144 | static ssize_t trigger_store(struct kobject *kobj, struct kobj_attribute *attr, |
| 129 | 145 | const char *buf, size_t count) |
| 130 | 146 | { |
| 131 | − preemptirq_start_test(); | |
| 147 | + ssize_t ret; | |
| 148 | + | |
| 149 | + ret = preemptirq_run_test(); | |
| 150 | + if (ret) | |
| 151 | + return ret; | |
| 132 | 152 | return count; |
| 133 | 153 | } |
| 134 | 154 | |
| @@ -148,11 +168,9 @@ static struct kobject *preemptirq_delay_kobj; · 13 unmodified lines | ||
| 148 | 168 | |
| 149 | 169 | static int __init preemptirq_delay_init(void) |
| 150 | 170 | { |
| 151 | − struct task_struct *test_task; | |
| 152 | 171 | int retval; |
| 153 | 172 | |
| 154 | − test_task = preemptirq_start_test(); | |
| 155 | − retval = PTR_ERR_OR_ZERO(test_task); | |
| 173 | + retval = preemptirq_run_test(); | |
| 156 | 174 | if (retval != 0) |
| 157 | 175 | return retval; |
| 158 | 176 | |
| @@ -947,7 +947,8 @@ int __trace_bputs(unsigned long ip, const char *str) · 946 unmodified lines | ||
| 947 | 947 | EXPORT_SYMBOL_GPL(__trace_bputs); |
| 948 | 948 | |
| 949 | 949 | #ifdef CONFIG_TRACER_SNAPSHOT |
| 950 | −void tracing_snapshot_instance_cond(struct trace_array *tr, void *cond_data) | |
| 950 | +static void tracing_snapshot_instance_cond(struct trace_array *tr, | |
| 951 | + void *cond_data) | |
| 951 | 952 | { |
| 952 | 953 | struct tracer *tracer = tr->current_trace; |
| 953 | 954 | unsigned long flags; |
| @@ -8525,6 +8526,19 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) · 7571 unmodified lines | ||
| 8525 | 8526 | */ |
| 8526 | 8527 | allocate_snapshot = false; |
| 8527 | 8528 | #endif |
| 8529 | + | |
| 8530 | + /* | |
| 8531 | + * Because of some magic with the way alloc_percpu() works on | |
| 8532 | + * x86_64, we need to synchronize the pgd of all the tables, | |
| 8533 | + * otherwise the trace events that happen in x86_64 page fault | |
| 8534 | + * handlers can't cope with accessing the chance that a | |
| 8535 | + * alloc_percpu()'d memory might be touched in the page fault trace | |
| 8536 | + * event. Oh, and we need to audit all other alloc_percpu() and vmalloc() | |
| 8537 | + * calls in tracing, because something might get triggered within a | |
| 8538 | + * page fault trace event! | |
| 8539 | + */ | |
| 8540 | + vmalloc_sync_mappings(); | |
| 8541 | + | |
| 8528 | 8542 | return 0; |
| 8529 | 8543 | } |
| 8530 | 8544 | |
| @@ -95,24 +95,20 @@ trace_boot_add_kprobe_event(struct xbc_node *node, const char *event) · 94 unmodified lines | ||
| 95 | 95 | struct xbc_node *anode; |
| 96 | 96 | char buf[MAX_BUF_LEN]; |
| 97 | 97 | const char *val; |
| 98 | − int ret; | |
| 98 | + int ret = 0; | |
| 99 | 99 | |
| 100 | − kprobe_event_cmd_init(&cmd, buf, MAX_BUF_LEN); | |
| 100 | + xbc_node_for_each_array_value(node, "probes", anode, val) { | |
| 101 | + kprobe_event_cmd_init(&cmd, buf, MAX_BUF_LEN); | |
| 101 | 102 | |
| 102 | − ret = kprobe_event_gen_cmd_start(&cmd, event, NULL); | |
| 103 | − if (ret) | |
| 104 | − return ret; | |
| 103 | + ret = kprobe_event_gen_cmd_start(&cmd, event, val); | |
| 104 | + if (ret) | |
| 105 | + break; | |
| 105 | 106 | |
| 106 | − xbc_node_for_each_array_value(node, "probes", anode, val) { | |
| 107 | − ret = kprobe_event_add_field(&cmd, val); | |
| 107 | + ret = kprobe_event_gen_cmd_end(&cmd); | |
| 108 | 108 | if (ret) |
| 109 | − return ret; | |
| 109 | + pr_err("Failed to add probe: %s\n", buf); | |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | − ret = kprobe_event_gen_cmd_end(&cmd); | |
| 113 | − if (ret) | |
| 114 | − pr_err("Failed to add probe: %s\n", buf); | |
| 115 | − | |
| 116 | 112 | return ret; |
| 117 | 113 | } |
| 118 | 114 | #else |
| @@ -453,7 +453,7 @@ static bool __within_notrace_func(unsigned long addr) · 452 unmodified lines | ||
| 453 | 453 | |
| 454 | 454 | static bool within_notrace_func(struct trace_kprobe *tk) |
| 455 | 455 | { |
| 456 | − unsigned long addr = addr = trace_kprobe_address(tk); | |
| 456 | + unsigned long addr = trace_kprobe_address(tk); | |
| 457 | 457 | char symname[KSYM_NAME_LEN], *p; |
| 458 | 458 | |
| 459 | 459 | if (!__within_notrace_func(addr)) |
| @@ -940,6 +940,9 @@ EXPORT_SYMBOL_GPL(kprobe_event_cmd_init); · 480 unmodified lines | ||
| 940 | 940 | * complete command or only the first part of it; in the latter case, |
| 941 | 941 | * kprobe_event_add_fields() can be used to add more fields following this. |
| 942 | 942 | * |
| 943 | + * Unlikely the synth_event_gen_cmd_start(), @loc must be specified. This | |
| 944 | + * returns -EINVAL if @loc == NULL. | |
| 945 | + * | |
| 943 | 946 | * Return: 0 if successful, error otherwise. |
| 944 | 947 | */ |
| 945 | 948 | int __kprobe_event_gen_cmd_start(struct dynevent_cmd *cmd, bool kretprobe, |
| @@ -953,6 +956,9 @@ int __kprobe_event_gen_cmd_start(struct dynevent_cmd *cmd, bool kretprobe, · 7 unmodified lines | ||
| 953 | 956 | if (cmd->type != DYNEVENT_TYPE_KPROBE) |
| 954 | 957 | return -EINVAL; |
| 955 | 958 | |
| 959 | + if (!loc) | |
| 960 | + return -EINVAL; | |
| 961 | + | |
| 956 | 962 | if (kretprobe) |
| 957 | 963 | snprintf(buf, MAX_EVENT_NAME_LEN, "r:kprobes/%s", name); |
| 958 | 964 | else |
| @@ -544,6 +544,11 @@ EXPORT_SYMBOL_GPL(fork_usermode_blob); · 543 unmodified lines | ||
| 544 | 544 | * Runs a user-space application. The application is started |
| 545 | 545 | * asynchronously if wait is not set, and runs as a child of system workqueues. |
| 546 | 546 | * (ie. it runs with full root capabilities and optimized affinity). |
| 547 | + * | |
| 548 | + * Note: successful return value does not guarantee the helper was called at | |
| 549 | + * all. You can't rely on sub_info->{init,cleanup} being called even for | |
| 550 | + * UMH_WAIT_* wait modes as STATIC_USERMODEHELPER_PATH="" turns all helpers | |
| 551 | + * into a successful no-op. | |
| 547 | 552 | */ |
| 548 | 553 | int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) |
| 549 | 554 | { |
| @@ -60,18 +60,15 @@ config UBSAN_SANITIZE_ALL · 59 unmodified lines | ||
| 60 | 60 | Enabling this option will get kernel image size increased |
| 61 | 61 | significantly. |
| 62 | 62 | |
| 63 | −config UBSAN_NO_ALIGNMENT | |
| 64 | − bool "Disable checking of pointers alignment" | |
| 65 | − default y if HAVE_EFFICIENT_UNALIGNED_ACCESS | |
| 63 | +config UBSAN_ALIGNMENT | |
| 64 | + bool "Enable checks for pointers alignment" | |
| 65 | + default !HAVE_EFFICIENT_UNALIGNED_ACCESS | |
| 66 | + depends on !X86 || !COMPILE_TEST | |
| 66 | 67 | help |
| 67 | − This option disables the check of unaligned memory accesses. | |
| 68 | − This option should be used when building allmodconfig. | |
| 69 | − Disabling this option on architectures that support unaligned | |
| 68 | + This option enables the check of unaligned memory accesses. | |
| 69 | + Enabling this option on architectures that support unaligned | |
| 70 | 70 | accesses may produce a lot of false positives. |
| 71 | 71 | |
| 72 | −config UBSAN_ALIGNMENT | |
| 73 | − def_bool !UBSAN_NO_ALIGNMENT | |
| 74 | − | |
| 75 | 72 | config TEST_UBSAN |
| 76 | 73 | tristate "Module for testing for undefined behavior detection" |
| 77 | 74 | depends on m |
| @@ -93,7 +93,7 @@ static void kunit_print_ok_not_ok(void *test_or_suite, · 92 unmodified lines | ||
| 93 | 93 | * representation. |
| 94 | 94 | */ |
| 95 | 95 | if (suite) |
| 96 | − pr_info("%s %zd - %s", | |
| 96 | + pr_info("%s %zd - %s\n", | |
| 97 | 97 | kunit_status_to_string(is_ok), |
| 98 | 98 | test_number, description); |
| 99 | 99 | else |
| @@ -21,7 +21,7 @@ struct backing_dev_info noop_backing_dev_info = { · 20 unmodified lines | ||
| 21 | 21 | EXPORT_SYMBOL_GPL(noop_backing_dev_info); |
| 22 | 22 | |
| 23 | 23 | static struct class *bdi_class; |
| 24 | −const char *bdi_unknown_name = "(unknown)"; | |
| 24 | +static const char *bdi_unknown_name = "(unknown)"; | |
| 25 | 25 | |
| 26 | 26 | /* |
| 27 | 27 | * bdi_lock protects bdi_tree and updates to bdi_list. bdi_list has RCU |
| @@ -938,7 +938,8 @@ int bdi_register_va(struct backing_dev_info *bdi, const char *fmt, va_list args) · 910 unmodified lines | ||
| 938 | 938 | if (bdi->dev) /* The driver needs to use separate queues per device */ |
| 939 | 939 | return 0; |
| 940 | 940 | |
| 941 | − dev = device_create_vargs(bdi_class, NULL, MKDEV(0, 0), bdi, fmt, args); | |
| 941 | + vsnprintf(bdi->dev_name, sizeof(bdi->dev_name), fmt, args); | |
| 942 | + dev = device_create(bdi_class, NULL, MKDEV(0, 0), bdi, bdi->dev_name); | |
| 942 | 943 | if (IS_ERR(dev)) |
| 943 | 944 | return PTR_ERR(dev); |
| 944 | 945 | |
| @@ -1043,6 +1044,14 @@ void bdi_put(struct backing_dev_info *bdi) · 98 unmodified lines | ||
| 1043 | 1044 | } |
| 1044 | 1045 | EXPORT_SYMBOL(bdi_put); |
| 1045 | 1046 | |
| 1047 | +const char *bdi_dev_name(struct backing_dev_info *bdi) | |
| 1048 | +{ | |
| 1049 | + if (!bdi || !bdi->dev) | |
| 1050 | + return bdi_unknown_name; | |
| 1051 | + return bdi->dev_name; | |
| 1052 | +} | |
| 1053 | +EXPORT_SYMBOL_GPL(bdi_dev_name); | |
| 1054 | + | |
| 1046 | 1055 | static wait_queue_head_t congestion_wqh[2] = { |
| 1047 | 1056 | __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]), |
| 1048 | 1057 | __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1]) |
| @@ -4990,19 +4990,22 @@ static struct mem_cgroup *mem_cgroup_alloc(void) · 4989 unmodified lines | ||
| 4990 | 4990 | unsigned int size; |
| 4991 | 4991 | int node; |
| 4992 | 4992 | int __maybe_unused i; |
| 4993 | + long error = -ENOMEM; | |
| 4993 | 4994 | |
| 4994 | 4995 | size = sizeof(struct mem_cgroup); |
| 4995 | 4996 | size += nr_node_ids * sizeof(struct mem_cgroup_per_node *); |
| 4996 | 4997 | |
| 4997 | 4998 | memcg = kzalloc(size, GFP_KERNEL); |
| 4998 | 4999 | if (!memcg) |
| 4999 | − return NULL; | |
| 5000 | + return ERR_PTR(error); | |
| 5000 | 5001 | |
| 5001 | 5002 | memcg->id.id = idr_alloc(&mem_cgroup_idr, NULL, |
| 5002 | 5003 | 1, MEM_CGROUP_ID_MAX, |
| 5003 | 5004 | GFP_KERNEL); |
| 5004 | − if (memcg->id.id < 0) | |
| 5005 | + if (memcg->id.id < 0) { | |
| 5006 | + error = memcg->id.id; | |
| 5005 | 5007 | goto fail; |
| 5008 | + } | |
| 5006 | 5009 | |
| 5007 | 5010 | memcg->vmstats_local = alloc_percpu(struct memcg_vmstats_percpu); |
| 5008 | 5011 | if (!memcg->vmstats_local) |
| @@ -5046,7 +5049,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) · 37 unmodified lines | ||
| 5046 | 5049 | fail: |
| 5047 | 5050 | mem_cgroup_id_remove(memcg); |
| 5048 | 5051 | __mem_cgroup_free(memcg); |
| 5049 | − return NULL; | |
| 5052 | + return ERR_PTR(error); | |
| 5050 | 5053 | } |
| 5051 | 5054 | |
| 5052 | 5055 | static struct cgroup_subsys_state * __ref |
| @@ -5057,8 +5060,8 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) · 4 unmodified lines | ||
| 5057 | 5060 | long error = -ENOMEM; |
| 5058 | 5061 | |
| 5059 | 5062 | memcg = mem_cgroup_alloc(); |
| 5060 | − if (!memcg) | |
| 5061 | − return ERR_PTR(error); | |
| 5063 | + if (IS_ERR(memcg)) | |
| 5064 | + return ERR_CAST(memcg); | |
| 5062 | 5065 | |
| 5063 | 5066 | WRITE_ONCE(memcg->high, PAGE_COUNTER_MAX); |
| 5064 | 5067 | memcg->soft_limit = PAGE_COUNTER_MAX; |
| @@ -5108,7 +5111,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) · 43 unmodified lines | ||
| 5108 | 5111 | fail: |
| 5109 | 5112 | mem_cgroup_id_remove(memcg); |
| 5110 | 5113 | mem_cgroup_free(memcg); |
| 5111 | − return ERR_PTR(-ENOMEM); | |
| 5114 | + return ERR_PTR(error); | |
| 5112 | 5115 | } |
| 5113 | 5116 | |
| 5114 | 5117 | static int mem_cgroup_css_online(struct cgroup_subsys_state *css) |
| @@ -1607,6 +1607,7 @@ void set_zone_contiguous(struct zone *zone) · 1606 unmodified lines | ||
| 1607 | 1607 | if (!__pageblock_pfn_to_page(block_start_pfn, |
| 1608 | 1608 | block_end_pfn, zone)) |
| 1609 | 1609 | return; |
| 1610 | + cond_resched(); | |
| 1610 | 1611 | } |
| 1611 | 1612 | |
| 1612 | 1613 | /* We confirm that there is no hole */ |
| @@ -2400,6 +2401,14 @@ static inline void boost_watermark(struct zone *zone) · 787 unmodified lines | ||
| 2400 | 2401 | |
| 2401 | 2402 | if (!watermark_boost_factor) |
| 2402 | 2403 | return; |
| 2404 | + /* | |
| 2405 | + * Don't bother in zones that are unlikely to produce results. | |
| 2406 | + * On small machines, including kdump capture kernels running | |
| 2407 | + * in a small area, boosting the watermark can cause an out of | |
| 2408 | + * memory situation immediately. | |
| 2409 | + */ | |
| 2410 | + if ((pageblock_nr_pages * 4) > zone_managed_pages(zone)) | |
| 2411 | + return; | |
| 2403 | 2412 | |
| 2404 | 2413 | max_boost = mult_frac(zone->_watermark[WMARK_HIGH], |
| 2405 | 2414 | watermark_boost_factor, 10000); |
| @@ -80,6 +80,7 @@ · 79 unmodified lines | ||
| 80 | 80 | #include <linux/workqueue.h> |
| 81 | 81 | #include <linux/kmemleak.h> |
| 82 | 82 | #include <linux/sched.h> |
| 83 | +#include <linux/sched/mm.h> | |
| 83 | 84 | |
| 84 | 85 | #include <asm/cacheflush.h> |
| 85 | 86 | #include <asm/sections.h> |
| @@ -1557,10 +1558,9 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr) · 1471 unmodified lines | ||
| 1557 | 1558 | static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, |
| 1558 | 1559 | gfp_t gfp) |
| 1559 | 1560 | { |
| 1560 | − /* whitelisted flags that can be passed to the backing allocators */ | |
| 1561 | − gfp_t pcpu_gfp = gfp & (GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); | |
| 1562 | − bool is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL; | |
| 1563 | − bool do_warn = !(gfp & __GFP_NOWARN); | |
| 1561 | + gfp_t pcpu_gfp; | |
| 1562 | + bool is_atomic; | |
| 1563 | + bool do_warn; | |
| 1564 | 1564 | static int warn_limit = 10; |
| 1565 | 1565 | struct pcpu_chunk *chunk, *next; |
| 1566 | 1566 | const char *err; |
| @@ -1569,6 +1569,12 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, · 2 unmodified lines | ||
| 1569 | 1569 | void __percpu *ptr; |
| 1570 | 1570 | size_t bits, bit_align; |
| 1571 | 1571 | |
| 1572 | + gfp = current_gfp_context(gfp); | |
| 1573 | + /* whitelisted flags that can be passed to the backing allocators */ | |
| 1574 | + pcpu_gfp = gfp & (GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); | |
| 1575 | + is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL; | |
| 1576 | + do_warn = !(gfp & __GFP_NOWARN); | |
| 1577 | + | |
| 1572 | 1578 | /* |
| 1573 | 1579 | * There is now a minimum allocation size of PCPU_MIN_ALLOC_SIZE, |
| 1574 | 1580 | * therefore alignment must be a minimum of that many bytes. |
| @@ -551,15 +551,32 @@ static void print_section(char *level, char *text, u8 *addr, · 550 unmodified lines | ||
| 551 | 551 | metadata_access_disable(); |
| 552 | 552 | } |
| 553 | 553 | |
| 554 | +/* | |
| 555 | + * See comment in calculate_sizes(). | |
| 556 | + */ | |
| 557 | +static inline bool freeptr_outside_object(struct kmem_cache *s) | |
| 558 | +{ | |
| 559 | + return s->offset >= s->inuse; | |
| 560 | +} | |
| 561 | + | |
| 562 | +/* | |
| 563 | + * Return offset of the end of info block which is inuse + free pointer if | |
| 564 | + * not overlapping with object. | |
| 565 | + */ | |
| 566 | +static inline unsigned int get_info_end(struct kmem_cache *s) | |
| 567 | +{ | |
| 568 | + if (freeptr_outside_object(s)) | |
| 569 | + return s->inuse + sizeof(void *); | |
| 570 | + else | |
| 571 | + return s->inuse; | |
| 572 | +} | |
| 573 | + | |
| 554 | 574 | static struct track *get_track(struct kmem_cache *s, void *object, |
| 555 | 575 | enum track_item alloc) |
| 556 | 576 | { |
| 557 | 577 | struct track *p; |
| 558 | 578 | |
| 559 | − if (s->offset) | |
| 560 | − p = object + s->offset + sizeof(void *); | |
| 561 | − else | |
| 562 | − p = object + s->inuse; | |
| 579 | + p = object + get_info_end(s); | |
| 563 | 580 | |
| 564 | 581 | return p + alloc; |
| 565 | 582 | } |
| @@ -686,10 +703,7 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p) · 120 unmodified lines | ||
| 686 | 703 | print_section(KERN_ERR, "Redzone ", p + s->object_size, |
| 687 | 704 | s->inuse - s->object_size); |
| 688 | 705 | |
| 689 | − if (s->offset) | |
| 690 | − off = s->offset + sizeof(void *); | |
| 691 | − else | |
| 692 | − off = s->inuse; | |
| 706 | + off = get_info_end(s); | |
| 693 | 707 | |
| 694 | 708 | if (s->flags & SLAB_STORE_USER) |
| 695 | 709 | off += 2 * sizeof(struct track); |
| @@ -782,7 +796,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page, · 86 unmodified lines | ||
| 782 | 796 | * object address |
| 783 | 797 | * Bytes of the object to be managed. |
| 784 | 798 | * If the freepointer may overlay the object then the free |
| 785 | − * pointer is the first word of the object. | |
| 799 | + * pointer is at the middle of the object. | |
| 786 | 800 | * |
| 787 | 801 | * Poisoning uses 0x6b (POISON_FREE) and the last byte is |
| 788 | 802 | * 0xa5 (POISON_END) |
| @@ -816,11 +830,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page, · 27 unmodified lines | ||
| 816 | 830 | |
| 817 | 831 | static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p) |
| 818 | 832 | { |
| 819 | − unsigned long off = s->inuse; /* The end of info */ | |
| 820 | − | |
| 821 | − if (s->offset) | |
| 822 | − /* Freepointer is placed after the object. */ | |
| 823 | − off += sizeof(void *); | |
| 833 | + unsigned long off = get_info_end(s); /* The end of info */ | |
| 824 | 834 | |
| 825 | 835 | if (s->flags & SLAB_STORE_USER) |
| 826 | 836 | /* We also have user information there */ |
| @@ -907,7 +917,7 @@ static int check_object(struct kmem_cache *s, struct page *page, · 80 unmodified lines | ||
| 907 | 917 | check_pad_bytes(s, page, p); |
| 908 | 918 | } |
| 909 | 919 | |
| 910 | − if (!s->offset && val == SLUB_RED_ACTIVE) | |
| 920 | + if (!freeptr_outside_object(s) && val == SLUB_RED_ACTIVE) | |
| 911 | 921 | /* |
| 912 | 922 | * Object and freepointer overlap. Cannot check |
| 913 | 923 | * freepointer while object is allocated. |
| @@ -3587,6 +3597,11 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order) · 2673 unmodified lines | ||
| 3587 | 3597 | * |
| 3588 | 3598 | * This is the case if we do RCU, have a constructor or |
| 3589 | 3599 | * destructor or are poisoning the objects. |
| 3600 | + * | |
| 3601 | + * The assumption that s->offset >= s->inuse means free | |
| 3602 | + * pointer is outside of the object is used in the | |
| 3603 | + * freeptr_outside_object() function. If that is no | |
| 3604 | + * longer true, the function needs to be modified. | |
| 3590 | 3605 | */ |
| 3591 | 3606 | s->offset = size; |
| 3592 | 3607 | size += sizeof(void *); |
| @@ -1625,7 +1625,6 @@ static __always_inline void update_lru_sizes(struct lruvec *lruvec, · 1624 unmodified lines | ||
| 1625 | 1625 | * @dst: The temp list to put pages on to. |
| 1626 | 1626 | * @nr_scanned: The number of pages that were scanned. |
| 1627 | 1627 | * @sc: The scan_control struct for this reclaim session |
| 1628 | − * @mode: One of the LRU isolation modes | |
| 1629 | 1628 | * @lru: LRU list id for isolating |
| 1630 | 1629 | * |
| 1631 | 1630 | * returns how many pages were moved onto *@dst. |
| @@ -177,18 +177,18 @@ static void vcc_destroy_socket(struct sock *sk) · 176 unmodified lines | ||
| 177 | 177 | |
| 178 | 178 | set_bit(ATM_VF_CLOSE, &vcc->flags); |
| 179 | 179 | clear_bit(ATM_VF_READY, &vcc->flags); |
| 180 | − if (vcc->dev) { | |
| 181 | − if (vcc->dev->ops->close) | |
| 182 | − vcc->dev->ops->close(vcc); | |
| 183 | − if (vcc->push) | |
| 184 | − vcc->push(vcc, NULL); /* atmarpd has no push */ | |
| 185 | − module_put(vcc->owner); | |
| 186 | − | |
| 187 | − while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | |
| 188 | − atm_return(vcc, skb->truesize); | |
| 189 | − kfree_skb(skb); | |
| 190 | − } | |
| 180 | + if (vcc->dev && vcc->dev->ops->close) | |
| 181 | + vcc->dev->ops->close(vcc); | |
| 182 | + if (vcc->push) | |
| 183 | + vcc->push(vcc, NULL); /* atmarpd has no push */ | |
| 184 | + module_put(vcc->owner); | |
| 185 | + | |
| 186 | + while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | |
| 187 | + atm_return(vcc, skb->truesize); | |
| 188 | + kfree_skb(skb); | |
| 189 | + } | |
| 191 | 190 | |
| 191 | + if (vcc->dev && vcc->dev->ops->owner) { | |
| 192 | 192 | module_put(vcc->dev->ops->owner); |
| 193 | 193 | atm_dev_put(vcc->dev); |
| 194 | 194 | } |
| @@ -1264,6 +1264,12 @@ static void lec_arp_clear_vccs(struct lec_arp_table *entry) · 1263 unmodified lines | ||
| 1264 | 1264 | entry->vcc = NULL; |
| 1265 | 1265 | } |
| 1266 | 1266 | if (entry->recv_vcc) { |
| 1267 | + struct atm_vcc *vcc = entry->recv_vcc; | |
| 1268 | + struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); | |
| 1269 | + | |
| 1270 | + kfree(vpriv); | |
| 1271 | + vcc->user_back = NULL; | |
| 1272 | + | |
| 1267 | 1273 | entry->recv_vcc->push = entry->old_recv_push; |
| 1268 | 1274 | vcc_release_async(entry->recv_vcc, -EPIPE); |
| 1269 | 1275 | entry->recv_vcc = NULL; |
| @@ -893,7 +893,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, · 892 unmodified lines | ||
| 893 | 893 | |
| 894 | 894 | orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig); |
| 895 | 895 | if (!orig_node) |
| 896 | − return; | |
| 896 | + goto out; | |
| 897 | 897 | |
| 898 | 898 | neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming, |
| 899 | 899 | ethhdr->h_source); |
| @@ -1009,15 +1009,8 @@ static struct batadv_nc_path *batadv_nc_get_path(struct batadv_priv *bat_priv, · 1008 unmodified lines | ||
| 1009 | 1009 | */ |
| 1010 | 1010 | static u8 batadv_nc_random_weight_tq(u8 tq) |
| 1011 | 1011 | { |
| 1012 | − u8 rand_val, rand_tq; | |
| 1013 | − | |
| 1014 | − get_random_bytes(&rand_val, sizeof(rand_val)); | |
| 1015 | − | |
| 1016 | 1012 | /* randomize the estimated packet loss (max TQ - estimated TQ) */ |
| 1017 | − rand_tq = rand_val * (BATADV_TQ_MAX_VALUE - tq); | |
| 1018 | − | |
| 1019 | − /* normalize the randomized packet loss */ | |
| 1020 | − rand_tq /= BATADV_TQ_MAX_VALUE; | |
| 1013 | + u8 rand_tq = prandom_u32_max(BATADV_TQ_MAX_VALUE + 1 - tq); | |
| 1021 | 1014 | |
| 1022 | 1015 | /* convert to (randomized) estimated tq again */ |
| 1023 | 1016 | return BATADV_TQ_MAX_VALUE - rand_tq; |
| @@ -1150,7 +1150,7 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj, · 1149 unmodified lines | ||
| 1150 | 1150 | ret = batadv_parse_throughput(net_dev, buff, "throughput_override", |
| 1151 | 1151 | &tp_override); |
| 1152 | 1152 | if (!ret) |
| 1153 | − return count; | |
| 1153 | + goto out; | |
| 1154 | 1154 | |
| 1155 | 1155 | old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override); |
| 1156 | 1156 | if (old_tp_override == tp_override) |
| @@ -1190,6 +1190,7 @@ static ssize_t batadv_show_throughput_override(struct kobject *kobj, · 33 unmodified lines | ||
| 1190 | 1190 | |
| 1191 | 1191 | tp_override = atomic_read(&hard_iface->bat_v.throughput_override); |
| 1192 | 1192 | |
| 1193 | + batadv_hardif_put(hard_iface); | |
| 1193 | 1194 | return sprintf(buff, "%u.%u MBit\n", tp_override / 10, |
| 1194 | 1195 | tp_override % 10); |
| 1195 | 1196 | } |
| @@ -612,6 +612,7 @@ int br_process_vlan_info(struct net_bridge *br, · 611 unmodified lines | ||
| 612 | 612 | v - 1, rtm_cmd); |
| 613 | 613 | v_change_start = 0; |
| 614 | 614 | } |
| 615 | + cond_resched(); | |
| 615 | 616 | } |
| 616 | 617 | /* v_change_start is set only if the last/whole range changed */ |
| 617 | 618 | if (v_change_start) |
| @@ -4283,6 +4283,11 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, · 4282 unmodified lines | ||
| 4283 | 4283 | end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); |
| 4284 | 4284 | end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); |
| 4285 | 4285 | dump = false; |
| 4286 | + | |
| 4287 | + if (start_offset == end_offset) { | |
| 4288 | + err = 0; | |
| 4289 | + goto nla_put_failure; | |
| 4290 | + } | |
| 4286 | 4291 | } |
| 4287 | 4292 | |
| 4288 | 4293 | err = devlink_nl_region_read_snapshot_fill(skb, devlink, |
| @@ -5363,6 +5368,7 @@ int devlink_health_report(struct devlink_health_reporter *reporter, · 1074 unmodified lines | ||
| 5363 | 5368 | { |
| 5364 | 5369 | enum devlink_health_reporter_state prev_health_state; |
| 5365 | 5370 | struct devlink *devlink = reporter->devlink; |
| 5371 | + unsigned long recover_ts_threshold; | |
| 5366 | 5372 | |
| 5367 | 5373 | /* write a log message of the current error */ |
| 5368 | 5374 | WARN_ON(!msg); |
| @@ -5373,10 +5379,12 @@ int devlink_health_report(struct devlink_health_reporter *reporter, · 4 unmodified lines | ||
| 5373 | 5379 | devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); |
| 5374 | 5380 | |
| 5375 | 5381 | /* abort if the previous error wasn't recovered */ |
| 5382 | + recover_ts_threshold = reporter->last_recovery_ts + | |
| 5383 | + msecs_to_jiffies(reporter->graceful_period); | |
| 5376 | 5384 | if (reporter->auto_recover && |
| 5377 | 5385 | (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY || |
| 5378 | − jiffies - reporter->last_recovery_ts < | |
| 5379 | − msecs_to_jiffies(reporter->graceful_period))) { | |
| 5386 | + (reporter->last_recovery_ts && reporter->recovery_count && | |
| 5387 | + time_is_after_jiffies(recover_ts_threshold)))) { | |
| 5380 | 5388 | trace_devlink_health_recover_aborted(devlink, |
| 5381 | 5389 | reporter->ops->name, |
| 5382 | 5390 | reporter->health_state, |
| @@ -213,6 +213,7 @@ static void sched_send_work(struct timer_list *t) · 212 unmodified lines | ||
| 213 | 213 | static void trace_drop_common(struct sk_buff *skb, void *location) |
| 214 | 214 | { |
| 215 | 215 | struct net_dm_alert_msg *msg; |
| 216 | + struct net_dm_drop_point *point; | |
| 216 | 217 | struct nlmsghdr *nlh; |
| 217 | 218 | struct nlattr *nla; |
| 218 | 219 | int i; |
| @@ -231,11 +232,13 @@ static void trace_drop_common(struct sk_buff *skb, void *location) · 12 unmodified lines | ||
| 231 | 232 | nlh = (struct nlmsghdr *)dskb->data; |
| 232 | 233 | nla = genlmsg_data(nlmsg_data(nlh)); |
| 233 | 234 | msg = nla_data(nla); |
| 235 | + point = msg->points; | |
| 234 | 236 | for (i = 0; i < msg->entries; i++) { |
| 235 | − if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { | |
| 236 | − msg->points[i].count++; | |
| 237 | + if (!memcmp(&location, &point->pc, sizeof(void *))) { | |
| 238 | + point->count++; | |
| 237 | 239 | goto out; |
| 238 | 240 | } |
| 241 | + point++; | |
| 239 | 242 | } |
| 240 | 243 | if (msg->entries == dm_hit_limit) |
| 241 | 244 | goto out; |
| @@ -244,8 +247,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location) · 2 unmodified lines | ||
| 244 | 247 | */ |
| 245 | 248 | __nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point)); |
| 246 | 249 | nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point)); |
| 247 | − memcpy(msg->points[msg->entries].pc, &location, sizeof(void *)); | |
| 248 | − msg->points[msg->entries].count = 1; | |
| 250 | + memcpy(point->pc, &location, sizeof(void *)); | |
| 251 | + point->count = 1; | |
| 249 | 252 | msg->entries++; |
| 250 | 253 | |
| 251 | 254 | if (!timer_pending(&data->send_timer)) { |
| @@ -1956,6 +1956,9 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, · 1955 unmodified lines | ||
| 1956 | 1956 | NEIGH_UPDATE_F_OVERRIDE_ISROUTER); |
| 1957 | 1957 | } |
| 1958 | 1958 | |
| 1959 | + if (protocol) | |
| 1960 | + neigh->protocol = protocol; | |
| 1961 | + | |
| 1959 | 1962 | if (ndm->ndm_flags & NTF_EXT_LEARNED) |
| 1960 | 1963 | flags |= NEIGH_UPDATE_F_EXT_LEARNED; |
| 1961 | 1964 | |
| @@ -1969,9 +1972,6 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, · 7 unmodified lines | ||
| 1969 | 1972 | err = __neigh_update(neigh, lladdr, ndm->ndm_state, flags, |
| 1970 | 1973 | NETLINK_CB(skb).portid, extack); |
| 1971 | 1974 | |
| 1972 | − if (protocol) | |
| 1973 | − neigh->protocol = protocol; | |
| 1974 | − | |
| 1975 | 1975 | neigh_release(neigh); |
| 1976 | 1976 | |
| 1977 | 1977 | out: |
| @@ -2364,7 +2364,6 @@ static void sk_leave_memory_pressure(struct sock *sk) · 2363 unmodified lines | ||
| 2364 | 2364 | } |
| 2365 | 2365 | } |
| 2366 | 2366 | |
| 2367 | −/* On 32bit arches, an skb frag is limited to 2^15 */ | |
| 2368 | 2367 | #define SKB_FRAG_PAGE_ORDER get_order(32768) |
| 2369 | 2368 | DEFINE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key); |
| 2370 | 2369 | |
| @@ -459,7 +459,7 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) · 458 unmodified lines | ||
| 459 | 459 | list_for_each_entry(dp, &dst->ports, list) { |
| 460 | 460 | err = dsa_port_setup(dp); |
| 461 | 461 | if (err) |
| 462 | − goto teardown; | |
| 462 | + continue; | |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | 465 | return 0; |
| @@ -289,7 +289,8 @@ static void dsa_master_ndo_teardown(struct net_device *dev) · 288 unmodified lines | ||
| 289 | 289 | { |
| 290 | 290 | struct dsa_port *cpu_dp = dev->dsa_ptr; |
| 291 | 291 | |
| 292 | − dev->netdev_ops = cpu_dp->orig_ndo_ops; | |
| 292 | + if (cpu_dp->orig_ndo_ops) | |
| 293 | + dev->netdev_ops = cpu_dp->orig_ndo_ops; | |
| 293 | 294 | cpu_dp->orig_ndo_ops = NULL; |
| 294 | 295 | } |
| 295 | 296 | |
| @@ -856,20 +856,18 @@ dsa_slave_add_cls_matchall_mirred(struct net_device *dev, · 855 unmodified lines | ||
| 856 | 856 | struct dsa_port *to_dp; |
| 857 | 857 | int err; |
| 858 | 858 | |
| 859 | − act = &cls->rule->action.entries[0]; | |
| 860 | − | |
| 861 | 859 | if (!ds->ops->port_mirror_add) |
| 862 | 860 | return -EOPNOTSUPP; |
| 863 | 861 | |
| 864 | − if (!act->dev) | |
| 865 | − return -EINVAL; | |
| 866 | − | |
| 867 | 862 | if (!flow_action_basic_hw_stats_check(&cls->rule->action, |
| 868 | 863 | cls->common.extack)) |
| 869 | 864 | return -EOPNOTSUPP; |
| 870 | 865 | |
| 871 | 866 | act = &cls->rule->action.entries[0]; |
| 872 | 867 | |
| 868 | + if (!act->dev) | |
| 869 | + return -EINVAL; | |
| 870 | + | |
| 873 | 871 | if (!dsa_slave_dev_check(act->dev)) |
| 874 | 872 | return -EOPNOTSUPP; |
| 875 | 873 | |
| @@ -18,7 +18,7 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb) · 17 unmodified lines | ||
| 18 | 18 | { |
| 19 | 19 | struct sk_buff *skb = *pskb; |
| 20 | 20 | struct hsr_port *port; |
| 21 | − u16 protocol; | |
| 21 | + __be16 protocol; | |
| 22 | 22 | |
| 23 | 23 | if (!skb_mac_header_was_set(skb)) { |
| 24 | 24 | WARN_ONCE(1, "%s: skb invalid", __func__); |
| @@ -3926,10 +3926,6 @@ void tcp_parse_options(const struct net *net, · 3925 unmodified lines | ||
| 3926 | 3926 | */ |
| 3927 | 3927 | break; |
| 3928 | 3928 | #endif |
| 3929 | − case TCPOPT_MPTCP: | |
| 3930 | − mptcp_parse_option(skb, ptr, opsize, opt_rx); | |
| 3931 | − break; | |
| 3932 | − | |
| 3933 | 3929 | case TCPOPT_FASTOPEN: |
| 3934 | 3930 | tcp_parse_fastopen_option( |
| 3935 | 3931 | opsize - TCPOLEN_FASTOPEN_BASE, |
| @@ -5990,9 +5986,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, · 2054 unmodified lines | ||
| 5990 | 5986 | tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
| 5991 | 5987 | tcp_initialize_rcv_mss(sk); |
| 5992 | 5988 | |
| 5993 | − if (sk_is_mptcp(sk)) | |
| 5994 | − mptcp_rcv_synsent(sk); | |
| 5995 | − | |
| 5996 | 5989 | /* Remember, tcp_poll() does not lock socket! |
| 5997 | 5990 | * Change state from SYN-SENT only after copied_seq |
| 5998 | 5991 | * is initialized. */ |
| @@ -1385,9 +1385,18 @@ static struct rt6_info *ip6_rt_pcpu_alloc(const struct fib6_result *res) · 1384 unmodified lines | ||
| 1385 | 1385 | } |
| 1386 | 1386 | ip6_rt_copy_init(pcpu_rt, res); |
| 1387 | 1387 | pcpu_rt->rt6i_flags |= RTF_PCPU; |
| 1388 | + | |
| 1389 | + if (f6i->nh) | |
| 1390 | + pcpu_rt->sernum = rt_genid_ipv6(dev_net(dev)); | |
| 1391 | + | |
| 1388 | 1392 | return pcpu_rt; |
| 1389 | 1393 | } |
| 1390 | 1394 | |
| 1395 | +static bool rt6_is_valid(const struct rt6_info *rt6) | |
| 1396 | +{ | |
| 1397 | + return rt6->sernum == rt_genid_ipv6(dev_net(rt6->dst.dev)); | |
| 1398 | +} | |
| 1399 | + | |
| 1391 | 1400 | /* It should be called with rcu_read_lock() acquired */ |
| 1392 | 1401 | static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res) |
| 1393 | 1402 | { |
| @@ -1395,6 +1404,19 @@ static struct rt6_info *rt6_get_pcpu_route(const struct fib6_result *res) · 1 unmodified line | ||
| 1395 | 1404 | |
| 1396 | 1405 | pcpu_rt = this_cpu_read(*res->nh->rt6i_pcpu); |
| 1397 | 1406 | |
| 1407 | + if (pcpu_rt && pcpu_rt->sernum && !rt6_is_valid(pcpu_rt)) { | |
| 1408 | + struct rt6_info *prev, **p; | |
| 1409 | + | |
| 1410 | + p = this_cpu_ptr(res->nh->rt6i_pcpu); | |
| 1411 | + prev = xchg(p, NULL); | |
| 1412 | + if (prev) { | |
| 1413 | + dst_dev_put(&prev->dst); | |
| 1414 | + dst_release(&prev->dst); | |
| 1415 | + } | |
| 1416 | + | |
| 1417 | + pcpu_rt = NULL; | |
| 1418 | + } | |
| 1419 | + | |
| 1398 | 1420 | return pcpu_rt; |
| 1399 | 1421 | } |
| 1400 | 1422 | |
| @@ -2593,6 +2615,9 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) · 1192 unmodified lines | ||
| 2593 | 2615 | |
| 2594 | 2616 | rt = container_of(dst, struct rt6_info, dst); |
| 2595 | 2617 | |
| 2618 | + if (rt->sernum) | |
| 2619 | + return rt6_is_valid(rt) ? dst : NULL; | |
| 2620 | + | |
| 2596 | 2621 | rcu_read_lock(); |
| 2597 | 2622 | |
| 2598 | 2623 | /* All IPV6 dsts are created with ->obsolete set to the value |
| @@ -27,8 +27,9 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len) |
| 29 | 29 | { |
| 30 | − int trailing; | |
| 31 | 30 | unsigned int tlv_offset; |
| 31 | + int max_last_entry; | |
| 32 | + int trailing; | |
| 32 | 33 | |
| 33 | 34 | if (srh->type != IPV6_SRCRT_TYPE_4) |
| 34 | 35 | return false; |
| @@ -36,7 +37,12 @@ bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len) · 1 unmodified line | ||
| 36 | 37 | if (((srh->hdrlen + 1) << 3) != len) |
| 37 | 38 | return false; |
| 38 | 39 | |
| 39 | − if (srh->segments_left > srh->first_segment) | |
| 40 | + max_last_entry = (srh->hdrlen / 2) - 1; | |
| 41 | + | |
| 42 | + if (srh->first_segment > max_last_entry) | |
| 43 | + return false; | |
| 44 | + | |
| 45 | + if (srh->segments_left > srh->first_segment + 1) | |
| 40 | 46 | return false; |
| 41 | 47 | |
| 42 | 48 | tlv_offset = sizeof(*srh) + ((srh->first_segment + 1) << 4); |
| @@ -16,10 +16,10 @@ static bool mptcp_cap_flag_sha256(u8 flags) · 15 unmodified lines | ||
| 16 | 16 | return (flags & MPTCP_CAP_FLAG_MASK) == MPTCP_CAP_HMAC_SHA256; |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | −void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, | |
| 20 | − int opsize, struct tcp_options_received *opt_rx) | |
| 19 | +static void mptcp_parse_option(const struct sk_buff *skb, | |
| 20 | + const unsigned char *ptr, int opsize, | |
| 21 | + struct mptcp_options_received *mp_opt) | |
| 21 | 22 | { |
| 22 | − struct mptcp_options_received *mp_opt = &opt_rx->mptcp; | |
| 23 | 23 | u8 subtype = *ptr >> 4; |
| 24 | 24 | int expected_opsize; |
| 25 | 25 | u8 version; |
| @@ -283,12 +283,20 @@ void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, · 257 unmodified lines | ||
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | void mptcp_get_options(const struct sk_buff *skb, |
| 286 | − struct tcp_options_received *opt_rx) | |
| 286 | + struct mptcp_options_received *mp_opt) | |
| 287 | 287 | { |
| 288 | − const unsigned char *ptr; | |
| 289 | 288 | const struct tcphdr *th = tcp_hdr(skb); |
| 290 | − int length = (th->doff * 4) - sizeof(struct tcphdr); | |
| 289 | + const unsigned char *ptr; | |
| 290 | + int length; | |
| 291 | + | |
| 292 | + /* initialize option status */ | |
| 293 | + mp_opt->mp_capable = 0; | |
| 294 | + mp_opt->mp_join = 0; | |
| 295 | + mp_opt->add_addr = 0; | |
| 296 | + mp_opt->rm_addr = 0; | |
| 297 | + mp_opt->dss = 0; | |
| 291 | 298 | |
| 299 | + length = (th->doff * 4) - sizeof(struct tcphdr); | |
| 292 | 300 | ptr = (const unsigned char *)(th + 1); |
| 293 | 301 | |
| 294 | 302 | while (length > 0) { |
| @@ -308,7 +316,7 @@ void mptcp_get_options(const struct sk_buff *skb, · 13 unmodified lines | ||
| 308 | 316 | if (opsize > length) |
| 309 | 317 | return; /* don't parse partial options */ |
| 310 | 318 | if (opcode == TCPOPT_MPTCP) |
| 311 | − mptcp_parse_option(skb, ptr, opsize, opt_rx); | |
| 319 | + mptcp_parse_option(skb, ptr, opsize, mp_opt); | |
| 312 | 320 | ptr += opsize - 2; |
| 313 | 321 | length -= opsize; |
| 314 | 322 | } |
| @@ -344,28 +352,6 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, · 29 unmodified lines | ||
| 344 | 352 | return false; |
| 345 | 353 | } |
| 346 | 354 | |
| 347 | −void mptcp_rcv_synsent(struct sock *sk) | |
| 348 | −{ | |
| 349 | − struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); | |
| 350 | − struct tcp_sock *tp = tcp_sk(sk); | |
| 351 | − | |
| 352 | − if (subflow->request_mptcp && tp->rx_opt.mptcp.mp_capable) { | |
| 353 | − subflow->mp_capable = 1; | |
| 354 | − subflow->can_ack = 1; | |
| 355 | − subflow->remote_key = tp->rx_opt.mptcp.sndr_key; | |
| 356 | − pr_debug("subflow=%p, remote_key=%llu", subflow, | |
| 357 | − subflow->remote_key); | |
| 358 | − } else if (subflow->request_join && tp->rx_opt.mptcp.mp_join) { | |
| 359 | − subflow->mp_join = 1; | |
| 360 | − subflow->thmac = tp->rx_opt.mptcp.thmac; | |
| 361 | − subflow->remote_nonce = tp->rx_opt.mptcp.nonce; | |
| 362 | − pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow, | |
| 363 | − subflow->thmac, subflow->remote_nonce); | |
| 364 | − } else if (subflow->request_mptcp) { | |
| 365 | − tcp_sk(sk)->is_mptcp = 0; | |
| 366 | − } | |
| 367 | −} | |
| 368 | − | |
| 369 | 355 | /* MP_JOIN client subflow must wait for 4th ack before sending any data: |
| 370 | 356 | * TCP can't schedule delack timer before the subflow is fully established. |
| 371 | 357 | * MPTCP uses the delack timer to do 3rd ack retransmissions |
| @@ -709,7 +695,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *sk, · 337 unmodified lines | ||
| 709 | 695 | if (TCP_SKB_CB(skb)->seq != subflow->ssn_offset + 1) |
| 710 | 696 | return subflow->mp_capable; |
| 711 | 697 | |
| 712 | − if (mp_opt->use_ack) { | |
| 698 | + if (mp_opt->dss && mp_opt->use_ack) { | |
| 713 | 699 | /* subflows are fully established as soon as we get any |
| 714 | 700 | * additional ack. |
| 715 | 701 | */ |
| @@ -717,8 +703,6 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *sk, · 1 unmodified line | ||
| 717 | 703 | goto fully_established; |
| 718 | 704 | } |
| 719 | 705 | |
| 720 | − WARN_ON_ONCE(subflow->can_ack); | |
| 721 | − | |
| 722 | 706 | /* If the first established packet does not contain MP_CAPABLE + data |
| 723 | 707 | * then fallback to TCP |
| 724 | 708 | */ |
| @@ -728,6 +712,8 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *sk, · 3 unmodified lines | ||
| 728 | 712 | return false; |
| 729 | 713 | } |
| 730 | 714 | |
| 715 | + if (unlikely(!READ_ONCE(msk->pm.server_side))) | |
| 716 | + pr_warn_once("bogus mpc option on established client sk"); | |
| 731 | 717 | subflow->fully_established = 1; |
| 732 | 718 | subflow->remote_key = mp_opt->sndr_key; |
| 733 | 719 | subflow->can_ack = 1; |
| @@ -819,41 +805,41 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, · 85 unmodified lines | ||
| 819 | 805 | { |
| 820 | 806 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); |
| 821 | 807 | struct mptcp_sock *msk = mptcp_sk(subflow->conn); |
| 822 | − struct mptcp_options_received *mp_opt; | |
| 808 | + struct mptcp_options_received mp_opt; | |
| 823 | 809 | struct mptcp_ext *mpext; |
| 824 | 810 | |
| 825 | − mp_opt = &opt_rx->mptcp; | |
| 826 | − if (!check_fully_established(msk, sk, subflow, skb, mp_opt)) | |
| 811 | + mptcp_get_options(skb, &mp_opt); | |
| 812 | + if (!check_fully_established(msk, sk, subflow, skb, &mp_opt)) | |
| 827 | 813 | return; |
| 828 | 814 | |
| 829 | − if (mp_opt->add_addr && add_addr_hmac_valid(msk, mp_opt)) { | |
| 815 | + if (mp_opt.add_addr && add_addr_hmac_valid(msk, &mp_opt)) { | |
| 830 | 816 | struct mptcp_addr_info addr; |
| 831 | 817 | |
| 832 | − addr.port = htons(mp_opt->port); | |
| 833 | − addr.id = mp_opt->addr_id; | |
| 834 | − if (mp_opt->family == MPTCP_ADDR_IPVERSION_4) { | |
| 818 | + addr.port = htons(mp_opt.port); | |
| 819 | + addr.id = mp_opt.addr_id; | |
| 820 | + if (mp_opt.family == MPTCP_ADDR_IPVERSION_4) { | |
| 835 | 821 | addr.family = AF_INET; |
| 836 | − addr.addr = mp_opt->addr; | |
| 822 | + addr.addr = mp_opt.addr; | |
| 837 | 823 | } |
| 838 | 824 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
| 839 | − else if (mp_opt->family == MPTCP_ADDR_IPVERSION_6) { | |
| 825 | + else if (mp_opt.family == MPTCP_ADDR_IPVERSION_6) { | |
| 840 | 826 | addr.family = AF_INET6; |
| 841 | − addr.addr6 = mp_opt->addr6; | |
| 827 | + addr.addr6 = mp_opt.addr6; | |
| 842 | 828 | } |
| 843 | 829 | #endif |
| 844 | − if (!mp_opt->echo) | |
| 830 | + if (!mp_opt.echo) | |
| 845 | 831 | mptcp_pm_add_addr_received(msk, &addr); |
| 846 | − mp_opt->add_addr = 0; | |
| 832 | + mp_opt.add_addr = 0; | |
| 847 | 833 | } |
| 848 | 834 | |
| 849 | − if (!mp_opt->dss) | |
| 835 | + if (!mp_opt.dss) | |
| 850 | 836 | return; |
| 851 | 837 | |
| 852 | 838 | /* we can't wait for recvmsg() to update the ack_seq, otherwise |
| 853 | 839 | * monodirectional flows will stuck |
| 854 | 840 | */ |
| 855 | − if (mp_opt->use_ack) | |
| 856 | − update_una(msk, mp_opt); | |
| 841 | + if (mp_opt.use_ack) | |
| 842 | + update_una(msk, &mp_opt); | |
| 857 | 843 | |
| 858 | 844 | mpext = skb_ext_add(skb, SKB_EXT_MPTCP); |
| 859 | 845 | if (!mpext) |
| @@ -861,8 +847,8 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, · 1 unmodified line | ||
| 861 | 847 | |
| 862 | 848 | memset(mpext, 0, sizeof(*mpext)); |
| 863 | 849 | |
| 864 | − if (mp_opt->use_map) { | |
| 865 | − if (mp_opt->mpc_map) { | |
| 850 | + if (mp_opt.use_map) { | |
| 851 | + if (mp_opt.mpc_map) { | |
| 866 | 852 | /* this is an MP_CAPABLE carrying MPTCP data |
| 867 | 853 | * we know this map the first chunk of data |
| 868 | 854 | */ |
| @@ -872,13 +858,14 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, · 3 unmodified lines | ||
| 872 | 858 | mpext->subflow_seq = 1; |
| 873 | 859 | mpext->dsn64 = 1; |
| 874 | 860 | mpext->mpc_map = 1; |
| 861 | + mpext->data_fin = 0; | |
| 875 | 862 | } else { |
| 876 | − mpext->data_seq = mp_opt->data_seq; | |
| 877 | − mpext->subflow_seq = mp_opt->subflow_seq; | |
| 878 | − mpext->dsn64 = mp_opt->dsn64; | |
| 879 | − mpext->data_fin = mp_opt->data_fin; | |
| 863 | + mpext->data_seq = mp_opt.data_seq; | |
| 864 | + mpext->subflow_seq = mp_opt.subflow_seq; | |
| 865 | + mpext->dsn64 = mp_opt.dsn64; | |
| 866 | + mpext->data_fin = mp_opt.data_fin; | |
| 880 | 867 | } |
| 881 | − mpext->data_len = mp_opt->data_len; | |
| 868 | + mpext->data_len = mp_opt.data_len; | |
| 882 | 869 | mpext->use_map = 1; |
| 883 | 870 | } |
| 884 | 871 | } |
| @@ -1316,11 +1316,12 @@ static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk) · 1315 unmodified lines | ||
| 1316 | 1316 | |
| 1317 | 1317 | static int mptcp_disconnect(struct sock *sk, int flags) |
| 1318 | 1318 | { |
| 1319 | − lock_sock(sk); | |
| 1320 | − __mptcp_clear_xmit(sk); | |
| 1321 | − release_sock(sk); | |
| 1322 | − mptcp_cancel_work(sk); | |
| 1323 | − return tcp_disconnect(sk, flags); | |
| 1319 | + /* Should never be called. | |
| 1320 | + * inet_stream_connect() calls ->disconnect, but that | |
| 1321 | + * refers to the subflow socket, not the mptcp one. | |
| 1322 | + */ | |
| 1323 | + WARN_ON_ONCE(1); | |
| 1324 | + return 0; | |
| 1324 | 1325 | } |
| 1325 | 1326 | |
| 1326 | 1327 | #if IS_ENABLED(CONFIG_MPTCP_IPV6) |
| @@ -1333,7 +1334,7 @@ static struct ipv6_pinfo *mptcp_inet6_sk(const struct sock *sk) · 6 unmodified lines | ||
| 1333 | 1334 | #endif |
| 1334 | 1335 | |
| 1335 | 1336 | struct sock *mptcp_sk_clone(const struct sock *sk, |
| 1336 | − const struct tcp_options_received *opt_rx, | |
| 1337 | + const struct mptcp_options_received *mp_opt, | |
| 1337 | 1338 | struct request_sock *req) |
| 1338 | 1339 | { |
| 1339 | 1340 | struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); |
| @@ -1372,9 +1373,9 @@ struct sock *mptcp_sk_clone(const struct sock *sk, · 32 unmodified lines | ||
| 1372 | 1373 | |
| 1373 | 1374 | msk->write_seq = subflow_req->idsn + 1; |
| 1374 | 1375 | atomic64_set(&msk->snd_una, msk->write_seq); |
| 1375 | − if (opt_rx->mptcp.mp_capable) { | |
| 1376 | + if (mp_opt->mp_capable) { | |
| 1376 | 1377 | msk->can_ack = true; |
| 1377 | − msk->remote_key = opt_rx->mptcp.sndr_key; | |
| 1378 | + msk->remote_key = mp_opt->sndr_key; | |
| 1378 | 1379 | mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq); |
| 1379 | 1380 | ack_seq++; |
| 1380 | 1381 | msk->ack_seq = ack_seq; |
| @@ -91,6 +91,45 @@ · 90 unmodified lines | ||
| 91 | 91 | #define MPTCP_WORK_RTX 2 |
| 92 | 92 | #define MPTCP_WORK_EOF 3 |
| 93 | 93 | |
| 94 | +struct mptcp_options_received { | |
| 95 | + u64 sndr_key; | |
| 96 | + u64 rcvr_key; | |
| 97 | + u64 data_ack; | |
| 98 | + u64 data_seq; | |
| 99 | + u32 subflow_seq; | |
| 100 | + u16 data_len; | |
| 101 | + u16 mp_capable : 1, | |
| 102 | + mp_join : 1, | |
| 103 | + dss : 1, | |
| 104 | + add_addr : 1, | |
| 105 | + rm_addr : 1, | |
| 106 | + family : 4, | |
| 107 | + echo : 1, | |
| 108 | + backup : 1; | |
| 109 | + u32 token; | |
| 110 | + u32 nonce; | |
| 111 | + u64 thmac; | |
| 112 | + u8 hmac[20]; | |
| 113 | + u8 join_id; | |
| 114 | + u8 use_map:1, | |
| 115 | + dsn64:1, | |
| 116 | + data_fin:1, | |
| 117 | + use_ack:1, | |
| 118 | + ack64:1, | |
| 119 | + mpc_map:1, | |
| 120 | + __unused:2; | |
| 121 | + u8 addr_id; | |
| 122 | + u8 rm_id; | |
| 123 | + union { | |
| 124 | + struct in_addr addr; | |
| 125 | +#if IS_ENABLED(CONFIG_MPTCP_IPV6) | |
| 126 | + struct in6_addr addr6; | |
| 127 | +#endif | |
| 128 | + }; | |
| 129 | + u64 ahmac; | |
| 130 | + u16 port; | |
| 131 | +}; | |
| 132 | + | |
| 94 | 133 | static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field) |
| 95 | 134 | { |
| 96 | 135 | return htonl((TCPOPT_MPTCP << 24) | (len << 16) | (subopt << 12) | |
| @@ -331,10 +370,10 @@ int mptcp_proto_v6_init(void); · 234 unmodified lines | ||
| 331 | 370 | #endif |
| 332 | 371 | |
| 333 | 372 | struct sock *mptcp_sk_clone(const struct sock *sk, |
| 334 | − const struct tcp_options_received *opt_rx, | |
| 373 | + const struct mptcp_options_received *mp_opt, | |
| 335 | 374 | struct request_sock *req); |
| 336 | 375 | void mptcp_get_options(const struct sk_buff *skb, |
| 337 | − struct tcp_options_received *opt_rx); | |
| 376 | + struct mptcp_options_received *mp_opt); | |
| 338 | 377 | |
| 339 | 378 | void mptcp_finish_connect(struct sock *sk); |
| 340 | 379 | void mptcp_data_ready(struct sock *sk, struct sock *ssk); |
| @@ -124,12 +124,11 @@ static void subflow_init_req(struct request_sock *req, · 123 unmodified lines | ||
| 124 | 124 | { |
| 125 | 125 | struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener); |
| 126 | 126 | struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); |
| 127 | − struct tcp_options_received rx_opt; | |
| 127 | + struct mptcp_options_received mp_opt; | |
| 128 | 128 | |
| 129 | 129 | pr_debug("subflow_req=%p, listener=%p", subflow_req, listener); |
| 130 | 130 | |
| 131 | − memset(&rx_opt.mptcp, 0, sizeof(rx_opt.mptcp)); | |
| 132 | − mptcp_get_options(skb, &rx_opt); | |
| 131 | + mptcp_get_options(skb, &mp_opt); | |
| 133 | 132 | |
| 134 | 133 | subflow_req->mp_capable = 0; |
| 135 | 134 | subflow_req->mp_join = 0; |
| @@ -142,16 +141,16 @@ static void subflow_init_req(struct request_sock *req, · 6 unmodified lines | ||
| 142 | 141 | return; |
| 143 | 142 | #endif |
| 144 | 143 | |
| 145 | − if (rx_opt.mptcp.mp_capable) { | |
| 144 | + if (mp_opt.mp_capable) { | |
| 146 | 145 | SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE); |
| 147 | 146 | |
| 148 | − if (rx_opt.mptcp.mp_join) | |
| 147 | + if (mp_opt.mp_join) | |
| 149 | 148 | return; |
| 150 | − } else if (rx_opt.mptcp.mp_join) { | |
| 149 | + } else if (mp_opt.mp_join) { | |
| 151 | 150 | SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNRX); |
| 152 | 151 | } |
| 153 | 152 | |
| 154 | − if (rx_opt.mptcp.mp_capable && listener->request_mptcp) { | |
| 153 | + if (mp_opt.mp_capable && listener->request_mptcp) { | |
| 155 | 154 | int err; |
| 156 | 155 | |
| 157 | 156 | err = mptcp_token_new_request(req); |
| @@ -159,13 +158,13 @@ static void subflow_init_req(struct request_sock *req, · 1 unmodified line | ||
| 159 | 158 | subflow_req->mp_capable = 1; |
| 160 | 159 | |
| 161 | 160 | subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq; |
| 162 | − } else if (rx_opt.mptcp.mp_join && listener->request_mptcp) { | |
| 161 | + } else if (mp_opt.mp_join && listener->request_mptcp) { | |
| 163 | 162 | subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq; |
| 164 | 163 | subflow_req->mp_join = 1; |
| 165 | − subflow_req->backup = rx_opt.mptcp.backup; | |
| 166 | − subflow_req->remote_id = rx_opt.mptcp.join_id; | |
| 167 | − subflow_req->token = rx_opt.mptcp.token; | |
| 168 | − subflow_req->remote_nonce = rx_opt.mptcp.nonce; | |
| 164 | + subflow_req->backup = mp_opt.backup; | |
| 165 | + subflow_req->remote_id = mp_opt.join_id; | |
| 166 | + subflow_req->token = mp_opt.token; | |
| 167 | + subflow_req->remote_nonce = mp_opt.nonce; | |
| 169 | 168 | pr_debug("token=%u, remote_nonce=%u", subflow_req->token, |
| 170 | 169 | subflow_req->remote_nonce); |
| 171 | 170 | if (!subflow_token_join_request(req, skb)) { |
| @@ -221,23 +220,47 @@ static bool subflow_thmac_valid(struct mptcp_subflow_context *subflow) · 49 unmodified lines | ||
| 221 | 220 | static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) |
| 222 | 221 | { |
| 223 | 222 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); |
| 223 | + struct mptcp_options_received mp_opt; | |
| 224 | 224 | struct sock *parent = subflow->conn; |
| 225 | + struct tcp_sock *tp = tcp_sk(sk); | |
| 225 | 226 | |
| 226 | 227 | subflow->icsk_af_ops->sk_rx_dst_set(sk, skb); |
| 227 | 228 | |
| 228 | − if (inet_sk_state_load(parent) != TCP_ESTABLISHED) { | |
| 229 | + if (inet_sk_state_load(parent) == TCP_SYN_SENT) { | |
| 229 | 230 | inet_sk_state_store(parent, TCP_ESTABLISHED); |
| 230 | 231 | parent->sk_state_change(parent); |
| 231 | 232 | } |
| 232 | 233 | |
| 233 | − if (subflow->conn_finished || !tcp_sk(sk)->is_mptcp) | |
| 234 | + /* be sure no special action on any packet other than syn-ack */ | |
| 235 | + if (subflow->conn_finished) | |
| 236 | + return; | |
| 237 | + | |
| 238 | + subflow->conn_finished = 1; | |
| 239 | + | |
| 240 | + mptcp_get_options(skb, &mp_opt); | |
| 241 | + if (subflow->request_mptcp && mp_opt.mp_capable) { | |
| 242 | + subflow->mp_capable = 1; | |
| 243 | + subflow->can_ack = 1; | |
| 244 | + subflow->remote_key = mp_opt.sndr_key; | |
| 245 | + pr_debug("subflow=%p, remote_key=%llu", subflow, | |
| 246 | + subflow->remote_key); | |
| 247 | + } else if (subflow->request_join && mp_opt.mp_join) { | |
| 248 | + subflow->mp_join = 1; | |
| 249 | + subflow->thmac = mp_opt.thmac; | |
| 250 | + subflow->remote_nonce = mp_opt.nonce; | |
| 251 | + pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow, | |
| 252 | + subflow->thmac, subflow->remote_nonce); | |
| 253 | + } else if (subflow->request_mptcp) { | |
| 254 | + tp->is_mptcp = 0; | |
| 255 | + } | |
| 256 | + | |
| 257 | + if (!tp->is_mptcp) | |
| 234 | 258 | return; |
| 235 | 259 | |
| 236 | 260 | if (subflow->mp_capable) { |
| 237 | 261 | pr_debug("subflow=%p, remote_key=%llu", mptcp_subflow_ctx(sk), |
| 238 | 262 | subflow->remote_key); |
| 239 | 263 | mptcp_finish_connect(sk); |
| 240 | − subflow->conn_finished = 1; | |
| 241 | 264 | |
| 242 | 265 | if (skb) { |
| 243 | 266 | pr_debug("synack seq=%u", TCP_SKB_CB(skb)->seq); |
| @@ -264,7 +287,6 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) · 20 unmodified lines | ||
| 264 | 287 | if (!mptcp_finish_join(sk)) |
| 265 | 288 | goto do_reset; |
| 266 | 289 | |
| 267 | − subflow->conn_finished = 1; | |
| 268 | 290 | MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); |
| 269 | 291 | } else { |
| 270 | 292 | do_reset: |
| @@ -322,7 +344,7 @@ drop: · 51 unmodified lines | ||
| 322 | 344 | |
| 323 | 345 | /* validate hmac received in third ACK */ |
| 324 | 346 | static bool subflow_hmac_valid(const struct request_sock *req, |
| 325 | − const struct tcp_options_received *rx_opt) | |
| 347 | + const struct mptcp_options_received *mp_opt) | |
| 326 | 348 | { |
| 327 | 349 | const struct mptcp_subflow_request_sock *subflow_req; |
| 328 | 350 | u8 hmac[MPTCPOPT_HMAC_LEN]; |
| @@ -339,7 +361,7 @@ static bool subflow_hmac_valid(const struct request_sock *req, · 10 unmodified lines | ||
| 339 | 361 | subflow_req->local_nonce, hmac); |
| 340 | 362 | |
| 341 | 363 | ret = true; |
| 342 | − if (crypto_memneq(hmac, rx_opt->mptcp.hmac, sizeof(hmac))) | |
| 364 | + if (crypto_memneq(hmac, mp_opt->hmac, sizeof(hmac))) | |
| 343 | 365 | ret = false; |
| 344 | 366 | |
| 345 | 367 | sock_put((struct sock *)msk); |
| @@ -395,7 +417,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, · 49 unmodified lines | ||
| 395 | 417 | { |
| 396 | 418 | struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk); |
| 397 | 419 | struct mptcp_subflow_request_sock *subflow_req; |
| 398 | − struct tcp_options_received opt_rx; | |
| 420 | + struct mptcp_options_received mp_opt; | |
| 399 | 421 | bool fallback_is_fatal = false; |
| 400 | 422 | struct sock *new_msk = NULL; |
| 401 | 423 | bool fallback = false; |
| @@ -403,7 +425,10 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, · 1 unmodified line | ||
| 403 | 425 | |
| 404 | 426 | pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn); |
| 405 | 427 | |
| 406 | − opt_rx.mptcp.mp_capable = 0; | |
| 428 | + /* we need later a valid 'mp_capable' value even when options are not | |
| 429 | + * parsed | |
| 430 | + */ | |
| 431 | + mp_opt.mp_capable = 0; | |
| 407 | 432 | if (tcp_rsk(req)->is_mptcp == 0) |
| 408 | 433 | goto create_child; |
| 409 | 434 | |
| @@ -418,22 +443,21 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, · 8 unmodified lines | ||
| 418 | 443 | goto create_msk; |
| 419 | 444 | } |
| 420 | 445 | |
| 421 | − mptcp_get_options(skb, &opt_rx); | |
| 422 | − if (!opt_rx.mptcp.mp_capable) { | |
| 446 | + mptcp_get_options(skb, &mp_opt); | |
| 447 | + if (!mp_opt.mp_capable) { | |
| 423 | 448 | fallback = true; |
| 424 | 449 | goto create_child; |
| 425 | 450 | } |
| 426 | 451 | |
| 427 | 452 | create_msk: |
| 428 | − new_msk = mptcp_sk_clone(listener->conn, &opt_rx, req); | |
| 453 | + new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); | |
| 429 | 454 | if (!new_msk) |
| 430 | 455 | fallback = true; |
| 431 | 456 | } else if (subflow_req->mp_join) { |
| 432 | 457 | fallback_is_fatal = true; |
| 433 | − opt_rx.mptcp.mp_join = 0; | |
| 434 | − mptcp_get_options(skb, &opt_rx); | |
| 435 | − if (!opt_rx.mptcp.mp_join || | |
| 436 | − !subflow_hmac_valid(req, &opt_rx)) { | |
| 458 | + mptcp_get_options(skb, &mp_opt); | |
| 459 | + if (!mp_opt.mp_join || | |
| 460 | + !subflow_hmac_valid(req, &mp_opt)) { | |
| 437 | 461 | SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC); |
| 438 | 462 | return NULL; |
| 439 | 463 | } |
| @@ -473,9 +497,9 @@ create_child: · 33 unmodified lines | ||
| 473 | 497 | /* with OoO packets we can reach here without ingress |
| 474 | 498 | * mpc option |
| 475 | 499 | */ |
| 476 | − ctx->remote_key = opt_rx.mptcp.sndr_key; | |
| 477 | − ctx->fully_established = opt_rx.mptcp.mp_capable; | |
| 478 | − ctx->can_ack = opt_rx.mptcp.mp_capable; | |
| 500 | + ctx->remote_key = mp_opt.sndr_key; | |
| 501 | + ctx->fully_established = mp_opt.mp_capable; | |
| 502 | + ctx->can_ack = mp_opt.mp_capable; | |
| 479 | 503 | } else if (ctx->mp_join) { |
| 480 | 504 | struct mptcp_sock *owner; |
| 481 | 505 | |
| @@ -499,7 +523,7 @@ out: · 17 unmodified lines | ||
| 499 | 523 | /* check for expected invariant - should never trigger, just help |
| 500 | 524 | * catching eariler subtle bugs |
| 501 | 525 | */ |
| 502 | − WARN_ON_ONCE(*own_req && child && tcp_sk(child)->is_mptcp && | |
| 526 | + WARN_ON_ONCE(child && *own_req && tcp_sk(child)->is_mptcp && | |
| 503 | 527 | (!mptcp_subflow_ctx(child) || |
| 504 | 528 | !mptcp_subflow_ctx(child)->conn)); |
| 505 | 529 | return child; |
| @@ -68,15 +68,13 @@ static bool udp_manip_pkt(struct sk_buff *skb, · 67 unmodified lines | ||
| 68 | 68 | enum nf_nat_manip_type maniptype) |
| 69 | 69 | { |
| 70 | 70 | struct udphdr *hdr; |
| 71 | − bool do_csum; | |
| 72 | 71 | |
| 73 | 72 | if (skb_ensure_writable(skb, hdroff + sizeof(*hdr))) |
| 74 | 73 | return false; |
| 75 | 74 | |
| 76 | 75 | hdr = (struct udphdr *)(skb->data + hdroff); |
| 77 | − do_csum = hdr->check || skb->ip_summed == CHECKSUM_PARTIAL; | |
| 76 | + __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, !!hdr->check); | |
| 78 | 77 | |
| 79 | − __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, do_csum); | |
| 80 | 78 | return true; |
| 81 | 79 | } |
| 82 | 80 | |
| @@ -165,12 +165,12 @@ static bool nf_osf_match_one(const struct sk_buff *skb, · 164 unmodified lines | ||
| 165 | 165 | static const struct tcphdr *nf_osf_hdr_ctx_init(struct nf_osf_hdr_ctx *ctx, |
| 166 | 166 | const struct sk_buff *skb, |
| 167 | 167 | const struct iphdr *ip, |
| 168 | − unsigned char *opts) | |
| 168 | + unsigned char *opts, | |
| 169 | + struct tcphdr *_tcph) | |
| 169 | 170 | { |
| 170 | 171 | const struct tcphdr *tcp; |
| 171 | − struct tcphdr _tcph; | |
| 172 | 172 | |
| 173 | − tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph); | |
| 173 | + tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), _tcph); | |
| 174 | 174 | if (!tcp) |
| 175 | 175 | return NULL; |
| 176 | 176 | |
| @@ -205,10 +205,11 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, · 28 unmodified lines | ||
| 205 | 205 | int fmatch = FMATCH_WRONG; |
| 206 | 206 | struct nf_osf_hdr_ctx ctx; |
| 207 | 207 | const struct tcphdr *tcp; |
| 208 | + struct tcphdr _tcph; | |
| 208 | 209 | |
| 209 | 210 | memset(&ctx, 0, sizeof(ctx)); |
| 210 | 211 | |
| 211 | − tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts); | |
| 212 | + tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts, &_tcph); | |
| 212 | 213 | if (!tcp) |
| 213 | 214 | return false; |
| 214 | 215 | |
| @@ -265,10 +266,11 @@ bool nf_osf_find(const struct sk_buff *skb, · 50 unmodified lines | ||
| 265 | 266 | const struct nf_osf_finger *kf; |
| 266 | 267 | struct nf_osf_hdr_ctx ctx; |
| 267 | 268 | const struct tcphdr *tcp; |
| 269 | + struct tcphdr _tcph; | |
| 268 | 270 | |
| 269 | 271 | memset(&ctx, 0, sizeof(ctx)); |
| 270 | 272 | |
| 271 | − tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts); | |
| 273 | + tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts, &_tcph); | |
| 272 | 274 | if (!tcp) |
| 273 | 275 | return false; |
| 274 | 276 | |
| @@ -2070,6 +2070,7 @@ replay: · 2069 unmodified lines | ||
| 2070 | 2070 | err = PTR_ERR(block); |
| 2071 | 2071 | goto errout; |
| 2072 | 2072 | } |
| 2073 | + block->classid = parent; | |
| 2073 | 2074 | |
| 2074 | 2075 | chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0; |
| 2075 | 2076 | if (chain_index > TC_ACT_EXT_VAL_MASK) { |
| @@ -2612,12 +2613,10 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) · 536 unmodified lines | ||
| 2612 | 2613 | return skb->len; |
| 2613 | 2614 | |
| 2614 | 2615 | parent = tcm->tcm_parent; |
| 2615 | − if (!parent) { | |
| 2616 | + if (!parent) | |
| 2616 | 2617 | q = dev->qdisc; |
| 2617 | − parent = q->handle; | |
| 2618 | − } else { | |
| 2618 | + else | |
| 2619 | 2619 | q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); |
| 2620 | − } | |
| 2621 | 2620 | if (!q) |
| 2622 | 2621 | goto out; |
| 2623 | 2622 | cops = q->ops->cl_ops; |
| @@ -2633,6 +2632,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) · 9 unmodified lines | ||
| 2633 | 2632 | block = cops->tcf_block(q, cl, NULL); |
| 2634 | 2633 | if (!block) |
| 2635 | 2634 | goto out; |
| 2635 | + parent = block->classid; | |
| 2636 | 2636 | if (tcf_block_shared(block)) |
| 2637 | 2637 | q = NULL; |
| 2638 | 2638 | } |
| @@ -3523,6 +3523,16 @@ static void tcf_sample_get_group(struct flow_action_entry *entry, · 884 unmodified lines | ||
| 3523 | 3523 | #endif |
| 3524 | 3524 | } |
| 3525 | 3525 | |
| 3526 | +static enum flow_action_hw_stats tc_act_hw_stats(u8 hw_stats) | |
| 3527 | +{ | |
| 3528 | + if (WARN_ON_ONCE(hw_stats > TCA_ACT_HW_STATS_ANY)) | |
| 3529 | + return FLOW_ACTION_HW_STATS_DONT_CARE; | |
| 3530 | + else if (!hw_stats) | |
| 3531 | + return FLOW_ACTION_HW_STATS_DISABLED; | |
| 3532 | + | |
| 3533 | + return hw_stats; | |
| 3534 | +} | |
| 3535 | + | |
| 3526 | 3536 | int tc_setup_flow_action(struct flow_action *flow_action, |
| 3527 | 3537 | const struct tcf_exts *exts) |
| 3528 | 3538 | { |
| @@ -3546,7 +3556,7 @@ int tc_setup_flow_action(struct flow_action *flow_action, · 17 unmodified lines | ||
| 3546 | 3556 | if (err) |
| 3547 | 3557 | goto err_out_locked; |
| 3548 | 3558 | |
| 3549 | − entry->hw_stats = act->hw_stats; | |
| 3559 | + entry->hw_stats = tc_act_hw_stats(act->hw_stats); | |
| 3550 | 3560 | |
| 3551 | 3561 | if (is_tcf_gact_ok(act)) { |
| 3552 | 3562 | entry->id = FLOW_ACTION_ACCEPT; |
| @@ -3614,7 +3624,7 @@ int tc_setup_flow_action(struct flow_action *flow_action, · 61 unmodified lines | ||
| 3614 | 3624 | entry->mangle.mask = tcf_pedit_mask(act, k); |
| 3615 | 3625 | entry->mangle.val = tcf_pedit_val(act, k); |
| 3616 | 3626 | entry->mangle.offset = tcf_pedit_offset(act, k); |
| 3617 | − entry->hw_stats = act->hw_stats; | |
| 3627 | + entry->hw_stats = tc_act_hw_stats(act->hw_stats); | |
| 3618 | 3628 | entry = &flow_action->entries[++j]; |
| 3619 | 3629 | } |
| 3620 | 3630 | } else if (is_tcf_csum(act)) { |
| @@ -323,7 +323,8 @@ static void choke_reset(struct Qdisc *sch) · 322 unmodified lines | ||
| 323 | 323 | |
| 324 | 324 | sch->q.qlen = 0; |
| 325 | 325 | sch->qstats.backlog = 0; |
| 326 | − memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *)); | |
| 326 | + if (q->tab) | |
| 327 | + memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *)); | |
| 327 | 328 | q->head = q->tail = 0; |
| 328 | 329 | red_restart(&q->vars); |
| 329 | 330 | } |
| @@ -416,7 +416,7 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt, · 415 unmodified lines | ||
| 416 | 416 | q->quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM])); |
| 417 | 417 | |
| 418 | 418 | if (tb[TCA_FQ_CODEL_DROP_BATCH_SIZE]) |
| 419 | − q->drop_batch_size = min(1U, nla_get_u32(tb[TCA_FQ_CODEL_DROP_BATCH_SIZE])); | |
| 419 | + q->drop_batch_size = max(1U, nla_get_u32(tb[TCA_FQ_CODEL_DROP_BATCH_SIZE])); | |
| 420 | 420 | |
| 421 | 421 | if (tb[TCA_FQ_CODEL_MEMORY_LIMIT]) |
| 422 | 422 | q->memory_limit = min(1U << 31, nla_get_u32(tb[TCA_FQ_CODEL_MEMORY_LIMIT])); |
| @@ -637,6 +637,15 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) · 636 unmodified lines | ||
| 637 | 637 | if (ctl->divisor && |
| 638 | 638 | (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)) |
| 639 | 639 | return -EINVAL; |
| 640 | + | |
| 641 | + /* slot->allot is a short, make sure quantum is not too big. */ | |
| 642 | + if (ctl->quantum) { | |
| 643 | + unsigned int scaled = SFQ_ALLOT_SIZE(ctl->quantum); | |
| 644 | + | |
| 645 | + if (scaled <= 0 || scaled > SHRT_MAX) | |
| 646 | + return -EINVAL; | |
| 647 | + } | |
| 648 | + | |
| 640 | 649 | if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, |
| 641 | 650 | ctl_v1->Wlog)) |
| 642 | 651 | return -EINVAL; |
| @@ -169,6 +169,9 @@ static int skbprio_change(struct Qdisc *sch, struct nlattr *opt, · 168 unmodified lines | ||
| 169 | 169 | { |
| 170 | 170 | struct tc_skbprio_qopt *ctl = nla_data(opt); |
| 171 | 171 | |
| 172 | + if (opt->nla_len != nla_attr_size(sizeof(*ctl))) | |
| 173 | + return -EINVAL; | |
| 174 | + | |
| 172 | 175 | sch->limit = ctl->limit; |
| 173 | 176 | return 0; |
| 174 | 177 | } |
| @@ -880,6 +880,20 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); · 879 unmodified lines | ||
| 880 | 880 | /* |
| 881 | 881 | * Free an RPC client |
| 882 | 882 | */ |
| 883 | +static void rpc_free_client_work(struct work_struct *work) | |
| 884 | +{ | |
| 885 | + struct rpc_clnt *clnt = container_of(work, struct rpc_clnt, cl_work); | |
| 886 | + | |
| 887 | + /* These might block on processes that might allocate memory, | |
| 888 | + * so they cannot be called in rpciod, so they are handled separately | |
| 889 | + * here. | |
| 890 | + */ | |
| 891 | + rpc_clnt_debugfs_unregister(clnt); | |
| 892 | + rpc_clnt_remove_pipedir(clnt); | |
| 893 | + | |
| 894 | + kfree(clnt); | |
| 895 | + rpciod_down(); | |
| 896 | +} | |
| 883 | 897 | static struct rpc_clnt * |
| 884 | 898 | rpc_free_client(struct rpc_clnt *clnt) |
| 885 | 899 | { |
| @@ -890,17 +904,16 @@ rpc_free_client(struct rpc_clnt *clnt) · 4 unmodified lines | ||
| 890 | 904 | rcu_dereference(clnt->cl_xprt)->servername); |
| 891 | 905 | if (clnt->cl_parent != clnt) |
| 892 | 906 | parent = clnt->cl_parent; |
| 893 | − rpc_clnt_debugfs_unregister(clnt); | |
| 894 | − rpc_clnt_remove_pipedir(clnt); | |
| 895 | 907 | rpc_unregister_client(clnt); |
| 896 | 908 | rpc_free_iostats(clnt->cl_metrics); |
| 897 | 909 | clnt->cl_metrics = NULL; |
| 898 | 910 | xprt_put(rcu_dereference_raw(clnt->cl_xprt)); |
| 899 | 911 | xprt_iter_destroy(&clnt->cl_xpi); |
| 900 | − rpciod_down(); | |
| 901 | 912 | put_cred(clnt->cl_cred); |
| 902 | 913 | rpc_free_clid(clnt); |
| 903 | − kfree(clnt); | |
| 914 | + | |
| 915 | + INIT_WORK(&clnt->cl_work, rpc_free_client_work); | |
| 916 | + schedule_work(&clnt->cl_work); | |
| 904 | 917 | return parent; |
| 905 | 918 | } |
| 906 | 919 | |
| @@ -2808,8 +2821,7 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, · 1901 unmodified lines | ||
| 2808 | 2821 | task = rpc_call_null_helper(clnt, xprt, NULL, |
| 2809 | 2822 | RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS, |
| 2810 | 2823 | &rpc_cb_add_xprt_call_ops, data); |
| 2811 | − if (IS_ERR(task)) | |
| 2812 | − return PTR_ERR(task); | |
| 2824 | + | |
| 2813 | 2825 | rpc_put_task(task); |
| 2814 | 2826 | success: |
| 2815 | 2827 | return 1; |
| @@ -388,7 +388,9 @@ static int rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, · 387 unmodified lines | ||
| 388 | 388 | } while (nsegs); |
| 389 | 389 | |
| 390 | 390 | done: |
| 391 | − return xdr_stream_encode_item_absent(xdr); | |
| 391 | + if (xdr_stream_encode_item_absent(xdr) < 0) | |
| 392 | + return -EMSGSIZE; | |
| 393 | + return 0; | |
| 392 | 394 | } |
| 393 | 395 | |
| 394 | 396 | /* Register and XDR encode the Write list. Supports encoding a list |
| @@ -454,7 +456,9 @@ static int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, · 59 unmodified lines | ||
| 454 | 456 | *segcount = cpu_to_be32(nchunks); |
| 455 | 457 | |
| 456 | 458 | done: |
| 457 | − return xdr_stream_encode_item_absent(xdr); | |
| 459 | + if (xdr_stream_encode_item_absent(xdr) < 0) | |
| 460 | + return -EMSGSIZE; | |
| 461 | + return 0; | |
| 458 | 462 | } |
| 459 | 463 | |
| 460 | 464 | /* Register and XDR encode the Reply chunk. Supports encoding an array |
| @@ -480,8 +484,11 @@ static int rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, · 19 unmodified lines | ||
| 480 | 484 | int nsegs, nchunks; |
| 481 | 485 | __be32 *segcount; |
| 482 | 486 | |
| 483 | − if (wtype != rpcrdma_replych) | |
| 484 | − return xdr_stream_encode_item_absent(xdr); | |
| 487 | + if (wtype != rpcrdma_replych) { | |
| 488 | + if (xdr_stream_encode_item_absent(xdr) < 0) | |
| 489 | + return -EMSGSIZE; | |
| 490 | + return 0; | |
| 491 | + } | |
| 485 | 492 | |
| 486 | 493 | seg = req->rl_segments; |
| 487 | 494 | nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf, 0, wtype, seg); |
| @@ -289,6 +289,7 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) · 288 unmodified lines | ||
| 289 | 289 | case RDMA_CM_EVENT_DISCONNECTED: |
| 290 | 290 | ep->re_connect_status = -ECONNABORTED; |
| 291 | 291 | disconnected: |
| 292 | + xprt_force_disconnect(xprt); | |
| 292 | 293 | return rpcrdma_ep_destroy(ep); |
| 293 | 294 | default: |
| 294 | 295 | break; |
| @@ -1355,8 +1356,8 @@ int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 1060 unmodified lines | ||
| 1355 | 1356 | --ep->re_send_count; |
| 1356 | 1357 | } |
| 1357 | 1358 | |
| 1359 | + trace_xprtrdma_post_send(req); | |
| 1358 | 1360 | rc = frwr_send(r_xprt, req); |
| 1359 | − trace_xprtrdma_post_send(req, rc); | |
| 1360 | 1361 | if (rc) |
| 1361 | 1362 | return -ENOTCONN; |
| 1362 | 1363 | return 0; |
| @@ -402,10 +402,11 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con) · 401 unmodified lines | ||
| 402 | 402 | read_lock_bh(&sk->sk_callback_lock); |
| 403 | 403 | ret = tipc_conn_rcv_sub(srv, con, &s); |
| 404 | 404 | read_unlock_bh(&sk->sk_callback_lock); |
| 405 | + if (!ret) | |
| 406 | + return 0; | |
| 405 | 407 | } |
| 406 | − if (ret < 0) | |
| 407 | − tipc_conn_close(con); | |
| 408 | 408 | |
| 409 | + tipc_conn_close(con); | |
| 409 | 410 | return ret; |
| 410 | 411 | } |
| 411 | 412 | |
| @@ -800,6 +800,8 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, · 799 unmodified lines | ||
| 800 | 800 | *copied -= sk_msg_free(sk, msg); |
| 801 | 801 | tls_free_open_rec(sk); |
| 802 | 802 | } |
| 803 | + if (psock) | |
| 804 | + sk_psock_put(sk, psock); | |
| 803 | 805 | return err; |
| 804 | 806 | } |
| 805 | 807 | more_data: |
| @@ -2081,8 +2083,9 @@ static void tls_data_ready(struct sock *sk) · 1275 unmodified lines | ||
| 2081 | 2083 | strp_data_ready(&ctx->strp); |
| 2082 | 2084 | |
| 2083 | 2085 | psock = sk_psock_get(sk); |
| 2084 | − if (psock && !list_empty(&psock->ingress_msg)) { | |
| 2085 | − ctx->saved_data_ready(sk); | |
| 2086 | + if (psock) { | |
| 2087 | + if (!list_empty(&psock->ingress_msg)) | |
| 2088 | + ctx->saved_data_ready(sk); | |
| 2086 | 2089 | sk_psock_put(sk, psock); |
| 2087 | 2090 | } |
| 2088 | 2091 | } |
| @@ -157,7 +157,11 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque) · 156 unmodified lines | ||
| 157 | 157 | |
| 158 | 158 | void virtio_transport_deliver_tap_pkt(struct virtio_vsock_pkt *pkt) |
| 159 | 159 | { |
| 160 | + if (pkt->tap_delivered) | |
| 161 | + return; | |
| 162 | + | |
| 160 | 163 | vsock_deliver_tap(virtio_transport_build_skb, pkt); |
| 164 | + pkt->tap_delivered = true; | |
| 161 | 165 | } |
| 162 | 166 | EXPORT_SYMBOL_GPL(virtio_transport_deliver_tap_pkt); |
| 163 | 167 | |
| @@ -357,6 +357,12 @@ void x25_disconnect(struct sock *sk, int reason, unsigned char cause, · 356 unmodified lines | ||
| 357 | 357 | sk->sk_state_change(sk); |
| 358 | 358 | sock_set_flag(sk, SOCK_DEAD); |
| 359 | 359 | } |
| 360 | + if (x25->neighbour) { | |
| 361 | + read_lock_bh(&x25_list_lock); | |
| 362 | + x25_neigh_put(x25->neighbour); | |
| 363 | + x25->neighbour = NULL; | |
| 364 | + read_unlock_bh(&x25_list_lock); | |
| 365 | + } | |
| 360 | 366 | } |
| 361 | 367 | |
| 362 | 368 | /* |
| @@ -416,7 +416,7 @@ TRACE_EVENT_FN(foo_bar_with_fn, · 415 unmodified lines | ||
| 416 | 416 | * Note, TRACE_EVENT() itself is simply defined as: |
| 417 | 417 | * |
| 418 | 418 | * #define TRACE_EVENT(name, proto, args, tstruct, assign, printk) \ |
| 419 | − * DEFINE_EVENT_CLASS(name, proto, args, tstruct, assign, printk); \ | |
| 419 | + * DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, printk); \ | |
| 420 | 420 | * DEFINE_EVENT(name, name, proto, args) |
| 421 | 421 | * |
| 422 | 422 | * The DEFINE_EVENT() also can be declared with conditions and reg functions: |
| @@ -126,7 +126,7 @@ faultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) - \ · 125 unmodified lines | ||
| 126 | 126 | faultline=`cat $T.dis | head -1 | cut -d":" -f2-` |
| 127 | 127 | faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` |
| 128 | 128 | |
| 129 | −cat $T.oo | sed -e "${faultlinenum}s/^\(.*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" | |
| 129 | +cat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" | |
| 130 | 130 | echo |
| 131 | 131 | cat $T.aa |
| 132 | 132 | cleanup |
| @@ -4,6 +4,7 @@ GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) · 3 unmodified lines | ||
| 4 | 4 | HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti |
| 5 | 5 | HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb |
| 6 | 6 | HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat |
| 7 | +HOST_EXTRACXXFLAGS += -Wno-format-diag | |
| 7 | 8 | |
| 8 | 9 | $(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h |
| 9 | 10 | quiet_cmd_create_randomize_layout_seed = GENSEED $@ |
| @@ -35,7 +35,9 @@ · 34 unmodified lines | ||
| 35 | 35 | #include "ggc.h" |
| 36 | 36 | #include "timevar.h" |
| 37 | 37 | |
| 38 | +#if BUILDING_GCC_VERSION < 10000 | |
| 38 | 39 | #include "params.h" |
| 40 | +#endif | |
| 39 | 41 | |
| 40 | 42 | #if BUILDING_GCC_VERSION <= 4009 |
| 41 | 43 | #include "pointer-set.h" |
| @@ -847,6 +849,7 @@ static inline gimple gimple_build_assign_with_ops(enum tree_code subcode, tree l · 805 unmodified lines | ||
| 847 | 849 | return gimple_build_assign(lhs, subcode, op1, op2 PASS_MEM_STAT); |
| 848 | 850 | } |
| 849 | 851 | |
| 852 | +#if BUILDING_GCC_VERSION < 10000 | |
| 850 | 853 | template <> |
| 851 | 854 | template <> |
| 852 | 855 | inline bool is_a_helper<const ggoto *>::test(const_gimple gs) |
| @@ -860,6 +863,7 @@ inline bool is_a_helper<const greturn *>::test(const_gimple gs) · 7 unmodified lines | ||
| 860 | 863 | { |
| 861 | 864 | return gs->code == GIMPLE_RETURN; |
| 862 | 865 | } |
| 866 | +#endif | |
| 863 | 867 | |
| 864 | 868 | static inline gasm *as_a_gasm(gimple stmt) |
| 865 | 869 | { |
| @@ -51,7 +51,6 @@ static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after) · 50 unmodified lines | ||
| 51 | 51 | gimple stmt; |
| 52 | 52 | gcall *stackleak_track_stack; |
| 53 | 53 | cgraph_node_ptr node; |
| 54 | − int frequency; | |
| 55 | 54 | basic_block bb; |
| 56 | 55 | |
| 57 | 56 | /* Insert call to void stackleak_track_stack(void) */ |
| @@ -68,9 +67,9 @@ static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after) · 10 unmodified lines | ||
| 68 | 67 | bb = gimple_bb(stackleak_track_stack); |
| 69 | 68 | node = cgraph_get_create_node(track_function_decl); |
| 70 | 69 | gcc_assert(node); |
| 71 | − frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); | |
| 72 | 70 | cgraph_create_edge(cgraph_get_node(current_function_decl), node, |
| 73 | − stackleak_track_stack, bb->count, frequency); | |
| 71 | + stackleak_track_stack, bb->count, | |
| 72 | + compute_call_stmt_bb_frequency(current_function_decl, bb)); | |
| 74 | 73 | } |
| 75 | 74 | |
| 76 | 75 | static bool is_alloca(gimple stmt) |
| @@ -12,7 +12,7 @@ rb_node_type = utils.CachedType("struct rb_node") · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | def rb_first(root): |
| 14 | 14 | if root.type == rb_root_type.get_type(): |
| 15 | − node = node.address.cast(rb_root_type.get_type().pointer()) | |
| 15 | + node = root.address.cast(rb_root_type.get_type().pointer()) | |
| 16 | 16 | elif root.type != rb_root_type.get_type().pointer(): |
| 17 | 17 | raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) |
| 18 | 18 | |
| @@ -28,7 +28,7 @@ def rb_first(root): · 9 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | def rb_last(root): |
| 30 | 30 | if root.type == rb_root_type.get_type(): |
| 31 | − node = node.address.cast(rb_root_type.get_type().pointer()) | |
| 31 | + node = root.address.cast(rb_root_type.get_type().pointer()) | |
| 32 | 32 | elif root.type != rb_root_type.get_type().pointer(): |
| 33 | 33 | raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) |
| 34 | 34 | |
| @@ -34,7 +34,7 @@ struct sym_entry { · 33 unmodified lines | ||
| 34 | 34 | unsigned int len; |
| 35 | 35 | unsigned int start_pos; |
| 36 | 36 | unsigned int percpu_absolute; |
| 37 | − unsigned char sym[0]; | |
| 37 | + unsigned char sym[]; | |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | struct addr_range { |
| @@ -5842,40 +5842,60 @@ static unsigned int selinux_ipv6_postroute(void *priv, · 5841 unmodified lines | ||
| 5842 | 5842 | |
| 5843 | 5843 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 5844 | 5844 | { |
| 5845 | − int err = 0; | |
| 5846 | − u32 perm; | |
| 5845 | + int rc = 0; | |
| 5846 | + unsigned int msg_len; | |
| 5847 | + unsigned int data_len = skb->len; | |
| 5848 | + unsigned char *data = skb->data; | |
| 5847 | 5849 | struct nlmsghdr *nlh; |
| 5848 | 5850 | struct sk_security_struct *sksec = sk->sk_security; |
| 5851 | + u16 sclass = sksec->sclass; | |
| 5852 | + u32 perm; | |
| 5849 | 5853 | |
| 5850 | − if (skb->len < NLMSG_HDRLEN) { | |
| 5851 | − err = -EINVAL; | |
| 5852 | − goto out; | |
| 5853 | − } | |
| 5854 | − nlh = nlmsg_hdr(skb); | |
| 5854 | + while (data_len >= nlmsg_total_size(0)) { | |
| 5855 | + nlh = (struct nlmsghdr *)data; | |
| 5856 | + | |
| 5857 | + /* NOTE: the nlmsg_len field isn't reliably set by some netlink | |
| 5858 | + * users which means we can't reject skb's with bogus | |
| 5859 | + * length fields; our solution is to follow what | |
| 5860 | + * netlink_rcv_skb() does and simply skip processing at | |
| 5861 | + * messages with length fields that are clearly junk | |
| 5862 | + */ | |
| 5863 | + if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len) | |
| 5864 | + return 0; | |
| 5855 | 5865 | |
| 5856 | − err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); | |
| 5857 | − if (err) { | |
| 5858 | − if (err == -EINVAL) { | |
| 5866 | + rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm); | |
| 5867 | + if (rc == 0) { | |
| 5868 | + rc = sock_has_perm(sk, perm); | |
| 5869 | + if (rc) | |
| 5870 | + return rc; | |
| 5871 | + } else if (rc == -EINVAL) { | |
| 5872 | + /* -EINVAL is a missing msg/perm mapping */ | |
| 5859 | 5873 | pr_warn_ratelimited("SELinux: unrecognized netlink" |
| 5860 | − " message: protocol=%hu nlmsg_type=%hu sclass=%s" | |
| 5861 | − " pid=%d comm=%s\n", | |
| 5862 | − sk->sk_protocol, nlh->nlmsg_type, | |
| 5863 | − secclass_map[sksec->sclass - 1].name, | |
| 5864 | − task_pid_nr(current), current->comm); | |
| 5865 | − if (!enforcing_enabled(&selinux_state) || | |
| 5866 | − security_get_allow_unknown(&selinux_state)) | |
| 5867 | − err = 0; | |
| 5874 | + " message: protocol=%hu nlmsg_type=%hu sclass=%s" | |
| 5875 | + " pid=%d comm=%s\n", | |
| 5876 | + sk->sk_protocol, nlh->nlmsg_type, | |
| 5877 | + secclass_map[sclass - 1].name, | |
| 5878 | + task_pid_nr(current), current->comm); | |
| 5879 | + if (enforcing_enabled(&selinux_state) && | |
| 5880 | + !security_get_allow_unknown(&selinux_state)) | |
| 5881 | + return rc; | |
| 5882 | + rc = 0; | |
| 5883 | + } else if (rc == -ENOENT) { | |
| 5884 | + /* -ENOENT is a missing socket/class mapping, ignore */ | |
| 5885 | + rc = 0; | |
| 5886 | + } else { | |
| 5887 | + return rc; | |
| 5868 | 5888 | } |
| 5869 | 5889 | |
| 5870 | − /* Ignore */ | |
| 5871 | − if (err == -ENOENT) | |
| 5872 | − err = 0; | |
| 5873 | − goto out; | |
| 5890 | + /* move to the next message after applying netlink padding */ | |
| 5891 | + msg_len = NLMSG_ALIGN(nlh->nlmsg_len); | |
| 5892 | + if (msg_len >= data_len) | |
| 5893 | + return 0; | |
| 5894 | + data_len -= msg_len; | |
| 5895 | + data += msg_len; | |
| 5874 | 5896 | } |
| 5875 | 5897 | |
| 5876 | − err = sock_has_perm(sk, perm); | |
| 5877 | −out: | |
| 5878 | − return err; | |
| 5898 | + return rc; | |
| 5879 | 5899 | } |
| 5880 | 5900 | |
| 5881 | 5901 | static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) |
| @@ -429,7 +429,7 @@ int cond_read_list(struct policydb *p, void *fp) · 428 unmodified lines | ||
| 429 | 429 | |
| 430 | 430 | p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL); |
| 431 | 431 | if (!p->cond_list) |
| 432 | − return rc; | |
| 432 | + return -ENOMEM; | |
| 433 | 433 | |
| 434 | 434 | rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel); |
| 435 | 435 | if (rc) |
| @@ -205,13 +205,14 @@ static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug, · 204 unmodified lines | ||
| 205 | 205 | plugin = snd_pcm_plug_first(plug); |
| 206 | 206 | while (plugin && frames > 0) { |
| 207 | 207 | plugin_next = plugin->next; |
| 208 | + if (check_size && plugin->buf_frames && | |
| 209 | + frames > plugin->buf_frames) | |
| 210 | + frames = plugin->buf_frames; | |
| 208 | 211 | if (plugin->dst_frames) { |
| 209 | 212 | frames = plugin->dst_frames(plugin, frames); |
| 210 | 213 | if (frames < 0) |
| 211 | 214 | return frames; |
| 212 | 215 | } |
| 213 | − if (check_size && frames > plugin->buf_frames) | |
| 214 | − frames = plugin->buf_frames; | |
| 215 | 216 | plugin = plugin_next; |
| 216 | 217 | } |
| 217 | 218 | return frames; |
| @@ -225,14 +226,15 @@ static snd_pcm_sframes_t calc_src_frames(struct snd_pcm_substream *plug, · 7 unmodified lines | ||
| 225 | 226 | |
| 226 | 227 | plugin = snd_pcm_plug_last(plug); |
| 227 | 228 | while (plugin && frames > 0) { |
| 228 | − if (check_size && frames > plugin->buf_frames) | |
| 229 | − frames = plugin->buf_frames; | |
| 230 | 229 | plugin_prev = plugin->prev; |
| 231 | 230 | if (plugin->src_frames) { |
| 232 | 231 | frames = plugin->src_frames(plugin, frames); |
| 233 | 232 | if (frames < 0) |
| 234 | 233 | return frames; |
| 235 | 234 | } |
| 235 | + if (check_size && plugin->buf_frames && | |
| 236 | + frames > plugin->buf_frames) | |
| 237 | + frames = plugin->buf_frames; | |
| 236 | 238 | plugin = plugin_prev; |
| 237 | 239 | } |
| 238 | 240 | return frames; |
| @@ -867,10 +867,13 @@ static void snd_miro_write(struct snd_miro *chip, unsigned char reg, · 866 unmodified lines | ||
| 867 | 867 | spin_unlock_irqrestore(&chip->lock, flags); |
| 868 | 868 | } |
| 869 | 869 | |
| 870 | +static inline void snd_miro_write_mask(struct snd_miro *chip, | |
| 871 | + unsigned char reg, unsigned char value, unsigned char mask) | |
| 872 | +{ | |
| 873 | + unsigned char oldval = snd_miro_read(chip, reg); | |
| 870 | 874 | |
| 871 | −#define snd_miro_write_mask(chip, reg, value, mask) \ | |
| 872 | − snd_miro_write(chip, reg, \ | |
| 873 | − (snd_miro_read(chip, reg) & ~(mask)) | ((value) & (mask))) | |
| 875 | + snd_miro_write(chip, reg, (oldval & ~mask) | (value & mask)); | |
| 876 | +} | |
| 874 | 877 | |
| 875 | 878 | /* |
| 876 | 879 | * Proc Interface |
| @@ -317,10 +317,13 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, · 316 unmodified lines | ||
| 317 | 317 | } |
| 318 | 318 | |
| 319 | 319 | |
| 320 | −#define snd_opti9xx_write_mask(chip, reg, value, mask) \ | |
| 321 | − snd_opti9xx_write(chip, reg, \ | |
| 322 | − (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) | |
| 320 | +static inline void snd_opti9xx_write_mask(struct snd_opti9xx *chip, | |
| 321 | + unsigned char reg, unsigned char value, unsigned char mask) | |
| 322 | +{ | |
| 323 | + unsigned char oldval = snd_opti9xx_read(chip, reg); | |
| 323 | 324 | |
| 325 | + snd_opti9xx_write(chip, reg, (oldval & ~mask) | (value & mask)); | |
| 326 | +} | |
| 324 | 327 | |
| 325 | 328 | static int snd_opti9xx_configure(struct snd_opti9xx *chip, |
| 326 | 329 | long port, |
| @@ -2078,9 +2078,10 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream, · 2077 unmodified lines | ||
| 2078 | 2078 | * some HD-audio PCI entries are exposed without any codecs, and such devices |
| 2079 | 2079 | * should be ignored from the beginning. |
| 2080 | 2080 | */ |
| 2081 | −static const struct snd_pci_quirk driver_blacklist[] = { | |
| 2082 | − SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0), | |
| 2083 | − SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0), | |
| 2081 | +static const struct pci_device_id driver_blacklist[] = { | |
| 2082 | + { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1043, 0x874f) }, /* ASUS ROG Zenith II / Strix */ | |
| 2083 | + { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb59) }, /* MSI TRX40 Creator */ | |
| 2084 | + { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb60) }, /* MSI TRX40 */ | |
| 2084 | 2085 | {} |
| 2085 | 2086 | }; |
| 2086 | 2087 | |
| @@ -2100,7 +2101,7 @@ static int azx_probe(struct pci_dev *pci, · 13 unmodified lines | ||
| 2100 | 2101 | bool schedule_probe; |
| 2101 | 2102 | int err; |
| 2102 | 2103 | |
| 2103 | − if (snd_pci_quirk_lookup(pci, driver_blacklist)) { | |
| 2104 | + if (pci_match_id(driver_blacklist, pci)) { | |
| 2104 | 2105 | dev_info(&pci->dev, "Skipping the blacklisted device\n"); |
| 2105 | 2106 | return -ENODEV; |
| 2106 | 2107 | } |
| @@ -1848,8 +1848,10 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) · 1847 unmodified lines | ||
| 1848 | 1848 | /* Add sanity check to pass klockwork check. |
| 1849 | 1849 | * This should never happen. |
| 1850 | 1850 | */ |
| 1851 | − if (WARN_ON(spdif == NULL)) | |
| 1851 | + if (WARN_ON(spdif == NULL)) { | |
| 1852 | + mutex_unlock(&codec->spdif_mutex); | |
| 1852 | 1853 | return true; |
| 1854 | + } | |
| 1853 | 1855 | non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO); |
| 1854 | 1856 | mutex_unlock(&codec->spdif_mutex); |
| 1855 | 1857 | return non_pcm; |
| @@ -2198,7 +2200,9 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) · 342 unmodified lines | ||
| 2198 | 2200 | |
| 2199 | 2201 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
| 2200 | 2202 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
| 2203 | + struct hdmi_eld *pin_eld = &per_pin->sink_eld; | |
| 2201 | 2204 | |
| 2205 | + pin_eld->eld_valid = false; | |
| 2202 | 2206 | hdmi_present_sense(per_pin, 0); |
| 2203 | 2207 | } |
| 2204 | 2208 | |
| @@ -7420,6 +7420,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 7419 unmodified lines | ||
| 7420 | 7420 | SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7421 | 7421 | SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7422 | 7422 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), |
| 7423 | + SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), | |
| 7423 | 7424 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
| 7424 | 7425 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
| 7425 | 7426 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
| @@ -21,8 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | enum { |
| 22 | 22 | LINE6_PODHD300, |
| 23 | 23 | LINE6_PODHD400, |
| 24 | − LINE6_PODHD500_0, | |
| 25 | − LINE6_PODHD500_1, | |
| 24 | + LINE6_PODHD500, | |
| 26 | 25 | LINE6_PODX3, |
| 27 | 26 | LINE6_PODX3LIVE, |
| 28 | 27 | LINE6_PODHD500X, |
| @@ -318,8 +317,7 @@ static const struct usb_device_id podhd_id_table[] = { · 289 unmodified lines | ||
| 318 | 317 | /* TODO: no need to alloc data interfaces when only audio is used */ |
| 319 | 318 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, |
| 320 | 319 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, |
| 321 | − { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, | |
| 322 | − { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | |
| 320 | + { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500 }, | |
| 323 | 321 | { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, |
| 324 | 322 | { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, |
| 325 | 323 | { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X }, |
| @@ -352,23 +350,13 @@ static const struct line6_properties podhd_properties_table[] = { · 26 unmodified lines | ||
| 352 | 350 | .ep_audio_r = 0x82, |
| 353 | 351 | .ep_audio_w = 0x01, |
| 354 | 352 | }, |
| 355 | − [LINE6_PODHD500_0] = { | |
| 353 | + [LINE6_PODHD500] = { | |
| 356 | 354 | .id = "PODHD500", |
| 357 | 355 | .name = "POD HD500", |
| 358 | − .capabilities = LINE6_CAP_PCM | |
| 356 | + .capabilities = LINE6_CAP_PCM | LINE6_CAP_CONTROL | |
| 359 | 357 | | LINE6_CAP_HWMON, |
| 360 | 358 | .altsetting = 1, |
| 361 | − .ep_ctrl_r = 0x81, | |
| 362 | − .ep_ctrl_w = 0x01, | |
| 363 | − .ep_audio_r = 0x86, | |
| 364 | − .ep_audio_w = 0x02, | |
| 365 | − }, | |
| 366 | − [LINE6_PODHD500_1] = { | |
| 367 | − .id = "PODHD500", | |
| 368 | − .name = "POD HD500", | |
| 369 | − .capabilities = LINE6_CAP_PCM | |
| 370 | − | LINE6_CAP_HWMON, | |
| 371 | − .altsetting = 0, | |
| 359 | + .ctrl_if = 1, | |
| 372 | 360 | .ep_ctrl_r = 0x81, |
| 373 | 361 | .ep_ctrl_w = 0x01, |
| 374 | 362 | .ep_audio_r = 0x86, |
| @@ -1687,7 +1687,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, · 1686 unmodified lines | ||
| 1687 | 1687 | |
| 1688 | 1688 | case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ |
| 1689 | 1689 | case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */ |
| 1690 | − case USB_ID(0x16b0, 0x06b2): /* NuPrime DAC-10 */ | |
| 1690 | + case USB_ID(0x16d0, 0x06b2): /* NuPrime DAC-10 */ | |
| 1691 | 1691 | case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ |
| 1692 | 1692 | case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ |
| 1693 | 1693 | case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ |
| @@ -314,6 +314,7 @@ int apply_xbc(const char *path, const char *xbc_path) · 313 unmodified lines | ||
| 314 | 314 | ret = delete_xbc(path); |
| 315 | 315 | if (ret < 0) { |
| 316 | 316 | pr_err("Failed to delete previous boot config: %d\n", ret); |
| 317 | + free(data); | |
| 317 | 318 | return ret; |
| 318 | 319 | } |
| 319 | 320 | |
| @@ -321,24 +322,26 @@ int apply_xbc(const char *path, const char *xbc_path) · 1 unmodified line | ||
| 321 | 322 | fd = open(path, O_RDWR | O_APPEND); |
| 322 | 323 | if (fd < 0) { |
| 323 | 324 | pr_err("Failed to open %s: %d\n", path, fd); |
| 325 | + free(data); | |
| 324 | 326 | return fd; |
| 325 | 327 | } |
| 326 | 328 | /* TODO: Ensure the @path is initramfs/initrd image */ |
| 327 | 329 | ret = write(fd, data, size + 8); |
| 328 | 330 | if (ret < 0) { |
| 329 | 331 | pr_err("Failed to apply a boot config: %d\n", ret); |
| 330 | − return ret; | |
| 332 | + goto out; | |
| 331 | 333 | } |
| 332 | 334 | /* Write a magic word of the bootconfig */ |
| 333 | 335 | ret = write(fd, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN); |
| 334 | 336 | if (ret < 0) { |
| 335 | 337 | pr_err("Failed to apply a boot config magic: %d\n", ret); |
| 336 | − return ret; | |
| 338 | + goto out; | |
| 337 | 339 | } |
| 340 | +out: | |
| 338 | 341 | close(fd); |
| 339 | 342 | free(data); |
| 340 | 343 | |
| 341 | − return 0; | |
| 344 | + return ret; | |
| 342 | 345 | } |
| 343 | 346 | |
| 344 | 347 | int usage(void) |
| @@ -159,7 +159,12 @@ class IocgStat: · 158 unmodified lines | ||
| 159 | 159 | else: |
| 160 | 160 | self.inflight_pct = 0 |
| 161 | 161 | |
| 162 | − self.debt_ms = iocg.abs_vdebt.counter.value_() / VTIME_PER_USEC / 1000 | |
| 162 | + # vdebt used to be an atomic64_t and is now u64, support both | |
| 163 | + try: | |
| 164 | + self.debt_ms = iocg.abs_vdebt.counter.value_() / VTIME_PER_USEC / 1000 | |
| 165 | + except: | |
| 166 | + self.debt_ms = iocg.abs_vdebt.value_() / VTIME_PER_USEC / 1000 | |
| 167 | + | |
| 163 | 168 | self.use_delay = blkg.use_delay.counter.value_() |
| 164 | 169 | self.delay_ms = blkg.delay_nsec.counter.value_() / 1_000_000 |
| 165 | 170 | |
| @@ -72,6 +72,17 @@ static struct instruction *next_insn_same_func(struct objtool_file *file, · 71 unmodified lines | ||
| 72 | 72 | return find_insn(file, func->cfunc->sec, func->cfunc->offset); |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | +static struct instruction *prev_insn_same_sym(struct objtool_file *file, | |
| 76 | + struct instruction *insn) | |
| 77 | +{ | |
| 78 | + struct instruction *prev = list_prev_entry(insn, list); | |
| 79 | + | |
| 80 | + if (&prev->list != &file->insn_list && prev->func == insn->func) | |
| 81 | + return prev; | |
| 82 | + | |
| 83 | + return NULL; | |
| 84 | +} | |
| 85 | + | |
| 75 | 86 | #define func_for_each_insn(file, func, insn) \ |
| 76 | 87 | for (insn = find_insn(file, func->sec, func->offset); \ |
| 77 | 88 | insn; \ |
| @@ -1050,8 +1061,8 @@ static struct rela *find_jump_table(struct objtool_file *file, · 972 unmodified lines | ||
| 1050 | 1061 | * it. |
| 1051 | 1062 | */ |
| 1052 | 1063 | for (; |
| 1053 | − &insn->list != &file->insn_list && insn->func && insn->func->pfunc == func; | |
| 1054 | − insn = insn->first_jump_src ?: list_prev_entry(insn, list)) { | |
| 1064 | + insn && insn->func && insn->func->pfunc == func; | |
| 1065 | + insn = insn->first_jump_src ?: prev_insn_same_sym(file, insn)) { | |
| 1055 | 1066 | |
| 1056 | 1067 | if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC) |
| 1057 | 1068 | break; |
| @@ -1449,7 +1460,7 @@ static int update_insn_state_regs(struct instruction *insn, struct insn_state *s · 391 unmodified lines | ||
| 1449 | 1460 | struct cfi_reg *cfa = &state->cfa; |
| 1450 | 1461 | struct stack_op *op = &insn->stack_op; |
| 1451 | 1462 | |
| 1452 | − if (cfa->base != CFI_SP) | |
| 1463 | + if (cfa->base != CFI_SP && cfa->base != CFI_SP_INDIRECT) | |
| 1453 | 1464 | return 0; |
| 1454 | 1465 | |
| 1455 | 1466 | /* push */ |
| @@ -87,9 +87,10 @@ struct elf { · 86 unmodified lines | ||
| 87 | 87 | #define OFFSET_STRIDE (1UL << OFFSET_STRIDE_BITS) |
| 88 | 88 | #define OFFSET_STRIDE_MASK (~(OFFSET_STRIDE - 1)) |
| 89 | 89 | |
| 90 | −#define for_offset_range(_offset, _start, _end) \ | |
| 91 | − for (_offset = ((_start) & OFFSET_STRIDE_MASK); \ | |
| 92 | − _offset <= ((_end) & OFFSET_STRIDE_MASK); \ | |
| 90 | +#define for_offset_range(_offset, _start, _end) \ | |
| 91 | + for (_offset = ((_start) & OFFSET_STRIDE_MASK); \ | |
| 92 | + _offset >= ((_start) & OFFSET_STRIDE_MASK) && \ | |
| 93 | + _offset <= ((_end) & OFFSET_STRIDE_MASK); \ | |
| 93 | 94 | _offset += OFFSET_STRIDE) |
| 94 | 95 | |
| 95 | 96 | static inline u32 sec_offset_hash(struct section *sec, unsigned long offset) |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #define _GNU_SOURCE |
| 4 | 4 | #include <poll.h> |
| 5 | 5 | #include <unistd.h> |
| 6 | +#include <assert.h> | |
| 6 | 7 | #include <signal.h> |
| 7 | 8 | #include <pthread.h> |
| 8 | 9 | #include <sys/epoll.h> |
| @@ -3136,4 +3137,149 @@ TEST(epoll59) · 3127 unmodified lines | ||
| 3136 | 3137 | close(ctx.sfd[0]); |
| 3137 | 3138 | } |
| 3138 | 3139 | |
| 3140 | +enum { | |
| 3141 | + EPOLL60_EVENTS_NR = 10, | |
| 3142 | +}; | |
| 3143 | + | |
| 3144 | +struct epoll60_ctx { | |
| 3145 | + volatile int stopped; | |
| 3146 | + int ready; | |
| 3147 | + int waiters; | |
| 3148 | + int epfd; | |
| 3149 | + int evfd[EPOLL60_EVENTS_NR]; | |
| 3150 | +}; | |
| 3151 | + | |
| 3152 | +static void *epoll60_wait_thread(void *ctx_) | |
| 3153 | +{ | |
| 3154 | + struct epoll60_ctx *ctx = ctx_; | |
| 3155 | + struct epoll_event e; | |
| 3156 | + sigset_t sigmask; | |
| 3157 | + uint64_t v; | |
| 3158 | + int ret; | |
| 3159 | + | |
| 3160 | + /* Block SIGUSR1 */ | |
| 3161 | + sigemptyset(&sigmask); | |
| 3162 | + sigaddset(&sigmask, SIGUSR1); | |
| 3163 | + sigprocmask(SIG_SETMASK, &sigmask, NULL); | |
| 3164 | + | |
| 3165 | + /* Prepare empty mask for epoll_pwait() */ | |
| 3166 | + sigemptyset(&sigmask); | |
| 3167 | + | |
| 3168 | + while (!ctx->stopped) { | |
| 3169 | + /* Mark we are ready */ | |
| 3170 | + __atomic_fetch_add(&ctx->ready, 1, __ATOMIC_ACQUIRE); | |
| 3171 | + | |
| 3172 | + /* Start when all are ready */ | |
| 3173 | + while (__atomic_load_n(&ctx->ready, __ATOMIC_ACQUIRE) && | |
| 3174 | + !ctx->stopped); | |
| 3175 | + | |
| 3176 | + /* Account this waiter */ | |
| 3177 | + __atomic_fetch_add(&ctx->waiters, 1, __ATOMIC_ACQUIRE); | |
| 3178 | + | |
| 3179 | + ret = epoll_pwait(ctx->epfd, &e, 1, 2000, &sigmask); | |
| 3180 | + if (ret != 1) { | |
| 3181 | + /* We expect only signal delivery on stop */ | |
| 3182 | + assert(ret < 0 && errno == EINTR && "Lost wakeup!\n"); | |
| 3183 | + assert(ctx->stopped); | |
| 3184 | + break; | |
| 3185 | + } | |
| 3186 | + | |
| 3187 | + ret = read(e.data.fd, &v, sizeof(v)); | |
| 3188 | + /* Since we are on ET mode, thus each thread gets its own fd. */ | |
| 3189 | + assert(ret == sizeof(v)); | |
| 3190 | + | |
| 3191 | + __atomic_fetch_sub(&ctx->waiters, 1, __ATOMIC_RELEASE); | |
| 3192 | + } | |
| 3193 | + | |
| 3194 | + return NULL; | |
| 3195 | +} | |
| 3196 | + | |
| 3197 | +static inline unsigned long long msecs(void) | |
| 3198 | +{ | |
| 3199 | + struct timespec ts; | |
| 3200 | + unsigned long long msecs; | |
| 3201 | + | |
| 3202 | + clock_gettime(CLOCK_REALTIME, &ts); | |
| 3203 | + msecs = ts.tv_sec * 1000ull; | |
| 3204 | + msecs += ts.tv_nsec / 1000000ull; | |
| 3205 | + | |
| 3206 | + return msecs; | |
| 3207 | +} | |
| 3208 | + | |
| 3209 | +static inline int count_waiters(struct epoll60_ctx *ctx) | |
| 3210 | +{ | |
| 3211 | + return __atomic_load_n(&ctx->waiters, __ATOMIC_ACQUIRE); | |
| 3212 | +} | |
| 3213 | + | |
| 3214 | +TEST(epoll60) | |
| 3215 | +{ | |
| 3216 | + struct epoll60_ctx ctx = { 0 }; | |
| 3217 | + pthread_t waiters[ARRAY_SIZE(ctx.evfd)]; | |
| 3218 | + struct epoll_event e; | |
| 3219 | + int i, n, ret; | |
| 3220 | + | |
| 3221 | + signal(SIGUSR1, signal_handler); | |
| 3222 | + | |
| 3223 | + ctx.epfd = epoll_create1(0); | |
| 3224 | + ASSERT_GE(ctx.epfd, 0); | |
| 3225 | + | |
| 3226 | + /* Create event fds */ | |
| 3227 | + for (i = 0; i < ARRAY_SIZE(ctx.evfd); i++) { | |
| 3228 | + ctx.evfd[i] = eventfd(0, EFD_NONBLOCK); | |
| 3229 | + ASSERT_GE(ctx.evfd[i], 0); | |
| 3230 | + | |
| 3231 | + e.events = EPOLLIN | EPOLLET; | |
| 3232 | + e.data.fd = ctx.evfd[i]; | |
| 3233 | + ASSERT_EQ(epoll_ctl(ctx.epfd, EPOLL_CTL_ADD, ctx.evfd[i], &e), 0); | |
| 3234 | + } | |
| 3235 | + | |
| 3236 | + /* Create waiter threads */ | |
| 3237 | + for (i = 0; i < ARRAY_SIZE(waiters); i++) | |
| 3238 | + ASSERT_EQ(pthread_create(&waiters[i], NULL, | |
| 3239 | + epoll60_wait_thread, &ctx), 0); | |
| 3240 | + | |
| 3241 | + for (i = 0; i < 300; i++) { | |
| 3242 | + uint64_t v = 1, ms; | |
| 3243 | + | |
| 3244 | + /* Wait for all to be ready */ | |
| 3245 | + while (__atomic_load_n(&ctx.ready, __ATOMIC_ACQUIRE) != | |
| 3246 | + ARRAY_SIZE(ctx.evfd)) | |
| 3247 | + ; | |
| 3248 | + | |
| 3249 | + /* Steady, go */ | |
| 3250 | + __atomic_fetch_sub(&ctx.ready, ARRAY_SIZE(ctx.evfd), | |
| 3251 | + __ATOMIC_ACQUIRE); | |
| 3252 | + | |
| 3253 | + /* Wait all have gone to kernel */ | |
| 3254 | + while (count_waiters(&ctx) != ARRAY_SIZE(ctx.evfd)) | |
| 3255 | + ; | |
| 3256 | + | |
| 3257 | + /* 1ms should be enough to schedule away */ | |
| 3258 | + usleep(1000); | |
| 3259 | + | |
| 3260 | + /* Quickly signal all handles at once */ | |
| 3261 | + for (n = 0; n < ARRAY_SIZE(ctx.evfd); n++) { | |
| 3262 | + ret = write(ctx.evfd[n], &v, sizeof(v)); | |
| 3263 | + ASSERT_EQ(ret, sizeof(v)); | |
| 3264 | + } | |
| 3265 | + | |
| 3266 | + /* Busy loop for 1s and wait for all waiters to wake up */ | |
| 3267 | + ms = msecs(); | |
| 3268 | + while (count_waiters(&ctx) && msecs() < ms + 1000) | |
| 3269 | + ; | |
| 3270 | + | |
| 3271 | + ASSERT_EQ(count_waiters(&ctx), 0); | |
| 3272 | + } | |
| 3273 | + ctx.stopped = 1; | |
| 3274 | + /* Stop waiters */ | |
| 3275 | + for (i = 0; i < ARRAY_SIZE(waiters); i++) | |
| 3276 | + ret = pthread_kill(waiters[i], SIGUSR1); | |
| 3277 | + for (i = 0; i < ARRAY_SIZE(waiters); i++) | |
| 3278 | + pthread_join(waiters[i], NULL); | |
| 3279 | + | |
| 3280 | + for (i = 0; i < ARRAY_SIZE(waiters); i++) | |
| 3281 | + close(ctx.evfd[i]); | |
| 3282 | + close(ctx.epfd); | |
| 3283 | +} | |
| 3284 | + | |
| 3139 | 3285 | TEST_HARNESS_MAIN |
| @@ -17,6 +17,7 @@ echo " -v|--verbose Increase verbosity of test messages" · 16 unmodified lines | ||
| 17 | 17 | echo " -vv Alias of -v -v (Show all results in stdout)" |
| 18 | 18 | echo " -vvv Alias of -v -v -v (Show all commands immediately)" |
| 19 | 19 | echo " --fail-unsupported Treat UNSUPPORTED as a failure" |
| 20 | +echo " --fail-unresolved Treat UNRESOLVED as a failure" | |
| 20 | 21 | echo " -d|--debug Debug mode (trace all shell commands)" |
| 21 | 22 | echo " -l|--logdir <dir> Save logs on the <dir>" |
| 22 | 23 | echo " If <dir> is -, all logs output in console only" |
| @@ -29,8 +30,25 @@ err_ret=1 · 6 unmodified lines | ||
| 29 | 30 | # kselftest skip code is 4 |
| 30 | 31 | err_skip=4 |
| 31 | 32 | |
| 33 | +# cgroup RT scheduling prevents chrt commands from succeeding, which | |
| 34 | +# induces failures in test wakeup tests. Disable for the duration of | |
| 35 | +# the tests. | |
| 36 | + | |
| 37 | +readonly sched_rt_runtime=/proc/sys/kernel/sched_rt_runtime_us | |
| 38 | + | |
| 39 | +sched_rt_runtime_orig=$(cat $sched_rt_runtime) | |
| 40 | + | |
| 41 | +setup() { | |
| 42 | + echo -1 > $sched_rt_runtime | |
| 43 | +} | |
| 44 | + | |
| 45 | +cleanup() { | |
| 46 | + echo $sched_rt_runtime_orig > $sched_rt_runtime | |
| 47 | +} | |
| 48 | + | |
| 32 | 49 | errexit() { # message |
| 33 | 50 | echo "Error: $1" 1>&2 |
| 51 | + cleanup | |
| 34 | 52 | exit $err_ret |
| 35 | 53 | } |
| 36 | 54 | |
| @@ -39,6 +57,8 @@ if [ `id -u` -ne 0 ]; then · 2 unmodified lines | ||
| 39 | 57 | errexit "this must be run by root user" |
| 40 | 58 | fi |
| 41 | 59 | |
| 60 | +setup | |
| 61 | + | |
| 42 | 62 | # Utilities |
| 43 | 63 | absdir() { # file_path |
| 44 | 64 | (cd `dirname $1`; pwd) |
| @@ -93,6 +113,10 @@ parse_opts() { # opts · 48 unmodified lines | ||
| 93 | 113 | UNSUPPORTED_RESULT=1 |
| 94 | 114 | shift 1 |
| 95 | 115 | ;; |
| 116 | + --fail-unresolved) | |
| 117 | + UNRESOLVED_RESULT=1 | |
| 118 | + shift 1 | |
| 119 | + ;; | |
| 96 | 120 | --logdir|-l) |
| 97 | 121 | LOG_DIR=$2 |
| 98 | 122 | shift 2 |
| @@ -157,6 +181,7 @@ KEEP_LOG=0 · 58 unmodified lines | ||
| 157 | 181 | DEBUG=0 |
| 158 | 182 | VERBOSE=0 |
| 159 | 183 | UNSUPPORTED_RESULT=0 |
| 184 | +UNRESOLVED_RESULT=0 | |
| 160 | 185 | STOP_FAILURE=0 |
| 161 | 186 | # Parse command-line options |
| 162 | 187 | parse_opts $* |
| @@ -235,6 +260,7 @@ TOTAL_RESULT=0 · 72 unmodified lines | ||
| 235 | 260 | |
| 236 | 261 | INSTANCE= |
| 237 | 262 | CASENO=0 |
| 263 | + | |
| 238 | 264 | testcase() { # testfile |
| 239 | 265 | CASENO=$((CASENO+1)) |
| 240 | 266 | desc=`grep "^#[ \t]*description:" $1 | cut -f2 -d:` |
| @@ -260,7 +286,7 @@ eval_result() { # sigval · 19 unmodified lines | ||
| 260 | 286 | $UNRESOLVED) |
| 261 | 287 | prlog " [${color_blue}UNRESOLVED${color_reset}]" |
| 262 | 288 | UNRESOLVED_CASES="$UNRESOLVED_CASES $CASENO" |
| 263 | − return 1 # this is a kind of bug.. something happened. | |
| 289 | + return $UNRESOLVED_RESULT # depends on use case | |
| 264 | 290 | ;; |
| 265 | 291 | $UNTESTED) |
| 266 | 292 | prlog " [${color_blue}UNTESTED${color_reset}]" |
| @@ -273,7 +299,7 @@ eval_result() { # sigval · 6 unmodified lines | ||
| 273 | 299 | return $UNSUPPORTED_RESULT # depends on use case |
| 274 | 300 | ;; |
| 275 | 301 | $XFAIL) |
| 276 | − prlog " [${color_red}XFAIL${color_reset}]" | |
| 302 | + prlog " [${color_green}XFAIL${color_reset}]" | |
| 277 | 303 | XFAILED_CASES="$XFAILED_CASES $CASENO" |
| 278 | 304 | return 0 |
| 279 | 305 | ;; |
| @@ -406,5 +432,7 @@ prlog "# of unsupported: " `echo $UNSUPPORTED_CASES | wc -w` · 126 unmodified lines | ||
| 406 | 432 | prlog "# of xfailed: " `echo $XFAILED_CASES | wc -w` |
| 407 | 433 | prlog "# of undefined(test bug): " `echo $UNDEFINED_CASES | wc -w` |
| 408 | 434 | |
| 435 | +cleanup | |
| 436 | + | |
| 409 | 437 | # if no error, return 0 |
| 410 | 438 | exit $TOTAL_RESULT |
| @@ -10,10 +10,7 @@ if ! grep -q function_graph available_tracers; then · 9 unmodified lines | ||
| 10 | 10 | exit_unsupported |
| 11 | 11 | fi |
| 12 | 12 | |
| 13 | −if [ ! -f set_ftrace_filter ]; then | |
| 14 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 15 | − exit_unsupported | |
| 16 | −fi | |
| 13 | +check_filter_file set_ftrace_filter | |
| 17 | 14 | |
| 18 | 15 | do_reset() { |
| 19 | 16 | if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then |
| @@ -9,6 +9,8 @@ if ! grep -q function_graph available_tracers; then · 8 unmodified lines | ||
| 9 | 9 | exit_unsupported |
| 10 | 10 | fi |
| 11 | 11 | |
| 12 | +check_filter_file set_ftrace_filter | |
| 13 | + | |
| 12 | 14 | fail() { # msg |
| 13 | 15 | echo $1 |
| 14 | 16 | exit_fail |
| @@ -9,6 +9,8 @@ if ! grep -q function available_tracers; then · 8 unmodified lines | ||
| 9 | 9 | exit_unsupported |
| 10 | 10 | fi |
| 11 | 11 | |
| 12 | +check_filter_file set_ftrace_filter | |
| 13 | + | |
| 12 | 14 | disable_tracing |
| 13 | 15 | clear_trace |
| 14 | 16 | |
| @@ -15,10 +15,7 @@ if [ ! -f set_ftrace_notrace_pid ]; then · 14 unmodified lines | ||
| 15 | 15 | exit_unsupported |
| 16 | 16 | fi |
| 17 | 17 | |
| 18 | −if [ ! -f set_ftrace_filter ]; then | |
| 19 | − echo "set_ftrace_filter not found? Is function tracer not set?" | |
| 20 | − exit_unsupported | |
| 21 | −fi | |
| 18 | +check_filter_file set_ftrace_filter | |
| 22 | 19 | |
| 23 | 20 | do_function_fork=1 |
| 24 | 21 | |
| @@ -16,10 +16,7 @@ if [ ! -f set_ftrace_pid ]; then · 15 unmodified lines | ||
| 16 | 16 | exit_unsupported |
| 17 | 17 | fi |
| 18 | 18 | |
| 19 | −if [ ! -f set_ftrace_filter ]; then | |
| 20 | − echo "set_ftrace_filter not found? Is function tracer not set?" | |
| 21 | − exit_unsupported | |
| 22 | −fi | |
| 19 | +check_filter_file set_ftrace_filter | |
| 23 | 20 | |
| 24 | 21 | do_function_fork=1 |
| 25 | 22 | |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | # description: ftrace - stacktrace filter command |
| 4 | 4 | # flags: instance |
| 5 | 5 | |
| 6 | −[ ! -f set_ftrace_filter ] && exit_unsupported | |
| 6 | +check_filter_file set_ftrace_filter | |
| 7 | 7 | |
| 8 | 8 | echo _do_fork:stacktrace >> set_ftrace_filter |
| 9 | 9 | |
| @@ -11,10 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | # |
| 12 | 12 | |
| 13 | 13 | # The triggers are set within the set_ftrace_filter file |
| 14 | −if [ ! -f set_ftrace_filter ]; then | |
| 15 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 16 | − exit_unsupported | |
| 17 | −fi | |
| 14 | +check_filter_file set_ftrace_filter | |
| 18 | 15 | |
| 19 | 16 | do_reset() { |
| 20 | 17 | reset_ftrace_filter |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | # description: ftrace - function trace on module |
| 4 | 4 | |
| 5 | −[ ! -f set_ftrace_filter ] && exit_unsupported | |
| 5 | +check_filter_file set_ftrace_filter | |
| 6 | 6 | |
| 7 | 7 | : "mod: allows to filter a non exist function" |
| 8 | 8 | echo 'non_exist_func:mod:non_exist_module' > set_ftrace_filter |
| @@ -18,10 +18,7 @@ if ! grep -q function_graph available_tracers; then · 17 unmodified lines | ||
| 18 | 18 | exit_unsupported; |
| 19 | 19 | fi |
| 20 | 20 | |
| 21 | −if [ ! -f set_ftrace_filter ]; then | |
| 22 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 23 | − exit_unsupported | |
| 24 | −fi | |
| 21 | +check_filter_file set_ftrace_filter | |
| 25 | 22 | |
| 26 | 23 | if [ ! -f function_profile_enabled ]; then |
| 27 | 24 | echo "function_profile_enabled not found, function profiling enabled?" |
| @@ -10,10 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | # |
| 11 | 11 | |
| 12 | 12 | # The triggers are set within the set_ftrace_filter file |
| 13 | −if [ ! -f set_ftrace_filter ]; then | |
| 14 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 15 | − exit_unsupported | |
| 16 | −fi | |
| 13 | +check_filter_file set_ftrace_filter | |
| 17 | 14 | |
| 18 | 15 | fail() { # mesg |
| 19 | 16 | echo $1 |
| @@ -8,6 +8,8 @@ if [ ! -f stack_trace ]; then · 7 unmodified lines | ||
| 8 | 8 | exit_unsupported |
| 9 | 9 | fi |
| 10 | 10 | |
| 11 | +check_filter_file stack_trace_filter | |
| 12 | + | |
| 11 | 13 | echo > stack_trace_filter |
| 12 | 14 | echo 0 > stack_max_size |
| 13 | 15 | echo 1 > /proc/sys/kernel/stack_tracer_enabled |
| @@ -11,10 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | # |
| 12 | 12 | |
| 13 | 13 | # The triggers are set within the set_ftrace_filter file |
| 14 | −if [ ! -f set_ftrace_filter ]; then | |
| 15 | − echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | |
| 16 | − exit_unsupported | |
| 17 | −fi | |
| 14 | +check_filter_file set_ftrace_filter | |
| 18 | 15 | |
| 19 | 16 | fail() { # mesg |
| 20 | 17 | echo $1 |
| @@ -1,3 +1,9 @@ | ||
| 1 | +check_filter_file() { # check filter file introduced by dynamic ftrace | |
| 2 | + if [ ! -f "$1" ]; then | |
| 3 | + echo "$1 not found? Is dynamic ftrace not set?" | |
| 4 | + exit_unsupported | |
| 5 | + fi | |
| 6 | +} | |
| 1 | 7 | |
| 2 | 8 | clear_trace() { # reset trace output |
| 3 | 9 | echo > trace |
| @@ -38,7 +38,7 @@ for width in 64 32 16 8; do · 37 unmodified lines | ||
| 38 | 38 | echo 0 > events/kprobes/testprobe/enable |
| 39 | 39 | |
| 40 | 40 | : "Confirm the arguments is recorded in given types correctly" |
| 41 | − ARGS=`grep "testprobe" trace | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'` | |
| 41 | + ARGS=`grep "testprobe" trace | head -n 1 | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'` | |
| 42 | 42 | check_types $ARGS $width |
| 43 | 43 | |
| 44 | 44 | : "Clear event for next loop" |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | ||
| 5 | 5 | [ -f kprobe_events ] || exit_unsupported # this is configurable |
| 6 | 6 | grep "function" available_tracers || exit_unsupported # this is configurable |
| 7 | 7 | |
| 8 | +check_filter_file set_ftrace_filter | |
| 9 | + | |
| 8 | 10 | # prepare |
| 9 | 11 | echo nop > current_tracer |
| 10 | 12 | echo _do_fork > set_ftrace_filter |
| @@ -1,13 +1,13 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | −MOUNT_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) | |
| 4 | −MOUNT_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) | |
| 5 | −ifeq ($(MOUNT_LDLIBS),) | |
| 6 | −MOUNT_LDLIBS := -lmount -I/usr/include/libmount | |
| 3 | +VAR_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) | |
| 4 | +VAR_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) | |
| 5 | +ifeq ($(VAR_LDLIBS),) | |
| 6 | +VAR_LDLIBS := -lmount -I/usr/include/libmount | |
| 7 | 7 | endif |
| 8 | 8 | |
| 9 | −CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) | |
| 10 | −LDLIBS += $(MOUNT_LDLIBS) | |
| 9 | +CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) | |
| 10 | +LDLIBS += $(VAR_LDLIBS) | |
| 11 | 11 | |
| 12 | 12 | TEST_PROGS := gpio-mockup.sh |
| 13 | 13 | TEST_FILES := gpio-mockup-sysfs.sh |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE |
| 3 | −LDLIBS := $(LDLIBS) -lm | |
| 3 | +LDLIBS += -lm | |
| 4 | 4 | |
| 5 | 5 | uname_M := $(shell uname -m 2>/dev/null || echo not) |
| 6 | 6 | ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) |
| @@ -0,0 +1,272 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +# SPDX-License-Identifier: GPL-2.0 | |
| 3 | +# kselftest_deps.sh | |
| 4 | +# | |
| 5 | +# Checks for kselftest build dependencies on the build system. | |
| 6 | +# Copyright (c) 2020 Shuah Khan <skhan@linuxfoundation.org> | |
| 7 | +# | |
| 8 | +# | |
| 9 | + | |
| 10 | +usage() | |
| 11 | +{ | |
| 12 | + | |
| 13 | +echo -e "Usage: $0 -[p] <compiler> [test_name]\n" | |
| 14 | +echo -e "\tkselftest_deps.sh [-p] gcc" | |
| 15 | +echo -e "\tkselftest_deps.sh [-p] gcc vm" | |
| 16 | +echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc" | |
| 17 | +echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc vm\n" | |
| 18 | +echo "- Should be run in selftests directory in the kernel repo." | |
| 19 | +echo "- Checks if Kselftests can be built/cross-built on a system." | |
| 20 | +echo "- Parses all test/sub-test Makefile to find library dependencies." | |
| 21 | +echo "- Runs compile test on a trivial C file with LDLIBS specified" | |
| 22 | +echo " in the test Makefiles to identify missing library dependencies." | |
| 23 | +echo "- Prints suggested target list for a system filtering out tests" | |
| 24 | +echo " failed the build dependency check from the TARGETS in Selftests" | |
| 25 | +echo " main Makefile when optional -p is specified." | |
| 26 | +echo "- Prints pass/fail dependency check for each tests/sub-test." | |
| 27 | +echo "- Prints pass/fail targets and libraries." | |
| 28 | +echo "- Default: runs dependency checks on all tests." | |
| 29 | +echo "- Optional test name can be specified to check dependencies for it." | |
| 30 | +exit 1 | |
| 31 | + | |
| 32 | +} | |
| 33 | + | |
| 34 | +# Start main() | |
| 35 | +main() | |
| 36 | +{ | |
| 37 | + | |
| 38 | +base_dir=`pwd` | |
| 39 | +# Make sure we're in the selftests top-level directory. | |
| 40 | +if [ $(basename "$base_dir") != "selftests" ]; then | |
| 41 | + echo -e "\tPlease run $0 in" | |
| 42 | + echo -e "\ttools/testing/selftests directory ..." | |
| 43 | + exit 1 | |
| 44 | +fi | |
| 45 | + | |
| 46 | +print_targets=0 | |
| 47 | + | |
| 48 | +while getopts "p" arg; do | |
| 49 | + case $arg in | |
| 50 | + p) | |
| 51 | + print_targets=1 | |
| 52 | + shift;; | |
| 53 | + esac | |
| 54 | +done | |
| 55 | + | |
| 56 | +if [ $# -eq 0 ] | |
| 57 | +then | |
| 58 | + usage | |
| 59 | +fi | |
| 60 | + | |
| 61 | +# Compiler | |
| 62 | +CC=$1 | |
| 63 | + | |
| 64 | +tmp_file=$(mktemp).c | |
| 65 | +trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT | |
| 66 | +#echo $tmp_file | |
| 67 | + | |
| 68 | +pass=$(mktemp).out | |
| 69 | +trap "rm -f $pass" EXIT | |
| 70 | +#echo $pass | |
| 71 | + | |
| 72 | +fail=$(mktemp).out | |
| 73 | +trap "rm -f $fail" EXIT | |
| 74 | +#echo $fail | |
| 75 | + | |
| 76 | +# Generate tmp source fire for compile test | |
| 77 | +cat << "EOF" > $tmp_file | |
| 78 | +int main() | |
| 79 | +{ | |
| 80 | +} | |
| 81 | +EOF | |
| 82 | + | |
| 83 | +# Save results | |
| 84 | +total_cnt=0 | |
| 85 | +fail_trgts=() | |
| 86 | +fail_libs=() | |
| 87 | +fail_cnt=0 | |
| 88 | +pass_trgts=() | |
| 89 | +pass_libs=() | |
| 90 | +pass_cnt=0 | |
| 91 | + | |
| 92 | +# Get all TARGETS from selftests Makefile | |
| 93 | +targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) | |
| 94 | + | |
| 95 | +# Single test case | |
| 96 | +if [ $# -eq 2 ] | |
| 97 | +then | |
| 98 | + test=$2/Makefile | |
| 99 | + | |
| 100 | + l1_test $test | |
| 101 | + l2_test $test | |
| 102 | + l3_test $test | |
| 103 | + | |
| 104 | + print_results $1 $2 | |
| 105 | + exit $? | |
| 106 | +fi | |
| 107 | + | |
| 108 | +# Level 1: LDLIBS set static. | |
| 109 | +# | |
| 110 | +# Find all LDLIBS set statically for all executables built by a Makefile | |
| 111 | +# and filter out VAR_LDLIBS to discard the following: | |
| 112 | +# gpio/Makefile:LDLIBS += $(VAR_LDLIBS) | |
| 113 | +# Append space at the end of the list to append more tests. | |
| 114 | + | |
| 115 | +l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ | |
| 116 | + grep -v "VAR_LDLIBS" | awk -F: '{print $1}') | |
| 117 | + | |
| 118 | +# Level 2: LDLIBS set dynamically. | |
| 119 | +# | |
| 120 | +# Level 2 | |
| 121 | +# Some tests have multiple valid LDLIBS lines for individual sub-tests | |
| 122 | +# that need dependency checks. Find them and append them to the tests | |
| 123 | +# e.g: vm/Makefile:$(OUTPUT)/userfaultfd: LDLIBS += -lpthread | |
| 124 | +# Filter out VAR_LDLIBS to discard the following: | |
| 125 | +# memfd/Makefile:$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) | |
| 126 | +# Append space at the end of the list to append more tests. | |
| 127 | + | |
| 128 | +l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ | |
| 129 | + grep -v "VAR_LDLIBS" | awk -F: '{print $1}') | |
| 130 | + | |
| 131 | +# Level 3 | |
| 132 | +# gpio, memfd and others use pkg-config to find mount and fuse libs | |
| 133 | +# respectively and save it in VAR_LDLIBS. If pkg-config doesn't find | |
| 134 | +# any, VAR_LDLIBS set to default. | |
| 135 | +# Use the default value and filter out pkg-config for dependency check. | |
| 136 | +# e.g: | |
| 137 | +# gpio/Makefile | |
| 138 | +# VAR_LDLIBS := $(shell pkg-config --libs mount) 2>/dev/null) | |
| 139 | +# memfd/Makefile | |
| 140 | +# VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) | |
| 141 | + | |
| 142 | +l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \ | |
| 143 | + grep -v "pkg-config" | awk -F: '{print $1}') | |
| 144 | + | |
| 145 | +#echo $l1_tests | |
| 146 | +#echo $l2_1_tests | |
| 147 | +#echo $l3_tests | |
| 148 | + | |
| 149 | +all_tests | |
| 150 | +print_results $1 $2 | |
| 151 | + | |
| 152 | +exit $? | |
| 153 | +} | |
| 154 | +# end main() | |
| 155 | + | |
| 156 | +all_tests() | |
| 157 | +{ | |
| 158 | + for test in $l1_tests; do | |
| 159 | + l1_test $test | |
| 160 | + done | |
| 161 | + | |
| 162 | + for test in $l2_tests; do | |
| 163 | + l2_test $test | |
| 164 | + done | |
| 165 | + | |
| 166 | + for test in $l3_tests; do | |
| 167 | + l3_test $test | |
| 168 | + done | |
| 169 | +} | |
| 170 | + | |
| 171 | +# Use same parsing used for l1_tests and pick libraries this time. | |
| 172 | +l1_test() | |
| 173 | +{ | |
| 174 | + test_libs=$(grep --include=Makefile "^LDLIBS" $test | \ | |
| 175 | + grep -v "VAR_LDLIBS" | \ | |
| 176 | + sed -e 's/\:/ /' | \ | |
| 177 | + sed -e 's/+/ /' | cut -d "=" -f 2) | |
| 178 | + | |
| 179 | + check_libs $test $test_libs | |
| 180 | +} | |
| 181 | + | |
| 182 | +# Use same parsing used for l2__tests and pick libraries this time. | |
| 183 | +l2_test() | |
| 184 | +{ | |
| 185 | + test_libs=$(grep --include=Makefile ": LDLIBS" $test | \ | |
| 186 | + grep -v "VAR_LDLIBS" | \ | |
| 187 | + sed -e 's/\:/ /' | sed -e 's/+/ /' | \ | |
| 188 | + cut -d "=" -f 2) | |
| 189 | + | |
| 190 | + check_libs $test $test_libs | |
| 191 | +} | |
| 192 | + | |
| 193 | +l3_test() | |
| 194 | +{ | |
| 195 | + test_libs=$(grep --include=Makefile "^VAR_LDLIBS" $test | \ | |
| 196 | + grep -v "pkg-config" | sed -e 's/\:/ /' | | |
| 197 | + sed -e 's/+/ /' | cut -d "=" -f 2) | |
| 198 | + | |
| 199 | + check_libs $test $test_libs | |
| 200 | +} | |
| 201 | + | |
| 202 | +check_libs() | |
| 203 | +{ | |
| 204 | + | |
| 205 | +if [[ ! -z "${test_libs// }" ]] | |
| 206 | +then | |
| 207 | + | |
| 208 | + #echo $test_libs | |
| 209 | + | |
| 210 | + for lib in $test_libs; do | |
| 211 | + | |
| 212 | + let total_cnt+=1 | |
| 213 | + $CC -o $tmp_file.bin $lib $tmp_file > /dev/null 2>&1 | |
| 214 | + if [ $? -ne 0 ]; then | |
| 215 | + echo "FAIL: $test dependency check: $lib" >> $fail | |
| 216 | + let fail_cnt+=1 | |
| 217 | + fail_libs+="$lib " | |
| 218 | + fail_target=$(echo "$test" | cut -d "/" -f1) | |
| 219 | + fail_trgts+="$fail_target " | |
| 220 | + targets=$(echo "$targets" | grep -v "$fail_target") | |
| 221 | + else | |
| 222 | + echo "PASS: $test dependency check passed $lib" >> $pass | |
| 223 | + let pass_cnt+=1 | |
| 224 | + pass_libs+="$lib " | |
| 225 | + pass_trgts+="$(echo "$test" | cut -d "/" -f1) " | |
| 226 | + fi | |
| 227 | + | |
| 228 | + done | |
| 229 | +fi | |
| 230 | +} | |
| 231 | + | |
| 232 | +print_results() | |
| 233 | +{ | |
| 234 | + echo -e "========================================================"; | |
| 235 | + echo -e "Kselftest Dependency Check for [$0 $1 $2] results..." | |
| 236 | + | |
| 237 | + if [ $print_targets -ne 0 ] | |
| 238 | + then | |
| 239 | + echo -e "Suggested Selftest Targets for your configuration:" | |
| 240 | + echo -e "$targets"; | |
| 241 | + fi | |
| 242 | + | |
| 243 | + echo -e "========================================================"; | |
| 244 | + echo -e "Checked tests defining LDLIBS dependencies" | |
| 245 | + echo -e "--------------------------------------------------------"; | |
| 246 | + echo -e "Total tests with Dependencies:" | |
| 247 | + echo -e "$total_cnt Pass: $pass_cnt Fail: $fail_cnt"; | |
| 248 | + | |
| 249 | + if [ $pass_cnt -ne 0 ]; then | |
| 250 | + echo -e "--------------------------------------------------------"; | |
| 251 | + cat $pass | |
| 252 | + echo -e "--------------------------------------------------------"; | |
| 253 | + echo -e "Targets passed build dependency check on system:" | |
| 254 | + echo -e "$(echo "$pass_trgts" | xargs -n1 | sort -u | xargs)" | |
| 255 | + fi | |
| 256 | + | |
| 257 | + if [ $fail_cnt -ne 0 ]; then | |
| 258 | + echo -e "--------------------------------------------------------"; | |
| 259 | + cat $fail | |
| 260 | + echo -e "--------------------------------------------------------"; | |
| 261 | + echo -e "Targets failed build dependency check on system:" | |
| 262 | + echo -e "$(echo "$fail_trgts" | xargs -n1 | sort -u | xargs)" | |
| 263 | + echo -e "--------------------------------------------------------"; | |
| 264 | + echo -e "Missing libraries system" | |
| 265 | + echo -e "$(echo "$fail_libs" | xargs -n1 | sort -u | xargs)" | |
| 266 | + fi | |
| 267 | + | |
| 268 | + echo -e "--------------------------------------------------------"; | |
| 269 | + echo -e "========================================================"; | |
| 270 | +} | |
| 271 | + | |
| 272 | +main "$@" | |
| @@ -5,8 +5,34 @@ all: · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | top_srcdir = ../../../.. |
| 7 | 7 | KSFT_KHDR_INSTALL := 1 |
| 8 | + | |
| 9 | +# For cross-builds to work, UNAME_M has to map to ARCH and arch specific | |
| 10 | +# directories and targets in this Makefile. "uname -m" doesn't map to | |
| 11 | +# arch specific sub-directory names. | |
| 12 | +# | |
| 13 | +# UNAME_M variable to used to run the compiles pointing to the right arch | |
| 14 | +# directories and build the right targets for these supported architectures. | |
| 15 | +# | |
| 16 | +# TEST_GEN_PROGS and LIBKVM are set using UNAME_M variable. | |
| 17 | +# LINUX_TOOL_ARCH_INCLUDE is set using ARCH variable. | |
| 18 | +# | |
| 19 | +# x86_64 targets are named to include x86_64 as a suffix and directories | |
| 20 | +# for includes are in x86_64 sub-directory. s390x and aarch64 follow the | |
| 21 | +# same convention. "uname -m" doesn't result in the correct mapping for | |
| 22 | +# s390x and aarch64. | |
| 23 | +# | |
| 24 | +# No change necessary for x86_64 | |
| 8 | 25 | UNAME_M := $(shell uname -m) |
| 9 | 26 | |
| 27 | +# Set UNAME_M for arm64 compile/install to work | |
| 28 | +ifeq ($(ARCH),arm64) | |
| 29 | + UNAME_M := aarch64 | |
| 30 | +endif | |
| 31 | +# Set UNAME_M s390x compile/install to work | |
| 32 | +ifeq ($(ARCH),s390) | |
| 33 | + UNAME_M := s390x | |
| 34 | +endif | |
| 35 | + | |
| 10 | 36 | LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c lib/test_util.c |
| 11 | 37 | LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/svm.c lib/x86_64/ucall.c |
| 12 | 38 | LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c |
| @@ -53,7 +79,7 @@ LIBKVM += $(LIBKVM_$(UNAME_M)) · 40 unmodified lines | ||
| 53 | 79 | INSTALL_HDR_PATH = $(top_srcdir)/usr |
| 54 | 80 | LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/ |
| 55 | 81 | LINUX_TOOL_INCLUDE = $(top_srcdir)/tools/include |
| 56 | −LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/x86/include | |
| 82 | +LINUX_TOOL_ARCH_INCLUDE = $(top_srcdir)/tools/arch/$(ARCH)/include | |
| 57 | 83 | CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \ |
| 58 | 84 | -fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \ |
| 59 | 85 | -I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \ |
| @@ -84,6 +110,7 @@ $(LIBKVM_OBJ): $(OUTPUT)/%.o: %.c · 24 unmodified lines | ||
| 84 | 110 | $(OUTPUT)/libkvm.a: $(LIBKVM_OBJ) |
| 85 | 111 | $(AR) crs $@ $^ |
| 86 | 112 | |
| 113 | +x := $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))) | |
| 87 | 114 | all: $(STATIC_LIBS) |
| 88 | 115 | $(TEST_GEN_PROGS): $(STATIC_LIBS) |
| 89 | 116 | |
| @@ -219,8 +219,8 @@ struct hv_enlightened_vmcs { · 218 unmodified lines | ||
| 219 | 219 | #define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK \ |
| 220 | 220 | (~((1ull << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT) - 1)) |
| 221 | 221 | |
| 222 | −struct hv_enlightened_vmcs *current_evmcs; | |
| 223 | −struct hv_vp_assist_page *current_vp_assist; | |
| 222 | +extern struct hv_enlightened_vmcs *current_evmcs; | |
| 223 | +extern struct hv_vp_assist_page *current_vp_assist; | |
| 224 | 224 | |
| 225 | 225 | int vcpu_enable_evmcs(struct kvm_vm *vm, int vcpu_id); |
| 226 | 226 | |
| @@ -17,6 +17,9 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | bool enable_evmcs; |
| 19 | 19 | |
| 20 | +struct hv_enlightened_vmcs *current_evmcs; | |
| 21 | +struct hv_vp_assist_page *current_vp_assist; | |
| 22 | + | |
| 20 | 23 | struct eptPageTableEntry { |
| 21 | 24 | uint64_t readable:1; |
| 22 | 25 | uint64_t writable:1; |
| @@ -8,11 +8,21 @@ TEST_GEN_PROGS := memfd_test · 7 unmodified lines | ||
| 8 | 8 | TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh |
| 9 | 9 | TEST_GEN_FILES := fuse_test fuse_mnt |
| 10 | 10 | |
| 11 | −fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) | |
| 11 | +VAR_CFLAGS := $(shell pkg-config fuse --cflags 2>/dev/null) | |
| 12 | +ifeq ($(VAR_CFLAGS),) | |
| 13 | +VAR_CFLAGS := -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse | |
| 14 | +endif | |
| 15 | + | |
| 16 | +VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) | |
| 17 | +ifeq ($(VAR_LDLIBS),) | |
| 18 | +VAR_LDLIBS := -lfuse -pthread | |
| 19 | +endif | |
| 20 | + | |
| 21 | +fuse_mnt.o: CFLAGS += $(VAR_CFLAGS) | |
| 12 | 22 | |
| 13 | 23 | include ../lib.mk |
| 14 | 24 | |
| 15 | −$(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs) | |
| 25 | +$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) | |
| 16 | 26 | |
| 17 | 27 | $(OUTPUT)/memfd_test: memfd_test.c common.c |
| 18 | 28 | $(OUTPUT)/fuse_test: fuse_test.c common.c |
| @@ -165,9 +165,10 @@ void *child_thread(void *arg) · 164 unmodified lines | ||
| 165 | 165 | socklen_t zc_len = sizeof(zc); |
| 166 | 166 | int res; |
| 167 | 167 | |
| 168 | + memset(&zc, 0, sizeof(zc)); | |
| 168 | 169 | zc.address = (__u64)((unsigned long)addr); |
| 169 | 170 | zc.length = chunk_size; |
| 170 | − zc.recv_skip_hint = 0; | |
| 171 | + | |
| 171 | 172 | res = getsockopt(fd, IPPROTO_TCP, TCP_ZEROCOPY_RECEIVE, |
| 172 | 173 | &zc, &zc_len); |
| 173 | 174 | if (res == -1) |
| @@ -281,12 +282,14 @@ static void setup_sockaddr(int domain, const char *str_addr, · 107 unmodified lines | ||
| 281 | 282 | static void do_accept(int fdlisten) |
| 282 | 283 | { |
| 283 | 284 | pthread_attr_t attr; |
| 285 | + int rcvlowat; | |
| 284 | 286 | |
| 285 | 287 | pthread_attr_init(&attr); |
| 286 | 288 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| 287 | 289 | |
| 290 | + rcvlowat = chunk_size; | |
| 288 | 291 | if (setsockopt(fdlisten, SOL_SOCKET, SO_RCVLOWAT, |
| 289 | − &chunk_size, sizeof(chunk_size)) == -1) { | |
| 292 | + &rcvlowat, sizeof(rcvlowat)) == -1) { | |
| 290 | 293 | perror("setsockopt SO_RCVLOWAT"); |
| 291 | 294 | } |
| 292 | 295 | |
| @@ -48,8 +48,11 @@ cleanup() { · 47 unmodified lines | ||
| 48 | 48 | exec 2>/dev/null |
| 49 | 49 | printf "$orig_message_cost" > /proc/sys/net/core/message_cost |
| 50 | 50 | ip0 link del dev wg0 |
| 51 | + ip0 link del dev wg1 | |
| 51 | 52 | ip1 link del dev wg0 |
| 53 | + ip1 link del dev wg1 | |
| 52 | 54 | ip2 link del dev wg0 |
| 55 | + ip2 link del dev wg1 | |
| 53 | 56 | local to_kill="$(ip netns pids $netns0) $(ip netns pids $netns1) $(ip netns pids $netns2)" |
| 54 | 57 | [[ -n $to_kill ]] && kill $to_kill |
| 55 | 58 | pp ip netns del $netns1 |
| @@ -77,18 +80,20 @@ ip0 link set wg0 netns $netns2 · 21 unmodified lines | ||
| 77 | 80 | key1="$(pp wg genkey)" |
| 78 | 81 | key2="$(pp wg genkey)" |
| 79 | 82 | key3="$(pp wg genkey)" |
| 83 | +key4="$(pp wg genkey)" | |
| 80 | 84 | pub1="$(pp wg pubkey <<<"$key1")" |
| 81 | 85 | pub2="$(pp wg pubkey <<<"$key2")" |
| 82 | 86 | pub3="$(pp wg pubkey <<<"$key3")" |
| 87 | +pub4="$(pp wg pubkey <<<"$key4")" | |
| 83 | 88 | psk="$(pp wg genpsk)" |
| 84 | 89 | [[ -n $key1 && -n $key2 && -n $psk ]] |
| 85 | 90 | |
| 86 | 91 | configure_peers() { |
| 87 | 92 | ip1 addr add 192.168.241.1/24 dev wg0 |
| 88 | − ip1 addr add fd00::1/24 dev wg0 | |
| 93 | + ip1 addr add fd00::1/112 dev wg0 | |
| 89 | 94 | |
| 90 | 95 | ip2 addr add 192.168.241.2/24 dev wg0 |
| 91 | − ip2 addr add fd00::2/24 dev wg0 | |
| 96 | + ip2 addr add fd00::2/112 dev wg0 | |
| 92 | 97 | |
| 93 | 98 | n1 wg set wg0 \ |
| 94 | 99 | private-key <(echo "$key1") \ |
| @@ -230,9 +235,38 @@ n1 ping -W 1 -c 1 192.168.241.2 · 135 unmodified lines | ||
| 230 | 235 | n1 wg set wg0 private-key <(echo "$key3") |
| 231 | 236 | n2 wg set wg0 peer "$pub3" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 peer "$pub1" remove |
| 232 | 237 | n1 ping -W 1 -c 1 192.168.241.2 |
| 238 | +n2 wg set wg0 peer "$pub3" remove | |
| 239 | + | |
| 240 | +# Test that we can route wg through wg | |
| 241 | +ip1 addr flush dev wg0 | |
| 242 | +ip2 addr flush dev wg0 | |
| 243 | +ip1 addr add fd00::5:1/112 dev wg0 | |
| 244 | +ip2 addr add fd00::5:2/112 dev wg0 | |
| 245 | +n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk") allowed-ips fd00::5:2/128 endpoint 127.0.0.1:2 | |
| 246 | +n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips fd00::5:1/128 endpoint 127.212.121.99:9998 | |
| 247 | +ip1 link add wg1 type wireguard | |
| 248 | +ip2 link add wg1 type wireguard | |
| 249 | +ip1 addr add 192.168.241.1/24 dev wg1 | |
| 250 | +ip1 addr add fd00::1/112 dev wg1 | |
| 251 | +ip2 addr add 192.168.241.2/24 dev wg1 | |
| 252 | +ip2 addr add fd00::2/112 dev wg1 | |
| 253 | +ip1 link set mtu 1340 up dev wg1 | |
| 254 | +ip2 link set mtu 1340 up dev wg1 | |
| 255 | +n1 wg set wg1 listen-port 5 private-key <(echo "$key3") peer "$pub4" allowed-ips 192.168.241.2/32,fd00::2/128 endpoint [fd00::5:2]:5 | |
| 256 | +n2 wg set wg1 listen-port 5 private-key <(echo "$key4") peer "$pub3" allowed-ips 192.168.241.1/32,fd00::1/128 endpoint [fd00::5:1]:5 | |
| 257 | +tests | |
| 258 | +# Try to set up a routing loop between the two namespaces | |
| 259 | +ip1 link set netns $netns0 dev wg1 | |
| 260 | +ip0 addr add 192.168.241.1/24 dev wg1 | |
| 261 | +ip0 link set up dev wg1 | |
| 262 | +n0 ping -W 1 -c 1 192.168.241.2 | |
| 263 | +n1 wg set wg0 peer "$pub2" endpoint 192.168.241.2:7 | |
| 264 | +ip2 link del wg0 | |
| 265 | +ip2 link del wg1 | |
| 266 | +! n0 ping -W 1 -c 10 -f 192.168.241.2 || false # Should not crash kernel | |
| 233 | 267 | |
| 268 | +ip0 link del wg1 | |
| 234 | 269 | ip1 link del wg0 |
| 235 | −ip2 link del wg0 | |
| 236 | 270 | |
| 237 | 271 | # Test using NAT. We now change the topology to this: |
| 238 | 272 | # ┌────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌────────────────────────────────────────┐ |
| @@ -282,6 +316,20 @@ pp sleep 3 · 43 unmodified lines | ||
| 282 | 316 | n2 ping -W 1 -c 1 192.168.241.1 |
| 283 | 317 | n1 wg set wg0 peer "$pub2" persistent-keepalive 0 |
| 284 | 318 | |
| 319 | +# Test that onion routing works, even when it loops | |
| 320 | +n1 wg set wg0 peer "$pub3" allowed-ips 192.168.242.2/32 endpoint 192.168.241.2:5 | |
| 321 | +ip1 addr add 192.168.242.1/24 dev wg0 | |
| 322 | +ip2 link add wg1 type wireguard | |
| 323 | +ip2 addr add 192.168.242.2/24 dev wg1 | |
| 324 | +n2 wg set wg1 private-key <(echo "$key3") listen-port 5 peer "$pub1" allowed-ips 192.168.242.1/32 | |
| 325 | +ip2 link set wg1 up | |
| 326 | +n1 ping -W 1 -c 1 192.168.242.2 | |
| 327 | +ip2 link del wg1 | |
| 328 | +n1 wg set wg0 peer "$pub3" endpoint 192.168.242.2:5 | |
| 329 | +! n1 ping -W 1 -c 1 192.168.242.2 || false # Should not crash kernel | |
| 330 | +n1 wg set wg0 peer "$pub3" remove | |
| 331 | +ip1 addr del 192.168.242.1/24 dev wg0 | |
| 332 | + | |
| 285 | 333 | # Do a wg-quick(8)-style policy routing for the default route, making sure vethc has a v6 address to tease out bugs. |
| 286 | 334 | ip1 -6 addr add fc00::9/96 dev vethc |
| 287 | 335 | ip1 -6 route add default via fc00::1 |
| @@ -10,3 +10,4 @@ CONFIG_CMDLINE_BOOL=y · 9 unmodified lines | ||
| 10 | 10 | CONFIG_CMDLINE="console=hvc0 wg.success=hvc1" |
| 11 | 11 | CONFIG_SECTION_MISMATCH_WARN_ONLY=y |
| 12 | 12 | CONFIG_FRAME_WARN=1280 |
| 13 | +CONFIG_THREAD_SHIFT=14 | |
| @@ -25,7 +25,6 @@ CONFIG_KASAN=y · 24 unmodified lines | ||
| 25 | 25 | CONFIG_KASAN_INLINE=y |
| 26 | 26 | CONFIG_UBSAN=y |
| 27 | 27 | CONFIG_UBSAN_SANITIZE_ALL=y |
| 28 | −CONFIG_UBSAN_NO_ALIGNMENT=y | |
| 29 | 28 | CONFIG_UBSAN_NULL=y |
| 30 | 29 | CONFIG_DEBUG_KMEMLEAK=y |
| 31 | 30 | CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=8192 |
| @@ -125,12 +125,16 @@ static void __hyp_text kvm_adjust_itstate(struct kvm_vcpu *vcpu) · 124 unmodified lines | ||
| 125 | 125 | */ |
| 126 | 126 | void __hyp_text kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr) |
| 127 | 127 | { |
| 128 | + u32 pc = *vcpu_pc(vcpu); | |
| 128 | 129 | bool is_thumb; |
| 129 | 130 | |
| 130 | 131 | is_thumb = !!(*vcpu_cpsr(vcpu) & PSR_AA32_T_BIT); |
| 131 | 132 | if (is_thumb && !is_wide_instr) |
| 132 | − *vcpu_pc(vcpu) += 2; | |
| 133 | + pc += 2; | |
| 133 | 134 | else |
| 134 | − *vcpu_pc(vcpu) += 4; | |
| 135 | + pc += 4; | |
| 136 | + | |
| 137 | + *vcpu_pc(vcpu) = pc; | |
| 138 | + | |
| 135 | 139 | kvm_adjust_itstate(vcpu); |
| 136 | 140 | } |
| @@ -186,6 +186,33 @@ static void kvm_psci_system_reset(struct kvm_vcpu *vcpu) · 185 unmodified lines | ||
| 186 | 186 | kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET); |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | +static void kvm_psci_narrow_to_32bit(struct kvm_vcpu *vcpu) | |
| 190 | +{ | |
| 191 | + int i; | |
| 192 | + | |
| 193 | + /* | |
| 194 | + * Zero the input registers' upper 32 bits. They will be fully | |
| 195 | + * zeroed on exit, so we're fine changing them in place. | |
| 196 | + */ | |
| 197 | + for (i = 1; i < 4; i++) | |
| 198 | + vcpu_set_reg(vcpu, i, lower_32_bits(vcpu_get_reg(vcpu, i))); | |
| 199 | +} | |
| 200 | + | |
| 201 | +static unsigned long kvm_psci_check_allowed_function(struct kvm_vcpu *vcpu, u32 fn) | |
| 202 | +{ | |
| 203 | + switch(fn) { | |
| 204 | + case PSCI_0_2_FN64_CPU_SUSPEND: | |
| 205 | + case PSCI_0_2_FN64_CPU_ON: | |
| 206 | + case PSCI_0_2_FN64_AFFINITY_INFO: | |
| 207 | + /* Disallow these functions for 32bit guests */ | |
| 208 | + if (vcpu_mode_is_32bit(vcpu)) | |
| 209 | + return PSCI_RET_NOT_SUPPORTED; | |
| 210 | + break; | |
| 211 | + } | |
| 212 | + | |
| 213 | + return 0; | |
| 214 | +} | |
| 215 | + | |
| 189 | 216 | static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) |
| 190 | 217 | { |
| 191 | 218 | struct kvm *kvm = vcpu->kvm; |
| @@ -193,6 +220,10 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 193 | 220 | unsigned long val; |
| 194 | 221 | int ret = 1; |
| 195 | 222 | |
| 223 | + val = kvm_psci_check_allowed_function(vcpu, psci_fn); | |
| 224 | + if (val) | |
| 225 | + goto out; | |
| 226 | + | |
| 196 | 227 | switch (psci_fn) { |
| 197 | 228 | case PSCI_0_2_FN_PSCI_VERSION: |
| 198 | 229 | /* |
| @@ -210,12 +241,16 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 210 | 241 | val = PSCI_RET_SUCCESS; |
| 211 | 242 | break; |
| 212 | 243 | case PSCI_0_2_FN_CPU_ON: |
| 244 | + kvm_psci_narrow_to_32bit(vcpu); | |
| 245 | + fallthrough; | |
| 213 | 246 | case PSCI_0_2_FN64_CPU_ON: |
| 214 | 247 | mutex_lock(&kvm->lock); |
| 215 | 248 | val = kvm_psci_vcpu_on(vcpu); |
| 216 | 249 | mutex_unlock(&kvm->lock); |
| 217 | 250 | break; |
| 218 | 251 | case PSCI_0_2_FN_AFFINITY_INFO: |
| 252 | + kvm_psci_narrow_to_32bit(vcpu); | |
| 253 | + fallthrough; | |
| 219 | 254 | case PSCI_0_2_FN64_AFFINITY_INFO: |
| 220 | 255 | val = kvm_psci_vcpu_affinity_info(vcpu); |
| 221 | 256 | break; |
| @@ -256,6 +291,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) · 34 unmodified lines | ||
| 256 | 291 | break; |
| 257 | 292 | } |
| 258 | 293 | |
| 294 | +out: | |
| 259 | 295 | smccc_set_retval(vcpu, val, 0, 0, 0); |
| 260 | 296 | return ret; |
| 261 | 297 | } |
| @@ -273,6 +309,10 @@ static int kvm_psci_1_0_call(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 273 | 309 | break; |
| 274 | 310 | case PSCI_1_0_FN_PSCI_FEATURES: |
| 275 | 311 | feature = smccc_get_arg1(vcpu); |
| 312 | + val = kvm_psci_check_allowed_function(vcpu, feature); | |
| 313 | + if (val) | |
| 314 | + break; | |
| 315 | + | |
| 276 | 316 | switch(feature) { |
| 277 | 317 | case PSCI_0_2_FN_PSCI_VERSION: |
| 278 | 318 | case PSCI_0_2_FN_CPU_SUSPEND: |
| @@ -294,8 +294,15 @@ int vgic_init(struct kvm *kvm) · 293 unmodified lines | ||
| 294 | 294 | } |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | − if (vgic_has_its(kvm)) { | |
| 297 | + if (vgic_has_its(kvm)) | |
| 298 | 298 | vgic_lpi_translation_cache_init(kvm); |
| 299 | + | |
| 300 | + /* | |
| 301 | + * If we have GICv4.1 enabled, unconditionnaly request enable the | |
| 302 | + * v4 support so that we get HW-accelerated vSGIs. Otherwise, only | |
| 303 | + * enable it if we present a virtual ITS to the guest. | |
| 304 | + */ | |
| 305 | + if (vgic_supports_direct_msis(kvm)) { | |
| 299 | 306 | ret = vgic_v4_init(kvm); |
| 300 | 307 | if (ret) |
| 301 | 308 | goto out; |
| @@ -348,6 +355,12 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) · 46 unmodified lines | ||
| 348 | 355 | { |
| 349 | 356 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| 350 | 357 | |
| 358 | + /* | |
| 359 | + * Retire all pending LPIs on this vcpu anyway as we're | |
| 360 | + * going to destroy it. | |
| 361 | + */ | |
| 362 | + vgic_flush_pending_lpis(vcpu); | |
| 363 | + | |
| 351 | 364 | INIT_LIST_HEAD(&vgic_cpu->ap_list_head); |
| 352 | 365 | } |
| 353 | 366 | |
| @@ -359,10 +372,10 @@ static void __kvm_vgic_destroy(struct kvm *kvm) · 5 unmodified lines | ||
| 359 | 372 | |
| 360 | 373 | vgic_debug_destroy(kvm); |
| 361 | 374 | |
| 362 | − kvm_vgic_dist_destroy(kvm); | |
| 363 | − | |
| 364 | 375 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 365 | 376 | kvm_vgic_vcpu_destroy(vcpu); |
| 377 | + | |
| 378 | + kvm_vgic_dist_destroy(kvm); | |
| 366 | 379 | } |
| 367 | 380 | |
| 368 | 381 | void kvm_vgic_destroy(struct kvm *kvm) |
| @@ -96,14 +96,21 @@ out_unlock: · 95 unmodified lines | ||
| 96 | 96 | * We "cache" the configuration table entries in our struct vgic_irq's. |
| 97 | 97 | * However we only have those structs for mapped IRQs, so we read in |
| 98 | 98 | * the respective config data from memory here upon mapping the LPI. |
| 99 | + * | |
| 100 | + * Should any of these fail, behave as if we couldn't create the LPI | |
| 101 | + * by dropping the refcount and returning the error. | |
| 99 | 102 | */ |
| 100 | 103 | ret = update_lpi_config(kvm, irq, NULL, false); |
| 101 | − if (ret) | |
| 104 | + if (ret) { | |
| 105 | + vgic_put_irq(kvm, irq); | |
| 102 | 106 | return ERR_PTR(ret); |
| 107 | + } | |
| 103 | 108 | |
| 104 | 109 | ret = vgic_v3_lpi_sync_pending_status(kvm, irq); |
| 105 | − if (ret) | |
| 110 | + if (ret) { | |
| 111 | + vgic_put_irq(kvm, irq); | |
| 106 | 112 | return ERR_PTR(ret); |
| 113 | + } | |
| 107 | 114 | |
| 108 | 115 | return irq; |
| 109 | 116 | } |
| @@ -409,24 +409,28 @@ static const struct vgic_register_region vgic_v2_dist_registers[] = { · 408 unmodified lines | ||
| 409 | 409 | NULL, vgic_mmio_uaccess_write_v2_group, 1, |
| 410 | 410 | VGIC_ACCESS_32bit), |
| 411 | 411 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ENABLE_SET, |
| 412 | − vgic_mmio_read_enable, vgic_mmio_write_senable, NULL, NULL, 1, | |
| 412 | + vgic_mmio_read_enable, vgic_mmio_write_senable, | |
| 413 | + NULL, vgic_uaccess_write_senable, 1, | |
| 413 | 414 | VGIC_ACCESS_32bit), |
| 414 | 415 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ENABLE_CLEAR, |
| 415 | − vgic_mmio_read_enable, vgic_mmio_write_cenable, NULL, NULL, 1, | |
| 416 | + vgic_mmio_read_enable, vgic_mmio_write_cenable, | |
| 417 | + NULL, vgic_uaccess_write_cenable, 1, | |
| 416 | 418 | VGIC_ACCESS_32bit), |
| 417 | 419 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_SET, |
| 418 | − vgic_mmio_read_pending, vgic_mmio_write_spending, NULL, NULL, 1, | |
| 420 | + vgic_mmio_read_pending, vgic_mmio_write_spending, | |
| 421 | + NULL, vgic_uaccess_write_spending, 1, | |
| 419 | 422 | VGIC_ACCESS_32bit), |
| 420 | 423 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PENDING_CLEAR, |
| 421 | − vgic_mmio_read_pending, vgic_mmio_write_cpending, NULL, NULL, 1, | |
| 424 | + vgic_mmio_read_pending, vgic_mmio_write_cpending, | |
| 425 | + NULL, vgic_uaccess_write_cpending, 1, | |
| 422 | 426 | VGIC_ACCESS_32bit), |
| 423 | 427 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_SET, |
| 424 | 428 | vgic_mmio_read_active, vgic_mmio_write_sactive, |
| 425 | − NULL, vgic_mmio_uaccess_write_sactive, 1, | |
| 429 | + vgic_uaccess_read_active, vgic_mmio_uaccess_write_sactive, 1, | |
| 426 | 430 | VGIC_ACCESS_32bit), |
| 427 | 431 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ACTIVE_CLEAR, |
| 428 | 432 | vgic_mmio_read_active, vgic_mmio_write_cactive, |
| 429 | − NULL, vgic_mmio_uaccess_write_cactive, 1, | |
| 433 | + vgic_uaccess_read_active, vgic_mmio_uaccess_write_cactive, 1, | |
| 430 | 434 | VGIC_ACCESS_32bit), |
| 431 | 435 | REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_PRI, |
| 432 | 436 | vgic_mmio_read_priority, vgic_mmio_write_priority, NULL, NULL, |
| @@ -50,7 +50,8 @@ bool vgic_has_its(struct kvm *kvm) · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | bool vgic_supports_direct_msis(struct kvm *kvm) |
| 52 | 52 | { |
| 53 | − return kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm); | |
| 53 | + return (kvm_vgic_global_state.has_gicv4_1 || | |
| 54 | + (kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm))); | |
| 54 | 55 | } |
| 55 | 56 | |
| 56 | 57 | /* |
| @@ -538,10 +539,12 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = { · 481 unmodified lines | ||
| 538 | 539 | vgic_mmio_read_group, vgic_mmio_write_group, NULL, NULL, 1, |
| 539 | 540 | VGIC_ACCESS_32bit), |
| 540 | 541 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISENABLER, |
| 541 | − vgic_mmio_read_enable, vgic_mmio_write_senable, NULL, NULL, 1, | |
| 542 | + vgic_mmio_read_enable, vgic_mmio_write_senable, | |
| 543 | + NULL, vgic_uaccess_write_senable, 1, | |
| 542 | 544 | VGIC_ACCESS_32bit), |
| 543 | 545 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICENABLER, |
| 544 | − vgic_mmio_read_enable, vgic_mmio_write_cenable, NULL, NULL, 1, | |
| 546 | + vgic_mmio_read_enable, vgic_mmio_write_cenable, | |
| 547 | + NULL, vgic_uaccess_write_cenable, 1, | |
| 545 | 548 | VGIC_ACCESS_32bit), |
| 546 | 549 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISPENDR, |
| 547 | 550 | vgic_mmio_read_pending, vgic_mmio_write_spending, |
| @@ -553,11 +556,11 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = { · 5 unmodified lines | ||
| 553 | 556 | VGIC_ACCESS_32bit), |
| 554 | 557 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISACTIVER, |
| 555 | 558 | vgic_mmio_read_active, vgic_mmio_write_sactive, |
| 556 | − NULL, vgic_mmio_uaccess_write_sactive, 1, | |
| 559 | + vgic_uaccess_read_active, vgic_mmio_uaccess_write_sactive, 1, | |
| 557 | 560 | VGIC_ACCESS_32bit), |
| 558 | 561 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICACTIVER, |
| 559 | 562 | vgic_mmio_read_active, vgic_mmio_write_cactive, |
| 560 | − NULL, vgic_mmio_uaccess_write_cactive, | |
| 563 | + vgic_uaccess_read_active, vgic_mmio_uaccess_write_cactive, | |
| 561 | 564 | 1, VGIC_ACCESS_32bit), |
| 562 | 565 | REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IPRIORITYR, |
| 563 | 566 | vgic_mmio_read_priority, vgic_mmio_write_priority, NULL, NULL, |
| @@ -609,11 +612,13 @@ static const struct vgic_register_region vgic_v3_rd_registers[] = { · 45 unmodified lines | ||
| 609 | 612 | REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_IGROUPR0, |
| 610 | 613 | vgic_mmio_read_group, vgic_mmio_write_group, 4, |
| 611 | 614 | VGIC_ACCESS_32bit), |
| 612 | − REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_ISENABLER0, | |
| 613 | − vgic_mmio_read_enable, vgic_mmio_write_senable, 4, | |
| 615 | + REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISENABLER0, | |
| 616 | + vgic_mmio_read_enable, vgic_mmio_write_senable, | |
| 617 | + NULL, vgic_uaccess_write_senable, 4, | |
| 614 | 618 | VGIC_ACCESS_32bit), |
| 615 | − REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_ICENABLER0, | |
| 616 | − vgic_mmio_read_enable, vgic_mmio_write_cenable, 4, | |
| 619 | + REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICENABLER0, | |
| 620 | + vgic_mmio_read_enable, vgic_mmio_write_cenable, | |
| 621 | + NULL, vgic_uaccess_write_cenable, 4, | |
| 617 | 622 | VGIC_ACCESS_32bit), |
| 618 | 623 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISPENDR0, |
| 619 | 624 | vgic_mmio_read_pending, vgic_mmio_write_spending, |
| @@ -625,12 +630,12 @@ static const struct vgic_register_region vgic_v3_rd_registers[] = { · 5 unmodified lines | ||
| 625 | 630 | VGIC_ACCESS_32bit), |
| 626 | 631 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISACTIVER0, |
| 627 | 632 | vgic_mmio_read_active, vgic_mmio_write_sactive, |
| 628 | − NULL, vgic_mmio_uaccess_write_sactive, | |
| 629 | − 4, VGIC_ACCESS_32bit), | |
| 633 | + vgic_uaccess_read_active, vgic_mmio_uaccess_write_sactive, 4, | |
| 634 | + VGIC_ACCESS_32bit), | |
| 630 | 635 | REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICACTIVER0, |
| 631 | 636 | vgic_mmio_read_active, vgic_mmio_write_cactive, |
| 632 | − NULL, vgic_mmio_uaccess_write_cactive, | |
| 633 | − 4, VGIC_ACCESS_32bit), | |
| 637 | + vgic_uaccess_read_active, vgic_mmio_uaccess_write_cactive, 4, | |
| 638 | + VGIC_ACCESS_32bit), | |
| 634 | 639 | REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_IPRIORITYR0, |
| 635 | 640 | vgic_mmio_read_priority, vgic_mmio_write_priority, 32, |
| 636 | 641 | VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), |
| @@ -184,6 +184,48 @@ void vgic_mmio_write_cenable(struct kvm_vcpu *vcpu, · 183 unmodified lines | ||
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | +int vgic_uaccess_write_senable(struct kvm_vcpu *vcpu, | |
| 188 | + gpa_t addr, unsigned int len, | |
| 189 | + unsigned long val) | |
| 190 | +{ | |
| 191 | + u32 intid = VGIC_ADDR_TO_INTID(addr, 1); | |
| 192 | + int i; | |
| 193 | + unsigned long flags; | |
| 194 | + | |
| 195 | + for_each_set_bit(i, &val, len * 8) { | |
| 196 | + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); | |
| 197 | + | |
| 198 | + raw_spin_lock_irqsave(&irq->irq_lock, flags); | |
| 199 | + irq->enabled = true; | |
| 200 | + vgic_queue_irq_unlock(vcpu->kvm, irq, flags); | |
| 201 | + | |
| 202 | + vgic_put_irq(vcpu->kvm, irq); | |
| 203 | + } | |
| 204 | + | |
| 205 | + return 0; | |
| 206 | +} | |
| 207 | + | |
| 208 | +int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, | |
| 209 | + gpa_t addr, unsigned int len, | |
| 210 | + unsigned long val) | |
| 211 | +{ | |
| 212 | + u32 intid = VGIC_ADDR_TO_INTID(addr, 1); | |
| 213 | + int i; | |
| 214 | + unsigned long flags; | |
| 215 | + | |
| 216 | + for_each_set_bit(i, &val, len * 8) { | |
| 217 | + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); | |
| 218 | + | |
| 219 | + raw_spin_lock_irqsave(&irq->irq_lock, flags); | |
| 220 | + irq->enabled = false; | |
| 221 | + raw_spin_unlock_irqrestore(&irq->irq_lock, flags); | |
| 222 | + | |
| 223 | + vgic_put_irq(vcpu->kvm, irq); | |
| 224 | + } | |
| 225 | + | |
| 226 | + return 0; | |
| 227 | +} | |
| 228 | + | |
| 187 | 229 | unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, |
| 188 | 230 | gpa_t addr, unsigned int len) |
| 189 | 231 | { |
| @@ -219,17 +261,6 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, · 29 unmodified lines | ||
| 219 | 261 | return value; |
| 220 | 262 | } |
| 221 | 263 | |
| 222 | −/* Must be called with irq->irq_lock held */ | |
| 223 | −static void vgic_hw_irq_spending(struct kvm_vcpu *vcpu, struct vgic_irq *irq, | |
| 224 | − bool is_uaccess) | |
| 225 | −{ | |
| 226 | − if (is_uaccess) | |
| 227 | − return; | |
| 228 | − | |
| 229 | − irq->pending_latch = true; | |
| 230 | − vgic_irq_set_phys_active(irq, true); | |
| 231 | −} | |
| 232 | − | |
| 233 | 264 | static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq) |
| 234 | 265 | { |
| 235 | 266 | return (vgic_irq_is_sgi(irq->intid) && |
| @@ -240,7 +271,6 @@ void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, · 4 unmodified lines | ||
| 240 | 271 | gpa_t addr, unsigned int len, |
| 241 | 272 | unsigned long val) |
| 242 | 273 | { |
| 243 | − bool is_uaccess = !kvm_get_running_vcpu(); | |
| 244 | 274 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); |
| 245 | 275 | int i; |
| 246 | 276 | unsigned long flags; |
| @@ -270,22 +300,48 @@ void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, · 23 unmodified lines | ||
| 270 | 300 | continue; |
| 271 | 301 | } |
| 272 | 302 | |
| 303 | + irq->pending_latch = true; | |
| 273 | 304 | if (irq->hw) |
| 274 | − vgic_hw_irq_spending(vcpu, irq, is_uaccess); | |
| 275 | − else | |
| 276 | − irq->pending_latch = true; | |
| 305 | + vgic_irq_set_phys_active(irq, true); | |
| 306 | + | |
| 277 | 307 | vgic_queue_irq_unlock(vcpu->kvm, irq, flags); |
| 278 | 308 | vgic_put_irq(vcpu->kvm, irq); |
| 279 | 309 | } |
| 280 | 310 | } |
| 281 | 311 | |
| 282 | −/* Must be called with irq->irq_lock held */ | |
| 283 | −static void vgic_hw_irq_cpending(struct kvm_vcpu *vcpu, struct vgic_irq *irq, | |
| 284 | − bool is_uaccess) | |
| 312 | +int vgic_uaccess_write_spending(struct kvm_vcpu *vcpu, | |
| 313 | + gpa_t addr, unsigned int len, | |
| 314 | + unsigned long val) | |
| 285 | 315 | { |
| 286 | − if (is_uaccess) | |
| 287 | − return; | |
| 316 | + u32 intid = VGIC_ADDR_TO_INTID(addr, 1); | |
| 317 | + int i; | |
| 318 | + unsigned long flags; | |
| 319 | + | |
| 320 | + for_each_set_bit(i, &val, len * 8) { | |
| 321 | + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); | |
| 322 | + | |
| 323 | + raw_spin_lock_irqsave(&irq->irq_lock, flags); | |
| 324 | + irq->pending_latch = true; | |
| 288 | 325 | |
| 326 | + /* | |
| 327 | + * GICv2 SGIs are terribly broken. We can't restore | |
| 328 | + * the source of the interrupt, so just pick the vcpu | |
| 329 | + * itself as the source... | |
| 330 | + */ | |
| 331 | + if (is_vgic_v2_sgi(vcpu, irq)) | |
| 332 | + irq->source |= BIT(vcpu->vcpu_id); | |
| 333 | + | |
| 334 | + vgic_queue_irq_unlock(vcpu->kvm, irq, flags); | |
| 335 | + | |
| 336 | + vgic_put_irq(vcpu->kvm, irq); | |
| 337 | + } | |
| 338 | + | |
| 339 | + return 0; | |
| 340 | +} | |
| 341 | + | |
| 342 | +/* Must be called with irq->irq_lock held */ | |
| 343 | +static void vgic_hw_irq_cpending(struct kvm_vcpu *vcpu, struct vgic_irq *irq) | |
| 344 | +{ | |
| 289 | 345 | irq->pending_latch = false; |
| 290 | 346 | |
| 291 | 347 | /* |
| @@ -308,7 +364,6 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu, · 16 unmodified lines | ||
| 308 | 364 | gpa_t addr, unsigned int len, |
| 309 | 365 | unsigned long val) |
| 310 | 366 | { |
| 311 | − bool is_uaccess = !kvm_get_running_vcpu(); | |
| 312 | 367 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); |
| 313 | 368 | int i; |
| 314 | 369 | unsigned long flags; |
| @@ -339,7 +394,7 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu, · 24 unmodified lines | ||
| 339 | 394 | } |
| 340 | 395 | |
| 341 | 396 | if (irq->hw) |
| 342 | − vgic_hw_irq_cpending(vcpu, irq, is_uaccess); | |
| 397 | + vgic_hw_irq_cpending(vcpu, irq); | |
| 343 | 398 | else |
| 344 | 399 | irq->pending_latch = false; |
| 345 | 400 | |
| @@ -348,8 +403,68 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu, · 2 unmodified lines | ||
| 348 | 403 | } |
| 349 | 404 | } |
| 350 | 405 | |
| 351 | −unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu, | |
| 352 | − gpa_t addr, unsigned int len) | |
| 406 | +int vgic_uaccess_write_cpending(struct kvm_vcpu *vcpu, | |
| 407 | + gpa_t addr, unsigned int len, | |
| 408 | + unsigned long val) | |
| 409 | +{ | |
| 410 | + u32 intid = VGIC_ADDR_TO_INTID(addr, 1); | |
| 411 | + int i; | |
| 412 | + unsigned long flags; | |
| 413 | + | |
| 414 | + for_each_set_bit(i, &val, len * 8) { | |
| 415 | + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); | |
| 416 | + | |
| 417 | + raw_spin_lock_irqsave(&irq->irq_lock, flags); | |
| 418 | + /* | |
| 419 | + * More fun with GICv2 SGIs! If we're clearing one of them | |
| 420 | + * from userspace, which source vcpu to clear? Let's not | |
| 421 | + * even think of it, and blow the whole set. | |
| 422 | + */ | |
| 423 | + if (is_vgic_v2_sgi(vcpu, irq)) | |
| 424 | + irq->source = 0; | |
| 425 | + | |
| 426 | + irq->pending_latch = false; | |
| 427 | + | |
| 428 | + raw_spin_unlock_irqrestore(&irq->irq_lock, flags); | |
| 429 | + | |
| 430 | + vgic_put_irq(vcpu->kvm, irq); | |
| 431 | + } | |
| 432 | + | |
| 433 | + return 0; | |
| 434 | +} | |
| 435 | + | |
| 436 | +/* | |
| 437 | + * If we are fiddling with an IRQ's active state, we have to make sure the IRQ | |
| 438 | + * is not queued on some running VCPU's LRs, because then the change to the | |
| 439 | + * active state can be overwritten when the VCPU's state is synced coming back | |
| 440 | + * from the guest. | |
| 441 | + * | |
| 442 | + * For shared interrupts as well as GICv3 private interrupts, we have to | |
| 443 | + * stop all the VCPUs because interrupts can be migrated while we don't hold | |
| 444 | + * the IRQ locks and we don't want to be chasing moving targets. | |
| 445 | + * | |
| 446 | + * For GICv2 private interrupts we don't have to do anything because | |
| 447 | + * userspace accesses to the VGIC state already require all VCPUs to be | |
| 448 | + * stopped, and only the VCPU itself can modify its private interrupts | |
| 449 | + * active state, which guarantees that the VCPU is not running. | |
| 450 | + */ | |
| 451 | +static void vgic_access_active_prepare(struct kvm_vcpu *vcpu, u32 intid) | |
| 452 | +{ | |
| 453 | + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || | |
| 454 | + intid >= VGIC_NR_PRIVATE_IRQS) | |
| 455 | + kvm_arm_halt_guest(vcpu->kvm); | |
| 456 | +} | |
| 457 | + | |
| 458 | +/* See vgic_access_active_prepare */ | |
| 459 | +static void vgic_access_active_finish(struct kvm_vcpu *vcpu, u32 intid) | |
| 460 | +{ | |
| 461 | + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || | |
| 462 | + intid >= VGIC_NR_PRIVATE_IRQS) | |
| 463 | + kvm_arm_resume_guest(vcpu->kvm); | |
| 464 | +} | |
| 465 | + | |
| 466 | +static unsigned long __vgic_mmio_read_active(struct kvm_vcpu *vcpu, | |
| 467 | + gpa_t addr, unsigned int len) | |
| 353 | 468 | { |
| 354 | 469 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); |
| 355 | 470 | u32 value = 0; |
| @@ -359,6 +474,10 @@ unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu, · 3 unmodified lines | ||
| 359 | 474 | for (i = 0; i < len * 8; i++) { |
| 360 | 475 | struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); |
| 361 | 476 | |
| 477 | + /* | |
| 478 | + * Even for HW interrupts, don't evaluate the HW state as | |
| 479 | + * all the guest is interested in is the virtual state. | |
| 480 | + */ | |
| 362 | 481 | if (irq->active) |
| 363 | 482 | value |= (1U << i); |
| 364 | 483 | |
| @@ -368,6 +487,29 @@ unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu, · 3 unmodified lines | ||
| 368 | 487 | return value; |
| 369 | 488 | } |
| 370 | 489 | |
| 490 | +unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu, | |
| 491 | + gpa_t addr, unsigned int len) | |
| 492 | +{ | |
| 493 | + u32 intid = VGIC_ADDR_TO_INTID(addr, 1); | |
| 494 | + u32 val; | |
| 495 | + | |
| 496 | + mutex_lock(&vcpu->kvm->lock); | |
| 497 | + vgic_access_active_prepare(vcpu, intid); | |
| 498 | + | |
| 499 | + val = __vgic_mmio_read_active(vcpu, addr, len); | |
| 500 | + | |
| 501 | + vgic_access_active_finish(vcpu, intid); | |
| 502 | + mutex_unlock(&vcpu->kvm->lock); | |
| 503 | + | |
| 504 | + return val; | |
| 505 | +} | |
| 506 | + | |
| 507 | +unsigned long vgic_uaccess_read_active(struct kvm_vcpu *vcpu, | |
| 508 | + gpa_t addr, unsigned int len) | |
| 509 | +{ | |
| 510 | + return __vgic_mmio_read_active(vcpu, addr, len); | |
| 511 | +} | |
| 512 | + | |
| 371 | 513 | /* Must be called with irq->irq_lock held */ |
| 372 | 514 | static void vgic_hw_irq_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, |
| 373 | 515 | bool active, bool is_uaccess) |
| @@ -426,36 +568,6 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq, · 52 unmodified lines | ||
| 426 | 568 | raw_spin_unlock_irqrestore(&irq->irq_lock, flags); |
| 427 | 569 | } |
| 428 | 570 | |
| 429 | −/* | |
| 430 | − * If we are fiddling with an IRQ's active state, we have to make sure the IRQ | |
| 431 | − * is not queued on some running VCPU's LRs, because then the change to the | |
| 432 | − * active state can be overwritten when the VCPU's state is synced coming back | |
| 433 | − * from the guest. | |
| 434 | − * | |
| 435 | − * For shared interrupts, we have to stop all the VCPUs because interrupts can | |
| 436 | − * be migrated while we don't hold the IRQ locks and we don't want to be | |
| 437 | − * chasing moving targets. | |
| 438 | − * | |
| 439 | − * For private interrupts we don't have to do anything because userspace | |
| 440 | − * accesses to the VGIC state already require all VCPUs to be stopped, and | |
| 441 | − * only the VCPU itself can modify its private interrupts active state, which | |
| 442 | − * guarantees that the VCPU is not running. | |
| 443 | − */ | |
| 444 | −static void vgic_change_active_prepare(struct kvm_vcpu *vcpu, u32 intid) | |
| 445 | −{ | |
| 446 | − if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || | |
| 447 | − intid > VGIC_NR_PRIVATE_IRQS) | |
| 448 | − kvm_arm_halt_guest(vcpu->kvm); | |
| 449 | −} | |
| 450 | − | |
| 451 | −/* See vgic_change_active_prepare */ | |
| 452 | −static void vgic_change_active_finish(struct kvm_vcpu *vcpu, u32 intid) | |
| 453 | −{ | |
| 454 | − if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3 || | |
| 455 | − intid > VGIC_NR_PRIVATE_IRQS) | |
| 456 | − kvm_arm_resume_guest(vcpu->kvm); | |
| 457 | −} | |
| 458 | − | |
| 459 | 571 | static void __vgic_mmio_write_cactive(struct kvm_vcpu *vcpu, |
| 460 | 572 | gpa_t addr, unsigned int len, |
| 461 | 573 | unsigned long val) |
| @@ -477,11 +589,11 @@ void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu, · 15 unmodified lines | ||
| 477 | 589 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); |
| 478 | 590 | |
| 479 | 591 | mutex_lock(&vcpu->kvm->lock); |
| 480 | − vgic_change_active_prepare(vcpu, intid); | |
| 592 | + vgic_access_active_prepare(vcpu, intid); | |
| 481 | 593 | |
| 482 | 594 | __vgic_mmio_write_cactive(vcpu, addr, len, val); |
| 483 | 595 | |
| 484 | − vgic_change_active_finish(vcpu, intid); | |
| 596 | + vgic_access_active_finish(vcpu, intid); | |
| 485 | 597 | mutex_unlock(&vcpu->kvm->lock); |
| 486 | 598 | } |
| 487 | 599 | |
| @@ -514,11 +626,11 @@ void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu, · 26 unmodified lines | ||
| 514 | 626 | u32 intid = VGIC_ADDR_TO_INTID(addr, 1); |
| 515 | 627 | |
| 516 | 628 | mutex_lock(&vcpu->kvm->lock); |
| 517 | − vgic_change_active_prepare(vcpu, intid); | |
| 629 | + vgic_access_active_prepare(vcpu, intid); | |
| 518 | 630 | |
| 519 | 631 | __vgic_mmio_write_sactive(vcpu, addr, len, val); |
| 520 | 632 | |
| 521 | − vgic_change_active_finish(vcpu, intid); | |
| 633 | + vgic_access_active_finish(vcpu, intid); | |
| 522 | 634 | mutex_unlock(&vcpu->kvm->lock); |
| 523 | 635 | } |
| 524 | 636 | |
| @@ -138,6 +138,14 @@ void vgic_mmio_write_cenable(struct kvm_vcpu *vcpu, · 137 unmodified lines | ||
| 138 | 138 | gpa_t addr, unsigned int len, |
| 139 | 139 | unsigned long val); |
| 140 | 140 | |
| 141 | +int vgic_uaccess_write_senable(struct kvm_vcpu *vcpu, | |
| 142 | + gpa_t addr, unsigned int len, | |
| 143 | + unsigned long val); | |
| 144 | + | |
| 145 | +int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, | |
| 146 | + gpa_t addr, unsigned int len, | |
| 147 | + unsigned long val); | |
| 148 | + | |
| 141 | 149 | unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, |
| 142 | 150 | gpa_t addr, unsigned int len); |
| 143 | 151 | |
| @@ -149,9 +157,20 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu, · 5 unmodified lines | ||
| 149 | 157 | gpa_t addr, unsigned int len, |
| 150 | 158 | unsigned long val); |
| 151 | 159 | |
| 160 | +int vgic_uaccess_write_spending(struct kvm_vcpu *vcpu, | |
| 161 | + gpa_t addr, unsigned int len, | |
| 162 | + unsigned long val); | |
| 163 | + | |
| 164 | +int vgic_uaccess_write_cpending(struct kvm_vcpu *vcpu, | |
| 165 | + gpa_t addr, unsigned int len, | |
| 166 | + unsigned long val); | |
| 167 | + | |
| 152 | 168 | unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu, |
| 153 | 169 | gpa_t addr, unsigned int len); |
| 154 | 170 | |
| 171 | +unsigned long vgic_uaccess_read_active(struct kvm_vcpu *vcpu, | |
| 172 | + gpa_t addr, unsigned int len); | |
| 173 | + | |
| 155 | 174 | void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu, |
| 156 | 175 | gpa_t addr, unsigned int len, |
| 157 | 176 | unsigned long val); |