Linux 4.17-rc4 * tag 'v4.17-rc4': (920 commits) Linux 4.17-rc4 KVM: x86: remove APIC Timer periodic/oneshot spikes genksyms: fix typo in parse.tab.{c,h} generation rules kbuild: replace hardcoded bison in cmd_bison_h with $(YACC) gcc-plugins: fix build condition of SANCOV plugin MAINTAINERS: Update Kbuild entry with a few paths Revert "usb: host: ehci: Use dma_pool_zalloc()" platform/x86: Kconfig: Fix dell-laptop dependency chain. platform/x86: asus-wireless: Fix NULL pointer dereference arm64: vgic-v2: Fix proxying of cpuif access KVM: arm/arm64: vgic_init: Cleanup reference to process_maintenance KVM: arm64: Fix order of vcpu_write_sys_reg() arguments MAINTAINERS & files: Canonize the e-mails I use at files media: imx-media-csi: Fix inconsistent IS_ERR and PTR_ERR tools: power/acpi, revert to LD = gcc bdi: Fix oops in wb_workfn() RDMA/cma: Do not query GID during QP state transition to RTR IB/mlx4: Fix integer overflow when calculating optimal MTT size IB/hfi1: Fix memory leak in exception path in get_irq_affinity() IB/{hfi1, rdmavt}: Fix memory leak in hfi1_alloc_devdata() upon failure ...
Unified · Split
| @@ -557,6 +557,14 @@ A: Although LLVM IR generation and optimization try to stay architecture · 556 unmodified lines | ||
| 557 | 557 | pulls in some header files containing file scope host assembly codes. |
| 558 | 558 | - You can add "-fno-jump-tables" to work around the switch table issue. |
| 559 | 559 | |
| 560 | − Otherwise, you can use bpf target. | |
| 560 | + Otherwise, you can use bpf target. Additionally, you _must_ use bpf target | |
| 561 | + when: | |
| 562 | + | |
| 563 | + - Your program uses data structures with pointer or long / unsigned long | |
| 564 | + types that interface with BPF helpers or context data structures. Access | |
| 565 | + into these structures is verified by the BPF verifier and may result | |
| 566 | + in verification failures if the native architecture is not aligned with | |
| 567 | + the BPF architecture, e.g. 64-bit. An example of this is | |
| 568 | + BPF_PROG_TYPE_SK_MSG require '-target bpf' | |
| 561 | 569 | |
| 562 | 570 | Happy BPF hacking! |
| @@ -136,6 +136,19 @@ Sorting · 135 unmodified lines | ||
| 136 | 136 | .. kernel-doc:: lib/list_sort.c |
| 137 | 137 | :export: |
| 138 | 138 | |
| 139 | +Text Searching | |
| 140 | +-------------- | |
| 141 | + | |
| 142 | +.. kernel-doc:: lib/textsearch.c | |
| 143 | + :doc: ts_intro | |
| 144 | + | |
| 145 | +.. kernel-doc:: lib/textsearch.c | |
| 146 | + :export: | |
| 147 | + | |
| 148 | +.. kernel-doc:: include/linux/textsearch.h | |
| 149 | + :functions: textsearch_find textsearch_next \ | |
| 150 | + textsearch_get_pattern textsearch_get_pattern_len | |
| 151 | + | |
| 139 | 152 | UUID/GUID |
| 140 | 153 | --------- |
| 141 | 154 | |
| @@ -4,6 +4,13 @@ Required properties: · 3 unmodified lines | ||
| 4 | 4 | - compatible: |
| 5 | 5 | atmel,maxtouch |
| 6 | 6 | |
| 7 | + The following compatibles have been used in various products but are | |
| 8 | + deprecated: | |
| 9 | + atmel,qt602240_ts | |
| 10 | + atmel,atmel_mxt_ts | |
| 11 | + atmel,atmel_mxt_tp | |
| 12 | + atmel,mXT224 | |
| 13 | + | |
| 7 | 14 | - reg: The I2C address of the device |
| 8 | 15 | |
| 9 | 16 | - interrupts: The sink for the touchpad's IRQ output |
| @@ -21,7 +21,7 @@ Required properties: · 20 unmodified lines | ||
| 21 | 21 | - interrupts : identifier to the device interrupt |
| 22 | 22 | - clocks : a list of phandle + clock-specifier pairs, one for each |
| 23 | 23 | entry in clock names. |
| 24 | −- clocks-names : | |
| 24 | +- clock-names : | |
| 25 | 25 | * "xtal" for external xtal clock identifier |
| 26 | 26 | * "pclk" for the bus core clock, either the clk81 clock or the gate clock |
| 27 | 27 | * "baud" for the source of the baudrate generator, can be either the xtal |
| @@ -24,7 +24,7 @@ Required properties: · 23 unmodified lines | ||
| 24 | 24 | - Must contain two elements for the extended variant of the IP |
| 25 | 25 | (marvell,armada-3700-uart-ext): "uart-tx" and "uart-rx", |
| 26 | 26 | respectively the UART TX interrupt and the UART RX interrupt. A |
| 27 | − corresponding interrupts-names property must be defined. | |
| 27 | + corresponding interrupt-names property must be defined. | |
| 28 | 28 | - For backward compatibility reasons, a single element interrupts |
| 29 | 29 | property is also supported for the standard variant of the IP, |
| 30 | 30 | containing only the UART sum interrupt. This form is deprecated |
| @@ -17,6 +17,8 @@ Required properties: · 16 unmodified lines | ||
| 17 | 17 | - "renesas,scifa-r8a7745" for R8A7745 (RZ/G1E) SCIFA compatible UART. |
| 18 | 18 | - "renesas,scifb-r8a7745" for R8A7745 (RZ/G1E) SCIFB compatible UART. |
| 19 | 19 | - "renesas,hscif-r8a7745" for R8A7745 (RZ/G1E) HSCIF compatible UART. |
| 20 | + - "renesas,scif-r8a77470" for R8A77470 (RZ/G1C) SCIF compatible UART. | |
| 21 | + - "renesas,hscif-r8a77470" for R8A77470 (RZ/G1C) HSCIF compatible UART. | |
| 20 | 22 | - "renesas,scif-r8a7778" for R8A7778 (R-Car M1) SCIF compatible UART. |
| 21 | 23 | - "renesas,scif-r8a7779" for R8A7779 (R-Car H1) SCIF compatible UART. |
| 22 | 24 | - "renesas,scif-r8a7790" for R8A7790 (R-Car H2) SCIF compatible UART. |
| @@ -49,19 +49,6 @@ on the SoC (only first trip points defined in DT will be configured): · 48 unmodified lines | ||
| 49 | 49 | - samsung,exynos5433-tmu: 8 |
| 50 | 50 | - samsung,exynos7-tmu: 8 |
| 51 | 51 | |
| 52 | −Following properties are mandatory (depending on SoC): | |
| 53 | −- samsung,tmu_gain: Gain value for internal TMU operation. | |
| 54 | −- samsung,tmu_reference_voltage: Value of TMU IP block's reference voltage | |
| 55 | −- samsung,tmu_noise_cancel_mode: Mode for noise cancellation | |
| 56 | −- samsung,tmu_efuse_value: Default level of temperature - it is needed when | |
| 57 | − in factory fusing produced wrong value | |
| 58 | −- samsung,tmu_min_efuse_value: Minimum temperature fused value | |
| 59 | −- samsung,tmu_max_efuse_value: Maximum temperature fused value | |
| 60 | −- samsung,tmu_first_point_trim: First point trimming value | |
| 61 | −- samsung,tmu_second_point_trim: Second point trimming value | |
| 62 | −- samsung,tmu_default_temp_offset: Default temperature offset | |
| 63 | −- samsung,tmu_cal_type: Callibration type | |
| 64 | − | |
| 65 | 52 | ** Optional properties: |
| 66 | 53 | |
| 67 | 54 | - vtmu-supply: This entry is optional and provides the regulator node supplying |
| @@ -78,7 +65,7 @@ Example 1): · 10 unmodified lines | ||
| 78 | 65 | clocks = <&clock 383>; |
| 79 | 66 | clock-names = "tmu_apbif"; |
| 80 | 67 | vtmu-supply = <&tmu_regulator_node>; |
| 81 | − #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 68 | + #thermal-sensor-cells = <0>; | |
| 82 | 69 | }; |
| 83 | 70 | |
| 84 | 71 | Example 2): |
| @@ -89,7 +76,7 @@ Example 2): · 4 unmodified lines | ||
| 89 | 76 | interrupts = <0 58 0>; |
| 90 | 77 | clocks = <&clock 21>; |
| 91 | 78 | clock-names = "tmu_apbif"; |
| 92 | − #include "exynos5440-tmu-sensor-conf.dtsi" | |
| 79 | + #thermal-sensor-cells = <0>; | |
| 93 | 80 | }; |
| 94 | 81 | |
| 95 | 82 | Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register") |
| @@ -99,7 +86,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register") · 3 unmodified lines | ||
| 99 | 86 | interrupts = <0 184 0>; |
| 100 | 87 | clocks = <&clock 318>, <&clock 318>; |
| 101 | 88 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
| 102 | − #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 89 | + #thermal-sensor-cells = <0>; | |
| 103 | 90 | }; |
| 104 | 91 | |
| 105 | 92 | tmu_cpu3: tmu@1006c000 { |
| @@ -108,7 +95,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register") · 2 unmodified lines | ||
| 108 | 95 | interrupts = <0 185 0>; |
| 109 | 96 | clocks = <&clock 318>, <&clock 319>; |
| 110 | 97 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
| 111 | − #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 98 | + #thermal-sensor-cells = <0>; | |
| 112 | 99 | }; |
| 113 | 100 | |
| 114 | 101 | tmu_gpu: tmu@100a0000 { |
| @@ -117,7 +104,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register") · 2 unmodified lines | ||
| 117 | 104 | interrupts = <0 215 0>; |
| 118 | 105 | clocks = <&clock 319>, <&clock 318>; |
| 119 | 106 | clock-names = "tmu_apbif", "tmu_triminfo_apbif"; |
| 120 | − #include "exynos4412-tmu-sensor-conf.dtsi" | |
| 107 | + #thermal-sensor-cells = <0>; | |
| 121 | 108 | }; |
| 122 | 109 | |
| 123 | 110 | Note: For multi-instance tmu each instance should have an alias correctly |
| @@ -55,8 +55,7 @@ of heat dissipation). For example a fan's cooling states correspond to · 54 unmodified lines | ||
| 55 | 55 | the different fan speeds possible. Cooling states are referred to by |
| 56 | 56 | single unsigned integers, where larger numbers mean greater heat |
| 57 | 57 | dissipation. The precise set of cooling states associated with a device |
| 58 | −(as referred to by the cooling-min-level and cooling-max-level | |
| 59 | −properties) should be defined in a particular device's binding. | |
| 58 | +should be defined in a particular device's binding. | |
| 60 | 59 | For more examples of cooling devices, refer to the example sections below. |
| 61 | 60 | |
| 62 | 61 | Required properties: |
| @@ -69,15 +68,6 @@ Required properties: · 6 unmodified lines | ||
| 69 | 68 | See Cooling device maps section below for more details |
| 70 | 69 | on how consumers refer to cooling devices. |
| 71 | 70 | |
| 72 | −Optional properties: | |
| 73 | −- cooling-min-level: An integer indicating the smallest | |
| 74 | − Type: unsigned cooling state accepted. Typically 0. | |
| 75 | − Size: one cell | |
| 76 | − | |
| 77 | −- cooling-max-level: An integer indicating the largest | |
| 78 | − Type: unsigned cooling state accepted. | |
| 79 | − Size: one cell | |
| 80 | − | |
| 81 | 71 | * Trip points |
| 82 | 72 | |
| 83 | 73 | The trip node is a node to describe a point in the temperature domain |
| @@ -226,8 +216,6 @@ cpus { · 142 unmodified lines | ||
| 226 | 216 | 396000 950000 |
| 227 | 217 | 198000 850000 |
| 228 | 218 | >; |
| 229 | − cooling-min-level = <0>; | |
| 230 | − cooling-max-level = <3>; | |
| 231 | 219 | #cooling-cells = <2>; /* min followed by max */ |
| 232 | 220 | }; |
| 233 | 221 | ... |
| @@ -241,8 +229,6 @@ cpus { · 7 unmodified lines | ||
| 241 | 229 | */ |
| 242 | 230 | fan0: fan@48 { |
| 243 | 231 | ... |
| 244 | − cooling-min-level = <0>; | |
| 245 | − cooling-max-level = <9>; | |
| 246 | 232 | #cooling-cells = <2>; /* min followed by max */ |
| 247 | 233 | }; |
| 248 | 234 | }; |
| @@ -0,0 +1,21 @@ | ||
| 1 | +Nuvoton NPCM7xx timer | |
| 2 | + | |
| 3 | +Nuvoton NPCM7xx have three timer modules, each timer module provides five 24-bit | |
| 4 | +timer counters. | |
| 5 | + | |
| 6 | +Required properties: | |
| 7 | +- compatible : "nuvoton,npcm750-timer" for Poleg NPCM750. | |
| 8 | +- reg : Offset and length of the register set for the device. | |
| 9 | +- interrupts : Contain the timer interrupt with flags for | |
| 10 | + falling edge. | |
| 11 | +- clocks : phandle of timer reference clock (usually a 25 MHz clock). | |
| 12 | + | |
| 13 | +Example: | |
| 14 | + | |
| 15 | +timer@f0008000 { | |
| 16 | + compatible = "nuvoton,npcm750-timer"; | |
| 17 | + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; | |
| 18 | + reg = <0xf0008000 0x50>; | |
| 19 | + clocks = <&clk NPCM7XX_CLK_TIMER>; | |
| 20 | +}; | |
| 21 | + | |
| @@ -15,7 +15,7 @@ Required properties: · 14 unmodified lines | ||
| 15 | 15 | - interrupts : Should be the clock event device interrupt. |
| 16 | 16 | - clocks : The clocks provided by the SoC to drive the timer, must contain |
| 17 | 17 | an entry for each entry in clock-names. |
| 18 | −- clock-names : Must include the following entries: "igp" and "per". | |
| 18 | +- clock-names : Must include the following entries: "ipg" and "per". | |
| 19 | 19 | |
| 20 | 20 | Example: |
| 21 | 21 | tpm5: tpm@40260000 { |
| @@ -28,7 +28,10 @@ Required properties: · 27 unmodified lines | ||
| 28 | 28 | - interrupts: one XHCI interrupt should be described here. |
| 29 | 29 | |
| 30 | 30 | Optional properties: |
| 31 | − - clocks: reference to a clock | |
| 31 | + - clocks: reference to the clocks | |
| 32 | + - clock-names: mandatory if there is a second clock, in this case | |
| 33 | + the name must be "core" for the first clock and "reg" for the | |
| 34 | + second one | |
| 32 | 35 | - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM |
| 33 | 36 | - usb3-lpm-capable: determines if platform is USB3 LPM capable |
| 34 | 37 | - quirk-broken-port-ped: set if the controller has broken port disable mechanism |
| @@ -177,14 +177,14 @@ BUGS · 176 unmodified lines | ||
| 177 | 177 | **** |
| 178 | 178 | |
| 179 | 179 | |
| 180 | −Report bugs to Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 180 | +Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 181 | 181 | |
| 182 | 182 | |
| 183 | 183 | COPYRIGHT |
| 184 | 184 | ********* |
| 185 | 185 | |
| 186 | 186 | |
| 187 | −Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>. | |
| 187 | +Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. | |
| 188 | 188 | |
| 189 | 189 | License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. |
| 190 | 190 | |
| @@ -17,17 +17,17 @@ an error is returned. · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | request_firmware |
| 19 | 19 | ---------------- |
| 20 | −.. kernel-doc:: drivers/base/firmware_class.c | |
| 20 | +.. kernel-doc:: drivers/base/firmware_loader/main.c | |
| 21 | 21 | :functions: request_firmware |
| 22 | 22 | |
| 23 | 23 | request_firmware_direct |
| 24 | 24 | ----------------------- |
| 25 | −.. kernel-doc:: drivers/base/firmware_class.c | |
| 25 | +.. kernel-doc:: drivers/base/firmware_loader/main.c | |
| 26 | 26 | :functions: request_firmware_direct |
| 27 | 27 | |
| 28 | 28 | request_firmware_into_buf |
| 29 | 29 | ------------------------- |
| 30 | −.. kernel-doc:: drivers/base/firmware_class.c | |
| 30 | +.. kernel-doc:: drivers/base/firmware_loader/main.c | |
| 31 | 31 | :functions: request_firmware_into_buf |
| 32 | 32 | |
| 33 | 33 | Asynchronous firmware requests |
| @@ -41,7 +41,7 @@ in atomic contexts. · 7 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | request_firmware_nowait |
| 43 | 43 | ----------------------- |
| 44 | −.. kernel-doc:: drivers/base/firmware_class.c | |
| 44 | +.. kernel-doc:: drivers/base/firmware_loader/main.c | |
| 45 | 45 | :functions: request_firmware_nowait |
| 46 | 46 | |
| 47 | 47 | Special optimizations on reboot |
| @@ -50,12 +50,12 @@ Special optimizations on reboot · 2 unmodified lines | ||
| 50 | 50 | Some devices have an optimization in place to enable the firmware to be |
| 51 | 51 | retained during system reboot. When such optimizations are used the driver |
| 52 | 52 | author must ensure the firmware is still available on resume from suspend, |
| 53 | −this can be done with firmware_request_cache() insted of requesting for the | |
| 54 | −firmare to be loaded. | |
| 53 | +this can be done with firmware_request_cache() instead of requesting for the | |
| 54 | +firmware to be loaded. | |
| 55 | 55 | |
| 56 | 56 | firmware_request_cache() |
| 57 | −----------------------- | |
| 58 | −.. kernel-doc:: drivers/base/firmware_class.c | |
| 57 | +------------------------ | |
| 58 | +.. kernel-doc:: drivers/base/firmware_loader/main.c | |
| 59 | 59 | :functions: firmware_request_cache |
| 60 | 60 | |
| 61 | 61 | request firmware API expected driver use |
| @@ -28,7 +28,7 @@ Device Drivers Base · 27 unmodified lines | ||
| 28 | 28 | .. kernel-doc:: drivers/base/node.c |
| 29 | 29 | :internal: |
| 30 | 30 | |
| 31 | −.. kernel-doc:: drivers/base/firmware_class.c | |
| 31 | +.. kernel-doc:: drivers/base/firmware_loader/main.c | |
| 32 | 32 | :export: |
| 33 | 33 | |
| 34 | 34 | .. kernel-doc:: drivers/base/transport_class.c |
| @@ -210,7 +210,7 @@ If the connector is dual-role capable, there may also be a switch for the data · 209 unmodified lines | ||
| 210 | 210 | role. USB Type-C Connector Class does not supply separate API for them. The |
| 211 | 211 | port drivers can use USB Role Class API with those. |
| 212 | 212 | |
| 213 | −Illustration of the muxes behind a connector that supports an alternate mode: | |
| 213 | +Illustration of the muxes behind a connector that supports an alternate mode:: | |
| 214 | 214 | |
| 215 | 215 | ------------------------ |
| 216 | 216 | | Connector | |
| @@ -9,8 +9,8 @@ i2c adapters present on your system at a given time. i2cdetect is part of · 8 unmodified lines | ||
| 9 | 9 | the i2c-tools package. |
| 10 | 10 | |
| 11 | 11 | I2C device files are character device files with major device number 89 |
| 12 | −and a minor device number corresponding to the number assigned as | |
| 13 | −explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., | |
| 12 | +and a minor device number corresponding to the number assigned as | |
| 13 | +explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., | |
| 14 | 14 | i2c-10, ...). All 256 minor device numbers are reserved for i2c. |
| 15 | 15 | |
| 16 | 16 | |
| @@ -23,11 +23,6 @@ First, you need to include these two headers: · 6 unmodified lines | ||
| 23 | 23 | #include <linux/i2c-dev.h> |
| 24 | 24 | #include <i2c/smbus.h> |
| 25 | 25 | |
| 26 | −(Please note that there are two files named "i2c-dev.h" out there. One is | |
| 27 | −distributed with the Linux kernel and the other one is included in the | |
| 28 | −source tree of i2c-tools. They used to be different in content but since 2012 | |
| 29 | −they're identical. You should use "linux/i2c-dev.h"). | |
| 30 | − | |
| 31 | 26 | Now, you have to decide which adapter you want to access. You should |
| 32 | 27 | inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this. |
| 33 | 28 | Adapter numbers are assigned somewhat dynamically, so you can not |
| @@ -38,7 +33,7 @@ Next thing, open the device file, as follows: · 4 unmodified lines | ||
| 38 | 33 | int file; |
| 39 | 34 | int adapter_nr = 2; /* probably dynamically determined */ |
| 40 | 35 | char filename[20]; |
| 41 | − | |
| 36 | + | |
| 42 | 37 | snprintf(filename, 19, "/dev/i2c-%d", adapter_nr); |
| 43 | 38 | file = open(filename, O_RDWR); |
| 44 | 39 | if (file < 0) { |
| @@ -72,8 +67,10 @@ the device supports them. Both are illustrated below. · 27 unmodified lines | ||
| 72 | 67 | /* res contains the read word */ |
| 73 | 68 | } |
| 74 | 69 | |
| 75 | − /* Using I2C Write, equivalent of | |
| 76 | − i2c_smbus_write_word_data(file, reg, 0x6543) */ | |
| 70 | + /* | |
| 71 | + * Using I2C Write, equivalent of | |
| 72 | + * i2c_smbus_write_word_data(file, reg, 0x6543) | |
| 73 | + */ | |
| 77 | 74 | buf[0] = reg; |
| 78 | 75 | buf[1] = 0x43; |
| 79 | 76 | buf[2] = 0x65; |
| @@ -140,14 +137,14 @@ ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset) · 60 unmodified lines | ||
| 140 | 137 | set in each message, overriding the values set with the above ioctl's. |
| 141 | 138 | |
| 142 | 139 | ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args) |
| 143 | − Not meant to be called directly; instead, use the access functions | |
| 144 | − below. | |
| 140 | + If possible, use the provided i2c_smbus_* methods described below instead | |
| 141 | + of issuing direct ioctls. | |
| 145 | 142 | |
| 146 | 143 | You can do plain i2c transactions by using read(2) and write(2) calls. |
| 147 | 144 | You do not need to pass the address byte; instead, set it through |
| 148 | 145 | ioctl I2C_SLAVE before you try to access the device. |
| 149 | 146 | |
| 150 | −You can do SMBus level transactions (see documentation file smbus-protocol | |
| 147 | +You can do SMBus level transactions (see documentation file smbus-protocol | |
| 151 | 148 | for details) through the following functions: |
| 152 | 149 | __s32 i2c_smbus_write_quick(int file, __u8 value); |
| 153 | 150 | __s32 i2c_smbus_read_byte(int file); |
| @@ -158,7 +155,7 @@ for details) through the following functions: · 4 unmodified lines | ||
| 158 | 155 | __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value); |
| 159 | 156 | __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value); |
| 160 | 157 | __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values); |
| 161 | − __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, | |
| 158 | + __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, | |
| 162 | 159 | __u8 *values); |
| 163 | 160 | All these transactions return -1 on failure; you can read errno to see |
| 164 | 161 | what happened. The 'write' transactions return 0 on success; the |
| @@ -166,10 +163,9 @@ what happened. The 'write' transactions return 0 on success; the · 1 unmodified line | ||
| 166 | 163 | returns the number of values read. The block buffers need not be longer |
| 167 | 164 | than 32 bytes. |
| 168 | 165 | |
| 169 | −The above functions are all inline functions, that resolve to calls to | |
| 170 | −the i2c_smbus_access function, that on its turn calls a specific ioctl | |
| 171 | −with the data in a specific format. Read the source code if you | |
| 172 | −want to know what happens behind the screens. | |
| 166 | +The above functions are made available by linking against the libi2c library, | |
| 167 | +which is provided by the i2c-tools project. See: | |
| 168 | +https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/. | |
| 173 | 169 | |
| 174 | 170 | |
| 175 | 171 | Implementation details |
| @@ -217,7 +217,6 @@ Code Seq#(hex) Include File Comments · 216 unmodified lines | ||
| 217 | 217 | 'd' 02-40 pcmcia/ds.h conflict! |
| 218 | 218 | 'd' F0-FF linux/digi1.h |
| 219 | 219 | 'e' all linux/digi1.h conflict! |
| 220 | −'e' 00-1F drivers/net/irda/irtty-sir.h conflict! | |
| 221 | 220 | 'f' 00-1F linux/ext2_fs.h conflict! |
| 222 | 221 | 'f' 00-1F linux/ext3_fs.h conflict! |
| 223 | 222 | 'f' 00-0F fs/jfs/jfs_dinode.h conflict! |
| @@ -247,7 +246,6 @@ Code Seq#(hex) Include File Comments · 23 unmodified lines | ||
| 247 | 246 | 'm' all linux/synclink.h conflict! |
| 248 | 247 | 'm' 00-19 drivers/message/fusion/mptctl.h conflict! |
| 249 | 248 | 'm' 00 drivers/scsi/megaraid/megaraid_ioctl.h conflict! |
| 250 | −'m' 00-1F net/irda/irmod.h conflict! | |
| 251 | 249 | 'n' 00-7F linux/ncp_fs.h and fs/ncpfs/ioctl.c |
| 252 | 250 | 'n' 80-8F uapi/linux/nilfs2_api.h NILFS2 |
| 253 | 251 | 'n' E0-FF linux/matroxfb.h matroxfb |
| @@ -34,9 +34,13 @@ meta-data and shadow-data: · 33 unmodified lines | ||
| 34 | 34 | - data[] - storage for shadow data |
| 35 | 35 | |
| 36 | 36 | It is important to note that the klp_shadow_alloc() and |
| 37 | −klp_shadow_get_or_alloc() calls, described below, store a *copy* of the | |
| 38 | −data that the functions are provided. Callers should provide whatever | |
| 39 | −mutual exclusion is required of the shadow data. | |
| 37 | +klp_shadow_get_or_alloc() are zeroing the variable by default. | |
| 38 | +They also allow to call a custom constructor function when a non-zero | |
| 39 | +value is needed. Callers should provide whatever mutual exclusion | |
| 40 | +is required. | |
| 41 | + | |
| 42 | +Note that the constructor is called under klp_shadow_lock spinlock. It allows | |
| 43 | +to do actions that can be done only once when a new variable is allocated. | |
| 40 | 44 | |
| 41 | 45 | * klp_shadow_get() - retrieve a shadow variable data pointer |
| 42 | 46 | - search hashtable for <obj, id> pair |
| @@ -47,7 +51,7 @@ mutual exclusion is required of the shadow data. · 4 unmodified lines | ||
| 47 | 51 | - WARN and return NULL |
| 48 | 52 | - if <obj, id> doesn't already exist |
| 49 | 53 | - allocate a new shadow variable |
| 50 | − - copy data into the new shadow variable | |
| 54 | + - initialize the variable using a custom constructor and data when provided | |
| 51 | 55 | - add <obj, id> to the global hashtable |
| 52 | 56 | |
| 53 | 57 | * klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable |
| @@ -56,16 +60,20 @@ mutual exclusion is required of the shadow data. · 2 unmodified lines | ||
| 56 | 60 | - return existing shadow variable |
| 57 | 61 | - if <obj, id> doesn't already exist |
| 58 | 62 | - allocate a new shadow variable |
| 59 | − - copy data into the new shadow variable | |
| 63 | + - initialize the variable using a custom constructor and data when provided | |
| 60 | 64 | - add <obj, id> pair to the global hashtable |
| 61 | 65 | |
| 62 | 66 | * klp_shadow_free() - detach and free a <obj, id> shadow variable |
| 63 | 67 | - find and remove a <obj, id> reference from global hashtable |
| 64 | − - if found, free shadow variable | |
| 68 | + - if found | |
| 69 | + - call destructor function if defined | |
| 70 | + - free shadow variable | |
| 65 | 71 | |
| 66 | 72 | * klp_shadow_free_all() - detach and free all <*, id> shadow variables |
| 67 | 73 | - find and remove any <*, id> references from global hashtable |
| 68 | − - if found, free shadow variable | |
| 74 | + - if found | |
| 75 | + - call destructor function if defined | |
| 76 | + - free shadow variable | |
| 69 | 77 | |
| 70 | 78 | |
| 71 | 79 | 2. Use cases |
| @@ -107,7 +115,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, · 35 unmodified lines | ||
| 107 | 115 | sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); |
| 108 | 116 | |
| 109 | 117 | /* Attach a corresponding shadow variable, then initialize it */ |
| 110 | − ps_lock = klp_shadow_alloc(sta, PS_LOCK, NULL, sizeof(*ps_lock), gfp); | |
| 118 | + ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp, | |
| 119 | + NULL, NULL); | |
| 111 | 120 | if (!ps_lock) |
| 112 | 121 | goto shadow_fail; |
| 113 | 122 | spin_lock_init(ps_lock); |
| @@ -131,7 +140,7 @@ variable: · 17 unmodified lines | ||
| 131 | 140 | |
| 132 | 141 | void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) |
| 133 | 142 | { |
| 134 | − klp_shadow_free(sta, PS_LOCK); | |
| 143 | + klp_shadow_free(sta, PS_LOCK, NULL); | |
| 135 | 144 | kfree(sta); |
| 136 | 145 | ... |
| 137 | 146 | |
| @@ -148,16 +157,24 @@ shadow variables to parents already in-flight. · 10 unmodified lines | ||
| 148 | 157 | For commit 1d147bfa6429, a good spot to allocate a shadow spinlock is |
| 149 | 158 | inside ieee80211_sta_ps_deliver_wakeup(): |
| 150 | 159 | |
| 160 | +int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data) | |
| 161 | +{ | |
| 162 | + spinlock_t *lock = shadow_data; | |
| 163 | + | |
| 164 | + spin_lock_init(lock); | |
| 165 | + return 0; | |
| 166 | +} | |
| 167 | + | |
| 151 | 168 | #define PS_LOCK 1 |
| 152 | 169 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) |
| 153 | 170 | { |
| 154 | − DEFINE_SPINLOCK(ps_lock_fallback); | |
| 155 | 171 | spinlock_t *ps_lock; |
| 156 | 172 | |
| 157 | 173 | /* sync with ieee80211_tx_h_unicast_ps_buf */ |
| 158 | 174 | ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK, |
| 159 | − &ps_lock_fallback, sizeof(ps_lock_fallback), | |
| 160 | − GFP_ATOMIC); | |
| 175 | + sizeof(*ps_lock), GFP_ATOMIC, | |
| 176 | + ps_lock_shadow_ctor, NULL); | |
| 177 | + | |
| 161 | 178 | if (ps_lock) |
| 162 | 179 | spin_lock(ps_lock); |
| 163 | 180 | ... |
| @@ -7,7 +7,7 @@ file: uapi/v4l/keytable.c · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | /* keytable.c - This program allows checking/replacing keys at IR |
| 9 | 9 | |
| 10 | − Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 10 | + Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 11 | 11 | |
| 12 | 12 | This program is free software; you can redistribute it and/or modify |
| 13 | 13 | it under the terms of the GNU General Public License as published by |
| @@ -6,7 +6,7 @@ file: media/v4l/v4l2grab.c · 5 unmodified lines | ||
| 6 | 6 | .. code-block:: c |
| 7 | 7 | |
| 8 | 8 | /* V4L2 video picture grabber |
| 9 | − Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 9 | + Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 10 | 10 | |
| 11 | 11 | This program is free software; you can redistribute it and/or modify |
| 12 | 12 | it under the terms of the GNU General Public License as published by |
| @@ -169,7 +169,7 @@ access to BPF code as well. · 168 unmodified lines | ||
| 169 | 169 | BPF engine and instruction set |
| 170 | 170 | ------------------------------ |
| 171 | 171 | |
| 172 | −Under tools/net/ there's a small helper tool called bpf_asm which can | |
| 172 | +Under tools/bpf/ there's a small helper tool called bpf_asm which can | |
| 173 | 173 | be used to write low-level filters for example scenarios mentioned in the |
| 174 | 174 | previous section. Asm-like syntax mentioned here has been implemented in |
| 175 | 175 | bpf_asm and will be used for further explanations (instead of dealing with |
| @@ -359,7 +359,7 @@ $ ./bpf_asm -c foo · 183 unmodified lines | ||
| 359 | 359 | In particular, as usage with xt_bpf or cls_bpf can result in more complex BPF |
| 360 | 360 | filters that might not be obvious at first, it's good to test filters before |
| 361 | 361 | attaching to a live system. For that purpose, there's a small tool called |
| 362 | −bpf_dbg under tools/net/ in the kernel source directory. This debugger allows | |
| 362 | +bpf_dbg under tools/bpf/ in the kernel source directory. This debugger allows | |
| 363 | 363 | for testing BPF filters against given pcap files, single stepping through the |
| 364 | 364 | BPF code on the pcap's packets and to do BPF machine register dumps. |
| 365 | 365 | |
| @@ -483,7 +483,7 @@ Example output from dmesg: · 117 unmodified lines | ||
| 483 | 483 | [ 3389.935851] JIT code: 00000030: 00 e8 28 94 ff e0 83 f8 01 75 07 b8 ff ff 00 00 |
| 484 | 484 | [ 3389.935852] JIT code: 00000040: eb 02 31 c0 c9 c3 |
| 485 | 485 | |
| 486 | −In the kernel source tree under tools/net/, there's bpf_jit_disasm for | |
| 486 | +In the kernel source tree under tools/bpf/, there's bpf_jit_disasm for | |
| 487 | 487 | generating disassembly out of the kernel log's hexdump: |
| 488 | 488 | |
| 489 | 489 | # ./bpf_jit_disasm |
| @@ -1390,26 +1390,26 @@ mld_qrv - INTEGER · 1389 unmodified lines | ||
| 1390 | 1390 | Default: 2 (as specified by RFC3810 9.1) |
| 1391 | 1391 | Minimum: 1 (as specified by RFC6636 4.5) |
| 1392 | 1392 | |
| 1393 | −max_dst_opts_cnt - INTEGER | |
| 1393 | +max_dst_opts_number - INTEGER | |
| 1394 | 1394 | Maximum number of non-padding TLVs allowed in a Destination |
| 1395 | 1395 | options extension header. If this value is less than zero |
| 1396 | 1396 | then unknown options are disallowed and the number of known |
| 1397 | 1397 | TLVs allowed is the absolute value of this number. |
| 1398 | 1398 | Default: 8 |
| 1399 | 1399 | |
| 1400 | −max_hbh_opts_cnt - INTEGER | |
| 1400 | +max_hbh_opts_number - INTEGER | |
| 1401 | 1401 | Maximum number of non-padding TLVs allowed in a Hop-by-Hop |
| 1402 | 1402 | options extension header. If this value is less than zero |
| 1403 | 1403 | then unknown options are disallowed and the number of known |
| 1404 | 1404 | TLVs allowed is the absolute value of this number. |
| 1405 | 1405 | Default: 8 |
| 1406 | 1406 | |
| 1407 | −max dst_opts_len - INTEGER | |
| 1407 | +max_dst_opts_length - INTEGER | |
| 1408 | 1408 | Maximum length allowed for a Destination options extension |
| 1409 | 1409 | header. |
| 1410 | 1410 | Default: INT_MAX (unlimited) |
| 1411 | 1411 | |
| 1412 | −max hbh_opts_len - INTEGER | |
| 1412 | +max_hbh_length - INTEGER | |
| 1413 | 1413 | Maximum length allowed for a Hop-by-Hop options extension |
| 1414 | 1414 | header. |
| 1415 | 1415 | Default: INT_MAX (unlimited) |
| @@ -2126,18 +2126,3 @@ max_dgram_qlen - INTEGER · 710 unmodified lines | ||
| 2126 | 2126 | |
| 2127 | 2127 | Default: 10 |
| 2128 | 2128 | |
| 2129 | − | |
| 2130 | −UNDOCUMENTED: | |
| 2131 | − | |
| 2132 | −/proc/sys/net/irda/* | |
| 2133 | − fast_poll_increase FIXME | |
| 2134 | − warn_noreply_time FIXME | |
| 2135 | − discovery_slots FIXME | |
| 2136 | − slot_timeout FIXME | |
| 2137 | − max_baud_rate FIXME | |
| 2138 | − discovery_timeout FIXME | |
| 2139 | − lap_keepalive_time FIXME | |
| 2140 | − max_noreply_time FIXME | |
| 2141 | − max_tx_data_size FIXME | |
| 2142 | − max_tx_window FIXME | |
| 2143 | − min_tx_turn_time FIXME | |
| @@ -168,7 +168,7 @@ update on the CPUs, as discussed below: · 167 unmodified lines | ||
| 168 | 168 | |
| 169 | 169 | [Please bear in mind that the kernel requests the microcode images from |
| 170 | 170 | userspace, using the request_firmware() function defined in |
| 171 | −drivers/base/firmware_class.c] | |
| 171 | +drivers/base/firmware_loader/main.c] | |
| 172 | 172 | |
| 173 | 173 | |
| 174 | 174 | a. When all the CPUs are identical: |
| @@ -157,8 +157,5 @@ memory management. See ``include/sound/sndmagic.h`` for complete list of them. M · 156 unmodified lines | ||
| 157 | 157 | OSS sound drivers have their magic numbers constructed from the soundcard PCI |
| 158 | 158 | ID - these are not listed here as well. |
| 159 | 159 | |
| 160 | −IrDA subsystem also uses large number of own magic numbers, see | |
| 161 | −``include/net/irda/irda.h`` for a complete list of them. | |
| 162 | − | |
| 163 | 160 | HFS is another larger user of magic numbers - you can find them in |
| 164 | 161 | ``fs/hfs/hfs.h``. |
| @@ -387,11 +387,11 @@ tree for more details. · 386 unmodified lines | ||
| 387 | 387 | |
| 388 | 388 | =head1 BUGS |
| 389 | 389 | |
| 390 | −Report bugs to Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 390 | +Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 391 | 391 | |
| 392 | 392 | =head1 COPYRIGHT |
| 393 | 393 | |
| 394 | −Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>. | |
| 394 | +Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>. | |
| 395 | 395 | |
| 396 | 396 | License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>. |
| 397 | 397 | |
| @@ -461,9 +461,17 @@ of ftrace. Here is a list of some of the key files: · 460 unmodified lines | ||
| 461 | 461 | and ticks at the same rate as the hardware clocksource. |
| 462 | 462 | |
| 463 | 463 | boot: |
| 464 | − Same as mono. Used to be a separate clock which accounted | |
| 465 | − for the time spent in suspend while CLOCK_MONOTONIC did | |
| 466 | − not. | |
| 464 | + This is the boot clock (CLOCK_BOOTTIME) and is based on the | |
| 465 | + fast monotonic clock, but also accounts for time spent in | |
| 466 | + suspend. Since the clock access is designed for use in | |
| 467 | + tracing in the suspend path, some side effects are possible | |
| 468 | + if clock is accessed after the suspend time is accounted before | |
| 469 | + the fast mono clock is updated. In this case, the clock update | |
| 470 | + appears to happen slightly sooner than it normally would have. | |
| 471 | + Also on 32-bit systems, it's possible that the 64-bit boot offset | |
| 472 | + sees a partial update. These effects are rare and post | |
| 473 | + processing should be able to handle them. See comments in the | |
| 474 | + ktime_get_boot_fast_ns() function for more information. | |
| 467 | 475 | |
| 468 | 476 | To set a clock, simply echo the clock name into this file:: |
| 469 | 477 | |
| @@ -6,7 +6,7 @@ communicating in English you can also ask the Chinese maintainer for · 5 unmodified lines | ||
| 6 | 6 | help. Contact the Chinese maintainer if this translation is outdated |
| 7 | 7 | or if there is a problem with the translation. |
| 8 | 8 | |
| 9 | −Maintainer: Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 9 | +Maintainer: Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 10 | 10 | Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> |
| 11 | 11 | --------------------------------------------------------------------- |
| 12 | 12 | Documentation/video4linux/v4l2-framework.txt 的中文翻译 |
| @@ -14,7 +14,7 @@ Documentation/video4linux/v4l2-framework.txt 的中文翻译 · 1 unmodified line | ||
| 14 | 14 | 如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 |
| 15 | 15 | 交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 |
| 16 | 16 | 译存在问题,请联系中文版维护者。 |
| 17 | −英文版维护者: Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 17 | +英文版维护者: Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 18 | 18 | 中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> |
| 19 | 19 | 中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> |
| 20 | 20 | 中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> |
| @@ -1960,6 +1960,9 @@ ARM 32-bit VFP control registers have the following id bit patterns: · 1959 unmodified lines | ||
| 1960 | 1960 | ARM 64-bit FP registers have the following id bit patterns: |
| 1961 | 1961 | 0x4030 0000 0012 0 <regno:12> |
| 1962 | 1962 | |
| 1963 | +ARM firmware pseudo-registers have the following bit pattern: | |
| 1964 | + 0x4030 0000 0014 <regno:16> | |
| 1965 | + | |
| 1963 | 1966 | |
| 1964 | 1967 | arm64 registers are mapped using the lower 32 bits. The upper 16 of |
| 1965 | 1968 | that is the register group type, or coprocessor number: |
| @@ -1976,6 +1979,9 @@ arm64 CCSIDR registers are demultiplexed by CSSELR value: · 10 unmodified lines | ||
| 1976 | 1979 | arm64 system registers have the following id bit patterns: |
| 1977 | 1980 | 0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3> |
| 1978 | 1981 | |
| 1982 | +arm64 firmware pseudo-registers have the following bit pattern: | |
| 1983 | + 0x6030 0000 0014 <regno:16> | |
| 1984 | + | |
| 1979 | 1985 | |
| 1980 | 1986 | MIPS registers are mapped using the lower 32 bits. The upper 16 of that is |
| 1981 | 1987 | the register group type: |
| @@ -2510,7 +2516,8 @@ Possible features: · 528 unmodified lines | ||
| 2510 | 2516 | and execute guest code when KVM_RUN is called. |
| 2511 | 2517 | - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode. |
| 2512 | 2518 | Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only). |
| 2513 | − - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU. | |
| 2519 | + - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 (or a future revision | |
| 2520 | + backward compatible with v0.2) for the CPU. | |
| 2514 | 2521 | Depends on KVM_CAP_ARM_PSCI_0_2. |
| 2515 | 2522 | - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU. |
| 2516 | 2523 | Depends on KVM_CAP_ARM_PMU_V3. |
| @@ -0,0 +1,30 @@ | ||
| 1 | +KVM implements the PSCI (Power State Coordination Interface) | |
| 2 | +specification in order to provide services such as CPU on/off, reset | |
| 3 | +and power-off to the guest. | |
| 4 | + | |
| 5 | +The PSCI specification is regularly updated to provide new features, | |
| 6 | +and KVM implements these updates if they make sense from a virtualization | |
| 7 | +point of view. | |
| 8 | + | |
| 9 | +This means that a guest booted on two different versions of KVM can | |
| 10 | +observe two different "firmware" revisions. This could cause issues if | |
| 11 | +a given guest is tied to a particular PSCI revision (unlikely), or if | |
| 12 | +a migration causes a different PSCI version to be exposed out of the | |
| 13 | +blue to an unsuspecting guest. | |
| 14 | + | |
| 15 | +In order to remedy this situation, KVM exposes a set of "firmware | |
| 16 | +pseudo-registers" that can be manipulated using the GET/SET_ONE_REG | |
| 17 | +interface. These registers can be saved/restored by userspace, and set | |
| 18 | +to a convenient value if required. | |
| 19 | + | |
| 20 | +The following register is defined: | |
| 21 | + | |
| 22 | +* KVM_REG_ARM_PSCI_VERSION: | |
| 23 | + | |
| 24 | + - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set | |
| 25 | + (and thus has already been initialized) | |
| 26 | + - Returns the current PSCI version on GET_ONE_REG (defaulting to the | |
| 27 | + highest PSCI version implemented by KVM and compatible with v0.2) | |
| 28 | + - Allows any PSCI version implemented by KVM and compatible with | |
| 29 | + v0.2 to be set with SET_ONE_REG | |
| 30 | + - Affects the whole VM (even if the register view is per-vcpu) | |
| @@ -564,8 +564,9 @@ S: Maintained · 563 unmodified lines | ||
| 564 | 564 | F: drivers/media/dvb-frontends/af9033* |
| 565 | 565 | |
| 566 | 566 | AFFS FILE SYSTEM |
| 567 | +M: David Sterba <dsterba@suse.com> | |
| 567 | 568 | L: linux-fsdevel@vger.kernel.org |
| 568 | −S: Orphan | |
| 569 | +S: Odd Fixes | |
| 569 | 570 | F: Documentation/filesystems/affs.txt |
| 570 | 571 | F: fs/affs/ |
| 571 | 572 | |
| @@ -905,6 +906,8 @@ ANDROID ION DRIVER · 333 unmodified lines | ||
| 905 | 906 | M: Laura Abbott <labbott@redhat.com> |
| 906 | 907 | M: Sumit Semwal <sumit.semwal@linaro.org> |
| 907 | 908 | L: devel@driverdev.osuosl.org |
| 909 | +L: dri-devel@lists.freedesktop.org | |
| 910 | +L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers) | |
| 908 | 911 | S: Supported |
| 909 | 912 | F: drivers/staging/android/ion |
| 910 | 913 | F: drivers/staging/android/uapi/ion.h |
| @@ -1208,7 +1211,6 @@ F: drivers/*/*alpine* · 297 unmodified lines | ||
| 1208 | 1211 | ARM/ARTPEC MACHINE SUPPORT |
| 1209 | 1212 | M: Jesper Nilsson <jesper.nilsson@axis.com> |
| 1210 | 1213 | M: Lars Persson <lars.persson@axis.com> |
| 1211 | −M: Niklas Cassel <niklas.cassel@axis.com> | |
| 1212 | 1214 | S: Maintained |
| 1213 | 1215 | L: linux-arm-kernel@axis.com |
| 1214 | 1216 | F: arch/arm/mach-artpec |
| @@ -1373,7 +1375,8 @@ F: arch/arm/mach-ebsa110/ · 158 unmodified lines | ||
| 1373 | 1375 | F: drivers/net/ethernet/amd/am79c961a.* |
| 1374 | 1376 | |
| 1375 | 1377 | ARM/ENERGY MICRO (SILICON LABS) EFM32 SUPPORT |
| 1376 | −M: Uwe Kleine-König <kernel@pengutronix.de> | |
| 1378 | +M: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | |
| 1379 | +R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 1377 | 1380 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1378 | 1381 | S: Maintained |
| 1379 | 1382 | N: efm32 |
| @@ -1401,7 +1404,8 @@ F: arch/arm/mach-footbridge/ · 21 unmodified lines | ||
| 1401 | 1404 | |
| 1402 | 1405 | ARM/FREESCALE IMX / MXC ARM ARCHITECTURE |
| 1403 | 1406 | M: Shawn Guo <shawnguo@kernel.org> |
| 1404 | −M: Sascha Hauer <kernel@pengutronix.de> | |
| 1407 | +M: Sascha Hauer <s.hauer@pengutronix.de> | |
| 1408 | +R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 1405 | 1409 | R: Fabio Estevam <fabio.estevam@nxp.com> |
| 1406 | 1410 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1407 | 1411 | S: Maintained |
| @@ -1416,7 +1420,8 @@ F: include/soc/imx/ · 8 unmodified lines | ||
| 1416 | 1420 | |
| 1417 | 1421 | ARM/FREESCALE VYBRID ARM ARCHITECTURE |
| 1418 | 1422 | M: Shawn Guo <shawnguo@kernel.org> |
| 1419 | −M: Sascha Hauer <kernel@pengutronix.de> | |
| 1423 | +M: Sascha Hauer <s.hauer@pengutronix.de> | |
| 1424 | +R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 1420 | 1425 | R: Stefan Agner <stefan@agner.ch> |
| 1421 | 1426 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1422 | 1427 | S: Maintained |
| @@ -2549,7 +2554,6 @@ F: Documentation/devicetree/bindings/sound/axentia,* · 1126 unmodified lines | ||
| 2549 | 2554 | F: sound/soc/atmel/tse850-pcm5142.c |
| 2550 | 2555 | |
| 2551 | 2556 | AZ6007 DVB DRIVER |
| 2552 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 2553 | 2557 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 2554 | 2558 | L: linux-media@vger.kernel.org |
| 2555 | 2559 | W: https://linuxtv.org |
| @@ -2614,7 +2618,7 @@ S: Maintained · 58 unmodified lines | ||
| 2614 | 2618 | F: drivers/net/hamradio/baycom* |
| 2615 | 2619 | |
| 2616 | 2620 | BCACHE (BLOCK LAYER CACHE) |
| 2617 | −M: Michael Lyle <mlyle@lyle.org> | |
| 2621 | +M: Coly Li <colyli@suse.de> | |
| 2618 | 2622 | M: Kent Overstreet <kent.overstreet@gmail.com> |
| 2619 | 2623 | L: linux-bcache@vger.kernel.org |
| 2620 | 2624 | W: http://bcache.evilpiepirate.org |
| @@ -3078,7 +3082,6 @@ F: include/linux/btrfs* · 457 unmodified lines | ||
| 3078 | 3082 | F: include/uapi/linux/btrfs* |
| 3079 | 3083 | |
| 3080 | 3084 | BTTV VIDEO4LINUX DRIVER |
| 3081 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 3082 | 3085 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 3083 | 3086 | L: linux-media@vger.kernel.org |
| 3084 | 3087 | W: https://linuxtv.org |
| @@ -3807,7 +3810,6 @@ S: Maintained · 722 unmodified lines | ||
| 3807 | 3810 | F: drivers/media/dvb-frontends/cx24120* |
| 3808 | 3811 | |
| 3809 | 3812 | CX88 VIDEO4LINUX DRIVER |
| 3810 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 3811 | 3813 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 3812 | 3814 | L: linux-media@vger.kernel.org |
| 3813 | 3815 | W: https://linuxtv.org |
| @@ -4245,6 +4247,9 @@ F: include/trace/events/fs_dax.h · 431 unmodified lines | ||
| 4245 | 4247 | |
| 4246 | 4248 | DEVICE DIRECT ACCESS (DAX) |
| 4247 | 4249 | M: Dan Williams <dan.j.williams@intel.com> |
| 4250 | +M: Dave Jiang <dave.jiang@intel.com> | |
| 4251 | +M: Ross Zwisler <ross.zwisler@linux.intel.com> | |
| 4252 | +M: Vishal Verma <vishal.l.verma@intel.com> | |
| 4248 | 4253 | L: linux-nvdimm@lists.01.org |
| 4249 | 4254 | S: Supported |
| 4250 | 4255 | F: drivers/dax/ |
| @@ -5045,7 +5050,6 @@ F: drivers/edac/thunderx_edac* · 794 unmodified lines | ||
| 5045 | 5050 | |
| 5046 | 5051 | EDAC-CORE |
| 5047 | 5052 | M: Borislav Petkov <bp@alien8.de> |
| 5048 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 5049 | 5053 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5050 | 5054 | L: linux-edac@vger.kernel.org |
| 5051 | 5055 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next |
| @@ -5074,7 +5078,6 @@ S: Maintained · 22 unmodified lines | ||
| 5074 | 5078 | F: drivers/edac/fsl_ddr_edac.* |
| 5075 | 5079 | |
| 5076 | 5080 | EDAC-GHES |
| 5077 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 5078 | 5081 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5079 | 5082 | L: linux-edac@vger.kernel.org |
| 5080 | 5083 | S: Maintained |
| @@ -5091,21 +5094,18 @@ S: Maintained · 10 unmodified lines | ||
| 5091 | 5094 | F: drivers/edac/i5000_edac.c |
| 5092 | 5095 | |
| 5093 | 5096 | EDAC-I5400 |
| 5094 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 5095 | 5097 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5096 | 5098 | L: linux-edac@vger.kernel.org |
| 5097 | 5099 | S: Maintained |
| 5098 | 5100 | F: drivers/edac/i5400_edac.c |
| 5099 | 5101 | |
| 5100 | 5102 | EDAC-I7300 |
| 5101 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 5102 | 5103 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5103 | 5104 | L: linux-edac@vger.kernel.org |
| 5104 | 5105 | S: Maintained |
| 5105 | 5106 | F: drivers/edac/i7300_edac.c |
| 5106 | 5107 | |
| 5107 | 5108 | EDAC-I7CORE |
| 5108 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 5109 | 5109 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5110 | 5110 | L: linux-edac@vger.kernel.org |
| 5111 | 5111 | S: Maintained |
| @@ -5155,7 +5155,6 @@ S: Maintained · 43 unmodified lines | ||
| 5155 | 5155 | F: drivers/edac/r82600_edac.c |
| 5156 | 5156 | |
| 5157 | 5157 | EDAC-SBRIDGE |
| 5158 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 5159 | 5158 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5160 | 5159 | L: linux-edac@vger.kernel.org |
| 5161 | 5160 | S: Maintained |
| @@ -5214,7 +5213,6 @@ S: Maintained · 52 unmodified lines | ||
| 5214 | 5213 | F: drivers/net/ethernet/ibm/ehea/ |
| 5215 | 5214 | |
| 5216 | 5215 | EM28XX VIDEO4LINUX DRIVER |
| 5217 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 5218 | 5216 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 5219 | 5217 | L: linux-media@vger.kernel.org |
| 5220 | 5218 | W: https://linuxtv.org |
| @@ -5652,7 +5650,8 @@ F: drivers/net/ethernet/freescale/fec.h · 431 unmodified lines | ||
| 5652 | 5650 | F: Documentation/devicetree/bindings/net/fsl-fec.txt |
| 5653 | 5651 | |
| 5654 | 5652 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER |
| 5655 | −M: Sascha Hauer <kernel@pengutronix.de> | |
| 5653 | +M: Sascha Hauer <s.hauer@pengutronix.de> | |
| 5654 | +R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 5656 | 5655 | L: linux-fbdev@vger.kernel.org |
| 5657 | 5656 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 5658 | 5657 | S: Maintained |
| @@ -5784,6 +5783,14 @@ F: fs/crypto/ · 125 unmodified lines | ||
| 5784 | 5783 | F: include/linux/fscrypt*.h |
| 5785 | 5784 | F: Documentation/filesystems/fscrypt.rst |
| 5786 | 5785 | |
| 5786 | +FSNOTIFY: FILESYSTEM NOTIFICATION INFRASTRUCTURE | |
| 5787 | +M: Jan Kara <jack@suse.cz> | |
| 5788 | +R: Amir Goldstein <amir73il@gmail.com> | |
| 5789 | +L: linux-fsdevel@vger.kernel.org | |
| 5790 | +S: Maintained | |
| 5791 | +F: fs/notify/ | |
| 5792 | +F: include/linux/fsnotify*.h | |
| 5793 | + | |
| 5787 | 5794 | FUJITSU LAPTOP EXTRAS |
| 5788 | 5795 | M: Jonathan Woithe <jwoithe@just42.net> |
| 5789 | 5796 | L: platform-driver-x86@vger.kernel.org |
| @@ -6256,7 +6263,7 @@ S: Odd Fixes · 466 unmodified lines | ||
| 6256 | 6263 | F: drivers/media/usb/hdpvr/ |
| 6257 | 6264 | |
| 6258 | 6265 | HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER |
| 6259 | −M: Jimmy Vance <jimmy.vance@hpe.com> | |
| 6266 | +M: Jerry Hoemann <jerry.hoemann@hpe.com> | |
| 6260 | 6267 | S: Supported |
| 6261 | 6268 | F: Documentation/watchdog/hpwdt.txt |
| 6262 | 6269 | F: drivers/watchdog/hpwdt.c |
| @@ -7396,16 +7403,6 @@ S: Obsolete · 1133 unmodified lines | ||
| 7396 | 7403 | F: include/uapi/linux/ipx.h |
| 7397 | 7404 | F: drivers/staging/ipx/ |
| 7398 | 7405 | |
| 7399 | −IRDA SUBSYSTEM | |
| 7400 | −M: Samuel Ortiz <samuel@sortiz.org> | |
| 7401 | −L: irda-users@lists.sourceforge.net (subscribers-only) | |
| 7402 | −L: netdev@vger.kernel.org | |
| 7403 | −W: http://irda.sourceforge.net/ | |
| 7404 | −S: Obsolete | |
| 7405 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git | |
| 7406 | −F: Documentation/networking/irda.txt | |
| 7407 | −F: drivers/staging/irda/ | |
| 7408 | − | |
| 7409 | 7406 | IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY) |
| 7410 | 7407 | M: Marc Zyngier <marc.zyngier@arm.com> |
| 7411 | 7408 | S: Maintained |
| @@ -7670,9 +7667,11 @@ L: linux-kbuild@vger.kernel.org · 258 unmodified lines | ||
| 7670 | 7667 | S: Maintained |
| 7671 | 7668 | F: Documentation/kbuild/ |
| 7672 | 7669 | F: Makefile |
| 7673 | −F: scripts/Makefile.* | |
| 7670 | +F: scripts/Kbuild* | |
| 7671 | +F: scripts/Makefile* | |
| 7674 | 7672 | F: scripts/basic/ |
| 7675 | 7673 | F: scripts/mk* |
| 7674 | +F: scripts/mod/ | |
| 7676 | 7675 | F: scripts/package/ |
| 7677 | 7676 | |
| 7678 | 7677 | KERNEL JANITORS |
| @@ -7738,7 +7737,7 @@ F: arch/x86/include/asm/svm.h · 59 unmodified lines | ||
| 7738 | 7737 | F: arch/x86/kvm/svm.c |
| 7739 | 7738 | |
| 7740 | 7739 | KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm) |
| 7741 | −M: Christoffer Dall <christoffer.dall@linaro.org> | |
| 7740 | +M: Christoffer Dall <christoffer.dall@arm.com> | |
| 7742 | 7741 | M: Marc Zyngier <marc.zyngier@arm.com> |
| 7743 | 7742 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 7744 | 7743 | L: kvmarm@lists.cs.columbia.edu |
| @@ -7752,7 +7751,7 @@ F: virt/kvm/arm/ · 7 unmodified lines | ||
| 7752 | 7751 | F: include/kvm/arm_* |
| 7753 | 7752 | |
| 7754 | 7753 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) |
| 7755 | −M: Christoffer Dall <christoffer.dall@linaro.org> | |
| 7754 | +M: Christoffer Dall <christoffer.dall@arm.com> | |
| 7756 | 7755 | M: Marc Zyngier <marc.zyngier@arm.com> |
| 7757 | 7756 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 7758 | 7757 | L: kvmarm@lists.cs.columbia.edu |
| @@ -8048,6 +8047,9 @@ F: tools/lib/lockdep/ · 289 unmodified lines | ||
| 8048 | 8047 | |
| 8049 | 8048 | LIBNVDIMM BLK: MMIO-APERTURE DRIVER |
| 8050 | 8049 | M: Ross Zwisler <ross.zwisler@linux.intel.com> |
| 8050 | +M: Dan Williams <dan.j.williams@intel.com> | |
| 8051 | +M: Vishal Verma <vishal.l.verma@intel.com> | |
| 8052 | +M: Dave Jiang <dave.jiang@intel.com> | |
| 8051 | 8053 | L: linux-nvdimm@lists.01.org |
| 8052 | 8054 | Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ |
| 8053 | 8055 | S: Supported |
| @@ -8056,6 +8058,9 @@ F: drivers/nvdimm/region_devs.c · 2 unmodified lines | ||
| 8056 | 8058 | |
| 8057 | 8059 | LIBNVDIMM BTT: BLOCK TRANSLATION TABLE |
| 8058 | 8060 | M: Vishal Verma <vishal.l.verma@intel.com> |
| 8061 | +M: Dan Williams <dan.j.williams@intel.com> | |
| 8062 | +M: Ross Zwisler <ross.zwisler@linux.intel.com> | |
| 8063 | +M: Dave Jiang <dave.jiang@intel.com> | |
| 8059 | 8064 | L: linux-nvdimm@lists.01.org |
| 8060 | 8065 | Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ |
| 8061 | 8066 | S: Supported |
| @@ -8063,6 +8068,9 @@ F: drivers/nvdimm/btt* · 1 unmodified line | ||
| 8063 | 8068 | |
| 8064 | 8069 | LIBNVDIMM PMEM: PERSISTENT MEMORY DRIVER |
| 8065 | 8070 | M: Ross Zwisler <ross.zwisler@linux.intel.com> |
| 8071 | +M: Dan Williams <dan.j.williams@intel.com> | |
| 8072 | +M: Vishal Verma <vishal.l.verma@intel.com> | |
| 8073 | +M: Dave Jiang <dave.jiang@intel.com> | |
| 8066 | 8074 | L: linux-nvdimm@lists.01.org |
| 8067 | 8075 | Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ |
| 8068 | 8076 | S: Supported |
| @@ -8078,6 +8086,9 @@ F: Documentation/devicetree/bindings/pmem/pmem-region.txt · 9 unmodified lines | ||
| 8078 | 8086 | |
| 8079 | 8087 | LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM |
| 8080 | 8088 | M: Dan Williams <dan.j.williams@intel.com> |
| 8089 | +M: Ross Zwisler <ross.zwisler@linux.intel.com> | |
| 8090 | +M: Vishal Verma <vishal.l.verma@intel.com> | |
| 8091 | +M: Dave Jiang <dave.jiang@intel.com> | |
| 8081 | 8092 | L: linux-nvdimm@lists.01.org |
| 8082 | 8093 | Q: https://patchwork.kernel.org/project/linux-nvdimm/list/ |
| 8083 | 8094 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git |
| @@ -8852,7 +8863,6 @@ F: Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt · 768 unmodified lines | ||
| 8852 | 8863 | F: drivers/staging/media/tegra-vde/ |
| 8853 | 8864 | |
| 8854 | 8865 | MEDIA INPUT INFRASTRUCTURE (V4L/DVB) |
| 8855 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 8856 | 8866 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 8857 | 8867 | P: LinuxTV.org Project |
| 8858 | 8868 | L: linux-media@vger.kernel.org |
| @@ -9706,6 +9716,7 @@ W: https://fedorahosted.org/dropwatch/ · 847 unmodified lines | ||
| 9706 | 9716 | F: net/core/drop_monitor.c |
| 9707 | 9717 | |
| 9708 | 9718 | NETWORKING DRIVERS |
| 9719 | +M: "David S. Miller" <davem@davemloft.net> | |
| 9709 | 9720 | L: netdev@vger.kernel.org |
| 9710 | 9721 | W: http://www.linuxfoundation.org/en/Net |
| 9711 | 9722 | Q: http://patchwork.ozlabs.org/project/netdev/list/ |
| @@ -9765,6 +9776,7 @@ F: include/uapi/linux/net_namespace.h · 53 unmodified lines | ||
| 9765 | 9776 | F: tools/testing/selftests/net/ |
| 9766 | 9777 | F: lib/net_utils.c |
| 9767 | 9778 | F: lib/random32.c |
| 9779 | +F: Documentation/networking/ | |
| 9768 | 9780 | |
| 9769 | 9781 | NETWORKING [IPSEC] |
| 9770 | 9782 | M: Steffen Klassert <steffen.klassert@secunet.com> |
| @@ -10881,7 +10893,6 @@ F: drivers/pci/host/ · 1110 unmodified lines | ||
| 10881 | 10893 | F: drivers/pci/dwc/ |
| 10882 | 10894 | |
| 10883 | 10895 | PCIE DRIVER FOR AXIS ARTPEC |
| 10884 | −M: Niklas Cassel <niklas.cassel@axis.com> | |
| 10885 | 10896 | M: Jesper Nilsson <jesper.nilsson@axis.com> |
| 10886 | 10897 | L: linux-arm-kernel@axis.com |
| 10887 | 10898 | L: linux-pci@vger.kernel.org |
| @@ -12240,7 +12251,6 @@ S: Odd Fixes · 1352 unmodified lines | ||
| 12240 | 12251 | F: drivers/media/i2c/saa6588* |
| 12241 | 12252 | |
| 12242 | 12253 | SAA7134 VIDEO4LINUX DRIVER |
| 12243 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 12244 | 12254 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 12245 | 12255 | L: linux-media@vger.kernel.org |
| 12246 | 12256 | W: https://linuxtv.org |
| @@ -12479,6 +12489,7 @@ F: drivers/scsi/st_*.h · 232 unmodified lines | ||
| 12479 | 12489 | SCTP PROTOCOL |
| 12480 | 12490 | M: Vlad Yasevich <vyasevich@gmail.com> |
| 12481 | 12491 | M: Neil Horman <nhorman@tuxdriver.com> |
| 12492 | +M: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> | |
| 12482 | 12493 | L: linux-sctp@vger.kernel.org |
| 12483 | 12494 | W: http://lksctp.sourceforge.net |
| 12484 | 12495 | S: Maintained |
| @@ -12744,7 +12755,6 @@ S: Maintained · 259 unmodified lines | ||
| 12744 | 12755 | F: drivers/media/radio/si4713/radio-usb-si4713.c |
| 12745 | 12756 | |
| 12746 | 12757 | SIANO DVB DRIVER |
| 12747 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 12748 | 12758 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 12749 | 12759 | L: linux-media@vger.kernel.org |
| 12750 | 12760 | W: https://linuxtv.org |
| @@ -12816,7 +12826,8 @@ F: include/linux/siphash.h · 65 unmodified lines | ||
| 12816 | 12826 | |
| 12817 | 12827 | SIOX |
| 12818 | 12828 | M: Gavin Schenk <g.schenk@eckelmann.de> |
| 12819 | −M: Uwe Kleine-König <kernel@pengutronix.de> | |
| 12829 | +M: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | |
| 12830 | +R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 12820 | 12831 | S: Supported |
| 12821 | 12832 | F: drivers/siox/* |
| 12822 | 12833 | F: include/trace/events/siox.h |
| @@ -13734,7 +13745,6 @@ S: Maintained · 911 unmodified lines | ||
| 13734 | 13745 | F: drivers/media/i2c/tda9840* |
| 13735 | 13746 | |
| 13736 | 13747 | TEA5761 TUNER DRIVER |
| 13737 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 13738 | 13748 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13739 | 13749 | L: linux-media@vger.kernel.org |
| 13740 | 13750 | W: https://linuxtv.org |
| @@ -13743,7 +13753,6 @@ S: Odd fixes · 2 unmodified lines | ||
| 13743 | 13753 | F: drivers/media/tuners/tea5761.* |
| 13744 | 13754 | |
| 13745 | 13755 | TEA5767 TUNER DRIVER |
| 13746 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 13747 | 13756 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 13748 | 13757 | L: linux-media@vger.kernel.org |
| 13749 | 13758 | W: https://linuxtv.org |
| @@ -13833,7 +13842,6 @@ S: Supported · 83 unmodified lines | ||
| 13833 | 13842 | F: drivers/iommu/tegra* |
| 13834 | 13843 | |
| 13835 | 13844 | TEGRA KBC DRIVER |
| 13836 | −M: Rakesh Iyer <riyer@nvidia.com> | |
| 13837 | 13845 | M: Laxman Dewangan <ldewangan@nvidia.com> |
| 13838 | 13846 | S: Supported |
| 13839 | 13847 | F: drivers/input/keyboard/tegra-kbc.c |
| @@ -13936,7 +13944,7 @@ THUNDERBOLT DRIVER · 96 unmodified lines | ||
| 13936 | 13944 | M: Andreas Noever <andreas.noever@gmail.com> |
| 13937 | 13945 | M: Michael Jamet <michael.jamet@intel.com> |
| 13938 | 13946 | M: Mika Westerberg <mika.westerberg@linux.intel.com> |
| 13939 | −M: Yehezkel Bernat <yehezkel.bernat@intel.com> | |
| 13947 | +M: Yehezkel Bernat <YehezkelShB@gmail.com> | |
| 13940 | 13948 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git |
| 13941 | 13949 | S: Maintained |
| 13942 | 13950 | F: Documentation/admin-guide/thunderbolt.rst |
| @@ -13946,7 +13954,7 @@ F: include/linux/thunderbolt.h · 3 unmodified lines | ||
| 13946 | 13954 | THUNDERBOLT NETWORK DRIVER |
| 13947 | 13955 | M: Michael Jamet <michael.jamet@intel.com> |
| 13948 | 13956 | M: Mika Westerberg <mika.westerberg@linux.intel.com> |
| 13949 | −M: Yehezkel Bernat <yehezkel.bernat@intel.com> | |
| 13957 | +M: Yehezkel Bernat <YehezkelShB@gmail.com> | |
| 13950 | 13958 | L: netdev@vger.kernel.org |
| 13951 | 13959 | S: Maintained |
| 13952 | 13960 | F: drivers/net/thunderbolt.c |
| @@ -14160,7 +14168,6 @@ F: Documentation/networking/tlan.txt · 207 unmodified lines | ||
| 14160 | 14168 | F: drivers/net/ethernet/ti/tlan.* |
| 14161 | 14169 | |
| 14162 | 14170 | TM6000 VIDEO4LINUX DRIVER |
| 14163 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 14164 | 14171 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 14165 | 14172 | L: linux-media@vger.kernel.org |
| 14166 | 14173 | W: https://linuxtv.org |
| @@ -15393,7 +15400,6 @@ S: Maintained · 1226 unmodified lines | ||
| 15393 | 15400 | F: arch/x86/entry/vdso/ |
| 15394 | 15401 | |
| 15395 | 15402 | XC2028/3028 TUNER DRIVER |
| 15396 | −M: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
| 15397 | 15403 | M: Mauro Carvalho Chehab <mchehab@kernel.org> |
| 15398 | 15404 | L: linux-media@vger.kernel.org |
| 15399 | 15405 | W: https://linuxtv.org |
| @@ -2,8 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 4 |
| 3 | 3 | PATCHLEVEL = 17 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 6 | −NAME = Fearless Coyote | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | +NAME = Merciless Moray | |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| 9 | 9 | # To see a list of typical targets execute "make help" |
| @@ -134,37 +134,37 @@ · 133 unmodified lines | ||
| 134 | 134 | function = "gmii"; |
| 135 | 135 | groups = "gmii_gmac0_grp"; |
| 136 | 136 | }; |
| 137 | − /* Settings come from OpenWRT */ | |
| 137 | + /* Settings come from OpenWRT, pins on SL3516 */ | |
| 138 | 138 | conf0 { |
| 139 | − pins = "R8 GMAC0 RXDV", "U11 GMAC1 RXDV"; | |
| 139 | + pins = "V8 GMAC0 RXDV", "T10 GMAC1 RXDV"; | |
| 140 | 140 | skew-delay = <0>; |
| 141 | 141 | }; |
| 142 | 142 | conf1 { |
| 143 | − pins = "T8 GMAC0 RXC", "T11 GMAC1 RXC"; | |
| 143 | + pins = "Y7 GMAC0 RXC", "Y11 GMAC1 RXC"; | |
| 144 | 144 | skew-delay = <15>; |
| 145 | 145 | }; |
| 146 | 146 | conf2 { |
| 147 | − pins = "P8 GMAC0 TXEN", "V11 GMAC1 TXEN"; | |
| 147 | + pins = "T8 GMAC0 TXEN", "W11 GMAC1 TXEN"; | |
| 148 | 148 | skew-delay = <7>; |
| 149 | 149 | }; |
| 150 | 150 | conf3 { |
| 151 | − pins = "V7 GMAC0 TXC"; | |
| 151 | + pins = "U8 GMAC0 TXC"; | |
| 152 | 152 | skew-delay = <11>; |
| 153 | 153 | }; |
| 154 | 154 | conf4 { |
| 155 | − pins = "P10 GMAC1 TXC"; | |
| 155 | + pins = "V11 GMAC1 TXC"; | |
| 156 | 156 | skew-delay = <10>; |
| 157 | 157 | }; |
| 158 | 158 | conf5 { |
| 159 | 159 | /* The data lines all have default skew */ |
| 160 | − pins = "U8 GMAC0 RXD0", "V8 GMAC0 RXD1", | |
| 161 | − "P9 GMAC0 RXD2", "R9 GMAC0 RXD3", | |
| 162 | − "U7 GMAC0 TXD0", "T7 GMAC0 TXD1", | |
| 163 | − "R7 GMAC0 TXD2", "P7 GMAC0 TXD3", | |
| 164 | − "R11 GMAC1 RXD0", "P11 GMAC1 RXD1", | |
| 165 | − "V12 GMAC1 RXD2", "U12 GMAC1 RXD3", | |
| 166 | − "R10 GMAC1 TXD0", "T10 GMAC1 TXD1", | |
| 167 | − "U10 GMAC1 TXD2", "V10 GMAC1 TXD3"; | |
| 160 | + pins = "W8 GMAC0 RXD0", "V9 GMAC0 RXD1", | |
| 161 | + "Y8 GMAC0 RXD2", "U9 GMAC0 RXD3", | |
| 162 | + "T7 GMAC0 TXD0", "U6 GMAC0 TXD1", | |
| 163 | + "V7 GMAC0 TXD2", "U7 GMAC0 TXD3", | |
| 164 | + "Y12 GMAC1 RXD0", "V12 GMAC1 RXD1", | |
| 165 | + "T11 GMAC1 RXD2", "W12 GMAC1 RXD3", | |
| 166 | + "U10 GMAC1 TXD0", "Y10 GMAC1 TXD1", | |
| 167 | + "W10 GMAC1 TXD2", "T9 GMAC1 TXD3"; | |
| 168 | 168 | skew-delay = <7>; |
| 169 | 169 | }; |
| 170 | 170 | /* Set up drive strength on GMAC0 to 16 mA */ |
| @@ -163,10 +163,10 @@ · 162 unmodified lines | ||
| 163 | 163 | |
| 164 | 164 | cm2: cm2@8000 { |
| 165 | 165 | compatible = "ti,omap4-cm2", "simple-bus"; |
| 166 | − reg = <0x8000 0x3000>; | |
| 166 | + reg = <0x8000 0x2000>; | |
| 167 | 167 | #address-cells = <1>; |
| 168 | 168 | #size-cells = <1>; |
| 169 | − ranges = <0 0x8000 0x3000>; | |
| 169 | + ranges = <0 0x8000 0x2000>; | |
| 170 | 170 | |
| 171 | 171 | cm2_clocks: clocks { |
| 172 | 172 | #address-cells = <1>; |
| @@ -250,11 +250,11 @@ · 77 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | prm: prm@6000 { |
| 252 | 252 | compatible = "ti,omap4-prm"; |
| 253 | − reg = <0x6000 0x3000>; | |
| 253 | + reg = <0x6000 0x2000>; | |
| 254 | 254 | interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; |
| 255 | 255 | #address-cells = <1>; |
| 256 | 256 | #size-cells = <1>; |
| 257 | − ranges = <0 0x6000 0x3000>; | |
| 257 | + ranges = <0 0x6000 0x2000>; | |
| 258 | 258 | |
| 259 | 259 | prm_clocks: clocks { |
| 260 | 260 | #address-cells = <1>; |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | # CONFIG_LOCALVERSION_AUTO is not set |
| 2 | 2 | CONFIG_SYSVIPC=y |
| 3 | 3 | CONFIG_NO_HZ_IDLE=y |
| 4 | +CONFIG_HIGH_RES_TIMERS=y | |
| 4 | 5 | CONFIG_BSD_PROCESS_ACCT=y |
| 5 | 6 | CONFIG_USER_NS=y |
| 6 | 7 | CONFIG_RELAY=y |
| @@ -12,15 +13,21 @@ CONFIG_ARCH_GEMINI=y · 5 unmodified lines | ||
| 12 | 13 | CONFIG_PCI=y |
| 13 | 14 | CONFIG_PREEMPT=y |
| 14 | 15 | CONFIG_AEABI=y |
| 16 | +CONFIG_HIGHMEM=y | |
| 17 | +CONFIG_CMA=y | |
| 15 | 18 | CONFIG_CMDLINE="console=ttyS0,115200n8" |
| 16 | 19 | CONFIG_KEXEC=y |
| 17 | 20 | CONFIG_BINFMT_MISC=y |
| 18 | 21 | CONFIG_PM=y |
| 22 | +CONFIG_NET=y | |
| 23 | +CONFIG_UNIX=y | |
| 24 | +CONFIG_INET=y | |
| 19 | 25 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
| 20 | 26 | CONFIG_DEVTMPFS=y |
| 21 | 27 | CONFIG_MTD=y |
| 22 | 28 | CONFIG_MTD_BLOCK=y |
| 23 | 29 | CONFIG_MTD_CFI=y |
| 30 | +CONFIG_MTD_JEDECPROBE=y | |
| 24 | 31 | CONFIG_MTD_CFI_INTELEXT=y |
| 25 | 32 | CONFIG_MTD_CFI_AMDSTD=y |
| 26 | 33 | CONFIG_MTD_CFI_STAA=y |
| @@ -33,6 +40,11 @@ CONFIG_BLK_DEV_SD=y · 6 unmodified lines | ||
| 33 | 40 | # CONFIG_SCSI_LOWLEVEL is not set |
| 34 | 41 | CONFIG_ATA=y |
| 35 | 42 | CONFIG_PATA_FTIDE010=y |
| 43 | +CONFIG_NETDEVICES=y | |
| 44 | +CONFIG_GEMINI_ETHERNET=y | |
| 45 | +CONFIG_MDIO_BITBANG=y | |
| 46 | +CONFIG_MDIO_GPIO=y | |
| 47 | +CONFIG_REALTEK_PHY=y | |
| 36 | 48 | CONFIG_INPUT_EVDEV=y |
| 37 | 49 | CONFIG_KEYBOARD_GPIO=y |
| 38 | 50 | # CONFIG_INPUT_MOUSE is not set |
| @@ -43,9 +55,19 @@ CONFIG_SERIAL_8250_NR_UARTS=1 · 4 unmodified lines | ||
| 43 | 55 | CONFIG_SERIAL_8250_RUNTIME_UARTS=1 |
| 44 | 56 | CONFIG_SERIAL_OF_PLATFORM=y |
| 45 | 57 | # CONFIG_HW_RANDOM is not set |
| 46 | −# CONFIG_HWMON is not set | |
| 58 | +CONFIG_I2C_GPIO=y | |
| 59 | +CONFIG_SPI=y | |
| 60 | +CONFIG_SPI_GPIO=y | |
| 61 | +CONFIG_SENSORS_GPIO_FAN=y | |
| 62 | +CONFIG_SENSORS_LM75=y | |
| 63 | +CONFIG_THERMAL=y | |
| 47 | 64 | CONFIG_WATCHDOG=y |
| 48 | −CONFIG_GEMINI_WATCHDOG=y | |
| 65 | +CONFIG_REGULATOR=y | |
| 66 | +CONFIG_REGULATOR_FIXED_VOLTAGE=y | |
| 67 | +CONFIG_DRM=y | |
| 68 | +CONFIG_DRM_PANEL_ILITEK_IL9322=y | |
| 69 | +CONFIG_DRM_TVE200=y | |
| 70 | +CONFIG_LOGO=y | |
| 49 | 71 | CONFIG_USB=y |
| 50 | 72 | CONFIG_USB_MON=y |
| 51 | 73 | CONFIG_USB_FOTG210_HCD=y |
| @@ -54,6 +76,7 @@ CONFIG_NEW_LEDS=y · 2 unmodified lines | ||
| 54 | 76 | CONFIG_LEDS_CLASS=y |
| 55 | 77 | CONFIG_LEDS_GPIO=y |
| 56 | 78 | CONFIG_LEDS_TRIGGERS=y |
| 79 | +CONFIG_LEDS_TRIGGER_DISK=y | |
| 57 | 80 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
| 58 | 81 | CONFIG_RTC_CLASS=y |
| 59 | 82 | CONFIG_DMADEVICES=y |
| @@ -57,6 +57,7 @@ CONFIG_MTD_M25P80=y · 56 unmodified lines | ||
| 57 | 57 | CONFIG_MTD_NAND=y |
| 58 | 58 | CONFIG_MTD_NAND_DENALI_DT=y |
| 59 | 59 | CONFIG_MTD_SPI_NOR=y |
| 60 | +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set | |
| 60 | 61 | CONFIG_SPI_CADENCE_QUADSPI=y |
| 61 | 62 | CONFIG_OF_OVERLAY=y |
| 62 | 63 | CONFIG_OF_CONFIGFS=y |
| @@ -77,6 +77,9 @@ struct kvm_arch { · 76 unmodified lines | ||
| 77 | 77 | /* Interrupt controller */ |
| 78 | 78 | struct vgic_dist vgic; |
| 79 | 79 | int max_vcpus; |
| 80 | + | |
| 81 | + /* Mandated version of PSCI */ | |
| 82 | + u32 psci_version; | |
| 80 | 83 | }; |
| 81 | 84 | |
| 82 | 85 | #define KVM_NR_MEM_OBJS 40 |
| @@ -195,6 +195,12 @@ struct kvm_arch_memory_slot { · 194 unmodified lines | ||
| 195 | 195 | #define KVM_REG_ARM_VFP_FPINST 0x1009 |
| 196 | 196 | #define KVM_REG_ARM_VFP_FPINST2 0x100A |
| 197 | 197 | |
| 198 | +/* KVM-as-firmware specific pseudo-registers */ | |
| 199 | +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) | |
| 200 | +#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \ | |
| 201 | + KVM_REG_ARM_FW | ((r) & 0xffff)) | |
| 202 | +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) | |
| 203 | + | |
| 198 | 204 | /* Device Control API: ARM VGIC */ |
| 199 | 205 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 |
| 200 | 206 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/module.h> |
| 23 | 23 | #include <linux/vmalloc.h> |
| 24 | 24 | #include <linux/fs.h> |
| 25 | +#include <kvm/arm_psci.h> | |
| 25 | 26 | #include <asm/cputype.h> |
| 26 | 27 | #include <linux/uaccess.h> |
| 27 | 28 | #include <asm/kvm.h> |
| @@ -176,6 +177,7 @@ static unsigned long num_core_regs(void) · 148 unmodified lines | ||
| 176 | 177 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) |
| 177 | 178 | { |
| 178 | 179 | return num_core_regs() + kvm_arm_num_coproc_regs(vcpu) |
| 180 | + + kvm_arm_get_fw_num_regs(vcpu) | |
| 179 | 181 | + NUM_TIMER_REGS; |
| 180 | 182 | } |
| 181 | 183 | |
| @@ -196,6 +198,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) · 14 unmodified lines | ||
| 196 | 198 | uindices++; |
| 197 | 199 | } |
| 198 | 200 | |
| 201 | + ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices); | |
| 202 | + if (ret) | |
| 203 | + return ret; | |
| 204 | + uindices += kvm_arm_get_fw_num_regs(vcpu); | |
| 205 | + | |
| 199 | 206 | ret = copy_timer_indices(vcpu, uindices); |
| 200 | 207 | if (ret) |
| 201 | 208 | return ret; |
| @@ -214,6 +221,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 12 unmodified lines | ||
| 214 | 221 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 215 | 222 | return get_core_reg(vcpu, reg); |
| 216 | 223 | |
| 224 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 225 | + return kvm_arm_get_fw_reg(vcpu, reg); | |
| 226 | + | |
| 217 | 227 | if (is_timer_reg(reg->id)) |
| 218 | 228 | return get_timer_reg(vcpu, reg); |
| 219 | 229 | |
| @@ -230,6 +240,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 10 unmodified lines | ||
| 230 | 240 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 231 | 241 | return set_core_reg(vcpu, reg); |
| 232 | 242 | |
| 243 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 244 | + return kvm_arm_set_fw_reg(vcpu, reg); | |
| 245 | + | |
| 233 | 246 | if (is_timer_reg(reg->id)) |
| 234 | 247 | return set_timer_reg(vcpu, reg); |
| 235 | 248 | |
| @@ -243,8 +243,4 @@ arch/arm/mach-omap2/pm-asm-offsets.s: arch/arm/mach-omap2/pm-asm-offsets.c · 242 unmodified lines | ||
| 243 | 243 | include/generated/ti-pm-asm-offsets.h: arch/arm/mach-omap2/pm-asm-offsets.s FORCE |
| 244 | 244 | $(call filechk,offsets,__TI_PM_ASM_OFFSETS_H__) |
| 245 | 245 | |
| 246 | −# For rule to generate ti-emif-asm-offsets.h dependency | |
| 247 | −include drivers/memory/Makefile.asm-offsets | |
| 248 | − | |
| 249 | −arch/arm/mach-omap2/sleep33xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h | |
| 250 | −arch/arm/mach-omap2/sleep43xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h | |
| 246 | +$(obj)/sleep33xx.o $(obj)/sleep43xx.o: include/generated/ti-pm-asm-offsets.h | |
| @@ -7,9 +7,12 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <linux/kbuild.h> |
| 9 | 9 | #include <linux/platform_data/pm33xx.h> |
| 10 | +#include <linux/ti-emif-sram.h> | |
| 10 | 11 | |
| 11 | 12 | int main(void) |
| 12 | 13 | { |
| 14 | + ti_emif_asm_offsets(); | |
| 15 | + | |
| 13 | 16 | DEFINE(AMX3_PM_WFI_FLAGS_OFFSET, |
| 14 | 17 | offsetof(struct am33xx_pm_sram_data, wfi_flags)); |
| 15 | 18 | DEFINE(AMX3_PM_L2_AUX_CTRL_VAL_OFFSET, |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | * Dave Gerlach, Vaibhav Bedia |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | −#include <generated/ti-emif-asm-offsets.h> | |
| 10 | 9 | #include <generated/ti-pm-asm-offsets.h> |
| 11 | 10 | #include <linux/linkage.h> |
| 12 | 11 | #include <linux/ti-emif-sram.h> |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | * Dave Gerlach, Vaibhav Bedia |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | −#include <generated/ti-emif-asm-offsets.h> | |
| 10 | 9 | #include <generated/ti-pm-asm-offsets.h> |
| 11 | 10 | #include <linux/linkage.h> |
| 12 | 11 | #include <linux/ti-emif-sram.h> |
| @@ -427,9 +427,9 @@ static struct gpiod_lookup_table jive_wm8750_gpiod_table = { · 426 unmodified lines | ||
| 427 | 427 | .dev_id = "spi_gpio", |
| 428 | 428 | .table = { |
| 429 | 429 | GPIO_LOOKUP("GPIOB", 4, |
| 430 | − "gpio-sck", GPIO_ACTIVE_HIGH), | |
| 430 | + "sck", GPIO_ACTIVE_HIGH), | |
| 431 | 431 | GPIO_LOOKUP("GPIOB", 9, |
| 432 | − "gpio-mosi", GPIO_ACTIVE_HIGH), | |
| 432 | + "mosi", GPIO_ACTIVE_HIGH), | |
| 433 | 433 | GPIO_LOOKUP("GPIOH", 10, |
| 434 | 434 | "cs", GPIO_ACTIVE_HIGH), |
| 435 | 435 | { }, |
| @@ -56,7 +56,11 @@ KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) · 55 unmodified lines | ||
| 56 | 56 | KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) |
| 57 | 57 | KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) |
| 58 | 58 | |
| 59 | +ifeq ($(cc-name),clang) | |
| 60 | +KBUILD_CFLAGS += -DCONFIG_ARCH_SUPPORTS_INT128 | |
| 61 | +else | |
| 59 | 62 | KBUILD_CFLAGS += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128) |
| 63 | +endif | |
| 60 | 64 | |
| 61 | 65 | ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) |
| 62 | 66 | KBUILD_CPPFLAGS += -mbig-endian |
| @@ -212,3 +212,7 @@ · 211 unmodified lines | ||
| 212 | 212 | pinctrl-0 = <&uart_ao_a_pins>; |
| 213 | 213 | pinctrl-names = "default"; |
| 214 | 214 | }; |
| 215 | + | |
| 216 | +&usb0 { | |
| 217 | + status = "okay"; | |
| 218 | +}; | |
| @@ -271,3 +271,15 @@ · 270 unmodified lines | ||
| 271 | 271 | pinctrl-0 = <&uart_ao_a_pins>; |
| 272 | 272 | pinctrl-names = "default"; |
| 273 | 273 | }; |
| 274 | + | |
| 275 | +&usb0 { | |
| 276 | + status = "okay"; | |
| 277 | +}; | |
| 278 | + | |
| 279 | +&usb2_phy0 { | |
| 280 | + /* | |
| 281 | + * even though the schematics don't show it: | |
| 282 | + * HDMI_5V is also used as supply for the USB VBUS. | |
| 283 | + */ | |
| 284 | + phy-supply = <&hdmi_5v>; | |
| 285 | +}; | |
| @@ -215,3 +215,7 @@ · 214 unmodified lines | ||
| 215 | 215 | pinctrl-0 = <&uart_ao_a_pins>; |
| 216 | 216 | pinctrl-names = "default"; |
| 217 | 217 | }; |
| 218 | + | |
| 219 | +&usb0 { | |
| 220 | + status = "okay"; | |
| 221 | +}; | |
| @@ -185,3 +185,7 @@ · 184 unmodified lines | ||
| 185 | 185 | pinctrl-0 = <&uart_ao_a_pins>; |
| 186 | 186 | pinctrl-names = "default"; |
| 187 | 187 | }; |
| 188 | + | |
| 189 | +&usb0 { | |
| 190 | + status = "okay"; | |
| 191 | +}; | |
| @@ -20,6 +20,67 @@ · 19 unmodified lines | ||
| 20 | 20 | no-map; |
| 21 | 21 | }; |
| 22 | 22 | }; |
| 23 | + | |
| 24 | + soc { | |
| 25 | + usb0: usb@c9000000 { | |
| 26 | + status = "disabled"; | |
| 27 | + compatible = "amlogic,meson-gxl-dwc3"; | |
| 28 | + #address-cells = <2>; | |
| 29 | + #size-cells = <2>; | |
| 30 | + ranges; | |
| 31 | + | |
| 32 | + clocks = <&clkc CLKID_USB>; | |
| 33 | + clock-names = "usb_general"; | |
| 34 | + resets = <&reset RESET_USB_OTG>; | |
| 35 | + reset-names = "usb_otg"; | |
| 36 | + | |
| 37 | + dwc3: dwc3@c9000000 { | |
| 38 | + compatible = "snps,dwc3"; | |
| 39 | + reg = <0x0 0xc9000000 0x0 0x100000>; | |
| 40 | + interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; | |
| 41 | + dr_mode = "host"; | |
| 42 | + maximum-speed = "high-speed"; | |
| 43 | + snps,dis_u2_susphy_quirk; | |
| 44 | + phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>; | |
| 45 | + }; | |
| 46 | + }; | |
| 47 | + }; | |
| 48 | +}; | |
| 49 | + | |
| 50 | +&apb { | |
| 51 | + usb2_phy0: phy@78000 { | |
| 52 | + compatible = "amlogic,meson-gxl-usb2-phy"; | |
| 53 | + #phy-cells = <0>; | |
| 54 | + reg = <0x0 0x78000 0x0 0x20>; | |
| 55 | + clocks = <&clkc CLKID_USB>; | |
| 56 | + clock-names = "phy"; | |
| 57 | + resets = <&reset RESET_USB_OTG>; | |
| 58 | + reset-names = "phy"; | |
| 59 | + status = "okay"; | |
| 60 | + }; | |
| 61 | + | |
| 62 | + usb2_phy1: phy@78020 { | |
| 63 | + compatible = "amlogic,meson-gxl-usb2-phy"; | |
| 64 | + #phy-cells = <0>; | |
| 65 | + reg = <0x0 0x78020 0x0 0x20>; | |
| 66 | + clocks = <&clkc CLKID_USB>; | |
| 67 | + clock-names = "phy"; | |
| 68 | + resets = <&reset RESET_USB_OTG>; | |
| 69 | + reset-names = "phy"; | |
| 70 | + status = "okay"; | |
| 71 | + }; | |
| 72 | + | |
| 73 | + usb3_phy: phy@78080 { | |
| 74 | + compatible = "amlogic,meson-gxl-usb3-phy"; | |
| 75 | + #phy-cells = <0>; | |
| 76 | + reg = <0x0 0x78080 0x0 0x20>; | |
| 77 | + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; | |
| 78 | + clocks = <&clkc CLKID_USB>, <&clkc_AO CLKID_AO_CEC_32K>; | |
| 79 | + clock-names = "phy", "peripheral"; | |
| 80 | + resets = <&reset RESET_USB_OTG>, <&reset RESET_USB_OTG>; | |
| 81 | + reset-names = "phy", "peripheral"; | |
| 82 | + status = "okay"; | |
| 83 | + }; | |
| 23 | 84 | }; |
| 24 | 85 | |
| 25 | 86 | ðmac { |
| @@ -406,3 +406,7 @@ · 405 unmodified lines | ||
| 406 | 406 | status = "okay"; |
| 407 | 407 | vref-supply = <&vddio_ao18>; |
| 408 | 408 | }; |
| 409 | + | |
| 410 | +&usb0 { | |
| 411 | + status = "okay"; | |
| 412 | +}; | |
| @@ -80,6 +80,19 @@ · 79 unmodified lines | ||
| 80 | 80 | }; |
| 81 | 81 | }; |
| 82 | 82 | |
| 83 | +&apb { | |
| 84 | + usb2_phy2: phy@78040 { | |
| 85 | + compatible = "amlogic,meson-gxl-usb2-phy"; | |
| 86 | + #phy-cells = <0>; | |
| 87 | + reg = <0x0 0x78040 0x0 0x20>; | |
| 88 | + clocks = <&clkc CLKID_USB>; | |
| 89 | + clock-names = "phy"; | |
| 90 | + resets = <&reset RESET_USB_OTG>; | |
| 91 | + reset-names = "phy"; | |
| 92 | + status = "okay"; | |
| 93 | + }; | |
| 94 | +}; | |
| 95 | + | |
| 83 | 96 | &clkc_AO { |
| 84 | 97 | compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc"; |
| 85 | 98 | }; |
| @@ -100,3 +113,7 @@ · 14 unmodified lines | ||
| 100 | 113 | &hdmi_tx { |
| 101 | 114 | compatible = "amlogic,meson-gxm-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; |
| 102 | 115 | }; |
| 116 | + | |
| 117 | +&dwc3 { | |
| 118 | + phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>; | |
| 119 | +}; | |
| @@ -56,8 +56,6 @@ · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | gpio_keys { |
| 58 | 58 | compatible = "gpio-keys"; |
| 59 | − #address-cells = <1>; | |
| 60 | − #size-cells = <0>; | |
| 61 | 59 | |
| 62 | 60 | power-button { |
| 63 | 61 | debounce_interval = <50>; |
| @@ -36,11 +36,11 @@ · 35 unmodified lines | ||
| 36 | 36 | #size-cells = <1>; |
| 37 | 37 | ranges = <0x0 0x0 0x67d00000 0x00800000>; |
| 38 | 38 | |
| 39 | − sata0: ahci@210000 { | |
| 39 | + sata0: ahci@0 { | |
| 40 | 40 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 41 | − reg = <0x00210000 0x1000>; | |
| 41 | + reg = <0x00000000 0x1000>; | |
| 42 | 42 | reg-names = "ahci"; |
| 43 | − interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>; | |
| 43 | + interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>; | |
| 44 | 44 | #address-cells = <1>; |
| 45 | 45 | #size-cells = <0>; |
| 46 | 46 | status = "disabled"; |
| @@ -52,9 +52,9 @@ · 5 unmodified lines | ||
| 52 | 52 | }; |
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | − sata_phy0: sata_phy@212100 { | |
| 55 | + sata_phy0: sata_phy@2100 { | |
| 56 | 56 | compatible = "brcm,iproc-sr-sata-phy"; |
| 57 | − reg = <0x00212100 0x1000>; | |
| 57 | + reg = <0x00002100 0x1000>; | |
| 58 | 58 | reg-names = "phy"; |
| 59 | 59 | #address-cells = <1>; |
| 60 | 60 | #size-cells = <0>; |
| @@ -66,11 +66,11 @@ · 5 unmodified lines | ||
| 66 | 66 | }; |
| 67 | 67 | }; |
| 68 | 68 | |
| 69 | − sata1: ahci@310000 { | |
| 69 | + sata1: ahci@10000 { | |
| 70 | 70 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 71 | − reg = <0x00310000 0x1000>; | |
| 71 | + reg = <0x00010000 0x1000>; | |
| 72 | 72 | reg-names = "ahci"; |
| 73 | − interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>; | |
| 73 | + interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>; | |
| 74 | 74 | #address-cells = <1>; |
| 75 | 75 | #size-cells = <0>; |
| 76 | 76 | status = "disabled"; |
| @@ -82,9 +82,9 @@ · 5 unmodified lines | ||
| 82 | 82 | }; |
| 83 | 83 | }; |
| 84 | 84 | |
| 85 | − sata_phy1: sata_phy@312100 { | |
| 85 | + sata_phy1: sata_phy@12100 { | |
| 86 | 86 | compatible = "brcm,iproc-sr-sata-phy"; |
| 87 | − reg = <0x00312100 0x1000>; | |
| 87 | + reg = <0x00012100 0x1000>; | |
| 88 | 88 | reg-names = "phy"; |
| 89 | 89 | #address-cells = <1>; |
| 90 | 90 | #size-cells = <0>; |
| @@ -96,11 +96,11 @@ · 5 unmodified lines | ||
| 96 | 96 | }; |
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | − sata2: ahci@120000 { | |
| 99 | + sata2: ahci@20000 { | |
| 100 | 100 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 101 | − reg = <0x00120000 0x1000>; | |
| 101 | + reg = <0x00020000 0x1000>; | |
| 102 | 102 | reg-names = "ahci"; |
| 103 | − interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>; | |
| 103 | + interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>; | |
| 104 | 104 | #address-cells = <1>; |
| 105 | 105 | #size-cells = <0>; |
| 106 | 106 | status = "disabled"; |
| @@ -112,9 +112,9 @@ · 5 unmodified lines | ||
| 112 | 112 | }; |
| 113 | 113 | }; |
| 114 | 114 | |
| 115 | − sata_phy2: sata_phy@122100 { | |
| 115 | + sata_phy2: sata_phy@22100 { | |
| 116 | 116 | compatible = "brcm,iproc-sr-sata-phy"; |
| 117 | − reg = <0x00122100 0x1000>; | |
| 117 | + reg = <0x00022100 0x1000>; | |
| 118 | 118 | reg-names = "phy"; |
| 119 | 119 | #address-cells = <1>; |
| 120 | 120 | #size-cells = <0>; |
| @@ -126,11 +126,11 @@ · 5 unmodified lines | ||
| 126 | 126 | }; |
| 127 | 127 | }; |
| 128 | 128 | |
| 129 | − sata3: ahci@130000 { | |
| 129 | + sata3: ahci@30000 { | |
| 130 | 130 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 131 | − reg = <0x00130000 0x1000>; | |
| 131 | + reg = <0x00030000 0x1000>; | |
| 132 | 132 | reg-names = "ahci"; |
| 133 | − interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>; | |
| 133 | + interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>; | |
| 134 | 134 | #address-cells = <1>; |
| 135 | 135 | #size-cells = <0>; |
| 136 | 136 | status = "disabled"; |
| @@ -142,9 +142,9 @@ · 5 unmodified lines | ||
| 142 | 142 | }; |
| 143 | 143 | }; |
| 144 | 144 | |
| 145 | − sata_phy3: sata_phy@132100 { | |
| 145 | + sata_phy3: sata_phy@32100 { | |
| 146 | 146 | compatible = "brcm,iproc-sr-sata-phy"; |
| 147 | − reg = <0x00132100 0x1000>; | |
| 147 | + reg = <0x00032100 0x1000>; | |
| 148 | 148 | reg-names = "phy"; |
| 149 | 149 | #address-cells = <1>; |
| 150 | 150 | #size-cells = <0>; |
| @@ -156,11 +156,11 @@ · 5 unmodified lines | ||
| 156 | 156 | }; |
| 157 | 157 | }; |
| 158 | 158 | |
| 159 | − sata4: ahci@330000 { | |
| 159 | + sata4: ahci@100000 { | |
| 160 | 160 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 161 | − reg = <0x00330000 0x1000>; | |
| 161 | + reg = <0x00100000 0x1000>; | |
| 162 | 162 | reg-names = "ahci"; |
| 163 | − interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>; | |
| 163 | + interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>; | |
| 164 | 164 | #address-cells = <1>; |
| 165 | 165 | #size-cells = <0>; |
| 166 | 166 | status = "disabled"; |
| @@ -172,9 +172,9 @@ · 5 unmodified lines | ||
| 172 | 172 | }; |
| 173 | 173 | }; |
| 174 | 174 | |
| 175 | − sata_phy4: sata_phy@332100 { | |
| 175 | + sata_phy4: sata_phy@102100 { | |
| 176 | 176 | compatible = "brcm,iproc-sr-sata-phy"; |
| 177 | − reg = <0x00332100 0x1000>; | |
| 177 | + reg = <0x00102100 0x1000>; | |
| 178 | 178 | reg-names = "phy"; |
| 179 | 179 | #address-cells = <1>; |
| 180 | 180 | #size-cells = <0>; |
| @@ -186,11 +186,11 @@ · 5 unmodified lines | ||
| 186 | 186 | }; |
| 187 | 187 | }; |
| 188 | 188 | |
| 189 | − sata5: ahci@400000 { | |
| 189 | + sata5: ahci@110000 { | |
| 190 | 190 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 191 | − reg = <0x00400000 0x1000>; | |
| 191 | + reg = <0x00110000 0x1000>; | |
| 192 | 192 | reg-names = "ahci"; |
| 193 | − interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; | |
| 193 | + interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>; | |
| 194 | 194 | #address-cells = <1>; |
| 195 | 195 | #size-cells = <0>; |
| 196 | 196 | status = "disabled"; |
| @@ -202,9 +202,9 @@ · 5 unmodified lines | ||
| 202 | 202 | }; |
| 203 | 203 | }; |
| 204 | 204 | |
| 205 | − sata_phy5: sata_phy@402100 { | |
| 205 | + sata_phy5: sata_phy@112100 { | |
| 206 | 206 | compatible = "brcm,iproc-sr-sata-phy"; |
| 207 | − reg = <0x00402100 0x1000>; | |
| 207 | + reg = <0x00112100 0x1000>; | |
| 208 | 208 | reg-names = "phy"; |
| 209 | 209 | #address-cells = <1>; |
| 210 | 210 | #size-cells = <0>; |
| @@ -216,11 +216,11 @@ · 5 unmodified lines | ||
| 216 | 216 | }; |
| 217 | 217 | }; |
| 218 | 218 | |
| 219 | − sata6: ahci@410000 { | |
| 219 | + sata6: ahci@120000 { | |
| 220 | 220 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 221 | − reg = <0x00410000 0x1000>; | |
| 221 | + reg = <0x00120000 0x1000>; | |
| 222 | 222 | reg-names = "ahci"; |
| 223 | − interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; | |
| 223 | + interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>; | |
| 224 | 224 | #address-cells = <1>; |
| 225 | 225 | #size-cells = <0>; |
| 226 | 226 | status = "disabled"; |
| @@ -232,9 +232,9 @@ · 5 unmodified lines | ||
| 232 | 232 | }; |
| 233 | 233 | }; |
| 234 | 234 | |
| 235 | − sata_phy6: sata_phy@412100 { | |
| 235 | + sata_phy6: sata_phy@122100 { | |
| 236 | 236 | compatible = "brcm,iproc-sr-sata-phy"; |
| 237 | − reg = <0x00412100 0x1000>; | |
| 237 | + reg = <0x00122100 0x1000>; | |
| 238 | 238 | reg-names = "phy"; |
| 239 | 239 | #address-cells = <1>; |
| 240 | 240 | #size-cells = <0>; |
| @@ -246,11 +246,11 @@ · 5 unmodified lines | ||
| 246 | 246 | }; |
| 247 | 247 | }; |
| 248 | 248 | |
| 249 | − sata7: ahci@420000 { | |
| 249 | + sata7: ahci@130000 { | |
| 250 | 250 | compatible = "brcm,iproc-ahci", "generic-ahci"; |
| 251 | − reg = <0x00420000 0x1000>; | |
| 251 | + reg = <0x00130000 0x1000>; | |
| 252 | 252 | reg-names = "ahci"; |
| 253 | − interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; | |
| 253 | + interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>; | |
| 254 | 254 | #address-cells = <1>; |
| 255 | 255 | #size-cells = <0>; |
| 256 | 256 | status = "disabled"; |
| @@ -262,9 +262,9 @@ · 5 unmodified lines | ||
| 262 | 262 | }; |
| 263 | 263 | }; |
| 264 | 264 | |
| 265 | − sata_phy7: sata_phy@422100 { | |
| 265 | + sata_phy7: sata_phy@132100 { | |
| 266 | 266 | compatible = "brcm,iproc-sr-sata-phy"; |
| 267 | − reg = <0x00422100 0x1000>; | |
| 267 | + reg = <0x00132100 0x1000>; | |
| 268 | 268 | reg-names = "phy"; |
| 269 | 269 | #address-cells = <1>; |
| 270 | 270 | #size-cells = <0>; |
| @@ -333,7 +333,7 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu) · 332 unmodified lines | ||
| 333 | 333 | } else { |
| 334 | 334 | u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); |
| 335 | 335 | sctlr |= (1 << 25); |
| 336 | − vcpu_write_sys_reg(vcpu, SCTLR_EL1, sctlr); | |
| 336 | + vcpu_write_sys_reg(vcpu, sctlr, SCTLR_EL1); | |
| 337 | 337 | } |
| 338 | 338 | } |
| 339 | 339 | |
| @@ -75,6 +75,9 @@ struct kvm_arch { · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | /* Interrupt controller */ |
| 77 | 77 | struct vgic_dist vgic; |
| 78 | + | |
| 79 | + /* Mandated version of PSCI */ | |
| 80 | + u32 psci_version; | |
| 78 | 81 | }; |
| 79 | 82 | |
| 80 | 83 | #define KVM_NR_MEM_OBJS 40 |
| @@ -39,7 +39,7 @@ struct mod_arch_specific { · 38 unmodified lines | ||
| 39 | 39 | u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela, |
| 40 | 40 | Elf64_Sym *sym); |
| 41 | 41 | |
| 42 | −u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val); | |
| 42 | +u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val); | |
| 43 | 43 | |
| 44 | 44 | #ifdef CONFIG_RANDOMIZE_BASE |
| 45 | 45 | extern u64 module_alloc_base; |
| @@ -230,7 +230,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte) · 229 unmodified lines | ||
| 230 | 230 | } |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | −extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); | |
| 233 | +extern void __sync_icache_dcache(pte_t pteval); | |
| 234 | 234 | |
| 235 | 235 | /* |
| 236 | 236 | * PTE bits configuration in the presence of hardware Dirty Bit Management |
| @@ -253,7 +253,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, · 16 unmodified lines | ||
| 253 | 253 | pte_t old_pte; |
| 254 | 254 | |
| 255 | 255 | if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) |
| 256 | − __sync_icache_dcache(pte, addr); | |
| 256 | + __sync_icache_dcache(pte); | |
| 257 | 257 | |
| 258 | 258 | /* |
| 259 | 259 | * If the existing pte is valid, check for potential race with |
| @@ -206,6 +206,12 @@ struct kvm_arch_memory_slot { · 205 unmodified lines | ||
| 206 | 206 | #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) |
| 207 | 207 | #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) |
| 208 | 208 | |
| 209 | +/* KVM-as-firmware specific pseudo-registers */ | |
| 210 | +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) | |
| 211 | +#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ | |
| 212 | + KVM_REG_ARM_FW | ((r) & 0xffff)) | |
| 213 | +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) | |
| 214 | + | |
| 209 | 215 | /* Device Control API: ARM VGIC */ |
| 210 | 216 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 |
| 211 | 217 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 |
| @@ -868,6 +868,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry, · 867 unmodified lines | ||
| 868 | 868 | static const struct midr_range kpti_safe_list[] = { |
| 869 | 869 | MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), |
| 870 | 870 | MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), |
| 871 | + { /* sentinel */ } | |
| 871 | 872 | }; |
| 872 | 873 | char const *str = "command line option"; |
| 873 | 874 | |
| @@ -43,7 +43,7 @@ u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela, · 42 unmodified lines | ||
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | #ifdef CONFIG_ARM64_ERRATUM_843419 |
| 46 | −u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val) | |
| 46 | +u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val) | |
| 47 | 47 | { |
| 48 | 48 | struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core : |
| 49 | 49 | &mod->arch.init; |
| @@ -215,7 +215,7 @@ static int reloc_insn_adrp(struct module *mod, __le32 *place, u64 val) · 214 unmodified lines | ||
| 215 | 215 | insn &= ~BIT(31); |
| 216 | 216 | } else { |
| 217 | 217 | /* out of range for ADR -> emit a veneer */ |
| 218 | − val = module_emit_adrp_veneer(mod, place, val & ~0xfff); | |
| 218 | + val = module_emit_veneer_for_adrp(mod, place, val & ~0xfff); | |
| 219 | 219 | if (!val) |
| 220 | 220 | return -ENOEXEC; |
| 221 | 221 | insn = aarch64_insn_gen_branch_imm((u64)place, val, |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/sched/signal.h> |
| 26 | 26 | #include <linux/sched/task_stack.h> |
| 27 | 27 | #include <linux/mm.h> |
| 28 | +#include <linux/nospec.h> | |
| 28 | 29 | #include <linux/smp.h> |
| 29 | 30 | #include <linux/ptrace.h> |
| 30 | 31 | #include <linux/user.h> |
| @@ -249,15 +250,20 @@ static struct perf_event *ptrace_hbp_get_event(unsigned int note_type, · 218 unmodified lines | ||
| 249 | 250 | |
| 250 | 251 | switch (note_type) { |
| 251 | 252 | case NT_ARM_HW_BREAK: |
| 252 | − if (idx < ARM_MAX_BRP) | |
| 253 | − bp = tsk->thread.debug.hbp_break[idx]; | |
| 253 | + if (idx >= ARM_MAX_BRP) | |
| 254 | + goto out; | |
| 255 | + idx = array_index_nospec(idx, ARM_MAX_BRP); | |
| 256 | + bp = tsk->thread.debug.hbp_break[idx]; | |
| 254 | 257 | break; |
| 255 | 258 | case NT_ARM_HW_WATCH: |
| 256 | − if (idx < ARM_MAX_WRP) | |
| 257 | − bp = tsk->thread.debug.hbp_watch[idx]; | |
| 259 | + if (idx >= ARM_MAX_WRP) | |
| 260 | + goto out; | |
| 261 | + idx = array_index_nospec(idx, ARM_MAX_WRP); | |
| 262 | + bp = tsk->thread.debug.hbp_watch[idx]; | |
| 258 | 263 | break; |
| 259 | 264 | } |
| 260 | 265 | |
| 266 | +out: | |
| 261 | 267 | return bp; |
| 262 | 268 | } |
| 263 | 269 | |
| @@ -1458,9 +1464,7 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num, · 1194 unmodified lines | ||
| 1458 | 1464 | { |
| 1459 | 1465 | int ret; |
| 1460 | 1466 | u32 kdata; |
| 1461 | − mm_segment_t old_fs = get_fs(); | |
| 1462 | 1467 | |
| 1463 | − set_fs(KERNEL_DS); | |
| 1464 | 1468 | /* Watchpoint */ |
| 1465 | 1469 | if (num < 0) { |
| 1466 | 1470 | ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata); |
| @@ -1471,7 +1475,6 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num, · 4 unmodified lines | ||
| 1471 | 1475 | } else { |
| 1472 | 1476 | ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata); |
| 1473 | 1477 | } |
| 1474 | − set_fs(old_fs); | |
| 1475 | 1478 | |
| 1476 | 1479 | if (!ret) |
| 1477 | 1480 | ret = put_user(kdata, data); |
| @@ -1484,7 +1487,6 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num, · 6 unmodified lines | ||
| 1484 | 1487 | { |
| 1485 | 1488 | int ret; |
| 1486 | 1489 | u32 kdata = 0; |
| 1487 | − mm_segment_t old_fs = get_fs(); | |
| 1488 | 1490 | |
| 1489 | 1491 | if (num == 0) |
| 1490 | 1492 | return 0; |
| @@ -1493,12 +1495,10 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num, · 2 unmodified lines | ||
| 1493 | 1495 | if (ret) |
| 1494 | 1496 | return ret; |
| 1495 | 1497 | |
| 1496 | − set_fs(KERNEL_DS); | |
| 1497 | 1498 | if (num < 0) |
| 1498 | 1499 | ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata); |
| 1499 | 1500 | else |
| 1500 | 1501 | ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata); |
| 1501 | − set_fs(old_fs); | |
| 1502 | 1502 | |
| 1503 | 1503 | return ret; |
| 1504 | 1504 | } |
| @@ -277,7 +277,8 @@ void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size) · 276 unmodified lines | ||
| 277 | 277 | * If we were single stepping, we want to get the step exception after |
| 278 | 278 | * we return from the trap. |
| 279 | 279 | */ |
| 280 | − user_fastforward_single_step(current); | |
| 280 | + if (user_mode(regs)) | |
| 281 | + user_fastforward_single_step(current); | |
| 281 | 282 | } |
| 282 | 283 | |
| 283 | 284 | static LIST_HEAD(undef_hook); |
| @@ -366,7 +367,7 @@ void force_signal_inject(int signal, int code, unsigned long address) · 82 unmodified lines | ||
| 366 | 367 | } |
| 367 | 368 | |
| 368 | 369 | /* Force signals we don't understand to SIGKILL */ |
| 369 | − if (WARN_ON(signal != SIGKILL || | |
| 370 | + if (WARN_ON(signal != SIGKILL && | |
| 370 | 371 | siginfo_layout(signal, code) != SIL_FAULT)) { |
| 371 | 372 | signal = SIGKILL; |
| 372 | 373 | } |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/module.h> |
| 26 | 26 | #include <linux/vmalloc.h> |
| 27 | 27 | #include <linux/fs.h> |
| 28 | +#include <kvm/arm_psci.h> | |
| 28 | 29 | #include <asm/cputype.h> |
| 29 | 30 | #include <linux/uaccess.h> |
| 30 | 31 | #include <asm/kvm.h> |
| @@ -205,7 +206,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 174 unmodified lines | ||
| 205 | 206 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) |
| 206 | 207 | { |
| 207 | 208 | return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu) |
| 208 | − + NUM_TIMER_REGS; | |
| 209 | + + kvm_arm_get_fw_num_regs(vcpu) + NUM_TIMER_REGS; | |
| 209 | 210 | } |
| 210 | 211 | |
| 211 | 212 | /** |
| @@ -225,6 +226,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) · 13 unmodified lines | ||
| 225 | 226 | uindices++; |
| 226 | 227 | } |
| 227 | 228 | |
| 229 | + ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices); | |
| 230 | + if (ret) | |
| 231 | + return ret; | |
| 232 | + uindices += kvm_arm_get_fw_num_regs(vcpu); | |
| 233 | + | |
| 228 | 234 | ret = copy_timer_indices(vcpu, uindices); |
| 229 | 235 | if (ret) |
| 230 | 236 | return ret; |
| @@ -243,6 +249,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 12 unmodified lines | ||
| 243 | 249 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 244 | 250 | return get_core_reg(vcpu, reg); |
| 245 | 251 | |
| 252 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 253 | + return kvm_arm_get_fw_reg(vcpu, reg); | |
| 254 | + | |
| 246 | 255 | if (is_timer_reg(reg->id)) |
| 247 | 256 | return get_timer_reg(vcpu, reg); |
| 248 | 257 | |
| @@ -259,6 +268,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 10 unmodified lines | ||
| 259 | 268 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 260 | 269 | return set_core_reg(vcpu, reg); |
| 261 | 270 | |
| 271 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 272 | + return kvm_arm_set_fw_reg(vcpu, reg); | |
| 273 | + | |
| 262 | 274 | if (is_timer_reg(reg->id)) |
| 263 | 275 | return set_timer_reg(vcpu, reg); |
| 264 | 276 | |
| @@ -18,11 +18,20 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/compiler.h> |
| 19 | 19 | #include <linux/irqchip/arm-gic.h> |
| 20 | 20 | #include <linux/kvm_host.h> |
| 21 | +#include <linux/swab.h> | |
| 21 | 22 | |
| 22 | 23 | #include <asm/kvm_emulate.h> |
| 23 | 24 | #include <asm/kvm_hyp.h> |
| 24 | 25 | #include <asm/kvm_mmu.h> |
| 25 | 26 | |
| 27 | +static bool __hyp_text __is_be(struct kvm_vcpu *vcpu) | |
| 28 | +{ | |
| 29 | + if (vcpu_mode_is_32bit(vcpu)) | |
| 30 | + return !!(read_sysreg_el2(spsr) & COMPAT_PSR_E_BIT); | |
| 31 | + | |
| 32 | + return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE); | |
| 33 | +} | |
| 34 | + | |
| 26 | 35 | /* |
| 27 | 36 | * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the |
| 28 | 37 | * guest. |
| @@ -64,14 +73,19 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) · 35 unmodified lines | ||
| 64 | 73 | addr += fault_ipa - vgic->vgic_cpu_base; |
| 65 | 74 | |
| 66 | 75 | if (kvm_vcpu_dabt_iswrite(vcpu)) { |
| 67 | − u32 data = vcpu_data_guest_to_host(vcpu, | |
| 68 | − vcpu_get_reg(vcpu, rd), | |
| 69 | − sizeof(u32)); | |
| 76 | + u32 data = vcpu_get_reg(vcpu, rd); | |
| 77 | + if (__is_be(vcpu)) { | |
| 78 | + /* guest pre-swabbed data, undo this for writel() */ | |
| 79 | + data = swab32(data); | |
| 80 | + } | |
| 70 | 81 | writel_relaxed(data, addr); |
| 71 | 82 | } else { |
| 72 | 83 | u32 data = readl_relaxed(addr); |
| 73 | − vcpu_set_reg(vcpu, rd, vcpu_data_host_to_guest(vcpu, data, | |
| 74 | − sizeof(u32))); | |
| 84 | + if (__is_be(vcpu)) { | |
| 85 | + /* guest expects swabbed data */ | |
| 86 | + data = swab32(data); | |
| 87 | + } | |
| 88 | + vcpu_set_reg(vcpu, rd, data); | |
| 75 | 89 | } |
| 76 | 90 | |
| 77 | 91 | return 1; |
| @@ -996,14 +996,12 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz) · 995 unmodified lines | ||
| 996 | 996 | |
| 997 | 997 | if (id == SYS_ID_AA64PFR0_EL1) { |
| 998 | 998 | if (val & (0xfUL << ID_AA64PFR0_SVE_SHIFT)) |
| 999 | − pr_err_once("kvm [%i]: SVE unsupported for guests, suppressing\n", | |
| 1000 | − task_pid_nr(current)); | |
| 999 | + kvm_debug("SVE unsupported for guests, suppressing\n"); | |
| 1001 | 1000 | |
| 1002 | 1001 | val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT); |
| 1003 | 1002 | } else if (id == SYS_ID_AA64MMFR1_EL1) { |
| 1004 | 1003 | if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT)) |
| 1005 | − pr_err_once("kvm [%i]: LORegions unsupported for guests, suppressing\n", | |
| 1006 | − task_pid_nr(current)); | |
| 1004 | + kvm_debug("LORegions unsupported for guests, suppressing\n"); | |
| 1007 | 1005 | |
| 1008 | 1006 | val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT); |
| 1009 | 1007 | } |
| @@ -19,5 +19,9 @@ CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2 \ · 18 unmodified lines | ||
| 19 | 19 | -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15 \ |
| 20 | 20 | -fcall-saved-x18 -fomit-frame-pointer |
| 21 | 21 | CFLAGS_REMOVE_atomic_ll_sc.o := -pg |
| 22 | +GCOV_PROFILE_atomic_ll_sc.o := n | |
| 23 | +KASAN_SANITIZE_atomic_ll_sc.o := n | |
| 24 | +KCOV_INSTRUMENT_atomic_ll_sc.o := n | |
| 25 | +UBSAN_SANITIZE_atomic_ll_sc.o := n | |
| 22 | 26 | |
| 23 | 27 | lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o |
| @@ -58,7 +58,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, · 57 unmodified lines | ||
| 58 | 58 | flush_ptrace_access(vma, page, uaddr, dst, len); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | −void __sync_icache_dcache(pte_t pte, unsigned long addr) | |
| 61 | +void __sync_icache_dcache(pte_t pte) | |
| 62 | 62 | { |
| 63 | 63 | struct page *page = pte_page(pte); |
| 64 | 64 | |
| @@ -204,7 +204,7 @@ void __init kasan_init(void) · 203 unmodified lines | ||
| 204 | 204 | clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END); |
| 205 | 205 | |
| 206 | 206 | kasan_map_populate(kimg_shadow_start, kimg_shadow_end, |
| 207 | − pfn_to_nid(virt_to_pfn(lm_alias(_text)))); | |
| 207 | + early_pfn_to_nid(virt_to_pfn(lm_alias(_text)))); | |
| 208 | 208 | |
| 209 | 209 | kasan_populate_zero_shadow((void *)KASAN_SHADOW_START, |
| 210 | 210 | (void *)mod_shadow_start); |
| @@ -224,7 +224,7 @@ void __init kasan_init(void) · 13 unmodified lines | ||
| 224 | 224 | |
| 225 | 225 | kasan_map_populate((unsigned long)kasan_mem_to_shadow(start), |
| 226 | 226 | (unsigned long)kasan_mem_to_shadow(end), |
| 227 | − pfn_to_nid(virt_to_pfn(start))); | |
| 227 | + early_pfn_to_nid(virt_to_pfn(start))); | |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | /* |
| @@ -216,6 +216,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, · 215 unmodified lines | ||
| 216 | 216 | memcpy((void *) dst, src, count); |
| 217 | 217 | } |
| 218 | 218 | |
| 219 | +static inline void memset_io(volatile void __iomem *addr, int value, | |
| 220 | + size_t size) | |
| 221 | +{ | |
| 222 | + memset((void __force *)addr, value, size); | |
| 223 | +} | |
| 224 | + | |
| 219 | 225 | #define PCI_IO_ADDR (volatile void __iomem *) |
| 220 | 226 | |
| 221 | 227 | /* |
| @@ -199,3 +199,4 @@ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) · 198 unmodified lines | ||
| 199 | 199 | memcpy(dst, src, len); |
| 200 | 200 | return csum_partial(dst, len, sum); |
| 201 | 201 | } |
| 202 | +EXPORT_SYMBOL(csum_partial_copy_nocheck); | |
| @@ -51,6 +51,8 @@ · 50 unmodified lines | ||
| 51 | 51 | ranges = <0x02000000 0 0x40000000 |
| 52 | 52 | 0x40000000 0 0x40000000>; |
| 53 | 53 | |
| 54 | + bus-range = <0x00 0xff>; | |
| 55 | + | |
| 54 | 56 | interrupt-map-mask = <0 0 0 7>; |
| 55 | 57 | interrupt-map = <0 0 0 1 &pci0_intc 1>, |
| 56 | 58 | <0 0 0 2 &pci0_intc 2>, |
| @@ -79,6 +81,8 @@ · 22 unmodified lines | ||
| 79 | 81 | ranges = <0x02000000 0 0x20000000 |
| 80 | 82 | 0x20000000 0 0x20000000>; |
| 81 | 83 | |
| 84 | + bus-range = <0x00 0xff>; | |
| 85 | + | |
| 82 | 86 | interrupt-map-mask = <0 0 0 7>; |
| 83 | 87 | interrupt-map = <0 0 0 1 &pci1_intc 1>, |
| 84 | 88 | <0 0 0 2 &pci1_intc 2>, |
| @@ -107,6 +111,8 @@ · 22 unmodified lines | ||
| 107 | 111 | ranges = <0x02000000 0 0x16000000 |
| 108 | 112 | 0x16000000 0 0x100000>; |
| 109 | 113 | |
| 114 | + bus-range = <0x00 0xff>; | |
| 115 | + | |
| 110 | 116 | interrupt-map-mask = <0 0 0 7>; |
| 111 | 117 | interrupt-map = <0 0 0 1 &pci2_intc 1>, |
| 112 | 118 | <0 0 0 2 &pci2_intc 2>, |
| @@ -307,7 +307,7 @@ static inline void iounmap(const volatile void __iomem *addr) · 306 unmodified lines | ||
| 307 | 307 | #if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT) |
| 308 | 308 | #define war_io_reorder_wmb() wmb() |
| 309 | 309 | #else |
| 310 | −#define war_io_reorder_wmb() do { } while (0) | |
| 310 | +#define war_io_reorder_wmb() barrier() | |
| 311 | 311 | #endif |
| 312 | 312 | |
| 313 | 313 | #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ |
| @@ -377,6 +377,8 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ · 63 unmodified lines | ||
| 377 | 377 | BUG(); \ |
| 378 | 378 | } \ |
| 379 | 379 | \ |
| 380 | + /* prevent prefetching of coherent DMA data prematurely */ \ | |
| 381 | + rmb(); \ | |
| 380 | 382 | return pfx##ioswab##bwlq(__mem, __val); \ |
| 381 | 383 | } |
| 382 | 384 | |
| @@ -654,6 +654,13 @@ __clear_user(void __user *addr, __kernel_size_t size) · 653 unmodified lines | ||
| 654 | 654 | { |
| 655 | 655 | __kernel_size_t res; |
| 656 | 656 | |
| 657 | +#ifdef CONFIG_CPU_MICROMIPS | |
| 658 | +/* micromips memset / bzero also clobbers t7 & t8 */ | |
| 659 | +#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$15", "$24", "$31" | |
| 660 | +#else | |
| 661 | +#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31" | |
| 662 | +#endif /* CONFIG_CPU_MICROMIPS */ | |
| 663 | + | |
| 657 | 664 | if (eva_kernel_access()) { |
| 658 | 665 | __asm__ __volatile__( |
| 659 | 666 | "move\t$4, %1\n\t" |
| @@ -663,7 +670,7 @@ __clear_user(void __user *addr, __kernel_size_t size) · 3 unmodified lines | ||
| 663 | 670 | "move\t%0, $6" |
| 664 | 671 | : "=r" (res) |
| 665 | 672 | : "r" (addr), "r" (size) |
| 666 | − : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); | |
| 673 | + : bzero_clobbers); | |
| 667 | 674 | } else { |
| 668 | 675 | might_fault(); |
| 669 | 676 | __asm__ __volatile__( |
| @@ -674,7 +681,7 @@ __clear_user(void __user *addr, __kernel_size_t size) · 4 unmodified lines | ||
| 674 | 681 | "move\t%0, $6" |
| 675 | 682 | : "=r" (res) |
| 676 | 683 | : "r" (addr), "r" (size) |
| 677 | − : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); | |
| 684 | + : bzero_clobbers); | |
| 678 | 685 | } |
| 679 | 686 | |
| 680 | 687 | return res; |
| @@ -219,7 +219,7 @@ · 218 unmodified lines | ||
| 219 | 219 | 1: PTR_ADDIU a0, 1 /* fill bytewise */ |
| 220 | 220 | R10KCBARRIER(0(ra)) |
| 221 | 221 | bne t1, a0, 1b |
| 222 | − sb a1, -1(a0) | |
| 222 | + EX(sb, a1, -1(a0), .Lsmall_fixup\@) | |
| 223 | 223 | |
| 224 | 224 | 2: jr ra /* done */ |
| 225 | 225 | move a2, zero |
| @@ -252,13 +252,18 @@ · 26 unmodified lines | ||
| 252 | 252 | PTR_L t0, TI_TASK($28) |
| 253 | 253 | andi a2, STORMASK |
| 254 | 254 | LONG_L t0, THREAD_BUADDR(t0) |
| 255 | − LONG_ADDU a2, t1 | |
| 255 | + LONG_ADDU a2, a0 | |
| 256 | 256 | jr ra |
| 257 | 257 | LONG_SUBU a2, t0 |
| 258 | 258 | |
| 259 | 259 | .Llast_fixup\@: |
| 260 | 260 | jr ra |
| 261 | − andi v1, a2, STORMASK | |
| 261 | + nop | |
| 262 | + | |
| 263 | +.Lsmall_fixup\@: | |
| 264 | + PTR_SUBU a2, t1, a0 | |
| 265 | + jr ra | |
| 266 | + PTR_ADDIU a2, 1 | |
| 262 | 267 | |
| 263 | 268 | .endm |
| 264 | 269 | |
| @@ -123,6 +123,9 @@ INSTALL_TARGETS = zinstall install · 122 unmodified lines | ||
| 123 | 123 | |
| 124 | 124 | PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS) |
| 125 | 125 | |
| 126 | +# Default kernel to build | |
| 127 | +all: bzImage | |
| 128 | + | |
| 126 | 129 | zImage: vmlinuz |
| 127 | 130 | Image: vmlinux |
| 128 | 131 | |
| @@ -23,7 +23,7 @@ obj-$(CONFIG_SMP) += smp.o · 22 unmodified lines | ||
| 23 | 23 | obj-$(CONFIG_PA11) += pci-dma.o |
| 24 | 24 | obj-$(CONFIG_PCI) += pci.o |
| 25 | 25 | obj-$(CONFIG_MODULES) += module.o |
| 26 | −obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o | |
| 26 | +obj-$(CONFIG_64BIT) += sys_parisc32.o signal32.o | |
| 27 | 27 | obj-$(CONFIG_STACKTRACE)+= stacktrace.o |
| 28 | 28 | obj-$(CONFIG_AUDIT) += audit.o |
| 29 | 29 | obj64-$(CONFIG_AUDIT) += compat_audit.o |
| @@ -448,7 +448,8 @@ static int match_by_id(struct device * dev, void * data) · 447 unmodified lines | ||
| 448 | 448 | * Checks all the children of @parent for a matching @id. If none |
| 449 | 449 | * found, it allocates a new device and returns it. |
| 450 | 450 | */ |
| 451 | −static struct parisc_device * alloc_tree_node(struct device *parent, char id) | |
| 451 | +static struct parisc_device * __init alloc_tree_node( | |
| 452 | + struct device *parent, char id) | |
| 452 | 453 | { |
| 453 | 454 | struct match_id_data d = { |
| 454 | 455 | .id = id, |
| @@ -825,8 +826,8 @@ static void walk_lower_bus(struct parisc_device *dev) · 370 unmodified lines | ||
| 825 | 826 | * devices which are not physically connected (such as extra serial & |
| 826 | 827 | * keyboard ports). This problem is not yet solved. |
| 827 | 828 | */ |
| 828 | −static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, | |
| 829 | − struct device *parent) | |
| 829 | +static void __init walk_native_bus(unsigned long io_io_low, | |
| 830 | + unsigned long io_io_high, struct device *parent) | |
| 830 | 831 | { |
| 831 | 832 | int i, devices_found = 0; |
| 832 | 833 | unsigned long hpa = io_io_low; |
| @@ -174,7 +174,7 @@ void pcibios_set_master(struct pci_dev *dev) · 173 unmodified lines | ||
| 174 | 174 | * pcibios_init_bridge() initializes cache line and default latency |
| 175 | 175 | * for pci controllers and pci-pci bridges |
| 176 | 176 | */ |
| 177 | −void __init pcibios_init_bridge(struct pci_dev *dev) | |
| 177 | +void __ref pcibios_init_bridge(struct pci_dev *dev) | |
| 178 | 178 | { |
| 179 | 179 | unsigned short bridge_ctl, bridge_ctl_new; |
| 180 | 180 | |
| @@ -205,7 +205,7 @@ static int __init rtc_init(void) · 204 unmodified lines | ||
| 205 | 205 | device_initcall(rtc_init); |
| 206 | 206 | #endif |
| 207 | 207 | |
| 208 | −void read_persistent_clock(struct timespec *ts) | |
| 208 | +void read_persistent_clock64(struct timespec64 *ts) | |
| 209 | 209 | { |
| 210 | 210 | static struct pdc_tod tod_data; |
| 211 | 211 | if (pdc_tod_read(&tod_data) == 0) { |
| @@ -837,6 +837,17 @@ void __init initialize_ivt(const void *iva) · 836 unmodified lines | ||
| 837 | 837 | if (pdc_instr(&instr) == PDC_OK) |
| 838 | 838 | ivap[0] = instr; |
| 839 | 839 | |
| 840 | + /* | |
| 841 | + * Rules for the checksum of the HPMC handler: | |
| 842 | + * 1. The IVA does not point to PDC/PDH space (ie: the OS has installed | |
| 843 | + * its own IVA). | |
| 844 | + * 2. The word at IVA + 32 is nonzero. | |
| 845 | + * 3. If Length (IVA + 60) is not zero, then Length (IVA + 60) and | |
| 846 | + * Address (IVA + 56) are word-aligned. | |
| 847 | + * 4. The checksum of the 8 words starting at IVA + 32 plus the sum of | |
| 848 | + * the Length/4 words starting at Address is zero. | |
| 849 | + */ | |
| 850 | + | |
| 840 | 851 | /* Compute Checksum for HPMC handler */ |
| 841 | 852 | length = os_hpmc_size; |
| 842 | 853 | ivap[7] = length; |
| @@ -516,7 +516,7 @@ static void __init map_pages(unsigned long start_vaddr, · 515 unmodified lines | ||
| 516 | 516 | } |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | −void free_initmem(void) | |
| 519 | +void __ref free_initmem(void) | |
| 520 | 520 | { |
| 521 | 521 | unsigned long init_begin = (unsigned long)__init_begin; |
| 522 | 522 | unsigned long init_end = (unsigned long)__init_end; |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | extern void powernv_set_nmmu_ptcr(unsigned long ptcr); |
| 16 | 16 | extern struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, |
| 17 | 17 | unsigned long flags, |
| 18 | − struct npu_context *(*cb)(struct npu_context *, void *), | |
| 18 | + void (*cb)(struct npu_context *, void *), | |
| 19 | 19 | void *priv); |
| 20 | 20 | extern void pnv_npu2_destroy_context(struct npu_context *context, |
| 21 | 21 | struct pci_dev *gpdev); |
| @@ -807,7 +807,8 @@ static void eeh_restore_bridge_bars(struct eeh_dev *edev) · 806 unmodified lines | ||
| 807 | 807 | eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]); |
| 808 | 808 | |
| 809 | 809 | /* PCI Command: 0x4 */ |
| 810 | − eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1]); | |
| 810 | + eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1] | | |
| 811 | + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); | |
| 811 | 812 | |
| 812 | 813 | /* Check the PCIe link is ready */ |
| 813 | 814 | eeh_bridge_check_link(edev); |
| @@ -553,12 +553,12 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300) · 552 unmodified lines | ||
| 553 | 553 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE |
| 554 | 554 | lbz r0,HSTATE_HWTHREAD_STATE(r13) |
| 555 | 555 | cmpwi r0,KVM_HWTHREAD_IN_KERNEL |
| 556 | − beq 1f | |
| 556 | + beq 0f | |
| 557 | 557 | li r0,KVM_HWTHREAD_IN_KERNEL |
| 558 | 558 | stb r0,HSTATE_HWTHREAD_STATE(r13) |
| 559 | 559 | /* Order setting hwthread_state vs. testing hwthread_req */ |
| 560 | 560 | sync |
| 561 | − lbz r0,HSTATE_HWTHREAD_REQ(r13) | |
| 561 | +0: lbz r0,HSTATE_HWTHREAD_REQ(r13) | |
| 562 | 562 | cmpwi r0,0 |
| 563 | 563 | beq 1f |
| 564 | 564 | b kvm_start_guest |
| @@ -441,7 +441,6 @@ static int mce_handle_ierror(struct pt_regs *regs, · 440 unmodified lines | ||
| 441 | 441 | if (pfn != ULONG_MAX) { |
| 442 | 442 | *phys_addr = |
| 443 | 443 | (pfn << PAGE_SHIFT); |
| 444 | − handled = 1; | |
| 445 | 444 | } |
| 446 | 445 | } |
| 447 | 446 | } |
| @@ -532,9 +531,7 @@ static int mce_handle_derror(struct pt_regs *regs, · 84 unmodified lines | ||
| 532 | 531 | * kernel/exception-64s.h |
| 533 | 532 | */ |
| 534 | 533 | if (get_paca()->in_mce < MAX_MCE_DEPTH) |
| 535 | − if (!mce_find_instr_ea_and_pfn(regs, addr, | |
| 536 | − phys_addr)) | |
| 537 | − handled = 1; | |
| 534 | + mce_find_instr_ea_and_pfn(regs, addr, phys_addr); | |
| 538 | 535 | } |
| 539 | 536 | found = 1; |
| 540 | 537 | } |
| @@ -572,7 +569,7 @@ static long mce_handle_error(struct pt_regs *regs, · 31 unmodified lines | ||
| 572 | 569 | const struct mce_ierror_table itable[]) |
| 573 | 570 | { |
| 574 | 571 | struct mce_error_info mce_err = { 0 }; |
| 575 | − uint64_t addr, phys_addr; | |
| 572 | + uint64_t addr, phys_addr = ULONG_MAX; | |
| 576 | 573 | uint64_t srr1 = regs->msr; |
| 577 | 574 | long handled; |
| 578 | 575 | |
| @@ -890,6 +890,17 @@ static void __ref init_fallback_flush(void) · 889 unmodified lines | ||
| 890 | 890 | return; |
| 891 | 891 | |
| 892 | 892 | l1d_size = ppc64_caches.l1d.size; |
| 893 | + | |
| 894 | + /* | |
| 895 | + * If there is no d-cache-size property in the device tree, l1d_size | |
| 896 | + * could be zero. That leads to the loop in the asm wrapping around to | |
| 897 | + * 2^64-1, and then walking off the end of the fallback area and | |
| 898 | + * eventually causing a page fault which is fatal. Just default to | |
| 899 | + * something vaguely sane. | |
| 900 | + */ | |
| 901 | + if (!l1d_size) | |
| 902 | + l1d_size = (64 * 1024); | |
| 903 | + | |
| 893 | 904 | limit = min(ppc64_bolted_size(), ppc64_rma_size); |
| 894 | 905 | |
| 895 | 906 | /* |
| @@ -566,10 +566,35 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) · 565 unmodified lines | ||
| 566 | 566 | #endif |
| 567 | 567 | |
| 568 | 568 | #ifdef CONFIG_NMI_IPI |
| 569 | −static void stop_this_cpu(struct pt_regs *regs) | |
| 570 | −#else | |
| 569 | +static void nmi_stop_this_cpu(struct pt_regs *regs) | |
| 570 | +{ | |
| 571 | + /* | |
| 572 | + * This is a special case because it never returns, so the NMI IPI | |
| 573 | + * handling would never mark it as done, which makes any later | |
| 574 | + * smp_send_nmi_ipi() call spin forever. Mark it done now. | |
| 575 | + * | |
| 576 | + * IRQs are already hard disabled by the smp_handle_nmi_ipi. | |
| 577 | + */ | |
| 578 | + nmi_ipi_lock(); | |
| 579 | + nmi_ipi_busy_count--; | |
| 580 | + nmi_ipi_unlock(); | |
| 581 | + | |
| 582 | + /* Remove this CPU */ | |
| 583 | + set_cpu_online(smp_processor_id(), false); | |
| 584 | + | |
| 585 | + spin_begin(); | |
| 586 | + while (1) | |
| 587 | + spin_cpu_relax(); | |
| 588 | +} | |
| 589 | + | |
| 590 | +void smp_send_stop(void) | |
| 591 | +{ | |
| 592 | + smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, nmi_stop_this_cpu, 1000000); | |
| 593 | +} | |
| 594 | + | |
| 595 | +#else /* CONFIG_NMI_IPI */ | |
| 596 | + | |
| 571 | 597 | static void stop_this_cpu(void *dummy) |
| 572 | −#endif | |
| 573 | 598 | { |
| 574 | 599 | /* Remove this CPU */ |
| 575 | 600 | set_cpu_online(smp_processor_id(), false); |
| @@ -582,12 +607,22 @@ static void stop_this_cpu(void *dummy) · 6 unmodified lines | ||
| 582 | 607 | |
| 583 | 608 | void smp_send_stop(void) |
| 584 | 609 | { |
| 585 | −#ifdef CONFIG_NMI_IPI | |
| 586 | − smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, stop_this_cpu, 1000000); | |
| 587 | −#else | |
| 610 | + static bool stopped = false; | |
| 611 | + | |
| 612 | + /* | |
| 613 | + * Prevent waiting on csd lock from a previous smp_send_stop. | |
| 614 | + * This is racy, but in general callers try to do the right | |
| 615 | + * thing and only fire off one smp_send_stop (e.g., see | |
| 616 | + * kernel/panic.c) | |
| 617 | + */ | |
| 618 | + if (stopped) | |
| 619 | + return; | |
| 620 | + | |
| 621 | + stopped = true; | |
| 622 | + | |
| 588 | 623 | smp_call_function(stop_this_cpu, NULL, 0); |
| 589 | −#endif | |
| 590 | 624 | } |
| 625 | +#endif /* CONFIG_NMI_IPI */ | |
| 591 | 626 | |
| 592 | 627 | struct thread_info *current_set[NR_CPUS]; |
| 593 | 628 | |
| @@ -305,6 +305,13 @@ void kvmppc_core_queue_fpunavail(struct kvm_vcpu *vcpu) · 304 unmodified lines | ||
| 305 | 305 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_FP_UNAVAIL); |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | +#ifdef CONFIG_ALTIVEC | |
| 309 | +void kvmppc_core_queue_vec_unavail(struct kvm_vcpu *vcpu) | |
| 310 | +{ | |
| 311 | + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ALTIVEC_UNAVAIL); | |
| 312 | +} | |
| 313 | +#endif | |
| 314 | + | |
| 308 | 315 | void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu) |
| 309 | 316 | { |
| 310 | 317 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DECREMENTER); |
| @@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, · 54 unmodified lines | ||
| 55 | 55 | unsigned int *target = (unsigned int *)branch_target(src); |
| 56 | 56 | |
| 57 | 57 | /* Branch within the section doesn't need translating */ |
| 58 | − if (target < alt_start || target >= alt_end) { | |
| 58 | + if (target < alt_start || target > alt_end) { | |
| 59 | 59 | instr = translate_branch(dest, src); |
| 60 | 60 | if (!instr) |
| 61 | 61 | return 1; |
| @@ -133,6 +133,7 @@ int __meminit arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap * · 132 unmodified lines | ||
| 133 | 133 | start, start + size, rc); |
| 134 | 134 | return -EFAULT; |
| 135 | 135 | } |
| 136 | + flush_inval_dcache_range(start, start + size); | |
| 136 | 137 | |
| 137 | 138 | return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); |
| 138 | 139 | } |
| @@ -159,6 +160,7 @@ int __meminit arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap · 20 unmodified lines | ||
| 159 | 160 | |
| 160 | 161 | /* Remove htab bolted mappings for this section of memory */ |
| 161 | 162 | start = (unsigned long)__va(start); |
| 163 | + flush_inval_dcache_range(start, start + size); | |
| 162 | 164 | ret = remove_section_mapping(start, start + size); |
| 163 | 165 | |
| 164 | 166 | /* Ensure all vmalloc mappings are flushed in case they also |
| @@ -1093,7 +1093,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private) · 1092 unmodified lines | ||
| 1093 | 1093 | LOAD_INT(c), LOAD_FRAC(c), |
| 1094 | 1094 | count_active_contexts(), |
| 1095 | 1095 | atomic_read(&nr_spu_contexts), |
| 1096 | − idr_get_cursor(&task_active_pid_ns(current)->idr)); | |
| 1096 | + idr_get_cursor(&task_active_pid_ns(current)->idr) - 1); | |
| 1097 | 1097 | return 0; |
| 1098 | 1098 | } |
| 1099 | 1099 | |
| @@ -82,19 +82,6 @@ static const struct file_operations memtrace_fops = { · 81 unmodified lines | ||
| 82 | 82 | .open = simple_open, |
| 83 | 83 | }; |
| 84 | 84 | |
| 85 | −static void flush_memory_region(u64 base, u64 size) | |
| 86 | −{ | |
| 87 | − unsigned long line_size = ppc64_caches.l1d.size; | |
| 88 | − u64 end = base + size; | |
| 89 | − u64 addr; | |
| 90 | − | |
| 91 | − base = round_down(base, line_size); | |
| 92 | − end = round_up(end, line_size); | |
| 93 | − | |
| 94 | − for (addr = base; addr < end; addr += line_size) | |
| 95 | − asm volatile("dcbf 0,%0" : "=r" (addr) :: "memory"); | |
| 96 | −} | |
| 97 | − | |
| 98 | 85 | static int check_memblock_online(struct memory_block *mem, void *arg) |
| 99 | 86 | { |
| 100 | 87 | if (mem->state != MEM_ONLINE) |
| @@ -132,10 +119,6 @@ static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages) · 31 unmodified lines | ||
| 132 | 119 | walk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE, |
| 133 | 120 | change_memblock_state); |
| 134 | 121 | |
| 135 | − /* RCU grace period? */ | |
| 136 | − flush_memory_region((u64)__va(start_pfn << PAGE_SHIFT), | |
| 137 | − nr_pages << PAGE_SHIFT); | |
| 138 | − | |
| 139 | 122 | lock_device_hotplug(); |
| 140 | 123 | remove_memory(nid, start_pfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT); |
| 141 | 124 | unlock_device_hotplug(); |
| @@ -33,6 +33,19 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #define npu_to_phb(x) container_of(x, struct pnv_phb, npu) |
| 35 | 35 | |
| 36 | +/* | |
| 37 | + * spinlock to protect initialisation of an npu_context for a particular | |
| 38 | + * mm_struct. | |
| 39 | + */ | |
| 40 | +static DEFINE_SPINLOCK(npu_context_lock); | |
| 41 | + | |
| 42 | +/* | |
| 43 | + * When an address shootdown range exceeds this threshold we invalidate the | |
| 44 | + * entire TLB on the GPU for the given PID rather than each specific address in | |
| 45 | + * the range. | |
| 46 | + */ | |
| 47 | +#define ATSD_THRESHOLD (2*1024*1024) | |
| 48 | + | |
| 36 | 49 | /* |
| 37 | 50 | * Other types of TCE cache invalidation are not functional in the |
| 38 | 51 | * hardware. |
| @@ -401,7 +414,7 @@ struct npu_context { · 362 unmodified lines | ||
| 401 | 414 | bool nmmu_flush; |
| 402 | 415 | |
| 403 | 416 | /* Callback to stop translation requests on a given GPU */ |
| 404 | − struct npu_context *(*release_cb)(struct npu_context *, void *); | |
| 417 | + void (*release_cb)(struct npu_context *context, void *priv); | |
| 405 | 418 | |
| 406 | 419 | /* |
| 407 | 420 | * Private pointer passed to the above callback for usage by |
| @@ -671,11 +684,19 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, · 263 unmodified lines | ||
| 671 | 684 | struct npu_context *npu_context = mn_to_npu_context(mn); |
| 672 | 685 | unsigned long address; |
| 673 | 686 | |
| 674 | − for (address = start; address < end; address += PAGE_SIZE) | |
| 675 | − mmio_invalidate(npu_context, 1, address, false); | |
| 687 | + if (end - start > ATSD_THRESHOLD) { | |
| 688 | + /* | |
| 689 | + * Just invalidate the entire PID if the address range is too | |
| 690 | + * large. | |
| 691 | + */ | |
| 692 | + mmio_invalidate(npu_context, 0, 0, true); | |
| 693 | + } else { | |
| 694 | + for (address = start; address < end; address += PAGE_SIZE) | |
| 695 | + mmio_invalidate(npu_context, 1, address, false); | |
| 676 | 696 | |
| 677 | − /* Do the flush only on the final addess == end */ | |
| 678 | − mmio_invalidate(npu_context, 1, address, true); | |
| 697 | + /* Do the flush only on the final addess == end */ | |
| 698 | + mmio_invalidate(npu_context, 1, address, true); | |
| 699 | + } | |
| 679 | 700 | } |
| 680 | 701 | |
| 681 | 702 | static const struct mmu_notifier_ops nv_nmmu_notifier_ops = { |
| @@ -696,11 +717,12 @@ static const struct mmu_notifier_ops nv_nmmu_notifier_ops = { · 14 unmodified lines | ||
| 696 | 717 | * Returns an error if there no contexts are currently available or a |
| 697 | 718 | * npu_context which should be passed to pnv_npu2_handle_fault(). |
| 698 | 719 | * |
| 699 | − * mmap_sem must be held in write mode. | |
| 720 | + * mmap_sem must be held in write mode and must not be called from interrupt | |
| 721 | + * context. | |
| 700 | 722 | */ |
| 701 | 723 | struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, |
| 702 | 724 | unsigned long flags, |
| 703 | − struct npu_context *(*cb)(struct npu_context *, void *), | |
| 725 | + void (*cb)(struct npu_context *, void *), | |
| 704 | 726 | void *priv) |
| 705 | 727 | { |
| 706 | 728 | int rc; |
| @@ -743,7 +765,9 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, · 36 unmodified lines | ||
| 743 | 765 | /* |
| 744 | 766 | * Setup the NPU context table for a particular GPU. These need to be |
| 745 | 767 | * per-GPU as we need the tables to filter ATSDs when there are no |
| 746 | − * active contexts on a particular GPU. | |
| 768 | + * active contexts on a particular GPU. It is safe for these to be | |
| 769 | + * called concurrently with destroy as the OPAL call takes appropriate | |
| 770 | + * locks and refcounts on init/destroy. | |
| 747 | 771 | */ |
| 748 | 772 | rc = opal_npu_init_context(nphb->opal_id, mm->context.id, flags, |
| 749 | 773 | PCI_DEVID(gpdev->bus->number, gpdev->devfn)); |
| @@ -754,8 +778,29 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, · 4 unmodified lines | ||
| 754 | 778 | * We store the npu pci device so we can more easily get at the |
| 755 | 779 | * associated npus. |
| 756 | 780 | */ |
| 781 | + spin_lock(&npu_context_lock); | |
| 757 | 782 | npu_context = mm->context.npu_context; |
| 783 | + if (npu_context) { | |
| 784 | + if (npu_context->release_cb != cb || | |
| 785 | + npu_context->priv != priv) { | |
| 786 | + spin_unlock(&npu_context_lock); | |
| 787 | + opal_npu_destroy_context(nphb->opal_id, mm->context.id, | |
| 788 | + PCI_DEVID(gpdev->bus->number, | |
| 789 | + gpdev->devfn)); | |
| 790 | + return ERR_PTR(-EINVAL); | |
| 791 | + } | |
| 792 | + | |
| 793 | + WARN_ON(!kref_get_unless_zero(&npu_context->kref)); | |
| 794 | + } | |
| 795 | + spin_unlock(&npu_context_lock); | |
| 796 | + | |
| 758 | 797 | if (!npu_context) { |
| 798 | + /* | |
| 799 | + * We can set up these fields without holding the | |
| 800 | + * npu_context_lock as the npu_context hasn't been returned to | |
| 801 | + * the caller meaning it can't be destroyed. Parallel allocation | |
| 802 | + * is protected against by mmap_sem. | |
| 803 | + */ | |
| 759 | 804 | rc = -ENOMEM; |
| 760 | 805 | npu_context = kzalloc(sizeof(struct npu_context), GFP_KERNEL); |
| 761 | 806 | if (npu_context) { |
| @@ -774,8 +819,6 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, · 12 unmodified lines | ||
| 774 | 819 | } |
| 775 | 820 | |
| 776 | 821 | mm->context.npu_context = npu_context; |
| 777 | − } else { | |
| 778 | − WARN_ON(!kref_get_unless_zero(&npu_context->kref)); | |
| 779 | 822 | } |
| 780 | 823 | |
| 781 | 824 | npu_context->release_cb = cb; |
| @@ -814,15 +857,16 @@ static void pnv_npu2_release_context(struct kref *kref) · 32 unmodified lines | ||
| 814 | 857 | mm_context_remove_copro(npu_context->mm); |
| 815 | 858 | |
| 816 | 859 | npu_context->mm->context.npu_context = NULL; |
| 817 | − mmu_notifier_unregister(&npu_context->mn, | |
| 818 | − npu_context->mm); | |
| 819 | − | |
| 820 | − kfree(npu_context); | |
| 821 | 860 | } |
| 822 | 861 | |
| 862 | +/* | |
| 863 | + * Destroy a context on the given GPU. May free the npu_context if it is no | |
| 864 | + * longer active on any GPUs. Must not be called from interrupt context. | |
| 865 | + */ | |
| 823 | 866 | void pnv_npu2_destroy_context(struct npu_context *npu_context, |
| 824 | 867 | struct pci_dev *gpdev) |
| 825 | 868 | { |
| 869 | + int removed; | |
| 826 | 870 | struct pnv_phb *nphb; |
| 827 | 871 | struct npu *npu; |
| 828 | 872 | struct pci_dev *npdev = pnv_pci_get_npu_dev(gpdev, 0); |
| @@ -844,7 +888,21 @@ void pnv_npu2_destroy_context(struct npu_context *npu_context, · 15 unmodified lines | ||
| 844 | 888 | WRITE_ONCE(npu_context->npdev[npu->index][nvlink_index], NULL); |
| 845 | 889 | opal_npu_destroy_context(nphb->opal_id, npu_context->mm->context.id, |
| 846 | 890 | PCI_DEVID(gpdev->bus->number, gpdev->devfn)); |
| 847 | − kref_put(&npu_context->kref, pnv_npu2_release_context); | |
| 891 | + spin_lock(&npu_context_lock); | |
| 892 | + removed = kref_put(&npu_context->kref, pnv_npu2_release_context); | |
| 893 | + spin_unlock(&npu_context_lock); | |
| 894 | + | |
| 895 | + /* | |
| 896 | + * We need to do this outside of pnv_npu2_release_context so that it is | |
| 897 | + * outside the spinlock as mmu_notifier_destroy uses SRCU. | |
| 898 | + */ | |
| 899 | + if (removed) { | |
| 900 | + mmu_notifier_unregister(&npu_context->mn, | |
| 901 | + npu_context->mm); | |
| 902 | + | |
| 903 | + kfree(npu_context); | |
| 904 | + } | |
| 905 | + | |
| 848 | 906 | } |
| 849 | 907 | EXPORT_SYMBOL(pnv_npu2_destroy_context); |
| 850 | 908 | |
| @@ -48,10 +48,12 @@ unsigned long __init opal_get_boot_time(void) · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { |
| 50 | 50 | rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); |
| 51 | − if (rc == OPAL_BUSY_EVENT) | |
| 51 | + if (rc == OPAL_BUSY_EVENT) { | |
| 52 | + mdelay(OPAL_BUSY_DELAY_MS); | |
| 52 | 53 | opal_poll_events(NULL); |
| 53 | − else if (rc == OPAL_BUSY) | |
| 54 | − mdelay(10); | |
| 54 | + } else if (rc == OPAL_BUSY) { | |
| 55 | + mdelay(OPAL_BUSY_DELAY_MS); | |
| 56 | + } | |
| 55 | 57 | } |
| 56 | 58 | if (rc != OPAL_SUCCESS) |
| 57 | 59 | return 0; |
| @@ -389,6 +389,10 @@ static void xive_native_setup_cpu(unsigned int cpu, struct xive_cpu *xc) · 388 unmodified lines | ||
| 389 | 389 | if (xive_pool_vps == XIVE_INVALID_VP) |
| 390 | 390 | return; |
| 391 | 391 | |
| 392 | + /* Check if pool VP already active, if it is, pull it */ | |
| 393 | + if (in_be32(xive_tima + TM_QW2_HV_POOL + TM_WORD2) & TM_QW2W2_VP) | |
| 394 | + in_be64(xive_tima + TM_SPC_PULL_POOL_CTX); | |
| 395 | + | |
| 392 | 396 | /* Enable the pool VP */ |
| 393 | 397 | vp = xive_pool_vps + cpu; |
| 394 | 398 | pr_debug("CPU %d setting up pool VP 0x%x\n", cpu, vp); |
| @@ -11,6 +11,7 @@ config RISCV · 10 unmodified lines | ||
| 11 | 11 | select ARCH_WANT_FRAME_POINTERS |
| 12 | 12 | select CLONE_BACKWARDS |
| 13 | 13 | select COMMON_CLK |
| 14 | + select DMA_DIRECT_OPS | |
| 14 | 15 | select GENERIC_CLOCKEVENTS |
| 15 | 16 | select GENERIC_CPU_DEVICES |
| 16 | 17 | select GENERIC_IRQ_SHOW |
| @@ -89,9 +90,6 @@ config PGTABLE_LEVELS · 72 unmodified lines | ||
| 89 | 90 | config HAVE_KPROBES |
| 90 | 91 | def_bool n |
| 91 | 92 | |
| 92 | −config DMA_DIRECT_OPS | |
| 93 | − def_bool y | |
| 94 | − | |
| 95 | 93 | menu "Platform type" |
| 96 | 94 | |
| 97 | 95 | choice |
| @@ -15,7 +15,6 @@ generic-y += fcntl.h · 14 unmodified lines | ||
| 15 | 15 | generic-y += futex.h |
| 16 | 16 | generic-y += hardirq.h |
| 17 | 17 | generic-y += hash.h |
| 18 | −generic-y += handle_irq.h | |
| 19 | 18 | generic-y += hw_irq.h |
| 20 | 19 | generic-y += ioctl.h |
| 21 | 20 | generic-y += ioctls.h |
| @@ -52,7 +52,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE · 51 unmodified lines | ||
| 52 | 52 | # Add -lgcc so rv32 gets static muldi3 and lshrdi3 definitions. |
| 53 | 53 | # Make sure only to export the intended __vdso_xxx symbol offsets. |
| 54 | 54 | quiet_cmd_vdsold = VDSOLD $@ |
| 55 | − cmd_vdsold = $(CC) $(KCFLAGS) -nostdlib $(SYSCFLAGS_$(@F)) \ | |
| 55 | + cmd_vdsold = $(CC) $(KCFLAGS) $(call cc-option, -no-pie) -nostdlib $(SYSCFLAGS_$(@F)) \ | |
| 56 | 56 | -Wl,-T,$(filter-out FORCE,$^) -o $@.tmp -lgcc && \ |
| 57 | 57 | $(CROSS_COMPILE)objcopy \ |
| 58 | 58 | $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ |
| @@ -8,3 +8,4 @@ obj-$(CONFIG_APPLDATA_BASE) += appldata/ · 7 unmodified lines | ||
| 8 | 8 | obj-y += net/ |
| 9 | 9 | obj-$(CONFIG_PCI) += pci/ |
| 10 | 10 | obj-$(CONFIG_NUMA) += numa/ |
| 11 | +obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += purgatory/ | |
| @@ -47,10 +47,6 @@ config PGSTE · 46 unmodified lines | ||
| 47 | 47 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC |
| 48 | 48 | def_bool y |
| 49 | 49 | |
| 50 | −config KEXEC | |
| 51 | − def_bool y | |
| 52 | − select KEXEC_CORE | |
| 53 | − | |
| 54 | 50 | config AUDIT_ARCH |
| 55 | 51 | def_bool y |
| 56 | 52 | |
| @@ -290,12 +286,12 @@ config MARCH_Z13 · 233 unmodified lines | ||
| 290 | 286 | older machines. |
| 291 | 287 | |
| 292 | 288 | config MARCH_Z14 |
| 293 | − bool "IBM z14" | |
| 289 | + bool "IBM z14 ZR1 and z14" | |
| 294 | 290 | select HAVE_MARCH_Z14_FEATURES |
| 295 | 291 | help |
| 296 | − Select this to enable optimizations for IBM z14 (3906 series). | |
| 297 | − The kernel will be slightly faster but will not work on older | |
| 298 | − machines. | |
| 292 | + Select this to enable optimizations for IBM z14 ZR1 and z14 (3907 | |
| 293 | + and 3906 series). The kernel will be slightly faster but will not | |
| 294 | + work on older machines. | |
| 299 | 295 | |
| 300 | 296 | endchoice |
| 301 | 297 | |
| @@ -525,6 +521,26 @@ source kernel/Kconfig.preempt · 223 unmodified lines | ||
| 525 | 521 | |
| 526 | 522 | source kernel/Kconfig.hz |
| 527 | 523 | |
| 524 | +config KEXEC | |
| 525 | + def_bool y | |
| 526 | + select KEXEC_CORE | |
| 527 | + | |
| 528 | +config KEXEC_FILE | |
| 529 | + bool "kexec file based system call" | |
| 530 | + select KEXEC_CORE | |
| 531 | + select BUILD_BIN2C | |
| 532 | + depends on CRYPTO | |
| 533 | + depends on CRYPTO_SHA256 | |
| 534 | + depends on CRYPTO_SHA256_S390 | |
| 535 | + help | |
| 536 | + Enable the kexec file based system call. In contrast to the normal | |
| 537 | + kexec system call this system call takes file descriptors for the | |
| 538 | + kernel and initramfs as arguments. | |
| 539 | + | |
| 540 | +config ARCH_HAS_KEXEC_PURGATORY | |
| 541 | + def_bool y | |
| 542 | + depends on KEXEC_FILE | |
| 543 | + | |
| 528 | 544 | config ARCH_RANDOM |
| 529 | 545 | def_bool y |
| 530 | 546 | prompt "s390 architectural random number generation API" |
| @@ -3,12 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | # Makefile for the linux s390-specific parts of the memory manager. |
| 4 | 4 | # |
| 5 | 5 | |
| 6 | −COMPILE_VERSION := __linux_compile_version_id__`hostname | \ | |
| 7 | − tr -c '[0-9A-Za-z]' '_'`__`date | \ | |
| 8 | − tr -c '[0-9A-Za-z]' '_'`_t | |
| 9 | − | |
| 10 | −ccflags-y := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I. | |
| 11 | − | |
| 12 | 6 | targets := image |
| 13 | 7 | targets += bzImage |
| 14 | 8 | subdir- := compressed |
| @@ -1,3 +1,4 @@ | ||
| 1 | 1 | sizes.h |
| 2 | 2 | vmlinux |
| 3 | 3 | vmlinux.lds |
| 4 | +vmlinux.bin.full | |
| @@ -24,13 +24,13 @@ CONFIG_CPUSETS=y · 23 unmodified lines | ||
| 24 | 24 | CONFIG_CGROUP_DEVICE=y |
| 25 | 25 | CONFIG_CGROUP_CPUACCT=y |
| 26 | 26 | CONFIG_CGROUP_PERF=y |
| 27 | −CONFIG_CHECKPOINT_RESTORE=y | |
| 28 | 27 | CONFIG_NAMESPACES=y |
| 29 | 28 | CONFIG_USER_NS=y |
| 30 | 29 | CONFIG_SCHED_AUTOGROUP=y |
| 31 | 30 | CONFIG_BLK_DEV_INITRD=y |
| 32 | 31 | CONFIG_EXPERT=y |
| 33 | 32 | # CONFIG_SYSFS_SYSCALL is not set |
| 33 | +CONFIG_CHECKPOINT_RESTORE=y | |
| 34 | 34 | CONFIG_BPF_SYSCALL=y |
| 35 | 35 | CONFIG_USERFAULTFD=y |
| 36 | 36 | # CONFIG_COMPAT_BRK is not set |
| @@ -59,10 +59,11 @@ CONFIG_CFQ_GROUP_IOSCHED=y · 22 unmodified lines | ||
| 59 | 59 | CONFIG_DEFAULT_DEADLINE=y |
| 60 | 60 | CONFIG_LIVEPATCH=y |
| 61 | 61 | CONFIG_TUNE_ZEC12=y |
| 62 | −CONFIG_NR_CPUS=256 | |
| 62 | +CONFIG_NR_CPUS=512 | |
| 63 | 63 | CONFIG_NUMA=y |
| 64 | 64 | CONFIG_PREEMPT=y |
| 65 | 65 | CONFIG_HZ_100=y |
| 66 | +CONFIG_KEXEC_FILE=y | |
| 66 | 67 | CONFIG_MEMORY_HOTPLUG=y |
| 67 | 68 | CONFIG_MEMORY_HOTREMOVE=y |
| 68 | 69 | CONFIG_KSM=y |
| @@ -305,7 +306,6 @@ CONFIG_IP6_NF_SECURITY=m · 236 unmodified lines | ||
| 305 | 306 | CONFIG_IP6_NF_NAT=m |
| 306 | 307 | CONFIG_IP6_NF_TARGET_MASQUERADE=m |
| 307 | 308 | CONFIG_NF_TABLES_BRIDGE=m |
| 308 | −CONFIG_NET_SCTPPROBE=m | |
| 309 | 309 | CONFIG_RDS=m |
| 310 | 310 | CONFIG_RDS_RDMA=m |
| 311 | 311 | CONFIG_RDS_TCP=m |
| @@ -364,11 +364,11 @@ CONFIG_NET_ACT_SIMP=m · 52 unmodified lines | ||
| 364 | 364 | CONFIG_NET_ACT_SKBEDIT=m |
| 365 | 365 | CONFIG_NET_ACT_CSUM=m |
| 366 | 366 | CONFIG_DNS_RESOLVER=y |
| 367 | +CONFIG_OPENVSWITCH=m | |
| 367 | 368 | CONFIG_NETLINK_DIAG=m |
| 368 | 369 | CONFIG_CGROUP_NET_PRIO=y |
| 369 | 370 | CONFIG_BPF_JIT=y |
| 370 | 371 | CONFIG_NET_PKTGEN=m |
| 371 | −CONFIG_NET_TCPPROBE=m | |
| 372 | 372 | CONFIG_DEVTMPFS=y |
| 373 | 373 | CONFIG_DMA_CMA=y |
| 374 | 374 | CONFIG_CMA_SIZE_MBYTES=0 |
| @@ -380,9 +380,9 @@ CONFIG_BLK_DEV_DRBD=m · 5 unmodified lines | ||
| 380 | 380 | CONFIG_BLK_DEV_NBD=m |
| 381 | 381 | CONFIG_BLK_DEV_RAM=y |
| 382 | 382 | CONFIG_BLK_DEV_RAM_SIZE=32768 |
| 383 | −CONFIG_BLK_DEV_RAM_DAX=y | |
| 384 | 383 | CONFIG_VIRTIO_BLK=y |
| 385 | 384 | CONFIG_BLK_DEV_RBD=m |
| 385 | +CONFIG_BLK_DEV_NVME=m | |
| 386 | 386 | CONFIG_ENCLOSURE_SERVICES=m |
| 387 | 387 | CONFIG_GENWQE=m |
| 388 | 388 | CONFIG_RAID_ATTRS=m |
| @@ -461,6 +461,7 @@ CONFIG_PPTP=m · 72 unmodified lines | ||
| 461 | 461 | CONFIG_PPPOL2TP=m |
| 462 | 462 | CONFIG_PPP_ASYNC=m |
| 463 | 463 | CONFIG_PPP_SYNC_TTY=m |
| 464 | +CONFIG_INPUT_EVDEV=y | |
| 464 | 465 | # CONFIG_INPUT_KEYBOARD is not set |
| 465 | 466 | # CONFIG_INPUT_MOUSE is not set |
| 466 | 467 | # CONFIG_SERIO is not set |
| @@ -474,6 +475,9 @@ CONFIG_WATCHDOG=y · 7 unmodified lines | ||
| 474 | 475 | CONFIG_WATCHDOG_NOWAYOUT=y |
| 475 | 476 | CONFIG_SOFT_WATCHDOG=m |
| 476 | 477 | CONFIG_DIAG288_WATCHDOG=m |
| 478 | +CONFIG_DRM=y | |
| 479 | +CONFIG_DRM_VIRTIO_GPU=y | |
| 480 | +CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 477 | 481 | # CONFIG_HID is not set |
| 478 | 482 | # CONFIG_USB_SUPPORT is not set |
| 479 | 483 | CONFIG_INFINIBAND=m |
| @@ -482,7 +486,9 @@ CONFIG_MLX4_INFINIBAND=m · 2 unmodified lines | ||
| 482 | 486 | CONFIG_MLX5_INFINIBAND=m |
| 483 | 487 | CONFIG_VFIO=m |
| 484 | 488 | CONFIG_VFIO_PCI=m |
| 489 | +CONFIG_VIRTIO_PCI=m | |
| 485 | 490 | CONFIG_VIRTIO_BALLOON=m |
| 491 | +CONFIG_VIRTIO_INPUT=y | |
| 486 | 492 | CONFIG_EXT4_FS=y |
| 487 | 493 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 488 | 494 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -641,6 +647,8 @@ CONFIG_ATOMIC64_SELFTEST=y · 152 unmodified lines | ||
| 641 | 647 | CONFIG_TEST_BPF=m |
| 642 | 648 | CONFIG_BUG_ON_DATA_CORRUPTION=y |
| 643 | 649 | CONFIG_S390_PTDUMP=y |
| 650 | +CONFIG_PERSISTENT_KEYRINGS=y | |
| 651 | +CONFIG_BIG_KEYS=y | |
| 644 | 652 | CONFIG_ENCRYPTED_KEYS=m |
| 645 | 653 | CONFIG_SECURITY=y |
| 646 | 654 | CONFIG_SECURITY_NETWORK=y |
| @@ -649,17 +657,20 @@ CONFIG_SECURITY_SELINUX=y · 2 unmodified lines | ||
| 649 | 657 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y |
| 650 | 658 | CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 |
| 651 | 659 | CONFIG_SECURITY_SELINUX_DISABLE=y |
| 660 | +CONFIG_INTEGRITY_SIGNATURE=y | |
| 661 | +CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y | |
| 652 | 662 | CONFIG_IMA=y |
| 663 | +CONFIG_IMA_DEFAULT_HASH_SHA256=y | |
| 664 | +CONFIG_IMA_WRITE_POLICY=y | |
| 653 | 665 | CONFIG_IMA_APPRAISE=y |
| 654 | −CONFIG_CRYPTO_RSA=m | |
| 655 | 666 | CONFIG_CRYPTO_DH=m |
| 656 | 667 | CONFIG_CRYPTO_ECDH=m |
| 657 | 668 | CONFIG_CRYPTO_USER=m |
| 669 | +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set | |
| 658 | 670 | CONFIG_CRYPTO_PCRYPT=m |
| 659 | 671 | CONFIG_CRYPTO_CRYPTD=m |
| 660 | 672 | CONFIG_CRYPTO_MCRYPTD=m |
| 661 | 673 | CONFIG_CRYPTO_TEST=m |
| 662 | −CONFIG_CRYPTO_GCM=m | |
| 663 | 674 | CONFIG_CRYPTO_CHACHA20POLY1305=m |
| 664 | 675 | CONFIG_CRYPTO_LRW=m |
| 665 | 676 | CONFIG_CRYPTO_PCBC=m |
| @@ -707,9 +718,8 @@ CONFIG_CRYPTO_DES_S390=m · 41 unmodified lines | ||
| 707 | 718 | CONFIG_CRYPTO_AES_S390=m |
| 708 | 719 | CONFIG_CRYPTO_GHASH_S390=m |
| 709 | 720 | CONFIG_CRYPTO_CRC32_S390=y |
| 710 | −CONFIG_ASYMMETRIC_KEY_TYPE=y | |
| 711 | −CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m | |
| 712 | −CONFIG_X509_CERTIFICATE_PARSER=m | |
| 721 | +CONFIG_PKCS7_MESSAGE_PARSER=y | |
| 722 | +CONFIG_SYSTEM_TRUSTED_KEYRING=y | |
| 713 | 723 | CONFIG_CRC7=m |
| 714 | 724 | CONFIG_CRC8=m |
| 715 | 725 | CONFIG_RANDOM32_SELFTEST=y |
| @@ -1,661 +0,0 @@ | ||
| 1 | −CONFIG_SYSVIPC=y | |
| 2 | −CONFIG_POSIX_MQUEUE=y | |
| 3 | −CONFIG_AUDIT=y | |
| 4 | −CONFIG_NO_HZ_IDLE=y | |
| 5 | −CONFIG_HIGH_RES_TIMERS=y | |
| 6 | −CONFIG_BSD_PROCESS_ACCT=y | |
| 7 | −CONFIG_BSD_PROCESS_ACCT_V3=y | |
| 8 | −CONFIG_TASKSTATS=y | |
| 9 | −CONFIG_TASK_DELAY_ACCT=y | |
| 10 | −CONFIG_TASK_XACCT=y | |
| 11 | −CONFIG_TASK_IO_ACCOUNTING=y | |
| 12 | −CONFIG_IKCONFIG=y | |
| 13 | −CONFIG_IKCONFIG_PROC=y | |
| 14 | −CONFIG_NUMA_BALANCING=y | |
| 15 | −# CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set | |
| 16 | −CONFIG_MEMCG=y | |
| 17 | −CONFIG_MEMCG_SWAP=y | |
| 18 | −CONFIG_BLK_CGROUP=y | |
| 19 | −CONFIG_CFS_BANDWIDTH=y | |
| 20 | −CONFIG_RT_GROUP_SCHED=y | |
| 21 | −CONFIG_CGROUP_PIDS=y | |
| 22 | −CONFIG_CGROUP_FREEZER=y | |
| 23 | −CONFIG_CGROUP_HUGETLB=y | |
| 24 | −CONFIG_CPUSETS=y | |
| 25 | −CONFIG_CGROUP_DEVICE=y | |
| 26 | −CONFIG_CGROUP_CPUACCT=y | |
| 27 | −CONFIG_CGROUP_PERF=y | |
| 28 | −CONFIG_CHECKPOINT_RESTORE=y | |
| 29 | −CONFIG_NAMESPACES=y | |
| 30 | −CONFIG_USER_NS=y | |
| 31 | −CONFIG_SCHED_AUTOGROUP=y | |
| 32 | −CONFIG_BLK_DEV_INITRD=y | |
| 33 | −CONFIG_EXPERT=y | |
| 34 | −# CONFIG_SYSFS_SYSCALL is not set | |
| 35 | −CONFIG_BPF_SYSCALL=y | |
| 36 | −CONFIG_USERFAULTFD=y | |
| 37 | −# CONFIG_COMPAT_BRK is not set | |
| 38 | −CONFIG_PROFILING=y | |
| 39 | −CONFIG_OPROFILE=m | |
| 40 | −CONFIG_KPROBES=y | |
| 41 | −CONFIG_JUMP_LABEL=y | |
| 42 | −CONFIG_GCOV_KERNEL=y | |
| 43 | −CONFIG_GCOV_PROFILE_ALL=y | |
| 44 | −CONFIG_MODULES=y | |
| 45 | −CONFIG_MODULE_FORCE_LOAD=y | |
| 46 | −CONFIG_MODULE_UNLOAD=y | |
| 47 | −CONFIG_MODULE_FORCE_UNLOAD=y | |
| 48 | −CONFIG_MODVERSIONS=y | |
| 49 | −CONFIG_MODULE_SRCVERSION_ALL=y | |
| 50 | −CONFIG_BLK_DEV_INTEGRITY=y | |
| 51 | −CONFIG_BLK_DEV_THROTTLING=y | |
| 52 | −CONFIG_BLK_WBT=y | |
| 53 | −CONFIG_BLK_WBT_SQ=y | |
| 54 | −CONFIG_PARTITION_ADVANCED=y | |
| 55 | −CONFIG_IBM_PARTITION=y | |
| 56 | −CONFIG_BSD_DISKLABEL=y | |
| 57 | −CONFIG_MINIX_SUBPARTITION=y | |
| 58 | −CONFIG_SOLARIS_X86_PARTITION=y | |
| 59 | −CONFIG_UNIXWARE_DISKLABEL=y | |
| 60 | −CONFIG_CFQ_GROUP_IOSCHED=y | |
| 61 | −CONFIG_DEFAULT_DEADLINE=y | |
| 62 | −CONFIG_LIVEPATCH=y | |
| 63 | −CONFIG_TUNE_ZEC12=y | |
| 64 | −CONFIG_NR_CPUS=512 | |
| 65 | −CONFIG_NUMA=y | |
| 66 | −CONFIG_HZ_100=y | |
| 67 | −CONFIG_MEMORY_HOTPLUG=y | |
| 68 | −CONFIG_MEMORY_HOTREMOVE=y | |
| 69 | −CONFIG_KSM=y | |
| 70 | −CONFIG_TRANSPARENT_HUGEPAGE=y | |
| 71 | −CONFIG_CLEANCACHE=y | |
| 72 | −CONFIG_FRONTSWAP=y | |
| 73 | −CONFIG_MEM_SOFT_DIRTY=y | |
| 74 | −CONFIG_ZSWAP=y | |
| 75 | −CONFIG_ZBUD=m | |
| 76 | −CONFIG_ZSMALLOC=m | |
| 77 | −CONFIG_ZSMALLOC_STAT=y | |
| 78 | −CONFIG_DEFERRED_STRUCT_PAGE_INIT=y | |
| 79 | −CONFIG_IDLE_PAGE_TRACKING=y | |
| 80 | −CONFIG_PCI=y | |
| 81 | −CONFIG_HOTPLUG_PCI=y | |
| 82 | −CONFIG_HOTPLUG_PCI_S390=y | |
| 83 | −CONFIG_CHSC_SCH=y | |
| 84 | −CONFIG_CRASH_DUMP=y | |
| 85 | −CONFIG_BINFMT_MISC=m | |
| 86 | −CONFIG_HIBERNATION=y | |
| 87 | −CONFIG_NET=y | |
| 88 | −CONFIG_PACKET=y | |
| 89 | −CONFIG_PACKET_DIAG=m | |
| 90 | −CONFIG_UNIX=y | |
| 91 | −CONFIG_UNIX_DIAG=m | |
| 92 | −CONFIG_XFRM_USER=m | |
| 93 | −CONFIG_NET_KEY=m | |
| 94 | −CONFIG_SMC=m | |
| 95 | −CONFIG_SMC_DIAG=m | |
| 96 | −CONFIG_INET=y | |
| 97 | −CONFIG_IP_MULTICAST=y | |
| 98 | −CONFIG_IP_ADVANCED_ROUTER=y | |
| 99 | −CONFIG_IP_MULTIPLE_TABLES=y | |
| 100 | −CONFIG_IP_ROUTE_MULTIPATH=y | |
| 101 | −CONFIG_IP_ROUTE_VERBOSE=y | |
| 102 | −CONFIG_NET_IPIP=m | |
| 103 | −CONFIG_NET_IPGRE_DEMUX=m | |
| 104 | −CONFIG_NET_IPGRE=m | |
| 105 | −CONFIG_NET_IPGRE_BROADCAST=y | |
| 106 | −CONFIG_IP_MROUTE=y | |
| 107 | −CONFIG_IP_MROUTE_MULTIPLE_TABLES=y | |
| 108 | −CONFIG_IP_PIMSM_V1=y | |
| 109 | −CONFIG_IP_PIMSM_V2=y | |
| 110 | −CONFIG_SYN_COOKIES=y | |
| 111 | −CONFIG_NET_IPVTI=m | |
| 112 | −CONFIG_INET_AH=m | |
| 113 | −CONFIG_INET_ESP=m | |
| 114 | −CONFIG_INET_IPCOMP=m | |
| 115 | −CONFIG_INET_XFRM_MODE_TRANSPORT=m | |
| 116 | −CONFIG_INET_XFRM_MODE_TUNNEL=m | |
| 117 | −CONFIG_INET_XFRM_MODE_BEET=m | |
| 118 | −CONFIG_INET_DIAG=m | |
| 119 | −CONFIG_INET_UDP_DIAG=m | |
| 120 | −CONFIG_TCP_CONG_ADVANCED=y | |
| 121 | −CONFIG_TCP_CONG_HSTCP=m | |
| 122 | −CONFIG_TCP_CONG_HYBLA=m | |
| 123 | −CONFIG_TCP_CONG_SCALABLE=m | |
| 124 | −CONFIG_TCP_CONG_LP=m | |
| 125 | −CONFIG_TCP_CONG_VENO=m | |
| 126 | −CONFIG_TCP_CONG_YEAH=m | |
| 127 | −CONFIG_TCP_CONG_ILLINOIS=m | |
| 128 | −CONFIG_IPV6_ROUTER_PREF=y | |
| 129 | −CONFIG_INET6_AH=m | |
| 130 | −CONFIG_INET6_ESP=m | |
| 131 | −CONFIG_INET6_IPCOMP=m | |
| 132 | −CONFIG_IPV6_MIP6=m | |
| 133 | −CONFIG_INET6_XFRM_MODE_TRANSPORT=m | |
| 134 | −CONFIG_INET6_XFRM_MODE_TUNNEL=m | |
| 135 | −CONFIG_INET6_XFRM_MODE_BEET=m | |
| 136 | −CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | |
| 137 | −CONFIG_IPV6_VTI=m | |
| 138 | −CONFIG_IPV6_SIT=m | |
| 139 | −CONFIG_IPV6_GRE=m | |
| 140 | −CONFIG_IPV6_MULTIPLE_TABLES=y | |
| 141 | −CONFIG_IPV6_SUBTREES=y | |
| 142 | −CONFIG_NETFILTER=y | |
| 143 | −CONFIG_NF_CONNTRACK=m | |
| 144 | −CONFIG_NF_CONNTRACK_SECMARK=y | |
| 145 | −CONFIG_NF_CONNTRACK_EVENTS=y | |
| 146 | −CONFIG_NF_CONNTRACK_TIMEOUT=y | |
| 147 | −CONFIG_NF_CONNTRACK_TIMESTAMP=y | |
| 148 | −CONFIG_NF_CONNTRACK_AMANDA=m | |
| 149 | −CONFIG_NF_CONNTRACK_FTP=m | |
| 150 | −CONFIG_NF_CONNTRACK_H323=m | |
| 151 | −CONFIG_NF_CONNTRACK_IRC=m | |
| 152 | −CONFIG_NF_CONNTRACK_NETBIOS_NS=m | |
| 153 | −CONFIG_NF_CONNTRACK_SNMP=m | |
| 154 | −CONFIG_NF_CONNTRACK_PPTP=m | |
| 155 | −CONFIG_NF_CONNTRACK_SANE=m | |
| 156 | −CONFIG_NF_CONNTRACK_SIP=m | |
| 157 | −CONFIG_NF_CONNTRACK_TFTP=m | |
| 158 | −CONFIG_NF_CT_NETLINK=m | |
| 159 | −CONFIG_NF_CT_NETLINK_TIMEOUT=m | |
| 160 | −CONFIG_NF_TABLES=m | |
| 161 | −CONFIG_NFT_EXTHDR=m | |
| 162 | −CONFIG_NFT_META=m | |
| 163 | −CONFIG_NFT_CT=m | |
| 164 | −CONFIG_NFT_COUNTER=m | |
| 165 | −CONFIG_NFT_LOG=m | |
| 166 | −CONFIG_NFT_LIMIT=m | |
| 167 | −CONFIG_NFT_NAT=m | |
| 168 | −CONFIG_NFT_COMPAT=m | |
| 169 | −CONFIG_NFT_HASH=m | |
| 170 | −CONFIG_NETFILTER_XT_SET=m | |
| 171 | −CONFIG_NETFILTER_XT_TARGET_AUDIT=m | |
| 172 | −CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m | |
| 173 | −CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m | |
| 174 | −CONFIG_NETFILTER_XT_TARGET_CONNMARK=m | |
| 175 | −CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m | |
| 176 | −CONFIG_NETFILTER_XT_TARGET_CT=m | |
| 177 | −CONFIG_NETFILTER_XT_TARGET_DSCP=m | |
| 178 | −CONFIG_NETFILTER_XT_TARGET_HMARK=m | |
| 179 | −CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m | |
| 180 | −CONFIG_NETFILTER_XT_TARGET_LOG=m | |
| 181 | −CONFIG_NETFILTER_XT_TARGET_MARK=m | |
| 182 | −CONFIG_NETFILTER_XT_TARGET_NFLOG=m | |
| 183 | −CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m | |
| 184 | −CONFIG_NETFILTER_XT_TARGET_TEE=m | |
| 185 | −CONFIG_NETFILTER_XT_TARGET_TPROXY=m | |
| 186 | −CONFIG_NETFILTER_XT_TARGET_TRACE=m | |
| 187 | −CONFIG_NETFILTER_XT_TARGET_SECMARK=m | |
| 188 | −CONFIG_NETFILTER_XT_TARGET_TCPMSS=m | |
| 189 | −CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m | |
| 190 | −CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m | |
| 191 | −CONFIG_NETFILTER_XT_MATCH_BPF=m | |
| 192 | −CONFIG_NETFILTER_XT_MATCH_CLUSTER=m | |
| 193 | −CONFIG_NETFILTER_XT_MATCH_COMMENT=m | |
| 194 | −CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m | |
| 195 | −CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m | |
| 196 | −CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m | |
| 197 | −CONFIG_NETFILTER_XT_MATCH_CONNMARK=m | |
| 198 | −CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m | |
| 199 | −CONFIG_NETFILTER_XT_MATCH_CPU=m | |
| 200 | −CONFIG_NETFILTER_XT_MATCH_DCCP=m | |
| 201 | −CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m | |
| 202 | −CONFIG_NETFILTER_XT_MATCH_DSCP=m | |
| 203 | −CONFIG_NETFILTER_XT_MATCH_ESP=m | |
| 204 | −CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m | |
| 205 | −CONFIG_NETFILTER_XT_MATCH_HELPER=m | |
| 206 | −CONFIG_NETFILTER_XT_MATCH_IPRANGE=m | |
| 207 | −CONFIG_NETFILTER_XT_MATCH_IPVS=m | |
| 208 | −CONFIG_NETFILTER_XT_MATCH_LENGTH=m | |
| 209 | −CONFIG_NETFILTER_XT_MATCH_LIMIT=m | |
| 210 | −CONFIG_NETFILTER_XT_MATCH_MAC=m | |
| 211 | −CONFIG_NETFILTER_XT_MATCH_MARK=m | |
| 212 | −CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m | |
| 213 | −CONFIG_NETFILTER_XT_MATCH_NFACCT=m | |
| 214 | −CONFIG_NETFILTER_XT_MATCH_OSF=m | |
| 215 | −CONFIG_NETFILTER_XT_MATCH_OWNER=m | |
| 216 | −CONFIG_NETFILTER_XT_MATCH_POLICY=m | |
| 217 | −CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m | |
| 218 | −CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m | |
| 219 | −CONFIG_NETFILTER_XT_MATCH_QUOTA=m | |
| 220 | −CONFIG_NETFILTER_XT_MATCH_RATEEST=m | |
| 221 | −CONFIG_NETFILTER_XT_MATCH_REALM=m | |
| 222 | −CONFIG_NETFILTER_XT_MATCH_RECENT=m | |
| 223 | −CONFIG_NETFILTER_XT_MATCH_STATE=m | |
| 224 | −CONFIG_NETFILTER_XT_MATCH_STATISTIC=m | |
| 225 | −CONFIG_NETFILTER_XT_MATCH_STRING=m | |
| 226 | −CONFIG_NETFILTER_XT_MATCH_TCPMSS=m | |
| 227 | −CONFIG_NETFILTER_XT_MATCH_TIME=m | |
| 228 | −CONFIG_NETFILTER_XT_MATCH_U32=m | |
| 229 | −CONFIG_IP_SET=m | |
| 230 | −CONFIG_IP_SET_BITMAP_IP=m | |
| 231 | −CONFIG_IP_SET_BITMAP_IPMAC=m | |
| 232 | −CONFIG_IP_SET_BITMAP_PORT=m | |
| 233 | −CONFIG_IP_SET_HASH_IP=m | |
| 234 | −CONFIG_IP_SET_HASH_IPPORT=m | |
| 235 | −CONFIG_IP_SET_HASH_IPPORTIP=m | |
| 236 | −CONFIG_IP_SET_HASH_IPPORTNET=m | |
| 237 | −CONFIG_IP_SET_HASH_NETPORTNET=m | |
| 238 | −CONFIG_IP_SET_HASH_NET=m | |
| 239 | −CONFIG_IP_SET_HASH_NETNET=m | |
| 240 | −CONFIG_IP_SET_HASH_NETPORT=m | |
| 241 | −CONFIG_IP_SET_HASH_NETIFACE=m | |
| 242 | −CONFIG_IP_SET_LIST_SET=m | |
| 243 | −CONFIG_IP_VS=m | |
| 244 | −CONFIG_IP_VS_PROTO_TCP=y | |
| 245 | −CONFIG_IP_VS_PROTO_UDP=y | |
| 246 | −CONFIG_IP_VS_PROTO_ESP=y | |
| 247 | −CONFIG_IP_VS_PROTO_AH=y | |
| 248 | −CONFIG_IP_VS_RR=m | |
| 249 | −CONFIG_IP_VS_WRR=m | |
| 250 | −CONFIG_IP_VS_LC=m | |
| 251 | −CONFIG_IP_VS_WLC=m | |
| 252 | −CONFIG_IP_VS_LBLC=m | |
| 253 | −CONFIG_IP_VS_LBLCR=m | |
| 254 | −CONFIG_IP_VS_DH=m | |
| 255 | −CONFIG_IP_VS_SH=m | |
| 256 | −CONFIG_IP_VS_SED=m | |
| 257 | −CONFIG_IP_VS_NQ=m | |
| 258 | −CONFIG_IP_VS_FTP=m | |
| 259 | −CONFIG_IP_VS_PE_SIP=m | |
| 260 | −CONFIG_NF_CONNTRACK_IPV4=m | |
| 261 | −CONFIG_NF_TABLES_IPV4=m | |
| 262 | −CONFIG_NFT_CHAIN_ROUTE_IPV4=m | |
| 263 | −CONFIG_NF_TABLES_ARP=m | |
| 264 | −CONFIG_NFT_CHAIN_NAT_IPV4=m | |
| 265 | −CONFIG_IP_NF_IPTABLES=m | |
| 266 | −CONFIG_IP_NF_MATCH_AH=m | |
| 267 | −CONFIG_IP_NF_MATCH_ECN=m | |
| 268 | −CONFIG_IP_NF_MATCH_RPFILTER=m | |
| 269 | −CONFIG_IP_NF_MATCH_TTL=m | |
| 270 | −CONFIG_IP_NF_FILTER=m | |
| 271 | −CONFIG_IP_NF_TARGET_REJECT=m | |
| 272 | −CONFIG_IP_NF_NAT=m | |
| 273 | −CONFIG_IP_NF_TARGET_MASQUERADE=m | |
| 274 | −CONFIG_IP_NF_MANGLE=m | |
| 275 | −CONFIG_IP_NF_TARGET_CLUSTERIP=m | |
| 276 | −CONFIG_IP_NF_TARGET_ECN=m | |
| 277 | −CONFIG_IP_NF_TARGET_TTL=m | |
| 278 | −CONFIG_IP_NF_RAW=m | |
| 279 | −CONFIG_IP_NF_SECURITY=m | |
| 280 | −CONFIG_IP_NF_ARPTABLES=m | |
| 281 | −CONFIG_IP_NF_ARPFILTER=m | |
| 282 | −CONFIG_IP_NF_ARP_MANGLE=m | |
| 283 | −CONFIG_NF_CONNTRACK_IPV6=m | |
| 284 | −CONFIG_NF_TABLES_IPV6=m | |
| 285 | −CONFIG_NFT_CHAIN_ROUTE_IPV6=m | |
| 286 | −CONFIG_NFT_CHAIN_NAT_IPV6=m | |
| 287 | −CONFIG_IP6_NF_IPTABLES=m | |
| 288 | −CONFIG_IP6_NF_MATCH_AH=m | |
| 289 | −CONFIG_IP6_NF_MATCH_EUI64=m | |
| 290 | −CONFIG_IP6_NF_MATCH_FRAG=m | |
| 291 | −CONFIG_IP6_NF_MATCH_OPTS=m | |
| 292 | −CONFIG_IP6_NF_MATCH_HL=m | |
| 293 | −CONFIG_IP6_NF_MATCH_IPV6HEADER=m | |
| 294 | −CONFIG_IP6_NF_MATCH_MH=m | |
| 295 | −CONFIG_IP6_NF_MATCH_RPFILTER=m | |
| 296 | −CONFIG_IP6_NF_MATCH_RT=m | |
| 297 | −CONFIG_IP6_NF_TARGET_HL=m | |
| 298 | −CONFIG_IP6_NF_FILTER=m | |
| 299 | −CONFIG_IP6_NF_TARGET_REJECT=m | |
| 300 | −CONFIG_IP6_NF_MANGLE=m | |
| 301 | −CONFIG_IP6_NF_RAW=m | |
| 302 | −CONFIG_IP6_NF_SECURITY=m | |
| 303 | −CONFIG_IP6_NF_NAT=m | |
| 304 | −CONFIG_IP6_NF_TARGET_MASQUERADE=m | |
| 305 | −CONFIG_NF_TABLES_BRIDGE=m | |
| 306 | −CONFIG_NET_SCTPPROBE=m | |
| 307 | −CONFIG_RDS=m | |
| 308 | −CONFIG_RDS_RDMA=m | |
| 309 | −CONFIG_RDS_TCP=m | |
| 310 | −CONFIG_L2TP=m | |
| 311 | −CONFIG_L2TP_DEBUGFS=m | |
| 312 | −CONFIG_L2TP_V3=y | |
| 313 | −CONFIG_L2TP_IP=m | |
| 314 | −CONFIG_L2TP_ETH=m | |
| 315 | −CONFIG_BRIDGE=m | |
| 316 | −CONFIG_VLAN_8021Q=m | |
| 317 | −CONFIG_VLAN_8021Q_GVRP=y | |
| 318 | −CONFIG_NET_SCHED=y | |
| 319 | −CONFIG_NET_SCH_CBQ=m | |
| 320 | −CONFIG_NET_SCH_HTB=m | |
| 321 | −CONFIG_NET_SCH_HFSC=m | |
| 322 | −CONFIG_NET_SCH_PRIO=m | |
| 323 | −CONFIG_NET_SCH_MULTIQ=m | |
| 324 | −CONFIG_NET_SCH_RED=m | |
| 325 | −CONFIG_NET_SCH_SFB=m | |
| 326 | −CONFIG_NET_SCH_SFQ=m | |
| 327 | −CONFIG_NET_SCH_TEQL=m | |
| 328 | −CONFIG_NET_SCH_TBF=m | |
| 329 | −CONFIG_NET_SCH_GRED=m | |
| 330 | −CONFIG_NET_SCH_DSMARK=m | |
| 331 | −CONFIG_NET_SCH_NETEM=m | |
| 332 | −CONFIG_NET_SCH_DRR=m | |
| 333 | −CONFIG_NET_SCH_MQPRIO=m | |
| 334 | −CONFIG_NET_SCH_CHOKE=m | |
| 335 | −CONFIG_NET_SCH_QFQ=m | |
| 336 | −CONFIG_NET_SCH_CODEL=m | |
| 337 | −CONFIG_NET_SCH_FQ_CODEL=m | |
| 338 | −CONFIG_NET_SCH_INGRESS=m | |
| 339 | −CONFIG_NET_SCH_PLUG=m | |
| 340 | −CONFIG_NET_CLS_BASIC=m | |
| 341 | −CONFIG_NET_CLS_TCINDEX=m | |
| 342 | −CONFIG_NET_CLS_ROUTE4=m | |
| 343 | −CONFIG_NET_CLS_FW=m | |
| 344 | −CONFIG_NET_CLS_U32=m | |
| 345 | −CONFIG_CLS_U32_PERF=y | |
| 346 | −CONFIG_CLS_U32_MARK=y | |
| 347 | −CONFIG_NET_CLS_RSVP=m | |
| 348 | −CONFIG_NET_CLS_RSVP6=m | |
| 349 | −CONFIG_NET_CLS_FLOW=m | |
| 350 | −CONFIG_NET_CLS_CGROUP=y | |
| 351 | −CONFIG_NET_CLS_BPF=m | |
| 352 | −CONFIG_NET_CLS_ACT=y | |
| 353 | −CONFIG_NET_ACT_POLICE=m | |
| 354 | −CONFIG_NET_ACT_GACT=m | |
| 355 | −CONFIG_GACT_PROB=y | |
| 356 | −CONFIG_NET_ACT_MIRRED=m | |
| 357 | −CONFIG_NET_ACT_IPT=m | |
| 358 | −CONFIG_NET_ACT_NAT=m | |
| 359 | −CONFIG_NET_ACT_PEDIT=m | |
| 360 | −CONFIG_NET_ACT_SIMP=m | |
| 361 | −CONFIG_NET_ACT_SKBEDIT=m | |
| 362 | −CONFIG_NET_ACT_CSUM=m | |
| 363 | −CONFIG_DNS_RESOLVER=y | |
| 364 | −CONFIG_NETLINK_DIAG=m | |
| 365 | −CONFIG_CGROUP_NET_PRIO=y | |
| 366 | −CONFIG_BPF_JIT=y | |
| 367 | −CONFIG_NET_PKTGEN=m | |
| 368 | −CONFIG_NET_TCPPROBE=m | |
| 369 | −CONFIG_DEVTMPFS=y | |
| 370 | −CONFIG_DMA_CMA=y | |
| 371 | −CONFIG_CMA_SIZE_MBYTES=0 | |
| 372 | −CONFIG_CONNECTOR=y | |
| 373 | −CONFIG_ZRAM=m | |
| 374 | −CONFIG_BLK_DEV_LOOP=m | |
| 375 | −CONFIG_BLK_DEV_CRYPTOLOOP=m | |
| 376 | −CONFIG_BLK_DEV_DRBD=m | |
| 377 | −CONFIG_BLK_DEV_NBD=m | |
| 378 | −CONFIG_BLK_DEV_RAM=y | |
| 379 | −CONFIG_BLK_DEV_RAM_SIZE=32768 | |
| 380 | −CONFIG_BLK_DEV_RAM_DAX=y | |
| 381 | −CONFIG_VIRTIO_BLK=y | |
| 382 | −CONFIG_ENCLOSURE_SERVICES=m | |
| 383 | −CONFIG_GENWQE=m | |
| 384 | −CONFIG_RAID_ATTRS=m | |
| 385 | −CONFIG_SCSI=y | |
| 386 | −CONFIG_BLK_DEV_SD=y | |
| 387 | −CONFIG_CHR_DEV_ST=m | |
| 388 | −CONFIG_CHR_DEV_OSST=m | |
| 389 | −CONFIG_BLK_DEV_SR=m | |
| 390 | −CONFIG_CHR_DEV_SG=y | |
| 391 | −CONFIG_CHR_DEV_SCH=m | |
| 392 | −CONFIG_SCSI_ENCLOSURE=m | |
| 393 | −CONFIG_SCSI_CONSTANTS=y | |
| 394 | −CONFIG_SCSI_LOGGING=y | |
| 395 | −CONFIG_SCSI_SPI_ATTRS=m | |
| 396 | −CONFIG_SCSI_FC_ATTRS=y | |
| 397 | −CONFIG_SCSI_SAS_LIBSAS=m | |
| 398 | −CONFIG_SCSI_SRP_ATTRS=m | |
| 399 | −CONFIG_ISCSI_TCP=m | |
| 400 | −CONFIG_SCSI_DEBUG=m | |
| 401 | −CONFIG_ZFCP=y | |
| 402 | −CONFIG_SCSI_VIRTIO=m | |
| 403 | −CONFIG_SCSI_DH=y | |
| 404 | −CONFIG_SCSI_DH_RDAC=m | |
| 405 | −CONFIG_SCSI_DH_HP_SW=m | |
| 406 | −CONFIG_SCSI_DH_EMC=m | |
| 407 | −CONFIG_SCSI_DH_ALUA=m | |
| 408 | −CONFIG_SCSI_OSD_INITIATOR=m | |
| 409 | −CONFIG_SCSI_OSD_ULD=m | |
| 410 | −CONFIG_MD=y | |
| 411 | −CONFIG_BLK_DEV_MD=y | |
| 412 | −CONFIG_MD_LINEAR=m | |
| 413 | −CONFIG_MD_MULTIPATH=m | |
| 414 | −CONFIG_MD_FAULTY=m | |
| 415 | −CONFIG_BLK_DEV_DM=m | |
| 416 | −CONFIG_DM_CRYPT=m | |
| 417 | −CONFIG_DM_SNAPSHOT=m | |
| 418 | −CONFIG_DM_THIN_PROVISIONING=m | |
| 419 | −CONFIG_DM_MIRROR=m | |
| 420 | −CONFIG_DM_LOG_USERSPACE=m | |
| 421 | −CONFIG_DM_RAID=m | |
| 422 | −CONFIG_DM_ZERO=m | |
| 423 | −CONFIG_DM_MULTIPATH=m | |
| 424 | −CONFIG_DM_MULTIPATH_QL=m | |
| 425 | −CONFIG_DM_MULTIPATH_ST=m | |
| 426 | −CONFIG_DM_DELAY=m | |
| 427 | −CONFIG_DM_UEVENT=y | |
| 428 | −CONFIG_DM_FLAKEY=m | |
| 429 | −CONFIG_DM_VERITY=m | |
| 430 | −CONFIG_DM_SWITCH=m | |
| 431 | −CONFIG_NETDEVICES=y | |
| 432 | −CONFIG_BONDING=m | |
| 433 | −CONFIG_DUMMY=m | |
| 434 | −CONFIG_EQUALIZER=m | |
| 435 | −CONFIG_IFB=m | |
| 436 | −CONFIG_MACVLAN=m | |
| 437 | −CONFIG_MACVTAP=m | |
| 438 | −CONFIG_VXLAN=m | |
| 439 | −CONFIG_TUN=m | |
| 440 | −CONFIG_VETH=m | |
| 441 | −CONFIG_VIRTIO_NET=m | |
| 442 | −CONFIG_NLMON=m | |
| 443 | −# CONFIG_NET_VENDOR_ARC is not set | |
| 444 | −# CONFIG_NET_VENDOR_CHELSIO is not set | |
| 445 | −# CONFIG_NET_VENDOR_INTEL is not set | |
| 446 | −# CONFIG_NET_VENDOR_MARVELL is not set | |
| 447 | −CONFIG_MLX4_EN=m | |
| 448 | −CONFIG_MLX5_CORE=m | |
| 449 | −CONFIG_MLX5_CORE_EN=y | |
| 450 | −# CONFIG_NET_VENDOR_NATSEMI is not set | |
| 451 | −CONFIG_PPP=m | |
| 452 | −CONFIG_PPP_BSDCOMP=m | |
| 453 | −CONFIG_PPP_DEFLATE=m | |
| 454 | −CONFIG_PPP_MPPE=m | |
| 455 | −CONFIG_PPPOE=m | |
| 456 | −CONFIG_PPTP=m | |
| 457 | −CONFIG_PPPOL2TP=m | |
| 458 | −CONFIG_PPP_ASYNC=m | |
| 459 | −CONFIG_PPP_SYNC_TTY=m | |
| 460 | −# CONFIG_INPUT_KEYBOARD is not set | |
| 461 | −# CONFIG_INPUT_MOUSE is not set | |
| 462 | −# CONFIG_SERIO is not set | |
| 463 | −CONFIG_LEGACY_PTY_COUNT=0 | |
| 464 | −CONFIG_HW_RANDOM_VIRTIO=m | |
| 465 | −CONFIG_RAW_DRIVER=m | |
| 466 | −CONFIG_HANGCHECK_TIMER=m | |
| 467 | −CONFIG_TN3270_FS=y | |
| 468 | −# CONFIG_HWMON is not set | |
| 469 | −CONFIG_WATCHDOG=y | |
| 470 | −CONFIG_WATCHDOG_NOWAYOUT=y | |
| 471 | −CONFIG_SOFT_WATCHDOG=m | |
| 472 | −CONFIG_DIAG288_WATCHDOG=m | |
| 473 | −# CONFIG_HID is not set | |
| 474 | −# CONFIG_USB_SUPPORT is not set | |
| 475 | −CONFIG_INFINIBAND=m | |
| 476 | −CONFIG_INFINIBAND_USER_ACCESS=m | |
| 477 | −CONFIG_MLX4_INFINIBAND=m | |
| 478 | −CONFIG_MLX5_INFINIBAND=m | |
| 479 | −CONFIG_VFIO=m | |
| 480 | −CONFIG_VFIO_PCI=m | |
| 481 | −CONFIG_VIRTIO_BALLOON=m | |
| 482 | −CONFIG_EXT4_FS=y | |
| 483 | −CONFIG_EXT4_FS_POSIX_ACL=y | |
| 484 | −CONFIG_EXT4_FS_SECURITY=y | |
| 485 | −CONFIG_EXT4_ENCRYPTION=y | |
| 486 | −CONFIG_JBD2_DEBUG=y | |
| 487 | −CONFIG_JFS_FS=m | |
| 488 | −CONFIG_JFS_POSIX_ACL=y | |
| 489 | −CONFIG_JFS_SECURITY=y | |
| 490 | −CONFIG_JFS_STATISTICS=y | |
| 491 | −CONFIG_XFS_FS=y | |
| 492 | −CONFIG_XFS_QUOTA=y | |
| 493 | −CONFIG_XFS_POSIX_ACL=y | |
| 494 | −CONFIG_XFS_RT=y | |
| 495 | −CONFIG_GFS2_FS=m | |
| 496 | −CONFIG_GFS2_FS_LOCKING_DLM=y | |
| 497 | −CONFIG_OCFS2_FS=m | |
| 498 | −CONFIG_BTRFS_FS=y | |
| 499 | −CONFIG_BTRFS_FS_POSIX_ACL=y | |
| 500 | −CONFIG_NILFS2_FS=m | |
| 501 | −CONFIG_FS_DAX=y | |
| 502 | −CONFIG_EXPORTFS_BLOCK_OPS=y | |
| 503 | −CONFIG_FANOTIFY=y | |
| 504 | −CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y | |
| 505 | −CONFIG_QUOTA_NETLINK_INTERFACE=y | |
| 506 | −CONFIG_QFMT_V1=m | |
| 507 | −CONFIG_QFMT_V2=m | |
| 508 | −CONFIG_AUTOFS4_FS=m | |
| 509 | −CONFIG_FUSE_FS=y | |
| 510 | −CONFIG_CUSE=m | |
| 511 | −CONFIG_OVERLAY_FS=m | |
| 512 | −CONFIG_OVERLAY_FS_REDIRECT_DIR=y | |
| 513 | −CONFIG_FSCACHE=m | |
| 514 | −CONFIG_CACHEFILES=m | |
| 515 | −CONFIG_ISO9660_FS=y | |
| 516 | −CONFIG_JOLIET=y | |
| 517 | −CONFIG_ZISOFS=y | |
| 518 | −CONFIG_UDF_FS=m | |
| 519 | −CONFIG_MSDOS_FS=m | |
| 520 | −CONFIG_VFAT_FS=m | |
| 521 | −CONFIG_NTFS_FS=m | |
| 522 | −CONFIG_NTFS_RW=y | |
| 523 | −CONFIG_PROC_KCORE=y | |
| 524 | −CONFIG_TMPFS=y | |
| 525 | −CONFIG_TMPFS_POSIX_ACL=y | |
| 526 | −CONFIG_HUGETLBFS=y | |
| 527 | −CONFIG_CONFIGFS_FS=m | |
| 528 | −CONFIG_ECRYPT_FS=m | |
| 529 | −CONFIG_CRAMFS=m | |
| 530 | −CONFIG_SQUASHFS=m | |
| 531 | −CONFIG_SQUASHFS_XATTR=y | |
| 532 | −CONFIG_SQUASHFS_LZO=y | |
| 533 | −CONFIG_SQUASHFS_XZ=y | |
| 534 | −CONFIG_ROMFS_FS=m | |
| 535 | −CONFIG_NFS_FS=m | |
| 536 | −CONFIG_NFS_V3_ACL=y | |
| 537 | −CONFIG_NFS_V4=m | |
| 538 | −CONFIG_NFS_SWAP=y | |
| 539 | −CONFIG_NFSD=m | |
| 540 | −CONFIG_NFSD_V3_ACL=y | |
| 541 | −CONFIG_NFSD_V4=y | |
| 542 | −CONFIG_NFSD_V4_SECURITY_LABEL=y | |
| 543 | −CONFIG_CIFS=m | |
| 544 | −CONFIG_CIFS_STATS=y | |
| 545 | −CONFIG_CIFS_STATS2=y | |
| 546 | −CONFIG_CIFS_WEAK_PW_HASH=y | |
| 547 | −CONFIG_CIFS_UPCALL=y | |
| 548 | −CONFIG_CIFS_XATTR=y | |
| 549 | −CONFIG_CIFS_POSIX=y | |
| 550 | −# CONFIG_CIFS_DEBUG is not set | |
| 551 | −CONFIG_CIFS_DFS_UPCALL=y | |
| 552 | −CONFIG_NLS_DEFAULT="utf8" | |
| 553 | −CONFIG_NLS_CODEPAGE_437=m | |
| 554 | −CONFIG_NLS_CODEPAGE_850=m | |
| 555 | −CONFIG_NLS_ASCII=m | |
| 556 | −CONFIG_NLS_ISO8859_1=m | |
| 557 | −CONFIG_NLS_ISO8859_15=m | |
| 558 | −CONFIG_NLS_UTF8=m | |
| 559 | −CONFIG_DLM=m | |
| 560 | −CONFIG_PRINTK_TIME=y | |
| 561 | −CONFIG_DEBUG_INFO=y | |
| 562 | −CONFIG_DEBUG_INFO_DWARF4=y | |
| 563 | −CONFIG_GDB_SCRIPTS=y | |
| 564 | −# CONFIG_ENABLE_MUST_CHECK is not set | |
| 565 | −CONFIG_FRAME_WARN=1024 | |
| 566 | −CONFIG_UNUSED_SYMBOLS=y | |
| 567 | −CONFIG_MAGIC_SYSRQ=y | |
| 568 | −CONFIG_DEBUG_MEMORY_INIT=y | |
| 569 | −CONFIG_PANIC_ON_OOPS=y | |
| 570 | −CONFIG_RCU_TORTURE_TEST=m | |
| 571 | −CONFIG_RCU_CPU_STALL_TIMEOUT=60 | |
| 572 | −CONFIG_LATENCYTOP=y | |
| 573 | −CONFIG_SCHED_TRACER=y | |
| 574 | −CONFIG_FTRACE_SYSCALLS=y | |
| 575 | −CONFIG_STACK_TRACER=y | |
| 576 | −CONFIG_BLK_DEV_IO_TRACE=y | |
| 577 | −CONFIG_FUNCTION_PROFILER=y | |
| 578 | −CONFIG_HIST_TRIGGERS=y | |
| 579 | −CONFIG_LKDTM=m | |
| 580 | −CONFIG_PERCPU_TEST=m | |
| 581 | −CONFIG_ATOMIC64_SELFTEST=y | |
| 582 | −CONFIG_TEST_BPF=m | |
| 583 | −CONFIG_BUG_ON_DATA_CORRUPTION=y | |
| 584 | −CONFIG_S390_PTDUMP=y | |
| 585 | −CONFIG_PERSISTENT_KEYRINGS=y | |
| 586 | −CONFIG_BIG_KEYS=y | |
| 587 | −CONFIG_ENCRYPTED_KEYS=m | |
| 588 | −CONFIG_SECURITY=y | |
| 589 | −CONFIG_SECURITY_NETWORK=y | |
| 590 | −CONFIG_SECURITY_SELINUX=y | |
| 591 | −CONFIG_SECURITY_SELINUX_BOOTPARAM=y | |
| 592 | −CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 | |
| 593 | −CONFIG_SECURITY_SELINUX_DISABLE=y | |
| 594 | −CONFIG_INTEGRITY_SIGNATURE=y | |
| 595 | −CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y | |
| 596 | −CONFIG_IMA=y | |
| 597 | −CONFIG_IMA_WRITE_POLICY=y | |
| 598 | −CONFIG_IMA_APPRAISE=y | |
| 599 | −CONFIG_CRYPTO_DH=m | |
| 600 | −CONFIG_CRYPTO_ECDH=m | |
| 601 | −CONFIG_CRYPTO_USER=m | |
| 602 | −# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set | |
| 603 | −CONFIG_CRYPTO_PCRYPT=m | |
| 604 | −CONFIG_CRYPTO_CRYPTD=m | |
| 605 | −CONFIG_CRYPTO_MCRYPTD=m | |
| 606 | −CONFIG_CRYPTO_TEST=m | |
| 607 | −CONFIG_CRYPTO_CHACHA20POLY1305=m | |
| 608 | −CONFIG_CRYPTO_LRW=m | |
| 609 | −CONFIG_CRYPTO_PCBC=m | |
| 610 | −CONFIG_CRYPTO_KEYWRAP=m | |
| 611 | −CONFIG_CRYPTO_XCBC=m | |
| 612 | −CONFIG_CRYPTO_VMAC=m | |
| 613 | −CONFIG_CRYPTO_CRC32=m | |
| 614 | −CONFIG_CRYPTO_MICHAEL_MIC=m | |
| 615 | −CONFIG_CRYPTO_RMD128=m | |
| 616 | −CONFIG_CRYPTO_RMD160=m | |
| 617 | −CONFIG_CRYPTO_RMD256=m | |
| 618 | −CONFIG_CRYPTO_RMD320=m | |
| 619 | −CONFIG_CRYPTO_SHA512=m | |
| 620 | −CONFIG_CRYPTO_SHA3=m | |
| 621 | −CONFIG_CRYPTO_TGR192=m | |
| 622 | −CONFIG_CRYPTO_WP512=m | |
| 623 | −CONFIG_CRYPTO_AES_TI=m | |
| 624 | −CONFIG_CRYPTO_ANUBIS=m | |
| 625 | −CONFIG_CRYPTO_BLOWFISH=m | |
| 626 | −CONFIG_CRYPTO_CAMELLIA=m | |
| 627 | −CONFIG_CRYPTO_CAST5=m | |
| 628 | −CONFIG_CRYPTO_CAST6=m | |
| 629 | −CONFIG_CRYPTO_FCRYPT=m | |
| 630 | −CONFIG_CRYPTO_KHAZAD=m | |
| 631 | −CONFIG_CRYPTO_SALSA20=m | |
| 632 | −CONFIG_CRYPTO_SEED=m | |
| 633 | −CONFIG_CRYPTO_SERPENT=m | |
| 634 | −CONFIG_CRYPTO_TEA=m | |
| 635 | −CONFIG_CRYPTO_TWOFISH=m | |
| 636 | −CONFIG_CRYPTO_842=m | |
| 637 | −CONFIG_CRYPTO_LZ4=m | |
| 638 | −CONFIG_CRYPTO_LZ4HC=m | |
| 639 | −CONFIG_CRYPTO_ANSI_CPRNG=m | |
| 640 | −CONFIG_CRYPTO_USER_API_HASH=m | |
| 641 | −CONFIG_CRYPTO_USER_API_SKCIPHER=m | |
| 642 | −CONFIG_CRYPTO_USER_API_RNG=m | |
| 643 | −CONFIG_CRYPTO_USER_API_AEAD=m | |
| 644 | −CONFIG_ZCRYPT=m | |
| 645 | −CONFIG_PKEY=m | |
| 646 | −CONFIG_CRYPTO_PAES_S390=m | |
| 647 | −CONFIG_CRYPTO_SHA1_S390=m | |
| 648 | −CONFIG_CRYPTO_SHA256_S390=m | |
| 649 | −CONFIG_CRYPTO_SHA512_S390=m | |
| 650 | −CONFIG_CRYPTO_DES_S390=m | |
| 651 | −CONFIG_CRYPTO_AES_S390=m | |
| 652 | −CONFIG_CRYPTO_GHASH_S390=m | |
| 653 | −CONFIG_CRYPTO_CRC32_S390=y | |
| 654 | −CONFIG_CRC7=m | |
| 655 | −CONFIG_CRC8=m | |
| 656 | −CONFIG_CORDIC=m | |
| 657 | −CONFIG_CMM=m | |
| 658 | −CONFIG_APPLDATA_BASE=y | |
| 659 | −CONFIG_KVM=m | |
| 660 | −CONFIG_KVM_S390_UCONTROL=y | |
| 661 | −CONFIG_VHOST_NET=m | |
| @@ -25,13 +25,13 @@ CONFIG_CPUSETS=y · 24 unmodified lines | ||
| 25 | 25 | CONFIG_CGROUP_DEVICE=y |
| 26 | 26 | CONFIG_CGROUP_CPUACCT=y |
| 27 | 27 | CONFIG_CGROUP_PERF=y |
| 28 | −CONFIG_CHECKPOINT_RESTORE=y | |
| 29 | 28 | CONFIG_NAMESPACES=y |
| 30 | 29 | CONFIG_USER_NS=y |
| 31 | 30 | CONFIG_SCHED_AUTOGROUP=y |
| 32 | 31 | CONFIG_BLK_DEV_INITRD=y |
| 33 | 32 | CONFIG_EXPERT=y |
| 34 | 33 | # CONFIG_SYSFS_SYSCALL is not set |
| 34 | +CONFIG_CHECKPOINT_RESTORE=y | |
| 35 | 35 | CONFIG_BPF_SYSCALL=y |
| 36 | 36 | CONFIG_USERFAULTFD=y |
| 37 | 37 | # CONFIG_COMPAT_BRK is not set |
| @@ -45,6 +45,8 @@ CONFIG_MODULE_UNLOAD=y · 7 unmodified lines | ||
| 45 | 45 | CONFIG_MODULE_FORCE_UNLOAD=y |
| 46 | 46 | CONFIG_MODVERSIONS=y |
| 47 | 47 | CONFIG_MODULE_SRCVERSION_ALL=y |
| 48 | +CONFIG_MODULE_SIG=y | |
| 49 | +CONFIG_MODULE_SIG_SHA256=y | |
| 48 | 50 | CONFIG_BLK_DEV_INTEGRITY=y |
| 49 | 51 | CONFIG_BLK_DEV_THROTTLING=y |
| 50 | 52 | CONFIG_BLK_WBT=y |
| @@ -62,6 +64,7 @@ CONFIG_TUNE_ZEC12=y · 11 unmodified lines | ||
| 62 | 64 | CONFIG_NR_CPUS=512 |
| 63 | 65 | CONFIG_NUMA=y |
| 64 | 66 | CONFIG_HZ_100=y |
| 67 | +CONFIG_KEXEC_FILE=y | |
| 65 | 68 | CONFIG_MEMORY_HOTPLUG=y |
| 66 | 69 | CONFIG_MEMORY_HOTREMOVE=y |
| 67 | 70 | CONFIG_KSM=y |
| @@ -301,7 +304,6 @@ CONFIG_IP6_NF_SECURITY=m · 233 unmodified lines | ||
| 301 | 304 | CONFIG_IP6_NF_NAT=m |
| 302 | 305 | CONFIG_IP6_NF_TARGET_MASQUERADE=m |
| 303 | 306 | CONFIG_NF_TABLES_BRIDGE=m |
| 304 | −CONFIG_NET_SCTPPROBE=m | |
| 305 | 307 | CONFIG_RDS=m |
| 306 | 308 | CONFIG_RDS_RDMA=m |
| 307 | 309 | CONFIG_RDS_TCP=m |
| @@ -359,11 +361,11 @@ CONFIG_NET_ACT_SIMP=m · 51 unmodified lines | ||
| 359 | 361 | CONFIG_NET_ACT_SKBEDIT=m |
| 360 | 362 | CONFIG_NET_ACT_CSUM=m |
| 361 | 363 | CONFIG_DNS_RESOLVER=y |
| 364 | +CONFIG_OPENVSWITCH=m | |
| 362 | 365 | CONFIG_NETLINK_DIAG=m |
| 363 | 366 | CONFIG_CGROUP_NET_PRIO=y |
| 364 | 367 | CONFIG_BPF_JIT=y |
| 365 | 368 | CONFIG_NET_PKTGEN=m |
| 366 | −CONFIG_NET_TCPPROBE=m | |
| 367 | 369 | CONFIG_DEVTMPFS=y |
| 368 | 370 | CONFIG_DMA_CMA=y |
| 369 | 371 | CONFIG_CMA_SIZE_MBYTES=0 |
| @@ -375,8 +377,9 @@ CONFIG_BLK_DEV_DRBD=m · 5 unmodified lines | ||
| 375 | 377 | CONFIG_BLK_DEV_NBD=m |
| 376 | 378 | CONFIG_BLK_DEV_RAM=y |
| 377 | 379 | CONFIG_BLK_DEV_RAM_SIZE=32768 |
| 378 | −CONFIG_BLK_DEV_RAM_DAX=y | |
| 379 | 380 | CONFIG_VIRTIO_BLK=y |
| 381 | +CONFIG_BLK_DEV_RBD=m | |
| 382 | +CONFIG_BLK_DEV_NVME=m | |
| 380 | 383 | CONFIG_ENCLOSURE_SERVICES=m |
| 381 | 384 | CONFIG_GENWQE=m |
| 382 | 385 | CONFIG_RAID_ATTRS=m |
| @@ -455,6 +458,7 @@ CONFIG_PPTP=m · 72 unmodified lines | ||
| 455 | 458 | CONFIG_PPPOL2TP=m |
| 456 | 459 | CONFIG_PPP_ASYNC=m |
| 457 | 460 | CONFIG_PPP_SYNC_TTY=m |
| 461 | +CONFIG_INPUT_EVDEV=y | |
| 458 | 462 | # CONFIG_INPUT_KEYBOARD is not set |
| 459 | 463 | # CONFIG_INPUT_MOUSE is not set |
| 460 | 464 | # CONFIG_SERIO is not set |
| @@ -468,6 +472,9 @@ CONFIG_WATCHDOG=y · 7 unmodified lines | ||
| 468 | 472 | CONFIG_WATCHDOG_NOWAYOUT=y |
| 469 | 473 | CONFIG_SOFT_WATCHDOG=m |
| 470 | 474 | CONFIG_DIAG288_WATCHDOG=m |
| 475 | +CONFIG_DRM=y | |
| 476 | +CONFIG_DRM_VIRTIO_GPU=y | |
| 477 | +CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 471 | 478 | # CONFIG_HID is not set |
| 472 | 479 | # CONFIG_USB_SUPPORT is not set |
| 473 | 480 | CONFIG_INFINIBAND=m |
| @@ -476,7 +483,9 @@ CONFIG_MLX4_INFINIBAND=m · 2 unmodified lines | ||
| 476 | 483 | CONFIG_MLX5_INFINIBAND=m |
| 477 | 484 | CONFIG_VFIO=m |
| 478 | 485 | CONFIG_VFIO_PCI=m |
| 486 | +CONFIG_VIRTIO_PCI=m | |
| 479 | 487 | CONFIG_VIRTIO_BALLOON=m |
| 488 | +CONFIG_VIRTIO_INPUT=y | |
| 480 | 489 | CONFIG_EXT4_FS=y |
| 481 | 490 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 482 | 491 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -507,7 +516,6 @@ CONFIG_AUTOFS4_FS=m · 24 unmodified lines | ||
| 507 | 516 | CONFIG_FUSE_FS=y |
| 508 | 517 | CONFIG_CUSE=m |
| 509 | 518 | CONFIG_OVERLAY_FS=m |
| 510 | −CONFIG_OVERLAY_FS_REDIRECT_DIR=y | |
| 511 | 519 | CONFIG_FSCACHE=m |
| 512 | 520 | CONFIG_CACHEFILES=m |
| 513 | 521 | CONFIG_ISO9660_FS=y |
| @@ -592,8 +600,10 @@ CONFIG_SECURITY_SELINUX_DISABLE=y · 78 unmodified lines | ||
| 592 | 600 | CONFIG_INTEGRITY_SIGNATURE=y |
| 593 | 601 | CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y |
| 594 | 602 | CONFIG_IMA=y |
| 603 | +CONFIG_IMA_DEFAULT_HASH_SHA256=y | |
| 595 | 604 | CONFIG_IMA_WRITE_POLICY=y |
| 596 | 605 | CONFIG_IMA_APPRAISE=y |
| 606 | +CONFIG_CRYPTO_FIPS=y | |
| 597 | 607 | CONFIG_CRYPTO_DH=m |
| 598 | 608 | CONFIG_CRYPTO_ECDH=m |
| 599 | 609 | CONFIG_CRYPTO_USER=m |
| @@ -8,6 +8,7 @@ CONFIG_TASKSTATS=y · 7 unmodified lines | ||
| 8 | 8 | CONFIG_TASK_DELAY_ACCT=y |
| 9 | 9 | CONFIG_TASK_XACCT=y |
| 10 | 10 | CONFIG_TASK_IO_ACCOUNTING=y |
| 11 | +# CONFIG_CPU_ISOLATION is not set | |
| 11 | 12 | CONFIG_IKCONFIG=y |
| 12 | 13 | CONFIG_IKCONFIG_PROC=y |
| 13 | 14 | CONFIG_CGROUPS=y |
| @@ -23,12 +24,12 @@ CONFIG_CPUSETS=y · 9 unmodified lines | ||
| 23 | 24 | CONFIG_CGROUP_DEVICE=y |
| 24 | 25 | CONFIG_CGROUP_CPUACCT=y |
| 25 | 26 | CONFIG_CGROUP_PERF=y |
| 26 | −CONFIG_CHECKPOINT_RESTORE=y | |
| 27 | 27 | CONFIG_NAMESPACES=y |
| 28 | 28 | CONFIG_USER_NS=y |
| 29 | 29 | CONFIG_BLK_DEV_INITRD=y |
| 30 | 30 | CONFIG_EXPERT=y |
| 31 | 31 | # CONFIG_SYSFS_SYSCALL is not set |
| 32 | +CONFIG_CHECKPOINT_RESTORE=y | |
| 32 | 33 | CONFIG_BPF_SYSCALL=y |
| 33 | 34 | CONFIG_USERFAULTFD=y |
| 34 | 35 | # CONFIG_COMPAT_BRK is not set |
| @@ -47,6 +48,7 @@ CONFIG_LIVEPATCH=y · 12 unmodified lines | ||
| 47 | 48 | CONFIG_NR_CPUS=256 |
| 48 | 49 | CONFIG_NUMA=y |
| 49 | 50 | CONFIG_HZ_100=y |
| 51 | +CONFIG_KEXEC_FILE=y | |
| 50 | 52 | CONFIG_MEMORY_HOTPLUG=y |
| 51 | 53 | CONFIG_MEMORY_HOTREMOVE=y |
| 52 | 54 | CONFIG_KSM=y |
| @@ -129,10 +131,13 @@ CONFIG_EQUALIZER=m · 76 unmodified lines | ||
| 129 | 131 | CONFIG_TUN=m |
| 130 | 132 | CONFIG_VIRTIO_NET=y |
| 131 | 133 | # CONFIG_NET_VENDOR_ALACRITECH is not set |
| 134 | +# CONFIG_NET_VENDOR_CORTINA is not set | |
| 132 | 135 | # CONFIG_NET_VENDOR_SOLARFLARE is not set |
| 136 | +# CONFIG_NET_VENDOR_SOCIONEXT is not set | |
| 133 | 137 | # CONFIG_NET_VENDOR_SYNOPSYS is not set |
| 134 | 138 | # CONFIG_INPUT is not set |
| 135 | 139 | # CONFIG_SERIO is not set |
| 140 | +# CONFIG_VT is not set | |
| 136 | 141 | CONFIG_DEVKMEM=y |
| 137 | 142 | CONFIG_RAW_DRIVER=m |
| 138 | 143 | CONFIG_VIRTIO_BALLOON=y |
| @@ -177,13 +182,15 @@ CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y · 38 unmodified lines | ||
| 177 | 182 | CONFIG_STACK_TRACER=y |
| 178 | 183 | CONFIG_BLK_DEV_IO_TRACE=y |
| 179 | 184 | CONFIG_FUNCTION_PROFILER=y |
| 180 | −CONFIG_KPROBES_SANITY_TEST=y | |
| 185 | +# CONFIG_RUNTIME_TESTING_MENU is not set | |
| 181 | 186 | CONFIG_S390_PTDUMP=y |
| 182 | 187 | CONFIG_CRYPTO_CRYPTD=m |
| 188 | +CONFIG_CRYPTO_AUTHENC=m | |
| 183 | 189 | CONFIG_CRYPTO_TEST=m |
| 184 | 190 | CONFIG_CRYPTO_CCM=m |
| 185 | 191 | CONFIG_CRYPTO_GCM=m |
| 186 | 192 | CONFIG_CRYPTO_CBC=y |
| 193 | +CONFIG_CRYPTO_CFB=m | |
| 187 | 194 | CONFIG_CRYPTO_CTS=m |
| 188 | 195 | CONFIG_CRYPTO_LRW=m |
| 189 | 196 | CONFIG_CRYPTO_PCBC=m |
| @@ -213,6 +220,8 @@ CONFIG_CRYPTO_KHAZAD=m · 23 unmodified lines | ||
| 213 | 220 | CONFIG_CRYPTO_SALSA20=m |
| 214 | 221 | CONFIG_CRYPTO_SEED=m |
| 215 | 222 | CONFIG_CRYPTO_SERPENT=m |
| 223 | +CONFIG_CRYPTO_SM4=m | |
| 224 | +CONFIG_CRYPTO_SPECK=m | |
| 216 | 225 | CONFIG_CRYPTO_TEA=m |
| 217 | 226 | CONFIG_CRYPTO_TWOFISH=m |
| 218 | 227 | CONFIG_CRYPTO_DEFLATE=m |
| @@ -320,7 +320,7 @@ static void hypfs_kill_super(struct super_block *sb) · 319 unmodified lines | ||
| 320 | 320 | |
| 321 | 321 | if (sb->s_root) |
| 322 | 322 | hypfs_delete_tree(sb->s_root); |
| 323 | − if (sb_info->update_file) | |
| 323 | + if (sb_info && sb_info->update_file) | |
| 324 | 324 | hypfs_remove(sb_info->update_file); |
| 325 | 325 | kfree(sb->s_fs_info); |
| 326 | 326 | sb->s_fs_info = NULL; |
| @@ -46,4 +46,27 @@ · 45 unmodified lines | ||
| 46 | 46 | static inline void crash_setup_regs(struct pt_regs *newregs, |
| 47 | 47 | struct pt_regs *oldregs) { } |
| 48 | 48 | |
| 49 | +struct kimage; | |
| 50 | +struct s390_load_data { | |
| 51 | + /* Pointer to the kernel buffer. Used to register cmdline etc.. */ | |
| 52 | + void *kernel_buf; | |
| 53 | + | |
| 54 | + /* Total size of loaded segments in memory. Used as an offset. */ | |
| 55 | + size_t memsz; | |
| 56 | + | |
| 57 | + /* Load address of initrd. Used to register INITRD_START in kernel. */ | |
| 58 | + unsigned long initrd_load_addr; | |
| 59 | +}; | |
| 60 | + | |
| 61 | +int kexec_file_add_purgatory(struct kimage *image, | |
| 62 | + struct s390_load_data *data); | |
| 63 | +int kexec_file_add_initrd(struct kimage *image, | |
| 64 | + struct s390_load_data *data, | |
| 65 | + char *initrd, unsigned long initrd_len); | |
| 66 | +int *kexec_file_update_kernel(struct kimage *iamge, | |
| 67 | + struct s390_load_data *data); | |
| 68 | + | |
| 69 | +extern const struct kexec_file_ops s390_kexec_image_ops; | |
| 70 | +extern const struct kexec_file_ops s390_kexec_elf_ops; | |
| 71 | + | |
| 49 | 72 | #endif /*_S390_KEXEC_H */ |
| @@ -0,0 +1,17 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* | |
| 3 | + * Copyright IBM Corp. 2018 | |
| 4 | + * | |
| 5 | + * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | |
| 6 | + */ | |
| 7 | + | |
| 8 | +#ifndef _S390_PURGATORY_H_ | |
| 9 | +#define _S390_PURGATORY_H_ | |
| 10 | +#ifndef __ASSEMBLY__ | |
| 11 | + | |
| 12 | +#include <linux/purgatory.h> | |
| 13 | + | |
| 14 | +int verify_sha256_digest(void); | |
| 15 | + | |
| 16 | +#endif /* __ASSEMBLY__ */ | |
| 17 | +#endif /* _S390_PURGATORY_H_ */ | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | /* |
| 3 | 3 | * S390 version |
| 4 | − * Copyright IBM Corp. 1999, 2010 | |
| 4 | + * Copyright IBM Corp. 1999, 2017 | |
| 5 | 5 | */ |
| 6 | 6 | #ifndef _ASM_S390_SETUP_H |
| 7 | 7 | #define _ASM_S390_SETUP_H |
| @@ -37,17 +37,31 @@ · 29 unmodified lines | ||
| 37 | 37 | #define LPP_MAGIC _BITUL(31) |
| 38 | 38 | #define LPP_PID_MASK _AC(0xffffffff, UL) |
| 39 | 39 | |
| 40 | +/* Offsets to entry points in kernel/head.S */ | |
| 41 | + | |
| 42 | +#define STARTUP_NORMAL_OFFSET 0x10000 | |
| 43 | +#define STARTUP_KDUMP_OFFSET 0x10010 | |
| 44 | + | |
| 45 | +/* Offsets to parameters in kernel/head.S */ | |
| 46 | + | |
| 47 | +#define IPL_DEVICE_OFFSET 0x10400 | |
| 48 | +#define INITRD_START_OFFSET 0x10408 | |
| 49 | +#define INITRD_SIZE_OFFSET 0x10410 | |
| 50 | +#define OLDMEM_BASE_OFFSET 0x10418 | |
| 51 | +#define OLDMEM_SIZE_OFFSET 0x10420 | |
| 52 | +#define COMMAND_LINE_OFFSET 0x10480 | |
| 53 | + | |
| 40 | 54 | #ifndef __ASSEMBLY__ |
| 41 | 55 | |
| 42 | 56 | #include <asm/lowcore.h> |
| 43 | 57 | #include <asm/types.h> |
| 44 | 58 | |
| 45 | −#define IPL_DEVICE (*(unsigned long *) (0x10400)) | |
| 46 | −#define INITRD_START (*(unsigned long *) (0x10408)) | |
| 47 | −#define INITRD_SIZE (*(unsigned long *) (0x10410)) | |
| 48 | −#define OLDMEM_BASE (*(unsigned long *) (0x10418)) | |
| 49 | −#define OLDMEM_SIZE (*(unsigned long *) (0x10420)) | |
| 50 | −#define COMMAND_LINE ((char *) (0x10480)) | |
| 59 | +#define IPL_DEVICE (*(unsigned long *) (IPL_DEVICE_OFFSET)) | |
| 60 | +#define INITRD_START (*(unsigned long *) (INITRD_START_OFFSET)) | |
| 61 | +#define INITRD_SIZE (*(unsigned long *) (INITRD_SIZE_OFFSET)) | |
| 62 | +#define OLDMEM_BASE (*(unsigned long *) (OLDMEM_BASE_OFFSET)) | |
| 63 | +#define OLDMEM_SIZE (*(unsigned long *) (OLDMEM_SIZE_OFFSET)) | |
| 64 | +#define COMMAND_LINE ((char *) (COMMAND_LINE_OFFSET)) | |
| 51 | 65 | |
| 52 | 66 | extern int memory_end_set; |
| 53 | 67 | extern unsigned long memory_end; |
| @@ -121,12 +135,12 @@ extern void (*_machine_power_off)(void); · 67 unmodified lines | ||
| 121 | 135 | |
| 122 | 136 | #else /* __ASSEMBLY__ */ |
| 123 | 137 | |
| 124 | −#define IPL_DEVICE 0x10400 | |
| 125 | −#define INITRD_START 0x10408 | |
| 126 | −#define INITRD_SIZE 0x10410 | |
| 127 | −#define OLDMEM_BASE 0x10418 | |
| 128 | −#define OLDMEM_SIZE 0x10420 | |
| 129 | −#define COMMAND_LINE 0x10480 | |
| 138 | +#define IPL_DEVICE (IPL_DEVICE_OFFSET) | |
| 139 | +#define INITRD_START (INITRD_START_OFFSET) | |
| 140 | +#define INITRD_SIZE (INITRD_SIZE_OFFSET) | |
| 141 | +#define OLDMEM_BASE (OLDMEM_BASE_OFFSET) | |
| 142 | +#define OLDMEM_SIZE (OLDMEM_SIZE_OFFSET) | |
| 143 | +#define COMMAND_LINE (COMMAND_LINE_OFFSET) | |
| 130 | 144 | |
| 131 | 145 | #endif /* __ASSEMBLY__ */ |
| 132 | 146 | #endif /* _ASM_S390_SETUP_H */ |
| @@ -45,6 +45,9 @@ struct thread_info { · 44 unmodified lines | ||
| 45 | 45 | void arch_release_task_struct(struct task_struct *tsk); |
| 46 | 46 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); |
| 47 | 47 | |
| 48 | +void arch_setup_new_exec(void); | |
| 49 | +#define arch_setup_new_exec arch_setup_new_exec | |
| 50 | + | |
| 48 | 51 | #endif |
| 49 | 52 | |
| 50 | 53 | /* |
| @@ -97,22 +97,31 @@ typedef unsigned long sigset_t; · 96 unmodified lines | ||
| 97 | 97 | #include <asm-generic/signal-defs.h> |
| 98 | 98 | |
| 99 | 99 | #ifndef __KERNEL__ |
| 100 | −/* Here we must cater to libcs that poke about in kernel headers. */ | |
| 101 | 100 | |
| 101 | +/* | |
| 102 | + * There are two system calls in regard to sigaction, sys_rt_sigaction | |
| 103 | + * and sys_sigaction. Internally the kernel uses the struct old_sigaction | |
| 104 | + * for the older sys_sigaction system call, and the kernel version of the | |
| 105 | + * struct sigaction for the newer sys_rt_sigaction. | |
| 106 | + * | |
| 107 | + * The uapi definition for struct sigaction has made a strange distinction | |
| 108 | + * between 31-bit and 64-bit in the past. For 64-bit the uapi structure | |
| 109 | + * looks like the kernel struct sigaction, but for 31-bit it used to | |
| 110 | + * look like the kernel struct old_sigaction. That practically made the | |
| 111 | + * structure unusable for either system call. To get around this problem | |
| 112 | + * the glibc always had its own definitions for the sigaction structures. | |
| 113 | + * | |
| 114 | + * The current struct sigaction uapi definition below is suitable for the | |
| 115 | + * sys_rt_sigaction system call only. | |
| 116 | + */ | |
| 102 | 117 | struct sigaction { |
| 103 | 118 | union { |
| 104 | 119 | __sighandler_t _sa_handler; |
| 105 | 120 | void (*_sa_sigaction)(int, struct siginfo *, void *); |
| 106 | 121 | } _u; |
| 107 | −#ifndef __s390x__ /* lovely */ | |
| 108 | − sigset_t sa_mask; | |
| 109 | − unsigned long sa_flags; | |
| 110 | − void (*sa_restorer)(void); | |
| 111 | −#else /* __s390x__ */ | |
| 112 | 122 | unsigned long sa_flags; |
| 113 | 123 | void (*sa_restorer)(void); |
| 114 | 124 | sigset_t sa_mask; |
| 115 | −#endif /* __s390x__ */ | |
| 116 | 125 | }; |
| 117 | 126 | |
| 118 | 127 | #define sa_handler _u._sa_handler |
| @@ -82,6 +82,9 @@ obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o · 81 unmodified lines | ||
| 82 | 82 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
| 83 | 83 | obj-$(CONFIG_UPROBES) += uprobes.o |
| 84 | 84 | |
| 85 | +obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o | |
| 86 | +obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o | |
| 87 | + | |
| 85 | 88 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o |
| 86 | 89 | obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o |
| 87 | 90 | |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/kbuild.h> |
| 11 | 11 | #include <linux/kvm_host.h> |
| 12 | 12 | #include <linux/sched.h> |
| 13 | +#include <linux/purgatory.h> | |
| 13 | 14 | #include <asm/idle.h> |
| 14 | 15 | #include <asm/vdso.h> |
| 15 | 16 | #include <asm/pgtable.h> |
| @@ -204,5 +205,9 @@ int main(void) · 188 unmodified lines | ||
| 204 | 205 | OFFSET(__GMAP_ASCE, gmap, asce); |
| 205 | 206 | OFFSET(__SIE_PROG0C, kvm_s390_sie_block, prog0c); |
| 206 | 207 | OFFSET(__SIE_PROG20, kvm_s390_sie_block, prog20); |
| 208 | + /* kexec_sha_region */ | |
| 209 | + OFFSET(__KEXEC_SHA_REGION_START, kexec_sha_region, start); | |
| 210 | + OFFSET(__KEXEC_SHA_REGION_LEN, kexec_sha_region, len); | |
| 211 | + DEFINE(__KEXEC_SHA_REGION_SIZE, sizeof(struct kexec_sha_region)); | |
| 207 | 212 | return 0; |
| 208 | 213 | } |
| @@ -182,3 +182,4 @@ COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, · 181 unmodified lines | ||
| 182 | 182 | COMPAT_SYSCALL_WRAP2(s390_guarded_storage, int, command, struct gs_cb *, gs_cb); |
| 183 | 183 | COMPAT_SYSCALL_WRAP5(statx, int, dfd, const char __user *, path, unsigned, flags, unsigned, mask, struct statx __user *, buffer); |
| 184 | 184 | COMPAT_SYSCALL_WRAP4(s390_sthyi, unsigned long, code, void __user *, info, u64 __user *, rc, unsigned long, flags); |
| 185 | +COMPAT_SYSCALL_WRAP5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags) | |
| @@ -0,0 +1,147 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * ELF loader for kexec_file_load system call. | |
| 4 | + * | |
| 5 | + * Copyright IBM Corp. 2018 | |
| 6 | + * | |
| 7 | + * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/errno.h> | |
| 11 | +#include <linux/kernel.h> | |
| 12 | +#include <linux/kexec.h> | |
| 13 | +#include <asm/setup.h> | |
| 14 | + | |
| 15 | +static int kexec_file_add_elf_kernel(struct kimage *image, | |
| 16 | + struct s390_load_data *data, | |
| 17 | + char *kernel, unsigned long kernel_len) | |
| 18 | +{ | |
| 19 | + struct kexec_buf buf; | |
| 20 | + const Elf_Ehdr *ehdr; | |
| 21 | + const Elf_Phdr *phdr; | |
| 22 | + int i, ret; | |
| 23 | + | |
| 24 | + ehdr = (Elf_Ehdr *)kernel; | |
| 25 | + buf.image = image; | |
| 26 | + | |
| 27 | + phdr = (void *)ehdr + ehdr->e_phoff; | |
| 28 | + for (i = 0; i < ehdr->e_phnum; i++, phdr++) { | |
| 29 | + if (phdr->p_type != PT_LOAD) | |
| 30 | + continue; | |
| 31 | + | |
| 32 | + buf.buffer = kernel + phdr->p_offset; | |
| 33 | + buf.bufsz = phdr->p_filesz; | |
| 34 | + | |
| 35 | + buf.mem = ALIGN(phdr->p_paddr, phdr->p_align); | |
| 36 | + buf.memsz = phdr->p_memsz; | |
| 37 | + | |
| 38 | + if (phdr->p_paddr == 0) { | |
| 39 | + data->kernel_buf = buf.buffer; | |
| 40 | + data->memsz += STARTUP_NORMAL_OFFSET; | |
| 41 | + | |
| 42 | + buf.buffer += STARTUP_NORMAL_OFFSET; | |
| 43 | + buf.bufsz -= STARTUP_NORMAL_OFFSET; | |
| 44 | + | |
| 45 | + buf.mem += STARTUP_NORMAL_OFFSET; | |
| 46 | + buf.memsz -= STARTUP_NORMAL_OFFSET; | |
| 47 | + } | |
| 48 | + | |
| 49 | + if (image->type == KEXEC_TYPE_CRASH) | |
| 50 | + buf.mem += crashk_res.start; | |
| 51 | + | |
| 52 | + ret = kexec_add_buffer(&buf); | |
| 53 | + if (ret) | |
| 54 | + return ret; | |
| 55 | + | |
| 56 | + data->memsz += buf.memsz; | |
| 57 | + } | |
| 58 | + | |
| 59 | + return 0; | |
| 60 | +} | |
| 61 | + | |
| 62 | +static void *s390_elf_load(struct kimage *image, | |
| 63 | + char *kernel, unsigned long kernel_len, | |
| 64 | + char *initrd, unsigned long initrd_len, | |
| 65 | + char *cmdline, unsigned long cmdline_len) | |
| 66 | +{ | |
| 67 | + struct s390_load_data data = {0}; | |
| 68 | + const Elf_Ehdr *ehdr; | |
| 69 | + const Elf_Phdr *phdr; | |
| 70 | + size_t size; | |
| 71 | + int i, ret; | |
| 72 | + | |
| 73 | + /* image->fobs->probe already checked for valid ELF magic number. */ | |
| 74 | + ehdr = (Elf_Ehdr *)kernel; | |
| 75 | + | |
| 76 | + if (ehdr->e_type != ET_EXEC || | |
| 77 | + ehdr->e_ident[EI_CLASS] != ELFCLASS64 || | |
| 78 | + !elf_check_arch(ehdr)) | |
| 79 | + return ERR_PTR(-EINVAL); | |
| 80 | + | |
| 81 | + if (!ehdr->e_phnum || ehdr->e_phentsize != sizeof(Elf_Phdr)) | |
| 82 | + return ERR_PTR(-EINVAL); | |
| 83 | + | |
| 84 | + size = ehdr->e_ehsize + ehdr->e_phoff; | |
| 85 | + size += ehdr->e_phentsize * ehdr->e_phnum; | |
| 86 | + if (size > kernel_len) | |
| 87 | + return ERR_PTR(-EINVAL); | |
| 88 | + | |
| 89 | + phdr = (void *)ehdr + ehdr->e_phoff; | |
| 90 | + size = ALIGN(size, phdr->p_align); | |
| 91 | + for (i = 0; i < ehdr->e_phnum; i++, phdr++) { | |
| 92 | + if (phdr->p_type == PT_INTERP) | |
| 93 | + return ERR_PTR(-EINVAL); | |
| 94 | + | |
| 95 | + if (phdr->p_offset > kernel_len) | |
| 96 | + return ERR_PTR(-EINVAL); | |
| 97 | + | |
| 98 | + size += ALIGN(phdr->p_filesz, phdr->p_align); | |
| 99 | + } | |
| 100 | + | |
| 101 | + if (size > kernel_len) | |
| 102 | + return ERR_PTR(-EINVAL); | |
| 103 | + | |
| 104 | + ret = kexec_file_add_elf_kernel(image, &data, kernel, kernel_len); | |
| 105 | + if (ret) | |
| 106 | + return ERR_PTR(ret); | |
| 107 | + | |
| 108 | + if (!data.memsz) | |
| 109 | + return ERR_PTR(-EINVAL); | |
| 110 | + | |
| 111 | + if (initrd) { | |
| 112 | + ret = kexec_file_add_initrd(image, &data, initrd, initrd_len); | |
| 113 | + if (ret) | |
| 114 | + return ERR_PTR(ret); | |
| 115 | + } | |
| 116 | + | |
| 117 | + ret = kexec_file_add_purgatory(image, &data); | |
| 118 | + if (ret) | |
| 119 | + return ERR_PTR(ret); | |
| 120 | + | |
| 121 | + return kexec_file_update_kernel(image, &data); | |
| 122 | +} | |
| 123 | + | |
| 124 | +static int s390_elf_probe(const char *buf, unsigned long len) | |
| 125 | +{ | |
| 126 | + const Elf_Ehdr *ehdr; | |
| 127 | + | |
| 128 | + if (len < sizeof(Elf_Ehdr)) | |
| 129 | + return -ENOEXEC; | |
| 130 | + | |
| 131 | + ehdr = (Elf_Ehdr *)buf; | |
| 132 | + | |
| 133 | + /* Only check the ELF magic number here and do proper validity check | |
| 134 | + * in the loader. Any check here that fails would send the erroneous | |
| 135 | + * ELF file to the image loader that does not care what it gets. | |
| 136 | + * (Most likely) causing behavior not intended by the user. | |
| 137 | + */ | |
| 138 | + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) | |
| 139 | + return -ENOEXEC; | |
| 140 | + | |
| 141 | + return 0; | |
| 142 | +} | |
| 143 | + | |
| 144 | +const struct kexec_file_ops s390_kexec_elf_ops = { | |
| 145 | + .probe = s390_elf_probe, | |
| 146 | + .load = s390_elf_load, | |
| 147 | +}; | |
| @@ -0,0 +1,76 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Image loader for kexec_file_load system call. | |
| 4 | + * | |
| 5 | + * Copyright IBM Corp. 2018 | |
| 6 | + * | |
| 7 | + * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/errno.h> | |
| 11 | +#include <linux/kernel.h> | |
| 12 | +#include <linux/kexec.h> | |
| 13 | +#include <asm/setup.h> | |
| 14 | + | |
| 15 | +static int kexec_file_add_image_kernel(struct kimage *image, | |
| 16 | + struct s390_load_data *data, | |
| 17 | + char *kernel, unsigned long kernel_len) | |
| 18 | +{ | |
| 19 | + struct kexec_buf buf; | |
| 20 | + int ret; | |
| 21 | + | |
| 22 | + buf.image = image; | |
| 23 | + | |
| 24 | + buf.buffer = kernel + STARTUP_NORMAL_OFFSET; | |
| 25 | + buf.bufsz = kernel_len - STARTUP_NORMAL_OFFSET; | |
| 26 | + | |
| 27 | + buf.mem = STARTUP_NORMAL_OFFSET; | |
| 28 | + if (image->type == KEXEC_TYPE_CRASH) | |
| 29 | + buf.mem += crashk_res.start; | |
| 30 | + buf.memsz = buf.bufsz; | |
| 31 | + | |
| 32 | + ret = kexec_add_buffer(&buf); | |
| 33 | + | |
| 34 | + data->kernel_buf = kernel; | |
| 35 | + data->memsz += buf.memsz + STARTUP_NORMAL_OFFSET; | |
| 36 | + | |
| 37 | + return ret; | |
| 38 | +} | |
| 39 | + | |
| 40 | +static void *s390_image_load(struct kimage *image, | |
| 41 | + char *kernel, unsigned long kernel_len, | |
| 42 | + char *initrd, unsigned long initrd_len, | |
| 43 | + char *cmdline, unsigned long cmdline_len) | |
| 44 | +{ | |
| 45 | + struct s390_load_data data = {0}; | |
| 46 | + int ret; | |
| 47 | + | |
| 48 | + ret = kexec_file_add_image_kernel(image, &data, kernel, kernel_len); | |
| 49 | + if (ret) | |
| 50 | + return ERR_PTR(ret); | |
| 51 | + | |
| 52 | + if (initrd) { | |
| 53 | + ret = kexec_file_add_initrd(image, &data, initrd, initrd_len); | |
| 54 | + if (ret) | |
| 55 | + return ERR_PTR(ret); | |
| 56 | + } | |
| 57 | + | |
| 58 | + ret = kexec_file_add_purgatory(image, &data); | |
| 59 | + if (ret) | |
| 60 | + return ERR_PTR(ret); | |
| 61 | + | |
| 62 | + return kexec_file_update_kernel(image, &data); | |
| 63 | +} | |
| 64 | + | |
| 65 | +static int s390_image_probe(const char *buf, unsigned long len) | |
| 66 | +{ | |
| 67 | + /* Can't reliably tell if an image is valid. Therefore give the | |
| 68 | + * user whatever he wants. | |
| 69 | + */ | |
| 70 | + return 0; | |
| 71 | +} | |
| 72 | + | |
| 73 | +const struct kexec_file_ops s390_kexec_image_ops = { | |
| 74 | + .probe = s390_image_probe, | |
| 75 | + .load = s390_image_load, | |
| 76 | +}; | |
| @@ -0,0 +1,245 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * s390 code for kexec_file_load system call | |
| 4 | + * | |
| 5 | + * Copyright IBM Corp. 2018 | |
| 6 | + * | |
| 7 | + * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/elf.h> | |
| 11 | +#include <linux/kexec.h> | |
| 12 | +#include <asm/setup.h> | |
| 13 | + | |
| 14 | +const struct kexec_file_ops * const kexec_file_loaders[] = { | |
| 15 | + &s390_kexec_elf_ops, | |
| 16 | + &s390_kexec_image_ops, | |
| 17 | + NULL, | |
| 18 | +}; | |
| 19 | + | |
| 20 | +int *kexec_file_update_kernel(struct kimage *image, | |
| 21 | + struct s390_load_data *data) | |
| 22 | +{ | |
| 23 | + unsigned long *loc; | |
| 24 | + | |
| 25 | + if (image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE) | |
| 26 | + return ERR_PTR(-EINVAL); | |
| 27 | + | |
| 28 | + if (image->cmdline_buf_len) | |
| 29 | + memcpy(data->kernel_buf + COMMAND_LINE_OFFSET, | |
| 30 | + image->cmdline_buf, image->cmdline_buf_len); | |
| 31 | + | |
| 32 | + if (image->type == KEXEC_TYPE_CRASH) { | |
| 33 | + loc = (unsigned long *)(data->kernel_buf + OLDMEM_BASE_OFFSET); | |
| 34 | + *loc = crashk_res.start; | |
| 35 | + | |
| 36 | + loc = (unsigned long *)(data->kernel_buf + OLDMEM_SIZE_OFFSET); | |
| 37 | + *loc = crashk_res.end - crashk_res.start + 1; | |
| 38 | + } | |
| 39 | + | |
| 40 | + if (image->initrd_buf) { | |
| 41 | + loc = (unsigned long *)(data->kernel_buf + INITRD_START_OFFSET); | |
| 42 | + *loc = data->initrd_load_addr; | |
| 43 | + | |
| 44 | + loc = (unsigned long *)(data->kernel_buf + INITRD_SIZE_OFFSET); | |
| 45 | + *loc = image->initrd_buf_len; | |
| 46 | + } | |
| 47 | + | |
| 48 | + return NULL; | |
| 49 | +} | |
| 50 | + | |
| 51 | +static int kexec_file_update_purgatory(struct kimage *image) | |
| 52 | +{ | |
| 53 | + u64 entry, type; | |
| 54 | + int ret; | |
| 55 | + | |
| 56 | + if (image->type == KEXEC_TYPE_CRASH) { | |
| 57 | + entry = STARTUP_KDUMP_OFFSET; | |
| 58 | + type = KEXEC_TYPE_CRASH; | |
| 59 | + } else { | |
| 60 | + entry = STARTUP_NORMAL_OFFSET; | |
| 61 | + type = KEXEC_TYPE_DEFAULT; | |
| 62 | + } | |
| 63 | + | |
| 64 | + ret = kexec_purgatory_get_set_symbol(image, "kernel_entry", &entry, | |
| 65 | + sizeof(entry), false); | |
| 66 | + if (ret) | |
| 67 | + return ret; | |
| 68 | + | |
| 69 | + ret = kexec_purgatory_get_set_symbol(image, "kernel_type", &type, | |
| 70 | + sizeof(type), false); | |
| 71 | + if (ret) | |
| 72 | + return ret; | |
| 73 | + | |
| 74 | + if (image->type == KEXEC_TYPE_CRASH) { | |
| 75 | + u64 crash_size; | |
| 76 | + | |
| 77 | + ret = kexec_purgatory_get_set_symbol(image, "crash_start", | |
| 78 | + &crashk_res.start, | |
| 79 | + sizeof(crashk_res.start), | |
| 80 | + false); | |
| 81 | + if (ret) | |
| 82 | + return ret; | |
| 83 | + | |
| 84 | + crash_size = crashk_res.end - crashk_res.start + 1; | |
| 85 | + ret = kexec_purgatory_get_set_symbol(image, "crash_size", | |
| 86 | + &crash_size, | |
| 87 | + sizeof(crash_size), | |
| 88 | + false); | |
| 89 | + } | |
| 90 | + return ret; | |
| 91 | +} | |
| 92 | + | |
| 93 | +int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data) | |
| 94 | +{ | |
| 95 | + struct kexec_buf buf; | |
| 96 | + int ret; | |
| 97 | + | |
| 98 | + buf.image = image; | |
| 99 | + | |
| 100 | + data->memsz = ALIGN(data->memsz, PAGE_SIZE); | |
| 101 | + buf.mem = data->memsz; | |
| 102 | + if (image->type == KEXEC_TYPE_CRASH) | |
| 103 | + buf.mem += crashk_res.start; | |
| 104 | + | |
| 105 | + ret = kexec_load_purgatory(image, &buf); | |
| 106 | + if (ret) | |
| 107 | + return ret; | |
| 108 | + | |
| 109 | + ret = kexec_file_update_purgatory(image); | |
| 110 | + return ret; | |
| 111 | +} | |
| 112 | + | |
| 113 | +int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data, | |
| 114 | + char *initrd, unsigned long initrd_len) | |
| 115 | +{ | |
| 116 | + struct kexec_buf buf; | |
| 117 | + int ret; | |
| 118 | + | |
| 119 | + buf.image = image; | |
| 120 | + | |
| 121 | + buf.buffer = initrd; | |
| 122 | + buf.bufsz = initrd_len; | |
| 123 | + | |
| 124 | + data->memsz = ALIGN(data->memsz, PAGE_SIZE); | |
| 125 | + buf.mem = data->memsz; | |
| 126 | + if (image->type == KEXEC_TYPE_CRASH) | |
| 127 | + buf.mem += crashk_res.start; | |
| 128 | + buf.memsz = buf.bufsz; | |
| 129 | + | |
| 130 | + data->initrd_load_addr = buf.mem; | |
| 131 | + data->memsz += buf.memsz; | |
| 132 | + | |
| 133 | + ret = kexec_add_buffer(&buf); | |
| 134 | + return ret; | |
| 135 | +} | |
| 136 | + | |
| 137 | +/* | |
| 138 | + * The kernel is loaded to a fixed location. Turn off kexec_locate_mem_hole | |
| 139 | + * and provide kbuf->mem by hand. | |
| 140 | + */ | |
| 141 | +int arch_kexec_walk_mem(struct kexec_buf *kbuf, | |
| 142 | + int (*func)(struct resource *, void *)) | |
| 143 | +{ | |
| 144 | + return 1; | |
| 145 | +} | |
| 146 | + | |
| 147 | +int arch_kexec_apply_relocations_add(struct purgatory_info *pi, | |
| 148 | + Elf_Shdr *section, | |
| 149 | + const Elf_Shdr *relsec, | |
| 150 | + const Elf_Shdr *symtab) | |
| 151 | +{ | |
| 152 | + Elf_Rela *relas; | |
| 153 | + int i; | |
| 154 | + | |
| 155 | + relas = (void *)pi->ehdr + relsec->sh_offset; | |
| 156 | + | |
| 157 | + for (i = 0; i < relsec->sh_size / sizeof(*relas); i++) { | |
| 158 | + const Elf_Sym *sym; /* symbol to relocate */ | |
| 159 | + unsigned long addr; /* final location after relocation */ | |
| 160 | + unsigned long val; /* relocated symbol value */ | |
| 161 | + void *loc; /* tmp location to modify */ | |
| 162 | + | |
| 163 | + sym = (void *)pi->ehdr + symtab->sh_offset; | |
| 164 | + sym += ELF64_R_SYM(relas[i].r_info); | |
| 165 | + | |
| 166 | + if (sym->st_shndx == SHN_UNDEF) | |
| 167 | + return -ENOEXEC; | |
| 168 | + | |
| 169 | + if (sym->st_shndx == SHN_COMMON) | |
| 170 | + return -ENOEXEC; | |
| 171 | + | |
| 172 | + if (sym->st_shndx >= pi->ehdr->e_shnum && | |
| 173 | + sym->st_shndx != SHN_ABS) | |
| 174 | + return -ENOEXEC; | |
| 175 | + | |
| 176 | + loc = pi->purgatory_buf; | |
| 177 | + loc += section->sh_offset; | |
| 178 | + loc += relas[i].r_offset; | |
| 179 | + | |
| 180 | + val = sym->st_value; | |
| 181 | + if (sym->st_shndx != SHN_ABS) | |
| 182 | + val += pi->sechdrs[sym->st_shndx].sh_addr; | |
| 183 | + val += relas[i].r_addend; | |
| 184 | + | |
| 185 | + addr = section->sh_addr + relas[i].r_offset; | |
| 186 | + | |
| 187 | + switch (ELF64_R_TYPE(relas[i].r_info)) { | |
| 188 | + case R_390_8: /* Direct 8 bit. */ | |
| 189 | + *(u8 *)loc = val; | |
| 190 | + break; | |
| 191 | + case R_390_12: /* Direct 12 bit. */ | |
| 192 | + *(u16 *)loc &= 0xf000; | |
| 193 | + *(u16 *)loc |= val & 0xfff; | |
| 194 | + break; | |
| 195 | + case R_390_16: /* Direct 16 bit. */ | |
| 196 | + *(u16 *)loc = val; | |
| 197 | + break; | |
| 198 | + case R_390_20: /* Direct 20 bit. */ | |
| 199 | + *(u32 *)loc &= 0xf00000ff; | |
| 200 | + *(u32 *)loc |= (val & 0xfff) << 16; /* DL */ | |
| 201 | + *(u32 *)loc |= (val & 0xff000) >> 4; /* DH */ | |
| 202 | + break; | |
| 203 | + case R_390_32: /* Direct 32 bit. */ | |
| 204 | + *(u32 *)loc = val; | |
| 205 | + break; | |
| 206 | + case R_390_64: /* Direct 64 bit. */ | |
| 207 | + *(u64 *)loc = val; | |
| 208 | + break; | |
| 209 | + case R_390_PC16: /* PC relative 16 bit. */ | |
| 210 | + *(u16 *)loc = (val - addr); | |
| 211 | + break; | |
| 212 | + case R_390_PC16DBL: /* PC relative 16 bit shifted by 1. */ | |
| 213 | + *(u16 *)loc = (val - addr) >> 1; | |
| 214 | + break; | |
| 215 | + case R_390_PC32DBL: /* PC relative 32 bit shifted by 1. */ | |
| 216 | + *(u32 *)loc = (val - addr) >> 1; | |
| 217 | + break; | |
| 218 | + case R_390_PC32: /* PC relative 32 bit. */ | |
| 219 | + *(u32 *)loc = (val - addr); | |
| 220 | + break; | |
| 221 | + case R_390_PC64: /* PC relative 64 bit. */ | |
| 222 | + *(u64 *)loc = (val - addr); | |
| 223 | + break; | |
| 224 | + default: | |
| 225 | + break; | |
| 226 | + } | |
| 227 | + } | |
| 228 | + return 0; | |
| 229 | +} | |
| 230 | + | |
| 231 | +int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, | |
| 232 | + unsigned long buf_len) | |
| 233 | +{ | |
| 234 | + /* A kernel must be at least large enough to contain head.S. During | |
| 235 | + * load memory in head.S will be accessed, e.g. to register the next | |
| 236 | + * command line. If the next kernel were smaller the current kernel | |
| 237 | + * will panic at load. | |
| 238 | + * | |
| 239 | + * 0x11000 = sizeof(head.S) | |
| 240 | + */ | |
| 241 | + if (buf_len < 0x11000) | |
| 242 | + return -ENOEXEC; | |
| 243 | + | |
| 244 | + return kexec_image_probe_default(image, buf, buf_len); | |
| 245 | +} | |
| @@ -465,11 +465,11 @@ int module_finalize(const Elf_Ehdr *hdr, · 464 unmodified lines | ||
| 465 | 465 | apply_alternatives(aseg, aseg + s->sh_size); |
| 466 | 466 | |
| 467 | 467 | if (IS_ENABLED(CONFIG_EXPOLINE) && |
| 468 | − (!strcmp(".nospec_call_table", secname))) | |
| 468 | + (!strncmp(".s390_indirect", secname, 14))) | |
| 469 | 469 | nospec_revert(aseg, aseg + s->sh_size); |
| 470 | 470 | |
| 471 | 471 | if (IS_ENABLED(CONFIG_EXPOLINE) && |
| 472 | − (!strcmp(".nospec_return_table", secname))) | |
| 472 | + (!strncmp(".s390_return", secname, 12))) | |
| 473 | 473 | nospec_revert(aseg, aseg + s->sh_size); |
| 474 | 474 | } |
| 475 | 475 | |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/module.h> |
| 3 | 3 | #include <linux/device.h> |
| 4 | +#include <linux/cpu.h> | |
| 4 | 5 | #include <asm/nospec-branch.h> |
| 5 | 6 | |
| 6 | 7 | static int __init nobp_setup_early(char *str) |
| @@ -123,7 +123,7 @@ CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES_IV, 0x00a1); · 122 unmodified lines | ||
| 123 | 123 | CPUMF_EVENT_ATTR(cf_zec12, TX_NC_TABORT, 0x00b1); |
| 124 | 124 | CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_NO_SPECIAL, 0x00b2); |
| 125 | 125 | CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_SPECIAL, 0x00b3); |
| 126 | −CPUMF_EVENT_ATTR(cf_z13, L1D_WRITES_RO_EXCL, 0x0080); | |
| 126 | +CPUMF_EVENT_ATTR(cf_z13, L1D_RO_EXCL_WRITES, 0x0080); | |
| 127 | 127 | CPUMF_EVENT_ATTR(cf_z13, DTLB1_WRITES, 0x0081); |
| 128 | 128 | CPUMF_EVENT_ATTR(cf_z13, DTLB1_MISSES, 0x0082); |
| 129 | 129 | CPUMF_EVENT_ATTR(cf_z13, DTLB1_HPAGE_WRITES, 0x0083); |
| @@ -179,7 +179,7 @@ CPUMF_EVENT_ATTR(cf_z13, TX_C_TABORT_NO_SPECIAL, 0x00db); · 49 unmodified lines | ||
| 179 | 179 | CPUMF_EVENT_ATTR(cf_z13, TX_C_TABORT_SPECIAL, 0x00dc); |
| 180 | 180 | CPUMF_EVENT_ATTR(cf_z13, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); |
| 181 | 181 | CPUMF_EVENT_ATTR(cf_z13, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); |
| 182 | −CPUMF_EVENT_ATTR(cf_z14, L1D_WRITES_RO_EXCL, 0x0080); | |
| 182 | +CPUMF_EVENT_ATTR(cf_z14, L1D_RO_EXCL_WRITES, 0x0080); | |
| 183 | 183 | CPUMF_EVENT_ATTR(cf_z14, DTLB2_WRITES, 0x0081); |
| 184 | 184 | CPUMF_EVENT_ATTR(cf_z14, DTLB2_MISSES, 0x0082); |
| 185 | 185 | CPUMF_EVENT_ATTR(cf_z14, DTLB2_HPAGE_WRITES, 0x0083); |
| @@ -371,7 +371,7 @@ static struct attribute *cpumcf_zec12_pmu_event_attr[] __initdata = { · 185 unmodified lines | ||
| 371 | 371 | }; |
| 372 | 372 | |
| 373 | 373 | static struct attribute *cpumcf_z13_pmu_event_attr[] __initdata = { |
| 374 | − CPUMF_EVENT_PTR(cf_z13, L1D_WRITES_RO_EXCL), | |
| 374 | + CPUMF_EVENT_PTR(cf_z13, L1D_RO_EXCL_WRITES), | |
| 375 | 375 | CPUMF_EVENT_PTR(cf_z13, DTLB1_WRITES), |
| 376 | 376 | CPUMF_EVENT_PTR(cf_z13, DTLB1_MISSES), |
| 377 | 377 | CPUMF_EVENT_PTR(cf_z13, DTLB1_HPAGE_WRITES), |
| @@ -431,7 +431,7 @@ static struct attribute *cpumcf_z13_pmu_event_attr[] __initdata = { · 53 unmodified lines | ||
| 431 | 431 | }; |
| 432 | 432 | |
| 433 | 433 | static struct attribute *cpumcf_z14_pmu_event_attr[] __initdata = { |
| 434 | − CPUMF_EVENT_PTR(cf_z14, L1D_WRITES_RO_EXCL), | |
| 434 | + CPUMF_EVENT_PTR(cf_z14, L1D_RO_EXCL_WRITES), | |
| 435 | 435 | CPUMF_EVENT_PTR(cf_z14, DTLB2_WRITES), |
| 436 | 436 | CPUMF_EVENT_PTR(cf_z14, DTLB2_MISSES), |
| 437 | 437 | CPUMF_EVENT_PTR(cf_z14, DTLB2_HPAGE_WRITES), |
| @@ -583,6 +583,7 @@ __init const struct attribute_group **cpumf_cf_event_group(void) · 145 unmodified lines | ||
| 583 | 583 | model = cpumcf_z13_pmu_event_attr; |
| 584 | 584 | break; |
| 585 | 585 | case 0x3906: |
| 586 | + case 0x3907: | |
| 586 | 587 | model = cpumcf_z14_pmu_event_attr; |
| 587 | 588 | break; |
| 588 | 589 | default: |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/random.h> |
| 30 | 30 | #include <linux/export.h> |
| 31 | 31 | #include <linux/init_task.h> |
| 32 | +#include <asm/cpu_mf.h> | |
| 32 | 33 | #include <asm/io.h> |
| 33 | 34 | #include <asm/processor.h> |
| 34 | 35 | #include <asm/vtimer.h> |
| @@ -48,6 +49,15 @@ void flush_thread(void) · 13 unmodified lines | ||
| 48 | 49 | { |
| 49 | 50 | } |
| 50 | 51 | |
| 52 | +void arch_setup_new_exec(void) | |
| 53 | +{ | |
| 54 | + if (S390_lowcore.current_pid != current->pid) { | |
| 55 | + S390_lowcore.current_pid = current->pid; | |
| 56 | + if (test_facility(40)) | |
| 57 | + lpp(&S390_lowcore.lpp); | |
| 58 | + } | |
| 59 | +} | |
| 60 | + | |
| 51 | 61 | void arch_release_task_struct(struct task_struct *tsk) |
| 52 | 62 | { |
| 53 | 63 | runtime_instr_release(tsk); |
| @@ -821,6 +821,7 @@ static int __init setup_hwcaps(void) · 820 unmodified lines | ||
| 821 | 821 | strcpy(elf_platform, "z13"); |
| 822 | 822 | break; |
| 823 | 823 | case 0x3906: |
| 824 | + case 0x3907: | |
| 824 | 825 | strcpy(elf_platform, "z14"); |
| 825 | 826 | break; |
| 826 | 827 | } |
| @@ -388,3 +388,4 @@ · 387 unmodified lines | ||
| 388 | 388 | 378 common s390_guarded_storage sys_s390_guarded_storage compat_sys_s390_guarded_storage |
| 389 | 389 | 379 common statx sys_statx compat_sys_statx |
| 390 | 390 | 380 common s390_sthyi sys_s390_sthyi compat_sys_s390_sthyi |
| 391 | +381 common kexec_file_load sys_kexec_file_load compat_sys_kexec_file_load | |
| @@ -150,6 +150,15 @@ unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline, · 149 unmodified lines | ||
| 150 | 150 | return orig; |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | +bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, | |
| 154 | + struct pt_regs *regs) | |
| 155 | +{ | |
| 156 | + if (ctx == RP_CHECK_CHAIN_CALL) | |
| 157 | + return user_stack_pointer(regs) <= ret->stack; | |
| 158 | + else | |
| 159 | + return user_stack_pointer(regs) < ret->stack; | |
| 160 | +} | |
| 161 | + | |
| 153 | 162 | /* Instruction Emulation */ |
| 154 | 163 | |
| 155 | 164 | static void adjust_psw_addr(psw_t *psw, unsigned long len) |
| @@ -0,0 +1,2 @@ | ||
| 1 | +kexec-purgatory.c | |
| 2 | +purgatory.ro | |
| @@ -0,0 +1,37 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | + | |
| 3 | +OBJECT_FILES_NON_STANDARD := y | |
| 4 | + | |
| 5 | +purgatory-y := head.o purgatory.o string.o sha256.o mem.o | |
| 6 | + | |
| 7 | +targets += $(purgatory-y) purgatory.ro kexec-purgatory.c | |
| 8 | +PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y)) | |
| 9 | + | |
| 10 | +$(obj)/sha256.o: $(srctree)/lib/sha256.c | |
| 11 | + $(call if_changed_rule,cc_o_c) | |
| 12 | + | |
| 13 | +$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S | |
| 14 | + $(call if_changed_rule,as_o_S) | |
| 15 | + | |
| 16 | +$(obj)/string.o: $(srctree)/arch/s390/lib/string.c | |
| 17 | + $(call if_changed_rule,cc_o_c) | |
| 18 | + | |
| 19 | +LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib | |
| 20 | +LDFLAGS_purgatory.ro += -z nodefaultlib | |
| 21 | +KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes | |
| 22 | +KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare | |
| 23 | +KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding | |
| 24 | +KBUILD_CFLAGS += -c -MD -Os -m64 | |
| 25 | +KBUILD_CFLAGS += $(call cc-option,-fno-PIE) | |
| 26 | + | |
| 27 | +$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE | |
| 28 | + $(call if_changed,ld) | |
| 29 | + | |
| 30 | +CMD_BIN2C = $(objtree)/scripts/basic/bin2c | |
| 31 | +quiet_cmd_bin2c = BIN2C $@ | |
| 32 | + cmd_bin2c = $(CMD_BIN2C) kexec_purgatory < $< > $@ | |
| 33 | + | |
| 34 | +$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE | |
| 35 | + $(call if_changed,bin2c) | |
| 36 | + | |
| 37 | +obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += kexec-purgatory.o | |
| @@ -0,0 +1,279 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* | |
| 3 | + * Purgatory setup code | |
| 4 | + * | |
| 5 | + * Copyright IBM Corp. 2018 | |
| 6 | + * | |
| 7 | + * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/linkage.h> | |
| 11 | +#include <asm/asm-offsets.h> | |
| 12 | +#include <asm/page.h> | |
| 13 | +#include <asm/sigp.h> | |
| 14 | + | |
| 15 | +/* The purgatory is the code running between two kernels. It's main purpose | |
| 16 | + * is to verify that the next kernel was not corrupted after load and to | |
| 17 | + * start it. | |
| 18 | + * | |
| 19 | + * If the next kernel is a crash kernel there are some peculiarities to | |
| 20 | + * consider: | |
| 21 | + * | |
| 22 | + * First the purgatory is called twice. Once only to verify the | |
| 23 | + * sha digest. So if the crash kernel got corrupted the old kernel can try | |
| 24 | + * to trigger a stand-alone dumper. And once to actually load the crash kernel. | |
| 25 | + * | |
| 26 | + * Second the purgatory also has to swap the crash memory region with its | |
| 27 | + * destination at address 0. As the purgatory is part of crash memory this | |
| 28 | + * requires some finesse. The tactic here is that the purgatory first copies | |
| 29 | + * itself to the end of the destination and then swaps the rest of the | |
| 30 | + * memory running from there. | |
| 31 | + */ | |
| 32 | + | |
| 33 | +#define bufsz purgatory_end-stack | |
| 34 | + | |
| 35 | +.macro MEMCPY dst,src,len | |
| 36 | + lgr %r0,\dst | |
| 37 | + lgr %r1,\len | |
| 38 | + lgr %r2,\src | |
| 39 | + lgr %r3,\len | |
| 40 | + | |
| 41 | +20: mvcle %r0,%r2,0 | |
| 42 | + jo 20b | |
| 43 | +.endm | |
| 44 | + | |
| 45 | +.macro MEMSWAP dst,src,buf,len | |
| 46 | +10: cghi \len,bufsz | |
| 47 | + jh 11f | |
| 48 | + lgr %r4,\len | |
| 49 | + j 12f | |
| 50 | +11: lghi %r4,bufsz | |
| 51 | + | |
| 52 | +12: MEMCPY \buf,\dst,%r4 | |
| 53 | + MEMCPY \dst,\src,%r4 | |
| 54 | + MEMCPY \src,\buf,%r4 | |
| 55 | + | |
| 56 | + agr \dst,%r4 | |
| 57 | + agr \src,%r4 | |
| 58 | + sgr \len,%r4 | |
| 59 | + | |
| 60 | + cghi \len,0 | |
| 61 | + jh 10b | |
| 62 | +.endm | |
| 63 | + | |
| 64 | +.macro START_NEXT_KERNEL base | |
| 65 | + lg %r4,kernel_entry-\base(%r13) | |
| 66 | + lg %r5,load_psw_mask-\base(%r13) | |
| 67 | + ogr %r4,%r5 | |
| 68 | + stg %r4,0(%r0) | |
| 69 | + | |
| 70 | + xgr %r0,%r0 | |
| 71 | + diag %r0,%r0,0x308 | |
| 72 | +.endm | |
| 73 | + | |
| 74 | +.text | |
| 75 | +.align PAGE_SIZE | |
| 76 | +ENTRY(purgatory_start) | |
| 77 | + /* The purgatory might be called after a diag308 so better set | |
| 78 | + * architecture and addressing mode. | |
| 79 | + */ | |
| 80 | + lhi %r1,1 | |
| 81 | + sigp %r1,%r0,SIGP_SET_ARCHITECTURE | |
| 82 | + sam64 | |
| 83 | + | |
| 84 | + larl %r5,gprregs | |
| 85 | + stmg %r6,%r15,0(%r5) | |
| 86 | + | |
| 87 | + basr %r13,0 | |
| 88 | +.base_crash: | |
| 89 | + | |
| 90 | + /* Setup stack */ | |
| 91 | + larl %r15,purgatory_end | |
| 92 | + aghi %r15,-160 | |
| 93 | + | |
| 94 | + /* If the next kernel is KEXEC_TYPE_CRASH the purgatory is called | |
| 95 | + * directly with a flag passed in %r2 whether the purgatory shall do | |
| 96 | + * checksum verification only (%r2 = 0 -> verification only). | |
| 97 | + * | |
| 98 | + * Check now and preserve over C function call by storing in | |
| 99 | + * %r10 whith | |
| 100 | + * 1 -> checksum verification only | |
| 101 | + * 0 -> load new kernel | |
| 102 | + */ | |
| 103 | + lghi %r10,0 | |
| 104 | + lg %r11,kernel_type-.base_crash(%r13) | |
| 105 | + cghi %r11,1 /* KEXEC_TYPE_CRASH */ | |
| 106 | + jne .do_checksum_verification | |
| 107 | + cghi %r2,0 /* checksum verification only */ | |
| 108 | + jne .do_checksum_verification | |
| 109 | + lghi %r10,1 | |
| 110 | + | |
| 111 | +.do_checksum_verification: | |
| 112 | + brasl %r14,verify_sha256_digest | |
| 113 | + | |
| 114 | + cghi %r10,1 /* checksum verification only */ | |
| 115 | + je .return_old_kernel | |
| 116 | + cghi %r2,0 /* checksum match */ | |
| 117 | + jne .disabled_wait | |
| 118 | + | |
| 119 | + /* If the next kernel is a crash kernel the purgatory has to swap | |
| 120 | + * the mem regions first. | |
| 121 | + */ | |
| 122 | + cghi %r11,1 /* KEXEC_TYPE_CRASH */ | |
| 123 | + je .start_crash_kernel | |
| 124 | + | |
| 125 | + /* start normal kernel */ | |
| 126 | + START_NEXT_KERNEL .base_crash | |
| 127 | + | |
| 128 | +.return_old_kernel: | |
| 129 | + lmg %r6,%r15,gprregs-.base_crash(%r13) | |
| 130 | + br %r14 | |
| 131 | + | |
| 132 | +.disabled_wait: | |
| 133 | + lpswe disabled_wait_psw-.base_crash(%r13) | |
| 134 | + | |
| 135 | +.start_crash_kernel: | |
| 136 | + /* Location of purgatory_start in crash memory */ | |
| 137 | + lgr %r8,%r13 | |
| 138 | + aghi %r8,-(.base_crash-purgatory_start) | |
| 139 | + | |
| 140 | + /* Destination for this code i.e. end of memory to be swapped. */ | |
| 141 | + lg %r9,crash_size-.base_crash(%r13) | |
| 142 | + aghi %r9,-(purgatory_end-purgatory_start) | |
| 143 | + | |
| 144 | + /* Destination in crash memory, i.e. same as r9 but in crash memory. */ | |
| 145 | + lg %r10,crash_start-.base_crash(%r13) | |
| 146 | + agr %r10,%r9 | |
| 147 | + | |
| 148 | + /* Buffer location (in crash memory) and size. As the purgatory is | |
| 149 | + * behind the point of no return it can re-use the stack as buffer. | |
| 150 | + */ | |
| 151 | + lghi %r11,bufsz | |
| 152 | + larl %r12,stack | |
| 153 | + | |
| 154 | + MEMCPY %r12,%r9,%r11 /* dst -> (crash) buf */ | |
| 155 | + MEMCPY %r9,%r8,%r11 /* self -> dst */ | |
| 156 | + | |
| 157 | + /* Jump to new location. */ | |
| 158 | + lgr %r7,%r9 | |
| 159 | + aghi %r7,.jump_to_dst-purgatory_start | |
| 160 | + br %r7 | |
| 161 | + | |
| 162 | +.jump_to_dst: | |
| 163 | + basr %r13,0 | |
| 164 | +.base_dst: | |
| 165 | + | |
| 166 | + /* clear buffer */ | |
| 167 | + MEMCPY %r12,%r10,%r11 /* (crash) buf -> (crash) dst */ | |
| 168 | + | |
| 169 | + /* Load new buffer location after jump */ | |
| 170 | + larl %r7,stack | |
| 171 | + aghi %r10,stack-purgatory_start | |
| 172 | + MEMCPY %r10,%r7,%r11 /* (new) buf -> (crash) buf */ | |
| 173 | + | |
| 174 | + /* Now the code is set up to run from its designated location. Start | |
| 175 | + * swapping the rest of crash memory now. | |
| 176 | + * | |
| 177 | + * The registers will be used as follow: | |
| 178 | + * | |
| 179 | + * %r0-%r4 reserved for macros defined above | |
| 180 | + * %r5-%r6 tmp registers | |
| 181 | + * %r7 pointer to current struct sha region | |
| 182 | + * %r8 index to iterate over all sha regions | |
| 183 | + * %r9 pointer in crash memory | |
| 184 | + * %r10 pointer in old kernel | |
| 185 | + * %r11 total size (still) to be moved | |
| 186 | + * %r12 pointer to buffer | |
| 187 | + */ | |
| 188 | + lgr %r12,%r7 | |
| 189 | + lgr %r11,%r9 | |
| 190 | + lghi %r10,0 | |
| 191 | + lg %r9,crash_start-.base_dst(%r13) | |
| 192 | + lghi %r8,16 /* KEXEC_SEGMENTS_MAX */ | |
| 193 | + larl %r7,purgatory_sha_regions | |
| 194 | + | |
| 195 | + j .loop_first | |
| 196 | + | |
| 197 | + /* Loop over all purgatory_sha_regions. */ | |
| 198 | +.loop_next: | |
| 199 | + aghi %r8,-1 | |
| 200 | + cghi %r8,0 | |
| 201 | + je .loop_out | |
| 202 | + | |
| 203 | + aghi %r7,__KEXEC_SHA_REGION_SIZE | |
| 204 | + | |
| 205 | +.loop_first: | |
| 206 | + lg %r5,__KEXEC_SHA_REGION_START(%r7) | |
| 207 | + cghi %r5,0 | |
| 208 | + je .loop_next | |
| 209 | + | |
| 210 | + /* Copy [end last sha region, start current sha region) */ | |
| 211 | + /* Note: kexec_sha_region->start points in crash memory */ | |
| 212 | + sgr %r5,%r9 | |
| 213 | + MEMCPY %r9,%r10,%r5 | |
| 214 | + | |
| 215 | + agr %r9,%r5 | |
| 216 | + agr %r10,%r5 | |
| 217 | + sgr %r11,%r5 | |
| 218 | + | |
| 219 | + /* Swap sha region */ | |
| 220 | + lg %r6,__KEXEC_SHA_REGION_LEN(%r7) | |
| 221 | + MEMSWAP %r9,%r10,%r12,%r6 | |
| 222 | + sg %r11,__KEXEC_SHA_REGION_LEN(%r7) | |
| 223 | + j .loop_next | |
| 224 | + | |
| 225 | +.loop_out: | |
| 226 | + /* Copy rest of crash memory */ | |
| 227 | + MEMCPY %r9,%r10,%r11 | |
| 228 | + | |
| 229 | + /* start crash kernel */ | |
| 230 | + START_NEXT_KERNEL .base_dst | |
| 231 | + | |
| 232 | + | |
| 233 | +load_psw_mask: | |
| 234 | + .long 0x00080000,0x80000000 | |
| 235 | + | |
| 236 | + .align 8 | |
| 237 | +disabled_wait_psw: | |
| 238 | + .quad 0x0002000180000000 | |
| 239 | + .quad 0x0000000000000000 + .do_checksum_verification | |
| 240 | + | |
| 241 | +gprregs: | |
| 242 | + .rept 10 | |
| 243 | + .quad 0 | |
| 244 | + .endr | |
| 245 | + | |
| 246 | +purgatory_sha256_digest: | |
| 247 | + .global purgatory_sha256_digest | |
| 248 | + .rept 32 /* SHA256_DIGEST_SIZE */ | |
| 249 | + .byte 0 | |
| 250 | + .endr | |
| 251 | + | |
| 252 | +purgatory_sha_regions: | |
| 253 | + .global purgatory_sha_regions | |
| 254 | + .rept 16 * __KEXEC_SHA_REGION_SIZE /* KEXEC_SEGMENTS_MAX */ | |
| 255 | + .byte 0 | |
| 256 | + .endr | |
| 257 | + | |
| 258 | +kernel_entry: | |
| 259 | + .global kernel_entry | |
| 260 | + .quad 0 | |
| 261 | + | |
| 262 | +kernel_type: | |
| 263 | + .global kernel_type | |
| 264 | + .quad 0 | |
| 265 | + | |
| 266 | +crash_start: | |
| 267 | + .global crash_start | |
| 268 | + .quad 0 | |
| 269 | + | |
| 270 | +crash_size: | |
| 271 | + .global crash_size | |
| 272 | + .quad 0 | |
| 273 | + | |
| 274 | + .align PAGE_SIZE | |
| 275 | +stack: | |
| 276 | + /* The buffer to move this code must be as big as the code. */ | |
| 277 | + .skip stack-purgatory_start | |
| 278 | + .align PAGE_SIZE | |
| 279 | +purgatory_end: | |
| @@ -0,0 +1,42 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Purgatory code running between two kernels. | |
| 4 | + * | |
| 5 | + * Copyright IBM Corp. 2018 | |
| 6 | + * | |
| 7 | + * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | |
| 8 | + */ | |
| 9 | + | |
| 10 | +#include <linux/kexec.h> | |
| 11 | +#include <linux/sha256.h> | |
| 12 | +#include <linux/string.h> | |
| 13 | +#include <asm/purgatory.h> | |
| 14 | + | |
| 15 | +struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX]; | |
| 16 | +u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE]; | |
| 17 | + | |
| 18 | +u64 kernel_entry; | |
| 19 | +u64 kernel_type; | |
| 20 | + | |
| 21 | +u64 crash_start; | |
| 22 | +u64 crash_size; | |
| 23 | + | |
| 24 | +int verify_sha256_digest(void) | |
| 25 | +{ | |
| 26 | + struct kexec_sha_region *ptr, *end; | |
| 27 | + u8 digest[SHA256_DIGEST_SIZE]; | |
| 28 | + struct sha256_state sctx; | |
| 29 | + | |
| 30 | + sha256_init(&sctx); | |
| 31 | + end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions); | |
| 32 | + | |
| 33 | + for (ptr = purgatory_sha_regions; ptr < end; ptr++) | |
| 34 | + sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len); | |
| 35 | + | |
| 36 | + sha256_final(&sctx, digest); | |
| 37 | + | |
| 38 | + if (memcmp(digest, purgatory_sha256_digest, sizeof(digest))) | |
| 39 | + return 1; | |
| 40 | + | |
| 41 | + return 0; | |
| 42 | +} | |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * This program is free software: you can redistribute it and/or modify |
| 5 | 5 | * it under the terms of the GNU General Public License as published by |
| 6 | − * the Free Software Foundation, either version 3 of the License, or | |
| 6 | + * the Free Software Foundation, either version 2 of the License, or | |
| 7 | 7 | * (at your option) any later version. |
| 8 | 8 | * |
| 9 | 9 | * This program is distributed in the hope that it will be useful, |
| @@ -403,7 +403,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, · 402 unmodified lines | ||
| 403 | 403 | if (err) { |
| 404 | 404 | printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", |
| 405 | 405 | dev_name(&vdev->dev), err); |
| 406 | − kfree(vdev); | |
| 406 | + put_device(&vdev->dev); | |
| 407 | 407 | return NULL; |
| 408 | 408 | } |
| 409 | 409 | if (vdev->dp) |
| @@ -52,6 +52,7 @@ config X86 · 51 unmodified lines | ||
| 52 | 52 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
| 53 | 53 | select ARCH_HAS_ELF_RANDOMIZE |
| 54 | 54 | select ARCH_HAS_FAST_MULTIPLIER |
| 55 | + select ARCH_HAS_FILTER_PGPROT | |
| 55 | 56 | select ARCH_HAS_FORTIFY_SOURCE |
| 56 | 57 | select ARCH_HAS_GCOV_PROFILE_ALL |
| 57 | 58 | select ARCH_HAS_KCOV if X86_64 |
| @@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX · 215 unmodified lines | ||
| 273 | 274 | config ARCH_HAS_CACHE_LINE_SIZE |
| 274 | 275 | def_bool y |
| 275 | 276 | |
| 277 | +config ARCH_HAS_FILTER_PGPROT | |
| 278 | + def_bool y | |
| 279 | + | |
| 276 | 280 | config HAVE_SETUP_PER_CPU_AREA |
| 277 | 281 | def_bool y |
| 278 | 282 | |
| @@ -84,13 +84,13 @@ ENTRY(entry_SYSENTER_compat) · 83 unmodified lines | ||
| 84 | 84 | pushq %rdx /* pt_regs->dx */ |
| 85 | 85 | pushq %rcx /* pt_regs->cx */ |
| 86 | 86 | pushq $-ENOSYS /* pt_regs->ax */ |
| 87 | − pushq $0 /* pt_regs->r8 = 0 */ | |
| 87 | + pushq %r8 /* pt_regs->r8 */ | |
| 88 | 88 | xorl %r8d, %r8d /* nospec r8 */ |
| 89 | − pushq $0 /* pt_regs->r9 = 0 */ | |
| 89 | + pushq %r9 /* pt_regs->r9 */ | |
| 90 | 90 | xorl %r9d, %r9d /* nospec r9 */ |
| 91 | − pushq $0 /* pt_regs->r10 = 0 */ | |
| 91 | + pushq %r10 /* pt_regs->r10 */ | |
| 92 | 92 | xorl %r10d, %r10d /* nospec r10 */ |
| 93 | − pushq $0 /* pt_regs->r11 = 0 */ | |
| 93 | + pushq %r11 /* pt_regs->r11 */ | |
| 94 | 94 | xorl %r11d, %r11d /* nospec r11 */ |
| 95 | 95 | pushq %rbx /* pt_regs->rbx */ |
| 96 | 96 | xorl %ebx, %ebx /* nospec rbx */ |
| @@ -3339,7 +3339,8 @@ static void intel_pmu_cpu_starting(int cpu) · 3338 unmodified lines | ||
| 3339 | 3339 | |
| 3340 | 3340 | cpuc->lbr_sel = NULL; |
| 3341 | 3341 | |
| 3342 | − flip_smm_bit(&x86_pmu.attr_freeze_on_smi); | |
| 3342 | + if (x86_pmu.version > 1) | |
| 3343 | + flip_smm_bit(&x86_pmu.attr_freeze_on_smi); | |
| 3343 | 3344 | |
| 3344 | 3345 | if (!cpuc->shared_regs) |
| 3345 | 3346 | return; |
| @@ -3502,6 +3503,8 @@ static __initconst const struct x86_pmu core_pmu = { · 156 unmodified lines | ||
| 3502 | 3503 | .cpu_dying = intel_pmu_cpu_dying, |
| 3503 | 3504 | }; |
| 3504 | 3505 | |
| 3506 | +static struct attribute *intel_pmu_attrs[]; | |
| 3507 | + | |
| 3505 | 3508 | static __initconst const struct x86_pmu intel_pmu = { |
| 3506 | 3509 | .name = "Intel", |
| 3507 | 3510 | .handle_irq = intel_pmu_handle_irq, |
| @@ -3533,6 +3536,8 @@ static __initconst const struct x86_pmu intel_pmu = { · 25 unmodified lines | ||
| 3533 | 3536 | .format_attrs = intel_arch3_formats_attr, |
| 3534 | 3537 | .events_sysfs_show = intel_event_sysfs_show, |
| 3535 | 3538 | |
| 3539 | + .attrs = intel_pmu_attrs, | |
| 3540 | + | |
| 3536 | 3541 | .cpu_prepare = intel_pmu_cpu_prepare, |
| 3537 | 3542 | .cpu_starting = intel_pmu_cpu_starting, |
| 3538 | 3543 | .cpu_dying = intel_pmu_cpu_dying, |
| @@ -3911,8 +3916,6 @@ __init int intel_pmu_init(void) · 372 unmodified lines | ||
| 3911 | 3916 | |
| 3912 | 3917 | x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); |
| 3913 | 3918 | |
| 3914 | − | |
| 3915 | − x86_pmu.attrs = intel_pmu_attrs; | |
| 3916 | 3919 | /* |
| 3917 | 3920 | * Quirk: v2 perfmon does not report fixed-purpose events, so |
| 3918 | 3921 | * assume at least 3 events, when not running in a hypervisor: |
| @@ -3028,10 +3028,27 @@ static struct intel_uncore_type bdx_uncore_cbox = { · 3027 unmodified lines | ||
| 3028 | 3028 | .format_group = &hswep_uncore_cbox_format_group, |
| 3029 | 3029 | }; |
| 3030 | 3030 | |
| 3031 | +static struct intel_uncore_type bdx_uncore_sbox = { | |
| 3032 | + .name = "sbox", | |
| 3033 | + .num_counters = 4, | |
| 3034 | + .num_boxes = 4, | |
| 3035 | + .perf_ctr_bits = 48, | |
| 3036 | + .event_ctl = HSWEP_S0_MSR_PMON_CTL0, | |
| 3037 | + .perf_ctr = HSWEP_S0_MSR_PMON_CTR0, | |
| 3038 | + .event_mask = HSWEP_S_MSR_PMON_RAW_EVENT_MASK, | |
| 3039 | + .box_ctl = HSWEP_S0_MSR_PMON_BOX_CTL, | |
| 3040 | + .msr_offset = HSWEP_SBOX_MSR_OFFSET, | |
| 3041 | + .ops = &hswep_uncore_sbox_msr_ops, | |
| 3042 | + .format_group = &hswep_uncore_sbox_format_group, | |
| 3043 | +}; | |
| 3044 | + | |
| 3045 | +#define BDX_MSR_UNCORE_SBOX 3 | |
| 3046 | + | |
| 3031 | 3047 | static struct intel_uncore_type *bdx_msr_uncores[] = { |
| 3032 | 3048 | &bdx_uncore_ubox, |
| 3033 | 3049 | &bdx_uncore_cbox, |
| 3034 | 3050 | &hswep_uncore_pcu, |
| 3051 | + &bdx_uncore_sbox, | |
| 3035 | 3052 | NULL, |
| 3036 | 3053 | }; |
| 3037 | 3054 | |
| @@ -3043,10 +3060,25 @@ static struct event_constraint bdx_uncore_pcu_constraints[] = { · 5 unmodified lines | ||
| 3043 | 3060 | |
| 3044 | 3061 | void bdx_uncore_cpu_init(void) |
| 3045 | 3062 | { |
| 3063 | + int pkg = topology_phys_to_logical_pkg(0); | |
| 3064 | + | |
| 3046 | 3065 | if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) |
| 3047 | 3066 | bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; |
| 3048 | 3067 | uncore_msr_uncores = bdx_msr_uncores; |
| 3049 | 3068 | |
| 3069 | + /* BDX-DE doesn't have SBOX */ | |
| 3070 | + if (boot_cpu_data.x86_model == 86) { | |
| 3071 | + uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; | |
| 3072 | + /* Detect systems with no SBOXes */ | |
| 3073 | + } else if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) { | |
| 3074 | + struct pci_dev *pdev; | |
| 3075 | + u32 capid4; | |
| 3076 | + | |
| 3077 | + pdev = uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]; | |
| 3078 | + pci_read_config_dword(pdev, 0x94, &capid4); | |
| 3079 | + if (((capid4 >> 6) & 0x3) == 0) | |
| 3080 | + bdx_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; | |
| 3081 | + } | |
| 3050 | 3082 | hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints; |
| 3051 | 3083 | } |
| 3052 | 3084 | |
| @@ -3264,6 +3296,11 @@ static const struct pci_device_id bdx_uncore_pci_ids[] = { · 211 unmodified lines | ||
| 3264 | 3296 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46), |
| 3265 | 3297 | .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 2), |
| 3266 | 3298 | }, |
| 3299 | + { /* PCU.3 (for Capability registers) */ | |
| 3300 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fc0), | |
| 3301 | + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, | |
| 3302 | + HSWEP_PCI_PCU_3), | |
| 3303 | + }, | |
| 3267 | 3304 | { /* end: all zeroes */ } |
| 3268 | 3305 | }; |
| 3269 | 3306 | |
| @@ -136,7 +136,6 @@ · 135 unmodified lines | ||
| 136 | 136 | #endif |
| 137 | 137 | |
| 138 | 138 | #ifndef __ASSEMBLY__ |
| 139 | −#ifndef __BPF__ | |
| 140 | 139 | /* |
| 141 | 140 | * This output constraint should be used for any inline asm which has a "call" |
| 142 | 141 | * instruction. Otherwise the asm may be inserted before the frame pointer |
| @@ -146,6 +145,5 @@ · 3 unmodified lines | ||
| 146 | 145 | register unsigned long current_stack_pointer asm(_ASM_SP); |
| 147 | 146 | #define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) |
| 148 | 147 | #endif |
| 149 | −#endif | |
| 150 | 148 | |
| 151 | 149 | #endif /* _ASM_X86_ASM_H */ |
| @@ -320,6 +320,7 @@ · 319 unmodified lines | ||
| 320 | 320 | #define X86_FEATURE_AVX512_VPOPCNTDQ (16*32+14) /* POPCNT for vectors of DW/QW */ |
| 321 | 321 | #define X86_FEATURE_LA57 (16*32+16) /* 5-level page tables */ |
| 322 | 322 | #define X86_FEATURE_RDPID (16*32+22) /* RDPID instruction */ |
| 323 | +#define X86_FEATURE_CLDEMOTE (16*32+25) /* CLDEMOTE instruction */ | |
| 323 | 324 | |
| 324 | 325 | /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */ |
| 325 | 326 | #define X86_FEATURE_OVERFLOW_RECOV (17*32+ 0) /* MCA overflow recovery support */ |
| @@ -46,7 +46,21 @@ int ftrace_int3_handler(struct pt_regs *regs); · 45 unmodified lines | ||
| 46 | 46 | #endif /* CONFIG_FUNCTION_TRACER */ |
| 47 | 47 | |
| 48 | 48 | |
| 49 | −#if !defined(__ASSEMBLY__) && !defined(COMPILE_OFFSETS) | |
| 49 | +#ifndef __ASSEMBLY__ | |
| 50 | + | |
| 51 | +#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME | |
| 52 | +static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) | |
| 53 | +{ | |
| 54 | + /* | |
| 55 | + * Compare the symbol name with the system call name. Skip the | |
| 56 | + * "__x64_sys", "__ia32_sys" or simple "sys" prefix. | |
| 57 | + */ | |
| 58 | + return !strcmp(sym + 3, name + 3) || | |
| 59 | + (!strncmp(sym, "__x64_", 6) && !strcmp(sym + 9, name + 3)) || | |
| 60 | + (!strncmp(sym, "__ia32_", 7) && !strcmp(sym + 10, name + 3)); | |
| 61 | +} | |
| 62 | + | |
| 63 | +#ifndef COMPILE_OFFSETS | |
| 50 | 64 | |
| 51 | 65 | #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_IA32_EMULATION) |
| 52 | 66 | #include <asm/compat.h> |
| @@ -67,6 +81,7 @@ static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs) · 14 unmodified lines | ||
| 67 | 81 | return false; |
| 68 | 82 | } |
| 69 | 83 | #endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_IA32_EMULATION */ |
| 70 | −#endif /* !__ASSEMBLY__ && !COMPILE_OFFSETS */ | |
| 84 | +#endif /* !COMPILE_OFFSETS */ | |
| 85 | +#endif /* !__ASSEMBLY__ */ | |
| 71 | 86 | |
| 72 | 87 | #endif /* _ASM_X86_FTRACE_H */ |
| @@ -34,11 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | * (0x80 is the syscall vector, 0x30-0x3f are for ISA) |
| 35 | 35 | */ |
| 36 | 36 | #define FIRST_EXTERNAL_VECTOR 0x20 |
| 37 | −/* | |
| 38 | − * We start allocating at 0x21 to spread out vectors evenly between | |
| 39 | − * priority levels. (0x80 is the syscall vector) | |
| 40 | − */ | |
| 41 | −#define VECTOR_OFFSET_START 1 | |
| 42 | 37 | |
| 43 | 38 | /* |
| 44 | 39 | * Reserve the lowest usable vector (and hence lowest priority) 0x20 for |
| @@ -119,8 +114,6 @@ · 74 unmodified lines | ||
| 119 | 114 | #define FIRST_SYSTEM_VECTOR NR_VECTORS |
| 120 | 115 | #endif |
| 121 | 116 | |
| 122 | −#define FPU_IRQ 13 | |
| 123 | − | |
| 124 | 117 | /* |
| 125 | 118 | * Size the maximum number of interrupts. |
| 126 | 119 | * |
| @@ -1,4 +1,4 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL2.0 */ | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | |
| 3 | 3 | /* |
| 4 | 4 | * Jailhouse paravirt detection |
| @@ -1013,6 +1013,7 @@ struct kvm_x86_ops { · 1012 unmodified lines | ||
| 1013 | 1013 | |
| 1014 | 1014 | bool (*has_wbinvd_exit)(void); |
| 1015 | 1015 | |
| 1016 | + u64 (*read_l1_tsc_offset)(struct kvm_vcpu *vcpu); | |
| 1016 | 1017 | void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset); |
| 1017 | 1018 | |
| 1018 | 1019 | void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2); |
| @@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) · 600 unmodified lines | ||
| 601 | 601 | |
| 602 | 602 | #define canon_pgprot(p) __pgprot(massage_pgprot(p)) |
| 603 | 603 | |
| 604 | +static inline pgprot_t arch_filter_pgprot(pgprot_t prot) | |
| 605 | +{ | |
| 606 | + return canon_pgprot(prot); | |
| 607 | +} | |
| 608 | + | |
| 604 | 609 | static inline int is_new_memtype_allowed(u64 paddr, unsigned long size, |
| 605 | 610 | enum page_cache_mode pcm, |
| 606 | 611 | enum page_cache_mode new_pcm) |
| @@ -105,14 +105,14 @@ extern unsigned int ptrs_per_p4d; · 104 unmodified lines | ||
| 105 | 105 | #define LDT_PGD_ENTRY (pgtable_l5_enabled ? LDT_PGD_ENTRY_L5 : LDT_PGD_ENTRY_L4) |
| 106 | 106 | #define LDT_BASE_ADDR (LDT_PGD_ENTRY << PGDIR_SHIFT) |
| 107 | 107 | |
| 108 | −#define __VMALLOC_BASE_L4 0xffffc90000000000 | |
| 109 | −#define __VMALLOC_BASE_L5 0xffa0000000000000 | |
| 108 | +#define __VMALLOC_BASE_L4 0xffffc90000000000UL | |
| 109 | +#define __VMALLOC_BASE_L5 0xffa0000000000000UL | |
| 110 | 110 | |
| 111 | 111 | #define VMALLOC_SIZE_TB_L4 32UL |
| 112 | 112 | #define VMALLOC_SIZE_TB_L5 12800UL |
| 113 | 113 | |
| 114 | −#define __VMEMMAP_BASE_L4 0xffffea0000000000 | |
| 115 | −#define __VMEMMAP_BASE_L5 0xffd4000000000000 | |
| 114 | +#define __VMEMMAP_BASE_L4 0xffffea0000000000UL | |
| 115 | +#define __VMEMMAP_BASE_L5 0xffd4000000000000UL | |
| 116 | 116 | |
| 117 | 117 | #ifdef CONFIG_DYNAMIC_MEMORY_LAYOUT |
| 118 | 118 | # define VMALLOC_START vmalloc_base |
| @@ -749,13 +749,11 @@ enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT, · 748 unmodified lines | ||
| 749 | 749 | extern void enable_sep_cpu(void); |
| 750 | 750 | extern int sysenter_setup(void); |
| 751 | 751 | |
| 752 | −extern void early_trap_init(void); | |
| 753 | 752 | void early_trap_pf_init(void); |
| 754 | 753 | |
| 755 | 754 | /* Defined in head.S */ |
| 756 | 755 | extern struct desc_ptr early_gdt_descr; |
| 757 | 756 | |
| 758 | −extern void cpu_set_gdt(int); | |
| 759 | 757 | extern void switch_to_new_gdt(int); |
| 760 | 758 | extern void load_direct_gdt(int); |
| 761 | 759 | extern void load_fixmap_gdt(int); |
| @@ -1 +1,32 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | |
| 2 | +#ifndef __ASM_X64_MSGBUF_H | |
| 3 | +#define __ASM_X64_MSGBUF_H | |
| 4 | + | |
| 5 | +#if !defined(__x86_64__) || !defined(__ILP32__) | |
| 1 | 6 | #include <asm-generic/msgbuf.h> |
| 7 | +#else | |
| 8 | +/* | |
| 9 | + * The msqid64_ds structure for x86 architecture with x32 ABI. | |
| 10 | + * | |
| 11 | + * On x86-32 and x86-64 we can just use the generic definition, but | |
| 12 | + * x32 uses the same binary layout as x86_64, which is differnet | |
| 13 | + * from other 32-bit architectures. | |
| 14 | + */ | |
| 15 | + | |
| 16 | +struct msqid64_ds { | |
| 17 | + struct ipc64_perm msg_perm; | |
| 18 | + __kernel_time_t msg_stime; /* last msgsnd time */ | |
| 19 | + __kernel_time_t msg_rtime; /* last msgrcv time */ | |
| 20 | + __kernel_time_t msg_ctime; /* last change time */ | |
| 21 | + __kernel_ulong_t msg_cbytes; /* current number of bytes on queue */ | |
| 22 | + __kernel_ulong_t msg_qnum; /* number of messages in queue */ | |
| 23 | + __kernel_ulong_t msg_qbytes; /* max number of bytes on queue */ | |
| 24 | + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ | |
| 25 | + __kernel_pid_t msg_lrpid; /* last receive pid */ | |
| 26 | + __kernel_ulong_t __unused4; | |
| 27 | + __kernel_ulong_t __unused5; | |
| 28 | +}; | |
| 29 | + | |
| 30 | +#endif | |
| 31 | + | |
| 32 | +#endif /* __ASM_GENERIC_MSGBUF_H */ | |
| @@ -1 +1,43 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | |
| 2 | +#ifndef __ASM_X86_SHMBUF_H | |
| 3 | +#define __ASM_X86_SHMBUF_H | |
| 4 | + | |
| 5 | +#if !defined(__x86_64__) || !defined(__ILP32__) | |
| 1 | 6 | #include <asm-generic/shmbuf.h> |
| 7 | +#else | |
| 8 | +/* | |
| 9 | + * The shmid64_ds structure for x86 architecture with x32 ABI. | |
| 10 | + * | |
| 11 | + * On x86-32 and x86-64 we can just use the generic definition, but | |
| 12 | + * x32 uses the same binary layout as x86_64, which is differnet | |
| 13 | + * from other 32-bit architectures. | |
| 14 | + */ | |
| 15 | + | |
| 16 | +struct shmid64_ds { | |
| 17 | + struct ipc64_perm shm_perm; /* operation perms */ | |
| 18 | + size_t shm_segsz; /* size of segment (bytes) */ | |
| 19 | + __kernel_time_t shm_atime; /* last attach time */ | |
| 20 | + __kernel_time_t shm_dtime; /* last detach time */ | |
| 21 | + __kernel_time_t shm_ctime; /* last change time */ | |
| 22 | + __kernel_pid_t shm_cpid; /* pid of creator */ | |
| 23 | + __kernel_pid_t shm_lpid; /* pid of last operator */ | |
| 24 | + __kernel_ulong_t shm_nattch; /* no. of current attaches */ | |
| 25 | + __kernel_ulong_t __unused4; | |
| 26 | + __kernel_ulong_t __unused5; | |
| 27 | +}; | |
| 28 | + | |
| 29 | +struct shminfo64 { | |
| 30 | + __kernel_ulong_t shmmax; | |
| 31 | + __kernel_ulong_t shmmin; | |
| 32 | + __kernel_ulong_t shmmni; | |
| 33 | + __kernel_ulong_t shmseg; | |
| 34 | + __kernel_ulong_t shmall; | |
| 35 | + __kernel_ulong_t __unused1; | |
| 36 | + __kernel_ulong_t __unused2; | |
| 37 | + __kernel_ulong_t __unused3; | |
| 38 | + __kernel_ulong_t __unused4; | |
| 39 | +}; | |
| 40 | + | |
| 41 | +#endif | |
| 42 | + | |
| 43 | +#endif /* __ASM_X86_SHMBUF_H */ | |
| @@ -215,6 +215,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) · 214 unmodified lines | ||
| 215 | 215 | apic_id = processor->local_apic_id; |
| 216 | 216 | enabled = processor->lapic_flags & ACPI_MADT_ENABLED; |
| 217 | 217 | |
| 218 | + /* Ignore invalid ID */ | |
| 219 | + if (apic_id == 0xffffffff) | |
| 220 | + return 0; | |
| 221 | + | |
| 218 | 222 | /* |
| 219 | 223 | * We need to register disabled CPU as well to permit |
| 220 | 224 | * counting disabled CPUs. This allows us to size |
| @@ -848,6 +848,11 @@ void get_cpu_cap(struct cpuinfo_x86 *c) · 847 unmodified lines | ||
| 848 | 848 | c->x86_power = edx; |
| 849 | 849 | } |
| 850 | 850 | |
| 851 | + if (c->extended_cpuid_level >= 0x80000008) { | |
| 852 | + cpuid(0x80000008, &eax, &ebx, &ecx, &edx); | |
| 853 | + c->x86_capability[CPUID_8000_0008_EBX] = ebx; | |
| 854 | + } | |
| 855 | + | |
| 851 | 856 | if (c->extended_cpuid_level >= 0x8000000a) |
| 852 | 857 | c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a); |
| 853 | 858 | |
| @@ -871,7 +876,6 @@ static void get_cpu_address_sizes(struct cpuinfo_x86 *c) · 17 unmodified lines | ||
| 871 | 876 | |
| 872 | 877 | c->x86_virt_bits = (eax >> 8) & 0xff; |
| 873 | 878 | c->x86_phys_bits = eax & 0xff; |
| 874 | − c->x86_capability[CPUID_8000_0008_EBX] = ebx; | |
| 875 | 879 | } |
| 876 | 880 | #ifdef CONFIG_X86_32 |
| 877 | 881 | else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36)) |
| @@ -835,6 +835,9 @@ static const struct _tlb_table intel_tlb_table[] = { · 834 unmodified lines | ||
| 835 | 835 | { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, |
| 836 | 836 | { 0x61, TLB_INST_4K, 48, " TLB_INST 4 KByte pages, full associative" }, |
| 837 | 837 | { 0x63, TLB_DATA_1G, 4, " TLB_DATA 1 GByte pages, 4-way set associative" }, |
| 838 | + { 0x6b, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 8-way associative" }, | |
| 839 | + { 0x6c, TLB_DATA_2M_4M, 128, " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" }, | |
| 840 | + { 0x6d, TLB_DATA_1G, 16, " TLB_DATA 1 GByte pages, fully associative" }, | |
| 838 | 841 | { 0x76, TLB_INST_2M_4M, 8, " TLB_INST 2-MByte or 4-MByte pages, fully associative" }, |
| 839 | 842 | { 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" }, |
| 840 | 843 | { 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" }, |
| @@ -564,14 +564,12 @@ static int __reload_late(void *info) · 563 unmodified lines | ||
| 564 | 564 | apply_microcode_local(&err); |
| 565 | 565 | spin_unlock(&update_lock); |
| 566 | 566 | |
| 567 | + /* siblings return UCODE_OK because their engine got updated already */ | |
| 567 | 568 | if (err > UCODE_NFOUND) { |
| 568 | 569 | pr_warn("Error reloading microcode on CPU %d\n", cpu); |
| 569 | − return -1; | |
| 570 | − /* siblings return UCODE_OK because their engine got updated already */ | |
| 570 | + ret = -1; | |
| 571 | 571 | } else if (err == UCODE_UPDATED || err == UCODE_OK) { |
| 572 | 572 | ret = 1; |
| 573 | − } else { | |
| 574 | − return ret; | |
| 575 | 573 | } |
| 576 | 574 | |
| 577 | 575 | /* |
| @@ -485,7 +485,6 @@ static void show_saved_mc(void) · 484 unmodified lines | ||
| 485 | 485 | */ |
| 486 | 486 | static void save_mc_for_early(u8 *mc, unsigned int size) |
| 487 | 487 | { |
| 488 | −#ifdef CONFIG_HOTPLUG_CPU | |
| 489 | 488 | /* Synchronization during CPU hotplug. */ |
| 490 | 489 | static DEFINE_MUTEX(x86_cpu_microcode_mutex); |
| 491 | 490 | |
| @@ -495,7 +494,6 @@ static void save_mc_for_early(u8 *mc, unsigned int size) · 3 unmodified lines | ||
| 495 | 494 | show_saved_mc(); |
| 496 | 495 | |
| 497 | 496 | mutex_unlock(&x86_cpu_microcode_mutex); |
| 498 | −#endif | |
| 499 | 497 | } |
| 500 | 498 | |
| 501 | 499 | static bool load_builtin_intel_microcode(struct cpio_data *cp) |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL2.0 | |
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | 2 | /* |
| 3 | 3 | * Jailhouse paravirt_ops implementation |
| 4 | 4 | * |
| @@ -398,11 +398,10 @@ static void *bzImage64_load(struct kimage *image, char *kernel, · 397 unmodified lines | ||
| 398 | 398 | * little bit simple |
| 399 | 399 | */ |
| 400 | 400 | efi_map_sz = efi_get_runtime_map_size(); |
| 401 | − efi_map_sz = ALIGN(efi_map_sz, 16); | |
| 402 | 401 | params_cmdline_sz = sizeof(struct boot_params) + cmdline_len + |
| 403 | 402 | MAX_ELFCOREHDR_STR_LEN; |
| 404 | 403 | params_cmdline_sz = ALIGN(params_cmdline_sz, 16); |
| 405 | − kbuf.bufsz = params_cmdline_sz + efi_map_sz + | |
| 404 | + kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) + | |
| 406 | 405 | sizeof(struct setup_data) + |
| 407 | 406 | sizeof(struct efi_setup_data); |
| 408 | 407 | |
| @@ -410,7 +409,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel, · 1 unmodified line | ||
| 410 | 409 | if (!params) |
| 411 | 410 | return ERR_PTR(-ENOMEM); |
| 412 | 411 | efi_map_offset = params_cmdline_sz; |
| 413 | − efi_setup_data_offset = efi_map_offset + efi_map_sz; | |
| 412 | + efi_setup_data_offset = efi_map_offset + ALIGN(efi_map_sz, 16); | |
| 414 | 413 | |
| 415 | 414 | /* Copy setup header onto bootparams. Documentation/x86/boot.txt */ |
| 416 | 415 | setup_header_size = 0x0202 + kernel[0x0201] - setup_hdr_offset; |
| @@ -166,7 +166,7 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot) · 165 unmodified lines | ||
| 166 | 166 | */ |
| 167 | 167 | pte_prot = __pgprot(__PAGE_KERNEL_RO & ~_PAGE_GLOBAL); |
| 168 | 168 | /* Filter out unsuppored __PAGE_KERNEL* bits: */ |
| 169 | − pgprot_val(pte_prot) |= __supported_pte_mask; | |
| 169 | + pgprot_val(pte_prot) &= __supported_pte_mask; | |
| 170 | 170 | pte = pfn_pte(pfn, pte_prot); |
| 171 | 171 | set_pte_at(mm, va, ptep, pte); |
| 172 | 172 | pte_unmap_unlock(ptep, ptl); |
| @@ -1,90 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 2 | −/* Fallback functions when the main IOMMU code is not compiled in. This | |
| 3 | − code is roughly equivalent to i386. */ | |
| 4 | −#include <linux/dma-direct.h> | |
| 5 | −#include <linux/scatterlist.h> | |
| 6 | −#include <linux/string.h> | |
| 7 | −#include <linux/gfp.h> | |
| 8 | −#include <linux/pci.h> | |
| 9 | −#include <linux/mm.h> | |
| 10 | − | |
| 11 | −#include <asm/processor.h> | |
| 12 | −#include <asm/iommu.h> | |
| 13 | −#include <asm/dma.h> | |
| 14 | − | |
| 15 | −#define NOMMU_MAPPING_ERROR 0 | |
| 16 | − | |
| 17 | −static int | |
| 18 | −check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) | |
| 19 | −{ | |
| 20 | − if (hwdev && !dma_capable(hwdev, bus, size)) { | |
| 21 | − if (*hwdev->dma_mask >= DMA_BIT_MASK(32)) | |
| 22 | − printk(KERN_ERR | |
| 23 | − "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", | |
| 24 | − name, (long long)bus, size, | |
| 25 | − (long long)*hwdev->dma_mask); | |
| 26 | − return 0; | |
| 27 | − } | |
| 28 | − return 1; | |
| 29 | −} | |
| 30 | − | |
| 31 | −static dma_addr_t nommu_map_page(struct device *dev, struct page *page, | |
| 32 | − unsigned long offset, size_t size, | |
| 33 | − enum dma_data_direction dir, | |
| 34 | − unsigned long attrs) | |
| 35 | −{ | |
| 36 | − dma_addr_t bus = phys_to_dma(dev, page_to_phys(page)) + offset; | |
| 37 | − WARN_ON(size == 0); | |
| 38 | − if (!check_addr("map_single", dev, bus, size)) | |
| 39 | − return NOMMU_MAPPING_ERROR; | |
| 40 | − return bus; | |
| 41 | −} | |
| 42 | − | |
| 43 | −/* Map a set of buffers described by scatterlist in streaming | |
| 44 | − * mode for DMA. This is the scatter-gather version of the | |
| 45 | − * above pci_map_single interface. Here the scatter gather list | |
| 46 | − * elements are each tagged with the appropriate dma address | |
| 47 | − * and length. They are obtained via sg_dma_{address,length}(SG). | |
| 48 | − * | |
| 49 | − * NOTE: An implementation may be able to use a smaller number of | |
| 50 | − * DMA address/length pairs than there are SG table elements. | |
| 51 | − * (for example via virtual mapping capabilities) | |
| 52 | − * The routine returns the number of addr/length pairs actually | |
| 53 | − * used, at most nents. | |
| 54 | − * | |
| 55 | − * Device ownership issues as mentioned above for pci_map_single are | |
| 56 | − * the same here. | |
| 57 | − */ | |
| 58 | −static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, | |
| 59 | − int nents, enum dma_data_direction dir, | |
| 60 | − unsigned long attrs) | |
| 61 | −{ | |
| 62 | − struct scatterlist *s; | |
| 63 | − int i; | |
| 64 | − | |
| 65 | − WARN_ON(nents == 0 || sg[0].length == 0); | |
| 66 | − | |
| 67 | − for_each_sg(sg, s, nents, i) { | |
| 68 | − BUG_ON(!sg_page(s)); | |
| 69 | − s->dma_address = sg_phys(s); | |
| 70 | − if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) | |
| 71 | − return 0; | |
| 72 | − s->dma_length = s->length; | |
| 73 | − } | |
| 74 | − return nents; | |
| 75 | −} | |
| 76 | − | |
| 77 | −static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr) | |
| 78 | −{ | |
| 79 | − return dma_addr == NOMMU_MAPPING_ERROR; | |
| 80 | −} | |
| 81 | − | |
| 82 | −const struct dma_map_ops nommu_dma_ops = { | |
| 83 | − .alloc = dma_generic_alloc_coherent, | |
| 84 | − .free = dma_generic_free_coherent, | |
| 85 | − .map_sg = nommu_map_sg, | |
| 86 | − .map_page = nommu_map_page, | |
| 87 | − .is_phys = 1, | |
| 88 | − .mapping_error = nommu_mapping_error, | |
| 89 | − .dma_supported = x86_dma_supported, | |
| 90 | −}; | |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | #include <linux/init_ohci1394_dma.h> |
| 51 | 51 | #include <linux/kvm_para.h> |
| 52 | 52 | #include <linux/dma-contiguous.h> |
| 53 | +#include <xen/xen.h> | |
| 53 | 54 | |
| 54 | 55 | #include <linux/errno.h> |
| 55 | 56 | #include <linux/kernel.h> |
| @@ -534,6 +535,11 @@ static void __init reserve_crashkernel(void) · 478 unmodified lines | ||
| 534 | 535 | high = true; |
| 535 | 536 | } |
| 536 | 537 | |
| 538 | + if (xen_pv_domain()) { | |
| 539 | + pr_info("Ignoring crashkernel for a Xen PV domain\n"); | |
| 540 | + return; | |
| 541 | + } | |
| 542 | + | |
| 537 | 543 | /* 0 means: find the address automatically */ |
| 538 | 544 | if (crash_base <= 0) { |
| 539 | 545 | /* |
| @@ -77,6 +77,8 @@ · 76 unmodified lines | ||
| 77 | 77 | #include <asm/i8259.h> |
| 78 | 78 | #include <asm/misc.h> |
| 79 | 79 | #include <asm/qspinlock.h> |
| 80 | +#include <asm/intel-family.h> | |
| 81 | +#include <asm/cpu_device_id.h> | |
| 80 | 82 | |
| 81 | 83 | /* Number of siblings per CPU package */ |
| 82 | 84 | int smp_num_siblings = 1; |
| @@ -390,15 +392,47 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) · 307 unmodified lines | ||
| 390 | 392 | return false; |
| 391 | 393 | } |
| 392 | 394 | |
| 395 | +/* | |
| 396 | + * Define snc_cpu[] for SNC (Sub-NUMA Cluster) CPUs. | |
| 397 | + * | |
| 398 | + * These are Intel CPUs that enumerate an LLC that is shared by | |
| 399 | + * multiple NUMA nodes. The LLC on these systems is shared for | |
| 400 | + * off-package data access but private to the NUMA node (half | |
| 401 | + * of the package) for on-package access. | |
| 402 | + * | |
| 403 | + * CPUID (the source of the information about the LLC) can only | |
| 404 | + * enumerate the cache as being shared *or* unshared, but not | |
| 405 | + * this particular configuration. The CPU in this case enumerates | |
| 406 | + * the cache to be shared across the entire package (spanning both | |
| 407 | + * NUMA nodes). | |
| 408 | + */ | |
| 409 | + | |
| 410 | +static const struct x86_cpu_id snc_cpu[] = { | |
| 411 | + { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X }, | |
| 412 | + {} | |
| 413 | +}; | |
| 414 | + | |
| 393 | 415 | static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) |
| 394 | 416 | { |
| 395 | 417 | int cpu1 = c->cpu_index, cpu2 = o->cpu_index; |
| 396 | 418 | |
| 397 | − if (per_cpu(cpu_llc_id, cpu1) != BAD_APICID && | |
| 398 | − per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2)) | |
| 399 | − return topology_sane(c, o, "llc"); | |
| 419 | + /* Do not match if we do not have a valid APICID for cpu: */ | |
| 420 | + if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID) | |
| 421 | + return false; | |
| 400 | 422 | |
| 401 | − return false; | |
| 423 | + /* Do not match if LLC id does not match: */ | |
| 424 | + if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2)) | |
| 425 | + return false; | |
| 426 | + | |
| 427 | + /* | |
| 428 | + * Allow the SNC topology without warning. Return of false | |
| 429 | + * means 'c' does not share the LLC of 'o'. This will be | |
| 430 | + * reflected to userspace. | |
| 431 | + */ | |
| 432 | + if (!topology_same_node(c, o) && x86_match_cpu(snc_cpu)) | |
| 433 | + return false; | |
| 434 | + | |
| 435 | + return topology_sane(c, o, "llc"); | |
| 402 | 436 | } |
| 403 | 437 | |
| 404 | 438 | /* |
| @@ -456,7 +490,8 @@ static struct sched_domain_topology_level x86_topology[] = { · 51 unmodified lines | ||
| 456 | 490 | |
| 457 | 491 | /* |
| 458 | 492 | * Set if a package/die has multiple NUMA nodes inside. |
| 459 | − * AMD Magny-Cours and Intel Cluster-on-Die have this. | |
| 493 | + * AMD Magny-Cours, Intel Cluster-on-Die, and Intel | |
| 494 | + * Sub-NUMA Clustering have this. | |
| 460 | 495 | */ |
| 461 | 496 | static bool x86_has_numa_in_package; |
| 462 | 497 | |
| @@ -1536,6 +1571,8 @@ static inline void mwait_play_dead(void) · 1073 unmodified lines | ||
| 1536 | 1571 | void *mwait_ptr; |
| 1537 | 1572 | int i; |
| 1538 | 1573 | |
| 1574 | + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) | |
| 1575 | + return; | |
| 1539 | 1576 | if (!this_cpu_has(X86_FEATURE_MWAIT)) |
| 1540 | 1577 | return; |
| 1541 | 1578 | if (!this_cpu_has(X86_FEATURE_CLFLUSH)) |
| @@ -317,7 +317,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) · 316 unmodified lines | ||
| 317 | 317 | hpet2 -= hpet1; |
| 318 | 318 | tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); |
| 319 | 319 | do_div(tmp, 1000000); |
| 320 | − do_div(deltatsc, tmp); | |
| 320 | + deltatsc = div64_u64(deltatsc, tmp); | |
| 321 | 321 | |
| 322 | 322 | return (unsigned long) deltatsc; |
| 323 | 323 | } |
| @@ -1067,6 +1067,7 @@ static struct clocksource clocksource_tsc_early = { · 743 unmodified lines | ||
| 1067 | 1067 | .resume = tsc_resume, |
| 1068 | 1068 | .mark_unstable = tsc_cs_mark_unstable, |
| 1069 | 1069 | .tick_stable = tsc_cs_tick_stable, |
| 1070 | + .list = LIST_HEAD_INIT(clocksource_tsc_early.list), | |
| 1070 | 1071 | }; |
| 1071 | 1072 | |
| 1072 | 1073 | /* |
| @@ -1086,6 +1087,7 @@ static struct clocksource clocksource_tsc = { · 13 unmodified lines | ||
| 1086 | 1087 | .resume = tsc_resume, |
| 1087 | 1088 | .mark_unstable = tsc_cs_mark_unstable, |
| 1088 | 1089 | .tick_stable = tsc_cs_tick_stable, |
| 1090 | + .list = LIST_HEAD_INIT(clocksource_tsc.list), | |
| 1089 | 1091 | }; |
| 1090 | 1092 | |
| 1091 | 1093 | void mark_tsc_unstable(char *reason) |
| @@ -1098,13 +1100,9 @@ void mark_tsc_unstable(char *reason) · 6 unmodified lines | ||
| 1098 | 1100 | clear_sched_clock_stable(); |
| 1099 | 1101 | disable_sched_clock_irqtime(); |
| 1100 | 1102 | pr_info("Marking TSC unstable due to %s\n", reason); |
| 1101 | − /* Change only the rating, when not registered */ | |
| 1102 | − if (clocksource_tsc.mult) { | |
| 1103 | − clocksource_mark_unstable(&clocksource_tsc); | |
| 1104 | − } else { | |
| 1105 | − clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE; | |
| 1106 | − clocksource_tsc.rating = 0; | |
| 1107 | − } | |
| 1103 | + | |
| 1104 | + clocksource_mark_unstable(&clocksource_tsc_early); | |
| 1105 | + clocksource_mark_unstable(&clocksource_tsc); | |
| 1108 | 1106 | } |
| 1109 | 1107 | |
| 1110 | 1108 | EXPORT_SYMBOL_GPL(mark_tsc_unstable); |
| @@ -1244,7 +1242,7 @@ static void tsc_refine_calibration_work(struct work_struct *work) · 133 unmodified lines | ||
| 1244 | 1242 | |
| 1245 | 1243 | /* Don't bother refining TSC on unstable systems */ |
| 1246 | 1244 | if (tsc_unstable) |
| 1247 | − return; | |
| 1245 | + goto unreg; | |
| 1248 | 1246 | |
| 1249 | 1247 | /* |
| 1250 | 1248 | * Since the work is started early in boot, we may be |
| @@ -1297,11 +1295,12 @@ static void tsc_refine_calibration_work(struct work_struct *work) · 46 unmodified lines | ||
| 1297 | 1295 | |
| 1298 | 1296 | out: |
| 1299 | 1297 | if (tsc_unstable) |
| 1300 | − return; | |
| 1298 | + goto unreg; | |
| 1301 | 1299 | |
| 1302 | 1300 | if (boot_cpu_has(X86_FEATURE_ART)) |
| 1303 | 1301 | art_related_clocksource = &clocksource_tsc; |
| 1304 | 1302 | clocksource_register_khz(&clocksource_tsc, tsc_khz); |
| 1303 | +unreg: | |
| 1305 | 1304 | clocksource_unregister(&clocksource_tsc_early); |
| 1306 | 1305 | } |
| 1307 | 1306 | |
| @@ -1311,8 +1310,8 @@ static int __init init_tsc_clocksource(void) · 3 unmodified lines | ||
| 1311 | 1310 | if (!boot_cpu_has(X86_FEATURE_TSC) || tsc_disabled > 0 || !tsc_khz) |
| 1312 | 1311 | return 0; |
| 1313 | 1312 | |
| 1314 | − if (check_tsc_unstable()) | |
| 1315 | − return 0; | |
| 1313 | + if (tsc_unstable) | |
| 1314 | + goto unreg; | |
| 1316 | 1315 | |
| 1317 | 1316 | if (tsc_clocksource_reliable) |
| 1318 | 1317 | clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; |
| @@ -1328,6 +1327,7 @@ static int __init init_tsc_clocksource(void) · 9 unmodified lines | ||
| 1328 | 1327 | if (boot_cpu_has(X86_FEATURE_ART)) |
| 1329 | 1328 | art_related_clocksource = &clocksource_tsc; |
| 1330 | 1329 | clocksource_register_khz(&clocksource_tsc, tsc_khz); |
| 1330 | +unreg: | |
| 1331 | 1331 | clocksource_unregister(&clocksource_tsc_early); |
| 1332 | 1332 | return 0; |
| 1333 | 1333 | } |
| @@ -1463,23 +1463,6 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic) · 1462 unmodified lines | ||
| 1463 | 1463 | local_irq_restore(flags); |
| 1464 | 1464 | } |
| 1465 | 1465 | |
| 1466 | −static void start_sw_period(struct kvm_lapic *apic) | |
| 1467 | −{ | |
| 1468 | − if (!apic->lapic_timer.period) | |
| 1469 | − return; | |
| 1470 | − | |
| 1471 | − if (apic_lvtt_oneshot(apic) && | |
| 1472 | − ktime_after(ktime_get(), | |
| 1473 | − apic->lapic_timer.target_expiration)) { | |
| 1474 | − apic_timer_expired(apic); | |
| 1475 | − return; | |
| 1476 | − } | |
| 1477 | − | |
| 1478 | − hrtimer_start(&apic->lapic_timer.timer, | |
| 1479 | − apic->lapic_timer.target_expiration, | |
| 1480 | − HRTIMER_MODE_ABS_PINNED); | |
| 1481 | −} | |
| 1482 | − | |
| 1483 | 1466 | static void update_target_expiration(struct kvm_lapic *apic, uint32_t old_divisor) |
| 1484 | 1467 | { |
| 1485 | 1468 | ktime_t now, remaining; |
| @@ -1546,6 +1529,26 @@ static void advance_periodic_target_expiration(struct kvm_lapic *apic) · 60 unmodified lines | ||
| 1546 | 1529 | apic->lapic_timer.period); |
| 1547 | 1530 | } |
| 1548 | 1531 | |
| 1532 | +static void start_sw_period(struct kvm_lapic *apic) | |
| 1533 | +{ | |
| 1534 | + if (!apic->lapic_timer.period) | |
| 1535 | + return; | |
| 1536 | + | |
| 1537 | + if (ktime_after(ktime_get(), | |
| 1538 | + apic->lapic_timer.target_expiration)) { | |
| 1539 | + apic_timer_expired(apic); | |
| 1540 | + | |
| 1541 | + if (apic_lvtt_oneshot(apic)) | |
| 1542 | + return; | |
| 1543 | + | |
| 1544 | + advance_periodic_target_expiration(apic); | |
| 1545 | + } | |
| 1546 | + | |
| 1547 | + hrtimer_start(&apic->lapic_timer.timer, | |
| 1548 | + apic->lapic_timer.target_expiration, | |
| 1549 | + HRTIMER_MODE_ABS_PINNED); | |
| 1550 | +} | |
| 1551 | + | |
| 1549 | 1552 | bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu) |
| 1550 | 1553 | { |
| 1551 | 1554 | if (!lapic_in_kernel(vcpu)) |
| @@ -1423,12 +1423,23 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type) · 1422 unmodified lines | ||
| 1423 | 1423 | seg->base = 0; |
| 1424 | 1424 | } |
| 1425 | 1425 | |
| 1426 | +static u64 svm_read_l1_tsc_offset(struct kvm_vcpu *vcpu) | |
| 1427 | +{ | |
| 1428 | + struct vcpu_svm *svm = to_svm(vcpu); | |
| 1429 | + | |
| 1430 | + if (is_guest_mode(vcpu)) | |
| 1431 | + return svm->nested.hsave->control.tsc_offset; | |
| 1432 | + | |
| 1433 | + return vcpu->arch.tsc_offset; | |
| 1434 | +} | |
| 1435 | + | |
| 1426 | 1436 | static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) |
| 1427 | 1437 | { |
| 1428 | 1438 | struct vcpu_svm *svm = to_svm(vcpu); |
| 1429 | 1439 | u64 g_tsc_offset = 0; |
| 1430 | 1440 | |
| 1431 | 1441 | if (is_guest_mode(vcpu)) { |
| 1442 | + /* Write L1's TSC offset. */ | |
| 1432 | 1443 | g_tsc_offset = svm->vmcb->control.tsc_offset - |
| 1433 | 1444 | svm->nested.hsave->control.tsc_offset; |
| 1434 | 1445 | svm->nested.hsave->control.tsc_offset = offset; |
| @@ -3322,6 +3333,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) · 1887 unmodified lines | ||
| 3322 | 3333 | /* Restore the original control entries */ |
| 3323 | 3334 | copy_vmcb_control_area(vmcb, hsave); |
| 3324 | 3335 | |
| 3336 | + svm->vcpu.arch.tsc_offset = svm->vmcb->control.tsc_offset; | |
| 3325 | 3337 | kvm_clear_exception_queue(&svm->vcpu); |
| 3326 | 3338 | kvm_clear_interrupt_queue(&svm->vcpu); |
| 3327 | 3339 | |
| @@ -3482,10 +3494,12 @@ static void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa, · 154 unmodified lines | ||
| 3482 | 3494 | /* We don't want to see VMMCALLs from a nested guest */ |
| 3483 | 3495 | clr_intercept(svm, INTERCEPT_VMMCALL); |
| 3484 | 3496 | |
| 3497 | + svm->vcpu.arch.tsc_offset += nested_vmcb->control.tsc_offset; | |
| 3498 | + svm->vmcb->control.tsc_offset = svm->vcpu.arch.tsc_offset; | |
| 3499 | + | |
| 3485 | 3500 | svm->vmcb->control.virt_ext = nested_vmcb->control.virt_ext; |
| 3486 | 3501 | svm->vmcb->control.int_vector = nested_vmcb->control.int_vector; |
| 3487 | 3502 | svm->vmcb->control.int_state = nested_vmcb->control.int_state; |
| 3488 | − svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset; | |
| 3489 | 3503 | svm->vmcb->control.event_inj = nested_vmcb->control.event_inj; |
| 3490 | 3504 | svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err; |
| 3491 | 3505 | |
| @@ -4035,12 +4049,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 543 unmodified lines | ||
| 4035 | 4049 | struct vcpu_svm *svm = to_svm(vcpu); |
| 4036 | 4050 | |
| 4037 | 4051 | switch (msr_info->index) { |
| 4038 | − case MSR_IA32_TSC: { | |
| 4039 | − msr_info->data = svm->vmcb->control.tsc_offset + | |
| 4040 | − kvm_scale_tsc(vcpu, rdtsc()); | |
| 4041 | − | |
| 4042 | − break; | |
| 4043 | − } | |
| 4044 | 4052 | case MSR_STAR: |
| 4045 | 4053 | msr_info->data = svm->vmcb->save.star; |
| 4046 | 4054 | break; |
| @@ -4193,9 +4201,6 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) · 146 unmodified lines | ||
| 4193 | 4201 | svm->vmcb->save.g_pat = data; |
| 4194 | 4202 | mark_dirty(svm->vmcb, VMCB_NPT); |
| 4195 | 4203 | break; |
| 4196 | − case MSR_IA32_TSC: | |
| 4197 | − kvm_write_tsc(vcpu, msr); | |
| 4198 | − break; | |
| 4199 | 4204 | case MSR_IA32_SPEC_CTRL: |
| 4200 | 4205 | if (!msr->host_initiated && |
| 4201 | 4206 | !guest_cpuid_has(vcpu, X86_FEATURE_IBRS)) |
| @@ -5265,9 +5270,8 @@ static int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq, · 1063 unmodified lines | ||
| 5265 | 5270 | } |
| 5266 | 5271 | |
| 5267 | 5272 | if (!ret && svm) { |
| 5268 | − trace_kvm_pi_irte_update(svm->vcpu.vcpu_id, | |
| 5269 | − host_irq, e->gsi, | |
| 5270 | − vcpu_info.vector, | |
| 5273 | + trace_kvm_pi_irte_update(host_irq, svm->vcpu.vcpu_id, | |
| 5274 | + e->gsi, vcpu_info.vector, | |
| 5271 | 5275 | vcpu_info.pi_desc_addr, set); |
| 5272 | 5276 | } |
| 5273 | 5277 | |
| @@ -7102,6 +7106,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { · 1828 unmodified lines | ||
| 7102 | 7106 | |
| 7103 | 7107 | .has_wbinvd_exit = svm_has_wbinvd_exit, |
| 7104 | 7108 | |
| 7109 | + .read_l1_tsc_offset = svm_read_l1_tsc_offset, | |
| 7105 | 7110 | .write_tsc_offset = svm_write_tsc_offset, |
| 7106 | 7111 | |
| 7107 | 7112 | .set_tdp_cr3 = set_tdp_cr3, |
| @@ -2880,18 +2880,15 @@ static void setup_msrs(struct vcpu_vmx *vmx) · 2879 unmodified lines | ||
| 2880 | 2880 | vmx_update_msr_bitmap(&vmx->vcpu); |
| 2881 | 2881 | } |
| 2882 | 2882 | |
| 2883 | −/* | |
| 2884 | − * reads and returns guest's timestamp counter "register" | |
| 2885 | − * guest_tsc = (host_tsc * tsc multiplier) >> 48 + tsc_offset | |
| 2886 | − * -- Intel TSC Scaling for Virtualization White Paper, sec 1.3 | |
| 2887 | − */ | |
| 2888 | −static u64 guest_read_tsc(struct kvm_vcpu *vcpu) | |
| 2883 | +static u64 vmx_read_l1_tsc_offset(struct kvm_vcpu *vcpu) | |
| 2889 | 2884 | { |
| 2890 | − u64 host_tsc, tsc_offset; | |
| 2885 | + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); | |
| 2891 | 2886 | |
| 2892 | − host_tsc = rdtsc(); | |
| 2893 | − tsc_offset = vmcs_read64(TSC_OFFSET); | |
| 2894 | − return kvm_scale_tsc(vcpu, host_tsc) + tsc_offset; | |
| 2887 | + if (is_guest_mode(vcpu) && | |
| 2888 | + (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)) | |
| 2889 | + return vcpu->arch.tsc_offset - vmcs12->tsc_offset; | |
| 2890 | + | |
| 2891 | + return vcpu->arch.tsc_offset; | |
| 2895 | 2892 | } |
| 2896 | 2893 | |
| 2897 | 2894 | /* |
| @@ -3524,9 +3521,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 626 unmodified lines | ||
| 3524 | 3521 | #endif |
| 3525 | 3522 | case MSR_EFER: |
| 3526 | 3523 | return kvm_get_msr_common(vcpu, msr_info); |
| 3527 | − case MSR_IA32_TSC: | |
| 3528 | − msr_info->data = guest_read_tsc(vcpu); | |
| 3529 | − break; | |
| 3530 | 3524 | case MSR_IA32_SPEC_CTRL: |
| 3531 | 3525 | if (!msr_info->host_initiated && |
| 3532 | 3526 | !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) && |
| @@ -3646,9 +3640,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 113 unmodified lines | ||
| 3646 | 3640 | return 1; |
| 3647 | 3641 | vmcs_write64(GUEST_BNDCFGS, data); |
| 3648 | 3642 | break; |
| 3649 | − case MSR_IA32_TSC: | |
| 3650 | − kvm_write_tsc(vcpu, msr_info); | |
| 3651 | − break; | |
| 3652 | 3643 | case MSR_IA32_SPEC_CTRL: |
| 3653 | 3644 | if (!msr_info->host_initiated && |
| 3654 | 3645 | !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) && |
| @@ -4553,12 +4544,6 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa) · 898 unmodified lines | ||
| 4553 | 4544 | __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid, invalidate_gpa); |
| 4554 | 4545 | } |
| 4555 | 4546 | |
| 4556 | −static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu) | |
| 4557 | −{ | |
| 4558 | − if (enable_ept) | |
| 4559 | − vmx_flush_tlb(vcpu, true); | |
| 4560 | −} | |
| 4561 | − | |
| 4562 | 4547 | static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) |
| 4563 | 4548 | { |
| 4564 | 4549 | ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits; |
| @@ -9287,7 +9272,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set) · 4722 unmodified lines | ||
| 9287 | 9272 | } else { |
| 9288 | 9273 | sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; |
| 9289 | 9274 | sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; |
| 9290 | − vmx_flush_tlb_ept_only(vcpu); | |
| 9275 | + vmx_flush_tlb(vcpu, true); | |
| 9291 | 9276 | } |
| 9292 | 9277 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control); |
| 9293 | 9278 | |
| @@ -9315,7 +9300,7 @@ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa) · 21 unmodified lines | ||
| 9315 | 9300 | !nested_cpu_has2(get_vmcs12(&vmx->vcpu), |
| 9316 | 9301 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
| 9317 | 9302 | vmcs_write64(APIC_ACCESS_ADDR, hpa); |
| 9318 | − vmx_flush_tlb_ept_only(vcpu); | |
| 9303 | + vmx_flush_tlb(vcpu, true); | |
| 9319 | 9304 | } |
| 9320 | 9305 | } |
| 9321 | 9306 | |
| @@ -10608,6 +10593,16 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, · 1286 unmodified lines | ||
| 10608 | 10593 | return true; |
| 10609 | 10594 | } |
| 10610 | 10595 | |
| 10596 | +static int nested_vmx_check_apic_access_controls(struct kvm_vcpu *vcpu, | |
| 10597 | + struct vmcs12 *vmcs12) | |
| 10598 | +{ | |
| 10599 | + if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) && | |
| 10600 | + !page_address_valid(vcpu, vmcs12->apic_access_addr)) | |
| 10601 | + return -EINVAL; | |
| 10602 | + else | |
| 10603 | + return 0; | |
| 10604 | +} | |
| 10605 | + | |
| 10611 | 10606 | static int nested_vmx_check_apicv_controls(struct kvm_vcpu *vcpu, |
| 10612 | 10607 | struct vmcs12 *vmcs12) |
| 10613 | 10608 | { |
| @@ -11176,11 +11171,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, · 562 unmodified lines | ||
| 11176 | 11171 | vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat); |
| 11177 | 11172 | } |
| 11178 | 11173 | |
| 11179 | − if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING) | |
| 11180 | − vmcs_write64(TSC_OFFSET, | |
| 11181 | − vcpu->arch.tsc_offset + vmcs12->tsc_offset); | |
| 11182 | − else | |
| 11183 | − vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset); | |
| 11174 | + vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset); | |
| 11175 | + | |
| 11184 | 11176 | if (kvm_has_tsc_control) |
| 11185 | 11177 | decache_tsc_multiplier(vmx); |
| 11186 | 11178 | |
| @@ -11222,7 +11214,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, · 35 unmodified lines | ||
| 11222 | 11214 | } |
| 11223 | 11215 | } else if (nested_cpu_has2(vmcs12, |
| 11224 | 11216 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
| 11225 | − vmx_flush_tlb_ept_only(vcpu); | |
| 11217 | + vmx_flush_tlb(vcpu, true); | |
| 11226 | 11218 | } |
| 11227 | 11219 | |
| 11228 | 11220 | /* |
| @@ -11299,6 +11291,9 @@ static int check_vmentry_prereqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) · 70 unmodified lines | ||
| 11299 | 11291 | if (nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12)) |
| 11300 | 11292 | return VMXERR_ENTRY_INVALID_CONTROL_FIELD; |
| 11301 | 11293 | |
| 11294 | + if (nested_vmx_check_apic_access_controls(vcpu, vmcs12)) | |
| 11295 | + return VMXERR_ENTRY_INVALID_CONTROL_FIELD; | |
| 11296 | + | |
| 11302 | 11297 | if (nested_vmx_check_tpr_shadow_controls(vcpu, vmcs12)) |
| 11303 | 11298 | return VMXERR_ENTRY_INVALID_CONTROL_FIELD; |
| 11304 | 11299 | |
| @@ -11420,6 +11415,7 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) · 115 unmodified lines | ||
| 11420 | 11415 | struct vmcs12 *vmcs12 = get_vmcs12(vcpu); |
| 11421 | 11416 | u32 msr_entry_idx; |
| 11422 | 11417 | u32 exit_qual; |
| 11418 | + int r; | |
| 11423 | 11419 | |
| 11424 | 11420 | enter_guest_mode(vcpu); |
| 11425 | 11421 | |
| @@ -11429,26 +11425,21 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) · 3 unmodified lines | ||
| 11429 | 11425 | vmx_switch_vmcs(vcpu, &vmx->nested.vmcs02); |
| 11430 | 11426 | vmx_segment_cache_clear(vmx); |
| 11431 | 11427 | |
| 11432 | − if (prepare_vmcs02(vcpu, vmcs12, from_vmentry, &exit_qual)) { | |
| 11433 | − leave_guest_mode(vcpu); | |
| 11434 | − vmx_switch_vmcs(vcpu, &vmx->vmcs01); | |
| 11435 | − nested_vmx_entry_failure(vcpu, vmcs12, | |
| 11436 | − EXIT_REASON_INVALID_STATE, exit_qual); | |
| 11437 | − return 1; | |
| 11438 | − } | |
| 11428 | + if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING) | |
| 11429 | + vcpu->arch.tsc_offset += vmcs12->tsc_offset; | |
| 11430 | + | |
| 11431 | + r = EXIT_REASON_INVALID_STATE; | |
| 11432 | + if (prepare_vmcs02(vcpu, vmcs12, from_vmentry, &exit_qual)) | |
| 11433 | + goto fail; | |
| 11439 | 11434 | |
| 11440 | 11435 | nested_get_vmcs12_pages(vcpu, vmcs12); |
| 11441 | 11436 | |
| 11437 | + r = EXIT_REASON_MSR_LOAD_FAIL; | |
| 11442 | 11438 | msr_entry_idx = nested_vmx_load_msr(vcpu, |
| 11443 | 11439 | vmcs12->vm_entry_msr_load_addr, |
| 11444 | 11440 | vmcs12->vm_entry_msr_load_count); |
| 11445 | − if (msr_entry_idx) { | |
| 11446 | − leave_guest_mode(vcpu); | |
| 11447 | − vmx_switch_vmcs(vcpu, &vmx->vmcs01); | |
| 11448 | − nested_vmx_entry_failure(vcpu, vmcs12, | |
| 11449 | − EXIT_REASON_MSR_LOAD_FAIL, msr_entry_idx); | |
| 11450 | − return 1; | |
| 11451 | − } | |
| 11441 | + if (msr_entry_idx) | |
| 11442 | + goto fail; | |
| 11452 | 11443 | |
| 11453 | 11444 | /* |
| 11454 | 11445 | * Note no nested_vmx_succeed or nested_vmx_fail here. At this point |
| @@ -11457,6 +11448,14 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) · 2 unmodified lines | ||
| 11457 | 11448 | * the success flag) when L2 exits (see nested_vmx_vmexit()). |
| 11458 | 11449 | */ |
| 11459 | 11450 | return 0; |
| 11451 | + | |
| 11452 | +fail: | |
| 11453 | + if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING) | |
| 11454 | + vcpu->arch.tsc_offset -= vmcs12->tsc_offset; | |
| 11455 | + leave_guest_mode(vcpu); | |
| 11456 | + vmx_switch_vmcs(vcpu, &vmx->vmcs01); | |
| 11457 | + nested_vmx_entry_failure(vcpu, vmcs12, r, exit_qual); | |
| 11458 | + return 1; | |
| 11460 | 11459 | } |
| 11461 | 11460 | |
| 11462 | 11461 | /* |
| @@ -12028,6 +12027,9 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, · 565 unmodified lines | ||
| 12028 | 12027 | |
| 12029 | 12028 | leave_guest_mode(vcpu); |
| 12030 | 12029 | |
| 12030 | + if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING) | |
| 12031 | + vcpu->arch.tsc_offset -= vmcs12->tsc_offset; | |
| 12032 | + | |
| 12031 | 12033 | if (likely(!vmx->fail)) { |
| 12032 | 12034 | if (exit_reason == -1) |
| 12033 | 12035 | sync_vmcs12(vcpu, vmcs12); |
| @@ -12065,7 +12067,7 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, · 31 unmodified lines | ||
| 12065 | 12067 | } else if (!nested_cpu_has_ept(vmcs12) && |
| 12066 | 12068 | nested_cpu_has2(vmcs12, |
| 12067 | 12069 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
| 12068 | − vmx_flush_tlb_ept_only(vcpu); | |
| 12070 | + vmx_flush_tlb(vcpu, true); | |
| 12069 | 12071 | } |
| 12070 | 12072 | |
| 12071 | 12073 | /* This is needed for same reason as it was needed in prepare_vmcs02 */ |
| @@ -12224,10 +12226,16 @@ static inline int u64_shl_div_u64(u64 a, unsigned int shift, · 152 unmodified lines | ||
| 12224 | 12226 | |
| 12225 | 12227 | static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc) |
| 12226 | 12228 | { |
| 12227 | − struct vcpu_vmx *vmx = to_vmx(vcpu); | |
| 12228 | − u64 tscl = rdtsc(); | |
| 12229 | − u64 guest_tscl = kvm_read_l1_tsc(vcpu, tscl); | |
| 12230 | − u64 delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl; | |
| 12229 | + struct vcpu_vmx *vmx; | |
| 12230 | + u64 tscl, guest_tscl, delta_tsc; | |
| 12231 | + | |
| 12232 | + if (kvm_mwait_in_guest(vcpu->kvm)) | |
| 12233 | + return -EOPNOTSUPP; | |
| 12234 | + | |
| 12235 | + vmx = to_vmx(vcpu); | |
| 12236 | + tscl = rdtsc(); | |
| 12237 | + guest_tscl = kvm_read_l1_tsc(vcpu, tscl); | |
| 12238 | + delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl; | |
| 12231 | 12239 | |
| 12232 | 12240 | /* Convert to host delta tsc if tsc scaling is enabled */ |
| 12233 | 12241 | if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio && |
| @@ -12533,7 +12541,7 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq, · 299 unmodified lines | ||
| 12533 | 12541 | vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu)); |
| 12534 | 12542 | vcpu_info.vector = irq.vector; |
| 12535 | 12543 | |
| 12536 | − trace_kvm_pi_irte_update(vcpu->vcpu_id, host_irq, e->gsi, | |
| 12544 | + trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi, | |
| 12537 | 12545 | vcpu_info.vector, vcpu_info.pi_desc_addr, set); |
| 12538 | 12546 | |
| 12539 | 12547 | if (set) |
| @@ -12712,6 +12720,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = { · 172 unmodified lines | ||
| 12712 | 12720 | |
| 12713 | 12721 | .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit, |
| 12714 | 12722 | |
| 12723 | + .read_l1_tsc_offset = vmx_read_l1_tsc_offset, | |
| 12715 | 12724 | .write_tsc_offset = vmx_write_tsc_offset, |
| 12716 | 12725 | |
| 12717 | 12726 | .set_tdp_cr3 = vmx_set_cr3, |
| @@ -1490,7 +1490,7 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu) · 1489 unmodified lines | ||
| 1490 | 1490 | |
| 1491 | 1491 | static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset) |
| 1492 | 1492 | { |
| 1493 | − u64 curr_offset = vcpu->arch.tsc_offset; | |
| 1493 | + u64 curr_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu); | |
| 1494 | 1494 | vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset; |
| 1495 | 1495 | } |
| 1496 | 1496 | |
| @@ -1532,7 +1532,9 @@ static u64 kvm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc) · 35 unmodified lines | ||
| 1532 | 1532 | |
| 1533 | 1533 | u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc) |
| 1534 | 1534 | { |
| 1535 | − return vcpu->arch.tsc_offset + kvm_scale_tsc(vcpu, host_tsc); | |
| 1535 | + u64 tsc_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu); | |
| 1536 | + | |
| 1537 | + return tsc_offset + kvm_scale_tsc(vcpu, host_tsc); | |
| 1536 | 1538 | } |
| 1537 | 1539 | EXPORT_SYMBOL_GPL(kvm_read_l1_tsc); |
| 1538 | 1540 | |
| @@ -2362,6 +2364,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 823 unmodified lines | ||
| 2362 | 2364 | return 1; |
| 2363 | 2365 | vcpu->arch.smbase = data; |
| 2364 | 2366 | break; |
| 2367 | + case MSR_IA32_TSC: | |
| 2368 | + kvm_write_tsc(vcpu, msr_info); | |
| 2369 | + break; | |
| 2365 | 2370 | case MSR_SMI_COUNT: |
| 2366 | 2371 | if (!msr_info->host_initiated) |
| 2367 | 2372 | return 1; |
| @@ -2605,6 +2610,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 237 unmodified lines | ||
| 2605 | 2610 | case MSR_IA32_UCODE_REV: |
| 2606 | 2611 | msr_info->data = vcpu->arch.microcode_version; |
| 2607 | 2612 | break; |
| 2613 | + case MSR_IA32_TSC: | |
| 2614 | + msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset; | |
| 2615 | + break; | |
| 2608 | 2616 | case MSR_MTRRcap: |
| 2609 | 2617 | case 0x200 ... 0x2ff: |
| 2610 | 2618 | return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data); |
| @@ -2819,7 +2827,8 @@ out: · 208 unmodified lines | ||
| 2819 | 2827 | static inline bool kvm_can_mwait_in_guest(void) |
| 2820 | 2828 | { |
| 2821 | 2829 | return boot_cpu_has(X86_FEATURE_MWAIT) && |
| 2822 | − !boot_cpu_has_bug(X86_BUG_MONITOR); | |
| 2830 | + !boot_cpu_has_bug(X86_BUG_MONITOR) && | |
| 2831 | + boot_cpu_has(X86_FEATURE_ARAT); | |
| 2823 | 2832 | } |
| 2824 | 2833 | |
| 2825 | 2834 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
| @@ -302,13 +302,6 @@ static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec) · 301 unmodified lines | ||
| 302 | 302 | __rem; \ |
| 303 | 303 | }) |
| 304 | 304 | |
| 305 | −#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) | |
| 306 | −#define KVM_X86_DISABLE_EXITS_HTL (1 << 1) | |
| 307 | −#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) | |
| 308 | −#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ | |
| 309 | − KVM_X86_DISABLE_EXITS_HTL | \ | |
| 310 | − KVM_X86_DISABLE_EXITS_PAUSE) | |
| 311 | − | |
| 312 | 305 | static inline bool kvm_mwait_in_guest(struct kvm *kvm) |
| 313 | 306 | { |
| 314 | 307 | return kvm->arch.mwait_in_guest; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/init.h> |
| 19 | 19 | #include <linux/sched.h> |
| 20 | 20 | #include <linux/seq_file.h> |
| 21 | +#include <linux/highmem.h> | |
| 21 | 22 | |
| 22 | 23 | #include <asm/pgtable.h> |
| 23 | 24 | |
| @@ -334,16 +335,16 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr, · 310 unmodified lines | ||
| 334 | 335 | pgprotval_t eff_in, unsigned long P) |
| 335 | 336 | { |
| 336 | 337 | int i; |
| 337 | − pte_t *start; | |
| 338 | + pte_t *pte; | |
| 338 | 339 | pgprotval_t prot, eff; |
| 339 | 340 | |
| 340 | − start = (pte_t *)pmd_page_vaddr(addr); | |
| 341 | 341 | for (i = 0; i < PTRS_PER_PTE; i++) { |
| 342 | − prot = pte_flags(*start); | |
| 343 | − eff = effective_prot(eff_in, prot); | |
| 344 | 342 | st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT); |
| 343 | + pte = pte_offset_map(&addr, st->current_address); | |
| 344 | + prot = pte_flags(*pte); | |
| 345 | + eff = effective_prot(eff_in, prot); | |
| 345 | 346 | note_page(m, st, __pgprot(prot), eff, 5); |
| 346 | − start++; | |
| 347 | + pte_unmap(pte); | |
| 347 | 348 | } |
| 348 | 349 | } |
| 349 | 350 | #ifdef CONFIG_KASAN |
| @@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m) · 92 unmodified lines | ||
| 93 | 93 | static inline void split_page_count(int level) { } |
| 94 | 94 | #endif |
| 95 | 95 | |
| 96 | +static inline int | |
| 97 | +within(unsigned long addr, unsigned long start, unsigned long end) | |
| 98 | +{ | |
| 99 | + return addr >= start && addr < end; | |
| 100 | +} | |
| 101 | + | |
| 102 | +static inline int | |
| 103 | +within_inclusive(unsigned long addr, unsigned long start, unsigned long end) | |
| 104 | +{ | |
| 105 | + return addr >= start && addr <= end; | |
| 106 | +} | |
| 107 | + | |
| 96 | 108 | #ifdef CONFIG_X86_64 |
| 97 | 109 | |
| 98 | 110 | static inline unsigned long highmap_start_pfn(void) |
| @@ -106,20 +118,25 @@ static inline unsigned long highmap_end_pfn(void) · 7 unmodified lines | ||
| 106 | 118 | return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT; |
| 107 | 119 | } |
| 108 | 120 | |
| 109 | −#endif | |
| 110 | − | |
| 111 | −static inline int | |
| 112 | −within(unsigned long addr, unsigned long start, unsigned long end) | |
| 121 | +static bool __cpa_pfn_in_highmap(unsigned long pfn) | |
| 113 | 122 | { |
| 114 | − return addr >= start && addr < end; | |
| 123 | + /* | |
| 124 | + * Kernel text has an alias mapping at a high address, known | |
| 125 | + * here as "highmap". | |
| 126 | + */ | |
| 127 | + return within_inclusive(pfn, highmap_start_pfn(), highmap_end_pfn()); | |
| 115 | 128 | } |
| 116 | 129 | |
| 117 | −static inline int | |
| 118 | −within_inclusive(unsigned long addr, unsigned long start, unsigned long end) | |
| 130 | +#else | |
| 131 | + | |
| 132 | +static bool __cpa_pfn_in_highmap(unsigned long pfn) | |
| 119 | 133 | { |
| 120 | − return addr >= start && addr <= end; | |
| 134 | + /* There is no highmap on 32-bit */ | |
| 135 | + return false; | |
| 121 | 136 | } |
| 122 | 137 | |
| 138 | +#endif | |
| 139 | + | |
| 123 | 140 | /* |
| 124 | 141 | * Flushing functions |
| 125 | 142 | */ |
| @@ -172,7 +189,7 @@ static void __cpa_flush_all(void *arg) · 46 unmodified lines | ||
| 172 | 189 | |
| 173 | 190 | static void cpa_flush_all(unsigned long cache) |
| 174 | 191 | { |
| 175 | − BUG_ON(irqs_disabled()); | |
| 192 | + BUG_ON(irqs_disabled() && !early_boot_irqs_disabled); | |
| 176 | 193 | |
| 177 | 194 | on_each_cpu(__cpa_flush_all, (void *) cache, 1); |
| 178 | 195 | } |
| @@ -236,7 +253,7 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache, · 57 unmodified lines | ||
| 236 | 253 | unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */ |
| 237 | 254 | #endif |
| 238 | 255 | |
| 239 | − BUG_ON(irqs_disabled()); | |
| 256 | + BUG_ON(irqs_disabled() && !early_boot_irqs_disabled); | |
| 240 | 257 | |
| 241 | 258 | on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1); |
| 242 | 259 | |
| @@ -1183,6 +1200,10 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr, · 940 unmodified lines | ||
| 1183 | 1200 | cpa->numpages = 1; |
| 1184 | 1201 | cpa->pfn = __pa(vaddr) >> PAGE_SHIFT; |
| 1185 | 1202 | return 0; |
| 1203 | + | |
| 1204 | + } else if (__cpa_pfn_in_highmap(cpa->pfn)) { | |
| 1205 | + /* Faults in the highmap are OK, so do not warn: */ | |
| 1206 | + return -EFAULT; | |
| 1186 | 1207 | } else { |
| 1187 | 1208 | WARN(1, KERN_WARNING "CPA: called for zero pte. " |
| 1188 | 1209 | "vaddr = %lx cpa->vaddr = %lx\n", vaddr, |
| @@ -1335,8 +1356,7 @@ static int cpa_process_alias(struct cpa_data *cpa) · 146 unmodified lines | ||
| 1335 | 1356 | * to touch the high mapped kernel as well: |
| 1336 | 1357 | */ |
| 1337 | 1358 | if (!within(vaddr, (unsigned long)_text, _brk_end) && |
| 1338 | − within_inclusive(cpa->pfn, highmap_start_pfn(), | |
| 1339 | − highmap_end_pfn())) { | |
| 1359 | + __cpa_pfn_in_highmap(cpa->pfn)) { | |
| 1340 | 1360 | unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + |
| 1341 | 1361 | __START_KERNEL_map - phys_base; |
| 1342 | 1362 | alias_cpa = *cpa; |
| @@ -421,6 +421,16 @@ static inline bool pti_kernel_image_global_ok(void) · 420 unmodified lines | ||
| 421 | 421 | if (boot_cpu_has(X86_FEATURE_K8)) |
| 422 | 422 | return false; |
| 423 | 423 | |
| 424 | + /* | |
| 425 | + * RANDSTRUCT derives its hardening benefits from the | |
| 426 | + * attacker's lack of knowledge about the layout of kernel | |
| 427 | + * data structures. Keep the kernel image non-global in | |
| 428 | + * cases where RANDSTRUCT is in use to help keep the layout a | |
| 429 | + * secret. | |
| 430 | + */ | |
| 431 | + if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT)) | |
| 432 | + return false; | |
| 433 | + | |
| 424 | 434 | return true; |
| 425 | 435 | } |
| 426 | 436 | |
| @@ -430,12 +440,24 @@ static inline bool pti_kernel_image_global_ok(void) · 3 unmodified lines | ||
| 430 | 440 | */ |
| 431 | 441 | void pti_clone_kernel_text(void) |
| 432 | 442 | { |
| 443 | + /* | |
| 444 | + * rodata is part of the kernel image and is normally | |
| 445 | + * readable on the filesystem or on the web. But, do not | |
| 446 | + * clone the areas past rodata, they might contain secrets. | |
| 447 | + */ | |
| 433 | 448 | unsigned long start = PFN_ALIGN(_text); |
| 434 | − unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE); | |
| 449 | + unsigned long end = (unsigned long)__end_rodata_hpage_align; | |
| 435 | 450 | |
| 436 | 451 | if (!pti_kernel_image_global_ok()) |
| 437 | 452 | return; |
| 438 | 453 | |
| 454 | + pr_debug("mapping partial kernel image into user address space\n"); | |
| 455 | + | |
| 456 | + /* | |
| 457 | + * Note that this will undo _some_ of the work that | |
| 458 | + * pti_set_kernel_image_nonglobal() did to clear the | |
| 459 | + * global bit. | |
| 460 | + */ | |
| 439 | 461 | pti_clone_pmds(start, end, _PAGE_RW); |
| 440 | 462 | } |
| 441 | 463 | |
| @@ -458,8 +480,6 @@ void pti_set_kernel_image_nonglobal(void) · 16 unmodified lines | ||
| 458 | 480 | if (pti_kernel_image_global_ok()) |
| 459 | 481 | return; |
| 460 | 482 | |
| 461 | − pr_debug("set kernel image non-global\n"); | |
| 462 | − | |
| 463 | 483 | set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT); |
| 464 | 484 | } |
| 465 | 485 | |
| @@ -1027,7 +1027,17 @@ emit_cond_jmp: /* convert BPF opcode to x86 */ · 1026 unmodified lines | ||
| 1027 | 1027 | break; |
| 1028 | 1028 | |
| 1029 | 1029 | case BPF_JMP | BPF_JA: |
| 1030 | − jmp_offset = addrs[i + insn->off] - addrs[i]; | |
| 1030 | + if (insn->off == -1) | |
| 1031 | + /* -1 jmp instructions will always jump | |
| 1032 | + * backwards two bytes. Explicitly handling | |
| 1033 | + * this case avoids wasting too many passes | |
| 1034 | + * when there are long sequences of replaced | |
| 1035 | + * dead code. | |
| 1036 | + */ | |
| 1037 | + jmp_offset = -2; | |
| 1038 | + else | |
| 1039 | + jmp_offset = addrs[i + insn->off] - addrs[i]; | |
| 1040 | + | |
| 1031 | 1041 | if (!jmp_offset) |
| 1032 | 1042 | /* optimize out nop jumps */ |
| 1033 | 1043 | break; |
| @@ -1226,6 +1236,7 @@ skip_init_addrs: · 192 unmodified lines | ||
| 1226 | 1236 | for (pass = 0; pass < 20 || image; pass++) { |
| 1227 | 1237 | proglen = do_jit(prog, addrs, image, oldproglen, &ctx); |
| 1228 | 1238 | if (proglen <= 0) { |
| 1239 | +out_image: | |
| 1229 | 1240 | image = NULL; |
| 1230 | 1241 | if (header) |
| 1231 | 1242 | bpf_jit_binary_free(header); |
| @@ -1236,8 +1247,7 @@ skip_init_addrs: · 4 unmodified lines | ||
| 1236 | 1247 | if (proglen != oldproglen) { |
| 1237 | 1248 | pr_err("bpf_jit: proglen=%d != oldproglen=%d\n", |
| 1238 | 1249 | proglen, oldproglen); |
| 1239 | − prog = orig_prog; | |
| 1240 | − goto out_addrs; | |
| 1250 | + goto out_image; | |
| 1241 | 1251 | } |
| 1242 | 1252 | break; |
| 1243 | 1253 | } |
| @@ -1273,7 +1283,7 @@ skip_init_addrs: · 29 unmodified lines | ||
| 1273 | 1283 | prog = orig_prog; |
| 1274 | 1284 | } |
| 1275 | 1285 | |
| 1276 | − if (!prog->is_func || extra_pass) { | |
| 1286 | + if (!image || !prog->is_func || extra_pass) { | |
| 1277 | 1287 | out_addrs: |
| 1278 | 1288 | kfree(addrs); |
| 1279 | 1289 | kfree(jit_data); |
| @@ -98,7 +98,7 @@ static int set_up_temporary_text_mapping(pgd_t *pgd) · 97 unmodified lines | ||
| 98 | 98 | set_pgd(pgd + pgd_index(restore_jump_address), new_pgd); |
| 99 | 99 | } else { |
| 100 | 100 | /* No p4d for 4-level paging: point the pgd to the pud page table */ |
| 101 | − pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot)); | |
| 101 | + pgd_t new_pgd = __pgd(__pa(pud) | pgprot_val(pgtable_prot)); | |
| 102 | 102 | set_pgd(pgd + pgd_index(restore_jump_address), new_pgd); |
| 103 | 103 | } |
| 104 | 104 | |
| @@ -421,45 +421,33 @@ static void xen_load_gdt(const struct desc_ptr *dtr) · 420 unmodified lines | ||
| 421 | 421 | { |
| 422 | 422 | unsigned long va = dtr->address; |
| 423 | 423 | unsigned int size = dtr->size + 1; |
| 424 | − unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE); | |
| 425 | − unsigned long frames[pages]; | |
| 426 | − int f; | |
| 427 | − | |
| 428 | − /* | |
| 429 | − * A GDT can be up to 64k in size, which corresponds to 8192 | |
| 430 | − * 8-byte entries, or 16 4k pages.. | |
| 431 | − */ | |
| 424 | + unsigned long pfn, mfn; | |
| 425 | + int level; | |
| 426 | + pte_t *ptep; | |
| 427 | + void *virt; | |
| 432 | 428 | |
| 433 | − BUG_ON(size > 65536); | |
| 429 | + /* @size should be at most GDT_SIZE which is smaller than PAGE_SIZE. */ | |
| 430 | + BUG_ON(size > PAGE_SIZE); | |
| 434 | 431 | BUG_ON(va & ~PAGE_MASK); |
| 435 | 432 | |
| 436 | − for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { | |
| 437 | − int level; | |
| 438 | − pte_t *ptep; | |
| 439 | − unsigned long pfn, mfn; | |
| 440 | − void *virt; | |
| 441 | − | |
| 442 | − /* | |
| 443 | − * The GDT is per-cpu and is in the percpu data area. | |
| 444 | − * That can be virtually mapped, so we need to do a | |
| 445 | − * page-walk to get the underlying MFN for the | |
| 446 | − * hypercall. The page can also be in the kernel's | |
| 447 | − * linear range, so we need to RO that mapping too. | |
| 448 | − */ | |
| 449 | − ptep = lookup_address(va, &level); | |
| 450 | − BUG_ON(ptep == NULL); | |
| 451 | − | |
| 452 | − pfn = pte_pfn(*ptep); | |
| 453 | − mfn = pfn_to_mfn(pfn); | |
| 454 | − virt = __va(PFN_PHYS(pfn)); | |
| 433 | + /* | |
| 434 | + * The GDT is per-cpu and is in the percpu data area. | |
| 435 | + * That can be virtually mapped, so we need to do a | |
| 436 | + * page-walk to get the underlying MFN for the | |
| 437 | + * hypercall. The page can also be in the kernel's | |
| 438 | + * linear range, so we need to RO that mapping too. | |
| 439 | + */ | |
| 440 | + ptep = lookup_address(va, &level); | |
| 441 | + BUG_ON(ptep == NULL); | |
| 455 | 442 | |
| 456 | − frames[f] = mfn; | |
| 443 | + pfn = pte_pfn(*ptep); | |
| 444 | + mfn = pfn_to_mfn(pfn); | |
| 445 | + virt = __va(PFN_PHYS(pfn)); | |
| 457 | 446 | |
| 458 | − make_lowmem_page_readonly((void *)va); | |
| 459 | − make_lowmem_page_readonly(virt); | |
| 460 | − } | |
| 447 | + make_lowmem_page_readonly((void *)va); | |
| 448 | + make_lowmem_page_readonly(virt); | |
| 461 | 449 | |
| 462 | − if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct))) | |
| 450 | + if (HYPERVISOR_set_gdt(&mfn, size / sizeof(struct desc_struct))) | |
| 463 | 451 | BUG(); |
| 464 | 452 | } |
| 465 | 453 | |
| @@ -470,34 +458,22 @@ static void __init xen_load_gdt_boot(const struct desc_ptr *dtr) · 4 unmodified lines | ||
| 470 | 458 | { |
| 471 | 459 | unsigned long va = dtr->address; |
| 472 | 460 | unsigned int size = dtr->size + 1; |
| 473 | − unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE); | |
| 474 | − unsigned long frames[pages]; | |
| 475 | − int f; | |
| 476 | − | |
| 477 | − /* | |
| 478 | − * A GDT can be up to 64k in size, which corresponds to 8192 | |
| 479 | − * 8-byte entries, or 16 4k pages.. | |
| 480 | − */ | |
| 461 | + unsigned long pfn, mfn; | |
| 462 | + pte_t pte; | |
| 481 | 463 | |
| 482 | − BUG_ON(size > 65536); | |
| 464 | + /* @size should be at most GDT_SIZE which is smaller than PAGE_SIZE. */ | |
| 465 | + BUG_ON(size > PAGE_SIZE); | |
| 483 | 466 | BUG_ON(va & ~PAGE_MASK); |
| 484 | 467 | |
| 485 | − for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { | |
| 486 | − pte_t pte; | |
| 487 | − unsigned long pfn, mfn; | |
| 468 | + pfn = virt_to_pfn(va); | |
| 469 | + mfn = pfn_to_mfn(pfn); | |
| 488 | 470 | |
| 489 | − pfn = virt_to_pfn(va); | |
| 490 | − mfn = pfn_to_mfn(pfn); | |
| 471 | + pte = pfn_pte(pfn, PAGE_KERNEL_RO); | |
| 491 | 472 | |
| 492 | − pte = pfn_pte(pfn, PAGE_KERNEL_RO); | |
| 493 | − | |
| 494 | − if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0)) | |
| 495 | − BUG(); | |
| 496 | − | |
| 497 | − frames[f] = mfn; | |
| 498 | − } | |
| 473 | + if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0)) | |
| 474 | + BUG(); | |
| 499 | 475 | |
| 500 | − if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct))) | |
| 476 | + if (HYPERVISOR_set_gdt(&mfn, size / sizeof(struct desc_struct))) | |
| 501 | 477 | BUG(); |
| 502 | 478 | } |
| 503 | 479 | |
| @@ -4934,8 +4934,16 @@ static void bfq_prepare_request(struct request *rq, struct bio *bio) · 4933 unmodified lines | ||
| 4934 | 4934 | bool new_queue = false; |
| 4935 | 4935 | bool bfqq_already_existing = false, split = false; |
| 4936 | 4936 | |
| 4937 | − if (!rq->elv.icq) | |
| 4937 | + /* | |
| 4938 | + * Even if we don't have an icq attached, we should still clear | |
| 4939 | + * the scheduler pointers, as they might point to previously | |
| 4940 | + * allocated bic/bfqq structs. | |
| 4941 | + */ | |
| 4942 | + if (!rq->elv.icq) { | |
| 4943 | + rq->elv.priv[0] = rq->elv.priv[1] = NULL; | |
| 4938 | 4944 | return; |
| 4945 | + } | |
| 4946 | + | |
| 4939 | 4947 | bic = icq_to_bic(rq->elv.icq); |
| 4940 | 4948 | |
| 4941 | 4949 | spin_lock_irq(&bfqd->lock); |
| @@ -1177,26 +1177,20 @@ int blkcg_init_queue(struct request_queue *q) · 1176 unmodified lines | ||
| 1177 | 1177 | |
| 1178 | 1178 | preloaded = !radix_tree_preload(GFP_KERNEL); |
| 1179 | 1179 | |
| 1180 | − /* | |
| 1181 | − * Make sure the root blkg exists and count the existing blkgs. As | |
| 1182 | − * @q is bypassing at this point, blkg_lookup_create() can't be | |
| 1183 | − * used. Open code insertion. | |
| 1184 | − */ | |
| 1180 | + /* Make sure the root blkg exists. */ | |
| 1185 | 1181 | rcu_read_lock(); |
| 1186 | 1182 | spin_lock_irq(q->queue_lock); |
| 1187 | 1183 | blkg = blkg_create(&blkcg_root, q, new_blkg); |
| 1184 | + if (IS_ERR(blkg)) | |
| 1185 | + goto err_unlock; | |
| 1186 | + q->root_blkg = blkg; | |
| 1187 | + q->root_rl.blkg = blkg; | |
| 1188 | 1188 | spin_unlock_irq(q->queue_lock); |
| 1189 | 1189 | rcu_read_unlock(); |
| 1190 | 1190 | |
| 1191 | 1191 | if (preloaded) |
| 1192 | 1192 | radix_tree_preload_end(); |
| 1193 | 1193 | |
| 1194 | − if (IS_ERR(blkg)) | |
| 1195 | − return PTR_ERR(blkg); | |
| 1196 | − | |
| 1197 | − q->root_blkg = blkg; | |
| 1198 | − q->root_rl.blkg = blkg; | |
| 1199 | − | |
| 1200 | 1194 | ret = blk_throtl_init(q); |
| 1201 | 1195 | if (ret) { |
| 1202 | 1196 | spin_lock_irq(q->queue_lock); |
| @@ -1204,6 +1198,13 @@ int blkcg_init_queue(struct request_queue *q) · 1 unmodified line | ||
| 1204 | 1198 | spin_unlock_irq(q->queue_lock); |
| 1205 | 1199 | } |
| 1206 | 1200 | return ret; |
| 1201 | + | |
| 1202 | +err_unlock: | |
| 1203 | + spin_unlock_irq(q->queue_lock); | |
| 1204 | + rcu_read_unlock(); | |
| 1205 | + if (preloaded) | |
| 1206 | + radix_tree_preload_end(); | |
| 1207 | + return PTR_ERR(blkg); | |
| 1207 | 1208 | } |
| 1208 | 1209 | |
| 1209 | 1210 | /** |
| @@ -1410,9 +1411,6 @@ void blkcg_deactivate_policy(struct request_queue *q, · 200 unmodified lines | ||
| 1410 | 1411 | __clear_bit(pol->plid, q->blkcg_pols); |
| 1411 | 1412 | |
| 1412 | 1413 | list_for_each_entry(blkg, &q->blkg_list, q_node) { |
| 1413 | − /* grab blkcg lock too while removing @pd from @blkg */ | |
| 1414 | − spin_lock(&blkg->blkcg->lock); | |
| 1415 | − | |
| 1416 | 1414 | if (blkg->pd[pol->plid]) { |
| 1417 | 1415 | if (!blkg->pd[pol->plid]->offline && |
| 1418 | 1416 | pol->pd_offline_fn) { |
| @@ -1422,8 +1420,6 @@ void blkcg_deactivate_policy(struct request_queue *q, · 3 unmodified lines | ||
| 1422 | 1420 | pol->pd_free_fn(blkg->pd[pol->plid]); |
| 1423 | 1421 | blkg->pd[pol->plid] = NULL; |
| 1424 | 1422 | } |
| 1425 | − | |
| 1426 | − spin_unlock(&blkg->blkcg->lock); | |
| 1427 | 1423 | } |
| 1428 | 1424 | |
| 1429 | 1425 | spin_unlock_irq(q->queue_lock); |
| @@ -201,6 +201,10 @@ void blk_rq_init(struct request_queue *q, struct request *rq) · 200 unmodified lines | ||
| 201 | 201 | rq->part = NULL; |
| 202 | 202 | seqcount_init(&rq->gstate_seq); |
| 203 | 203 | u64_stats_init(&rq->aborted_gstate_sync); |
| 204 | + /* | |
| 205 | + * See comment of blk_mq_init_request | |
| 206 | + */ | |
| 207 | + WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC); | |
| 204 | 208 | } |
| 205 | 209 | EXPORT_SYMBOL(blk_rq_init); |
| 206 | 210 | |
| @@ -915,7 +919,6 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) · 708 unmodified lines | ||
| 915 | 919 | |
| 916 | 920 | while (true) { |
| 917 | 921 | bool success = false; |
| 918 | − int ret; | |
| 919 | 922 | |
| 920 | 923 | rcu_read_lock(); |
| 921 | 924 | if (percpu_ref_tryget_live(&q->q_usage_counter)) { |
| @@ -947,14 +950,12 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) · 25 unmodified lines | ||
| 947 | 950 | */ |
| 948 | 951 | smp_rmb(); |
| 949 | 952 | |
| 950 | − ret = wait_event_interruptible(q->mq_freeze_wq, | |
| 951 | − (atomic_read(&q->mq_freeze_depth) == 0 && | |
| 952 | − (preempt || !blk_queue_preempt_only(q))) || | |
| 953 | − blk_queue_dying(q)); | |
| 953 | + wait_event(q->mq_freeze_wq, | |
| 954 | + (atomic_read(&q->mq_freeze_depth) == 0 && | |
| 955 | + (preempt || !blk_queue_preempt_only(q))) || | |
| 956 | + blk_queue_dying(q)); | |
| 954 | 957 | if (blk_queue_dying(q)) |
| 955 | 958 | return -ENODEV; |
| 956 | − if (ret) | |
| 957 | − return ret; | |
| 958 | 959 | } |
| 959 | 960 | } |
| 960 | 961 | |
| @@ -95,18 +95,15 @@ static void blk_mq_check_inflight(struct blk_mq_hw_ctx *hctx, · 94 unmodified lines | ||
| 95 | 95 | { |
| 96 | 96 | struct mq_inflight *mi = priv; |
| 97 | 97 | |
| 98 | − if (blk_mq_rq_state(rq) == MQ_RQ_IN_FLIGHT) { | |
| 99 | − /* | |
| 100 | − * index[0] counts the specific partition that was asked | |
| 101 | − * for. index[1] counts the ones that are active on the | |
| 102 | − * whole device, so increment that if mi->part is indeed | |
| 103 | − * a partition, and not a whole device. | |
| 104 | − */ | |
| 105 | − if (rq->part == mi->part) | |
| 106 | − mi->inflight[0]++; | |
| 107 | − if (mi->part->partno) | |
| 108 | − mi->inflight[1]++; | |
| 109 | − } | |
| 98 | + /* | |
| 99 | + * index[0] counts the specific partition that was asked for. index[1] | |
| 100 | + * counts the ones that are active on the whole device, so increment | |
| 101 | + * that if mi->part is indeed a partition, and not a whole device. | |
| 102 | + */ | |
| 103 | + if (rq->part == mi->part) | |
| 104 | + mi->inflight[0]++; | |
| 105 | + if (mi->part->partno) | |
| 106 | + mi->inflight[1]++; | |
| 110 | 107 | } |
| 111 | 108 | |
| 112 | 109 | void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, |
| @@ -118,6 +115,25 @@ void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, · 5 unmodified lines | ||
| 118 | 115 | blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi); |
| 119 | 116 | } |
| 120 | 117 | |
| 118 | +static void blk_mq_check_inflight_rw(struct blk_mq_hw_ctx *hctx, | |
| 119 | + struct request *rq, void *priv, | |
| 120 | + bool reserved) | |
| 121 | +{ | |
| 122 | + struct mq_inflight *mi = priv; | |
| 123 | + | |
| 124 | + if (rq->part == mi->part) | |
| 125 | + mi->inflight[rq_data_dir(rq)]++; | |
| 126 | +} | |
| 127 | + | |
| 128 | +void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part, | |
| 129 | + unsigned int inflight[2]) | |
| 130 | +{ | |
| 131 | + struct mq_inflight mi = { .part = part, .inflight = inflight, }; | |
| 132 | + | |
| 133 | + inflight[0] = inflight[1] = 0; | |
| 134 | + blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight_rw, &mi); | |
| 135 | +} | |
| 136 | + | |
| 121 | 137 | void blk_freeze_queue_start(struct request_queue *q) |
| 122 | 138 | { |
| 123 | 139 | int freeze_depth; |
| @@ -2042,6 +2058,13 @@ static int blk_mq_init_request(struct blk_mq_tag_set *set, struct request *rq, · 1918 unmodified lines | ||
| 2042 | 2058 | |
| 2043 | 2059 | seqcount_init(&rq->gstate_seq); |
| 2044 | 2060 | u64_stats_init(&rq->aborted_gstate_sync); |
| 2061 | + /* | |
| 2062 | + * start gstate with gen 1 instead of 0, otherwise it will be equal | |
| 2063 | + * to aborted_gstate, and be identified timed out by | |
| 2064 | + * blk_mq_terminate_expired. | |
| 2065 | + */ | |
| 2066 | + WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC); | |
| 2067 | + | |
| 2045 | 2068 | return 0; |
| 2046 | 2069 | } |
| 2047 | 2070 | |
| @@ -2329,7 +2352,7 @@ static void blk_mq_free_map_and_requests(struct blk_mq_tag_set *set, · 281 unmodified lines | ||
| 2329 | 2352 | |
| 2330 | 2353 | static void blk_mq_map_swqueue(struct request_queue *q) |
| 2331 | 2354 | { |
| 2332 | − unsigned int i; | |
| 2355 | + unsigned int i, hctx_idx; | |
| 2333 | 2356 | struct blk_mq_hw_ctx *hctx; |
| 2334 | 2357 | struct blk_mq_ctx *ctx; |
| 2335 | 2358 | struct blk_mq_tag_set *set = q->tag_set; |
| @@ -2346,8 +2369,23 @@ static void blk_mq_map_swqueue(struct request_queue *q) · 10 unmodified lines | ||
| 2346 | 2369 | |
| 2347 | 2370 | /* |
| 2348 | 2371 | * Map software to hardware queues. |
| 2372 | + * | |
| 2373 | + * If the cpu isn't present, the cpu is mapped to first hctx. | |
| 2349 | 2374 | */ |
| 2350 | 2375 | for_each_possible_cpu(i) { |
| 2376 | + hctx_idx = q->mq_map[i]; | |
| 2377 | + /* unmapped hw queue can be remapped after CPU topo changed */ | |
| 2378 | + if (!set->tags[hctx_idx] && | |
| 2379 | + !__blk_mq_alloc_rq_map(set, hctx_idx)) { | |
| 2380 | + /* | |
| 2381 | + * If tags initialization fail for some hctx, | |
| 2382 | + * that hctx won't be brought online. In this | |
| 2383 | + * case, remap the current ctx to hctx[0] which | |
| 2384 | + * is guaranteed to always have tags allocated | |
| 2385 | + */ | |
| 2386 | + q->mq_map[i] = 0; | |
| 2387 | + } | |
| 2388 | + | |
| 2351 | 2389 | ctx = per_cpu_ptr(q->queue_ctx, i); |
| 2352 | 2390 | hctx = blk_mq_map_queue(q, i); |
| 2353 | 2391 | |
| @@ -2359,8 +2397,21 @@ static void blk_mq_map_swqueue(struct request_queue *q) · 5 unmodified lines | ||
| 2359 | 2397 | mutex_unlock(&q->sysfs_lock); |
| 2360 | 2398 | |
| 2361 | 2399 | queue_for_each_hw_ctx(q, hctx, i) { |
| 2362 | − /* every hctx should get mapped by at least one CPU */ | |
| 2363 | − WARN_ON(!hctx->nr_ctx); | |
| 2400 | + /* | |
| 2401 | + * If no software queues are mapped to this hardware queue, | |
| 2402 | + * disable it and free the request entries. | |
| 2403 | + */ | |
| 2404 | + if (!hctx->nr_ctx) { | |
| 2405 | + /* Never unmap queue 0. We need it as a | |
| 2406 | + * fallback in case of a new remap fails | |
| 2407 | + * allocation | |
| 2408 | + */ | |
| 2409 | + if (i && set->tags[i]) | |
| 2410 | + blk_mq_free_map_and_requests(set, i); | |
| 2411 | + | |
| 2412 | + hctx->tags = NULL; | |
| 2413 | + continue; | |
| 2414 | + } | |
| 2364 | 2415 | |
| 2365 | 2416 | hctx->tags = set->tags[i]; |
| 2366 | 2417 | WARN_ON(!hctx->tags); |
| @@ -7,6 +7,9 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | struct blk_mq_tag_set; |
| 9 | 9 | |
| 10 | +/** | |
| 11 | + * struct blk_mq_ctx - State for a software queue facing the submitting CPUs | |
| 12 | + */ | |
| 10 | 13 | struct blk_mq_ctx { |
| 11 | 14 | struct { |
| 12 | 15 | spinlock_t lock; |
| @@ -185,7 +188,9 @@ static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx) · 172 unmodified lines | ||
| 185 | 188 | } |
| 186 | 189 | |
| 187 | 190 | void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part, |
| 188 | − unsigned int inflight[2]); | |
| 191 | + unsigned int inflight[2]); | |
| 192 | +void blk_mq_in_flight_rw(struct request_queue *q, struct hd_struct *part, | |
| 193 | + unsigned int inflight[2]); | |
| 189 | 194 | |
| 190 | 195 | static inline void blk_mq_put_dispatch_budget(struct blk_mq_hw_ctx *hctx) |
| 191 | 196 | { |
| @@ -82,6 +82,18 @@ void part_in_flight(struct request_queue *q, struct hd_struct *part, · 81 unmodified lines | ||
| 82 | 82 | } |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | +void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, | |
| 86 | + unsigned int inflight[2]) | |
| 87 | +{ | |
| 88 | + if (q->mq_ops) { | |
| 89 | + blk_mq_in_flight_rw(q, part, inflight); | |
| 90 | + return; | |
| 91 | + } | |
| 92 | + | |
| 93 | + inflight[0] = atomic_read(&part->in_flight[0]); | |
| 94 | + inflight[1] = atomic_read(&part->in_flight[1]); | |
| 95 | +} | |
| 96 | + | |
| 85 | 97 | struct hd_struct *__disk_get_part(struct gendisk *disk, int partno) |
| 86 | 98 | { |
| 87 | 99 | struct disk_part_tbl *ptbl = rcu_dereference(disk->part_tbl); |
| @@ -145,13 +145,15 @@ ssize_t part_stat_show(struct device *dev, · 144 unmodified lines | ||
| 145 | 145 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | −ssize_t part_inflight_show(struct device *dev, | |
| 149 | − struct device_attribute *attr, char *buf) | |
| 148 | +ssize_t part_inflight_show(struct device *dev, struct device_attribute *attr, | |
| 149 | + char *buf) | |
| 150 | 150 | { |
| 151 | 151 | struct hd_struct *p = dev_to_part(dev); |
| 152 | + struct request_queue *q = part_to_disk(p)->queue; | |
| 153 | + unsigned int inflight[2]; | |
| 152 | 154 | |
| 153 | − return sprintf(buf, "%8u %8u\n", atomic_read(&p->in_flight[0]), | |
| 154 | − atomic_read(&p->in_flight[1])); | |
| 155 | + part_in_flight_rw(q, p, inflight); | |
| 156 | + return sprintf(buf, "%8u %8u\n", inflight[0], inflight[1]); | |
| 155 | 157 | } |
| 156 | 158 | |
| 157 | 159 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| @@ -204,9 +204,14 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, · 203 unmodified lines | ||
| 204 | 204 | |
| 205 | 205 | down_read(&crypto_alg_sem); |
| 206 | 206 | alg = __crypto_alg_lookup(name, type | test, mask | test); |
| 207 | − if (!alg && test) | |
| 208 | − alg = __crypto_alg_lookup(name, type, mask) ? | |
| 209 | − ERR_PTR(-ELIBBAD) : NULL; | |
| 207 | + if (!alg && test) { | |
| 208 | + alg = __crypto_alg_lookup(name, type, mask); | |
| 209 | + if (alg && !crypto_is_larval(alg)) { | |
| 210 | + /* Test failed */ | |
| 211 | + crypto_mod_put(alg); | |
| 212 | + alg = ERR_PTR(-ELIBBAD); | |
| 213 | + } | |
| 214 | + } | |
| 210 | 215 | up_read(&crypto_alg_sem); |
| 211 | 216 | |
| 212 | 217 | return alg; |
| @@ -1134,8 +1134,10 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg) · 1133 unmodified lines | ||
| 1134 | 1134 | if (!drbg) |
| 1135 | 1135 | return; |
| 1136 | 1136 | kzfree(drbg->Vbuf); |
| 1137 | + drbg->Vbuf = NULL; | |
| 1137 | 1138 | drbg->V = NULL; |
| 1138 | 1139 | kzfree(drbg->Cbuf); |
| 1140 | + drbg->Cbuf = NULL; | |
| 1139 | 1141 | drbg->C = NULL; |
| 1140 | 1142 | kzfree(drbg->scratchpadbuf); |
| 1141 | 1143 | drbg->scratchpadbuf = NULL; |
| @@ -2123,6 +2123,25 @@ static int __init intel_opregion_present(void) · 2122 unmodified lines | ||
| 2123 | 2123 | return opregion; |
| 2124 | 2124 | } |
| 2125 | 2125 | |
| 2126 | +static bool dmi_is_desktop(void) | |
| 2127 | +{ | |
| 2128 | + const char *chassis_type; | |
| 2129 | + | |
| 2130 | + chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); | |
| 2131 | + if (!chassis_type) | |
| 2132 | + return false; | |
| 2133 | + | |
| 2134 | + if (!strcmp(chassis_type, "3") || /* 3: Desktop */ | |
| 2135 | + !strcmp(chassis_type, "4") || /* 4: Low Profile Desktop */ | |
| 2136 | + !strcmp(chassis_type, "5") || /* 5: Pizza Box */ | |
| 2137 | + !strcmp(chassis_type, "6") || /* 6: Mini Tower */ | |
| 2138 | + !strcmp(chassis_type, "7") || /* 7: Tower */ | |
| 2139 | + !strcmp(chassis_type, "11")) /* 11: Main Server Chassis */ | |
| 2140 | + return true; | |
| 2141 | + | |
| 2142 | + return false; | |
| 2143 | +} | |
| 2144 | + | |
| 2126 | 2145 | int acpi_video_register(void) |
| 2127 | 2146 | { |
| 2128 | 2147 | int ret = 0; |
| @@ -2143,8 +2162,12 @@ int acpi_video_register(void) · 14 unmodified lines | ||
| 2143 | 2162 | * win8 ready (where we also prefer the native backlight driver, so |
| 2144 | 2163 | * normally the acpi_video code should not register there anyways). |
| 2145 | 2164 | */ |
| 2146 | − if (only_lcd == -1) | |
| 2147 | − only_lcd = acpi_osi_is_win8(); | |
| 2165 | + if (only_lcd == -1) { | |
| 2166 | + if (dmi_is_desktop() && acpi_osi_is_win8()) | |
| 2167 | + only_lcd = true; | |
| 2168 | + else | |
| 2169 | + only_lcd = false; | |
| 2170 | + } | |
| 2148 | 2171 | |
| 2149 | 2172 | dmi_check_system(video_dmi_table); |
| 2150 | 2173 | |
| @@ -12,23 +12,64 @@ · 11 unmodified lines | ||
| 12 | 12 | #define pr_fmt(fmt) "ACPI: watchdog: " fmt |
| 13 | 13 | |
| 14 | 14 | #include <linux/acpi.h> |
| 15 | +#include <linux/dmi.h> | |
| 15 | 16 | #include <linux/ioport.h> |
| 16 | 17 | #include <linux/platform_device.h> |
| 17 | 18 | |
| 18 | 19 | #include "internal.h" |
| 19 | 20 | |
| 21 | +static const struct dmi_system_id acpi_watchdog_skip[] = { | |
| 22 | + { | |
| 23 | + /* | |
| 24 | + * On Lenovo Z50-70 there are two issues with the WDAT | |
| 25 | + * table. First some of the instructions use RTC SRAM | |
| 26 | + * to store persistent information. This does not work well | |
| 27 | + * with Linux RTC driver. Second, more important thing is | |
| 28 | + * that the instructions do not actually reset the system. | |
| 29 | + * | |
| 30 | + * On this particular system iTCO_wdt seems to work just | |
| 31 | + * fine so we prefer that over WDAT for now. | |
| 32 | + * | |
| 33 | + * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. | |
| 34 | + */ | |
| 35 | + .ident = "Lenovo Z50-70", | |
| 36 | + .matches = { | |
| 37 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 38 | + DMI_MATCH(DMI_PRODUCT_NAME, "20354"), | |
| 39 | + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"), | |
| 40 | + }, | |
| 41 | + }, | |
| 42 | + {} | |
| 43 | +}; | |
| 44 | + | |
| 45 | +static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) | |
| 46 | +{ | |
| 47 | + const struct acpi_table_wdat *wdat = NULL; | |
| 48 | + acpi_status status; | |
| 49 | + | |
| 50 | + if (acpi_disabled) | |
| 51 | + return NULL; | |
| 52 | + | |
| 53 | + if (dmi_check_system(acpi_watchdog_skip)) | |
| 54 | + return NULL; | |
| 55 | + | |
| 56 | + status = acpi_get_table(ACPI_SIG_WDAT, 0, | |
| 57 | + (struct acpi_table_header **)&wdat); | |
| 58 | + if (ACPI_FAILURE(status)) { | |
| 59 | + /* It is fine if there is no WDAT */ | |
| 60 | + return NULL; | |
| 61 | + } | |
| 62 | + | |
| 63 | + return wdat; | |
| 64 | +} | |
| 65 | + | |
| 20 | 66 | /** |
| 21 | 67 | * Returns true if this system should prefer ACPI based watchdog instead of |
| 22 | 68 | * the native one (which are typically the same hardware). |
| 23 | 69 | */ |
| 24 | 70 | bool acpi_has_watchdog(void) |
| 25 | 71 | { |
| 26 | − struct acpi_table_header hdr; | |
| 27 | − | |
| 28 | − if (acpi_disabled) | |
| 29 | − return false; | |
| 30 | − | |
| 31 | − return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr)); | |
| 72 | + return !!acpi_watchdog_get_wdat(); | |
| 32 | 73 | } |
| 33 | 74 | EXPORT_SYMBOL_GPL(acpi_has_watchdog); |
| 34 | 75 | |
| @@ -41,12 +82,10 @@ void __init acpi_watchdog_init(void) · 6 unmodified lines | ||
| 41 | 82 | struct platform_device *pdev; |
| 42 | 83 | struct resource *resources; |
| 43 | 84 | size_t nresources = 0; |
| 44 | − acpi_status status; | |
| 45 | 85 | int i; |
| 46 | 86 | |
| 47 | − status = acpi_get_table(ACPI_SIG_WDAT, 0, | |
| 48 | − (struct acpi_table_header **)&wdat); | |
| 49 | − if (ACPI_FAILURE(status)) { | |
| 87 | + wdat = acpi_watchdog_get_wdat(); | |
| 88 | + if (!wdat) { | |
| 50 | 89 | /* It is fine if there is no WDAT */ |
| 51 | 90 | return; |
| 52 | 91 | } |
| @@ -635,4 +635,26 @@ module_param_call(lid_init_state, · 634 unmodified lines | ||
| 635 | 635 | NULL, 0644); |
| 636 | 636 | MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state"); |
| 637 | 637 | |
| 638 | −module_acpi_driver(acpi_button_driver); | |
| 638 | +static int acpi_button_register_driver(struct acpi_driver *driver) | |
| 639 | +{ | |
| 640 | + /* | |
| 641 | + * Modules such as nouveau.ko and i915.ko have a link time dependency | |
| 642 | + * on acpi_lid_open(), and would therefore not be loadable on ACPI | |
| 643 | + * capable kernels booted in non-ACPI mode if the return value of | |
| 644 | + * acpi_bus_register_driver() is returned from here with ACPI disabled | |
| 645 | + * when this driver is built as a module. | |
| 646 | + */ | |
| 647 | + if (acpi_disabled) | |
| 648 | + return 0; | |
| 649 | + | |
| 650 | + return acpi_bus_register_driver(driver); | |
| 651 | +} | |
| 652 | + | |
| 653 | +static void acpi_button_unregister_driver(struct acpi_driver *driver) | |
| 654 | +{ | |
| 655 | + if (!acpi_disabled) | |
| 656 | + acpi_bus_unregister_driver(driver); | |
| 657 | +} | |
| 658 | + | |
| 659 | +module_driver(acpi_button_driver, acpi_button_register_driver, | |
| 660 | + acpi_button_unregister_driver); | |
| @@ -2166,10 +2166,10 @@ int __init acpi_scan_init(void) · 2165 unmodified lines | ||
| 2166 | 2166 | acpi_cmos_rtc_init(); |
| 2167 | 2167 | acpi_container_init(); |
| 2168 | 2168 | acpi_memory_hotplug_init(); |
| 2169 | + acpi_watchdog_init(); | |
| 2169 | 2170 | acpi_pnp_init(); |
| 2170 | 2171 | acpi_int340x_thermal_init(); |
| 2171 | 2172 | acpi_amba_init(); |
| 2172 | − acpi_watchdog_init(); | |
| 2173 | 2173 | acpi_init_lpit(); |
| 2174 | 2174 | |
| 2175 | 2175 | acpi_scan_add_handler(&generic_device_handler); |
| @@ -364,6 +364,19 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { · 363 unmodified lines | ||
| 364 | 364 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"), |
| 365 | 365 | }, |
| 366 | 366 | }, |
| 367 | + /* | |
| 368 | + * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using | |
| 369 | + * the Low Power S0 Idle firmware interface (see | |
| 370 | + * https://bugzilla.kernel.org/show_bug.cgi?id=199057). | |
| 371 | + */ | |
| 372 | + { | |
| 373 | + .callback = init_no_lps0, | |
| 374 | + .ident = "ThinkPad X1 Tablet(2016)", | |
| 375 | + .matches = { | |
| 376 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 377 | + DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"), | |
| 378 | + }, | |
| 379 | + }, | |
| 367 | 380 | {}, |
| 368 | 381 | }; |
| 369 | 382 | |
| @@ -69,11 +69,12 @@ static ssize_t driver_override_show(struct device *_dev, · 68 unmodified lines | ||
| 69 | 69 | struct device_attribute *attr, char *buf) |
| 70 | 70 | { |
| 71 | 71 | struct amba_device *dev = to_amba_device(_dev); |
| 72 | + ssize_t len; | |
| 72 | 73 | |
| 73 | − if (!dev->driver_override) | |
| 74 | − return 0; | |
| 75 | − | |
| 76 | − return sprintf(buf, "%s\n", dev->driver_override); | |
| 74 | + device_lock(_dev); | |
| 75 | + len = sprintf(buf, "%s\n", dev->driver_override); | |
| 76 | + device_unlock(_dev); | |
| 77 | + return len; | |
| 77 | 78 | } |
| 78 | 79 | |
| 79 | 80 | static ssize_t driver_override_store(struct device *_dev, |
| @@ -81,9 +82,10 @@ static ssize_t driver_override_store(struct device *_dev, · 1 unmodified line | ||
| 81 | 82 | const char *buf, size_t count) |
| 82 | 83 | { |
| 83 | 84 | struct amba_device *dev = to_amba_device(_dev); |
| 84 | − char *driver_override, *old = dev->driver_override, *cp; | |
| 85 | + char *driver_override, *old, *cp; | |
| 85 | 86 | |
| 86 | − if (count > PATH_MAX) | |
| 87 | + /* We need to keep extra room for a newline */ | |
| 88 | + if (count >= (PAGE_SIZE - 1)) | |
| 87 | 89 | return -EINVAL; |
| 88 | 90 | |
| 89 | 91 | driver_override = kstrndup(buf, count, GFP_KERNEL); |
| @@ -94,12 +96,15 @@ static ssize_t driver_override_store(struct device *_dev, · 4 unmodified lines | ||
| 94 | 96 | if (cp) |
| 95 | 97 | *cp = '\0'; |
| 96 | 98 | |
| 99 | + device_lock(_dev); | |
| 100 | + old = dev->driver_override; | |
| 97 | 101 | if (strlen(driver_override)) { |
| 98 | 102 | dev->driver_override = driver_override; |
| 99 | 103 | } else { |
| 100 | 104 | kfree(driver_override); |
| 101 | 105 | dev->driver_override = NULL; |
| 102 | 106 | } |
| 107 | + device_unlock(_dev); | |
| 103 | 108 | |
| 104 | 109 | kfree(old); |
| 105 | 110 | |
| @@ -2839,6 +2839,14 @@ static void binder_transaction(struct binder_proc *proc, · 2838 unmodified lines | ||
| 2839 | 2839 | else |
| 2840 | 2840 | return_error = BR_DEAD_REPLY; |
| 2841 | 2841 | mutex_unlock(&context->context_mgr_node_lock); |
| 2842 | + if (target_node && target_proc == proc) { | |
| 2843 | + binder_user_error("%d:%d got transaction to context manager from process owning it\n", | |
| 2844 | + proc->pid, thread->pid); | |
| 2845 | + return_error = BR_FAILED_REPLY; | |
| 2846 | + return_error_param = -EINVAL; | |
| 2847 | + return_error_line = __LINE__; | |
| 2848 | + goto err_invalid_target_handle; | |
| 2849 | + } | |
| 2842 | 2850 | } |
| 2843 | 2851 | if (!target_node) { |
| 2844 | 2852 | /* |
| @@ -671,7 +671,7 @@ static void ia_tx_poll (IADEV *iadev) { · 670 unmodified lines | ||
| 671 | 671 | if ((vcc->pop) && (skb1->len != 0)) |
| 672 | 672 | { |
| 673 | 673 | vcc->pop(vcc, skb1); |
| 674 | − IF_EVENT(printk("Tansmit Done - skb 0x%lx return\n", | |
| 674 | + IF_EVENT(printk("Transmit Done - skb 0x%lx return\n", | |
| 675 | 675 | (long)skb1);) |
| 676 | 676 | } |
| 677 | 677 | else |
| @@ -1665,7 +1665,7 @@ static void tx_intr(struct atm_dev *dev) · 987 unmodified lines | ||
| 1665 | 1665 | status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG); |
| 1666 | 1666 | if (status & TRANSMIT_DONE){ |
| 1667 | 1667 | |
| 1668 | − IF_EVENT(printk("Tansmit Done Intr logic run\n");) | |
| 1668 | + IF_EVENT(printk("Transmit Done Intr logic run\n");) | |
| 1669 | 1669 | spin_lock_irqsave(&iadev->tx_lock, flags); |
| 1670 | 1670 | ia_tx_poll(iadev); |
| 1671 | 1671 | spin_unlock_irqrestore(&iadev->tx_lock, flags); |
| @@ -312,8 +312,9 @@ static int __dma_mmap_from_coherent(struct dma_coherent_mem *mem, · 311 unmodified lines | ||
| 312 | 312 | * This checks whether the memory was allocated from the per-device |
| 313 | 313 | * coherent memory pool and if so, maps that memory to the provided vma. |
| 314 | 314 | * |
| 315 | − * Returns 1 if we correctly mapped the memory, or 0 if the caller should | |
| 316 | − * proceed with mapping memory from generic pools. | |
| 315 | + * Returns 1 if @vaddr belongs to the device coherent pool and the caller | |
| 316 | + * should return @ret, or 0 if they should proceed with mapping memory from | |
| 317 | + * generic areas. | |
| 317 | 318 | */ |
| 318 | 319 | int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma, |
| 319 | 320 | void *vaddr, size_t size, int *ret) |
| @@ -226,7 +226,6 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, · 225 unmodified lines | ||
| 226 | 226 | #ifndef CONFIG_ARCH_NO_COHERENT_DMA_MMAP |
| 227 | 227 | unsigned long user_count = vma_pages(vma); |
| 228 | 228 | unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; |
| 229 | − unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr)); | |
| 230 | 229 | unsigned long off = vma->vm_pgoff; |
| 231 | 230 | |
| 232 | 231 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| @@ -234,12 +233,11 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, · 1 unmodified line | ||
| 234 | 233 | if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) |
| 235 | 234 | return ret; |
| 236 | 235 | |
| 237 | − if (off < count && user_count <= (count - off)) { | |
| 236 | + if (off < count && user_count <= (count - off)) | |
| 238 | 237 | ret = remap_pfn_range(vma, vma->vm_start, |
| 239 | − pfn + off, | |
| 238 | + page_to_pfn(virt_to_page(cpu_addr)) + off, | |
| 240 | 239 | user_count << PAGE_SHIFT, |
| 241 | 240 | vma->vm_page_prot); |
| 242 | − } | |
| 243 | 241 | #endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */ |
| 244 | 242 | |
| 245 | 243 | return ret; |
| @@ -537,8 +537,8 @@ exit: · 536 unmodified lines | ||
| 537 | 537 | } |
| 538 | 538 | |
| 539 | 539 | /** |
| 540 | − * fw_load_sysfs_fallback - load a firmware via the syfs fallback mechanism | |
| 541 | − * @fw_sysfs: firmware syfs information for the firmware to load | |
| 540 | + * fw_load_sysfs_fallback - load a firmware via the sysfs fallback mechanism | |
| 541 | + * @fw_sysfs: firmware sysfs information for the firmware to load | |
| 542 | 542 | * @opt_flags: flags of options, FW_OPT_* |
| 543 | 543 | * @timeout: timeout to wait for the load |
| 544 | 544 | * |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/device.h> |
| 7 | 7 | |
| 8 | 8 | /** |
| 9 | − * struct firmware_fallback_config - firmware fallback configuratioon settings | |
| 9 | + * struct firmware_fallback_config - firmware fallback configuration settings | |
| 10 | 10 | * |
| 11 | 11 | * Helps describe and fine tune the fallback mechanism. |
| 12 | 12 | * |
| @@ -451,25 +451,47 @@ static int lo_req_flush(struct loop_device *lo, struct request *rq) · 450 unmodified lines | ||
| 451 | 451 | static void lo_complete_rq(struct request *rq) |
| 452 | 452 | { |
| 453 | 453 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); |
| 454 | + blk_status_t ret = BLK_STS_OK; | |
| 454 | 455 | |
| 455 | − if (unlikely(req_op(cmd->rq) == REQ_OP_READ && cmd->use_aio && | |
| 456 | − cmd->ret >= 0 && cmd->ret < blk_rq_bytes(cmd->rq))) { | |
| 457 | − struct bio *bio = cmd->rq->bio; | |
| 458 | − | |
| 459 | − bio_advance(bio, cmd->ret); | |
| 460 | − zero_fill_bio(bio); | |
| 456 | + if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) || | |
| 457 | + req_op(rq) != REQ_OP_READ) { | |
| 458 | + if (cmd->ret < 0) | |
| 459 | + ret = BLK_STS_IOERR; | |
| 460 | + goto end_io; | |
| 461 | 461 | } |
| 462 | 462 | |
| 463 | − blk_mq_end_request(rq, cmd->ret < 0 ? BLK_STS_IOERR : BLK_STS_OK); | |
| 463 | + /* | |
| 464 | + * Short READ - if we got some data, advance our request and | |
| 465 | + * retry it. If we got no data, end the rest with EIO. | |
| 466 | + */ | |
| 467 | + if (cmd->ret) { | |
| 468 | + blk_update_request(rq, BLK_STS_OK, cmd->ret); | |
| 469 | + cmd->ret = 0; | |
| 470 | + blk_mq_requeue_request(rq, true); | |
| 471 | + } else { | |
| 472 | + if (cmd->use_aio) { | |
| 473 | + struct bio *bio = rq->bio; | |
| 474 | + | |
| 475 | + while (bio) { | |
| 476 | + zero_fill_bio(bio); | |
| 477 | + bio = bio->bi_next; | |
| 478 | + } | |
| 479 | + } | |
| 480 | + ret = BLK_STS_IOERR; | |
| 481 | +end_io: | |
| 482 | + blk_mq_end_request(rq, ret); | |
| 483 | + } | |
| 464 | 484 | } |
| 465 | 485 | |
| 466 | 486 | static void lo_rw_aio_do_completion(struct loop_cmd *cmd) |
| 467 | 487 | { |
| 488 | + struct request *rq = blk_mq_rq_from_pdu(cmd); | |
| 489 | + | |
| 468 | 490 | if (!atomic_dec_and_test(&cmd->ref)) |
| 469 | 491 | return; |
| 470 | 492 | kfree(cmd->bvec); |
| 471 | 493 | cmd->bvec = NULL; |
| 472 | − blk_mq_complete_request(cmd->rq); | |
| 494 | + blk_mq_complete_request(rq); | |
| 473 | 495 | } |
| 474 | 496 | |
| 475 | 497 | static void lo_rw_aio_complete(struct kiocb *iocb, long ret, long ret2) |
| @@ -487,7 +509,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, · 11 unmodified lines | ||
| 487 | 509 | { |
| 488 | 510 | struct iov_iter iter; |
| 489 | 511 | struct bio_vec *bvec; |
| 490 | − struct request *rq = cmd->rq; | |
| 512 | + struct request *rq = blk_mq_rq_from_pdu(cmd); | |
| 491 | 513 | struct bio *bio = rq->bio; |
| 492 | 514 | struct file *file = lo->lo_backing_file; |
| 493 | 515 | unsigned int offset; |
| @@ -1702,15 +1724,16 @@ EXPORT_SYMBOL(loop_unregister_transfer); · 1208 unmodified lines | ||
| 1702 | 1724 | static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx, |
| 1703 | 1725 | const struct blk_mq_queue_data *bd) |
| 1704 | 1726 | { |
| 1705 | − struct loop_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); | |
| 1706 | − struct loop_device *lo = cmd->rq->q->queuedata; | |
| 1727 | + struct request *rq = bd->rq; | |
| 1728 | + struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); | |
| 1729 | + struct loop_device *lo = rq->q->queuedata; | |
| 1707 | 1730 | |
| 1708 | − blk_mq_start_request(bd->rq); | |
| 1731 | + blk_mq_start_request(rq); | |
| 1709 | 1732 | |
| 1710 | 1733 | if (lo->lo_state != Lo_bound) |
| 1711 | 1734 | return BLK_STS_IOERR; |
| 1712 | 1735 | |
| 1713 | − switch (req_op(cmd->rq)) { | |
| 1736 | + switch (req_op(rq)) { | |
| 1714 | 1737 | case REQ_OP_FLUSH: |
| 1715 | 1738 | case REQ_OP_DISCARD: |
| 1716 | 1739 | case REQ_OP_WRITE_ZEROES: |
| @@ -1723,8 +1746,8 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx, · 6 unmodified lines | ||
| 1723 | 1746 | |
| 1724 | 1747 | /* always use the first bio's css */ |
| 1725 | 1748 | #ifdef CONFIG_BLK_CGROUP |
| 1726 | − if (cmd->use_aio && cmd->rq->bio && cmd->rq->bio->bi_css) { | |
| 1727 | − cmd->css = cmd->rq->bio->bi_css; | |
| 1749 | + if (cmd->use_aio && rq->bio && rq->bio->bi_css) { | |
| 1750 | + cmd->css = rq->bio->bi_css; | |
| 1728 | 1751 | css_get(cmd->css); |
| 1729 | 1752 | } else |
| 1730 | 1753 | #endif |
| @@ -1736,8 +1759,9 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx, · 5 unmodified lines | ||
| 1736 | 1759 | |
| 1737 | 1760 | static void loop_handle_cmd(struct loop_cmd *cmd) |
| 1738 | 1761 | { |
| 1739 | − const bool write = op_is_write(req_op(cmd->rq)); | |
| 1740 | − struct loop_device *lo = cmd->rq->q->queuedata; | |
| 1762 | + struct request *rq = blk_mq_rq_from_pdu(cmd); | |
| 1763 | + const bool write = op_is_write(req_op(rq)); | |
| 1764 | + struct loop_device *lo = rq->q->queuedata; | |
| 1741 | 1765 | int ret = 0; |
| 1742 | 1766 | |
| 1743 | 1767 | if (write && (lo->lo_flags & LO_FLAGS_READ_ONLY)) { |
| @@ -1745,12 +1769,12 @@ static void loop_handle_cmd(struct loop_cmd *cmd) · 1 unmodified line | ||
| 1745 | 1769 | goto failed; |
| 1746 | 1770 | } |
| 1747 | 1771 | |
| 1748 | − ret = do_req_filebacked(lo, cmd->rq); | |
| 1772 | + ret = do_req_filebacked(lo, rq); | |
| 1749 | 1773 | failed: |
| 1750 | 1774 | /* complete non-aio request */ |
| 1751 | 1775 | if (!cmd->use_aio || ret) { |
| 1752 | 1776 | cmd->ret = ret ? -EIO : 0; |
| 1753 | − blk_mq_complete_request(cmd->rq); | |
| 1777 | + blk_mq_complete_request(rq); | |
| 1754 | 1778 | } |
| 1755 | 1779 | } |
| 1756 | 1780 | |
| @@ -1767,9 +1791,7 @@ static int loop_init_request(struct blk_mq_tag_set *set, struct request *rq, · 10 unmodified lines | ||
| 1767 | 1791 | { |
| 1768 | 1792 | struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq); |
| 1769 | 1793 | |
| 1770 | − cmd->rq = rq; | |
| 1771 | 1794 | kthread_init_work(&cmd->work, loop_queue_work); |
| 1772 | − | |
| 1773 | 1795 | return 0; |
| 1774 | 1796 | } |
| 1775 | 1797 | |
| @@ -66,7 +66,6 @@ struct loop_device { · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | struct loop_cmd { |
| 68 | 68 | struct kthread_work work; |
| 69 | − struct request *rq; | |
| 70 | 69 | bool use_aio; /* use AIO interface to handle I/O */ |
| 71 | 70 | atomic_t ref; /* only for aio */ |
| 72 | 71 | long ret; |
| @@ -732,6 +732,7 @@ static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts) · 731 unmodified lines | ||
| 732 | 732 | */ |
| 733 | 733 | enum { |
| 734 | 734 | Opt_queue_depth, |
| 735 | + Opt_lock_timeout, | |
| 735 | 736 | Opt_last_int, |
| 736 | 737 | /* int args above */ |
| 737 | 738 | Opt_last_string, |
| @@ -740,11 +741,13 @@ enum { · 2 unmodified lines | ||
| 740 | 741 | Opt_read_write, |
| 741 | 742 | Opt_lock_on_read, |
| 742 | 743 | Opt_exclusive, |
| 744 | + Opt_notrim, | |
| 743 | 745 | Opt_err |
| 744 | 746 | }; |
| 745 | 747 | |
| 746 | 748 | static match_table_t rbd_opts_tokens = { |
| 747 | 749 | {Opt_queue_depth, "queue_depth=%d"}, |
| 750 | + {Opt_lock_timeout, "lock_timeout=%d"}, | |
| 748 | 751 | /* int args above */ |
| 749 | 752 | /* string args above */ |
| 750 | 753 | {Opt_read_only, "read_only"}, |
| @@ -753,20 +756,25 @@ static match_table_t rbd_opts_tokens = { · 2 unmodified lines | ||
| 753 | 756 | {Opt_read_write, "rw"}, /* Alternate spelling */ |
| 754 | 757 | {Opt_lock_on_read, "lock_on_read"}, |
| 755 | 758 | {Opt_exclusive, "exclusive"}, |
| 759 | + {Opt_notrim, "notrim"}, | |
| 756 | 760 | {Opt_err, NULL} |
| 757 | 761 | }; |
| 758 | 762 | |
| 759 | 763 | struct rbd_options { |
| 760 | 764 | int queue_depth; |
| 765 | + unsigned long lock_timeout; | |
| 761 | 766 | bool read_only; |
| 762 | 767 | bool lock_on_read; |
| 763 | 768 | bool exclusive; |
| 769 | + bool trim; | |
| 764 | 770 | }; |
| 765 | 771 | |
| 766 | 772 | #define RBD_QUEUE_DEPTH_DEFAULT BLKDEV_MAX_RQ |
| 773 | +#define RBD_LOCK_TIMEOUT_DEFAULT 0 /* no timeout */ | |
| 767 | 774 | #define RBD_READ_ONLY_DEFAULT false |
| 768 | 775 | #define RBD_LOCK_ON_READ_DEFAULT false |
| 769 | 776 | #define RBD_EXCLUSIVE_DEFAULT false |
| 777 | +#define RBD_TRIM_DEFAULT true | |
| 770 | 778 | |
| 771 | 779 | static int parse_rbd_opts_token(char *c, void *private) |
| 772 | 780 | { |
| @@ -796,6 +804,14 @@ static int parse_rbd_opts_token(char *c, void *private) · 23 unmodified lines | ||
| 796 | 804 | } |
| 797 | 805 | rbd_opts->queue_depth = intval; |
| 798 | 806 | break; |
| 807 | + case Opt_lock_timeout: | |
| 808 | + /* 0 is "wait forever" (i.e. infinite timeout) */ | |
| 809 | + if (intval < 0 || intval > INT_MAX / 1000) { | |
| 810 | + pr_err("lock_timeout out of range\n"); | |
| 811 | + return -EINVAL; | |
| 812 | + } | |
| 813 | + rbd_opts->lock_timeout = msecs_to_jiffies(intval * 1000); | |
| 814 | + break; | |
| 799 | 815 | case Opt_read_only: |
| 800 | 816 | rbd_opts->read_only = true; |
| 801 | 817 | break; |
| @@ -808,6 +824,9 @@ static int parse_rbd_opts_token(char *c, void *private) · 6 unmodified lines | ||
| 808 | 824 | case Opt_exclusive: |
| 809 | 825 | rbd_opts->exclusive = true; |
| 810 | 826 | break; |
| 827 | + case Opt_notrim: | |
| 828 | + rbd_opts->trim = false; | |
| 829 | + break; | |
| 811 | 830 | default: |
| 812 | 831 | /* libceph prints "bad option" msg */ |
| 813 | 832 | return -EINVAL; |
| @@ -1392,7 +1411,7 @@ static bool rbd_img_is_write(struct rbd_img_request *img_req) · 578 unmodified lines | ||
| 1392 | 1411 | case OBJ_OP_DISCARD: |
| 1393 | 1412 | return true; |
| 1394 | 1413 | default: |
| 1395 | − rbd_assert(0); | |
| 1414 | + BUG(); | |
| 1396 | 1415 | } |
| 1397 | 1416 | } |
| 1398 | 1417 | |
| @@ -2466,7 +2485,7 @@ again: · 1067 unmodified lines | ||
| 2466 | 2485 | } |
| 2467 | 2486 | return false; |
| 2468 | 2487 | default: |
| 2469 | − rbd_assert(0); | |
| 2488 | + BUG(); | |
| 2470 | 2489 | } |
| 2471 | 2490 | } |
| 2472 | 2491 | |
| @@ -2494,7 +2513,7 @@ static bool __rbd_obj_handle_request(struct rbd_obj_request *obj_req) · 21 unmodified lines | ||
| 2494 | 2513 | } |
| 2495 | 2514 | return false; |
| 2496 | 2515 | default: |
| 2497 | − rbd_assert(0); | |
| 2516 | + BUG(); | |
| 2498 | 2517 | } |
| 2499 | 2518 | } |
| 2500 | 2519 | |
| @@ -3533,9 +3552,22 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, · 1032 unmodified lines | ||
| 3533 | 3552 | /* |
| 3534 | 3553 | * lock_rwsem must be held for read |
| 3535 | 3554 | */ |
| 3536 | −static void rbd_wait_state_locked(struct rbd_device *rbd_dev) | |
| 3555 | +static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire) | |
| 3537 | 3556 | { |
| 3538 | 3557 | DEFINE_WAIT(wait); |
| 3558 | + unsigned long timeout; | |
| 3559 | + int ret = 0; | |
| 3560 | + | |
| 3561 | + if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) | |
| 3562 | + return -EBLACKLISTED; | |
| 3563 | + | |
| 3564 | + if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) | |
| 3565 | + return 0; | |
| 3566 | + | |
| 3567 | + if (!may_acquire) { | |
| 3568 | + rbd_warn(rbd_dev, "exclusive lock required"); | |
| 3569 | + return -EROFS; | |
| 3570 | + } | |
| 3539 | 3571 | |
| 3540 | 3572 | do { |
| 3541 | 3573 | /* |
| @@ -3547,12 +3579,22 @@ static void rbd_wait_state_locked(struct rbd_device *rbd_dev) · 5 unmodified lines | ||
| 3547 | 3579 | prepare_to_wait_exclusive(&rbd_dev->lock_waitq, &wait, |
| 3548 | 3580 | TASK_UNINTERRUPTIBLE); |
| 3549 | 3581 | up_read(&rbd_dev->lock_rwsem); |
| 3550 | − schedule(); | |
| 3582 | + timeout = schedule_timeout(ceph_timeout_jiffies( | |
| 3583 | + rbd_dev->opts->lock_timeout)); | |
| 3551 | 3584 | down_read(&rbd_dev->lock_rwsem); |
| 3552 | − } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED && | |
| 3553 | − !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)); | |
| 3585 | + if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) { | |
| 3586 | + ret = -EBLACKLISTED; | |
| 3587 | + break; | |
| 3588 | + } | |
| 3589 | + if (!timeout) { | |
| 3590 | + rbd_warn(rbd_dev, "timed out waiting for lock"); | |
| 3591 | + ret = -ETIMEDOUT; | |
| 3592 | + break; | |
| 3593 | + } | |
| 3594 | + } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED); | |
| 3554 | 3595 | |
| 3555 | 3596 | finish_wait(&rbd_dev->lock_waitq, &wait); |
| 3597 | + return ret; | |
| 3556 | 3598 | } |
| 3557 | 3599 | |
| 3558 | 3600 | static void rbd_queue_workfn(struct work_struct *work) |
| @@ -3638,19 +3680,10 @@ static void rbd_queue_workfn(struct work_struct *work) · 79 unmodified lines | ||
| 3638 | 3680 | (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read); |
| 3639 | 3681 | if (must_be_locked) { |
| 3640 | 3682 | down_read(&rbd_dev->lock_rwsem); |
| 3641 | − if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED && | |
| 3642 | − !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) { | |
| 3643 | − if (rbd_dev->opts->exclusive) { | |
| 3644 | − rbd_warn(rbd_dev, "exclusive lock required"); | |
| 3645 | − result = -EROFS; | |
| 3646 | − goto err_unlock; | |
| 3647 | − } | |
| 3648 | − rbd_wait_state_locked(rbd_dev); | |
| 3649 | − } | |
| 3650 | − if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) { | |
| 3651 | − result = -EBLACKLISTED; | |
| 3683 | + result = rbd_wait_state_locked(rbd_dev, | |
| 3684 | + !rbd_dev->opts->exclusive); | |
| 3685 | + if (result) | |
| 3652 | 3686 | goto err_unlock; |
| 3653 | − } | |
| 3654 | 3687 | } |
| 3655 | 3688 | |
| 3656 | 3689 | img_request = rbd_img_request_create(rbd_dev, op_type, snapc); |
| @@ -3902,7 +3935,8 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) · 245 unmodified lines | ||
| 3902 | 3935 | { |
| 3903 | 3936 | struct gendisk *disk; |
| 3904 | 3937 | struct request_queue *q; |
| 3905 | − u64 segment_size; | |
| 3938 | + unsigned int objset_bytes = | |
| 3939 | + rbd_dev->layout.object_size * rbd_dev->layout.stripe_count; | |
| 3906 | 3940 | int err; |
| 3907 | 3941 | |
| 3908 | 3942 | /* create gendisk info */ |
| @@ -3942,20 +3976,19 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) · 33 unmodified lines | ||
| 3942 | 3976 | blk_queue_flag_set(QUEUE_FLAG_NONROT, q); |
| 3943 | 3977 | /* QUEUE_FLAG_ADD_RANDOM is off by default for blk-mq */ |
| 3944 | 3978 | |
| 3945 | − /* set io sizes to object size */ | |
| 3946 | − segment_size = rbd_obj_bytes(&rbd_dev->header); | |
| 3947 | − blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE); | |
| 3979 | + blk_queue_max_hw_sectors(q, objset_bytes >> SECTOR_SHIFT); | |
| 3948 | 3980 | q->limits.max_sectors = queue_max_hw_sectors(q); |
| 3949 | 3981 | blk_queue_max_segments(q, USHRT_MAX); |
| 3950 | 3982 | blk_queue_max_segment_size(q, UINT_MAX); |
| 3951 | − blk_queue_io_min(q, segment_size); | |
| 3952 | − blk_queue_io_opt(q, segment_size); | |
| 3983 | + blk_queue_io_min(q, objset_bytes); | |
| 3984 | + blk_queue_io_opt(q, objset_bytes); | |
| 3953 | 3985 | |
| 3954 | − /* enable the discard support */ | |
| 3955 | − blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); | |
| 3956 | − q->limits.discard_granularity = segment_size; | |
| 3957 | − blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE); | |
| 3958 | − blk_queue_max_write_zeroes_sectors(q, segment_size / SECTOR_SIZE); | |
| 3986 | + if (rbd_dev->opts->trim) { | |
| 3987 | + blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); | |
| 3988 | + q->limits.discard_granularity = objset_bytes; | |
| 3989 | + blk_queue_max_discard_sectors(q, objset_bytes >> SECTOR_SHIFT); | |
| 3990 | + blk_queue_max_write_zeroes_sectors(q, objset_bytes >> SECTOR_SHIFT); | |
| 3991 | + } | |
| 3959 | 3992 | |
| 3960 | 3993 | if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC)) |
| 3961 | 3994 | q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; |
| @@ -5179,8 +5212,10 @@ static int rbd_add_parse_args(const char *buf, · 1217 unmodified lines | ||
| 5179 | 5212 | |
| 5180 | 5213 | rbd_opts->read_only = RBD_READ_ONLY_DEFAULT; |
| 5181 | 5214 | rbd_opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT; |
| 5215 | + rbd_opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT; | |
| 5182 | 5216 | rbd_opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT; |
| 5183 | 5217 | rbd_opts->exclusive = RBD_EXCLUSIVE_DEFAULT; |
| 5218 | + rbd_opts->trim = RBD_TRIM_DEFAULT; | |
| 5184 | 5219 | |
| 5185 | 5220 | copts = ceph_parse_options(options, mon_addrs, |
| 5186 | 5221 | mon_addrs + mon_addrs_size - 1, |
| @@ -5216,6 +5251,8 @@ static void rbd_dev_image_unlock(struct rbd_device *rbd_dev) · 29 unmodified lines | ||
| 5216 | 5251 | |
| 5217 | 5252 | static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) |
| 5218 | 5253 | { |
| 5254 | + int ret; | |
| 5255 | + | |
| 5219 | 5256 | if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) { |
| 5220 | 5257 | rbd_warn(rbd_dev, "exclusive-lock feature is not enabled"); |
| 5221 | 5258 | return -EINVAL; |
| @@ -5223,9 +5260,9 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) · 1 unmodified line | ||
| 5223 | 5260 | |
| 5224 | 5261 | /* FIXME: "rbd map --exclusive" should be in interruptible */ |
| 5225 | 5262 | down_read(&rbd_dev->lock_rwsem); |
| 5226 | − rbd_wait_state_locked(rbd_dev); | |
| 5263 | + ret = rbd_wait_state_locked(rbd_dev, true); | |
| 5227 | 5264 | up_read(&rbd_dev->lock_rwsem); |
| 5228 | − if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) { | |
| 5265 | + if (ret) { | |
| 5229 | 5266 | rbd_warn(rbd_dev, "failed to acquire exclusive lock"); |
| 5230 | 5267 | return -EROFS; |
| 5231 | 5268 | } |
| @@ -110,7 +110,7 @@ struct iwm { · 109 unmodified lines | ||
| 110 | 110 | /* Select values for swim_select and swim_readbit */ |
| 111 | 111 | |
| 112 | 112 | #define READ_DATA_0 0x074 |
| 113 | −#define TWOMEG_DRIVE 0x075 | |
| 113 | +#define ONEMEG_DRIVE 0x075 | |
| 114 | 114 | #define SINGLE_SIDED 0x076 |
| 115 | 115 | #define DRIVE_PRESENT 0x077 |
| 116 | 116 | #define DISK_IN 0x170 |
| @@ -118,9 +118,9 @@ struct iwm { · 1 unmodified line | ||
| 118 | 118 | #define TRACK_ZERO 0x172 |
| 119 | 119 | #define TACHO 0x173 |
| 120 | 120 | #define READ_DATA_1 0x174 |
| 121 | −#define MFM_MODE 0x175 | |
| 121 | +#define GCR_MODE 0x175 | |
| 122 | 122 | #define SEEK_COMPLETE 0x176 |
| 123 | −#define ONEMEG_MEDIA 0x177 | |
| 123 | +#define TWOMEG_MEDIA 0x177 | |
| 124 | 124 | |
| 125 | 125 | /* Bits in handshake register */ |
| 126 | 126 | |
| @@ -612,7 +612,6 @@ static void setup_medium(struct floppy_state *fs) · 485 unmodified lines | ||
| 612 | 612 | struct floppy_struct *g; |
| 613 | 613 | fs->disk_in = 1; |
| 614 | 614 | fs->write_protected = swim_readbit(base, WRITE_PROT); |
| 615 | − fs->type = swim_readbit(base, ONEMEG_MEDIA); | |
| 616 | 615 | |
| 617 | 616 | if (swim_track00(base)) |
| 618 | 617 | printk(KERN_ERR |
| @@ -620,6 +619,9 @@ static void setup_medium(struct floppy_state *fs) · 1 unmodified line | ||
| 620 | 619 | |
| 621 | 620 | swim_track00(base); |
| 622 | 621 | |
| 622 | + fs->type = swim_readbit(base, TWOMEG_MEDIA) ? | |
| 623 | + HD_MEDIA : DD_MEDIA; | |
| 624 | + fs->head_number = swim_readbit(base, SINGLE_SIDED) ? 1 : 2; | |
| 623 | 625 | get_floppy_geometry(fs, 0, &g); |
| 624 | 626 | fs->total_secs = g->size; |
| 625 | 627 | fs->secpercyl = g->head * g->sect; |
| @@ -646,7 +648,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) · 20 unmodified lines | ||
| 646 | 648 | |
| 647 | 649 | swim_write(base, setup, S_IBM_DRIVE | S_FCLK_DIV2); |
| 648 | 650 | udelay(10); |
| 649 | − swim_drive(base, INTERNAL_DRIVE); | |
| 651 | + swim_drive(base, fs->location); | |
| 650 | 652 | swim_motor(base, ON); |
| 651 | 653 | swim_action(base, SETMFM); |
| 652 | 654 | if (fs->ejected) |
| @@ -656,6 +658,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) · 3 unmodified lines | ||
| 656 | 658 | goto out; |
| 657 | 659 | } |
| 658 | 660 | |
| 661 | + set_capacity(fs->disk, fs->total_secs); | |
| 662 | + | |
| 659 | 663 | if (mode & FMODE_NDELAY) |
| 660 | 664 | return 0; |
| 661 | 665 | |
| @@ -727,14 +731,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode, · 65 unmodified lines | ||
| 727 | 731 | if (copy_to_user((void __user *) param, (void *) &floppy_type, |
| 728 | 732 | sizeof(struct floppy_struct))) |
| 729 | 733 | return -EFAULT; |
| 730 | − break; | |
| 731 | − | |
| 732 | − default: | |
| 733 | − printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n", | |
| 734 | − cmd); | |
| 735 | − return -ENOSYS; | |
| 734 | + return 0; | |
| 736 | 735 | } |
| 737 | − return 0; | |
| 736 | + return -ENOTTY; | |
| 738 | 737 | } |
| 739 | 738 | |
| 740 | 739 | static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
| @@ -795,7 +794,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) · 54 unmodified lines | ||
| 795 | 794 | struct swim_priv *swd = data; |
| 796 | 795 | int drive = (*part & 3); |
| 797 | 796 | |
| 798 | − if (drive > swd->floppy_count) | |
| 797 | + if (drive >= swd->floppy_count) | |
| 799 | 798 | return NULL; |
| 800 | 799 | |
| 801 | 800 | *part = 0; |
| @@ -813,10 +812,9 @@ static int swim_add_floppy(struct swim_priv *swd, enum drive_location location) · 11 unmodified lines | ||
| 813 | 812 | |
| 814 | 813 | swim_motor(base, OFF); |
| 815 | 814 | |
| 816 | − if (swim_readbit(base, SINGLE_SIDED)) | |
| 817 | − fs->head_number = 1; | |
| 818 | − else | |
| 819 | − fs->head_number = 2; | |
| 815 | + fs->type = HD_MEDIA; | |
| 816 | + fs->head_number = 2; | |
| 817 | + | |
| 820 | 818 | fs->ref_count = 0; |
| 821 | 819 | fs->ejected = 1; |
| 822 | 820 | |
| @@ -834,10 +832,12 @@ static int swim_floppy_init(struct swim_priv *swd) · 11 unmodified lines | ||
| 834 | 832 | /* scan floppy drives */ |
| 835 | 833 | |
| 836 | 834 | swim_drive(base, INTERNAL_DRIVE); |
| 837 | − if (swim_readbit(base, DRIVE_PRESENT)) | |
| 835 | + if (swim_readbit(base, DRIVE_PRESENT) && | |
| 836 | + !swim_readbit(base, ONEMEG_DRIVE)) | |
| 838 | 837 | swim_add_floppy(swd, INTERNAL_DRIVE); |
| 839 | 838 | swim_drive(base, EXTERNAL_DRIVE); |
| 840 | − if (swim_readbit(base, DRIVE_PRESENT)) | |
| 839 | + if (swim_readbit(base, DRIVE_PRESENT) && | |
| 840 | + !swim_readbit(base, ONEMEG_DRIVE)) | |
| 841 | 841 | swim_add_floppy(swd, EXTERNAL_DRIVE); |
| 842 | 842 | |
| 843 | 843 | /* register floppy drives */ |
| @@ -861,7 +861,6 @@ static int swim_floppy_init(struct swim_priv *swd) · 17 unmodified lines | ||
| 861 | 861 | &swd->lock); |
| 862 | 862 | if (!swd->unit[drive].disk->queue) { |
| 863 | 863 | err = -ENOMEM; |
| 864 | − put_disk(swd->unit[drive].disk); | |
| 865 | 864 | goto exit_put_disks; |
| 866 | 865 | } |
| 867 | 866 | blk_queue_bounce_limit(swd->unit[drive].disk->queue, |
| @@ -911,7 +910,7 @@ static int swim_probe(struct platform_device *dev) · 43 unmodified lines | ||
| 911 | 910 | goto out; |
| 912 | 911 | } |
| 913 | 912 | |
| 914 | − swim_base = ioremap(res->start, resource_size(res)); | |
| 913 | + swim_base = (struct swim __iomem *)res->start; | |
| 915 | 914 | if (!swim_base) { |
| 916 | 915 | ret = -ENOMEM; |
| 917 | 916 | goto out_release_io; |
| @@ -923,7 +922,7 @@ static int swim_probe(struct platform_device *dev) · 5 unmodified lines | ||
| 923 | 922 | if (!get_swim_mode(swim_base)) { |
| 924 | 923 | printk(KERN_INFO "SWIM device not found !\n"); |
| 925 | 924 | ret = -ENODEV; |
| 926 | − goto out_iounmap; | |
| 925 | + goto out_release_io; | |
| 927 | 926 | } |
| 928 | 927 | |
| 929 | 928 | /* set platform driver data */ |
| @@ -931,7 +930,7 @@ static int swim_probe(struct platform_device *dev) · 1 unmodified line | ||
| 931 | 930 | swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL); |
| 932 | 931 | if (!swd) { |
| 933 | 932 | ret = -ENOMEM; |
| 934 | − goto out_iounmap; | |
| 933 | + goto out_release_io; | |
| 935 | 934 | } |
| 936 | 935 | platform_set_drvdata(dev, swd); |
| 937 | 936 | |
| @@ -945,8 +944,6 @@ static int swim_probe(struct platform_device *dev) · 7 unmodified lines | ||
| 945 | 944 | |
| 946 | 945 | out_kfree: |
| 947 | 946 | kfree(swd); |
| 948 | −out_iounmap: | |
| 949 | − iounmap(swim_base); | |
| 950 | 947 | out_release_io: |
| 951 | 948 | release_mem_region(res->start, resource_size(res)); |
| 952 | 949 | out: |
| @@ -974,8 +971,6 @@ static int swim_remove(struct platform_device *dev) · 21 unmodified lines | ||
| 974 | 971 | for (drive = 0; drive < swd->floppy_count; drive++) |
| 975 | 972 | floppy_eject(&swd->unit[drive]); |
| 976 | 973 | |
| 977 | − iounmap(swd->base); | |
| 978 | − | |
| 979 | 974 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
| 980 | 975 | if (res) |
| 981 | 976 | release_mem_region(res->start, resource_size(res)); |
| @@ -148,7 +148,7 @@ struct swim3 { · 147 unmodified lines | ||
| 148 | 148 | #define MOTOR_ON 2 |
| 149 | 149 | #define RELAX 3 /* also eject in progress */ |
| 150 | 150 | #define READ_DATA_0 4 |
| 151 | −#define TWOMEG_DRIVE 5 | |
| 151 | +#define ONEMEG_DRIVE 5 | |
| 152 | 152 | #define SINGLE_SIDED 6 /* drive or diskette is 4MB type? */ |
| 153 | 153 | #define DRIVE_PRESENT 7 |
| 154 | 154 | #define DISK_IN 8 |
| @@ -156,9 +156,9 @@ struct swim3 { · 1 unmodified line | ||
| 156 | 156 | #define TRACK_ZERO 10 |
| 157 | 157 | #define TACHO 11 |
| 158 | 158 | #define READ_DATA_1 12 |
| 159 | −#define MFM_MODE 13 | |
| 159 | +#define GCR_MODE 13 | |
| 160 | 160 | #define SEEK_COMPLETE 14 |
| 161 | −#define ONEMEG_MEDIA 15 | |
| 161 | +#define TWOMEG_MEDIA 15 | |
| 162 | 162 | |
| 163 | 163 | /* Definitions of values used in writing and formatting */ |
| 164 | 164 | #define DATA_ESCAPE 0x99 |
| @@ -33,6 +33,7 @@ config HISILICON_LPC · 32 unmodified lines | ||
| 33 | 33 | bool "Support for ISA I/O space on HiSilicon Hip06/7" |
| 34 | 34 | depends on ARM64 && (ARCH_HISI || COMPILE_TEST) |
| 35 | 35 | select INDIRECT_PIO |
| 36 | + select MFD_CORE if ACPI | |
| 36 | 37 | help |
| 37 | 38 | Driver to enable I/O access to devices attached to the Low Pin |
| 38 | 39 | Count bus on the HiSilicon Hip06/7 SoC. |
| @@ -2371,7 +2371,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, · 2370 unmodified lines | ||
| 2371 | 2371 | if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT) |
| 2372 | 2372 | return media_changed(cdi, 1); |
| 2373 | 2373 | |
| 2374 | − if ((unsigned int)arg >= cdi->capacity) | |
| 2374 | + if (arg >= cdi->capacity) | |
| 2375 | 2375 | return -EINVAL; |
| 2376 | 2376 | |
| 2377 | 2377 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
| @@ -261,6 +261,7 @@ · 260 unmodified lines | ||
| 261 | 261 | #include <linux/ptrace.h> |
| 262 | 262 | #include <linux/workqueue.h> |
| 263 | 263 | #include <linux/irq.h> |
| 264 | +#include <linux/ratelimit.h> | |
| 264 | 265 | #include <linux/syscalls.h> |
| 265 | 266 | #include <linux/completion.h> |
| 266 | 267 | #include <linux/uuid.h> |
| @@ -427,8 +428,9 @@ struct crng_state primary_crng = { · 160 unmodified lines | ||
| 427 | 428 | * its value (from 0->1->2). |
| 428 | 429 | */ |
| 429 | 430 | static int crng_init = 0; |
| 430 | −#define crng_ready() (likely(crng_init > 0)) | |
| 431 | +#define crng_ready() (likely(crng_init > 1)) | |
| 431 | 432 | static int crng_init_cnt = 0; |
| 433 | +static unsigned long crng_global_init_time = 0; | |
| 432 | 434 | #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE) |
| 433 | 435 | static void _extract_crng(struct crng_state *crng, |
| 434 | 436 | __u32 out[CHACHA20_BLOCK_WORDS]); |
| @@ -437,6 +439,16 @@ static void _crng_backtrack_protect(struct crng_state *crng, · 2 unmodified lines | ||
| 437 | 439 | static void process_random_ready_list(void); |
| 438 | 440 | static void _get_random_bytes(void *buf, int nbytes); |
| 439 | 441 | |
| 442 | +static struct ratelimit_state unseeded_warning = | |
| 443 | + RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3); | |
| 444 | +static struct ratelimit_state urandom_warning = | |
| 445 | + RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3); | |
| 446 | + | |
| 447 | +static int ratelimit_disable __read_mostly; | |
| 448 | + | |
| 449 | +module_param_named(ratelimit_disable, ratelimit_disable, int, 0644); | |
| 450 | +MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression"); | |
| 451 | + | |
| 440 | 452 | /********************************************************************** |
| 441 | 453 | * |
| 442 | 454 | * OS independent entropy store. Here are the functions which handle |
| @@ -787,6 +799,43 @@ static void crng_initialize(struct crng_state *crng) · 344 unmodified lines | ||
| 787 | 799 | crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; |
| 788 | 800 | } |
| 789 | 801 | |
| 802 | +#ifdef CONFIG_NUMA | |
| 803 | +static void do_numa_crng_init(struct work_struct *work) | |
| 804 | +{ | |
| 805 | + int i; | |
| 806 | + struct crng_state *crng; | |
| 807 | + struct crng_state **pool; | |
| 808 | + | |
| 809 | + pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); | |
| 810 | + for_each_online_node(i) { | |
| 811 | + crng = kmalloc_node(sizeof(struct crng_state), | |
| 812 | + GFP_KERNEL | __GFP_NOFAIL, i); | |
| 813 | + spin_lock_init(&crng->lock); | |
| 814 | + crng_initialize(crng); | |
| 815 | + pool[i] = crng; | |
| 816 | + } | |
| 817 | + mb(); | |
| 818 | + if (cmpxchg(&crng_node_pool, NULL, pool)) { | |
| 819 | + for_each_node(i) | |
| 820 | + kfree(pool[i]); | |
| 821 | + kfree(pool); | |
| 822 | + } | |
| 823 | +} | |
| 824 | + | |
| 825 | +static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init); | |
| 826 | + | |
| 827 | +static void numa_crng_init(void) | |
| 828 | +{ | |
| 829 | + schedule_work(&numa_crng_init_work); | |
| 830 | +} | |
| 831 | +#else | |
| 832 | +static void numa_crng_init(void) {} | |
| 833 | +#endif | |
| 834 | + | |
| 835 | +/* | |
| 836 | + * crng_fast_load() can be called by code in the interrupt service | |
| 837 | + * path. So we can't afford to dilly-dally. | |
| 838 | + */ | |
| 790 | 839 | static int crng_fast_load(const char *cp, size_t len) |
| 791 | 840 | { |
| 792 | 841 | unsigned long flags; |
| @@ -794,7 +843,7 @@ static int crng_fast_load(const char *cp, size_t len) · 1 unmodified line | ||
| 794 | 843 | |
| 795 | 844 | if (!spin_trylock_irqsave(&primary_crng.lock, flags)) |
| 796 | 845 | return 0; |
| 797 | − if (crng_ready()) { | |
| 846 | + if (crng_init != 0) { | |
| 798 | 847 | spin_unlock_irqrestore(&primary_crng.lock, flags); |
| 799 | 848 | return 0; |
| 800 | 849 | } |
| @@ -813,6 +862,51 @@ static int crng_fast_load(const char *cp, size_t len) · 12 unmodified lines | ||
| 813 | 862 | return 1; |
| 814 | 863 | } |
| 815 | 864 | |
| 865 | +/* | |
| 866 | + * crng_slow_load() is called by add_device_randomness, which has two | |
| 867 | + * attributes. (1) We can't trust the buffer passed to it is | |
| 868 | + * guaranteed to be unpredictable (so it might not have any entropy at | |
| 869 | + * all), and (2) it doesn't have the performance constraints of | |
| 870 | + * crng_fast_load(). | |
| 871 | + * | |
| 872 | + * So we do something more comprehensive which is guaranteed to touch | |
| 873 | + * all of the primary_crng's state, and which uses a LFSR with a | |
| 874 | + * period of 255 as part of the mixing algorithm. Finally, we do | |
| 875 | + * *not* advance crng_init_cnt since buffer we may get may be something | |
| 876 | + * like a fixed DMI table (for example), which might very well be | |
| 877 | + * unique to the machine, but is otherwise unvarying. | |
| 878 | + */ | |
| 879 | +static int crng_slow_load(const char *cp, size_t len) | |
| 880 | +{ | |
| 881 | + unsigned long flags; | |
| 882 | + static unsigned char lfsr = 1; | |
| 883 | + unsigned char tmp; | |
| 884 | + unsigned i, max = CHACHA20_KEY_SIZE; | |
| 885 | + const char * src_buf = cp; | |
| 886 | + char * dest_buf = (char *) &primary_crng.state[4]; | |
| 887 | + | |
| 888 | + if (!spin_trylock_irqsave(&primary_crng.lock, flags)) | |
| 889 | + return 0; | |
| 890 | + if (crng_init != 0) { | |
| 891 | + spin_unlock_irqrestore(&primary_crng.lock, flags); | |
| 892 | + return 0; | |
| 893 | + } | |
| 894 | + if (len > max) | |
| 895 | + max = len; | |
| 896 | + | |
| 897 | + for (i = 0; i < max ; i++) { | |
| 898 | + tmp = lfsr; | |
| 899 | + lfsr >>= 1; | |
| 900 | + if (tmp & 1) | |
| 901 | + lfsr ^= 0xE1; | |
| 902 | + tmp = dest_buf[i % CHACHA20_KEY_SIZE]; | |
| 903 | + dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr; | |
| 904 | + lfsr += (tmp << 3) | (tmp >> 5); | |
| 905 | + } | |
| 906 | + spin_unlock_irqrestore(&primary_crng.lock, flags); | |
| 907 | + return 1; | |
| 908 | +} | |
| 909 | + | |
| 816 | 910 | static void crng_reseed(struct crng_state *crng, struct entropy_store *r) |
| 817 | 911 | { |
| 818 | 912 | unsigned long flags; |
| @@ -831,7 +925,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) · 12 unmodified lines | ||
| 831 | 925 | _crng_backtrack_protect(&primary_crng, buf.block, |
| 832 | 926 | CHACHA20_KEY_SIZE); |
| 833 | 927 | } |
| 834 | − spin_lock_irqsave(&primary_crng.lock, flags); | |
| 928 | + spin_lock_irqsave(&crng->lock, flags); | |
| 835 | 929 | for (i = 0; i < 8; i++) { |
| 836 | 930 | unsigned long rv; |
| 837 | 931 | if (!arch_get_random_seed_long(&rv) && |
| @@ -841,13 +935,26 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) · 3 unmodified lines | ||
| 841 | 935 | } |
| 842 | 936 | memzero_explicit(&buf, sizeof(buf)); |
| 843 | 937 | crng->init_time = jiffies; |
| 844 | − spin_unlock_irqrestore(&primary_crng.lock, flags); | |
| 938 | + spin_unlock_irqrestore(&crng->lock, flags); | |
| 845 | 939 | if (crng == &primary_crng && crng_init < 2) { |
| 846 | 940 | invalidate_batched_entropy(); |
| 941 | + numa_crng_init(); | |
| 847 | 942 | crng_init = 2; |
| 848 | 943 | process_random_ready_list(); |
| 849 | 944 | wake_up_interruptible(&crng_init_wait); |
| 850 | 945 | pr_notice("random: crng init done\n"); |
| 946 | + if (unseeded_warning.missed) { | |
| 947 | + pr_notice("random: %d get_random_xx warning(s) missed " | |
| 948 | + "due to ratelimiting\n", | |
| 949 | + unseeded_warning.missed); | |
| 950 | + unseeded_warning.missed = 0; | |
| 951 | + } | |
| 952 | + if (urandom_warning.missed) { | |
| 953 | + pr_notice("random: %d urandom warning(s) missed " | |
| 954 | + "due to ratelimiting\n", | |
| 955 | + urandom_warning.missed); | |
| 956 | + urandom_warning.missed = 0; | |
| 957 | + } | |
| 851 | 958 | } |
| 852 | 959 | } |
| 853 | 960 | |
| @@ -856,8 +963,9 @@ static void _extract_crng(struct crng_state *crng, · 2 unmodified lines | ||
| 856 | 963 | { |
| 857 | 964 | unsigned long v, flags; |
| 858 | 965 | |
| 859 | − if (crng_init > 1 && | |
| 860 | − time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)) | |
| 966 | + if (crng_ready() && | |
| 967 | + (time_after(crng_global_init_time, crng->init_time) || | |
| 968 | + time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) | |
| 861 | 969 | crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); |
| 862 | 970 | spin_lock_irqsave(&crng->lock, flags); |
| 863 | 971 | if (arch_get_random_long(&v)) |
| @@ -981,10 +1089,8 @@ void add_device_randomness(const void *buf, unsigned int size) · 117 unmodified lines | ||
| 981 | 1089 | unsigned long time = random_get_entropy() ^ jiffies; |
| 982 | 1090 | unsigned long flags; |
| 983 | 1091 | |
| 984 | − if (!crng_ready()) { | |
| 985 | − crng_fast_load(buf, size); | |
| 986 | − return; | |
| 987 | − } | |
| 1092 | + if (!crng_ready() && size) | |
| 1093 | + crng_slow_load(buf, size); | |
| 988 | 1094 | |
| 989 | 1095 | trace_add_device_randomness(size, _RET_IP_); |
| 990 | 1096 | spin_lock_irqsave(&input_pool.lock, flags); |
| @@ -1139,7 +1245,7 @@ void add_interrupt_randomness(int irq, int irq_flags) · 148 unmodified lines | ||
| 1139 | 1245 | fast_mix(fast_pool); |
| 1140 | 1246 | add_interrupt_bench(cycles); |
| 1141 | 1247 | |
| 1142 | − if (!crng_ready()) { | |
| 1248 | + if (unlikely(crng_init == 0)) { | |
| 1143 | 1249 | if ((fast_pool->count >= 64) && |
| 1144 | 1250 | crng_fast_load((char *) fast_pool->pool, |
| 1145 | 1251 | sizeof(fast_pool->pool))) { |
| @@ -1489,8 +1595,9 @@ static void _warn_unseeded_randomness(const char *func_name, void *caller, · 343 unmodified lines | ||
| 1489 | 1595 | #ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM |
| 1490 | 1596 | print_once = true; |
| 1491 | 1597 | #endif |
| 1492 | − pr_notice("random: %s called from %pS with crng_init=%d\n", | |
| 1493 | − func_name, caller, crng_init); | |
| 1598 | + if (__ratelimit(&unseeded_warning)) | |
| 1599 | + pr_notice("random: %s called from %pS with crng_init=%d\n", | |
| 1600 | + func_name, caller, crng_init); | |
| 1494 | 1601 | } |
| 1495 | 1602 | |
| 1496 | 1603 | /* |
| @@ -1680,28 +1787,14 @@ static void init_std_data(struct entropy_store *r) · 183 unmodified lines | ||
| 1680 | 1787 | */ |
| 1681 | 1788 | static int rand_initialize(void) |
| 1682 | 1789 | { |
| 1683 | −#ifdef CONFIG_NUMA | |
| 1684 | − int i; | |
| 1685 | − struct crng_state *crng; | |
| 1686 | − struct crng_state **pool; | |
| 1687 | −#endif | |
| 1688 | − | |
| 1689 | 1790 | init_std_data(&input_pool); |
| 1690 | 1791 | init_std_data(&blocking_pool); |
| 1691 | 1792 | crng_initialize(&primary_crng); |
| 1692 | − | |
| 1693 | −#ifdef CONFIG_NUMA | |
| 1694 | − pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); | |
| 1695 | − for_each_online_node(i) { | |
| 1696 | − crng = kmalloc_node(sizeof(struct crng_state), | |
| 1697 | − GFP_KERNEL | __GFP_NOFAIL, i); | |
| 1698 | − spin_lock_init(&crng->lock); | |
| 1699 | − crng_initialize(crng); | |
| 1700 | − pool[i] = crng; | |
| 1793 | + crng_global_init_time = jiffies; | |
| 1794 | + if (ratelimit_disable) { | |
| 1795 | + urandom_warning.interval = 0; | |
| 1796 | + unseeded_warning.interval = 0; | |
| 1701 | 1797 | } |
| 1702 | − mb(); | |
| 1703 | − crng_node_pool = pool; | |
| 1704 | −#endif | |
| 1705 | 1798 | return 0; |
| 1706 | 1799 | } |
| 1707 | 1800 | early_initcall(rand_initialize); |
| @@ -1769,9 +1862,10 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) · 61 unmodified lines | ||
| 1769 | 1862 | |
| 1770 | 1863 | if (!crng_ready() && maxwarn > 0) { |
| 1771 | 1864 | maxwarn--; |
| 1772 | − printk(KERN_NOTICE "random: %s: uninitialized urandom read " | |
| 1773 | − "(%zd bytes read)\n", | |
| 1774 | − current->comm, nbytes); | |
| 1865 | + if (__ratelimit(&urandom_warning)) | |
| 1866 | + printk(KERN_NOTICE "random: %s: uninitialized " | |
| 1867 | + "urandom read (%zd bytes read)\n", | |
| 1868 | + current->comm, nbytes); | |
| 1775 | 1869 | spin_lock_irqsave(&primary_crng.lock, flags); |
| 1776 | 1870 | crng_init_cnt = 0; |
| 1777 | 1871 | spin_unlock_irqrestore(&primary_crng.lock, flags); |
| @@ -1875,6 +1969,14 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) · 97 unmodified lines | ||
| 1875 | 1969 | input_pool.entropy_count = 0; |
| 1876 | 1970 | blocking_pool.entropy_count = 0; |
| 1877 | 1971 | return 0; |
| 1972 | + case RNDRESEEDCRNG: | |
| 1973 | + if (!capable(CAP_SYS_ADMIN)) | |
| 1974 | + return -EPERM; | |
| 1975 | + if (crng_init < 2) | |
| 1976 | + return -ENODATA; | |
| 1977 | + crng_reseed(&primary_crng, NULL); | |
| 1978 | + crng_global_init_time = jiffies - 1; | |
| 1979 | + return 0; | |
| 1878 | 1980 | default: |
| 1879 | 1981 | return -EINVAL; |
| 1880 | 1982 | } |
| @@ -2212,7 +2314,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count, · 331 unmodified lines | ||
| 2212 | 2314 | { |
| 2213 | 2315 | struct entropy_store *poolp = &input_pool; |
| 2214 | 2316 | |
| 2215 | − if (!crng_ready()) { | |
| 2317 | + if (unlikely(crng_init == 0)) { | |
| 2216 | 2318 | crng_fast_load(buffer, count); |
| 2217 | 2319 | return; |
| 2218 | 2320 | } |
| @@ -422,7 +422,7 @@ static void reclaim_dma_bufs(void) · 421 unmodified lines | ||
| 422 | 422 | } |
| 423 | 423 | } |
| 424 | 424 | |
| 425 | −static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size, | |
| 425 | +static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size, | |
| 426 | 426 | int pages) |
| 427 | 427 | { |
| 428 | 428 | struct port_buffer *buf; |
| @@ -445,16 +445,16 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size, · 16 unmodified lines | ||
| 445 | 445 | return buf; |
| 446 | 446 | } |
| 447 | 447 | |
| 448 | − if (is_rproc_serial(vq->vdev)) { | |
| 448 | + if (is_rproc_serial(vdev)) { | |
| 449 | 449 | /* |
| 450 | 450 | * Allocate DMA memory from ancestor. When a virtio |
| 451 | 451 | * device is created by remoteproc, the DMA memory is |
| 452 | 452 | * associated with the grandparent device: |
| 453 | 453 | * vdev => rproc => platform-dev. |
| 454 | 454 | */ |
| 455 | − if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent) | |
| 455 | + if (!vdev->dev.parent || !vdev->dev.parent->parent) | |
| 456 | 456 | goto free_buf; |
| 457 | − buf->dev = vq->vdev->dev.parent->parent; | |
| 457 | + buf->dev = vdev->dev.parent->parent; | |
| 458 | 458 | |
| 459 | 459 | /* Increase device refcnt to avoid freeing it */ |
| 460 | 460 | get_device(buf->dev); |
| @@ -838,7 +838,7 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, · 377 unmodified lines | ||
| 838 | 838 | |
| 839 | 839 | count = min((size_t)(32 * 1024), count); |
| 840 | 840 | |
| 841 | − buf = alloc_buf(port->out_vq, count, 0); | |
| 841 | + buf = alloc_buf(port->portdev->vdev, count, 0); | |
| 842 | 842 | if (!buf) |
| 843 | 843 | return -ENOMEM; |
| 844 | 844 | |
| @@ -957,7 +957,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe, · 112 unmodified lines | ||
| 957 | 957 | if (ret < 0) |
| 958 | 958 | goto error_out; |
| 959 | 959 | |
| 960 | − buf = alloc_buf(port->out_vq, 0, pipe->nrbufs); | |
| 960 | + buf = alloc_buf(port->portdev->vdev, 0, pipe->nrbufs); | |
| 961 | 961 | if (!buf) { |
| 962 | 962 | ret = -ENOMEM; |
| 963 | 963 | goto error_out; |
| @@ -1374,7 +1374,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) · 410 unmodified lines | ||
| 1374 | 1374 | |
| 1375 | 1375 | nr_added_bufs = 0; |
| 1376 | 1376 | do { |
| 1377 | − buf = alloc_buf(vq, PAGE_SIZE, 0); | |
| 1377 | + buf = alloc_buf(vq->vdev, PAGE_SIZE, 0); | |
| 1378 | 1378 | if (!buf) |
| 1379 | 1379 | break; |
| 1380 | 1380 | |
| @@ -1402,7 +1402,6 @@ static int add_port(struct ports_device *portdev, u32 id) · 21 unmodified lines | ||
| 1402 | 1402 | { |
| 1403 | 1403 | char debugfs_name[16]; |
| 1404 | 1404 | struct port *port; |
| 1405 | − struct port_buffer *buf; | |
| 1406 | 1405 | dev_t devt; |
| 1407 | 1406 | unsigned int nr_added_bufs; |
| 1408 | 1407 | int err; |
| @@ -1513,8 +1512,6 @@ static int add_port(struct ports_device *portdev, u32 id) · 104 unmodified lines | ||
| 1513 | 1512 | return 0; |
| 1514 | 1513 | |
| 1515 | 1514 | free_inbufs: |
| 1516 | − while ((buf = virtqueue_detach_unused_buf(port->in_vq))) | |
| 1517 | − free_buf(buf, true); | |
| 1518 | 1515 | free_device: |
| 1519 | 1516 | device_destroy(pdrvdata.class, port->dev->devt); |
| 1520 | 1517 | free_cdev: |
| @@ -1539,34 +1536,14 @@ static void remove_port(struct kref *kref) · 18 unmodified lines | ||
| 1539 | 1536 | |
| 1540 | 1537 | static void remove_port_data(struct port *port) |
| 1541 | 1538 | { |
| 1542 | − struct port_buffer *buf; | |
| 1543 | − | |
| 1544 | 1539 | spin_lock_irq(&port->inbuf_lock); |
| 1545 | 1540 | /* Remove unused data this port might have received. */ |
| 1546 | 1541 | discard_port_data(port); |
| 1547 | 1542 | spin_unlock_irq(&port->inbuf_lock); |
| 1548 | 1543 | |
| 1549 | − /* Remove buffers we queued up for the Host to send us data in. */ | |
| 1550 | − do { | |
| 1551 | − spin_lock_irq(&port->inbuf_lock); | |
| 1552 | − buf = virtqueue_detach_unused_buf(port->in_vq); | |
| 1553 | − spin_unlock_irq(&port->inbuf_lock); | |
| 1554 | − if (buf) | |
| 1555 | − free_buf(buf, true); | |
| 1556 | − } while (buf); | |
| 1557 | − | |
| 1558 | 1544 | spin_lock_irq(&port->outvq_lock); |
| 1559 | 1545 | reclaim_consumed_buffers(port); |
| 1560 | 1546 | spin_unlock_irq(&port->outvq_lock); |
| 1561 | − | |
| 1562 | − /* Free pending buffers from the out-queue. */ | |
| 1563 | − do { | |
| 1564 | − spin_lock_irq(&port->outvq_lock); | |
| 1565 | − buf = virtqueue_detach_unused_buf(port->out_vq); | |
| 1566 | − spin_unlock_irq(&port->outvq_lock); | |
| 1567 | − if (buf) | |
| 1568 | − free_buf(buf, true); | |
| 1569 | − } while (buf); | |
| 1570 | 1547 | } |
| 1571 | 1548 | |
| 1572 | 1549 | /* |
| @@ -1791,13 +1768,24 @@ static void control_work_handler(struct work_struct *work) · 218 unmodified lines | ||
| 1791 | 1768 | spin_unlock(&portdev->c_ivq_lock); |
| 1792 | 1769 | } |
| 1793 | 1770 | |
| 1771 | +static void flush_bufs(struct virtqueue *vq, bool can_sleep) | |
| 1772 | +{ | |
| 1773 | + struct port_buffer *buf; | |
| 1774 | + unsigned int len; | |
| 1775 | + | |
| 1776 | + while ((buf = virtqueue_get_buf(vq, &len))) | |
| 1777 | + free_buf(buf, can_sleep); | |
| 1778 | +} | |
| 1779 | + | |
| 1794 | 1780 | static void out_intr(struct virtqueue *vq) |
| 1795 | 1781 | { |
| 1796 | 1782 | struct port *port; |
| 1797 | 1783 | |
| 1798 | 1784 | port = find_port_by_vq(vq->vdev->priv, vq); |
| 1799 | − if (!port) | |
| 1785 | + if (!port) { | |
| 1786 | + flush_bufs(vq, false); | |
| 1800 | 1787 | return; |
| 1788 | + } | |
| 1801 | 1789 | |
| 1802 | 1790 | wake_up_interruptible(&port->waitqueue); |
| 1803 | 1791 | } |
| @@ -1808,8 +1796,10 @@ static void in_intr(struct virtqueue *vq) · 4 unmodified lines | ||
| 1808 | 1796 | unsigned long flags; |
| 1809 | 1797 | |
| 1810 | 1798 | port = find_port_by_vq(vq->vdev->priv, vq); |
| 1811 | − if (!port) | |
| 1799 | + if (!port) { | |
| 1800 | + flush_bufs(vq, false); | |
| 1812 | 1801 | return; |
| 1802 | + } | |
| 1813 | 1803 | |
| 1814 | 1804 | spin_lock_irqsave(&port->inbuf_lock, flags); |
| 1815 | 1805 | port->inbuf = get_inbuf(port); |
| @@ -1984,24 +1974,54 @@ static const struct file_operations portdev_fops = { · 168 unmodified lines | ||
| 1984 | 1974 | |
| 1985 | 1975 | static void remove_vqs(struct ports_device *portdev) |
| 1986 | 1976 | { |
| 1977 | + struct virtqueue *vq; | |
| 1978 | + | |
| 1979 | + virtio_device_for_each_vq(portdev->vdev, vq) { | |
| 1980 | + struct port_buffer *buf; | |
| 1981 | + | |
| 1982 | + flush_bufs(vq, true); | |
| 1983 | + while ((buf = virtqueue_detach_unused_buf(vq))) | |
| 1984 | + free_buf(buf, true); | |
| 1985 | + } | |
| 1987 | 1986 | portdev->vdev->config->del_vqs(portdev->vdev); |
| 1988 | 1987 | kfree(portdev->in_vqs); |
| 1989 | 1988 | kfree(portdev->out_vqs); |
| 1990 | 1989 | } |
| 1991 | 1990 | |
| 1992 | −static void remove_controlq_data(struct ports_device *portdev) | |
| 1991 | +static void virtcons_remove(struct virtio_device *vdev) | |
| 1993 | 1992 | { |
| 1994 | − struct port_buffer *buf; | |
| 1995 | − unsigned int len; | |
| 1993 | + struct ports_device *portdev; | |
| 1994 | + struct port *port, *port2; | |
| 1996 | 1995 | |
| 1997 | − if (!use_multiport(portdev)) | |
| 1998 | − return; | |
| 1996 | + portdev = vdev->priv; | |
| 1999 | 1997 | |
| 2000 | − while ((buf = virtqueue_get_buf(portdev->c_ivq, &len))) | |
| 2001 | − free_buf(buf, true); | |
| 1998 | + spin_lock_irq(&pdrvdata_lock); | |
| 1999 | + list_del(&portdev->list); | |
| 2000 | + spin_unlock_irq(&pdrvdata_lock); | |
| 2002 | 2001 | |
| 2003 | − while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq))) | |
| 2004 | − free_buf(buf, true); | |
| 2002 | + /* Disable interrupts for vqs */ | |
| 2003 | + vdev->config->reset(vdev); | |
| 2004 | + /* Finish up work that's lined up */ | |
| 2005 | + if (use_multiport(portdev)) | |
| 2006 | + cancel_work_sync(&portdev->control_work); | |
| 2007 | + else | |
| 2008 | + cancel_work_sync(&portdev->config_work); | |
| 2009 | + | |
| 2010 | + list_for_each_entry_safe(port, port2, &portdev->ports, list) | |
| 2011 | + unplug_port(port); | |
| 2012 | + | |
| 2013 | + unregister_chrdev(portdev->chr_major, "virtio-portsdev"); | |
| 2014 | + | |
| 2015 | + /* | |
| 2016 | + * When yanking out a device, we immediately lose the | |
| 2017 | + * (device-side) queues. So there's no point in keeping the | |
| 2018 | + * guest side around till we drop our final reference. This | |
| 2019 | + * also means that any ports which are in an open state will | |
| 2020 | + * have to just stop using the port, as the vqs are going | |
| 2021 | + * away. | |
| 2022 | + */ | |
| 2023 | + remove_vqs(portdev); | |
| 2024 | + kfree(portdev); | |
| 2005 | 2025 | } |
| 2006 | 2026 | |
| 2007 | 2027 | /* |
| @@ -2070,6 +2090,7 @@ static int virtcons_probe(struct virtio_device *vdev) · 62 unmodified lines | ||
| 2070 | 2090 | |
| 2071 | 2091 | spin_lock_init(&portdev->ports_lock); |
| 2072 | 2092 | INIT_LIST_HEAD(&portdev->ports); |
| 2093 | + INIT_LIST_HEAD(&portdev->list); | |
| 2073 | 2094 | |
| 2074 | 2095 | virtio_device_ready(portdev->vdev); |
| 2075 | 2096 | |
| @@ -2087,8 +2108,15 @@ static int virtcons_probe(struct virtio_device *vdev) · 11 unmodified lines | ||
| 2087 | 2108 | if (!nr_added_bufs) { |
| 2088 | 2109 | dev_err(&vdev->dev, |
| 2089 | 2110 | "Error allocating buffers for control queue\n"); |
| 2090 | − err = -ENOMEM; | |
| 2091 | − goto free_vqs; | |
| 2111 | + /* | |
| 2112 | + * The host might want to notify mgmt sw about device | |
| 2113 | + * add failure. | |
| 2114 | + */ | |
| 2115 | + __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, | |
| 2116 | + VIRTIO_CONSOLE_DEVICE_READY, 0); | |
| 2117 | + /* Device was functional: we need full cleanup. */ | |
| 2118 | + virtcons_remove(vdev); | |
| 2119 | + return -ENOMEM; | |
| 2092 | 2120 | } |
| 2093 | 2121 | } else { |
| 2094 | 2122 | /* |
| @@ -2119,11 +2147,6 @@ static int virtcons_probe(struct virtio_device *vdev) · 24 unmodified lines | ||
| 2119 | 2147 | |
| 2120 | 2148 | return 0; |
| 2121 | 2149 | |
| 2122 | −free_vqs: | |
| 2123 | − /* The host might want to notify mgmt sw about device add failure */ | |
| 2124 | − __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, | |
| 2125 | − VIRTIO_CONSOLE_DEVICE_READY, 0); | |
| 2126 | − remove_vqs(portdev); | |
| 2127 | 2150 | free_chrdev: |
| 2128 | 2151 | unregister_chrdev(portdev->chr_major, "virtio-portsdev"); |
| 2129 | 2152 | free: |
| @@ -2132,43 +2155,6 @@ fail: · 2 unmodified lines | ||
| 2132 | 2155 | return err; |
| 2133 | 2156 | } |
| 2134 | 2157 | |
| 2135 | −static void virtcons_remove(struct virtio_device *vdev) | |
| 2136 | −{ | |
| 2137 | − struct ports_device *portdev; | |
| 2138 | − struct port *port, *port2; | |
| 2139 | − | |
| 2140 | − portdev = vdev->priv; | |
| 2141 | − | |
| 2142 | − spin_lock_irq(&pdrvdata_lock); | |
| 2143 | − list_del(&portdev->list); | |
| 2144 | − spin_unlock_irq(&pdrvdata_lock); | |
| 2145 | − | |
| 2146 | − /* Disable interrupts for vqs */ | |
| 2147 | − vdev->config->reset(vdev); | |
| 2148 | − /* Finish up work that's lined up */ | |
| 2149 | − if (use_multiport(portdev)) | |
| 2150 | − cancel_work_sync(&portdev->control_work); | |
| 2151 | − else | |
| 2152 | − cancel_work_sync(&portdev->config_work); | |
| 2153 | − | |
| 2154 | − list_for_each_entry_safe(port, port2, &portdev->ports, list) | |
| 2155 | − unplug_port(port); | |
| 2156 | − | |
| 2157 | − unregister_chrdev(portdev->chr_major, "virtio-portsdev"); | |
| 2158 | − | |
| 2159 | − /* | |
| 2160 | − * When yanking out a device, we immediately lose the | |
| 2161 | − * (device-side) queues. So there's no point in keeping the | |
| 2162 | − * guest side around till we drop our final reference. This | |
| 2163 | − * also means that any ports which are in an open state will | |
| 2164 | − * have to just stop using the port, as the vqs are going | |
| 2165 | − * away. | |
| 2166 | − */ | |
| 2167 | − remove_controlq_data(portdev); | |
| 2168 | − remove_vqs(portdev); | |
| 2169 | − kfree(portdev); | |
| 2170 | −} | |
| 2171 | − | |
| 2172 | 2158 | static struct virtio_device_id id_table[] = { |
| 2173 | 2159 | { VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID }, |
| 2174 | 2160 | { 0 }, |
| @@ -2209,7 +2195,6 @@ static int virtcons_freeze(struct virtio_device *vdev) · 34 unmodified lines | ||
| 2209 | 2195 | */ |
| 2210 | 2196 | if (use_multiport(portdev)) |
| 2211 | 2197 | virtqueue_disable_cb(portdev->c_ivq); |
| 2212 | − remove_controlq_data(portdev); | |
| 2213 | 2198 | |
| 2214 | 2199 | list_for_each_entry(port, &portdev->ports, list) { |
| 2215 | 2200 | virtqueue_disable_cb(port->in_vq); |
| @@ -541,7 +541,7 @@ probe_err: · 540 unmodified lines | ||
| 541 | 541 | return ret; |
| 542 | 542 | } |
| 543 | 543 | |
| 544 | −static int cs2000_resume(struct device *dev) | |
| 544 | +static int __maybe_unused cs2000_resume(struct device *dev) | |
| 545 | 545 | { |
| 546 | 546 | struct cs2000_priv *priv = dev_get_drvdata(dev); |
| 547 | 547 | |
| @@ -112,10 +112,18 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) · 111 unmodified lines | ||
| 112 | 112 | return 0; |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | +static int clk_mux_determine_rate(struct clk_hw *hw, | |
| 116 | + struct clk_rate_request *req) | |
| 117 | +{ | |
| 118 | + struct clk_mux *mux = to_clk_mux(hw); | |
| 119 | + | |
| 120 | + return clk_mux_determine_rate_flags(hw, req, mux->flags); | |
| 121 | +} | |
| 122 | + | |
| 115 | 123 | const struct clk_ops clk_mux_ops = { |
| 116 | 124 | .get_parent = clk_mux_get_parent, |
| 117 | 125 | .set_parent = clk_mux_set_parent, |
| 118 | − .determine_rate = __clk_mux_determine_rate, | |
| 126 | + .determine_rate = clk_mux_determine_rate, | |
| 119 | 127 | }; |
| 120 | 128 | EXPORT_SYMBOL_GPL(clk_mux_ops); |
| 121 | 129 | |
| @@ -216,7 +216,7 @@ static const char * const usart1_src[] = { · 215 unmodified lines | ||
| 216 | 216 | "pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse" |
| 217 | 217 | }; |
| 218 | 218 | |
| 219 | −const char * const usart234578_src[] = { | |
| 219 | +static const char * const usart234578_src[] = { | |
| 220 | 220 | "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" |
| 221 | 221 | }; |
| 222 | 222 | |
| @@ -224,10 +224,6 @@ static const char * const usart6_src[] = { · 1 unmodified line | ||
| 224 | 224 | "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" |
| 225 | 225 | }; |
| 226 | 226 | |
| 227 | −static const char * const dfsdm_src[] = { | |
| 228 | − "pclk2", "ck_mcu" | |
| 229 | −}; | |
| 230 | − | |
| 231 | 227 | static const char * const fdcan_src[] = { |
| 232 | 228 | "ck_hse", "pll3_q", "pll4_q" |
| 233 | 229 | }; |
| @@ -316,10 +312,8 @@ struct stm32_clk_mgate { · 82 unmodified lines | ||
| 316 | 312 | struct clock_config { |
| 317 | 313 | u32 id; |
| 318 | 314 | const char *name; |
| 319 | − union { | |
| 320 | − const char *parent_name; | |
| 321 | − const char * const *parent_names; | |
| 322 | − }; | |
| 315 | + const char *parent_name; | |
| 316 | + const char * const *parent_names; | |
| 323 | 317 | int num_parents; |
| 324 | 318 | unsigned long flags; |
| 325 | 319 | void *cfg; |
| @@ -469,7 +463,7 @@ static void mp1_gate_clk_disable(struct clk_hw *hw) · 143 unmodified lines | ||
| 469 | 463 | } |
| 470 | 464 | } |
| 471 | 465 | |
| 472 | −const struct clk_ops mp1_gate_clk_ops = { | |
| 466 | +static const struct clk_ops mp1_gate_clk_ops = { | |
| 473 | 467 | .enable = mp1_gate_clk_enable, |
| 474 | 468 | .disable = mp1_gate_clk_disable, |
| 475 | 469 | .is_enabled = clk_gate_is_enabled, |
| @@ -698,7 +692,7 @@ static void mp1_mgate_clk_disable(struct clk_hw *hw) · 222 unmodified lines | ||
| 698 | 692 | mp1_gate_clk_disable(hw); |
| 699 | 693 | } |
| 700 | 694 | |
| 701 | −const struct clk_ops mp1_mgate_clk_ops = { | |
| 695 | +static const struct clk_ops mp1_mgate_clk_ops = { | |
| 702 | 696 | .enable = mp1_mgate_clk_enable, |
| 703 | 697 | .disable = mp1_mgate_clk_disable, |
| 704 | 698 | .is_enabled = clk_gate_is_enabled, |
| @@ -732,7 +726,7 @@ static int clk_mmux_set_parent(struct clk_hw *hw, u8 index) · 27 unmodified lines | ||
| 732 | 726 | return 0; |
| 733 | 727 | } |
| 734 | 728 | |
| 735 | −const struct clk_ops clk_mmux_ops = { | |
| 729 | +static const struct clk_ops clk_mmux_ops = { | |
| 736 | 730 | .get_parent = clk_mmux_get_parent, |
| 737 | 731 | .set_parent = clk_mmux_set_parent, |
| 738 | 732 | .determine_rate = __clk_mux_determine_rate, |
| @@ -1048,10 +1042,10 @@ struct stm32_pll_cfg { · 309 unmodified lines | ||
| 1048 | 1042 | u32 offset; |
| 1049 | 1043 | }; |
| 1050 | 1044 | |
| 1051 | −struct clk_hw *_clk_register_pll(struct device *dev, | |
| 1052 | − struct clk_hw_onecell_data *clk_data, | |
| 1053 | − void __iomem *base, spinlock_t *lock, | |
| 1054 | − const struct clock_config *cfg) | |
| 1045 | +static struct clk_hw *_clk_register_pll(struct device *dev, | |
| 1046 | + struct clk_hw_onecell_data *clk_data, | |
| 1047 | + void __iomem *base, spinlock_t *lock, | |
| 1048 | + const struct clock_config *cfg) | |
| 1055 | 1049 | { |
| 1056 | 1050 | struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg; |
| 1057 | 1051 | |
| @@ -1405,7 +1399,8 @@ enum { · 347 unmodified lines | ||
| 1405 | 1399 | G_USBH, |
| 1406 | 1400 | G_ETHSTP, |
| 1407 | 1401 | G_RTCAPB, |
| 1408 | − G_TZC, | |
| 1402 | + G_TZC1, | |
| 1403 | + G_TZC2, | |
| 1409 | 1404 | G_TZPC, |
| 1410 | 1405 | G_IWDG1, |
| 1411 | 1406 | G_BSEC, |
| @@ -1417,7 +1412,7 @@ enum { · 5 unmodified lines | ||
| 1417 | 1412 | G_LAST |
| 1418 | 1413 | }; |
| 1419 | 1414 | |
| 1420 | −struct stm32_mgate mp1_mgate[G_LAST]; | |
| 1415 | +static struct stm32_mgate mp1_mgate[G_LAST]; | |
| 1421 | 1416 | |
| 1422 | 1417 | #define _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\ |
| 1423 | 1418 | _mgate, _ops)\ |
| @@ -1440,7 +1435,7 @@ struct stm32_mgate mp1_mgate[G_LAST]; · 16 unmodified lines | ||
| 1440 | 1435 | &mp1_mgate[_id], &mp1_mgate_clk_ops) |
| 1441 | 1436 | |
| 1442 | 1437 | /* Peripheral gates */ |
| 1443 | −struct stm32_gate_cfg per_gate_cfg[G_LAST] = { | |
| 1438 | +static struct stm32_gate_cfg per_gate_cfg[G_LAST] = { | |
| 1444 | 1439 | /* Multi gates */ |
| 1445 | 1440 | K_GATE(G_MDIO, RCC_APB1ENSETR, 31, 0), |
| 1446 | 1441 | K_MGATE(G_DAC12, RCC_APB1ENSETR, 29, 0), |
| @@ -1506,7 +1501,8 @@ struct stm32_gate_cfg per_gate_cfg[G_LAST] = { · 59 unmodified lines | ||
| 1506 | 1501 | K_GATE(G_BSEC, RCC_APB5ENSETR, 16, 0), |
| 1507 | 1502 | K_GATE(G_IWDG1, RCC_APB5ENSETR, 15, 0), |
| 1508 | 1503 | K_GATE(G_TZPC, RCC_APB5ENSETR, 13, 0), |
| 1509 | − K_GATE(G_TZC, RCC_APB5ENSETR, 12, 0), | |
| 1504 | + K_GATE(G_TZC2, RCC_APB5ENSETR, 12, 0), | |
| 1505 | + K_GATE(G_TZC1, RCC_APB5ENSETR, 11, 0), | |
| 1510 | 1506 | K_GATE(G_RTCAPB, RCC_APB5ENSETR, 8, 0), |
| 1511 | 1507 | K_MGATE(G_USART1, RCC_APB5ENSETR, 4, 0), |
| 1512 | 1508 | K_MGATE(G_I2C6, RCC_APB5ENSETR, 3, 0), |
| @@ -1600,7 +1596,7 @@ enum { · 87 unmodified lines | ||
| 1600 | 1596 | M_LAST |
| 1601 | 1597 | }; |
| 1602 | 1598 | |
| 1603 | −struct stm32_mmux ker_mux[M_LAST]; | |
| 1599 | +static struct stm32_mmux ker_mux[M_LAST]; | |
| 1604 | 1600 | |
| 1605 | 1601 | #define _K_MUX(_id, _offset, _shift, _width, _mux_flags, _mmux, _ops)\ |
| 1606 | 1602 | [_id] = {\ |
| @@ -1623,7 +1619,7 @@ struct stm32_mmux ker_mux[M_LAST]; · 16 unmodified lines | ||
| 1623 | 1619 | _K_MUX(_id, _offset, _shift, _width, _mux_flags,\ |
| 1624 | 1620 | &ker_mux[_id], &clk_mmux_ops) |
| 1625 | 1621 | |
| 1626 | −const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { | |
| 1622 | +static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { | |
| 1627 | 1623 | /* Kernel multi mux */ |
| 1628 | 1624 | K_MMUX(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0), |
| 1629 | 1625 | K_MMUX(M_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0), |
| @@ -1860,7 +1856,8 @@ static const struct clock_config stm32mp1_clock_cfg[] = { · 230 unmodified lines | ||
| 1860 | 1856 | PCLK(USART1, "usart1", "pclk5", 0, G_USART1), |
| 1861 | 1857 | PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IGNORE_UNUSED | |
| 1862 | 1858 | CLK_IS_CRITICAL, G_RTCAPB), |
| 1863 | − PCLK(TZC, "tzc", "pclk5", CLK_IGNORE_UNUSED, G_TZC), | |
| 1859 | + PCLK(TZC1, "tzc1", "ck_axi", CLK_IGNORE_UNUSED, G_TZC1), | |
| 1860 | + PCLK(TZC2, "tzc2", "ck_axi", CLK_IGNORE_UNUSED, G_TZC2), | |
| 1864 | 1861 | PCLK(TZPC, "tzpc", "pclk5", CLK_IGNORE_UNUSED, G_TZPC), |
| 1865 | 1862 | PCLK(IWDG1, "iwdg1", "pclk5", 0, G_IWDG1), |
| 1866 | 1863 | PCLK(BSEC, "bsec", "pclk5", CLK_IGNORE_UNUSED, G_BSEC), |
| @@ -1916,8 +1913,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = { · 49 unmodified lines | ||
| 1916 | 1913 | KCLK(RNG1_K, "rng1_k", rng_src, 0, G_RNG1, M_RNG1), |
| 1917 | 1914 | KCLK(RNG2_K, "rng2_k", rng_src, 0, G_RNG2, M_RNG2), |
| 1918 | 1915 | KCLK(USBPHY_K, "usbphy_k", usbphy_src, 0, G_USBPHY, M_USBPHY), |
| 1919 | − KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IGNORE_UNUSED, | |
| 1920 | − G_STGEN, M_STGEN), | |
| 1916 | + KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IS_CRITICAL, G_STGEN, M_STGEN), | |
| 1921 | 1917 | KCLK(SPDIF_K, "spdif_k", spdif_src, 0, G_SPDIF, M_SPDIF), |
| 1922 | 1918 | KCLK(SPI1_K, "spi1_k", spi123_src, 0, G_SPI1, M_SPI1), |
| 1923 | 1919 | KCLK(SPI2_K, "spi2_k", spi123_src, 0, G_SPI2, M_SPI23), |
| @@ -1948,8 +1944,8 @@ static const struct clock_config stm32mp1_clock_cfg[] = { · 24 unmodified lines | ||
| 1948 | 1944 | KCLK(FDCAN_K, "fdcan_k", fdcan_src, 0, G_FDCAN, M_FDCAN), |
| 1949 | 1945 | KCLK(SAI1_K, "sai1_k", sai_src, 0, G_SAI1, M_SAI1), |
| 1950 | 1946 | KCLK(SAI2_K, "sai2_k", sai2_src, 0, G_SAI2, M_SAI2), |
| 1951 | − KCLK(SAI3_K, "sai3_k", sai_src, 0, G_SAI2, M_SAI3), | |
| 1952 | − KCLK(SAI4_K, "sai4_k", sai_src, 0, G_SAI2, M_SAI4), | |
| 1947 | + KCLK(SAI3_K, "sai3_k", sai_src, 0, G_SAI3, M_SAI3), | |
| 1948 | + KCLK(SAI4_K, "sai4_k", sai_src, 0, G_SAI4, M_SAI4), | |
| 1953 | 1949 | KCLK(ADC12_K, "adc12_k", adc12_src, 0, G_ADC12, M_ADC12), |
| 1954 | 1950 | KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI), |
| 1955 | 1951 | KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1), |
| @@ -1992,10 +1988,6 @@ static const struct clock_config stm32mp1_clock_cfg[] = { · 36 unmodified lines | ||
| 1992 | 1988 | _DIV(RCC_MCO2CFGR, 4, 4, 0, NULL)), |
| 1993 | 1989 | |
| 1994 | 1990 | /* Debug clocks */ |
| 1995 | − FIXED_FACTOR(NO_ID, "ck_axi_div2", "ck_axi", 0, 1, 2), | |
| 1996 | − | |
| 1997 | − GATE(DBG, "ck_apb_dbg", "ck_axi_div2", 0, RCC_DBGCFGR, 8, 0), | |
| 1998 | − | |
| 1999 | 1991 | GATE(CK_DBG, "ck_sys_dbg", "ck_axi", 0, RCC_DBGCFGR, 8, 0), |
| 2000 | 1992 | |
| 2001 | 1993 | COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE, |
| @@ -426,9 +426,9 @@ static bool mux_is_better_rate(unsigned long rate, unsigned long now, · 425 unmodified lines | ||
| 426 | 426 | return now <= rate && now > best; |
| 427 | 427 | } |
| 428 | 428 | |
| 429 | −static int | |
| 430 | −clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req, | |
| 431 | − unsigned long flags) | |
| 429 | +int clk_mux_determine_rate_flags(struct clk_hw *hw, | |
| 430 | + struct clk_rate_request *req, | |
| 431 | + unsigned long flags) | |
| 432 | 432 | { |
| 433 | 433 | struct clk_core *core = hw->core, *parent, *best_parent = NULL; |
| 434 | 434 | int i, num_parents, ret; |
| @@ -488,6 +488,7 @@ out: · 53 unmodified lines | ||
| 488 | 488 | |
| 489 | 489 | return 0; |
| 490 | 490 | } |
| 491 | +EXPORT_SYMBOL_GPL(clk_mux_determine_rate_flags); | |
| 491 | 492 | |
| 492 | 493 | struct clk *__clk_lookup(const char *name) |
| 493 | 494 | { |
| @@ -153,10 +153,19 @@ static int clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index) · 152 unmodified lines | ||
| 153 | 153 | val << mux->shift); |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | +static int clk_regmap_mux_determine_rate(struct clk_hw *hw, | |
| 157 | + struct clk_rate_request *req) | |
| 158 | +{ | |
| 159 | + struct clk_regmap *clk = to_clk_regmap(hw); | |
| 160 | + struct clk_regmap_mux_data *mux = clk_get_regmap_mux_data(clk); | |
| 161 | + | |
| 162 | + return clk_mux_determine_rate_flags(hw, req, mux->flags); | |
| 163 | +} | |
| 164 | + | |
| 156 | 165 | const struct clk_ops clk_regmap_mux_ops = { |
| 157 | 166 | .get_parent = clk_regmap_mux_get_parent, |
| 158 | 167 | .set_parent = clk_regmap_mux_set_parent, |
| 159 | − .determine_rate = __clk_mux_determine_rate, | |
| 168 | + .determine_rate = clk_regmap_mux_determine_rate, | |
| 160 | 169 | }; |
| 161 | 170 | EXPORT_SYMBOL_GPL(clk_regmap_mux_ops); |
| 162 | 171 | |
| @@ -17,8 +17,6 @@ · 16 unmodified lines | ||
| 17 | 17 | #define AO_RTC_ALT_CLK_CNTL0 0x94 |
| 18 | 18 | #define AO_RTC_ALT_CLK_CNTL1 0x98 |
| 19 | 19 | |
| 20 | −extern const struct clk_ops meson_aoclk_gate_regmap_ops; | |
| 21 | − | |
| 22 | 20 | struct aoclk_cec_32k { |
| 23 | 21 | struct clk_hw hw; |
| 24 | 22 | struct regmap *regmap; |
| @@ -253,7 +253,7 @@ static struct clk_fixed_factor meson8b_fclk_div3_div = { · 252 unmodified lines | ||
| 253 | 253 | .mult = 1, |
| 254 | 254 | .div = 3, |
| 255 | 255 | .hw.init = &(struct clk_init_data){ |
| 256 | − .name = "fclk_div_div3", | |
| 256 | + .name = "fclk_div3_div", | |
| 257 | 257 | .ops = &clk_fixed_factor_ops, |
| 258 | 258 | .parent_names = (const char *[]){ "fixed_pll" }, |
| 259 | 259 | .num_parents = 1, |
| @@ -632,7 +632,8 @@ static struct clk_regmap meson8b_cpu_clk = { · 372 unmodified lines | ||
| 632 | 632 | .hw.init = &(struct clk_init_data){ |
| 633 | 633 | .name = "cpu_clk", |
| 634 | 634 | .ops = &clk_regmap_mux_ro_ops, |
| 635 | − .parent_names = (const char *[]){ "xtal", "cpu_out_sel" }, | |
| 635 | + .parent_names = (const char *[]){ "xtal", | |
| 636 | + "cpu_scale_out_sel" }, | |
| 636 | 637 | .num_parents = 2, |
| 637 | 638 | .flags = (CLK_SET_RATE_PARENT | |
| 638 | 639 | CLK_SET_RATE_NO_REPARENT), |
| @@ -133,6 +133,14 @@ config VT8500_TIMER · 132 unmodified lines | ||
| 133 | 133 | help |
| 134 | 134 | Enables support for the VT8500 driver. |
| 135 | 135 | |
| 136 | +config NPCM7XX_TIMER | |
| 137 | + bool "NPCM7xx timer driver" if COMPILE_TEST | |
| 138 | + depends on HAS_IOMEM | |
| 139 | + select CLKSRC_MMIO | |
| 140 | + help | |
| 141 | + Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx architecture, | |
| 142 | + While TIMER0 serves as clockevent and TIMER1 serves as clocksource. | |
| 143 | + | |
| 136 | 144 | config CADENCE_TTC_TIMER |
| 137 | 145 | bool "Cadence TTC timer driver" if COMPILE_TEST |
| 138 | 146 | depends on COMMON_CLK |
| @@ -56,6 +56,7 @@ obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o · 55 unmodified lines | ||
| 56 | 56 | obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o |
| 57 | 57 | obj-$(CONFIG_OWL_TIMER) += owl-timer.o |
| 58 | 58 | obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o |
| 59 | +obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o | |
| 59 | 60 | |
| 60 | 61 | obj-$(CONFIG_ARC_TIMERS) += arc_timer.o |
| 61 | 62 | obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o |
| @@ -17,9 +17,14 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/of_irq.h> |
| 18 | 18 | #include <linux/sched_clock.h> |
| 19 | 19 | |
| 20 | +#define TPM_PARAM 0x4 | |
| 21 | +#define TPM_PARAM_WIDTH_SHIFT 16 | |
| 22 | +#define TPM_PARAM_WIDTH_MASK (0xff << 16) | |
| 20 | 23 | #define TPM_SC 0x10 |
| 21 | 24 | #define TPM_SC_CMOD_INC_PER_CNT (0x1 << 3) |
| 22 | 25 | #define TPM_SC_CMOD_DIV_DEFAULT 0x3 |
| 26 | +#define TPM_SC_CMOD_DIV_MAX 0x7 | |
| 27 | +#define TPM_SC_TOF_MASK (0x1 << 7) | |
| 23 | 28 | #define TPM_CNT 0x14 |
| 24 | 29 | #define TPM_MOD 0x18 |
| 25 | 30 | #define TPM_STATUS 0x1c |
| @@ -29,8 +34,11 @@ · 3 unmodified lines | ||
| 29 | 34 | #define TPM_C0SC_MODE_SHIFT 2 |
| 30 | 35 | #define TPM_C0SC_MODE_MASK 0x3c |
| 31 | 36 | #define TPM_C0SC_MODE_SW_COMPARE 0x4 |
| 37 | +#define TPM_C0SC_CHF_MASK (0x1 << 7) | |
| 32 | 38 | #define TPM_C0V 0x24 |
| 33 | 39 | |
| 40 | +static int counter_width; | |
| 41 | +static int rating; | |
| 34 | 42 | static void __iomem *timer_base; |
| 35 | 43 | static struct clock_event_device clockevent_tpm; |
| 36 | 44 | |
| @@ -83,10 +91,11 @@ static int __init tpm_clocksource_init(unsigned long rate) · 46 unmodified lines | ||
| 83 | 91 | tpm_delay_timer.freq = rate; |
| 84 | 92 | register_current_timer_delay(&tpm_delay_timer); |
| 85 | 93 | |
| 86 | − sched_clock_register(tpm_read_sched_clock, 32, rate); | |
| 94 | + sched_clock_register(tpm_read_sched_clock, counter_width, rate); | |
| 87 | 95 | |
| 88 | 96 | return clocksource_mmio_init(timer_base + TPM_CNT, "imx-tpm", |
| 89 | − rate, 200, 32, clocksource_mmio_readl_up); | |
| 97 | + rate, rating, counter_width, | |
| 98 | + clocksource_mmio_readl_up); | |
| 90 | 99 | } |
| 91 | 100 | |
| 92 | 101 | static int tpm_set_next_event(unsigned long delta, |
| @@ -105,7 +114,7 @@ static int tpm_set_next_event(unsigned long delta, · 12 unmodified lines | ||
| 105 | 114 | * of writing CNT registers which may cause the min_delta event got |
| 106 | 115 | * missed, so we need add a ETIME check here in case it happened. |
| 107 | 116 | */ |
| 108 | − return (int)((next - now) <= 0) ? -ETIME : 0; | |
| 117 | + return (int)(next - now) <= 0 ? -ETIME : 0; | |
| 109 | 118 | } |
| 110 | 119 | |
| 111 | 120 | static int tpm_set_state_oneshot(struct clock_event_device *evt) |
| @@ -139,7 +148,6 @@ static struct clock_event_device clockevent_tpm = { · 27 unmodified lines | ||
| 139 | 148 | .set_state_oneshot = tpm_set_state_oneshot, |
| 140 | 149 | .set_next_event = tpm_set_next_event, |
| 141 | 150 | .set_state_shutdown = tpm_set_state_shutdown, |
| 142 | − .rating = 200, | |
| 143 | 151 | }; |
| 144 | 152 | |
| 145 | 153 | static int __init tpm_clockevent_init(unsigned long rate, int irq) |
| @@ -149,10 +157,11 @@ static int __init tpm_clockevent_init(unsigned long rate, int irq) · 3 unmodified lines | ||
| 149 | 157 | ret = request_irq(irq, tpm_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, |
| 150 | 158 | "i.MX7ULP TPM Timer", &clockevent_tpm); |
| 151 | 159 | |
| 160 | + clockevent_tpm.rating = rating; | |
| 152 | 161 | clockevent_tpm.cpumask = cpumask_of(0); |
| 153 | 162 | clockevent_tpm.irq = irq; |
| 154 | − clockevents_config_and_register(&clockevent_tpm, | |
| 155 | − rate, 300, 0xfffffffe); | |
| 163 | + clockevents_config_and_register(&clockevent_tpm, rate, 300, | |
| 164 | + GENMASK(counter_width - 1, 1)); | |
| 156 | 165 | |
| 157 | 166 | return ret; |
| 158 | 167 | } |
| @@ -179,7 +188,7 @@ static int __init tpm_timer_init(struct device_node *np) · 20 unmodified lines | ||
| 179 | 188 | ipg = of_clk_get_by_name(np, "ipg"); |
| 180 | 189 | per = of_clk_get_by_name(np, "per"); |
| 181 | 190 | if (IS_ERR(ipg) || IS_ERR(per)) { |
| 182 | − pr_err("tpm: failed to get igp or per clk\n"); | |
| 191 | + pr_err("tpm: failed to get ipg or per clk\n"); | |
| 183 | 192 | ret = -ENODEV; |
| 184 | 193 | goto err_clk_get; |
| 185 | 194 | } |
| @@ -197,6 +206,11 @@ static int __init tpm_timer_init(struct device_node *np) · 11 unmodified lines | ||
| 197 | 206 | goto err_per_clk_enable; |
| 198 | 207 | } |
| 199 | 208 | |
| 209 | + counter_width = (readl(timer_base + TPM_PARAM) & TPM_PARAM_WIDTH_MASK) | |
| 210 | + >> TPM_PARAM_WIDTH_SHIFT; | |
| 211 | + /* use rating 200 for 32-bit counter and 150 for 16-bit counter */ | |
| 212 | + rating = counter_width == 0x20 ? 200 : 150; | |
| 213 | + | |
| 200 | 214 | /* |
| 201 | 215 | * Initialize tpm module to a known state |
| 202 | 216 | * 1) Counter disabled |
| @@ -205,16 +219,25 @@ static int __init tpm_timer_init(struct device_node *np) · 2 unmodified lines | ||
| 205 | 219 | * 4) Channel0 disabled |
| 206 | 220 | * 5) DMA transfers disabled |
| 207 | 221 | */ |
| 222 | + /* make sure counter is disabled */ | |
| 208 | 223 | writel(0, timer_base + TPM_SC); |
| 224 | + /* TOF is W1C */ | |
| 225 | + writel(TPM_SC_TOF_MASK, timer_base + TPM_SC); | |
| 209 | 226 | writel(0, timer_base + TPM_CNT); |
| 210 | − writel(0, timer_base + TPM_C0SC); | |
| 227 | + /* CHF is W1C */ | |
| 228 | + writel(TPM_C0SC_CHF_MASK, timer_base + TPM_C0SC); | |
| 211 | 229 | |
| 212 | − /* increase per cnt, div 8 by default */ | |
| 213 | − writel(TPM_SC_CMOD_INC_PER_CNT | TPM_SC_CMOD_DIV_DEFAULT, | |
| 230 | + /* | |
| 231 | + * increase per cnt, | |
| 232 | + * div 8 for 32-bit counter and div 128 for 16-bit counter | |
| 233 | + */ | |
| 234 | + writel(TPM_SC_CMOD_INC_PER_CNT | | |
| 235 | + (counter_width == 0x20 ? | |
| 236 | + TPM_SC_CMOD_DIV_DEFAULT : TPM_SC_CMOD_DIV_MAX), | |
| 214 | 237 | timer_base + TPM_SC); |
| 215 | 238 | |
| 216 | 239 | /* set MOD register to maximum for free running mode */ |
| 217 | − writel(0xffffffff, timer_base + TPM_MOD); | |
| 240 | + writel(GENMASK(counter_width - 1, 0), timer_base + TPM_MOD); | |
| 218 | 241 | |
| 219 | 242 | rate = clk_get_rate(per) >> 3; |
| 220 | 243 | ret = tpm_clocksource_init(rate); |
| @@ -0,0 +1,215 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Copyright (C) 2014-2018 Nuvoton Technologies tomer.maimon@nuvoton.com | |
| 4 | + * All rights reserved. | |
| 5 | + * | |
| 6 | + * Copyright 2017 Google, Inc. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#include <linux/kernel.h> | |
| 10 | +#include <linux/sched.h> | |
| 11 | +#include <linux/init.h> | |
| 12 | +#include <linux/interrupt.h> | |
| 13 | +#include <linux/err.h> | |
| 14 | +#include <linux/clk.h> | |
| 15 | +#include <linux/io.h> | |
| 16 | +#include <linux/clockchips.h> | |
| 17 | +#include <linux/of_irq.h> | |
| 18 | +#include <linux/of_address.h> | |
| 19 | +#include "timer-of.h" | |
| 20 | + | |
| 21 | +/* Timers registers */ | |
| 22 | +#define NPCM7XX_REG_TCSR0 0x0 /* Timer 0 Control and Status Register */ | |
| 23 | +#define NPCM7XX_REG_TICR0 0x8 /* Timer 0 Initial Count Register */ | |
| 24 | +#define NPCM7XX_REG_TCSR1 0x4 /* Timer 1 Control and Status Register */ | |
| 25 | +#define NPCM7XX_REG_TICR1 0xc /* Timer 1 Initial Count Register */ | |
| 26 | +#define NPCM7XX_REG_TDR1 0x14 /* Timer 1 Data Register */ | |
| 27 | +#define NPCM7XX_REG_TISR 0x18 /* Timer Interrupt Status Register */ | |
| 28 | + | |
| 29 | +/* Timers control */ | |
| 30 | +#define NPCM7XX_Tx_RESETINT 0x1f | |
| 31 | +#define NPCM7XX_Tx_PERIOD BIT(27) | |
| 32 | +#define NPCM7XX_Tx_INTEN BIT(29) | |
| 33 | +#define NPCM7XX_Tx_COUNTEN BIT(30) | |
| 34 | +#define NPCM7XX_Tx_ONESHOT 0x0 | |
| 35 | +#define NPCM7XX_Tx_OPER GENMASK(3, 27) | |
| 36 | +#define NPCM7XX_Tx_MIN_PRESCALE 0x1 | |
| 37 | +#define NPCM7XX_Tx_TDR_MASK_BITS 24 | |
| 38 | +#define NPCM7XX_Tx_MAX_CNT 0xFFFFFF | |
| 39 | +#define NPCM7XX_T0_CLR_INT 0x1 | |
| 40 | +#define NPCM7XX_Tx_CLR_CSR 0x0 | |
| 41 | + | |
| 42 | +/* Timers operating mode */ | |
| 43 | +#define NPCM7XX_START_PERIODIC_Tx (NPCM7XX_Tx_PERIOD | NPCM7XX_Tx_COUNTEN | \ | |
| 44 | + NPCM7XX_Tx_INTEN | \ | |
| 45 | + NPCM7XX_Tx_MIN_PRESCALE) | |
| 46 | + | |
| 47 | +#define NPCM7XX_START_ONESHOT_Tx (NPCM7XX_Tx_ONESHOT | NPCM7XX_Tx_COUNTEN | \ | |
| 48 | + NPCM7XX_Tx_INTEN | \ | |
| 49 | + NPCM7XX_Tx_MIN_PRESCALE) | |
| 50 | + | |
| 51 | +#define NPCM7XX_START_Tx (NPCM7XX_Tx_COUNTEN | NPCM7XX_Tx_PERIOD | \ | |
| 52 | + NPCM7XX_Tx_MIN_PRESCALE) | |
| 53 | + | |
| 54 | +#define NPCM7XX_DEFAULT_CSR (NPCM7XX_Tx_CLR_CSR | NPCM7XX_Tx_MIN_PRESCALE) | |
| 55 | + | |
| 56 | +static int npcm7xx_timer_resume(struct clock_event_device *evt) | |
| 57 | +{ | |
| 58 | + struct timer_of *to = to_timer_of(evt); | |
| 59 | + u32 val; | |
| 60 | + | |
| 61 | + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 62 | + val |= NPCM7XX_Tx_COUNTEN; | |
| 63 | + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 64 | + | |
| 65 | + return 0; | |
| 66 | +} | |
| 67 | + | |
| 68 | +static int npcm7xx_timer_shutdown(struct clock_event_device *evt) | |
| 69 | +{ | |
| 70 | + struct timer_of *to = to_timer_of(evt); | |
| 71 | + u32 val; | |
| 72 | + | |
| 73 | + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 74 | + val &= ~NPCM7XX_Tx_COUNTEN; | |
| 75 | + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 76 | + | |
| 77 | + return 0; | |
| 78 | +} | |
| 79 | + | |
| 80 | +static int npcm7xx_timer_oneshot(struct clock_event_device *evt) | |
| 81 | +{ | |
| 82 | + struct timer_of *to = to_timer_of(evt); | |
| 83 | + u32 val; | |
| 84 | + | |
| 85 | + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 86 | + val &= ~NPCM7XX_Tx_OPER; | |
| 87 | + | |
| 88 | + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 89 | + val |= NPCM7XX_START_ONESHOT_Tx; | |
| 90 | + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 91 | + | |
| 92 | + return 0; | |
| 93 | +} | |
| 94 | + | |
| 95 | +static int npcm7xx_timer_periodic(struct clock_event_device *evt) | |
| 96 | +{ | |
| 97 | + struct timer_of *to = to_timer_of(evt); | |
| 98 | + u32 val; | |
| 99 | + | |
| 100 | + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 101 | + val &= ~NPCM7XX_Tx_OPER; | |
| 102 | + | |
| 103 | + writel(timer_of_period(to), timer_of_base(to) + NPCM7XX_REG_TICR0); | |
| 104 | + val |= NPCM7XX_START_PERIODIC_Tx; | |
| 105 | + | |
| 106 | + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 107 | + | |
| 108 | + return 0; | |
| 109 | +} | |
| 110 | + | |
| 111 | +static int npcm7xx_clockevent_set_next_event(unsigned long evt, | |
| 112 | + struct clock_event_device *clk) | |
| 113 | +{ | |
| 114 | + struct timer_of *to = to_timer_of(clk); | |
| 115 | + u32 val; | |
| 116 | + | |
| 117 | + writel(evt, timer_of_base(to) + NPCM7XX_REG_TICR0); | |
| 118 | + val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 119 | + val |= NPCM7XX_START_Tx; | |
| 120 | + writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0); | |
| 121 | + | |
| 122 | + return 0; | |
| 123 | +} | |
| 124 | + | |
| 125 | +static irqreturn_t npcm7xx_timer0_interrupt(int irq, void *dev_id) | |
| 126 | +{ | |
| 127 | + struct clock_event_device *evt = (struct clock_event_device *)dev_id; | |
| 128 | + struct timer_of *to = to_timer_of(evt); | |
| 129 | + | |
| 130 | + writel(NPCM7XX_T0_CLR_INT, timer_of_base(to) + NPCM7XX_REG_TISR); | |
| 131 | + | |
| 132 | + evt->event_handler(evt); | |
| 133 | + | |
| 134 | + return IRQ_HANDLED; | |
| 135 | +} | |
| 136 | + | |
| 137 | +static struct timer_of npcm7xx_to = { | |
| 138 | + .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK, | |
| 139 | + | |
| 140 | + .clkevt = { | |
| 141 | + .name = "npcm7xx-timer0", | |
| 142 | + .features = CLOCK_EVT_FEAT_PERIODIC | | |
| 143 | + CLOCK_EVT_FEAT_ONESHOT, | |
| 144 | + .set_next_event = npcm7xx_clockevent_set_next_event, | |
| 145 | + .set_state_shutdown = npcm7xx_timer_shutdown, | |
| 146 | + .set_state_periodic = npcm7xx_timer_periodic, | |
| 147 | + .set_state_oneshot = npcm7xx_timer_oneshot, | |
| 148 | + .tick_resume = npcm7xx_timer_resume, | |
| 149 | + .rating = 300, | |
| 150 | + }, | |
| 151 | + | |
| 152 | + .of_irq = { | |
| 153 | + .handler = npcm7xx_timer0_interrupt, | |
| 154 | + .flags = IRQF_TIMER | IRQF_IRQPOLL, | |
| 155 | + }, | |
| 156 | +}; | |
| 157 | + | |
| 158 | +static void __init npcm7xx_clockevents_init(void) | |
| 159 | +{ | |
| 160 | + writel(NPCM7XX_DEFAULT_CSR, | |
| 161 | + timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR0); | |
| 162 | + | |
| 163 | + writel(NPCM7XX_Tx_RESETINT, | |
| 164 | + timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TISR); | |
| 165 | + | |
| 166 | + npcm7xx_to.clkevt.cpumask = cpumask_of(0); | |
| 167 | + clockevents_config_and_register(&npcm7xx_to.clkevt, | |
| 168 | + timer_of_rate(&npcm7xx_to), | |
| 169 | + 0x1, NPCM7XX_Tx_MAX_CNT); | |
| 170 | +} | |
| 171 | + | |
| 172 | +static void __init npcm7xx_clocksource_init(void) | |
| 173 | +{ | |
| 174 | + u32 val; | |
| 175 | + | |
| 176 | + writel(NPCM7XX_DEFAULT_CSR, | |
| 177 | + timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1); | |
| 178 | + writel(NPCM7XX_Tx_MAX_CNT, | |
| 179 | + timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TICR1); | |
| 180 | + | |
| 181 | + val = readl(timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1); | |
| 182 | + val |= NPCM7XX_START_Tx; | |
| 183 | + writel(val, timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1); | |
| 184 | + | |
| 185 | + clocksource_mmio_init(timer_of_base(&npcm7xx_to) + | |
| 186 | + NPCM7XX_REG_TDR1, | |
| 187 | + "npcm7xx-timer1", timer_of_rate(&npcm7xx_to), | |
| 188 | + 200, (unsigned int)NPCM7XX_Tx_TDR_MASK_BITS, | |
| 189 | + clocksource_mmio_readl_down); | |
| 190 | +} | |
| 191 | + | |
| 192 | +static int __init npcm7xx_timer_init(struct device_node *np) | |
| 193 | +{ | |
| 194 | + int ret; | |
| 195 | + | |
| 196 | + ret = timer_of_init(np, &npcm7xx_to); | |
| 197 | + if (ret) | |
| 198 | + return ret; | |
| 199 | + | |
| 200 | + /* Clock input is divided by PRESCALE + 1 before it is fed */ | |
| 201 | + /* to the counter */ | |
| 202 | + npcm7xx_to.of_clk.rate = npcm7xx_to.of_clk.rate / | |
| 203 | + (NPCM7XX_Tx_MIN_PRESCALE + 1); | |
| 204 | + | |
| 205 | + npcm7xx_clocksource_init(); | |
| 206 | + npcm7xx_clockevents_init(); | |
| 207 | + | |
| 208 | + pr_info("Enabling NPCM7xx clocksource timer base: %px, IRQ: %d ", | |
| 209 | + timer_of_base(&npcm7xx_to), timer_of_irq(&npcm7xx_to)); | |
| 210 | + | |
| 211 | + return 0; | |
| 212 | +} | |
| 213 | + | |
| 214 | +TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init); | |
| 215 | + | |
| @@ -71,16 +71,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ · 70 unmodified lines | ||
| 71 | 71 | |
| 72 | 72 | Say Y, if you have a Broadcom SoC with AVS support for DFS or DVFS. |
| 73 | 73 | |
| 74 | −config ARM_BRCMSTB_AVS_CPUFREQ_DEBUG | |
| 75 | − bool "Broadcom STB AVS CPUfreq driver sysfs debug capability" | |
| 76 | − depends on ARM_BRCMSTB_AVS_CPUFREQ | |
| 77 | − help | |
| 78 | − Enabling this option turns on debug support via sysfs under | |
| 79 | − /sys/kernel/debug/brcmstb-avs-cpufreq. It is possible to read all and | |
| 80 | − write some AVS mailbox registers through sysfs entries. | |
| 81 | − | |
| 82 | − If in doubt, say N. | |
| 83 | − | |
| 84 | 74 | config ARM_EXYNOS5440_CPUFREQ |
| 85 | 75 | tristate "SAMSUNG EXYNOS5440" |
| 86 | 76 | depends on SOC_EXYNOS5440 |
| @@ -49,13 +49,6 @@ · 48 unmodified lines | ||
| 49 | 49 | #include <linux/platform_device.h> |
| 50 | 50 | #include <linux/semaphore.h> |
| 51 | 51 | |
| 52 | −#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG | |
| 53 | −#include <linux/ctype.h> | |
| 54 | −#include <linux/debugfs.h> | |
| 55 | −#include <linux/slab.h> | |
| 56 | −#include <linux/uaccess.h> | |
| 57 | −#endif | |
| 58 | − | |
| 59 | 52 | /* Max number of arguments AVS calls take */ |
| 60 | 53 | #define AVS_MAX_CMD_ARGS 4 |
| 61 | 54 | /* |
| @@ -182,88 +175,11 @@ struct private_data { · 120 unmodified lines | ||
| 182 | 175 | void __iomem *base; |
| 183 | 176 | void __iomem *avs_intr_base; |
| 184 | 177 | struct device *dev; |
| 185 | −#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG | |
| 186 | − struct dentry *debugfs; | |
| 187 | −#endif | |
| 188 | 178 | struct completion done; |
| 189 | 179 | struct semaphore sem; |
| 190 | 180 | struct pmap pmap; |
| 191 | 181 | }; |
| 192 | 182 | |
| 193 | −#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG | |
| 194 | − | |
| 195 | −enum debugfs_format { | |
| 196 | − DEBUGFS_NORMAL, | |
| 197 | − DEBUGFS_FLOAT, | |
| 198 | − DEBUGFS_REV, | |
| 199 | −}; | |
| 200 | − | |
| 201 | −struct debugfs_data { | |
| 202 | − struct debugfs_entry *entry; | |
| 203 | − struct private_data *priv; | |
| 204 | −}; | |
| 205 | − | |
| 206 | −struct debugfs_entry { | |
| 207 | − char *name; | |
| 208 | − u32 offset; | |
| 209 | − fmode_t mode; | |
| 210 | − enum debugfs_format format; | |
| 211 | −}; | |
| 212 | − | |
| 213 | −#define DEBUGFS_ENTRY(name, mode, format) { \ | |
| 214 | − #name, AVS_MBOX_##name, mode, format \ | |
| 215 | −} | |
| 216 | − | |
| 217 | −/* | |
| 218 | − * These are used for debugfs only. Otherwise we use AVS_MBOX_PARAM() directly. | |
| 219 | − */ | |
| 220 | −#define AVS_MBOX_PARAM1 AVS_MBOX_PARAM(0) | |
| 221 | −#define AVS_MBOX_PARAM2 AVS_MBOX_PARAM(1) | |
| 222 | −#define AVS_MBOX_PARAM3 AVS_MBOX_PARAM(2) | |
| 223 | −#define AVS_MBOX_PARAM4 AVS_MBOX_PARAM(3) | |
| 224 | − | |
| 225 | −/* | |
| 226 | − * This table stores the name, access permissions and offset for each hardware | |
| 227 | − * register and is used to generate debugfs entries. | |
| 228 | − */ | |
| 229 | −static struct debugfs_entry debugfs_entries[] = { | |
| 230 | − DEBUGFS_ENTRY(COMMAND, S_IWUSR, DEBUGFS_NORMAL), | |
| 231 | − DEBUGFS_ENTRY(STATUS, S_IWUSR, DEBUGFS_NORMAL), | |
| 232 | − DEBUGFS_ENTRY(VOLTAGE0, 0, DEBUGFS_FLOAT), | |
| 233 | − DEBUGFS_ENTRY(TEMP0, 0, DEBUGFS_FLOAT), | |
| 234 | − DEBUGFS_ENTRY(PV0, 0, DEBUGFS_FLOAT), | |
| 235 | − DEBUGFS_ENTRY(MV0, 0, DEBUGFS_FLOAT), | |
| 236 | − DEBUGFS_ENTRY(PARAM1, S_IWUSR, DEBUGFS_NORMAL), | |
| 237 | − DEBUGFS_ENTRY(PARAM2, S_IWUSR, DEBUGFS_NORMAL), | |
| 238 | − DEBUGFS_ENTRY(PARAM3, S_IWUSR, DEBUGFS_NORMAL), | |
| 239 | − DEBUGFS_ENTRY(PARAM4, S_IWUSR, DEBUGFS_NORMAL), | |
| 240 | − DEBUGFS_ENTRY(REVISION, 0, DEBUGFS_REV), | |
| 241 | − DEBUGFS_ENTRY(PSTATE, 0, DEBUGFS_NORMAL), | |
| 242 | − DEBUGFS_ENTRY(HEARTBEAT, 0, DEBUGFS_NORMAL), | |
| 243 | − DEBUGFS_ENTRY(MAGIC, S_IWUSR, DEBUGFS_NORMAL), | |
| 244 | − DEBUGFS_ENTRY(SIGMA_HVT, 0, DEBUGFS_NORMAL), | |
| 245 | − DEBUGFS_ENTRY(SIGMA_SVT, 0, DEBUGFS_NORMAL), | |
| 246 | − DEBUGFS_ENTRY(VOLTAGE1, 0, DEBUGFS_FLOAT), | |
| 247 | − DEBUGFS_ENTRY(TEMP1, 0, DEBUGFS_FLOAT), | |
| 248 | − DEBUGFS_ENTRY(PV1, 0, DEBUGFS_FLOAT), | |
| 249 | − DEBUGFS_ENTRY(MV1, 0, DEBUGFS_FLOAT), | |
| 250 | − DEBUGFS_ENTRY(FREQUENCY, 0, DEBUGFS_NORMAL), | |
| 251 | −}; | |
| 252 | − | |
| 253 | −static int brcm_avs_target_index(struct cpufreq_policy *, unsigned int); | |
| 254 | − | |
| 255 | −static char *__strtolower(char *s) | |
| 256 | −{ | |
| 257 | − char *p; | |
| 258 | − | |
| 259 | − for (p = s; *p; p++) | |
| 260 | − *p = tolower(*p); | |
| 261 | − | |
| 262 | − return s; | |
| 263 | −} | |
| 264 | − | |
| 265 | −#endif /* CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG */ | |
| 266 | − | |
| 267 | 183 | static void __iomem *__map_region(const char *name) |
| 268 | 184 | { |
| 269 | 185 | struct device_node *np; |
| @@ -516,238 +432,6 @@ brcm_avs_get_freq_table(struct device *dev, struct private_data *priv) · 246 unmodified lines | ||
| 516 | 432 | return table; |
| 517 | 433 | } |
| 518 | 434 | |
| 519 | −#ifdef CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG | |
| 520 | − | |
| 521 | −#define MANT(x) (unsigned int)(abs((x)) / 1000) | |
| 522 | −#define FRAC(x) (unsigned int)(abs((x)) - abs((x)) / 1000 * 1000) | |
| 523 | − | |
| 524 | −static int brcm_avs_debug_show(struct seq_file *s, void *data) | |
| 525 | −{ | |
| 526 | − struct debugfs_data *dbgfs = s->private; | |
| 527 | − void __iomem *base; | |
| 528 | − u32 val, offset; | |
| 529 | − | |
| 530 | − if (!dbgfs) { | |
| 531 | − seq_puts(s, "No device pointer\n"); | |
| 532 | − return 0; | |
| 533 | − } | |
| 534 | − | |
| 535 | − base = dbgfs->priv->base; | |
| 536 | − offset = dbgfs->entry->offset; | |
| 537 | − val = readl(base + offset); | |
| 538 | − switch (dbgfs->entry->format) { | |
| 539 | − case DEBUGFS_NORMAL: | |
| 540 | − seq_printf(s, "%u\n", val); | |
| 541 | − break; | |
| 542 | − case DEBUGFS_FLOAT: | |
| 543 | − seq_printf(s, "%d.%03d\n", MANT(val), FRAC(val)); | |
| 544 | − break; | |
| 545 | − case DEBUGFS_REV: | |
| 546 | − seq_printf(s, "%c.%c.%c.%c\n", (val >> 24 & 0xff), | |
| 547 | − (val >> 16 & 0xff), (val >> 8 & 0xff), | |
| 548 | − val & 0xff); | |
| 549 | − break; | |
| 550 | − } | |
| 551 | − seq_printf(s, "0x%08x\n", val); | |
| 552 | − | |
| 553 | − return 0; | |
| 554 | −} | |
| 555 | − | |
| 556 | −#undef MANT | |
| 557 | −#undef FRAC | |
| 558 | − | |
| 559 | −static ssize_t brcm_avs_seq_write(struct file *file, const char __user *buf, | |
| 560 | − size_t size, loff_t *ppos) | |
| 561 | −{ | |
| 562 | − struct seq_file *s = file->private_data; | |
| 563 | − struct debugfs_data *dbgfs = s->private; | |
| 564 | − struct private_data *priv = dbgfs->priv; | |
| 565 | − void __iomem *base, *avs_intr_base; | |
| 566 | − bool use_issue_command = false; | |
| 567 | − unsigned long val, offset; | |
| 568 | − char str[128]; | |
| 569 | − int ret; | |
| 570 | − char *str_ptr = str; | |
| 571 | − | |
| 572 | − if (size >= sizeof(str)) | |
| 573 | − return -E2BIG; | |
| 574 | − | |
| 575 | − memset(str, 0, sizeof(str)); | |
| 576 | − ret = copy_from_user(str, buf, size); | |
| 577 | − if (ret) | |
| 578 | − return ret; | |
| 579 | − | |
| 580 | − base = priv->base; | |
| 581 | − avs_intr_base = priv->avs_intr_base; | |
| 582 | − offset = dbgfs->entry->offset; | |
| 583 | − /* | |
| 584 | − * Special case writing to "command" entry only: if the string starts | |
| 585 | − * with a 'c', we use the driver's __issue_avs_command() function. | |
| 586 | − * Otherwise, we perform a raw write. This should allow testing of raw | |
| 587 | − * access as well as using the higher level function. (Raw access | |
| 588 | − * doesn't clear the firmware return status after issuing the command.) | |
| 589 | − */ | |
| 590 | − if (str_ptr[0] == 'c' && offset == AVS_MBOX_COMMAND) { | |
| 591 | − use_issue_command = true; | |
| 592 | − str_ptr++; | |
| 593 | − } | |
| 594 | − if (kstrtoul(str_ptr, 0, &val) != 0) | |
| 595 | − return -EINVAL; | |
| 596 | − | |
| 597 | − /* | |
| 598 | − * Setting the P-state is a special case. We need to update the CPU | |
| 599 | − * frequency we report. | |
| 600 | − */ | |
| 601 | − if (val == AVS_CMD_SET_PSTATE) { | |
| 602 | − struct cpufreq_policy *policy; | |
| 603 | − unsigned int pstate; | |
| 604 | − | |
| 605 | − policy = cpufreq_cpu_get(smp_processor_id()); | |
| 606 | − /* Read back the P-state we are about to set */ | |
| 607 | − pstate = readl(base + AVS_MBOX_PARAM(0)); | |
| 608 | − if (use_issue_command) { | |
| 609 | − ret = brcm_avs_target_index(policy, pstate); | |
| 610 | − return ret ? ret : size; | |
| 611 | − } | |
| 612 | − policy->cur = policy->freq_table[pstate].frequency; | |
| 613 | − } | |
| 614 | − | |
| 615 | − if (use_issue_command) { | |
| 616 | − ret = __issue_avs_command(priv, val, false, NULL); | |
| 617 | − } else { | |
| 618 | − /* Locking here is not perfect, but is only for debug. */ | |
| 619 | − ret = down_interruptible(&priv->sem); | |
| 620 | − if (ret) | |
| 621 | − return ret; | |
| 622 | − | |
| 623 | − writel(val, base + offset); | |
| 624 | − /* We have to wake up the firmware to process a command. */ | |
| 625 | − if (offset == AVS_MBOX_COMMAND) | |
| 626 | − writel(AVS_CPU_L2_INT_MASK, | |
| 627 | − avs_intr_base + AVS_CPU_L2_SET0); | |
| 628 | − up(&priv->sem); | |
| 629 | − } | |
| 630 | − | |
| 631 | − return ret ? ret : size; | |
| 632 | −} | |
| 633 | − | |
| 634 | −static struct debugfs_entry *__find_debugfs_entry(const char *name) | |
| 635 | −{ | |
| 636 | − int i; | |
| 637 | − | |
| 638 | − for (i = 0; i < ARRAY_SIZE(debugfs_entries); i++) | |
| 639 | − if (strcasecmp(debugfs_entries[i].name, name) == 0) | |
| 640 | − return &debugfs_entries[i]; | |
| 641 | − | |
| 642 | − return NULL; | |
| 643 | −} | |
| 644 | − | |
| 645 | −static int brcm_avs_debug_open(struct inode *inode, struct file *file) | |
| 646 | −{ | |
| 647 | − struct debugfs_data *data; | |
| 648 | − fmode_t fmode; | |
| 649 | − int ret; | |
| 650 | − | |
| 651 | − /* | |
| 652 | − * seq_open(), which is called by single_open(), clears "write" access. | |
| 653 | − * We need write access to some files, so we preserve our access mode | |
| 654 | − * and restore it. | |
| 655 | − */ | |
| 656 | − fmode = file->f_mode; | |
| 657 | − /* | |
| 658 | − * Check access permissions even for root. We don't want to be writing | |
| 659 | − * to read-only registers. Access for regular users has already been | |
| 660 | − * checked by the VFS layer. | |
| 661 | − */ | |
| 662 | − if ((fmode & FMODE_WRITER) && !(inode->i_mode & S_IWUSR)) | |
| 663 | − return -EACCES; | |
| 664 | − | |
| 665 | − data = kmalloc(sizeof(*data), GFP_KERNEL); | |
| 666 | − if (!data) | |
| 667 | − return -ENOMEM; | |
| 668 | − /* | |
| 669 | − * We use the same file system operations for all our debug files. To | |
| 670 | − * produce specific output, we look up the file name upon opening a | |
| 671 | − * debugfs entry and map it to a memory offset. This offset is then used | |
| 672 | − * in the generic "show" function to read a specific register. | |
| 673 | − */ | |
| 674 | − data->entry = __find_debugfs_entry(file->f_path.dentry->d_iname); | |
| 675 | − data->priv = inode->i_private; | |
| 676 | − | |
| 677 | − ret = single_open(file, brcm_avs_debug_show, data); | |
| 678 | − if (ret) | |
| 679 | − kfree(data); | |
| 680 | − file->f_mode = fmode; | |
| 681 | − | |
| 682 | − return ret; | |
| 683 | −} | |
| 684 | − | |
| 685 | −static int brcm_avs_debug_release(struct inode *inode, struct file *file) | |
| 686 | −{ | |
| 687 | − struct seq_file *seq_priv = file->private_data; | |
| 688 | − struct debugfs_data *data = seq_priv->private; | |
| 689 | − | |
| 690 | − kfree(data); | |
| 691 | − return single_release(inode, file); | |
| 692 | −} | |
| 693 | − | |
| 694 | −static const struct file_operations brcm_avs_debug_ops = { | |
| 695 | − .open = brcm_avs_debug_open, | |
| 696 | − .read = seq_read, | |
| 697 | − .write = brcm_avs_seq_write, | |
| 698 | − .llseek = seq_lseek, | |
| 699 | − .release = brcm_avs_debug_release, | |
| 700 | −}; | |
| 701 | − | |
| 702 | −static void brcm_avs_cpufreq_debug_init(struct platform_device *pdev) | |
| 703 | −{ | |
| 704 | − struct private_data *priv = platform_get_drvdata(pdev); | |
| 705 | − struct dentry *dir; | |
| 706 | − int i; | |
| 707 | − | |
| 708 | − if (!priv) | |
| 709 | − return; | |
| 710 | − | |
| 711 | − dir = debugfs_create_dir(BRCM_AVS_CPUFREQ_NAME, NULL); | |
| 712 | − if (IS_ERR_OR_NULL(dir)) | |
| 713 | − return; | |
| 714 | − priv->debugfs = dir; | |
| 715 | − | |
| 716 | − for (i = 0; i < ARRAY_SIZE(debugfs_entries); i++) { | |
| 717 | − /* | |
| 718 | − * The DEBUGFS_ENTRY macro generates uppercase strings. We | |
| 719 | − * convert them to lowercase before creating the debugfs | |
| 720 | − * entries. | |
| 721 | − */ | |
| 722 | − char *entry = __strtolower(debugfs_entries[i].name); | |
| 723 | − fmode_t mode = debugfs_entries[i].mode; | |
| 724 | − | |
| 725 | − if (!debugfs_create_file(entry, S_IFREG | S_IRUGO | mode, | |
| 726 | − dir, priv, &brcm_avs_debug_ops)) { | |
| 727 | − priv->debugfs = NULL; | |
| 728 | − debugfs_remove_recursive(dir); | |
| 729 | − break; | |
| 730 | − } | |
| 731 | − } | |
| 732 | −} | |
| 733 | − | |
| 734 | −static void brcm_avs_cpufreq_debug_exit(struct platform_device *pdev) | |
| 735 | −{ | |
| 736 | − struct private_data *priv = platform_get_drvdata(pdev); | |
| 737 | − | |
| 738 | − if (priv && priv->debugfs) { | |
| 739 | − debugfs_remove_recursive(priv->debugfs); | |
| 740 | − priv->debugfs = NULL; | |
| 741 | − } | |
| 742 | −} | |
| 743 | − | |
| 744 | −#else | |
| 745 | − | |
| 746 | −static void brcm_avs_cpufreq_debug_init(struct platform_device *pdev) {} | |
| 747 | −static void brcm_avs_cpufreq_debug_exit(struct platform_device *pdev) {} | |
| 748 | − | |
| 749 | −#endif /* CONFIG_ARM_BRCMSTB_AVS_CPUFREQ_DEBUG */ | |
| 750 | − | |
| 751 | 435 | /* |
| 752 | 436 | * To ensure the right firmware is running we need to |
| 753 | 437 | * - check the MAGIC matches what we expect |
| @@ -1016,11 +700,8 @@ static int brcm_avs_cpufreq_probe(struct platform_device *pdev) · 262 unmodified lines | ||
| 1016 | 700 | return ret; |
| 1017 | 701 | |
| 1018 | 702 | brcm_avs_driver.driver_data = pdev; |
| 1019 | − ret = cpufreq_register_driver(&brcm_avs_driver); | |
| 1020 | − if (!ret) | |
| 1021 | − brcm_avs_cpufreq_debug_init(pdev); | |
| 1022 | 703 | |
| 1023 | − return ret; | |
| 704 | + return cpufreq_register_driver(&brcm_avs_driver); | |
| 1024 | 705 | } |
| 1025 | 706 | |
| 1026 | 707 | static int brcm_avs_cpufreq_remove(struct platform_device *pdev) |
| @@ -1032,8 +713,6 @@ static int brcm_avs_cpufreq_remove(struct platform_device *pdev) · 5 unmodified lines | ||
| 1032 | 713 | if (ret) |
| 1033 | 714 | return ret; |
| 1034 | 715 | |
| 1035 | − brcm_avs_cpufreq_debug_exit(pdev); | |
| 1036 | − | |
| 1037 | 716 | priv = platform_get_drvdata(pdev); |
| 1038 | 717 | iounmap(priv->base); |
| 1039 | 718 | iounmap(priv->avs_intr_base); |
| @@ -126,6 +126,49 @@ static void cppc_cpufreq_stop_cpu(struct cpufreq_policy *policy) · 125 unmodified lines | ||
| 126 | 126 | cpu->perf_caps.lowest_perf, cpu_num, ret); |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | +/* | |
| 130 | + * The PCC subspace describes the rate at which platform can accept commands | |
| 131 | + * on the shared PCC channel (including READs which do not count towards freq | |
| 132 | + * trasition requests), so ideally we need to use the PCC values as a fallback | |
| 133 | + * if we don't have a platform specific transition_delay_us | |
| 134 | + */ | |
| 135 | +#ifdef CONFIG_ARM64 | |
| 136 | +#include <asm/cputype.h> | |
| 137 | + | |
| 138 | +static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu) | |
| 139 | +{ | |
| 140 | + unsigned long implementor = read_cpuid_implementor(); | |
| 141 | + unsigned long part_num = read_cpuid_part_number(); | |
| 142 | + unsigned int delay_us = 0; | |
| 143 | + | |
| 144 | + switch (implementor) { | |
| 145 | + case ARM_CPU_IMP_QCOM: | |
| 146 | + switch (part_num) { | |
| 147 | + case QCOM_CPU_PART_FALKOR_V1: | |
| 148 | + case QCOM_CPU_PART_FALKOR: | |
| 149 | + delay_us = 10000; | |
| 150 | + break; | |
| 151 | + default: | |
| 152 | + delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC; | |
| 153 | + break; | |
| 154 | + } | |
| 155 | + break; | |
| 156 | + default: | |
| 157 | + delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC; | |
| 158 | + break; | |
| 159 | + } | |
| 160 | + | |
| 161 | + return delay_us; | |
| 162 | +} | |
| 163 | + | |
| 164 | +#else | |
| 165 | + | |
| 166 | +static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu) | |
| 167 | +{ | |
| 168 | + return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; | |
| 169 | +} | |
| 170 | +#endif | |
| 171 | + | |
| 129 | 172 | static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) |
| 130 | 173 | { |
| 131 | 174 | struct cppc_cpudata *cpu; |
| @@ -162,8 +205,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) · 30 unmodified lines | ||
| 162 | 205 | cpu->perf_caps.highest_perf; |
| 163 | 206 | policy->cpuinfo.max_freq = cppc_dmi_max_khz; |
| 164 | 207 | |
| 165 | − policy->transition_delay_us = cppc_get_transition_latency(cpu_num) / | |
| 166 | − NSEC_PER_USEC; | |
| 208 | + policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num); | |
| 167 | 209 | policy->shared_type = cpu->shared_type; |
| 168 | 210 | |
| 169 | 211 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { |
| @@ -679,6 +679,16 @@ void gpstate_timer_handler(struct timer_list *t) · 678 unmodified lines | ||
| 679 | 679 | |
| 680 | 680 | if (!spin_trylock(&gpstates->gpstate_lock)) |
| 681 | 681 | return; |
| 682 | + /* | |
| 683 | + * If the timer has migrated to the different cpu then bring | |
| 684 | + * it back to one of the policy->cpus | |
| 685 | + */ | |
| 686 | + if (!cpumask_test_cpu(raw_smp_processor_id(), policy->cpus)) { | |
| 687 | + gpstates->timer.expires = jiffies + msecs_to_jiffies(1); | |
| 688 | + add_timer_on(&gpstates->timer, cpumask_first(policy->cpus)); | |
| 689 | + spin_unlock(&gpstates->gpstate_lock); | |
| 690 | + return; | |
| 691 | + } | |
| 682 | 692 | |
| 683 | 693 | /* |
| 684 | 694 | * If PMCR was last updated was using fast_swtich then |
| @@ -718,10 +728,8 @@ void gpstate_timer_handler(struct timer_list *t) · 33 unmodified lines | ||
| 718 | 728 | if (gpstate_idx != gpstates->last_lpstate_idx) |
| 719 | 729 | queue_gpstate_timer(gpstates); |
| 720 | 730 | |
| 731 | + set_pstate(&freq_data); | |
| 721 | 732 | spin_unlock(&gpstates->gpstate_lock); |
| 722 | − | |
| 723 | − /* Timer may get migrated to a different cpu on cpu hot unplug */ | |
| 724 | − smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1); | |
| 725 | 733 | } |
| 726 | 734 | |
| 727 | 735 | /* |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/dax.h> |
| 20 | 20 | #include <linux/fs.h> |
| 21 | 21 | #include <linux/mm.h> |
| 22 | +#include <linux/mman.h> | |
| 22 | 23 | #include "dax-private.h" |
| 23 | 24 | #include "dax.h" |
| 24 | 25 | |
| @@ -540,6 +541,7 @@ static const struct file_operations dax_fops = { · 515 unmodified lines | ||
| 540 | 541 | .release = dax_release, |
| 541 | 542 | .get_unmapped_area = dax_get_unmapped_area, |
| 542 | 543 | .mmap = dax_mmap, |
| 544 | + .mmap_supported_flags = MAP_SYNC, | |
| 543 | 545 | }; |
| 544 | 546 | |
| 545 | 547 | static void dev_dax_release(struct device *dev) |
| @@ -284,7 +284,7 @@ scmi_clock_info_get(const struct scmi_handle *handle, u32 clk_id) · 283 unmodified lines | ||
| 284 | 284 | struct clock_info *ci = handle->clk_priv; |
| 285 | 285 | struct scmi_clock_info *clk = ci->clk + clk_id; |
| 286 | 286 | |
| 287 | − if (!clk->name || !clk->name[0]) | |
| 287 | + if (!clk->name[0]) | |
| 288 | 288 | return NULL; |
| 289 | 289 | |
| 290 | 290 | return clk; |
| @@ -249,7 +249,7 @@ static int altera_ps_probe(struct spi_device *spi) · 248 unmodified lines | ||
| 249 | 249 | |
| 250 | 250 | conf->data = of_id->data; |
| 251 | 251 | conf->spi = spi; |
| 252 | − conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_HIGH); | |
| 252 | + conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_LOW); | |
| 253 | 253 | if (IS_ERR(conf->config)) { |
| 254 | 254 | dev_err(&spi->dev, "Failed to get config gpio: %ld\n", |
| 255 | 255 | PTR_ERR(conf->config)); |
| @@ -1459,10 +1459,11 @@ static const u32 sgpr_init_compute_shader[] = · 1458 unmodified lines | ||
| 1459 | 1459 | static const u32 vgpr_init_regs[] = |
| 1460 | 1460 | { |
| 1461 | 1461 | mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff, |
| 1462 | − mmCOMPUTE_RESOURCE_LIMITS, 0, | |
| 1462 | + mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */ | |
| 1463 | 1463 | mmCOMPUTE_NUM_THREAD_X, 256*4, |
| 1464 | 1464 | mmCOMPUTE_NUM_THREAD_Y, 1, |
| 1465 | 1465 | mmCOMPUTE_NUM_THREAD_Z, 1, |
| 1466 | + mmCOMPUTE_PGM_RSRC1, 0x100004f, /* VGPRS=15 (64 logical VGPRs), SGPRS=1 (16 SGPRs), BULKY=1 */ | |
| 1466 | 1467 | mmCOMPUTE_PGM_RSRC2, 20, |
| 1467 | 1468 | mmCOMPUTE_USER_DATA_0, 0xedcedc00, |
| 1468 | 1469 | mmCOMPUTE_USER_DATA_1, 0xedcedc01, |
| @@ -1479,10 +1480,11 @@ static const u32 vgpr_init_regs[] = · 10 unmodified lines | ||
| 1479 | 1480 | static const u32 sgpr1_init_regs[] = |
| 1480 | 1481 | { |
| 1481 | 1482 | mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f, |
| 1482 | − mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, | |
| 1483 | + mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */ | |
| 1483 | 1484 | mmCOMPUTE_NUM_THREAD_X, 256*5, |
| 1484 | 1485 | mmCOMPUTE_NUM_THREAD_Y, 1, |
| 1485 | 1486 | mmCOMPUTE_NUM_THREAD_Z, 1, |
| 1487 | + mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */ | |
| 1486 | 1488 | mmCOMPUTE_PGM_RSRC2, 20, |
| 1487 | 1489 | mmCOMPUTE_USER_DATA_0, 0xedcedc00, |
| 1488 | 1490 | mmCOMPUTE_USER_DATA_1, 0xedcedc01, |
| @@ -1503,6 +1505,7 @@ static const u32 sgpr2_init_regs[] = · 14 unmodified lines | ||
| 1503 | 1505 | mmCOMPUTE_NUM_THREAD_X, 256*5, |
| 1504 | 1506 | mmCOMPUTE_NUM_THREAD_Y, 1, |
| 1505 | 1507 | mmCOMPUTE_NUM_THREAD_Z, 1, |
| 1508 | + mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */ | |
| 1506 | 1509 | mmCOMPUTE_PGM_RSRC2, 20, |
| 1507 | 1510 | mmCOMPUTE_USER_DATA_0, 0xedcedc00, |
| 1508 | 1511 | mmCOMPUTE_USER_DATA_1, 0xedcedc01, |
| @@ -6,5 +6,6 @@ config HSA_AMD · 5 unmodified lines | ||
| 6 | 6 | tristate "HSA kernel driver for AMD GPU devices" |
| 7 | 7 | depends on DRM_AMDGPU && X86_64 |
| 8 | 8 | imply AMD_IOMMU_V2 |
| 9 | + select MMU_NOTIFIER | |
| 9 | 10 | help |
| 10 | 11 | Enable this if you want to use HSA features on AMD GPU devices. |
| @@ -749,12 +749,13 @@ static int kfd_ioctl_get_clock_counters(struct file *filep, · 748 unmodified lines | ||
| 749 | 749 | struct timespec64 time; |
| 750 | 750 | |
| 751 | 751 | dev = kfd_device_by_id(args->gpu_id); |
| 752 | − if (dev == NULL) | |
| 753 | − return -EINVAL; | |
| 754 | − | |
| 755 | − /* Reading GPU clock counter from KGD */ | |
| 756 | − args->gpu_clock_counter = | |
| 757 | − dev->kfd2kgd->get_gpu_clock_counter(dev->kgd); | |
| 752 | + if (dev) | |
| 753 | + /* Reading GPU clock counter from KGD */ | |
| 754 | + args->gpu_clock_counter = | |
| 755 | + dev->kfd2kgd->get_gpu_clock_counter(dev->kgd); | |
| 756 | + else | |
| 757 | + /* Node without GPU resource */ | |
| 758 | + args->gpu_clock_counter = 0; | |
| 758 | 759 | |
| 759 | 760 | /* No access to rdtsc. Using raw monotonic time */ |
| 760 | 761 | getrawmonotonic64(&time); |
| @@ -1147,7 +1148,7 @@ err_unlock: · 386 unmodified lines | ||
| 1147 | 1148 | return ret; |
| 1148 | 1149 | } |
| 1149 | 1150 | |
| 1150 | −bool kfd_dev_is_large_bar(struct kfd_dev *dev) | |
| 1151 | +static bool kfd_dev_is_large_bar(struct kfd_dev *dev) | |
| 1151 | 1152 | { |
| 1152 | 1153 | struct kfd_local_mem_info mem_info; |
| 1153 | 1154 | |
| @@ -1421,7 +1422,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, · 267 unmodified lines | ||
| 1421 | 1422 | |
| 1422 | 1423 | pdd = kfd_get_process_device_data(dev, p); |
| 1423 | 1424 | if (!pdd) { |
| 1424 | − err = PTR_ERR(pdd); | |
| 1425 | + err = -EINVAL; | |
| 1425 | 1426 | goto bind_process_to_device_failed; |
| 1426 | 1427 | } |
| 1427 | 1428 | |
| @@ -4557,6 +4557,7 @@ static int dm_update_crtcs_state(struct dc *dc, · 4556 unmodified lines | ||
| 4557 | 4557 | struct amdgpu_dm_connector *aconnector = NULL; |
| 4558 | 4558 | struct drm_connector_state *new_con_state = NULL; |
| 4559 | 4559 | struct dm_connector_state *dm_conn_state = NULL; |
| 4560 | + struct drm_plane_state *new_plane_state = NULL; | |
| 4560 | 4561 | |
| 4561 | 4562 | new_stream = NULL; |
| 4562 | 4563 | |
| @@ -4564,6 +4565,13 @@ static int dm_update_crtcs_state(struct dc *dc, · 1 unmodified line | ||
| 4564 | 4565 | dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); |
| 4565 | 4566 | acrtc = to_amdgpu_crtc(crtc); |
| 4566 | 4567 | |
| 4568 | + new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary); | |
| 4569 | + | |
| 4570 | + if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) { | |
| 4571 | + ret = -EINVAL; | |
| 4572 | + goto fail; | |
| 4573 | + } | |
| 4574 | + | |
| 4567 | 4575 | aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc); |
| 4568 | 4576 | |
| 4569 | 4577 | /* TODO This hack should go away */ |
| @@ -4760,7 +4768,7 @@ static int dm_update_planes_state(struct dc *dc, · 190 unmodified lines | ||
| 4760 | 4768 | if (!dm_old_crtc_state->stream) |
| 4761 | 4769 | continue; |
| 4762 | 4770 | |
| 4763 | − DRM_DEBUG_DRIVER("Disabling DRM plane: %d on DRM crtc %d\n", | |
| 4771 | + DRM_DEBUG_ATOMIC("Disabling DRM plane: %d on DRM crtc %d\n", | |
| 4764 | 4772 | plane->base.id, old_plane_crtc->base.id); |
| 4765 | 4773 | |
| 4766 | 4774 | if (!dc_remove_plane_from_context( |
| @@ -138,13 +138,6 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc) · 137 unmodified lines | ||
| 138 | 138 | lut = (struct drm_color_lut *)blob->data; |
| 139 | 139 | lut_size = blob->length / sizeof(struct drm_color_lut); |
| 140 | 140 | |
| 141 | − if (__is_lut_linear(lut, lut_size)) { | |
| 142 | − /* Set to bypass if lut is set to linear */ | |
| 143 | − stream->out_transfer_func->type = TF_TYPE_BYPASS; | |
| 144 | − stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; | |
| 145 | − return 0; | |
| 146 | − } | |
| 147 | − | |
| 148 | 141 | gamma = dc_create_gamma(); |
| 149 | 142 | if (!gamma) |
| 150 | 143 | return -ENOMEM; |
| @@ -329,14 +329,15 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev) · 328 unmodified lines | ||
| 329 | 329 | { |
| 330 | 330 | int src; |
| 331 | 331 | struct irq_list_head *lh; |
| 332 | + unsigned long irq_table_flags; | |
| 332 | 333 | DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n"); |
| 333 | − | |
| 334 | 334 | for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) { |
| 335 | − | |
| 335 | + DM_IRQ_TABLE_LOCK(adev, irq_table_flags); | |
| 336 | 336 | /* The handler was removed from the table, |
| 337 | 337 | * it means it is safe to flush all the 'work' |
| 338 | 338 | * (because no code can schedule a new one). */ |
| 339 | 339 | lh = &adev->dm.irq_handler_list_low_tab[src]; |
| 340 | + DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); | |
| 340 | 341 | flush_work(&lh->work); |
| 341 | 342 | } |
| 342 | 343 | } |
| @@ -161,6 +161,11 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector) · 160 unmodified lines | ||
| 161 | 161 | struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); |
| 162 | 162 | struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder; |
| 163 | 163 | |
| 164 | + if (amdgpu_dm_connector->edid) { | |
| 165 | + kfree(amdgpu_dm_connector->edid); | |
| 166 | + amdgpu_dm_connector->edid = NULL; | |
| 167 | + } | |
| 168 | + | |
| 164 | 169 | drm_encoder_cleanup(&amdgpu_encoder->base); |
| 165 | 170 | kfree(amdgpu_encoder); |
| 166 | 171 | drm_connector_cleanup(connector); |
| @@ -181,28 +186,22 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { · 14 unmodified lines | ||
| 181 | 186 | void dm_dp_mst_dc_sink_create(struct drm_connector *connector) |
| 182 | 187 | { |
| 183 | 188 | struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); |
| 184 | − struct edid *edid; | |
| 185 | 189 | struct dc_sink *dc_sink; |
| 186 | 190 | struct dc_sink_init_data init_params = { |
| 187 | 191 | .link = aconnector->dc_link, |
| 188 | 192 | .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; |
| 189 | 193 | |
| 194 | + /* FIXME none of this is safe. we shouldn't touch aconnector here in | |
| 195 | + * atomic_check | |
| 196 | + */ | |
| 197 | + | |
| 190 | 198 | /* |
| 191 | 199 | * TODO: Need to further figure out why ddc.algo is NULL while MST port exists |
| 192 | 200 | */ |
| 193 | 201 | if (!aconnector->port || !aconnector->port->aux.ddc.algo) |
| 194 | 202 | return; |
| 195 | 203 | |
| 196 | − edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); | |
| 197 | − | |
| 198 | − if (!edid) { | |
| 199 | − drm_mode_connector_update_edid_property( | |
| 200 | − &aconnector->base, | |
| 201 | − NULL); | |
| 202 | − return; | |
| 203 | − } | |
| 204 | − | |
| 205 | − aconnector->edid = edid; | |
| 204 | + ASSERT(aconnector->edid); | |
| 206 | 205 | |
| 207 | 206 | dc_sink = dc_link_add_remote_sink( |
| 208 | 207 | aconnector->dc_link, |
| @@ -215,9 +214,6 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector) · 6 unmodified lines | ||
| 215 | 214 | |
| 216 | 215 | amdgpu_dm_add_sink_to_freesync_module( |
| 217 | 216 | connector, aconnector->edid); |
| 218 | − | |
| 219 | − drm_mode_connector_update_edid_property( | |
| 220 | − &aconnector->base, aconnector->edid); | |
| 221 | 217 | } |
| 222 | 218 | |
| 223 | 219 | static int dm_dp_mst_get_modes(struct drm_connector *connector) |
| @@ -230,10 +226,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) · 6 unmodified lines | ||
| 230 | 226 | |
| 231 | 227 | if (!aconnector->edid) { |
| 232 | 228 | struct edid *edid; |
| 233 | − struct dc_sink *dc_sink; | |
| 234 | − struct dc_sink_init_data init_params = { | |
| 235 | − .link = aconnector->dc_link, | |
| 236 | − .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | |
| 237 | 229 | edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); |
| 238 | 230 | |
| 239 | 231 | if (!edid) { |
| @@ -244,11 +236,17 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) · 4 unmodified lines | ||
| 244 | 236 | } |
| 245 | 237 | |
| 246 | 238 | aconnector->edid = edid; |
| 239 | + } | |
| 247 | 240 | |
| 241 | + if (!aconnector->dc_sink) { | |
| 242 | + struct dc_sink *dc_sink; | |
| 243 | + struct dc_sink_init_data init_params = { | |
| 244 | + .link = aconnector->dc_link, | |
| 245 | + .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; | |
| 248 | 246 | dc_sink = dc_link_add_remote_sink( |
| 249 | 247 | aconnector->dc_link, |
| 250 | − (uint8_t *)edid, | |
| 251 | − (edid->extensions + 1) * EDID_LENGTH, | |
| 248 | + (uint8_t *)aconnector->edid, | |
| 249 | + (aconnector->edid->extensions + 1) * EDID_LENGTH, | |
| 252 | 250 | &init_params); |
| 253 | 251 | |
| 254 | 252 | dc_sink->priv = aconnector; |
| @@ -256,12 +254,12 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector) · 1 unmodified line | ||
| 256 | 254 | |
| 257 | 255 | if (aconnector->dc_sink) |
| 258 | 256 | amdgpu_dm_add_sink_to_freesync_module( |
| 259 | − connector, edid); | |
| 260 | − | |
| 261 | − drm_mode_connector_update_edid_property( | |
| 262 | − &aconnector->base, edid); | |
| 257 | + connector, aconnector->edid); | |
| 263 | 258 | } |
| 264 | 259 | |
| 260 | + drm_mode_connector_update_edid_property( | |
| 261 | + &aconnector->base, aconnector->edid); | |
| 262 | + | |
| 265 | 263 | ret = drm_add_edid_modes(connector, aconnector->edid); |
| 266 | 264 | |
| 267 | 265 | return ret; |
| @@ -424,14 +422,6 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, · 156 unmodified lines | ||
| 424 | 422 | dc_sink_release(aconnector->dc_sink); |
| 425 | 423 | aconnector->dc_sink = NULL; |
| 426 | 424 | } |
| 427 | − if (aconnector->edid) { | |
| 428 | − kfree(aconnector->edid); | |
| 429 | − aconnector->edid = NULL; | |
| 430 | − } | |
| 431 | − | |
| 432 | − drm_mode_connector_update_edid_property( | |
| 433 | − &aconnector->base, | |
| 434 | − NULL); | |
| 435 | 425 | |
| 436 | 426 | aconnector->mst_connected = false; |
| 437 | 427 | } |
| @@ -4743,23 +4743,27 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr) · 4742 unmodified lines | ||
| 4743 | 4743 | |
| 4744 | 4744 | for (i=0; i < dep_table->count; i++) { |
| 4745 | 4745 | if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { |
| 4746 | − data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC; | |
| 4747 | − break; | |
| 4746 | + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK; | |
| 4747 | + return; | |
| 4748 | 4748 | } |
| 4749 | 4749 | } |
| 4750 | − if (i == dep_table->count) | |
| 4750 | + if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { | |
| 4751 | 4751 | data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; |
| 4752 | + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK; | |
| 4753 | + } | |
| 4752 | 4754 | |
| 4753 | 4755 | dep_table = table_info->vdd_dep_on_sclk; |
| 4754 | 4756 | odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk); |
| 4755 | 4757 | for (i=0; i < dep_table->count; i++) { |
| 4756 | 4758 | if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) { |
| 4757 | − data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC; | |
| 4758 | − break; | |
| 4759 | + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK; | |
| 4760 | + return; | |
| 4759 | 4761 | } |
| 4760 | 4762 | } |
| 4761 | − if (i == dep_table->count) | |
| 4763 | + if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) { | |
| 4762 | 4764 | data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC; |
| 4765 | + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; | |
| 4766 | + } | |
| 4763 | 4767 | } |
| 4764 | 4768 | |
| 4765 | 4769 | static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, |
| @@ -412,8 +412,10 @@ typedef struct { · 411 unmodified lines | ||
| 412 | 412 | QuadraticInt_t ReservedEquation2; |
| 413 | 413 | QuadraticInt_t ReservedEquation3; |
| 414 | 414 | |
| 415 | + uint16_t MinVoltageUlvGfx; | |
| 416 | + uint16_t MinVoltageUlvSoc; | |
| 415 | 417 | |
| 416 | − uint32_t Reserved[15]; | |
| 418 | + uint32_t Reserved[14]; | |
| 417 | 419 | |
| 418 | 420 | |
| 419 | 421 | |
| @@ -56,7 +56,9 @@ static int dumb_vga_get_modes(struct drm_connector *connector) · 55 unmodified lines | ||
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | drm_mode_connector_update_edid_property(connector, edid); |
| 59 | − return drm_add_edid_modes(connector, edid); | |
| 59 | + ret = drm_add_edid_modes(connector, edid); | |
| 60 | + kfree(edid); | |
| 61 | + return ret; | |
| 60 | 62 | |
| 61 | 63 | fallback: |
| 62 | 64 | /* |
| @@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type, · 349 unmodified lines | ||
| 350 | 350 | { |
| 351 | 351 | uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE; |
| 352 | 352 | ssize_t ret; |
| 353 | + int retry; | |
| 353 | 354 | |
| 354 | 355 | if (type < DRM_DP_DUAL_MODE_TYPE2_DVI) |
| 355 | 356 | return 0; |
| 356 | 357 | |
| 357 | − ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN, | |
| 358 | − &tmds_oen, sizeof(tmds_oen)); | |
| 359 | − if (ret) { | |
| 360 | − DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n", | |
| 361 | − enable ? "enable" : "disable"); | |
| 362 | − return ret; | |
| 358 | + /* | |
| 359 | + * LSPCON adapters in low-power state may ignore the first write, so | |
| 360 | + * read back and verify the written value a few times. | |
| 361 | + */ | |
| 362 | + for (retry = 0; retry < 3; retry++) { | |
| 363 | + uint8_t tmp; | |
| 364 | + | |
| 365 | + ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN, | |
| 366 | + &tmds_oen, sizeof(tmds_oen)); | |
| 367 | + if (ret) { | |
| 368 | + DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n", | |
| 369 | + enable ? "enable" : "disable", | |
| 370 | + retry + 1); | |
| 371 | + return ret; | |
| 372 | + } | |
| 373 | + | |
| 374 | + ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN, | |
| 375 | + &tmp, sizeof(tmp)); | |
| 376 | + if (ret) { | |
| 377 | + DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n", | |
| 378 | + enable ? "enabling" : "disabling", | |
| 379 | + retry + 1); | |
| 380 | + return ret; | |
| 381 | + } | |
| 382 | + | |
| 383 | + if (tmp == tmds_oen) | |
| 384 | + return 0; | |
| 363 | 385 | } |
| 364 | 386 | |
| 365 | − return 0; | |
| 387 | + DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n", | |
| 388 | + enable ? "enabling" : "disabling"); | |
| 389 | + | |
| 390 | + return -EIO; | |
| 366 | 391 | } |
| 367 | 392 | EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output); |
| 368 | 393 | |
| @@ -4451,6 +4451,7 @@ drm_reset_display_info(struct drm_connector *connector) · 4450 unmodified lines | ||
| 4451 | 4451 | info->max_tmds_clock = 0; |
| 4452 | 4452 | info->dvi_dual = false; |
| 4453 | 4453 | info->has_hdmi_infoframe = false; |
| 4454 | + memset(&info->hdmi, 0, sizeof(info->hdmi)); | |
| 4454 | 4455 | |
| 4455 | 4456 | info->non_desktop = 0; |
| 4456 | 4457 | } |
| @@ -4462,17 +4463,11 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi · 5 unmodified lines | ||
| 4462 | 4463 | |
| 4463 | 4464 | u32 quirks = edid_get_quirks(edid); |
| 4464 | 4465 | |
| 4466 | + drm_reset_display_info(connector); | |
| 4467 | + | |
| 4465 | 4468 | info->width_mm = edid->width_cm * 10; |
| 4466 | 4469 | info->height_mm = edid->height_cm * 10; |
| 4467 | 4470 | |
| 4468 | − /* driver figures it out in this case */ | |
| 4469 | − info->bpc = 0; | |
| 4470 | − info->color_formats = 0; | |
| 4471 | − info->cea_rev = 0; | |
| 4472 | − info->max_tmds_clock = 0; | |
| 4473 | − info->dvi_dual = false; | |
| 4474 | − info->has_hdmi_infoframe = false; | |
| 4475 | − | |
| 4476 | 4471 | info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP); |
| 4477 | 4472 | |
| 4478 | 4473 | DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <drm/drm_fb_helper.h> |
| 19 | 19 | #include <drm/drm_atomic.h> |
| 20 | 20 | #include <drm/drm_atomic_helper.h> |
| 21 | +#include <drm/drm_gem_framebuffer_helper.h> | |
| 21 | 22 | #include <uapi/drm/exynos_drm.h> |
| 22 | 23 | |
| 23 | 24 | #include "exynos_drm_drv.h" |
| @@ -26,20 +27,6 @@ · 2 unmodified lines | ||
| 26 | 27 | #include "exynos_drm_iommu.h" |
| 27 | 28 | #include "exynos_drm_crtc.h" |
| 28 | 29 | |
| 29 | −#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) | |
| 30 | − | |
| 31 | −/* | |
| 32 | − * exynos specific framebuffer structure. | |
| 33 | − * | |
| 34 | − * @fb: drm framebuffer obejct. | |
| 35 | − * @exynos_gem: array of exynos specific gem object containing a gem object. | |
| 36 | − */ | |
| 37 | −struct exynos_drm_fb { | |
| 38 | − struct drm_framebuffer fb; | |
| 39 | − struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER]; | |
| 40 | − dma_addr_t dma_addr[MAX_FB_BUFFER]; | |
| 41 | −}; | |
| 42 | − | |
| 43 | 30 | static int check_fb_gem_memory_type(struct drm_device *drm_dev, |
| 44 | 31 | struct exynos_drm_gem *exynos_gem) |
| 45 | 32 | { |
| @@ -66,40 +53,9 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev, · 20 unmodified lines | ||
| 66 | 53 | return 0; |
| 67 | 54 | } |
| 68 | 55 | |
| 69 | −static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) | |
| 70 | −{ | |
| 71 | − struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); | |
| 72 | − unsigned int i; | |
| 73 | − | |
| 74 | − drm_framebuffer_cleanup(fb); | |
| 75 | − | |
| 76 | − for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) { | |
| 77 | − struct drm_gem_object *obj; | |
| 78 | − | |
| 79 | − if (exynos_fb->exynos_gem[i] == NULL) | |
| 80 | − continue; | |
| 81 | − | |
| 82 | − obj = &exynos_fb->exynos_gem[i]->base; | |
| 83 | − drm_gem_object_unreference_unlocked(obj); | |
| 84 | − } | |
| 85 | − | |
| 86 | − kfree(exynos_fb); | |
| 87 | − exynos_fb = NULL; | |
| 88 | −} | |
| 89 | − | |
| 90 | −static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb, | |
| 91 | − struct drm_file *file_priv, | |
| 92 | − unsigned int *handle) | |
| 93 | −{ | |
| 94 | − struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); | |
| 95 | − | |
| 96 | − return drm_gem_handle_create(file_priv, | |
| 97 | − &exynos_fb->exynos_gem[0]->base, handle); | |
| 98 | −} | |
| 99 | − | |
| 100 | 56 | static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = { |
| 101 | − .destroy = exynos_drm_fb_destroy, | |
| 102 | − .create_handle = exynos_drm_fb_create_handle, | |
| 57 | + .destroy = drm_gem_fb_destroy, | |
| 58 | + .create_handle = drm_gem_fb_create_handle, | |
| 103 | 59 | }; |
| 104 | 60 | |
| 105 | 61 | struct drm_framebuffer * |
| @@ -108,12 +64,12 @@ exynos_drm_framebuffer_init(struct drm_device *dev, · 2 unmodified lines | ||
| 108 | 64 | struct exynos_drm_gem **exynos_gem, |
| 109 | 65 | int count) |
| 110 | 66 | { |
| 111 | − struct exynos_drm_fb *exynos_fb; | |
| 67 | + struct drm_framebuffer *fb; | |
| 112 | 68 | int i; |
| 113 | 69 | int ret; |
| 114 | 70 | |
| 115 | − exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL); | |
| 116 | − if (!exynos_fb) | |
| 71 | + fb = kzalloc(sizeof(*fb), GFP_KERNEL); | |
| 72 | + if (!fb) | |
| 117 | 73 | return ERR_PTR(-ENOMEM); |
| 118 | 74 | |
| 119 | 75 | for (i = 0; i < count; i++) { |
| @@ -121,23 +77,21 @@ exynos_drm_framebuffer_init(struct drm_device *dev, · 1 unmodified line | ||
| 121 | 77 | if (ret < 0) |
| 122 | 78 | goto err; |
| 123 | 79 | |
| 124 | − exynos_fb->exynos_gem[i] = exynos_gem[i]; | |
| 125 | − exynos_fb->dma_addr[i] = exynos_gem[i]->dma_addr | |
| 126 | − + mode_cmd->offsets[i]; | |
| 80 | + fb->obj[i] = &exynos_gem[i]->base; | |
| 127 | 81 | } |
| 128 | 82 | |
| 129 | − drm_helper_mode_fill_fb_struct(dev, &exynos_fb->fb, mode_cmd); | |
| 83 | + drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd); | |
| 130 | 84 | |
| 131 | − ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs); | |
| 85 | + ret = drm_framebuffer_init(dev, fb, &exynos_drm_fb_funcs); | |
| 132 | 86 | if (ret < 0) { |
| 133 | 87 | DRM_ERROR("failed to initialize framebuffer\n"); |
| 134 | 88 | goto err; |
| 135 | 89 | } |
| 136 | 90 | |
| 137 | − return &exynos_fb->fb; | |
| 91 | + return fb; | |
| 138 | 92 | |
| 139 | 93 | err: |
| 140 | − kfree(exynos_fb); | |
| 94 | + kfree(fb); | |
| 141 | 95 | return ERR_PTR(ret); |
| 142 | 96 | } |
| 143 | 97 | |
| @@ -191,12 +145,13 @@ err: · 47 unmodified lines | ||
| 191 | 145 | |
| 192 | 146 | dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index) |
| 193 | 147 | { |
| 194 | − struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); | |
| 148 | + struct exynos_drm_gem *exynos_gem; | |
| 195 | 149 | |
| 196 | 150 | if (WARN_ON_ONCE(index >= MAX_FB_BUFFER)) |
| 197 | 151 | return 0; |
| 198 | 152 | |
| 199 | − return exynos_fb->dma_addr[index]; | |
| 153 | + exynos_gem = to_exynos_gem(fb->obj[index]); | |
| 154 | + return exynos_gem->dma_addr + fb->offsets[index]; | |
| 200 | 155 | } |
| 201 | 156 | |
| 202 | 157 | static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = { |
| @@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s) · 1079 unmodified lines | ||
| 1080 | 1080 | { |
| 1081 | 1081 | set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt, |
| 1082 | 1082 | s->workload->pending_events); |
| 1083 | + patch_value(s, cmd_ptr(s, 0), MI_NOOP); | |
| 1083 | 1084 | return 0; |
| 1084 | 1085 | } |
| 1085 | 1086 | |
| @@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = { · 168 unmodified lines | ||
| 169 | 169 | static void emulate_monitor_status_change(struct intel_vgpu *vgpu) |
| 170 | 170 | { |
| 171 | 171 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; |
| 172 | + int pipe; | |
| 173 | + | |
| 172 | 174 | vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT | |
| 173 | 175 | SDE_PORTC_HOTPLUG_CPT | |
| 174 | 176 | SDE_PORTD_HOTPLUG_CPT); |
| @@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) · 92 unmodified lines | ||
| 267 | 269 | if (IS_BROADWELL(dev_priv)) |
| 268 | 270 | vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; |
| 269 | 271 | |
| 272 | + /* Disable Primary/Sprite/Cursor plane */ | |
| 273 | + for_each_pipe(dev_priv, pipe) { | |
| 274 | + vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE; | |
| 275 | + vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE; | |
| 276 | + vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~CURSOR_MODE; | |
| 277 | + vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= CURSOR_MODE_DISABLE; | |
| 278 | + } | |
| 279 | + | |
| 270 | 280 | vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; |
| 271 | 281 | } |
| 272 | 282 | |
| @@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf, · 322 unmodified lines | ||
| 323 | 323 | struct intel_vgpu_fb_info *fb_info) |
| 324 | 324 | { |
| 325 | 325 | gvt_dmabuf->drm_format = fb_info->drm_format; |
| 326 | + gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod; | |
| 326 | 327 | gvt_dmabuf->width = fb_info->width; |
| 327 | 328 | gvt_dmabuf->height = fb_info->height; |
| 328 | 329 | gvt_dmabuf->stride = fb_info->stride; |
| @@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu, · 244 unmodified lines | ||
| 245 | 245 | plane->hw_format = fmt; |
| 246 | 246 | |
| 247 | 247 | plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK; |
| 248 | − if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) { | |
| 249 | − gvt_vgpu_err("invalid gma address: %lx\n", | |
| 250 | − (unsigned long)plane->base); | |
| 248 | + if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) | |
| 251 | 249 | return -EINVAL; |
| 252 | − } | |
| 253 | 250 | |
| 254 | 251 | plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); |
| 255 | 252 | if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { |
| 256 | − gvt_vgpu_err("invalid gma address: %lx\n", | |
| 257 | − (unsigned long)plane->base); | |
| 253 | + gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n", | |
| 254 | + plane->base); | |
| 258 | 255 | return -EINVAL; |
| 259 | 256 | } |
| 260 | 257 | |
| @@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu, · 110 unmodified lines | ||
| 371 | 368 | alpha_plane, alpha_force); |
| 372 | 369 | |
| 373 | 370 | plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK; |
| 374 | − if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) { | |
| 375 | − gvt_vgpu_err("invalid gma address: %lx\n", | |
| 376 | − (unsigned long)plane->base); | |
| 371 | + if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) | |
| 377 | 372 | return -EINVAL; |
| 378 | − } | |
| 379 | 373 | |
| 380 | 374 | plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); |
| 381 | 375 | if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { |
| 382 | − gvt_vgpu_err("invalid gma address: %lx\n", | |
| 383 | − (unsigned long)plane->base); | |
| 376 | + gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n", | |
| 377 | + plane->base); | |
| 384 | 378 | return -EINVAL; |
| 385 | 379 | } |
| 386 | 380 | |
| @@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu, · 89 unmodified lines | ||
| 476 | 470 | plane->drm_format = drm_format; |
| 477 | 471 | |
| 478 | 472 | plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK; |
| 479 | − if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) { | |
| 480 | − gvt_vgpu_err("invalid gma address: %lx\n", | |
| 481 | − (unsigned long)plane->base); | |
| 473 | + if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) | |
| 482 | 474 | return -EINVAL; |
| 483 | − } | |
| 484 | 475 | |
| 485 | 476 | plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); |
| 486 | 477 | if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { |
| 487 | − gvt_vgpu_err("invalid gma address: %lx\n", | |
| 488 | − (unsigned long)plane->base); | |
| 478 | + gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n", | |
| 479 | + plane->base); | |
| 489 | 480 | return -EINVAL; |
| 490 | 481 | } |
| 491 | 482 | |
| @@ -530,6 +530,16 @@ static void ggtt_set_guest_entry(struct intel_vgpu_mm *mm, · 529 unmodified lines | ||
| 530 | 530 | false, 0, mm->vgpu); |
| 531 | 531 | } |
| 532 | 532 | |
| 533 | +static void ggtt_get_host_entry(struct intel_vgpu_mm *mm, | |
| 534 | + struct intel_gvt_gtt_entry *entry, unsigned long index) | |
| 535 | +{ | |
| 536 | + struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops; | |
| 537 | + | |
| 538 | + GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT); | |
| 539 | + | |
| 540 | + pte_ops->get_entry(NULL, entry, index, false, 0, mm->vgpu); | |
| 541 | +} | |
| 542 | + | |
| 533 | 543 | static void ggtt_set_host_entry(struct intel_vgpu_mm *mm, |
| 534 | 544 | struct intel_gvt_gtt_entry *entry, unsigned long index) |
| 535 | 545 | { |
| @@ -1818,6 +1828,18 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, unsigned int off, · 1282 unmodified lines | ||
| 1818 | 1828 | return ret; |
| 1819 | 1829 | } |
| 1820 | 1830 | |
| 1831 | +static void ggtt_invalidate_pte(struct intel_vgpu *vgpu, | |
| 1832 | + struct intel_gvt_gtt_entry *entry) | |
| 1833 | +{ | |
| 1834 | + struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops; | |
| 1835 | + unsigned long pfn; | |
| 1836 | + | |
| 1837 | + pfn = pte_ops->get_pfn(entry); | |
| 1838 | + if (pfn != vgpu->gvt->gtt.scratch_mfn) | |
| 1839 | + intel_gvt_hypervisor_dma_unmap_guest_page(vgpu, | |
| 1840 | + pfn << PAGE_SHIFT); | |
| 1841 | +} | |
| 1842 | + | |
| 1821 | 1843 | static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, |
| 1822 | 1844 | void *p_data, unsigned int bytes) |
| 1823 | 1845 | { |
| @@ -1844,10 +1866,10 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, · 20 unmodified lines | ||
| 1844 | 1866 | |
| 1845 | 1867 | memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data, |
| 1846 | 1868 | bytes); |
| 1847 | − m = e; | |
| 1848 | 1869 | |
| 1849 | 1870 | if (ops->test_present(&e)) { |
| 1850 | 1871 | gfn = ops->get_pfn(&e); |
| 1872 | + m = e; | |
| 1851 | 1873 | |
| 1852 | 1874 | /* one PTE update may be issued in multiple writes and the |
| 1853 | 1875 | * first write may not construct a valid gfn |
| @@ -1868,8 +1890,12 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, · 14 unmodified lines | ||
| 1868 | 1890 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); |
| 1869 | 1891 | } else |
| 1870 | 1892 | ops->set_pfn(&m, dma_addr >> PAGE_SHIFT); |
| 1871 | − } else | |
| 1893 | + } else { | |
| 1894 | + ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index); | |
| 1895 | + ggtt_invalidate_pte(vgpu, &m); | |
| 1872 | 1896 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); |
| 1897 | + ops->clear_present(&m); | |
| 1898 | + } | |
| 1873 | 1899 | |
| 1874 | 1900 | out: |
| 1875 | 1901 | ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index); |
| @@ -2030,7 +2056,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) · 154 unmodified lines | ||
| 2030 | 2056 | return PTR_ERR(gtt->ggtt_mm); |
| 2031 | 2057 | } |
| 2032 | 2058 | |
| 2033 | − intel_vgpu_reset_ggtt(vgpu); | |
| 2059 | + intel_vgpu_reset_ggtt(vgpu, false); | |
| 2034 | 2060 | |
| 2035 | 2061 | return create_scratch_page_tree(vgpu); |
| 2036 | 2062 | } |
| @@ -2315,17 +2341,19 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu) · 278 unmodified lines | ||
| 2315 | 2341 | /** |
| 2316 | 2342 | * intel_vgpu_reset_ggtt - reset the GGTT entry |
| 2317 | 2343 | * @vgpu: a vGPU |
| 2344 | + * @invalidate_old: invalidate old entries | |
| 2318 | 2345 | * |
| 2319 | 2346 | * This function is called at the vGPU create stage |
| 2320 | 2347 | * to reset all the GGTT entries. |
| 2321 | 2348 | * |
| 2322 | 2349 | */ |
| 2323 | −void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) | |
| 2350 | +void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old) | |
| 2324 | 2351 | { |
| 2325 | 2352 | struct intel_gvt *gvt = vgpu->gvt; |
| 2326 | 2353 | struct drm_i915_private *dev_priv = gvt->dev_priv; |
| 2327 | 2354 | struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops; |
| 2328 | 2355 | struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE}; |
| 2356 | + struct intel_gvt_gtt_entry old_entry; | |
| 2329 | 2357 | u32 index; |
| 2330 | 2358 | u32 num_entries; |
| 2331 | 2359 | |
| @@ -2334,13 +2362,23 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) · 2 unmodified lines | ||
| 2334 | 2362 | |
| 2335 | 2363 | index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT; |
| 2336 | 2364 | num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT; |
| 2337 | − while (num_entries--) | |
| 2365 | + while (num_entries--) { | |
| 2366 | + if (invalidate_old) { | |
| 2367 | + ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index); | |
| 2368 | + ggtt_invalidate_pte(vgpu, &old_entry); | |
| 2369 | + } | |
| 2338 | 2370 | ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++); |
| 2371 | + } | |
| 2339 | 2372 | |
| 2340 | 2373 | index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT; |
| 2341 | 2374 | num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT; |
| 2342 | − while (num_entries--) | |
| 2375 | + while (num_entries--) { | |
| 2376 | + if (invalidate_old) { | |
| 2377 | + ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index); | |
| 2378 | + ggtt_invalidate_pte(vgpu, &old_entry); | |
| 2379 | + } | |
| 2343 | 2380 | ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++); |
| 2381 | + } | |
| 2344 | 2382 | |
| 2345 | 2383 | ggtt_invalidate(dev_priv); |
| 2346 | 2384 | } |
| @@ -2360,5 +2398,5 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) · 13 unmodified lines | ||
| 2360 | 2398 | * removing the shadow pages. |
| 2361 | 2399 | */ |
| 2362 | 2400 | intel_vgpu_destroy_all_ppgtt_mm(vgpu); |
| 2363 | − intel_vgpu_reset_ggtt(vgpu); | |
| 2401 | + intel_vgpu_reset_ggtt(vgpu, true); | |
| 2364 | 2402 | } |
| @@ -193,7 +193,7 @@ struct intel_vgpu_gtt { · 192 unmodified lines | ||
| 193 | 193 | |
| 194 | 194 | extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); |
| 195 | 195 | extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu); |
| 196 | −void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu); | |
| 196 | +void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old); | |
| 197 | 197 | void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu); |
| 198 | 198 | |
| 199 | 199 | extern int intel_gvt_init_gtt(struct intel_gvt *gvt); |
| @@ -1150,6 +1150,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification) · 1149 unmodified lines | ||
| 1150 | 1150 | switch (notification) { |
| 1151 | 1151 | case VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE: |
| 1152 | 1152 | root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY; |
| 1153 | + /* fall through */ | |
| 1153 | 1154 | case VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE: |
| 1154 | 1155 | mm = intel_vgpu_get_ppgtt_mm(vgpu, root_entry_type, pdps); |
| 1155 | 1156 | return PTR_ERR_OR_ZERO(mm); |
| @@ -1301,7 +1301,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd, · 1300 unmodified lines | ||
| 1301 | 1301 | |
| 1302 | 1302 | } |
| 1303 | 1303 | |
| 1304 | − return 0; | |
| 1304 | + return -ENOTTY; | |
| 1305 | 1305 | } |
| 1306 | 1306 | |
| 1307 | 1307 | static ssize_t |
| @@ -1105,30 +1105,32 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) · 1104 unmodified lines | ||
| 1105 | 1105 | |
| 1106 | 1106 | ret = i915_ggtt_probe_hw(dev_priv); |
| 1107 | 1107 | if (ret) |
| 1108 | − return ret; | |
| 1108 | + goto err_perf; | |
| 1109 | 1109 | |
| 1110 | − /* WARNING: Apparently we must kick fbdev drivers before vgacon, | |
| 1111 | − * otherwise the vga fbdev driver falls over. */ | |
| 1110 | + /* | |
| 1111 | + * WARNING: Apparently we must kick fbdev drivers before vgacon, | |
| 1112 | + * otherwise the vga fbdev driver falls over. | |
| 1113 | + */ | |
| 1112 | 1114 | ret = i915_kick_out_firmware_fb(dev_priv); |
| 1113 | 1115 | if (ret) { |
| 1114 | 1116 | DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); |
| 1115 | − goto out_ggtt; | |
| 1117 | + goto err_ggtt; | |
| 1116 | 1118 | } |
| 1117 | 1119 | |
| 1118 | 1120 | ret = i915_kick_out_vgacon(dev_priv); |
| 1119 | 1121 | if (ret) { |
| 1120 | 1122 | DRM_ERROR("failed to remove conflicting VGA console\n"); |
| 1121 | − goto out_ggtt; | |
| 1123 | + goto err_ggtt; | |
| 1122 | 1124 | } |
| 1123 | 1125 | |
| 1124 | 1126 | ret = i915_ggtt_init_hw(dev_priv); |
| 1125 | 1127 | if (ret) |
| 1126 | − return ret; | |
| 1128 | + goto err_ggtt; | |
| 1127 | 1129 | |
| 1128 | 1130 | ret = i915_ggtt_enable_hw(dev_priv); |
| 1129 | 1131 | if (ret) { |
| 1130 | 1132 | DRM_ERROR("failed to enable GGTT\n"); |
| 1131 | − goto out_ggtt; | |
| 1133 | + goto err_ggtt; | |
| 1132 | 1134 | } |
| 1133 | 1135 | |
| 1134 | 1136 | pci_set_master(pdev); |
| @@ -1139,7 +1141,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) · 4 unmodified lines | ||
| 1139 | 1141 | if (ret) { |
| 1140 | 1142 | DRM_ERROR("failed to set DMA mask\n"); |
| 1141 | 1143 | |
| 1142 | − goto out_ggtt; | |
| 1144 | + goto err_ggtt; | |
| 1143 | 1145 | } |
| 1144 | 1146 | } |
| 1145 | 1147 | |
| @@ -1157,7 +1159,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) · 11 unmodified lines | ||
| 1157 | 1159 | if (ret) { |
| 1158 | 1160 | DRM_ERROR("failed to set DMA mask\n"); |
| 1159 | 1161 | |
| 1160 | − goto out_ggtt; | |
| 1162 | + goto err_ggtt; | |
| 1161 | 1163 | } |
| 1162 | 1164 | } |
| 1163 | 1165 | |
| @@ -1190,13 +1192,14 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) · 26 unmodified lines | ||
| 1190 | 1192 | |
| 1191 | 1193 | ret = intel_gvt_init(dev_priv); |
| 1192 | 1194 | if (ret) |
| 1193 | − goto out_ggtt; | |
| 1195 | + goto err_ggtt; | |
| 1194 | 1196 | |
| 1195 | 1197 | return 0; |
| 1196 | 1198 | |
| 1197 | −out_ggtt: | |
| 1199 | +err_ggtt: | |
| 1198 | 1200 | i915_ggtt_cleanup_hw(dev_priv); |
| 1199 | − | |
| 1201 | +err_perf: | |
| 1202 | + i915_perf_fini(dev_priv); | |
| 1200 | 1203 | return ret; |
| 1201 | 1204 | } |
| 1202 | 1205 | |
| @@ -728,7 +728,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) · 727 unmodified lines | ||
| 728 | 728 | |
| 729 | 729 | err = radix_tree_insert(handles_vma, handle, vma); |
| 730 | 730 | if (unlikely(err)) { |
| 731 | − kfree(lut); | |
| 731 | + kmem_cache_free(eb->i915->luts, lut); | |
| 732 | 732 | goto err_obj; |
| 733 | 733 | } |
| 734 | 734 | |
| @@ -473,20 +473,37 @@ static u64 get_rc6(struct drm_i915_private *i915) · 472 unmodified lines | ||
| 473 | 473 | spin_lock_irqsave(&i915->pmu.lock, flags); |
| 474 | 474 | spin_lock(&kdev->power.lock); |
| 475 | 475 | |
| 476 | − if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) | |
| 477 | − i915->pmu.suspended_jiffies_last = | |
| 478 | − kdev->power.suspended_jiffies; | |
| 476 | + /* | |
| 477 | + * After the above branch intel_runtime_pm_get_if_in_use failed | |
| 478 | + * to get the runtime PM reference we cannot assume we are in | |
| 479 | + * runtime suspend since we can either: a) race with coming out | |
| 480 | + * of it before we took the power.lock, or b) there are other | |
| 481 | + * states than suspended which can bring us here. | |
| 482 | + * | |
| 483 | + * We need to double-check that we are indeed currently runtime | |
| 484 | + * suspended and if not we cannot do better than report the last | |
| 485 | + * known RC6 value. | |
| 486 | + */ | |
| 487 | + if (kdev->power.runtime_status == RPM_SUSPENDED) { | |
| 488 | + if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) | |
| 489 | + i915->pmu.suspended_jiffies_last = | |
| 490 | + kdev->power.suspended_jiffies; | |
| 479 | 491 | |
| 480 | − val = kdev->power.suspended_jiffies - | |
| 481 | − i915->pmu.suspended_jiffies_last; | |
| 482 | − val += jiffies - kdev->power.accounting_timestamp; | |
| 492 | + val = kdev->power.suspended_jiffies - | |
| 493 | + i915->pmu.suspended_jiffies_last; | |
| 494 | + val += jiffies - kdev->power.accounting_timestamp; | |
| 483 | 495 | |
| 484 | − spin_unlock(&kdev->power.lock); | |
| 496 | + val = jiffies_to_nsecs(val); | |
| 497 | + val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; | |
| 485 | 498 | |
| 486 | − val = jiffies_to_nsecs(val); | |
| 487 | − val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; | |
| 488 | − i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; | |
| 499 | + i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; | |
| 500 | + } else if (i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) { | |
| 501 | + val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur; | |
| 502 | + } else { | |
| 503 | + val = i915->pmu.sample[__I915_SAMPLE_RC6].cur; | |
| 504 | + } | |
| 489 | 505 | |
| 506 | + spin_unlock(&kdev->power.lock); | |
| 490 | 507 | spin_unlock_irqrestore(&i915->pmu.lock, flags); |
| 491 | 508 | } |
| 492 | 509 | |
| @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, · 728 unmodified lines | ||
| 729 | 729 | struct drm_i915_private *dev_priv = kdev_to_i915(kdev); |
| 730 | 730 | u32 tmp; |
| 731 | 731 | |
| 732 | − if (!IS_GEN9_BC(dev_priv)) | |
| 732 | + if (!IS_GEN9(dev_priv)) | |
| 733 | 733 | return; |
| 734 | 734 | |
| 735 | 735 | i915_audio_component_get_power(kdev); |
| @@ -1256,7 +1256,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, · 1255 unmodified lines | ||
| 1256 | 1256 | return; |
| 1257 | 1257 | |
| 1258 | 1258 | aux_channel = child->aux_channel; |
| 1259 | − ddc_pin = child->ddc_pin; | |
| 1260 | 1259 | |
| 1261 | 1260 | is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING; |
| 1262 | 1261 | is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT; |
| @@ -1303,9 +1302,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, · 40 unmodified lines | ||
| 1303 | 1302 | DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port)); |
| 1304 | 1303 | |
| 1305 | 1304 | if (is_dvi) { |
| 1306 | − info->alternate_ddc_pin = map_ddc_pin(dev_priv, ddc_pin); | |
| 1307 | − | |
| 1308 | − sanitize_ddc_pin(dev_priv, port); | |
| 1305 | + ddc_pin = map_ddc_pin(dev_priv, child->ddc_pin); | |
| 1306 | + if (intel_gmbus_is_valid_pin(dev_priv, ddc_pin)) { | |
| 1307 | + info->alternate_ddc_pin = ddc_pin; | |
| 1308 | + sanitize_ddc_pin(dev_priv, port); | |
| 1309 | + } else { | |
| 1310 | + DRM_DEBUG_KMS("Port %c has invalid DDC pin %d, " | |
| 1311 | + "sticking to defaults\n", | |
| 1312 | + port_name(port), ddc_pin); | |
| 1313 | + } | |
| 1309 | 1314 | } |
| 1310 | 1315 | |
| 1311 | 1316 | if (is_dp) { |
| @@ -2140,10 +2140,22 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) · 2139 unmodified lines | ||
| 2140 | 2140 | } |
| 2141 | 2141 | } |
| 2142 | 2142 | |
| 2143 | − /* According to BSpec, "The CD clock frequency must be at least twice | |
| 2143 | + /* | |
| 2144 | + * According to BSpec, "The CD clock frequency must be at least twice | |
| 2144 | 2145 | * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default. |
| 2146 | + * | |
| 2147 | + * FIXME: Check the actual, not default, BCLK being used. | |
| 2148 | + * | |
| 2149 | + * FIXME: This does not depend on ->has_audio because the higher CDCLK | |
| 2150 | + * is required for audio probe, also when there are no audio capable | |
| 2151 | + * displays connected at probe time. This leads to unnecessarily high | |
| 2152 | + * CDCLK when audio is not required. | |
| 2153 | + * | |
| 2154 | + * FIXME: This limit is only applied when there are displays connected | |
| 2155 | + * at probe time. If we probe without displays, we'll still end up using | |
| 2156 | + * the platform minimum CDCLK, failing audio probe. | |
| 2145 | 2157 | */ |
| 2146 | − if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9) | |
| 2158 | + if (INTEL_GEN(dev_priv) >= 9) | |
| 2147 | 2159 | min_cdclk = max(2 * 96000, min_cdclk); |
| 2148 | 2160 | |
| 2149 | 2161 | /* |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | */ |
| 36 | 36 | |
| 37 | 37 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" |
| 38 | +MODULE_FIRMWARE(I915_CSR_GLK); | |
| 38 | 39 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) |
| 39 | 40 | |
| 40 | 41 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin" |
| @@ -49,12 +49,12 @@ · 48 unmodified lines | ||
| 49 | 49 | * check the condition before the timeout. |
| 50 | 50 | */ |
| 51 | 51 | #define __wait_for(OP, COND, US, Wmin, Wmax) ({ \ |
| 52 | − unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1; \ | |
| 52 | + const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \ | |
| 53 | 53 | long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \ |
| 54 | 54 | int ret__; \ |
| 55 | 55 | might_sleep(); \ |
| 56 | 56 | for (;;) { \ |
| 57 | − bool expired__ = time_after(jiffies, timeout__); \ | |
| 57 | + const bool expired__ = ktime_after(ktime_get_raw(), end__); \ | |
| 58 | 58 | OP; \ |
| 59 | 59 | if (COND) { \ |
| 60 | 60 | ret__ = 0; \ |
| @@ -806,7 +806,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev) · 805 unmodified lines | ||
| 806 | 806 | return; |
| 807 | 807 | |
| 808 | 808 | intel_fbdev_sync(ifbdev); |
| 809 | − if (ifbdev->vma) | |
| 809 | + if (ifbdev->vma || ifbdev->helper.deferred_setup) | |
| 810 | 810 | drm_fb_helper_hotplug_event(&ifbdev->helper); |
| 811 | 811 | } |
| 812 | 812 | |
| @@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 576 unmodified lines | ||
| 577 | 577 | * know the next preemption status we see corresponds |
| 578 | 578 | * to this ELSP update. |
| 579 | 579 | */ |
| 580 | + GEM_BUG_ON(!execlists_is_active(execlists, | |
| 581 | + EXECLISTS_ACTIVE_USER)); | |
| 580 | 582 | GEM_BUG_ON(!port_count(&port[0])); |
| 581 | 583 | if (port_count(&port[0]) > 1) |
| 582 | 584 | goto unlock; |
| @@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) · 155 unmodified lines | ||
| 738 | 740 | memset(port, 0, sizeof(*port)); |
| 739 | 741 | port++; |
| 740 | 742 | } |
| 743 | + | |
| 744 | + execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); | |
| 741 | 745 | } |
| 742 | 746 | |
| 743 | 747 | static void execlists_cancel_requests(struct intel_engine_cs *engine) |
| @@ -1001,6 +1005,11 @@ static void execlists_submission_tasklet(unsigned long data) · 257 unmodified lines | ||
| 1001 | 1005 | |
| 1002 | 1006 | if (fw) |
| 1003 | 1007 | intel_uncore_forcewake_put(dev_priv, execlists->fw_domains); |
| 1008 | + | |
| 1009 | + /* If the engine is now idle, so should be the flag; and vice versa. */ | |
| 1010 | + GEM_BUG_ON(execlists_is_active(&engine->execlists, | |
| 1011 | + EXECLISTS_ACTIVE_USER) == | |
| 1012 | + !port_isset(engine->execlists.port)); | |
| 1004 | 1013 | } |
| 1005 | 1014 | |
| 1006 | 1015 | static void queue_request(struct intel_engine_cs *engine, |
| @@ -641,19 +641,18 @@ void skl_enable_dc6(struct drm_i915_private *dev_priv) · 640 unmodified lines | ||
| 641 | 641 | |
| 642 | 642 | DRM_DEBUG_KMS("Enabling DC6\n"); |
| 643 | 643 | |
| 644 | − gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); | |
| 644 | + /* Wa Display #1183: skl,kbl,cfl */ | |
| 645 | + if (IS_GEN9_BC(dev_priv)) | |
| 646 | + I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) | | |
| 647 | + SKL_SELECT_ALTERNATE_DC_EXIT); | |
| 645 | 648 | |
| 649 | + gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); | |
| 646 | 650 | } |
| 647 | 651 | |
| 648 | 652 | void skl_disable_dc6(struct drm_i915_private *dev_priv) |
| 649 | 653 | { |
| 650 | 654 | DRM_DEBUG_KMS("Disabling DC6\n"); |
| 651 | 655 | |
| 652 | − /* Wa Display #1183: skl,kbl,cfl */ | |
| 653 | − if (IS_GEN9_BC(dev_priv)) | |
| 654 | − I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) | | |
| 655 | − SKL_SELECT_ALTERNATE_DC_EXIT); | |
| 656 | − | |
| 657 | 656 | gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); |
| 658 | 657 | } |
| 659 | 658 | |
| @@ -351,6 +351,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc, · 350 unmodified lines | ||
| 351 | 351 | |
| 352 | 352 | spin_lock_irqsave(&dev->event_lock, flags); |
| 353 | 353 | mdp4_crtc->event = crtc->state->event; |
| 354 | + crtc->state->event = NULL; | |
| 354 | 355 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 355 | 356 | |
| 356 | 357 | blend_setup(crtc); |
| @@ -708,6 +708,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc, · 707 unmodified lines | ||
| 708 | 708 | |
| 709 | 709 | spin_lock_irqsave(&dev->event_lock, flags); |
| 710 | 710 | mdp5_crtc->event = crtc->state->event; |
| 711 | + crtc->state->event = NULL; | |
| 711 | 712 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 712 | 713 | |
| 713 | 714 | /* |
| @@ -171,7 +171,8 @@ uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats, · 170 unmodified lines | ||
| 171 | 171 | return i; |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | −const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format) | |
| 174 | +const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, | |
| 175 | + uint64_t modifier) | |
| 175 | 176 | { |
| 176 | 177 | int i; |
| 177 | 178 | for (i = 0; i < ARRAY_SIZE(formats); i++) { |
| @@ -98,7 +98,7 @@ struct mdp_format { · 97 unmodified lines | ||
| 98 | 98 | #define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv) |
| 99 | 99 | |
| 100 | 100 | uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only); |
| 101 | −const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format); | |
| 101 | +const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier); | |
| 102 | 102 | |
| 103 | 103 | /* MDP capabilities */ |
| 104 | 104 | #define MDP_CAP_SMP BIT(0) /* Shared Memory Pool */ |
| @@ -173,6 +173,7 @@ struct msm_dsi_host { · 172 unmodified lines | ||
| 173 | 173 | |
| 174 | 174 | bool registered; |
| 175 | 175 | bool power_on; |
| 176 | + bool enabled; | |
| 176 | 177 | int irq; |
| 177 | 178 | }; |
| 178 | 179 | |
| @@ -775,7 +776,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt( · 596 unmodified lines | ||
| 775 | 776 | switch (mipi_fmt) { |
| 776 | 777 | case MIPI_DSI_FMT_RGB888: return CMD_DST_FORMAT_RGB888; |
| 777 | 778 | case MIPI_DSI_FMT_RGB666_PACKED: |
| 778 | − case MIPI_DSI_FMT_RGB666: return VID_DST_FORMAT_RGB666; | |
| 779 | + case MIPI_DSI_FMT_RGB666: return CMD_DST_FORMAT_RGB666; | |
| 779 | 780 | case MIPI_DSI_FMT_RGB565: return CMD_DST_FORMAT_RGB565; |
| 780 | 781 | default: return CMD_DST_FORMAT_RGB888; |
| 781 | 782 | } |
| @@ -986,13 +987,19 @@ static void dsi_set_tx_power_mode(int mode, struct msm_dsi_host *msm_host) · 204 unmodified lines | ||
| 986 | 987 | |
| 987 | 988 | static void dsi_wait4video_done(struct msm_dsi_host *msm_host) |
| 988 | 989 | { |
| 990 | + u32 ret = 0; | |
| 991 | + struct device *dev = &msm_host->pdev->dev; | |
| 992 | + | |
| 989 | 993 | dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 1); |
| 990 | 994 | |
| 991 | 995 | reinit_completion(&msm_host->video_comp); |
| 992 | 996 | |
| 993 | − wait_for_completion_timeout(&msm_host->video_comp, | |
| 997 | + ret = wait_for_completion_timeout(&msm_host->video_comp, | |
| 994 | 998 | msecs_to_jiffies(70)); |
| 995 | 999 | |
| 1000 | + if (ret <= 0) | |
| 1001 | + dev_err(dev, "wait for video done timed out\n"); | |
| 1002 | + | |
| 996 | 1003 | dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0); |
| 997 | 1004 | } |
| 998 | 1005 | |
| @@ -1001,7 +1008,7 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) · 2 unmodified lines | ||
| 1001 | 1008 | if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)) |
| 1002 | 1009 | return; |
| 1003 | 1010 | |
| 1004 | − if (msm_host->power_on) { | |
| 1011 | + if (msm_host->power_on && msm_host->enabled) { | |
| 1005 | 1012 | dsi_wait4video_done(msm_host); |
| 1006 | 1013 | /* delay 4 ms to skip BLLP */ |
| 1007 | 1014 | usleep_range(2000, 4000); |
| @@ -2203,7 +2210,7 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host) · 1195 unmodified lines | ||
| 2203 | 2210 | * pm_runtime_put_autosuspend(&msm_host->pdev->dev); |
| 2204 | 2211 | * } |
| 2205 | 2212 | */ |
| 2206 | − | |
| 2213 | + msm_host->enabled = true; | |
| 2207 | 2214 | return 0; |
| 2208 | 2215 | } |
| 2209 | 2216 | |
| @@ -2211,6 +2218,7 @@ int msm_dsi_host_disable(struct mipi_dsi_host *host) · 1 unmodified line | ||
| 2211 | 2218 | { |
| 2212 | 2219 | struct msm_dsi_host *msm_host = to_msm_dsi_host(host); |
| 2213 | 2220 | |
| 2221 | + msm_host->enabled = false; | |
| 2214 | 2222 | dsi_op_mode_config(msm_host, |
| 2215 | 2223 | !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), false); |
| 2216 | 2224 | |
| @@ -265,6 +265,115 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, · 264 unmodified lines | ||
| 265 | 265 | return 0; |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | +int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, | |
| 269 | + struct msm_dsi_phy_clk_request *clk_req) | |
| 270 | +{ | |
| 271 | + const unsigned long bit_rate = clk_req->bitclk_rate; | |
| 272 | + const unsigned long esc_rate = clk_req->escclk_rate; | |
| 273 | + s32 ui, ui_x8, lpx; | |
| 274 | + s32 tmax, tmin; | |
| 275 | + s32 pcnt0 = 50; | |
| 276 | + s32 pcnt1 = 50; | |
| 277 | + s32 pcnt2 = 10; | |
| 278 | + s32 pcnt3 = 30; | |
| 279 | + s32 pcnt4 = 10; | |
| 280 | + s32 pcnt5 = 2; | |
| 281 | + s32 coeff = 1000; /* Precision, should avoid overflow */ | |
| 282 | + s32 hb_en, hb_en_ckln; | |
| 283 | + s32 temp; | |
| 284 | + | |
| 285 | + if (!bit_rate || !esc_rate) | |
| 286 | + return -EINVAL; | |
| 287 | + | |
| 288 | + timing->hs_halfbyte_en = 0; | |
| 289 | + hb_en = 0; | |
| 290 | + timing->hs_halfbyte_en_ckln = 0; | |
| 291 | + hb_en_ckln = 0; | |
| 292 | + | |
| 293 | + ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000); | |
| 294 | + ui_x8 = ui << 3; | |
| 295 | + lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000); | |
| 296 | + | |
| 297 | + temp = S_DIV_ROUND_UP(38 * coeff, ui_x8); | |
| 298 | + tmin = max_t(s32, temp, 0); | |
| 299 | + temp = (95 * coeff) / ui_x8; | |
| 300 | + tmax = max_t(s32, temp, 0); | |
| 301 | + timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false); | |
| 302 | + | |
| 303 | + temp = 300 * coeff - (timing->clk_prepare << 3) * ui; | |
| 304 | + tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1; | |
| 305 | + tmax = (tmin > 255) ? 511 : 255; | |
| 306 | + timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false); | |
| 307 | + | |
| 308 | + tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8); | |
| 309 | + temp = 105 * coeff + 12 * ui - 20 * coeff; | |
| 310 | + tmax = (temp + 3 * ui) / ui_x8; | |
| 311 | + timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false); | |
| 312 | + | |
| 313 | + temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8); | |
| 314 | + tmin = max_t(s32, temp, 0); | |
| 315 | + temp = (85 * coeff + 6 * ui) / ui_x8; | |
| 316 | + tmax = max_t(s32, temp, 0); | |
| 317 | + timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false); | |
| 318 | + | |
| 319 | + temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui; | |
| 320 | + tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1; | |
| 321 | + tmax = 255; | |
| 322 | + timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false); | |
| 323 | + | |
| 324 | + tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1; | |
| 325 | + temp = 105 * coeff + 12 * ui - 20 * coeff; | |
| 326 | + tmax = (temp / ui_x8) - 1; | |
| 327 | + timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false); | |
| 328 | + | |
| 329 | + temp = 50 * coeff + ((hb_en << 2) - 8) * ui; | |
| 330 | + timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8); | |
| 331 | + | |
| 332 | + tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1; | |
| 333 | + tmax = 255; | |
| 334 | + timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false); | |
| 335 | + | |
| 336 | + temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui; | |
| 337 | + timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8); | |
| 338 | + | |
| 339 | + temp = 60 * coeff + 52 * ui - 43 * ui; | |
| 340 | + tmin = DIV_ROUND_UP(temp, ui_x8) - 1; | |
| 341 | + tmax = 63; | |
| 342 | + timing->shared_timings.clk_post = | |
| 343 | + linear_inter(tmax, tmin, pcnt2, 0, false); | |
| 344 | + | |
| 345 | + temp = 8 * ui + (timing->clk_prepare << 3) * ui; | |
| 346 | + temp += (((timing->clk_zero + 3) << 3) + 11) * ui; | |
| 347 | + temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) : | |
| 348 | + (((timing->hs_rqst_ckln << 3) + 8) * ui); | |
| 349 | + tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1; | |
| 350 | + tmax = 63; | |
| 351 | + if (tmin > tmax) { | |
| 352 | + temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false); | |
| 353 | + timing->shared_timings.clk_pre = temp >> 1; | |
| 354 | + timing->shared_timings.clk_pre_inc_by_2 = 1; | |
| 355 | + } else { | |
| 356 | + timing->shared_timings.clk_pre = | |
| 357 | + linear_inter(tmax, tmin, pcnt2, 0, false); | |
| 358 | + timing->shared_timings.clk_pre_inc_by_2 = 0; | |
| 359 | + } | |
| 360 | + | |
| 361 | + timing->ta_go = 3; | |
| 362 | + timing->ta_sure = 0; | |
| 363 | + timing->ta_get = 4; | |
| 364 | + | |
| 365 | + DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", | |
| 366 | + timing->shared_timings.clk_pre, timing->shared_timings.clk_post, | |
| 367 | + timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero, | |
| 368 | + timing->clk_trail, timing->clk_prepare, timing->hs_exit, | |
| 369 | + timing->hs_zero, timing->hs_prepare, timing->hs_trail, | |
| 370 | + timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en, | |
| 371 | + timing->hs_halfbyte_en_ckln, timing->hs_prep_dly, | |
| 372 | + timing->hs_prep_dly_ckln); | |
| 373 | + | |
| 374 | + return 0; | |
| 375 | +} | |
| 376 | + | |
| 268 | 377 | void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, |
| 269 | 378 | u32 bit_mask) |
| 270 | 379 | { |
| @@ -101,6 +101,8 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing, · 100 unmodified lines | ||
| 101 | 101 | struct msm_dsi_phy_clk_request *clk_req); |
| 102 | 102 | int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, |
| 103 | 103 | struct msm_dsi_phy_clk_request *clk_req); |
| 104 | +int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, | |
| 105 | + struct msm_dsi_phy_clk_request *clk_req); | |
| 104 | 106 | void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, |
| 105 | 107 | u32 bit_mask); |
| 106 | 108 | int msm_dsi_phy_init_common(struct msm_dsi_phy *phy); |
| @@ -79,34 +79,6 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy) · 78 unmodified lines | ||
| 79 | 79 | dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04); |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | −static int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, | |
| 83 | − struct msm_dsi_phy_clk_request *clk_req) | |
| 84 | −{ | |
| 85 | − /* | |
| 86 | − * TODO: These params need to be computed, they're currently hardcoded | |
| 87 | − * for a 1440x2560@60Hz panel with a byteclk of 100.618 Mhz, and a | |
| 88 | − * default escape clock of 19.2 Mhz. | |
| 89 | − */ | |
| 90 | − | |
| 91 | − timing->hs_halfbyte_en = 0; | |
| 92 | − timing->clk_zero = 0x1c; | |
| 93 | − timing->clk_prepare = 0x07; | |
| 94 | − timing->clk_trail = 0x07; | |
| 95 | − timing->hs_exit = 0x23; | |
| 96 | − timing->hs_zero = 0x21; | |
| 97 | − timing->hs_prepare = 0x07; | |
| 98 | − timing->hs_trail = 0x07; | |
| 99 | − timing->hs_rqst = 0x05; | |
| 100 | − timing->ta_sure = 0x00; | |
| 101 | − timing->ta_go = 0x03; | |
| 102 | − timing->ta_get = 0x04; | |
| 103 | − | |
| 104 | − timing->shared_timings.clk_pre = 0x2d; | |
| 105 | − timing->shared_timings.clk_post = 0x0d; | |
| 106 | − | |
| 107 | − return 0; | |
| 108 | −} | |
| 109 | − | |
| 110 | 82 | static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, |
| 111 | 83 | struct msm_dsi_phy_clk_request *clk_req) |
| 112 | 84 | { |
| @@ -183,7 +183,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, · 182 unmodified lines | ||
| 183 | 183 | hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format); |
| 184 | 184 | vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format); |
| 185 | 185 | |
| 186 | − format = kms->funcs->get_format(kms, mode_cmd->pixel_format); | |
| 186 | + format = kms->funcs->get_format(kms, mode_cmd->pixel_format, | |
| 187 | + mode_cmd->modifier[0]); | |
| 187 | 188 | if (!format) { |
| 188 | 189 | dev_err(dev->dev, "unsupported pixel format: %4.4s\n", |
| 189 | 190 | (char *)&mode_cmd->pixel_format); |
| @@ -92,8 +92,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, · 91 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | if (IS_ERR(fb)) { |
| 94 | 94 | dev_err(dev->dev, "failed to allocate fb\n"); |
| 95 | − ret = PTR_ERR(fb); | |
| 96 | − goto fail; | |
| 95 | + return PTR_ERR(fb); | |
| 97 | 96 | } |
| 98 | 97 | |
| 99 | 98 | bo = msm_framebuffer_bo(fb, 0); |
| @@ -151,13 +150,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, · 51 unmodified lines | ||
| 151 | 150 | |
| 152 | 151 | fail_unlock: |
| 153 | 152 | mutex_unlock(&dev->struct_mutex); |
| 154 | −fail: | |
| 155 | − | |
| 156 | − if (ret) { | |
| 157 | − if (fb) | |
| 158 | − drm_framebuffer_remove(fb); | |
| 159 | − } | |
| 160 | − | |
| 153 | + drm_framebuffer_remove(fb); | |
| 161 | 154 | return ret; |
| 162 | 155 | } |
| 163 | 156 | |
| @@ -132,17 +132,19 @@ static void put_pages(struct drm_gem_object *obj) · 131 unmodified lines | ||
| 132 | 132 | struct msm_gem_object *msm_obj = to_msm_bo(obj); |
| 133 | 133 | |
| 134 | 134 | if (msm_obj->pages) { |
| 135 | − /* For non-cached buffers, ensure the new pages are clean | |
| 136 | − * because display controller, GPU, etc. are not coherent: | |
| 137 | − */ | |
| 138 | − if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) | |
| 139 | − dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl, | |
| 140 | − msm_obj->sgt->nents, DMA_BIDIRECTIONAL); | |
| 135 | + if (msm_obj->sgt) { | |
| 136 | + /* For non-cached buffers, ensure the new | |
| 137 | + * pages are clean because display controller, | |
| 138 | + * GPU, etc. are not coherent: | |
| 139 | + */ | |
| 140 | + if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) | |
| 141 | + dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl, | |
| 142 | + msm_obj->sgt->nents, | |
| 143 | + DMA_BIDIRECTIONAL); | |
| 141 | 144 | |
| 142 | − if (msm_obj->sgt) | |
| 143 | 145 | sg_free_table(msm_obj->sgt); |
| 144 | − | |
| 145 | − kfree(msm_obj->sgt); | |
| 146 | + kfree(msm_obj->sgt); | |
| 147 | + } | |
| 146 | 148 | |
| 147 | 149 | if (use_pages(obj)) |
| 148 | 150 | drm_gem_put_pages(obj, msm_obj->pages, true, false); |
| @@ -48,8 +48,11 @@ struct msm_kms_funcs { · 47 unmodified lines | ||
| 48 | 48 | /* functions to wait for atomic commit completed on each CRTC */ |
| 49 | 49 | void (*wait_for_crtc_commit_done)(struct msm_kms *kms, |
| 50 | 50 | struct drm_crtc *crtc); |
| 51 | + /* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */ | |
| 52 | + const struct msm_format *(*get_format)(struct msm_kms *kms, | |
| 53 | + const uint32_t format, | |
| 54 | + const uint64_t modifiers); | |
| 51 | 55 | /* misc: */ |
| 52 | − const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format); | |
| 53 | 56 | long (*round_pixclk)(struct msm_kms *kms, unsigned long rate, |
| 54 | 57 | struct drm_encoder *encoder); |
| 55 | 58 | int (*set_split_display)(struct msm_kms *kms, |
| @@ -179,10 +179,9 @@ qxl_push_command_ring_release(struct qxl_device *qdev, struct qxl_release *relea · 178 unmodified lines | ||
| 179 | 179 | uint32_t type, bool interruptible) |
| 180 | 180 | { |
| 181 | 181 | struct qxl_command cmd; |
| 182 | − struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); | |
| 183 | 182 | |
| 184 | 183 | cmd.type = type; |
| 185 | − cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset); | |
| 184 | + cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset); | |
| 186 | 185 | |
| 187 | 186 | return qxl_ring_push(qdev->command_ring, &cmd, interruptible); |
| 188 | 187 | } |
| @@ -192,10 +191,9 @@ qxl_push_cursor_ring_release(struct qxl_device *qdev, struct qxl_release *releas · 3 unmodified lines | ||
| 192 | 191 | uint32_t type, bool interruptible) |
| 193 | 192 | { |
| 194 | 193 | struct qxl_command cmd; |
| 195 | − struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); | |
| 196 | 194 | |
| 197 | 195 | cmd.type = type; |
| 198 | − cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset); | |
| 196 | + cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset); | |
| 199 | 197 | |
| 200 | 198 | return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible); |
| 201 | 199 | } |
| @@ -167,6 +167,7 @@ struct qxl_release { · 166 unmodified lines | ||
| 167 | 167 | |
| 168 | 168 | int id; |
| 169 | 169 | int type; |
| 170 | + struct qxl_bo *release_bo; | |
| 170 | 171 | uint32_t release_offset; |
| 171 | 172 | uint32_t surface_release_id; |
| 172 | 173 | struct ww_acquire_ctx ticket; |
| @@ -182,9 +182,9 @@ static int qxl_process_single_command(struct qxl_device *qdev, · 181 unmodified lines | ||
| 182 | 182 | goto out_free_reloc; |
| 183 | 183 | |
| 184 | 184 | /* TODO copy slow path code from i915 */ |
| 185 | − fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE)); | |
| 185 | + fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK)); | |
| 186 | 186 | unwritten = __copy_from_user_inatomic_nocache |
| 187 | − (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE), | |
| 187 | + (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_MASK), | |
| 188 | 188 | u64_to_user_ptr(cmd->command), cmd->command_size); |
| 189 | 189 | |
| 190 | 190 | { |
| @@ -173,6 +173,7 @@ qxl_release_free_list(struct qxl_release *release) · 172 unmodified lines | ||
| 173 | 173 | list_del(&entry->tv.head); |
| 174 | 174 | kfree(entry); |
| 175 | 175 | } |
| 176 | + release->release_bo = NULL; | |
| 176 | 177 | } |
| 177 | 178 | |
| 178 | 179 | void |
| @@ -296,7 +297,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev, · 117 unmodified lines | ||
| 296 | 297 | { |
| 297 | 298 | if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) { |
| 298 | 299 | int idr_ret; |
| 299 | − struct qxl_bo_list *entry = list_first_entry(&create_rel->bos, struct qxl_bo_list, tv.head); | |
| 300 | 300 | struct qxl_bo *bo; |
| 301 | 301 | union qxl_release_info *info; |
| 302 | 302 | |
| @@ -304,8 +304,9 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev, · 1 unmodified line | ||
| 304 | 304 | idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release); |
| 305 | 305 | if (idr_ret < 0) |
| 306 | 306 | return idr_ret; |
| 307 | − bo = to_qxl_bo(entry->tv.bo); | |
| 307 | + bo = create_rel->release_bo; | |
| 308 | 308 | |
| 309 | + (*release)->release_bo = bo; | |
| 309 | 310 | (*release)->release_offset = create_rel->release_offset + 64; |
| 310 | 311 | |
| 311 | 312 | qxl_release_list_add(*release, bo); |
| @@ -365,6 +366,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, · 53 unmodified lines | ||
| 365 | 366 | |
| 366 | 367 | bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]); |
| 367 | 368 | |
| 369 | + (*release)->release_bo = bo; | |
| 368 | 370 | (*release)->release_offset = qdev->current_release_bo_offset[cur_idx] * release_size_per_bo[cur_idx]; |
| 369 | 371 | qdev->current_release_bo_offset[cur_idx]++; |
| 370 | 372 | |
| @@ -408,13 +410,12 @@ union qxl_release_info *qxl_release_map(struct qxl_device *qdev, · 37 unmodified lines | ||
| 408 | 410 | { |
| 409 | 411 | void *ptr; |
| 410 | 412 | union qxl_release_info *info; |
| 411 | − struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); | |
| 412 | − struct qxl_bo *bo = to_qxl_bo(entry->tv.bo); | |
| 413 | + struct qxl_bo *bo = release->release_bo; | |
| 413 | 414 | |
| 414 | − ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_SIZE); | |
| 415 | + ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_MASK); | |
| 415 | 416 | if (!ptr) |
| 416 | 417 | return NULL; |
| 417 | − info = ptr + (release->release_offset & ~PAGE_SIZE); | |
| 418 | + info = ptr + (release->release_offset & ~PAGE_MASK); | |
| 418 | 419 | return info; |
| 419 | 420 | } |
| 420 | 421 | |
| @@ -422,11 +423,10 @@ void qxl_release_unmap(struct qxl_device *qdev, · 1 unmodified line | ||
| 422 | 423 | struct qxl_release *release, |
| 423 | 424 | union qxl_release_info *info) |
| 424 | 425 | { |
| 425 | − struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); | |
| 426 | − struct qxl_bo *bo = to_qxl_bo(entry->tv.bo); | |
| 426 | + struct qxl_bo *bo = release->release_bo; | |
| 427 | 427 | void *ptr; |
| 428 | 428 | |
| 429 | − ptr = ((void *)info) - (release->release_offset & ~PAGE_SIZE); | |
| 429 | + ptr = ((void *)info) - (release->release_offset & ~PAGE_MASK); | |
| 430 | 430 | qxl_bo_kunmap_atomic_page(qdev, bo, ptr); |
| 431 | 431 | } |
| 432 | 432 | |
| @@ -94,64 +94,9 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder) · 93 unmodified lines | ||
| 94 | 94 | } |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | −static enum drm_mode_status sun4i_lvds_encoder_mode_valid(struct drm_encoder *crtc, | |
| 98 | − const struct drm_display_mode *mode) | |
| 99 | −{ | |
| 100 | − struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(crtc); | |
| 101 | − struct sun4i_tcon *tcon = lvds->tcon; | |
| 102 | − u32 hsync = mode->hsync_end - mode->hsync_start; | |
| 103 | − u32 vsync = mode->vsync_end - mode->vsync_start; | |
| 104 | − unsigned long rate = mode->clock * 1000; | |
| 105 | − long rounded_rate; | |
| 106 | − | |
| 107 | − DRM_DEBUG_DRIVER("Validating modes...\n"); | |
| 108 | − | |
| 109 | − if (hsync < 1) | |
| 110 | − return MODE_HSYNC_NARROW; | |
| 111 | − | |
| 112 | − if (hsync > 0x3ff) | |
| 113 | − return MODE_HSYNC_WIDE; | |
| 114 | − | |
| 115 | − if ((mode->hdisplay < 1) || (mode->htotal < 1)) | |
| 116 | − return MODE_H_ILLEGAL; | |
| 117 | − | |
| 118 | − if ((mode->hdisplay > 0x7ff) || (mode->htotal > 0xfff)) | |
| 119 | − return MODE_BAD_HVALUE; | |
| 120 | − | |
| 121 | − DRM_DEBUG_DRIVER("Horizontal parameters OK\n"); | |
| 122 | − | |
| 123 | − if (vsync < 1) | |
| 124 | − return MODE_VSYNC_NARROW; | |
| 125 | − | |
| 126 | − if (vsync > 0x3ff) | |
| 127 | − return MODE_VSYNC_WIDE; | |
| 128 | − | |
| 129 | − if ((mode->vdisplay < 1) || (mode->vtotal < 1)) | |
| 130 | − return MODE_V_ILLEGAL; | |
| 131 | − | |
| 132 | − if ((mode->vdisplay > 0x7ff) || (mode->vtotal > 0xfff)) | |
| 133 | − return MODE_BAD_VVALUE; | |
| 134 | − | |
| 135 | − DRM_DEBUG_DRIVER("Vertical parameters OK\n"); | |
| 136 | − | |
| 137 | − tcon->dclk_min_div = 7; | |
| 138 | − tcon->dclk_max_div = 7; | |
| 139 | − rounded_rate = clk_round_rate(tcon->dclk, rate); | |
| 140 | − if (rounded_rate < rate) | |
| 141 | − return MODE_CLOCK_LOW; | |
| 142 | − | |
| 143 | − if (rounded_rate > rate) | |
| 144 | − return MODE_CLOCK_HIGH; | |
| 145 | − | |
| 146 | − DRM_DEBUG_DRIVER("Clock rate OK\n"); | |
| 147 | − | |
| 148 | − return MODE_OK; | |
| 149 | −} | |
| 150 | − | |
| 151 | 97 | static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = { |
| 152 | 98 | .disable = sun4i_lvds_encoder_disable, |
| 153 | 99 | .enable = sun4i_lvds_encoder_enable, |
| 154 | − .mode_valid = sun4i_lvds_encoder_mode_valid, | |
| 155 | 100 | }; |
| 156 | 101 | |
| 157 | 102 | static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = { |
| @@ -195,6 +195,7 @@ static void vc4_bo_destroy(struct vc4_bo *bo) · 194 unmodified lines | ||
| 195 | 195 | vc4_bo_set_label(obj, -1); |
| 196 | 196 | |
| 197 | 197 | if (bo->validated_shader) { |
| 198 | + kfree(bo->validated_shader->uniform_addr_offsets); | |
| 198 | 199 | kfree(bo->validated_shader->texture_samples); |
| 199 | 200 | kfree(bo->validated_shader); |
| 200 | 201 | bo->validated_shader = NULL; |
| @@ -591,6 +592,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo) · 390 unmodified lines | ||
| 591 | 592 | } |
| 592 | 593 | |
| 593 | 594 | if (bo->validated_shader) { |
| 595 | + kfree(bo->validated_shader->uniform_addr_offsets); | |
| 594 | 596 | kfree(bo->validated_shader->texture_samples); |
| 595 | 597 | kfree(bo->validated_shader); |
| 596 | 598 | bo->validated_shader = NULL; |
| @@ -760,6 +760,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) · 759 unmodified lines | ||
| 760 | 760 | struct vc4_async_flip_state { |
| 761 | 761 | struct drm_crtc *crtc; |
| 762 | 762 | struct drm_framebuffer *fb; |
| 763 | + struct drm_framebuffer *old_fb; | |
| 763 | 764 | struct drm_pending_vblank_event *event; |
| 764 | 765 | |
| 765 | 766 | struct vc4_seqno_cb cb; |
| @@ -789,6 +790,23 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) · 23 unmodified lines | ||
| 789 | 790 | |
| 790 | 791 | drm_crtc_vblank_put(crtc); |
| 791 | 792 | drm_framebuffer_put(flip_state->fb); |
| 793 | + | |
| 794 | + /* Decrement the BO usecnt in order to keep the inc/dec calls balanced | |
| 795 | + * when the planes are updated through the async update path. | |
| 796 | + * FIXME: we should move to generic async-page-flip when it's | |
| 797 | + * available, so that we can get rid of this hand-made cleanup_fb() | |
| 798 | + * logic. | |
| 799 | + */ | |
| 800 | + if (flip_state->old_fb) { | |
| 801 | + struct drm_gem_cma_object *cma_bo; | |
| 802 | + struct vc4_bo *bo; | |
| 803 | + | |
| 804 | + cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0); | |
| 805 | + bo = to_vc4_bo(&cma_bo->base); | |
| 806 | + vc4_bo_dec_usecnt(bo); | |
| 807 | + drm_framebuffer_put(flip_state->old_fb); | |
| 808 | + } | |
| 809 | + | |
| 792 | 810 | kfree(flip_state); |
| 793 | 811 | |
| 794 | 812 | up(&vc4->async_modeset); |
| @@ -813,9 +831,22 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, · 18 unmodified lines | ||
| 813 | 831 | struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); |
| 814 | 832 | struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); |
| 815 | 833 | |
| 834 | + /* Increment the BO usecnt here, so that we never end up with an | |
| 835 | + * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the | |
| 836 | + * plane is later updated through the non-async path. | |
| 837 | + * FIXME: we should move to generic async-page-flip when it's | |
| 838 | + * available, so that we can get rid of this hand-made prepare_fb() | |
| 839 | + * logic. | |
| 840 | + */ | |
| 841 | + ret = vc4_bo_inc_usecnt(bo); | |
| 842 | + if (ret) | |
| 843 | + return ret; | |
| 844 | + | |
| 816 | 845 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); |
| 817 | − if (!flip_state) | |
| 846 | + if (!flip_state) { | |
| 847 | + vc4_bo_dec_usecnt(bo); | |
| 818 | 848 | return -ENOMEM; |
| 849 | + } | |
| 819 | 850 | |
| 820 | 851 | drm_framebuffer_get(fb); |
| 821 | 852 | flip_state->fb = fb; |
| @@ -826,10 +857,23 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, · 4 unmodified lines | ||
| 826 | 857 | ret = down_interruptible(&vc4->async_modeset); |
| 827 | 858 | if (ret) { |
| 828 | 859 | drm_framebuffer_put(fb); |
| 860 | + vc4_bo_dec_usecnt(bo); | |
| 829 | 861 | kfree(flip_state); |
| 830 | 862 | return ret; |
| 831 | 863 | } |
| 832 | 864 | |
| 865 | + /* Save the current FB before it's replaced by the new one in | |
| 866 | + * drm_atomic_set_fb_for_plane(). We'll need the old FB in | |
| 867 | + * vc4_async_page_flip_complete() to decrement the BO usecnt and keep | |
| 868 | + * it consistent. | |
| 869 | + * FIXME: we should move to generic async-page-flip when it's | |
| 870 | + * available, so that we can get rid of this hand-made cleanup_fb() | |
| 871 | + * logic. | |
| 872 | + */ | |
| 873 | + flip_state->old_fb = plane->state->fb; | |
| 874 | + if (flip_state->old_fb) | |
| 875 | + drm_framebuffer_get(flip_state->old_fb); | |
| 876 | + | |
| 833 | 877 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); |
| 834 | 878 | |
| 835 | 879 | /* Immediately update the plane's legacy fb pointer, so that later |
| @@ -942,6 +942,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) · 941 unmodified lines | ||
| 942 | 942 | fail: |
| 943 | 943 | kfree(validation_state.branch_targets); |
| 944 | 944 | if (validated_shader) { |
| 945 | + kfree(validated_shader->uniform_addr_offsets); | |
| 945 | 946 | kfree(validated_shader->texture_samples); |
| 946 | 947 | kfree(validated_shader); |
| 947 | 948 | } |
| @@ -293,7 +293,7 @@ retry: · 292 unmodified lines | ||
| 293 | 293 | ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC); |
| 294 | 294 | if (ret == -ENOSPC) { |
| 295 | 295 | spin_unlock(&vgdev->ctrlq.qlock); |
| 296 | − wait_event(vgdev->ctrlq.ack_queue, vq->num_free); | |
| 296 | + wait_event(vgdev->ctrlq.ack_queue, vq->num_free >= outcnt + incnt); | |
| 297 | 297 | spin_lock(&vgdev->ctrlq.qlock); |
| 298 | 298 | goto retry; |
| 299 | 299 | } else { |
| @@ -368,7 +368,7 @@ retry: · 68 unmodified lines | ||
| 368 | 368 | ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC); |
| 369 | 369 | if (ret == -ENOSPC) { |
| 370 | 370 | spin_unlock(&vgdev->cursorq.qlock); |
| 371 | − wait_event(vgdev->cursorq.ack_queue, vq->num_free); | |
| 371 | + wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt); | |
| 372 | 372 | spin_lock(&vgdev->cursorq.qlock); |
| 373 | 373 | goto retry; |
| 374 | 374 | } else { |
| @@ -441,11 +441,11 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set) · 440 unmodified lines | ||
| 441 | 441 | struct drm_crtc *crtc = set->crtc; |
| 442 | 442 | struct drm_framebuffer *fb; |
| 443 | 443 | struct drm_crtc *tmp; |
| 444 | − struct drm_modeset_acquire_ctx *ctx; | |
| 445 | 444 | struct drm_device *dev = set->crtc->dev; |
| 445 | + struct drm_modeset_acquire_ctx ctx; | |
| 446 | 446 | int ret; |
| 447 | 447 | |
| 448 | − ctx = dev->mode_config.acquire_ctx; | |
| 448 | + drm_modeset_acquire_init(&ctx, 0); | |
| 449 | 449 | |
| 450 | 450 | restart: |
| 451 | 451 | /* |
| @@ -458,7 +458,7 @@ restart: · 6 unmodified lines | ||
| 458 | 458 | |
| 459 | 459 | fb = set->fb; |
| 460 | 460 | |
| 461 | − ret = crtc->funcs->set_config(set, ctx); | |
| 461 | + ret = crtc->funcs->set_config(set, &ctx); | |
| 462 | 462 | if (ret == 0) { |
| 463 | 463 | crtc->primary->crtc = crtc; |
| 464 | 464 | crtc->primary->fb = fb; |
| @@ -473,20 +473,13 @@ restart: · 8 unmodified lines | ||
| 473 | 473 | } |
| 474 | 474 | |
| 475 | 475 | if (ret == -EDEADLK) { |
| 476 | − dev->mode_config.acquire_ctx = NULL; | |
| 477 | − | |
| 478 | −retry_locking: | |
| 479 | − drm_modeset_backoff(ctx); | |
| 480 | − | |
| 481 | − ret = drm_modeset_lock_all_ctx(dev, ctx); | |
| 482 | − if (ret) | |
| 483 | − goto retry_locking; | |
| 484 | − | |
| 485 | − dev->mode_config.acquire_ctx = ctx; | |
| 486 | − | |
| 476 | + drm_modeset_backoff(&ctx); | |
| 487 | 477 | goto restart; |
| 488 | 478 | } |
| 489 | 479 | |
| 480 | + drm_modeset_drop_locks(&ctx); | |
| 481 | + drm_modeset_acquire_fini(&ctx); | |
| 482 | + | |
| 490 | 483 | return ret; |
| 491 | 484 | } |
| 492 | 485 | |
| @@ -624,7 +617,6 @@ static int vmw_fb_set_par(struct fb_info *info) · 131 unmodified lines | ||
| 624 | 617 | } |
| 625 | 618 | |
| 626 | 619 | mutex_lock(&par->bo_mutex); |
| 627 | − drm_modeset_lock_all(vmw_priv->dev); | |
| 628 | 620 | ret = vmw_fb_kms_framebuffer(info); |
| 629 | 621 | if (ret) |
| 630 | 622 | goto out_unlock; |
| @@ -657,7 +649,6 @@ out_unlock: · 26 unmodified lines | ||
| 657 | 649 | drm_mode_destroy(vmw_priv->dev, old_mode); |
| 658 | 650 | par->set_mode = mode; |
| 659 | 651 | |
| 660 | − drm_modeset_unlock_all(vmw_priv->dev); | |
| 661 | 652 | mutex_unlock(&par->bo_mutex); |
| 662 | 653 | |
| 663 | 654 | return ret; |
| @@ -713,18 +704,14 @@ int vmw_fb_init(struct vmw_private *vmw_priv) · 49 unmodified lines | ||
| 713 | 704 | par->max_width = fb_width; |
| 714 | 705 | par->max_height = fb_height; |
| 715 | 706 | |
| 716 | − drm_modeset_lock_all(vmw_priv->dev); | |
| 717 | 707 | ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width, |
| 718 | 708 | par->max_height, &par->con, |
| 719 | 709 | &par->crtc, &init_mode); |
| 720 | − if (ret) { | |
| 721 | − drm_modeset_unlock_all(vmw_priv->dev); | |
| 710 | + if (ret) | |
| 722 | 711 | goto err_kms; |
| 723 | − } | |
| 724 | 712 | |
| 725 | 713 | info->var.xres = init_mode->hdisplay; |
| 726 | 714 | info->var.yres = init_mode->vdisplay; |
| 727 | − drm_modeset_unlock_all(vmw_priv->dev); | |
| 728 | 715 | |
| 729 | 716 | /* |
| 730 | 717 | * Create buffers and alloc memory |
| @@ -832,7 +819,9 @@ int vmw_fb_close(struct vmw_private *vmw_priv) · 101 unmodified lines | ||
| 832 | 819 | cancel_delayed_work_sync(&par->local_work); |
| 833 | 820 | unregister_framebuffer(info); |
| 834 | 821 | |
| 822 | + mutex_lock(&par->bo_mutex); | |
| 835 | 823 | (void) vmw_fb_kms_detach(par, true, true); |
| 824 | + mutex_unlock(&par->bo_mutex); | |
| 836 | 825 | |
| 837 | 826 | vfree(par->vmalloc); |
| 838 | 827 | framebuffer_release(info); |
| @@ -2595,6 +2595,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, · 2594 unmodified lines | ||
| 2595 | 2595 | vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, |
| 2596 | 2596 | out_fence, NULL); |
| 2597 | 2597 | |
| 2598 | + vmw_dmabuf_unreference(&ctx->buf); | |
| 2598 | 2599 | vmw_resource_unreserve(res, false, NULL, 0); |
| 2599 | 2600 | mutex_unlock(&res->dev_priv->cmdbuf_mutex); |
| 2600 | 2601 | } |
| @@ -2680,7 +2681,9 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, · 79 unmodified lines | ||
| 2680 | 2681 | struct vmw_display_unit *du; |
| 2681 | 2682 | struct drm_display_mode *mode; |
| 2682 | 2683 | int i = 0; |
| 2684 | + int ret = 0; | |
| 2683 | 2685 | |
| 2686 | + mutex_lock(&dev_priv->dev->mode_config.mutex); | |
| 2684 | 2687 | list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list, |
| 2685 | 2688 | head) { |
| 2686 | 2689 | if (i == unit) |
| @@ -2691,7 +2694,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, · 4 unmodified lines | ||
| 2691 | 2694 | |
| 2692 | 2695 | if (i != unit) { |
| 2693 | 2696 | DRM_ERROR("Could not find initial display unit.\n"); |
| 2694 | − return -EINVAL; | |
| 2697 | + ret = -EINVAL; | |
| 2698 | + goto out_unlock; | |
| 2695 | 2699 | } |
| 2696 | 2700 | |
| 2697 | 2701 | if (list_empty(&con->modes)) |
| @@ -2699,7 +2703,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, · 1 unmodified line | ||
| 2699 | 2703 | |
| 2700 | 2704 | if (list_empty(&con->modes)) { |
| 2701 | 2705 | DRM_ERROR("Could not find initial display mode.\n"); |
| 2702 | − return -EINVAL; | |
| 2706 | + ret = -EINVAL; | |
| 2707 | + goto out_unlock; | |
| 2703 | 2708 | } |
| 2704 | 2709 | |
| 2705 | 2710 | du = vmw_connector_to_du(con); |
| @@ -2720,7 +2725,10 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, · 14 unmodified lines | ||
| 2720 | 2725 | head); |
| 2721 | 2726 | } |
| 2722 | 2727 | |
| 2723 | − return 0; | |
| 2728 | + out_unlock: | |
| 2729 | + mutex_unlock(&dev_priv->dev->mode_config.mutex); | |
| 2730 | + | |
| 2731 | + return ret; | |
| 2724 | 2732 | } |
| 2725 | 2733 | |
| 2726 | 2734 | /** |
| @@ -525,6 +525,9 @@ · 524 unmodified lines | ||
| 525 | 525 | #define I2C_VENDOR_ID_HANTICK 0x0911 |
| 526 | 526 | #define I2C_PRODUCT_ID_HANTICK_5288 0x5288 |
| 527 | 527 | |
| 528 | +#define I2C_VENDOR_ID_RAYD 0x2386 | |
| 529 | +#define I2C_PRODUCT_ID_RAYD_3118 0x3118 | |
| 530 | + | |
| 528 | 531 | #define USB_VENDOR_ID_HANWANG 0x0b57 |
| 529 | 532 | #define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000 |
| 530 | 533 | #define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff |
| @@ -387,7 +387,8 @@ static int hidinput_get_battery_property(struct power_supply *psy, · 386 unmodified lines | ||
| 387 | 387 | break; |
| 388 | 388 | |
| 389 | 389 | case POWER_SUPPLY_PROP_CAPACITY: |
| 390 | − if (dev->battery_report_type == HID_FEATURE_REPORT) { | |
| 390 | + if (dev->battery_status != HID_BATTERY_REPORTED && | |
| 391 | + !dev->battery_avoid_query) { | |
| 391 | 392 | value = hidinput_query_battery_capacity(dev); |
| 392 | 393 | if (value < 0) |
| 393 | 394 | return value; |
| @@ -403,17 +404,17 @@ static int hidinput_get_battery_property(struct power_supply *psy, · 9 unmodified lines | ||
| 403 | 404 | break; |
| 404 | 405 | |
| 405 | 406 | case POWER_SUPPLY_PROP_STATUS: |
| 406 | − if (!dev->battery_reported && | |
| 407 | − dev->battery_report_type == HID_FEATURE_REPORT) { | |
| 407 | + if (dev->battery_status != HID_BATTERY_REPORTED && | |
| 408 | + !dev->battery_avoid_query) { | |
| 408 | 409 | value = hidinput_query_battery_capacity(dev); |
| 409 | 410 | if (value < 0) |
| 410 | 411 | return value; |
| 411 | 412 | |
| 412 | 413 | dev->battery_capacity = value; |
| 413 | − dev->battery_reported = true; | |
| 414 | + dev->battery_status = HID_BATTERY_QUERIED; | |
| 414 | 415 | } |
| 415 | 416 | |
| 416 | − if (!dev->battery_reported) | |
| 417 | + if (dev->battery_status == HID_BATTERY_UNKNOWN) | |
| 417 | 418 | val->intval = POWER_SUPPLY_STATUS_UNKNOWN; |
| 418 | 419 | else if (dev->battery_capacity == 100) |
| 419 | 420 | val->intval = POWER_SUPPLY_STATUS_FULL; |
| @@ -486,6 +487,14 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, · 66 unmodified lines | ||
| 486 | 487 | dev->battery_report_type = report_type; |
| 487 | 488 | dev->battery_report_id = field->report->id; |
| 488 | 489 | |
| 490 | + /* | |
| 491 | + * Stylus is normally not connected to the device and thus we | |
| 492 | + * can't query the device and get meaningful battery strength. | |
| 493 | + * We have to wait for the device to report it on its own. | |
| 494 | + */ | |
| 495 | + dev->battery_avoid_query = report_type == HID_INPUT_REPORT && | |
| 496 | + field->physical == HID_DG_STYLUS; | |
| 497 | + | |
| 489 | 498 | dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); |
| 490 | 499 | if (IS_ERR(dev->battery)) { |
| 491 | 500 | error = PTR_ERR(dev->battery); |
| @@ -530,9 +539,10 @@ static void hidinput_update_battery(struct hid_device *dev, int value) · 38 unmodified lines | ||
| 530 | 539 | |
| 531 | 540 | capacity = hidinput_scale_battery_capacity(dev, value); |
| 532 | 541 | |
| 533 | − if (!dev->battery_reported || capacity != dev->battery_capacity) { | |
| 542 | + if (dev->battery_status != HID_BATTERY_REPORTED || | |
| 543 | + capacity != dev->battery_capacity) { | |
| 534 | 544 | dev->battery_capacity = capacity; |
| 535 | − dev->battery_reported = true; | |
| 545 | + dev->battery_status = HID_BATTERY_REPORTED; | |
| 536 | 546 | power_supply_changed(dev->battery); |
| 537 | 547 | } |
| 538 | 548 | } |
| @@ -192,6 +192,11 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t · 191 unmodified lines | ||
| 192 | 192 | int ret = 0, len; |
| 193 | 193 | unsigned char report_number; |
| 194 | 194 | |
| 195 | + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { | |
| 196 | + ret = -ENODEV; | |
| 197 | + goto out; | |
| 198 | + } | |
| 199 | + | |
| 195 | 200 | dev = hidraw_table[minor]->hid; |
| 196 | 201 | |
| 197 | 202 | if (!dev->ll_driver->raw_request) { |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | /* quirks to control the device */ |
| 48 | 48 | #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) |
| 49 | 49 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) |
| 50 | +#define I2C_HID_QUIRK_RESEND_REPORT_DESCR BIT(2) | |
| 50 | 51 | |
| 51 | 52 | /* flags */ |
| 52 | 53 | #define I2C_HID_STARTED 0 |
| @@ -171,6 +172,8 @@ static const struct i2c_hid_quirks { · 118 unmodified lines | ||
| 171 | 172 | I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, |
| 172 | 173 | { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, |
| 173 | 174 | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, |
| 175 | + { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118, | |
| 176 | + I2C_HID_QUIRK_RESEND_REPORT_DESCR }, | |
| 174 | 177 | { 0, 0 } |
| 175 | 178 | }; |
| 176 | 179 | |
| @@ -1220,6 +1223,16 @@ static int i2c_hid_resume(struct device *dev) · 1043 unmodified lines | ||
| 1220 | 1223 | if (ret) |
| 1221 | 1224 | return ret; |
| 1222 | 1225 | |
| 1226 | + /* RAYDIUM device (2386:3118) need to re-send report descr cmd | |
| 1227 | + * after resume, after this it will be back normal. | |
| 1228 | + * otherwise it issues too many incomplete reports. | |
| 1229 | + */ | |
| 1230 | + if (ihid->quirks & I2C_HID_QUIRK_RESEND_REPORT_DESCR) { | |
| 1231 | + ret = i2c_hid_command(client, &hid_report_descr_cmd, NULL, 0); | |
| 1232 | + if (ret) | |
| 1233 | + return ret; | |
| 1234 | + } | |
| 1235 | + | |
| 1223 | 1236 | if (hid->driver && hid->driver->reset_resume) { |
| 1224 | 1237 | ret = hid->driver->reset_resume(hid); |
| 1225 | 1238 | return ret; |
| @@ -689,6 +689,45 @@ static int wacom_intuos_get_tool_type(int tool_id) · 688 unmodified lines | ||
| 689 | 689 | return tool_type; |
| 690 | 690 | } |
| 691 | 691 | |
| 692 | +static void wacom_exit_report(struct wacom_wac *wacom) | |
| 693 | +{ | |
| 694 | + struct input_dev *input = wacom->pen_input; | |
| 695 | + struct wacom_features *features = &wacom->features; | |
| 696 | + unsigned char *data = wacom->data; | |
| 697 | + int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; | |
| 698 | + | |
| 699 | + /* | |
| 700 | + * Reset all states otherwise we lose the initial states | |
| 701 | + * when in-prox next time | |
| 702 | + */ | |
| 703 | + input_report_abs(input, ABS_X, 0); | |
| 704 | + input_report_abs(input, ABS_Y, 0); | |
| 705 | + input_report_abs(input, ABS_DISTANCE, 0); | |
| 706 | + input_report_abs(input, ABS_TILT_X, 0); | |
| 707 | + input_report_abs(input, ABS_TILT_Y, 0); | |
| 708 | + if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { | |
| 709 | + input_report_key(input, BTN_LEFT, 0); | |
| 710 | + input_report_key(input, BTN_MIDDLE, 0); | |
| 711 | + input_report_key(input, BTN_RIGHT, 0); | |
| 712 | + input_report_key(input, BTN_SIDE, 0); | |
| 713 | + input_report_key(input, BTN_EXTRA, 0); | |
| 714 | + input_report_abs(input, ABS_THROTTLE, 0); | |
| 715 | + input_report_abs(input, ABS_RZ, 0); | |
| 716 | + } else { | |
| 717 | + input_report_abs(input, ABS_PRESSURE, 0); | |
| 718 | + input_report_key(input, BTN_STYLUS, 0); | |
| 719 | + input_report_key(input, BTN_STYLUS2, 0); | |
| 720 | + input_report_key(input, BTN_TOUCH, 0); | |
| 721 | + input_report_abs(input, ABS_WHEEL, 0); | |
| 722 | + if (features->type >= INTUOS3S) | |
| 723 | + input_report_abs(input, ABS_Z, 0); | |
| 724 | + } | |
| 725 | + input_report_key(input, wacom->tool[idx], 0); | |
| 726 | + input_report_abs(input, ABS_MISC, 0); /* reset tool id */ | |
| 727 | + input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | |
| 728 | + wacom->id[idx] = 0; | |
| 729 | +} | |
| 730 | + | |
| 692 | 731 | static int wacom_intuos_inout(struct wacom_wac *wacom) |
| 693 | 732 | { |
| 694 | 733 | struct wacom_features *features = &wacom->features; |
| @@ -741,36 +780,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) · 46 unmodified lines | ||
| 741 | 780 | if (!wacom->id[idx]) |
| 742 | 781 | return 1; |
| 743 | 782 | |
| 744 | − /* | |
| 745 | − * Reset all states otherwise we lose the initial states | |
| 746 | − * when in-prox next time | |
| 747 | − */ | |
| 748 | − input_report_abs(input, ABS_X, 0); | |
| 749 | − input_report_abs(input, ABS_Y, 0); | |
| 750 | − input_report_abs(input, ABS_DISTANCE, 0); | |
| 751 | − input_report_abs(input, ABS_TILT_X, 0); | |
| 752 | − input_report_abs(input, ABS_TILT_Y, 0); | |
| 753 | − if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { | |
| 754 | − input_report_key(input, BTN_LEFT, 0); | |
| 755 | − input_report_key(input, BTN_MIDDLE, 0); | |
| 756 | − input_report_key(input, BTN_RIGHT, 0); | |
| 757 | − input_report_key(input, BTN_SIDE, 0); | |
| 758 | − input_report_key(input, BTN_EXTRA, 0); | |
| 759 | − input_report_abs(input, ABS_THROTTLE, 0); | |
| 760 | − input_report_abs(input, ABS_RZ, 0); | |
| 761 | − } else { | |
| 762 | − input_report_abs(input, ABS_PRESSURE, 0); | |
| 763 | − input_report_key(input, BTN_STYLUS, 0); | |
| 764 | − input_report_key(input, BTN_STYLUS2, 0); | |
| 765 | − input_report_key(input, BTN_TOUCH, 0); | |
| 766 | − input_report_abs(input, ABS_WHEEL, 0); | |
| 767 | − if (features->type >= INTUOS3S) | |
| 768 | − input_report_abs(input, ABS_Z, 0); | |
| 769 | − } | |
| 770 | − input_report_key(input, wacom->tool[idx], 0); | |
| 771 | − input_report_abs(input, ABS_MISC, 0); /* reset tool id */ | |
| 772 | − input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | |
| 773 | − wacom->id[idx] = 0; | |
| 783 | + wacom_exit_report(wacom); | |
| 774 | 784 | return 2; |
| 775 | 785 | } |
| 776 | 786 | |
| @@ -1235,6 +1245,12 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) · 458 unmodified lines | ||
| 1235 | 1245 | if (!valid) |
| 1236 | 1246 | continue; |
| 1237 | 1247 | |
| 1248 | + if (!prox) { | |
| 1249 | + wacom->shared->stylus_in_proximity = false; | |
| 1250 | + wacom_exit_report(wacom); | |
| 1251 | + input_sync(pen_input); | |
| 1252 | + return; | |
| 1253 | + } | |
| 1238 | 1254 | if (range) { |
| 1239 | 1255 | input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); |
| 1240 | 1256 | input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); |
| @@ -40,6 +40,10 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); · 39 unmodified lines | ||
| 40 | 40 | #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 |
| 41 | 41 | #endif |
| 42 | 42 | |
| 43 | +#ifndef PCI_DEVICE_ID_AMD_17H_RR_NB | |
| 44 | +#define PCI_DEVICE_ID_AMD_17H_RR_NB 0x15d0 | |
| 45 | +#endif | |
| 46 | + | |
| 43 | 47 | /* CPUID function 0x80000001, ebx */ |
| 44 | 48 | #define CPUID_PKGTYPE_MASK 0xf0000000 |
| 45 | 49 | #define CPUID_PKGTYPE_F 0x00000000 |
| @@ -72,6 +76,7 @@ struct k10temp_data { · 26 unmodified lines | ||
| 72 | 76 | struct pci_dev *pdev; |
| 73 | 77 | void (*read_tempreg)(struct pci_dev *pdev, u32 *regval); |
| 74 | 78 | int temp_offset; |
| 79 | + u32 temp_adjust_mask; | |
| 75 | 80 | }; |
| 76 | 81 | |
| 77 | 82 | struct tctl_offset { |
| @@ -84,6 +89,7 @@ static const struct tctl_offset tctl_offset_table[] = { · 6 unmodified lines | ||
| 84 | 89 | { 0x17, "AMD Ryzen 5 1600X", 20000 }, |
| 85 | 90 | { 0x17, "AMD Ryzen 7 1700X", 20000 }, |
| 86 | 91 | { 0x17, "AMD Ryzen 7 1800X", 20000 }, |
| 92 | + { 0x17, "AMD Ryzen 7 2700X", 10000 }, | |
| 87 | 93 | { 0x17, "AMD Ryzen Threadripper 1950X", 27000 }, |
| 88 | 94 | { 0x17, "AMD Ryzen Threadripper 1920X", 27000 }, |
| 89 | 95 | { 0x17, "AMD Ryzen Threadripper 1900X", 27000 }, |
| @@ -129,6 +135,8 @@ static ssize_t temp1_input_show(struct device *dev, · 39 unmodified lines | ||
| 129 | 135 | |
| 130 | 136 | data->read_tempreg(data->pdev, ®val); |
| 131 | 137 | temp = (regval >> 21) * 125; |
| 138 | + if (regval & data->temp_adjust_mask) | |
| 139 | + temp -= 49000; | |
| 132 | 140 | if (temp > data->temp_offset) |
| 133 | 141 | temp -= data->temp_offset; |
| 134 | 142 | else |
| @@ -259,12 +267,14 @@ static int k10temp_probe(struct pci_dev *pdev, · 124 unmodified lines | ||
| 259 | 267 | data->pdev = pdev; |
| 260 | 268 | |
| 261 | 269 | if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 || |
| 262 | − boot_cpu_data.x86_model == 0x70)) | |
| 270 | + boot_cpu_data.x86_model == 0x70)) { | |
| 263 | 271 | data->read_tempreg = read_tempreg_nb_f15; |
| 264 | − else if (boot_cpu_data.x86 == 0x17) | |
| 272 | + } else if (boot_cpu_data.x86 == 0x17) { | |
| 273 | + data->temp_adjust_mask = 0x80000; | |
| 265 | 274 | data->read_tempreg = read_tempreg_nb_f17; |
| 266 | − else | |
| 275 | + } else { | |
| 267 | 276 | data->read_tempreg = read_tempreg_pci; |
| 277 | + } | |
| 268 | 278 | |
| 269 | 279 | for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) { |
| 270 | 280 | const struct tctl_offset *entry = &tctl_offset_table[i]; |
| @@ -292,6 +302,7 @@ static const struct pci_device_id k10temp_id_table[] = { · 21 unmodified lines | ||
| 292 | 302 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, |
| 293 | 303 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, |
| 294 | 304 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, |
| 305 | + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_RR_NB) }, | |
| 295 | 306 | {} |
| 296 | 307 | }; |
| 297 | 308 | MODULE_DEVICE_TABLE(pci, k10temp_id_table); |
| @@ -1380,8 +1380,8 @@ static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data) · 1379 unmodified lines | ||
| 1380 | 1380 | /* Activate logical device if needed */ |
| 1381 | 1381 | val = superio_inb(sioaddr, SIO_REG_ENABLE); |
| 1382 | 1382 | if (!(val & 0x01)) { |
| 1383 | − pr_err("EC is disabled\n"); | |
| 1384 | − goto fail; | |
| 1383 | + pr_warn("Forcibly enabling EC access. Data may be unusable.\n"); | |
| 1384 | + superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | |
| 1385 | 1385 | } |
| 1386 | 1386 | |
| 1387 | 1387 | superio_exit(sioaddr); |
| @@ -170,7 +170,10 @@ static int scmi_hwmon_probe(struct scmi_device *sdev) · 169 unmodified lines | ||
| 170 | 170 | scmi_chip_info.info = ptr_scmi_ci; |
| 171 | 171 | chip_info = &scmi_chip_info; |
| 172 | 172 | |
| 173 | − for (type = 0; type < hwmon_max && nr_count[type]; type++) { | |
| 173 | + for (type = 0; type < hwmon_max; type++) { | |
| 174 | + if (!nr_count[type]) | |
| 175 | + continue; | |
| 176 | + | |
| 174 | 177 | scmi_hwmon_add_chan_info(scmi_hwmon_chan, dev, nr_count[type], |
| 175 | 178 | type, hwmon_attributes[type]); |
| 176 | 179 | *ptr_scmi_ci++ = scmi_hwmon_chan++; |
| @@ -707,7 +707,6 @@ config I2C_MPC · 706 unmodified lines | ||
| 707 | 707 | config I2C_MT65XX |
| 708 | 708 | tristate "MediaTek I2C adapter" |
| 709 | 709 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 710 | − depends on HAS_DMA | |
| 711 | 710 | help |
| 712 | 711 | This selects the MediaTek(R) Integrated Inter Circuit bus driver |
| 713 | 712 | for MT65xx and MT81xx. |
| @@ -885,7 +884,6 @@ config I2C_SH7760 · 171 unmodified lines | ||
| 885 | 884 | |
| 886 | 885 | config I2C_SH_MOBILE |
| 887 | 886 | tristate "SuperH Mobile I2C Controller" |
| 888 | − depends on HAS_DMA | |
| 889 | 887 | depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST |
| 890 | 888 | help |
| 891 | 889 | If you say yes to this option, support will be included for the |
| @@ -1098,7 +1096,6 @@ config I2C_XLP9XX · 206 unmodified lines | ||
| 1098 | 1096 | |
| 1099 | 1097 | config I2C_RCAR |
| 1100 | 1098 | tristate "Renesas R-Car I2C Controller" |
| 1101 | − depends on HAS_DMA | |
| 1102 | 1099 | depends on ARCH_RENESAS || COMPILE_TEST |
| 1103 | 1100 | select I2C_SLAVE |
| 1104 | 1101 | help |
| @@ -86,6 +86,7 @@ struct sprd_i2c { · 85 unmodified lines | ||
| 86 | 86 | u32 count; |
| 87 | 87 | int irq; |
| 88 | 88 | int err; |
| 89 | + bool is_suspended; | |
| 89 | 90 | }; |
| 90 | 91 | |
| 91 | 92 | static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count) |
| @@ -283,6 +284,9 @@ static int sprd_i2c_master_xfer(struct i2c_adapter *i2c_adap, · 191 unmodified lines | ||
| 283 | 284 | struct sprd_i2c *i2c_dev = i2c_adap->algo_data; |
| 284 | 285 | int im, ret; |
| 285 | 286 | |
| 287 | + if (i2c_dev->is_suspended) | |
| 288 | + return -EBUSY; | |
| 289 | + | |
| 286 | 290 | ret = pm_runtime_get_sync(i2c_dev->dev); |
| 287 | 291 | if (ret < 0) |
| 288 | 292 | return ret; |
| @@ -364,13 +368,12 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id) · 75 unmodified lines | ||
| 364 | 368 | struct sprd_i2c *i2c_dev = dev_id; |
| 365 | 369 | struct i2c_msg *msg = i2c_dev->msg; |
| 366 | 370 | bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK); |
| 367 | − u32 i2c_count = readl(i2c_dev->base + I2C_COUNT); | |
| 368 | 371 | u32 i2c_tran; |
| 369 | 372 | |
| 370 | 373 | if (msg->flags & I2C_M_RD) |
| 371 | 374 | i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD; |
| 372 | 375 | else |
| 373 | − i2c_tran = i2c_count; | |
| 376 | + i2c_tran = i2c_dev->count; | |
| 374 | 377 | |
| 375 | 378 | /* |
| 376 | 379 | * If we got one ACK from slave when writing data, and we did not |
| @@ -408,14 +411,13 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id) · 31 unmodified lines | ||
| 408 | 411 | { |
| 409 | 412 | struct sprd_i2c *i2c_dev = dev_id; |
| 410 | 413 | struct i2c_msg *msg = i2c_dev->msg; |
| 411 | − u32 i2c_count = readl(i2c_dev->base + I2C_COUNT); | |
| 412 | 414 | bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK); |
| 413 | 415 | u32 i2c_tran; |
| 414 | 416 | |
| 415 | 417 | if (msg->flags & I2C_M_RD) |
| 416 | 418 | i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD; |
| 417 | 419 | else |
| 418 | − i2c_tran = i2c_count; | |
| 420 | + i2c_tran = i2c_dev->count; | |
| 419 | 421 | |
| 420 | 422 | /* |
| 421 | 423 | * If we did not get one ACK from slave when writing data, then we |
| @@ -586,11 +588,23 @@ static int sprd_i2c_remove(struct platform_device *pdev) · 164 unmodified lines | ||
| 586 | 588 | |
| 587 | 589 | static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev) |
| 588 | 590 | { |
| 591 | + struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev); | |
| 592 | + | |
| 593 | + i2c_lock_adapter(&i2c_dev->adap); | |
| 594 | + i2c_dev->is_suspended = true; | |
| 595 | + i2c_unlock_adapter(&i2c_dev->adap); | |
| 596 | + | |
| 589 | 597 | return pm_runtime_force_suspend(pdev); |
| 590 | 598 | } |
| 591 | 599 | |
| 592 | 600 | static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev) |
| 593 | 601 | { |
| 602 | + struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev); | |
| 603 | + | |
| 604 | + i2c_lock_adapter(&i2c_dev->adap); | |
| 605 | + i2c_dev->is_suspended = false; | |
| 606 | + i2c_unlock_adapter(&i2c_dev->adap); | |
| 607 | + | |
| 594 | 608 | return pm_runtime_force_resume(pdev); |
| 595 | 609 | } |
| 596 | 610 | |
| @@ -280,7 +280,7 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, · 279 unmodified lines | ||
| 280 | 280 | */ |
| 281 | 281 | if (msgs[i].flags & I2C_M_RECV_LEN) { |
| 282 | 282 | if (!(msgs[i].flags & I2C_M_RD) || |
| 283 | − msgs[i].buf[0] < 1 || | |
| 283 | + msgs[i].len < 1 || msgs[i].buf[0] < 1 || | |
| 284 | 284 | msgs[i].len < msgs[i].buf[0] + |
| 285 | 285 | I2C_SMBUS_BLOCK_MAX) { |
| 286 | 286 | res = -EINVAL; |
| @@ -61,9 +61,12 @@ config INFINIBAND_ON_DEMAND_PAGING · 60 unmodified lines | ||
| 61 | 61 | pages on demand instead. |
| 62 | 62 | |
| 63 | 63 | config INFINIBAND_ADDR_TRANS |
| 64 | − bool | |
| 64 | + bool "RDMA/CM" | |
| 65 | 65 | depends on INFINIBAND |
| 66 | 66 | default y |
| 67 | + ---help--- | |
| 68 | + Support for RDMA communication manager (CM). | |
| 69 | + This allows for a generic connection abstraction over RDMA. | |
| 67 | 70 | |
| 68 | 71 | config INFINIBAND_ADDR_TRANS_CONFIGFS |
| 69 | 72 | bool |
| @@ -291,14 +291,18 @@ static int find_gid(struct ib_gid_table *table, const union ib_gid *gid, · 290 unmodified lines | ||
| 291 | 291 | * so lookup free slot only if requested. |
| 292 | 292 | */ |
| 293 | 293 | if (pempty && empty < 0) { |
| 294 | − if (data->props & GID_TABLE_ENTRY_INVALID) { | |
| 295 | − /* Found an invalid (free) entry; allocate it */ | |
| 296 | − if (data->props & GID_TABLE_ENTRY_DEFAULT) { | |
| 297 | − if (default_gid) | |
| 298 | − empty = curr_index; | |
| 299 | − } else { | |
| 300 | − empty = curr_index; | |
| 301 | − } | |
| 294 | + if (data->props & GID_TABLE_ENTRY_INVALID && | |
| 295 | + (default_gid == | |
| 296 | + !!(data->props & GID_TABLE_ENTRY_DEFAULT))) { | |
| 297 | + /* | |
| 298 | + * Found an invalid (free) entry; allocate it. | |
| 299 | + * If default GID is requested, then our | |
| 300 | + * found slot must be one of the DEFAULT | |
| 301 | + * reserved slots or we fail. | |
| 302 | + * This ensures that only DEFAULT reserved | |
| 303 | + * slots are used for default property GIDs. | |
| 304 | + */ | |
| 305 | + empty = curr_index; | |
| 302 | 306 | } |
| 303 | 307 | } |
| 304 | 308 | |
| @@ -420,8 +424,10 @@ int ib_cache_gid_add(struct ib_device *ib_dev, u8 port, · 115 unmodified lines | ||
| 420 | 424 | return ret; |
| 421 | 425 | } |
| 422 | 426 | |
| 423 | −int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | |
| 424 | − union ib_gid *gid, struct ib_gid_attr *attr) | |
| 427 | +static int | |
| 428 | +_ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | |
| 429 | + union ib_gid *gid, struct ib_gid_attr *attr, | |
| 430 | + unsigned long mask, bool default_gid) | |
| 425 | 431 | { |
| 426 | 432 | struct ib_gid_table *table; |
| 427 | 433 | int ret = 0; |
| @@ -431,11 +437,7 @@ int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, · 3 unmodified lines | ||
| 431 | 437 | |
| 432 | 438 | mutex_lock(&table->lock); |
| 433 | 439 | |
| 434 | − ix = find_gid(table, gid, attr, false, | |
| 435 | − GID_ATTR_FIND_MASK_GID | | |
| 436 | − GID_ATTR_FIND_MASK_GID_TYPE | | |
| 437 | − GID_ATTR_FIND_MASK_NETDEV, | |
| 438 | − NULL); | |
| 440 | + ix = find_gid(table, gid, attr, default_gid, mask, NULL); | |
| 439 | 441 | if (ix < 0) { |
| 440 | 442 | ret = -EINVAL; |
| 441 | 443 | goto out_unlock; |
| @@ -452,6 +454,17 @@ out_unlock: · 10 unmodified lines | ||
| 452 | 454 | return ret; |
| 453 | 455 | } |
| 454 | 456 | |
| 457 | +int ib_cache_gid_del(struct ib_device *ib_dev, u8 port, | |
| 458 | + union ib_gid *gid, struct ib_gid_attr *attr) | |
| 459 | +{ | |
| 460 | + unsigned long mask = GID_ATTR_FIND_MASK_GID | | |
| 461 | + GID_ATTR_FIND_MASK_GID_TYPE | | |
| 462 | + GID_ATTR_FIND_MASK_DEFAULT | | |
| 463 | + GID_ATTR_FIND_MASK_NETDEV; | |
| 464 | + | |
| 465 | + return _ib_cache_gid_del(ib_dev, port, gid, attr, mask, false); | |
| 466 | +} | |
| 467 | + | |
| 455 | 468 | int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port, |
| 456 | 469 | struct net_device *ndev) |
| 457 | 470 | { |
| @@ -728,7 +741,7 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, · 270 unmodified lines | ||
| 728 | 741 | unsigned long gid_type_mask, |
| 729 | 742 | enum ib_cache_gid_default_mode mode) |
| 730 | 743 | { |
| 731 | − union ib_gid gid; | |
| 744 | + union ib_gid gid = { }; | |
| 732 | 745 | struct ib_gid_attr gid_attr; |
| 733 | 746 | struct ib_gid_table *table; |
| 734 | 747 | unsigned int gid_type; |
| @@ -736,7 +749,9 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, · 1 unmodified line | ||
| 736 | 749 | |
| 737 | 750 | table = ib_dev->cache.ports[port - rdma_start_port(ib_dev)].gid; |
| 738 | 751 | |
| 739 | − make_default_gid(ndev, &gid); | |
| 752 | + mask = GID_ATTR_FIND_MASK_GID_TYPE | | |
| 753 | + GID_ATTR_FIND_MASK_DEFAULT | | |
| 754 | + GID_ATTR_FIND_MASK_NETDEV; | |
| 740 | 755 | memset(&gid_attr, 0, sizeof(gid_attr)); |
| 741 | 756 | gid_attr.ndev = ndev; |
| 742 | 757 | |
| @@ -747,12 +762,12 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port, · 4 unmodified lines | ||
| 747 | 762 | gid_attr.gid_type = gid_type; |
| 748 | 763 | |
| 749 | 764 | if (mode == IB_CACHE_GID_DEFAULT_MODE_SET) { |
| 750 | − mask = GID_ATTR_FIND_MASK_GID_TYPE | | |
| 751 | − GID_ATTR_FIND_MASK_DEFAULT; | |
| 765 | + make_default_gid(ndev, &gid); | |
| 752 | 766 | __ib_cache_gid_add(ib_dev, port, &gid, |
| 753 | 767 | &gid_attr, mask, true); |
| 754 | 768 | } else if (mode == IB_CACHE_GID_DEFAULT_MODE_DELETE) { |
| 755 | − ib_cache_gid_del(ib_dev, port, &gid, &gid_attr); | |
| 769 | + _ib_cache_gid_del(ib_dev, port, &gid, | |
| 770 | + &gid_attr, mask, true); | |
| 756 | 771 | } |
| 757 | 772 | } |
| 758 | 773 | } |
| @@ -382,6 +382,8 @@ struct cma_hdr { · 381 unmodified lines | ||
| 382 | 382 | #define CMA_VERSION 0x00 |
| 383 | 383 | |
| 384 | 384 | struct cma_req_info { |
| 385 | + struct sockaddr_storage listen_addr_storage; | |
| 386 | + struct sockaddr_storage src_addr_storage; | |
| 385 | 387 | struct ib_device *device; |
| 386 | 388 | int port; |
| 387 | 389 | union ib_gid local_gid; |
| @@ -866,7 +868,6 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv, · 478 unmodified lines | ||
| 866 | 868 | { |
| 867 | 869 | struct ib_qp_attr qp_attr; |
| 868 | 870 | int qp_attr_mask, ret; |
| 869 | − union ib_gid sgid; | |
| 870 | 871 | |
| 871 | 872 | mutex_lock(&id_priv->qp_mutex); |
| 872 | 873 | if (!id_priv->id.qp) { |
| @@ -889,12 +890,6 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv, · 16 unmodified lines | ||
| 889 | 890 | if (ret) |
| 890 | 891 | goto out; |
| 891 | 892 | |
| 892 | − ret = ib_query_gid(id_priv->id.device, id_priv->id.port_num, | |
| 893 | − rdma_ah_read_grh(&qp_attr.ah_attr)->sgid_index, | |
| 894 | − &sgid, NULL); | |
| 895 | − if (ret) | |
| 896 | − goto out; | |
| 897 | − | |
| 898 | 893 | BUG_ON(id_priv->cma_dev->device != id_priv->id.device); |
| 899 | 894 | |
| 900 | 895 | if (conn_param) |
| @@ -1340,11 +1335,11 @@ static bool validate_net_dev(struct net_device *net_dev, · 439 unmodified lines | ||
| 1340 | 1335 | } |
| 1341 | 1336 | |
| 1342 | 1337 | static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event, |
| 1343 | − const struct cma_req_info *req) | |
| 1338 | + struct cma_req_info *req) | |
| 1344 | 1339 | { |
| 1345 | − struct sockaddr_storage listen_addr_storage, src_addr_storage; | |
| 1346 | − struct sockaddr *listen_addr = (struct sockaddr *)&listen_addr_storage, | |
| 1347 | − *src_addr = (struct sockaddr *)&src_addr_storage; | |
| 1340 | + struct sockaddr *listen_addr = | |
| 1341 | + (struct sockaddr *)&req->listen_addr_storage; | |
| 1342 | + struct sockaddr *src_addr = (struct sockaddr *)&req->src_addr_storage; | |
| 1348 | 1343 | struct net_device *net_dev; |
| 1349 | 1344 | const union ib_gid *gid = req->has_gid ? &req->local_gid : NULL; |
| 1350 | 1345 | int err; |
| @@ -1359,11 +1354,6 @@ static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event, · 8 unmodified lines | ||
| 1359 | 1354 | if (!net_dev) |
| 1360 | 1355 | return ERR_PTR(-ENODEV); |
| 1361 | 1356 | |
| 1362 | − if (!validate_net_dev(net_dev, listen_addr, src_addr)) { | |
| 1363 | − dev_put(net_dev); | |
| 1364 | − return ERR_PTR(-EHOSTUNREACH); | |
| 1365 | − } | |
| 1366 | − | |
| 1367 | 1357 | return net_dev; |
| 1368 | 1358 | } |
| 1369 | 1359 | |
| @@ -1490,15 +1480,51 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id, · 120 unmodified lines | ||
| 1490 | 1480 | } |
| 1491 | 1481 | } |
| 1492 | 1482 | |
| 1483 | + /* | |
| 1484 | + * Net namespace might be getting deleted while route lookup, | |
| 1485 | + * cm_id lookup is in progress. Therefore, perform netdevice | |
| 1486 | + * validation, cm_id lookup under rcu lock. | |
| 1487 | + * RCU lock along with netdevice state check, synchronizes with | |
| 1488 | + * netdevice migrating to different net namespace and also avoids | |
| 1489 | + * case where net namespace doesn't get deleted while lookup is in | |
| 1490 | + * progress. | |
| 1491 | + * If the device state is not IFF_UP, its properties such as ifindex | |
| 1492 | + * and nd_net cannot be trusted to remain valid without rcu lock. | |
| 1493 | + * net/core/dev.c change_net_namespace() ensures to synchronize with | |
| 1494 | + * ongoing operations on net device after device is closed using | |
| 1495 | + * synchronize_net(). | |
| 1496 | + */ | |
| 1497 | + rcu_read_lock(); | |
| 1498 | + if (*net_dev) { | |
| 1499 | + /* | |
| 1500 | + * If netdevice is down, it is likely that it is administratively | |
| 1501 | + * down or it might be migrating to different namespace. | |
| 1502 | + * In that case avoid further processing, as the net namespace | |
| 1503 | + * or ifindex may change. | |
| 1504 | + */ | |
| 1505 | + if (((*net_dev)->flags & IFF_UP) == 0) { | |
| 1506 | + id_priv = ERR_PTR(-EHOSTUNREACH); | |
| 1507 | + goto err; | |
| 1508 | + } | |
| 1509 | + | |
| 1510 | + if (!validate_net_dev(*net_dev, | |
| 1511 | + (struct sockaddr *)&req.listen_addr_storage, | |
| 1512 | + (struct sockaddr *)&req.src_addr_storage)) { | |
| 1513 | + id_priv = ERR_PTR(-EHOSTUNREACH); | |
| 1514 | + goto err; | |
| 1515 | + } | |
| 1516 | + } | |
| 1517 | + | |
| 1493 | 1518 | bind_list = cma_ps_find(*net_dev ? dev_net(*net_dev) : &init_net, |
| 1494 | 1519 | rdma_ps_from_service_id(req.service_id), |
| 1495 | 1520 | cma_port_from_service_id(req.service_id)); |
| 1496 | 1521 | id_priv = cma_find_listener(bind_list, cm_id, ib_event, &req, *net_dev); |
| 1522 | +err: | |
| 1523 | + rcu_read_unlock(); | |
| 1497 | 1524 | if (IS_ERR(id_priv) && *net_dev) { |
| 1498 | 1525 | dev_put(*net_dev); |
| 1499 | 1526 | *net_dev = NULL; |
| 1500 | 1527 | } |
| 1501 | − | |
| 1502 | 1528 | return id_priv; |
| 1503 | 1529 | } |
| 1504 | 1530 | |
| @@ -114,7 +114,7 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, · 113 unmodified lines | ||
| 114 | 114 | struct sockaddr_storage *mapped_sockaddr, |
| 115 | 115 | u8 nl_client) |
| 116 | 116 | { |
| 117 | − struct hlist_head *hash_bucket_head; | |
| 117 | + struct hlist_head *hash_bucket_head = NULL; | |
| 118 | 118 | struct iwpm_mapping_info *map_info; |
| 119 | 119 | unsigned long flags; |
| 120 | 120 | int ret = -EINVAL; |
| @@ -142,6 +142,9 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, · 21 unmodified lines | ||
| 142 | 142 | } |
| 143 | 143 | } |
| 144 | 144 | spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags); |
| 145 | + | |
| 146 | + if (!hash_bucket_head) | |
| 147 | + kfree(map_info); | |
| 145 | 148 | return ret; |
| 146 | 149 | } |
| 147 | 150 | |
| @@ -59,7 +59,7 @@ module_param_named(recv_queue_size, mad_recvq_size, int, 0444); · 58 unmodified lines | ||
| 59 | 59 | MODULE_PARM_DESC(recv_queue_size, "Size of receive queue in number of work requests"); |
| 60 | 60 | |
| 61 | 61 | static struct list_head ib_mad_port_list; |
| 62 | −static u32 ib_mad_client_id = 0; | |
| 62 | +static atomic_t ib_mad_client_id = ATOMIC_INIT(0); | |
| 63 | 63 | |
| 64 | 64 | /* Port list lock */ |
| 65 | 65 | static DEFINE_SPINLOCK(ib_mad_port_list_lock); |
| @@ -377,7 +377,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, · 311 unmodified lines | ||
| 377 | 377 | } |
| 378 | 378 | |
| 379 | 379 | spin_lock_irqsave(&port_priv->reg_lock, flags); |
| 380 | − mad_agent_priv->agent.hi_tid = ++ib_mad_client_id; | |
| 380 | + mad_agent_priv->agent.hi_tid = atomic_inc_return(&ib_mad_client_id); | |
| 381 | 381 | |
| 382 | 382 | /* |
| 383 | 383 | * Make sure MAD registration (if supplied) |
| @@ -255,6 +255,7 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev, · 254 unmodified lines | ||
| 255 | 255 | struct net_device *rdma_ndev) |
| 256 | 256 | { |
| 257 | 257 | struct net_device *real_dev = rdma_vlan_dev_real_dev(event_ndev); |
| 258 | + unsigned long gid_type_mask; | |
| 258 | 259 | |
| 259 | 260 | if (!rdma_ndev) |
| 260 | 261 | return; |
| @@ -264,21 +265,22 @@ static void bond_delete_netdev_default_gids(struct ib_device *ib_dev, · 3 unmodified lines | ||
| 264 | 265 | |
| 265 | 266 | rcu_read_lock(); |
| 266 | 267 | |
| 267 | − if (rdma_is_upper_dev_rcu(rdma_ndev, event_ndev) && | |
| 268 | − is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) == | |
| 269 | − BONDING_SLAVE_STATE_INACTIVE) { | |
| 270 | − unsigned long gid_type_mask; | |
| 271 | − | |
| 268 | + if (((rdma_ndev != event_ndev && | |
| 269 | + !rdma_is_upper_dev_rcu(rdma_ndev, event_ndev)) || | |
| 270 | + is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) | |
| 271 | + == | |
| 272 | + BONDING_SLAVE_STATE_INACTIVE)) { | |
| 272 | 273 | rcu_read_unlock(); |
| 274 | + return; | |
| 275 | + } | |
| 273 | 276 | |
| 274 | − gid_type_mask = roce_gid_type_mask_support(ib_dev, port); | |
| 277 | + rcu_read_unlock(); | |
| 275 | 278 | |
| 276 | − ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev, | |
| 277 | − gid_type_mask, | |
| 278 | − IB_CACHE_GID_DEFAULT_MODE_DELETE); | |
| 279 | − } else { | |
| 280 | − rcu_read_unlock(); | |
| 281 | − } | |
| 279 | + gid_type_mask = roce_gid_type_mask_support(ib_dev, port); | |
| 280 | + | |
| 281 | + ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev, | |
| 282 | + gid_type_mask, | |
| 283 | + IB_CACHE_GID_DEFAULT_MODE_DELETE); | |
| 282 | 284 | } |
| 283 | 285 | |
| 284 | 286 | static void enum_netdev_ipv4_ips(struct ib_device *ib_dev, |
| @@ -159,6 +159,23 @@ static void ucma_put_ctx(struct ucma_context *ctx) · 158 unmodified lines | ||
| 159 | 159 | complete(&ctx->comp); |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | +/* | |
| 163 | + * Same as ucm_get_ctx but requires that ->cm_id->device is valid, eg that the | |
| 164 | + * CM_ID is bound. | |
| 165 | + */ | |
| 166 | +static struct ucma_context *ucma_get_ctx_dev(struct ucma_file *file, int id) | |
| 167 | +{ | |
| 168 | + struct ucma_context *ctx = ucma_get_ctx(file, id); | |
| 169 | + | |
| 170 | + if (IS_ERR(ctx)) | |
| 171 | + return ctx; | |
| 172 | + if (!ctx->cm_id->device) { | |
| 173 | + ucma_put_ctx(ctx); | |
| 174 | + return ERR_PTR(-EINVAL); | |
| 175 | + } | |
| 176 | + return ctx; | |
| 177 | +} | |
| 178 | + | |
| 162 | 179 | static void ucma_close_event_id(struct work_struct *work) |
| 163 | 180 | { |
| 164 | 181 | struct ucma_event *uevent_close = container_of(work, struct ucma_event, close_work); |
| @@ -683,7 +700,7 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, · 518 unmodified lines | ||
| 683 | 700 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 684 | 701 | return -EFAULT; |
| 685 | 702 | |
| 686 | − if (!rdma_addr_size_in6(&cmd.src_addr) || | |
| 703 | + if ((cmd.src_addr.sin6_family && !rdma_addr_size_in6(&cmd.src_addr)) || | |
| 687 | 704 | !rdma_addr_size_in6(&cmd.dst_addr)) |
| 688 | 705 | return -EINVAL; |
| 689 | 706 | |
| @@ -734,7 +751,7 @@ static ssize_t ucma_resolve_route(struct ucma_file *file, · 44 unmodified lines | ||
| 734 | 751 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 735 | 752 | return -EFAULT; |
| 736 | 753 | |
| 737 | − ctx = ucma_get_ctx(file, cmd.id); | |
| 754 | + ctx = ucma_get_ctx_dev(file, cmd.id); | |
| 738 | 755 | if (IS_ERR(ctx)) |
| 739 | 756 | return PTR_ERR(ctx); |
| 740 | 757 | |
| @@ -1050,7 +1067,7 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, · 309 unmodified lines | ||
| 1050 | 1067 | if (!cmd.conn_param.valid) |
| 1051 | 1068 | return -EINVAL; |
| 1052 | 1069 | |
| 1053 | − ctx = ucma_get_ctx(file, cmd.id); | |
| 1070 | + ctx = ucma_get_ctx_dev(file, cmd.id); | |
| 1054 | 1071 | if (IS_ERR(ctx)) |
| 1055 | 1072 | return PTR_ERR(ctx); |
| 1056 | 1073 | |
| @@ -1092,7 +1109,7 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, · 35 unmodified lines | ||
| 1092 | 1109 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1093 | 1110 | return -EFAULT; |
| 1094 | 1111 | |
| 1095 | − ctx = ucma_get_ctx(file, cmd.id); | |
| 1112 | + ctx = ucma_get_ctx_dev(file, cmd.id); | |
| 1096 | 1113 | if (IS_ERR(ctx)) |
| 1097 | 1114 | return PTR_ERR(ctx); |
| 1098 | 1115 | |
| @@ -1120,7 +1137,7 @@ static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf, · 21 unmodified lines | ||
| 1120 | 1137 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1121 | 1138 | return -EFAULT; |
| 1122 | 1139 | |
| 1123 | − ctx = ucma_get_ctx(file, cmd.id); | |
| 1140 | + ctx = ucma_get_ctx_dev(file, cmd.id); | |
| 1124 | 1141 | if (IS_ERR(ctx)) |
| 1125 | 1142 | return PTR_ERR(ctx); |
| 1126 | 1143 | |
| @@ -1139,7 +1156,7 @@ static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf, · 12 unmodified lines | ||
| 1139 | 1156 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1140 | 1157 | return -EFAULT; |
| 1141 | 1158 | |
| 1142 | − ctx = ucma_get_ctx(file, cmd.id); | |
| 1159 | + ctx = ucma_get_ctx_dev(file, cmd.id); | |
| 1143 | 1160 | if (IS_ERR(ctx)) |
| 1144 | 1161 | return PTR_ERR(ctx); |
| 1145 | 1162 | |
| @@ -1167,15 +1184,10 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, · 21 unmodified lines | ||
| 1167 | 1184 | if (cmd.qp_state > IB_QPS_ERR) |
| 1168 | 1185 | return -EINVAL; |
| 1169 | 1186 | |
| 1170 | − ctx = ucma_get_ctx(file, cmd.id); | |
| 1187 | + ctx = ucma_get_ctx_dev(file, cmd.id); | |
| 1171 | 1188 | if (IS_ERR(ctx)) |
| 1172 | 1189 | return PTR_ERR(ctx); |
| 1173 | 1190 | |
| 1174 | − if (!ctx->cm_id->device) { | |
| 1175 | − ret = -EINVAL; | |
| 1176 | − goto out; | |
| 1177 | − } | |
| 1178 | − | |
| 1179 | 1191 | resp.qp_attr_mask = 0; |
| 1180 | 1192 | memset(&qp_attr, 0, sizeof qp_attr); |
| 1181 | 1193 | qp_attr.qp_state = cmd.qp_state; |
| @@ -1316,13 +1328,13 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, · 134 unmodified lines | ||
| 1316 | 1328 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
| 1317 | 1329 | return -EFAULT; |
| 1318 | 1330 | |
| 1331 | + if (unlikely(cmd.optlen > KMALLOC_MAX_SIZE)) | |
| 1332 | + return -EINVAL; | |
| 1333 | + | |
| 1319 | 1334 | ctx = ucma_get_ctx(file, cmd.id); |
| 1320 | 1335 | if (IS_ERR(ctx)) |
| 1321 | 1336 | return PTR_ERR(ctx); |
| 1322 | 1337 | |
| 1323 | − if (unlikely(cmd.optlen > KMALLOC_MAX_SIZE)) | |
| 1324 | − return -EINVAL; | |
| 1325 | − | |
| 1326 | 1338 | optval = memdup_user(u64_to_user_ptr(cmd.optval), |
| 1327 | 1339 | cmd.optlen); |
| 1328 | 1340 | if (IS_ERR(optval)) { |
| @@ -1384,7 +1396,7 @@ static ssize_t ucma_process_join(struct ucma_file *file, · 55 unmodified lines | ||
| 1384 | 1396 | else |
| 1385 | 1397 | return -EINVAL; |
| 1386 | 1398 | |
| 1387 | − ctx = ucma_get_ctx(file, cmd->id); | |
| 1399 | + ctx = ucma_get_ctx_dev(file, cmd->id); | |
| 1388 | 1400 | if (IS_ERR(ctx)) |
| 1389 | 1401 | return PTR_ERR(ctx); |
| 1390 | 1402 | |
| @@ -691,6 +691,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, · 690 unmodified lines | ||
| 691 | 691 | |
| 692 | 692 | mr->device = pd->device; |
| 693 | 693 | mr->pd = pd; |
| 694 | + mr->dm = NULL; | |
| 694 | 695 | mr->uobject = uobj; |
| 695 | 696 | atomic_inc(&pd->usecnt); |
| 696 | 697 | mr->res.type = RDMA_RESTRACK_MR; |
| @@ -765,6 +766,11 @@ ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file, · 68 unmodified lines | ||
| 765 | 766 | |
| 766 | 767 | mr = uobj->object; |
| 767 | 768 | |
| 769 | + if (mr->dm) { | |
| 770 | + ret = -EINVAL; | |
| 771 | + goto put_uobjs; | |
| 772 | + } | |
| 773 | + | |
| 768 | 774 | if (cmd.flags & IB_MR_REREG_ACCESS) { |
| 769 | 775 | ret = ib_check_mr_access(cmd.access_flags); |
| 770 | 776 | if (ret) |
| @@ -234,6 +234,15 @@ static int uverbs_validate_kernel_mandatory(const struct uverbs_method_spec *met · 233 unmodified lines | ||
| 234 | 234 | return -EINVAL; |
| 235 | 235 | } |
| 236 | 236 | |
| 237 | + for (; i < method_spec->num_buckets; i++) { | |
| 238 | + struct uverbs_attr_spec_hash *attr_spec_bucket = | |
| 239 | + method_spec->attr_buckets[i]; | |
| 240 | + | |
| 241 | + if (!bitmap_empty(attr_spec_bucket->mandatory_attrs_bitmask, | |
| 242 | + attr_spec_bucket->num_attrs)) | |
| 243 | + return -EINVAL; | |
| 244 | + } | |
| 245 | + | |
| 237 | 246 | return 0; |
| 238 | 247 | } |
| 239 | 248 | |
| @@ -363,28 +363,28 @@ static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_MODIFY)(struct ib_device · 362 unmodified lines | ||
| 363 | 363 | |
| 364 | 364 | static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = { |
| 365 | 365 | [IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = { |
| 366 | − .ptr = { | |
| 366 | + { .ptr = { | |
| 367 | 367 | .type = UVERBS_ATTR_TYPE_PTR_IN, |
| 368 | 368 | UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm), |
| 369 | 369 | .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO, |
| 370 | − }, | |
| 370 | + } }, | |
| 371 | 371 | }, |
| 372 | 372 | }; |
| 373 | 373 | |
| 374 | 374 | static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = { |
| 375 | 375 | [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = { |
| 376 | − .ptr = { | |
| 376 | + { .ptr = { | |
| 377 | 377 | .type = UVERBS_ATTR_TYPE_PTR_IN, |
| 378 | 378 | /* No need to specify any data */ |
| 379 | 379 | .len = 0, |
| 380 | − } | |
| 380 | + } } | |
| 381 | 381 | }, |
| 382 | 382 | [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = { |
| 383 | − .ptr = { | |
| 383 | + { .ptr = { | |
| 384 | 384 | .type = UVERBS_ATTR_TYPE_PTR_IN, |
| 385 | 385 | UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size), |
| 386 | 386 | .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO, |
| 387 | − } | |
| 387 | + } } | |
| 388 | 388 | }, |
| 389 | 389 | }; |
| 390 | 390 | |
| @@ -1656,6 +1656,7 @@ struct ib_mr *ib_alloc_mr(struct ib_pd *pd, · 1655 unmodified lines | ||
| 1656 | 1656 | if (!IS_ERR(mr)) { |
| 1657 | 1657 | mr->device = pd->device; |
| 1658 | 1658 | mr->pd = pd; |
| 1659 | + mr->dm = NULL; | |
| 1659 | 1660 | mr->uobject = NULL; |
| 1660 | 1661 | atomic_inc(&pd->usecnt); |
| 1661 | 1662 | mr->need_inval = false; |
| @@ -315,7 +315,7 @@ static void advance_oldest_read(struct t4_wq *wq) · 314 unmodified lines | ||
| 315 | 315 | * Deal with out-of-order and/or completions that complete |
| 316 | 316 | * prior unsignalled WRs. |
| 317 | 317 | */ |
| 318 | −void c4iw_flush_hw_cq(struct c4iw_cq *chp) | |
| 318 | +void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp) | |
| 319 | 319 | { |
| 320 | 320 | struct t4_cqe *hw_cqe, *swcqe, read_cqe; |
| 321 | 321 | struct c4iw_qp *qhp; |
| @@ -339,6 +339,13 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp) · 17 unmodified lines | ||
| 339 | 339 | if (qhp == NULL) |
| 340 | 340 | goto next_cqe; |
| 341 | 341 | |
| 342 | + if (flush_qhp != qhp) { | |
| 343 | + spin_lock(&qhp->lock); | |
| 344 | + | |
| 345 | + if (qhp->wq.flushed == 1) | |
| 346 | + goto next_cqe; | |
| 347 | + } | |
| 348 | + | |
| 342 | 349 | if (CQE_OPCODE(hw_cqe) == FW_RI_TERMINATE) |
| 343 | 350 | goto next_cqe; |
| 344 | 351 | |
| @@ -390,6 +397,8 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp) · 45 unmodified lines | ||
| 390 | 397 | next_cqe: |
| 391 | 398 | t4_hwcq_consume(&chp->cq); |
| 392 | 399 | ret = t4_next_hw_cqe(&chp->cq, &hw_cqe); |
| 400 | + if (qhp && flush_qhp != qhp) | |
| 401 | + spin_unlock(&qhp->lock); | |
| 393 | 402 | } |
| 394 | 403 | } |
| 395 | 404 | |
| @@ -875,6 +875,11 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) · 874 unmodified lines | ||
| 875 | 875 | |
| 876 | 876 | rdev->status_page->db_off = 0; |
| 877 | 877 | |
| 878 | + init_completion(&rdev->rqt_compl); | |
| 879 | + init_completion(&rdev->pbl_compl); | |
| 880 | + kref_init(&rdev->rqt_kref); | |
| 881 | + kref_init(&rdev->pbl_kref); | |
| 882 | + | |
| 878 | 883 | return 0; |
| 879 | 884 | err_free_status_page_and_wr_log: |
| 880 | 885 | if (c4iw_wr_log && rdev->wr_log) |
| @@ -893,13 +898,15 @@ destroy_resource: · 12 unmodified lines | ||
| 893 | 898 | |
| 894 | 899 | static void c4iw_rdev_close(struct c4iw_rdev *rdev) |
| 895 | 900 | { |
| 896 | − destroy_workqueue(rdev->free_workq); | |
| 897 | 901 | kfree(rdev->wr_log); |
| 898 | 902 | c4iw_release_dev_ucontext(rdev, &rdev->uctx); |
| 899 | 903 | free_page((unsigned long)rdev->status_page); |
| 900 | 904 | c4iw_pblpool_destroy(rdev); |
| 901 | 905 | c4iw_rqtpool_destroy(rdev); |
| 906 | + wait_for_completion(&rdev->pbl_compl); | |
| 907 | + wait_for_completion(&rdev->rqt_compl); | |
| 902 | 908 | c4iw_ocqp_pool_destroy(rdev); |
| 909 | + destroy_workqueue(rdev->free_workq); | |
| 903 | 910 | c4iw_destroy_resource(&rdev->resource); |
| 904 | 911 | } |
| 905 | 912 | |
| @@ -185,6 +185,10 @@ struct c4iw_rdev { · 184 unmodified lines | ||
| 185 | 185 | struct wr_log_entry *wr_log; |
| 186 | 186 | int wr_log_size; |
| 187 | 187 | struct workqueue_struct *free_workq; |
| 188 | + struct completion rqt_compl; | |
| 189 | + struct completion pbl_compl; | |
| 190 | + struct kref rqt_kref; | |
| 191 | + struct kref pbl_kref; | |
| 188 | 192 | }; |
| 189 | 193 | |
| 190 | 194 | static inline int c4iw_fatal_error(struct c4iw_rdev *rdev) |
| @@ -1049,7 +1053,7 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size); · 858 unmodified lines | ||
| 1049 | 1053 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size); |
| 1050 | 1054 | u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size); |
| 1051 | 1055 | void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size); |
| 1052 | −void c4iw_flush_hw_cq(struct c4iw_cq *chp); | |
| 1056 | +void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp); | |
| 1053 | 1057 | void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count); |
| 1054 | 1058 | int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp); |
| 1055 | 1059 | int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count); |
| @@ -1343,12 +1343,12 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, · 1342 unmodified lines | ||
| 1343 | 1343 | qhp->wq.flushed = 1; |
| 1344 | 1344 | t4_set_wq_in_error(&qhp->wq); |
| 1345 | 1345 | |
| 1346 | − c4iw_flush_hw_cq(rchp); | |
| 1346 | + c4iw_flush_hw_cq(rchp, qhp); | |
| 1347 | 1347 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); |
| 1348 | 1348 | rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); |
| 1349 | 1349 | |
| 1350 | 1350 | if (schp != rchp) |
| 1351 | − c4iw_flush_hw_cq(schp); | |
| 1351 | + c4iw_flush_hw_cq(schp, qhp); | |
| 1352 | 1352 | sq_flushed = c4iw_flush_sq(qhp); |
| 1353 | 1353 | |
| 1354 | 1354 | spin_unlock(&qhp->lock); |
| @@ -260,12 +260,22 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size) · 259 unmodified lines | ||
| 260 | 260 | rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT); |
| 261 | 261 | if (rdev->stats.pbl.cur > rdev->stats.pbl.max) |
| 262 | 262 | rdev->stats.pbl.max = rdev->stats.pbl.cur; |
| 263 | + kref_get(&rdev->pbl_kref); | |
| 263 | 264 | } else |
| 264 | 265 | rdev->stats.pbl.fail++; |
| 265 | 266 | mutex_unlock(&rdev->stats.lock); |
| 266 | 267 | return (u32)addr; |
| 267 | 268 | } |
| 268 | 269 | |
| 270 | +static void destroy_pblpool(struct kref *kref) | |
| 271 | +{ | |
| 272 | + struct c4iw_rdev *rdev; | |
| 273 | + | |
| 274 | + rdev = container_of(kref, struct c4iw_rdev, pbl_kref); | |
| 275 | + gen_pool_destroy(rdev->pbl_pool); | |
| 276 | + complete(&rdev->pbl_compl); | |
| 277 | +} | |
| 278 | + | |
| 269 | 279 | void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) |
| 270 | 280 | { |
| 271 | 281 | pr_debug("addr 0x%x size %d\n", addr, size); |
| @@ -273,6 +283,7 @@ void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size) · 1 unmodified line | ||
| 273 | 283 | rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT); |
| 274 | 284 | mutex_unlock(&rdev->stats.lock); |
| 275 | 285 | gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size); |
| 286 | + kref_put(&rdev->pbl_kref, destroy_pblpool); | |
| 276 | 287 | } |
| 277 | 288 | |
| 278 | 289 | int c4iw_pblpool_create(struct c4iw_rdev *rdev) |
| @@ -310,7 +321,7 @@ int c4iw_pblpool_create(struct c4iw_rdev *rdev) · 31 unmodified lines | ||
| 310 | 321 | |
| 311 | 322 | void c4iw_pblpool_destroy(struct c4iw_rdev *rdev) |
| 312 | 323 | { |
| 313 | − gen_pool_destroy(rdev->pbl_pool); | |
| 324 | + kref_put(&rdev->pbl_kref, destroy_pblpool); | |
| 314 | 325 | } |
| 315 | 326 | |
| 316 | 327 | /* |
| @@ -331,12 +342,22 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size) · 14 unmodified lines | ||
| 331 | 342 | rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); |
| 332 | 343 | if (rdev->stats.rqt.cur > rdev->stats.rqt.max) |
| 333 | 344 | rdev->stats.rqt.max = rdev->stats.rqt.cur; |
| 345 | + kref_get(&rdev->rqt_kref); | |
| 334 | 346 | } else |
| 335 | 347 | rdev->stats.rqt.fail++; |
| 336 | 348 | mutex_unlock(&rdev->stats.lock); |
| 337 | 349 | return (u32)addr; |
| 338 | 350 | } |
| 339 | 351 | |
| 352 | +static void destroy_rqtpool(struct kref *kref) | |
| 353 | +{ | |
| 354 | + struct c4iw_rdev *rdev; | |
| 355 | + | |
| 356 | + rdev = container_of(kref, struct c4iw_rdev, rqt_kref); | |
| 357 | + gen_pool_destroy(rdev->rqt_pool); | |
| 358 | + complete(&rdev->rqt_compl); | |
| 359 | +} | |
| 360 | + | |
| 340 | 361 | void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) |
| 341 | 362 | { |
| 342 | 363 | pr_debug("addr 0x%x size %d\n", addr, size << 6); |
| @@ -344,6 +365,7 @@ void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size) · 1 unmodified line | ||
| 344 | 365 | rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT); |
| 345 | 366 | mutex_unlock(&rdev->stats.lock); |
| 346 | 367 | gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6); |
| 368 | + kref_put(&rdev->rqt_kref, destroy_rqtpool); | |
| 347 | 369 | } |
| 348 | 370 | |
| 349 | 371 | int c4iw_rqtpool_create(struct c4iw_rdev *rdev) |
| @@ -380,7 +402,7 @@ int c4iw_rqtpool_create(struct c4iw_rdev *rdev) · 30 unmodified lines | ||
| 380 | 402 | |
| 381 | 403 | void c4iw_rqtpool_destroy(struct c4iw_rdev *rdev) |
| 382 | 404 | { |
| 383 | − gen_pool_destroy(rdev->rqt_pool); | |
| 405 | + kref_put(&rdev->rqt_kref, destroy_rqtpool); | |
| 384 | 406 | } |
| 385 | 407 | |
| 386 | 408 | /* |
| @@ -412,7 +412,6 @@ static void hfi1_cleanup_sdma_notifier(struct hfi1_msix_entry *msix) · 411 unmodified lines | ||
| 412 | 412 | static int get_irq_affinity(struct hfi1_devdata *dd, |
| 413 | 413 | struct hfi1_msix_entry *msix) |
| 414 | 414 | { |
| 415 | − int ret; | |
| 416 | 415 | cpumask_var_t diff; |
| 417 | 416 | struct hfi1_affinity_node *entry; |
| 418 | 417 | struct cpu_mask_set *set = NULL; |
| @@ -424,10 +423,6 @@ static int get_irq_affinity(struct hfi1_devdata *dd, · 5 unmodified lines | ||
| 424 | 423 | extra[0] = '\0'; |
| 425 | 424 | cpumask_clear(&msix->mask); |
| 426 | 425 | |
| 427 | − ret = zalloc_cpumask_var(&diff, GFP_KERNEL); | |
| 428 | − if (!ret) | |
| 429 | − return -ENOMEM; | |
| 430 | − | |
| 431 | 426 | entry = node_affinity_lookup(dd->node); |
| 432 | 427 | |
| 433 | 428 | switch (msix->type) { |
| @@ -458,6 +453,9 @@ static int get_irq_affinity(struct hfi1_devdata *dd, · 24 unmodified lines | ||
| 458 | 453 | * finds its CPU here. |
| 459 | 454 | */ |
| 460 | 455 | if (cpu == -1 && set) { |
| 456 | + if (!zalloc_cpumask_var(&diff, GFP_KERNEL)) | |
| 457 | + return -ENOMEM; | |
| 458 | + | |
| 461 | 459 | if (cpumask_equal(&set->mask, &set->used)) { |
| 462 | 460 | /* |
| 463 | 461 | * We've used up all the CPUs, bump up the generation |
| @@ -469,6 +467,8 @@ static int get_irq_affinity(struct hfi1_devdata *dd, · 5 unmodified lines | ||
| 469 | 467 | cpumask_andnot(diff, &set->mask, &set->used); |
| 470 | 468 | cpu = cpumask_first(diff); |
| 471 | 469 | cpumask_set_cpu(cpu, &set->used); |
| 470 | + | |
| 471 | + free_cpumask_var(diff); | |
| 472 | 472 | } |
| 473 | 473 | |
| 474 | 474 | cpumask_set_cpu(cpu, &msix->mask); |
| @@ -482,7 +482,6 @@ static int get_irq_affinity(struct hfi1_devdata *dd, · 7 unmodified lines | ||
| 482 | 482 | hfi1_setup_sdma_notifier(msix); |
| 483 | 483 | } |
| 484 | 484 | |
| 485 | − free_cpumask_var(diff); | |
| 486 | 485 | return 0; |
| 487 | 486 | } |
| 488 | 487 | |
| @@ -433,31 +433,43 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt, · 432 unmodified lines | ||
| 433 | 433 | bool do_cnp) |
| 434 | 434 | { |
| 435 | 435 | struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); |
| 436 | + struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); | |
| 436 | 437 | struct ib_other_headers *ohdr = pkt->ohdr; |
| 437 | 438 | struct ib_grh *grh = pkt->grh; |
| 438 | 439 | u32 rqpn = 0, bth1; |
| 439 | − u16 pkey, rlid, dlid = ib_get_dlid(pkt->hdr); | |
| 440 | + u16 pkey; | |
| 441 | + u32 rlid, slid, dlid = 0; | |
| 440 | 442 | u8 hdr_type, sc, svc_type; |
| 441 | 443 | bool is_mcast = false; |
| 442 | 444 | |
| 445 | + /* can be called from prescan */ | |
| 443 | 446 | if (pkt->etype == RHF_RCV_TYPE_BYPASS) { |
| 444 | 447 | is_mcast = hfi1_is_16B_mcast(dlid); |
| 445 | 448 | pkey = hfi1_16B_get_pkey(pkt->hdr); |
| 446 | 449 | sc = hfi1_16B_get_sc(pkt->hdr); |
| 450 | + dlid = hfi1_16B_get_dlid(pkt->hdr); | |
| 451 | + slid = hfi1_16B_get_slid(pkt->hdr); | |
| 447 | 452 | hdr_type = HFI1_PKT_TYPE_16B; |
| 448 | 453 | } else { |
| 449 | 454 | is_mcast = (dlid > be16_to_cpu(IB_MULTICAST_LID_BASE)) && |
| 450 | 455 | (dlid != be16_to_cpu(IB_LID_PERMISSIVE)); |
| 451 | 456 | pkey = ib_bth_get_pkey(ohdr); |
| 452 | 457 | sc = hfi1_9B_get_sc5(pkt->hdr, pkt->rhf); |
| 458 | + dlid = ib_get_dlid(pkt->hdr); | |
| 459 | + slid = ib_get_slid(pkt->hdr); | |
| 453 | 460 | hdr_type = HFI1_PKT_TYPE_9B; |
| 454 | 461 | } |
| 455 | 462 | |
| 456 | 463 | switch (qp->ibqp.qp_type) { |
| 464 | + case IB_QPT_UD: | |
| 465 | + dlid = ppd->lid; | |
| 466 | + rlid = slid; | |
| 467 | + rqpn = ib_get_sqpn(pkt->ohdr); | |
| 468 | + svc_type = IB_CC_SVCTYPE_UD; | |
| 469 | + break; | |
| 457 | 470 | case IB_QPT_SMI: |
| 458 | 471 | case IB_QPT_GSI: |
| 459 | − case IB_QPT_UD: | |
| 460 | − rlid = ib_get_slid(pkt->hdr); | |
| 472 | + rlid = slid; | |
| 461 | 473 | rqpn = ib_get_sqpn(pkt->ohdr); |
| 462 | 474 | svc_type = IB_CC_SVCTYPE_UD; |
| 463 | 475 | break; |
| @@ -482,7 +494,6 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt, · 18 unmodified lines | ||
| 482 | 494 | dlid, rlid, sc, grh); |
| 483 | 495 | |
| 484 | 496 | if (!is_mcast && (bth1 & IB_BECN_SMASK)) { |
| 485 | − struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); | |
| 486 | 497 | u32 lqpn = bth1 & RVT_QPN_MASK; |
| 487 | 498 | u8 sl = ibp->sc_to_sl[sc]; |
| 488 | 499 | |
| @@ -1537,13 +1537,13 @@ void set_link_ipg(struct hfi1_pportdata *ppd); · 1536 unmodified lines | ||
| 1537 | 1537 | void process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn, |
| 1538 | 1538 | u32 rqpn, u8 svc_type); |
| 1539 | 1539 | void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, |
| 1540 | − u32 pkey, u32 slid, u32 dlid, u8 sc5, | |
| 1540 | + u16 pkey, u32 slid, u32 dlid, u8 sc5, | |
| 1541 | 1541 | const struct ib_grh *old_grh); |
| 1542 | 1542 | void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, |
| 1543 | − u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, | |
| 1543 | + u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, | |
| 1544 | 1544 | u8 sc5, const struct ib_grh *old_grh); |
| 1545 | 1545 | typedef void (*hfi1_handle_cnp)(struct hfi1_ibport *ibp, struct rvt_qp *qp, |
| 1546 | − u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, | |
| 1546 | + u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, | |
| 1547 | 1547 | u8 sc5, const struct ib_grh *old_grh); |
| 1548 | 1548 | |
| 1549 | 1549 | #define PKEY_CHECK_INVALID -1 |
| @@ -2437,7 +2437,7 @@ static inline void hfi1_make_16b_hdr(struct hfi1_16b_header *hdr, · 887 unmodified lines | ||
| 2437 | 2437 | ((slid >> OPA_16B_SLID_SHIFT) << OPA_16B_SLID_HIGH_SHIFT); |
| 2438 | 2438 | lrh2 = (lrh2 & ~OPA_16B_DLID_MASK) | |
| 2439 | 2439 | ((dlid >> OPA_16B_DLID_SHIFT) << OPA_16B_DLID_HIGH_SHIFT); |
| 2440 | − lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | (pkey << OPA_16B_PKEY_SHIFT); | |
| 2440 | + lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | ((u32)pkey << OPA_16B_PKEY_SHIFT); | |
| 2441 | 2441 | lrh2 = (lrh2 & ~OPA_16B_L4_MASK) | l4; |
| 2442 | 2442 | |
| 2443 | 2443 | hdr->lrh[0] = lrh0; |
| @@ -88,9 +88,9 @@ · 87 unmodified lines | ||
| 88 | 88 | * pio buffers per ctxt, etc.) Zero means use one user context per CPU. |
| 89 | 89 | */ |
| 90 | 90 | int num_user_contexts = -1; |
| 91 | −module_param_named(num_user_contexts, num_user_contexts, uint, S_IRUGO); | |
| 91 | +module_param_named(num_user_contexts, num_user_contexts, int, 0444); | |
| 92 | 92 | MODULE_PARM_DESC( |
| 93 | − num_user_contexts, "Set max number of user contexts to use"); | |
| 93 | + num_user_contexts, "Set max number of user contexts to use (default: -1 will use the real (non-HT) CPU count)"); | |
| 94 | 94 | |
| 95 | 95 | uint krcvqs[RXE_NUM_DATA_VL]; |
| 96 | 96 | int krcvqsset; |
| @@ -1209,30 +1209,49 @@ static void finalize_asic_data(struct hfi1_devdata *dd, · 1112 unmodified lines | ||
| 1209 | 1209 | kfree(ad); |
| 1210 | 1210 | } |
| 1211 | 1211 | |
| 1212 | −static void __hfi1_free_devdata(struct kobject *kobj) | |
| 1212 | +/** | |
| 1213 | + * hfi1_clean_devdata - cleans up per-unit data structure | |
| 1214 | + * @dd: pointer to a valid devdata structure | |
| 1215 | + * | |
| 1216 | + * It cleans up all data structures set up by | |
| 1217 | + * by hfi1_alloc_devdata(). | |
| 1218 | + */ | |
| 1219 | +static void hfi1_clean_devdata(struct hfi1_devdata *dd) | |
| 1213 | 1220 | { |
| 1214 | − struct hfi1_devdata *dd = | |
| 1215 | − container_of(kobj, struct hfi1_devdata, kobj); | |
| 1216 | 1221 | struct hfi1_asic_data *ad; |
| 1217 | 1222 | unsigned long flags; |
| 1218 | 1223 | |
| 1219 | 1224 | spin_lock_irqsave(&hfi1_devs_lock, flags); |
| 1220 | − idr_remove(&hfi1_unit_table, dd->unit); | |
| 1221 | − list_del(&dd->list); | |
| 1225 | + if (!list_empty(&dd->list)) { | |
| 1226 | + idr_remove(&hfi1_unit_table, dd->unit); | |
| 1227 | + list_del_init(&dd->list); | |
| 1228 | + } | |
| 1222 | 1229 | ad = release_asic_data(dd); |
| 1223 | 1230 | spin_unlock_irqrestore(&hfi1_devs_lock, flags); |
| 1224 | − if (ad) | |
| 1225 | − finalize_asic_data(dd, ad); | |
| 1231 | + | |
| 1232 | + finalize_asic_data(dd, ad); | |
| 1226 | 1233 | free_platform_config(dd); |
| 1227 | 1234 | rcu_barrier(); /* wait for rcu callbacks to complete */ |
| 1228 | 1235 | free_percpu(dd->int_counter); |
| 1229 | 1236 | free_percpu(dd->rcv_limit); |
| 1230 | 1237 | free_percpu(dd->send_schedule); |
| 1231 | 1238 | free_percpu(dd->tx_opstats); |
| 1239 | + dd->int_counter = NULL; | |
| 1240 | + dd->rcv_limit = NULL; | |
| 1241 | + dd->send_schedule = NULL; | |
| 1242 | + dd->tx_opstats = NULL; | |
| 1232 | 1243 | sdma_clean(dd, dd->num_sdma); |
| 1233 | 1244 | rvt_dealloc_device(&dd->verbs_dev.rdi); |
| 1234 | 1245 | } |
| 1235 | 1246 | |
| 1247 | +static void __hfi1_free_devdata(struct kobject *kobj) | |
| 1248 | +{ | |
| 1249 | + struct hfi1_devdata *dd = | |
| 1250 | + container_of(kobj, struct hfi1_devdata, kobj); | |
| 1251 | + | |
| 1252 | + hfi1_clean_devdata(dd); | |
| 1253 | +} | |
| 1254 | + | |
| 1236 | 1255 | static struct kobj_type hfi1_devdata_type = { |
| 1237 | 1256 | .release = __hfi1_free_devdata, |
| 1238 | 1257 | }; |
| @@ -1265,6 +1284,8 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) · 26 unmodified lines | ||
| 1265 | 1284 | return ERR_PTR(-ENOMEM); |
| 1266 | 1285 | dd->num_pports = nports; |
| 1267 | 1286 | dd->pport = (struct hfi1_pportdata *)(dd + 1); |
| 1287 | + dd->pcidev = pdev; | |
| 1288 | + pci_set_drvdata(pdev, dd); | |
| 1268 | 1289 | |
| 1269 | 1290 | INIT_LIST_HEAD(&dd->list); |
| 1270 | 1291 | idr_preload(GFP_KERNEL); |
| @@ -1331,9 +1352,7 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) · 60 unmodified lines | ||
| 1331 | 1352 | return dd; |
| 1332 | 1353 | |
| 1333 | 1354 | bail: |
| 1334 | − if (!list_empty(&dd->list)) | |
| 1335 | − list_del_init(&dd->list); | |
| 1336 | − rvt_dealloc_device(&dd->verbs_dev.rdi); | |
| 1355 | + hfi1_clean_devdata(dd); | |
| 1337 | 1356 | return ERR_PTR(ret); |
| 1338 | 1357 | } |
| 1339 | 1358 | |
| @@ -163,9 +163,6 @@ int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev) · 162 unmodified lines | ||
| 163 | 163 | resource_size_t addr; |
| 164 | 164 | int ret = 0; |
| 165 | 165 | |
| 166 | − dd->pcidev = pdev; | |
| 167 | − pci_set_drvdata(pdev, dd); | |
| 168 | − | |
| 169 | 166 | addr = pci_resource_start(pdev, 0); |
| 170 | 167 | len = pci_resource_len(pdev, 0); |
| 171 | 168 | |
| @@ -199,6 +199,7 @@ void free_platform_config(struct hfi1_devdata *dd) · 198 unmodified lines | ||
| 199 | 199 | { |
| 200 | 200 | /* Release memory allocated for eprom or fallback file read. */ |
| 201 | 201 | kfree(dd->platform_config.data); |
| 202 | + dd->platform_config.data = NULL; | |
| 202 | 203 | } |
| 203 | 204 | |
| 204 | 205 | void get_port_type(struct hfi1_pportdata *ppd) |
| @@ -204,6 +204,8 @@ static void clean_i2c_bus(struct hfi1_i2c_bus *bus) · 203 unmodified lines | ||
| 204 | 204 | |
| 205 | 205 | void clean_up_i2c(struct hfi1_devdata *dd, struct hfi1_asic_data *ad) |
| 206 | 206 | { |
| 207 | + if (!ad) | |
| 208 | + return; | |
| 207 | 209 | clean_i2c_bus(ad->i2c_bus0); |
| 208 | 210 | ad->i2c_bus0 = NULL; |
| 209 | 211 | clean_i2c_bus(ad->i2c_bus1); |
| @@ -733,6 +733,20 @@ static inline void hfi1_make_ruc_bth(struct rvt_qp *qp, · 732 unmodified lines | ||
| 733 | 733 | ohdr->bth[2] = cpu_to_be32(bth2); |
| 734 | 734 | } |
| 735 | 735 | |
| 736 | +/** | |
| 737 | + * hfi1_make_ruc_header_16B - build a 16B header | |
| 738 | + * @qp: the queue pair | |
| 739 | + * @ohdr: a pointer to the destination header memory | |
| 740 | + * @bth0: bth0 passed in from the RC/UC builder | |
| 741 | + * @bth2: bth2 passed in from the RC/UC builder | |
| 742 | + * @middle: non zero implies indicates ahg "could" be used | |
| 743 | + * @ps: the current packet state | |
| 744 | + * | |
| 745 | + * This routine may disarm ahg under these situations: | |
| 746 | + * - packet needs a GRH | |
| 747 | + * - BECN needed | |
| 748 | + * - migration state not IB_MIG_MIGRATED | |
| 749 | + */ | |
| 736 | 750 | static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, |
| 737 | 751 | struct ib_other_headers *ohdr, |
| 738 | 752 | u32 bth0, u32 bth2, int middle, |
| @@ -777,6 +791,12 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, · 38 unmodified lines | ||
| 777 | 791 | else |
| 778 | 792 | middle = 0; |
| 779 | 793 | |
| 794 | + if (qp->s_flags & RVT_S_ECN) { | |
| 795 | + qp->s_flags &= ~RVT_S_ECN; | |
| 796 | + /* we recently received a FECN, so return a BECN */ | |
| 797 | + becn = true; | |
| 798 | + middle = 0; | |
| 799 | + } | |
| 780 | 800 | if (middle) |
| 781 | 801 | build_ahg(qp, bth2); |
| 782 | 802 | else |
| @@ -784,11 +804,6 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, · 1 unmodified line | ||
| 784 | 804 | |
| 785 | 805 | bth0 |= pkey; |
| 786 | 806 | bth0 |= extra_bytes << 20; |
| 787 | − if (qp->s_flags & RVT_S_ECN) { | |
| 788 | − qp->s_flags &= ~RVT_S_ECN; | |
| 789 | − /* we recently received a FECN, so return a BECN */ | |
| 790 | − becn = true; | |
| 791 | − } | |
| 792 | 807 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); |
| 793 | 808 | |
| 794 | 809 | if (!ppd->lid) |
| @@ -806,6 +821,20 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, · 11 unmodified lines | ||
| 806 | 821 | pkey, becn, 0, l4, priv->s_sc); |
| 807 | 822 | } |
| 808 | 823 | |
| 824 | +/** | |
| 825 | + * hfi1_make_ruc_header_9B - build a 9B header | |
| 826 | + * @qp: the queue pair | |
| 827 | + * @ohdr: a pointer to the destination header memory | |
| 828 | + * @bth0: bth0 passed in from the RC/UC builder | |
| 829 | + * @bth2: bth2 passed in from the RC/UC builder | |
| 830 | + * @middle: non zero implies indicates ahg "could" be used | |
| 831 | + * @ps: the current packet state | |
| 832 | + * | |
| 833 | + * This routine may disarm ahg under these situations: | |
| 834 | + * - packet needs a GRH | |
| 835 | + * - BECN needed | |
| 836 | + * - migration state not IB_MIG_MIGRATED | |
| 837 | + */ | |
| 809 | 838 | static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, |
| 810 | 839 | struct ib_other_headers *ohdr, |
| 811 | 840 | u32 bth0, u32 bth2, int middle, |
| @@ -839,6 +868,12 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, · 27 unmodified lines | ||
| 839 | 868 | else |
| 840 | 869 | middle = 0; |
| 841 | 870 | |
| 871 | + if (qp->s_flags & RVT_S_ECN) { | |
| 872 | + qp->s_flags &= ~RVT_S_ECN; | |
| 873 | + /* we recently received a FECN, so return a BECN */ | |
| 874 | + bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); | |
| 875 | + middle = 0; | |
| 876 | + } | |
| 842 | 877 | if (middle) |
| 843 | 878 | build_ahg(qp, bth2); |
| 844 | 879 | else |
| @@ -846,11 +881,6 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, · 1 unmodified line | ||
| 846 | 881 | |
| 847 | 882 | bth0 |= pkey; |
| 848 | 883 | bth0 |= extra_bytes << 20; |
| 849 | − if (qp->s_flags & RVT_S_ECN) { | |
| 850 | − qp->s_flags &= ~RVT_S_ECN; | |
| 851 | − /* we recently received a FECN, so return a BECN */ | |
| 852 | − bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); | |
| 853 | − } | |
| 854 | 884 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); |
| 855 | 885 | hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh, |
| 856 | 886 | lrh0, |
| @@ -628,7 +628,7 @@ int hfi1_lookup_pkey_idx(struct hfi1_ibport *ibp, u16 pkey) · 627 unmodified lines | ||
| 628 | 628 | } |
| 629 | 629 | |
| 630 | 630 | void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, |
| 631 | − u32 remote_qpn, u32 pkey, u32 slid, u32 dlid, | |
| 631 | + u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, | |
| 632 | 632 | u8 sc5, const struct ib_grh *old_grh) |
| 633 | 633 | { |
| 634 | 634 | u64 pbc, pbc_flags = 0; |
| @@ -687,7 +687,7 @@ void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, · 52 unmodified lines | ||
| 687 | 687 | } |
| 688 | 688 | |
| 689 | 689 | void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, |
| 690 | − u32 pkey, u32 slid, u32 dlid, u8 sc5, | |
| 690 | + u16 pkey, u32 slid, u32 dlid, u8 sc5, | |
| 691 | 691 | const struct ib_grh *old_grh) |
| 692 | 692 | { |
| 693 | 693 | u64 pbc, pbc_flags = 0; |
| @@ -912,7 +912,7 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, · 911 unmodified lines | ||
| 912 | 912 | obj_per_chunk = buf_chunk_size / obj_size; |
| 913 | 913 | num_hem = (nobj + obj_per_chunk - 1) / obj_per_chunk; |
| 914 | 914 | bt_chunk_num = bt_chunk_size / 8; |
| 915 | − if (table->type >= HEM_TYPE_MTT) | |
| 915 | + if (type >= HEM_TYPE_MTT) | |
| 916 | 916 | num_bt_l0 = bt_chunk_num; |
| 917 | 917 | |
| 918 | 918 | table->hem = kcalloc(num_hem, sizeof(*table->hem), |
| @@ -920,7 +920,7 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, · 1 unmodified line | ||
| 920 | 920 | if (!table->hem) |
| 921 | 921 | goto err_kcalloc_hem_buf; |
| 922 | 922 | |
| 923 | − if (check_whether_bt_num_3(table->type, hop_num)) { | |
| 923 | + if (check_whether_bt_num_3(type, hop_num)) { | |
| 924 | 924 | unsigned long num_bt_l1; |
| 925 | 925 | |
| 926 | 926 | num_bt_l1 = (num_hem + bt_chunk_num - 1) / |
| @@ -939,8 +939,8 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, · 12 unmodified lines | ||
| 939 | 939 | goto err_kcalloc_l1_dma; |
| 940 | 940 | } |
| 941 | 941 | |
| 942 | − if (check_whether_bt_num_2(table->type, hop_num) || | |
| 943 | − check_whether_bt_num_3(table->type, hop_num)) { | |
| 942 | + if (check_whether_bt_num_2(type, hop_num) || | |
| 943 | + check_whether_bt_num_3(type, hop_num)) { | |
| 944 | 944 | table->bt_l0 = kcalloc(num_bt_l0, sizeof(*table->bt_l0), |
| 945 | 945 | GFP_KERNEL); |
| 946 | 946 | if (!table->bt_l0) |
| @@ -1039,14 +1039,14 @@ void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev, · 92 unmodified lines | ||
| 1039 | 1039 | void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev) |
| 1040 | 1040 | { |
| 1041 | 1041 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->cq_table.table); |
| 1042 | − hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.irrl_table); | |
| 1043 | 1042 | if (hr_dev->caps.trrl_entry_sz) |
| 1044 | 1043 | hns_roce_cleanup_hem_table(hr_dev, |
| 1045 | 1044 | &hr_dev->qp_table.trrl_table); |
| 1045 | + hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.irrl_table); | |
| 1046 | 1046 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.qp_table); |
| 1047 | 1047 | hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table); |
| 1048 | − hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table); | |
| 1049 | 1048 | if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE)) |
| 1050 | 1049 | hns_roce_cleanup_hem_table(hr_dev, |
| 1051 | 1050 | &hr_dev->mr_table.mtt_cqe_table); |
| 1051 | + hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table); | |
| 1052 | 1052 | } |
| @@ -71,6 +71,11 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, struct ib_send_wr *wr, · 70 unmodified lines | ||
| 71 | 71 | return -EINVAL; |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | + if (wr->opcode == IB_WR_RDMA_READ) { | |
| 75 | + dev_err(hr_dev->dev, "Not support inline data!\n"); | |
| 76 | + return -EINVAL; | |
| 77 | + } | |
| 78 | + | |
| 74 | 79 | for (i = 0; i < wr->num_sge; i++) { |
| 75 | 80 | memcpy(wqe, ((void *)wr->sg_list[i].addr), |
| 76 | 81 | wr->sg_list[i].length); |
| @@ -148,7 +153,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 71 unmodified lines | ||
| 148 | 153 | ibqp->qp_type != IB_QPT_GSI && |
| 149 | 154 | ibqp->qp_type != IB_QPT_UD)) { |
| 150 | 155 | dev_err(dev, "Not supported QP(0x%x)type!\n", ibqp->qp_type); |
| 151 | − *bad_wr = NULL; | |
| 156 | + *bad_wr = wr; | |
| 152 | 157 | return -EOPNOTSUPP; |
| 153 | 158 | } |
| 154 | 159 | |
| @@ -182,7 +187,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 27 unmodified lines | ||
| 182 | 187 | qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = |
| 183 | 188 | wr->wr_id; |
| 184 | 189 | |
| 185 | − owner_bit = ~(qp->sq.head >> ilog2(qp->sq.wqe_cnt)) & 0x1; | |
| 190 | + owner_bit = | |
| 191 | + ~(((qp->sq.head + nreq) >> ilog2(qp->sq.wqe_cnt)) & 0x1); | |
| 186 | 192 | |
| 187 | 193 | /* Corresponding to the QP type, wqe process separately */ |
| 188 | 194 | if (ibqp->qp_type == IB_QPT_GSI) { |
| @@ -456,6 +462,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 267 unmodified lines | ||
| 456 | 462 | } else { |
| 457 | 463 | dev_err(dev, "Illegal qp_type(0x%x)\n", ibqp->qp_type); |
| 458 | 464 | spin_unlock_irqrestore(&qp->sq.lock, flags); |
| 465 | + *bad_wr = wr; | |
| 459 | 466 | return -EOPNOTSUPP; |
| 460 | 467 | } |
| 461 | 468 | } |
| @@ -2592,10 +2599,12 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp, · 2130 unmodified lines | ||
| 2592 | 2599 | roce_set_field(qpc_mask->byte_4_sqpn_tst, V2_QPC_BYTE_4_SQPN_M, |
| 2593 | 2600 | V2_QPC_BYTE_4_SQPN_S, 0); |
| 2594 | 2601 | |
| 2595 | − roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | |
| 2596 | − V2_QPC_BYTE_56_DQPN_S, hr_qp->qpn); | |
| 2597 | − roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | |
| 2598 | − V2_QPC_BYTE_56_DQPN_S, 0); | |
| 2602 | + if (attr_mask & IB_QP_DEST_QPN) { | |
| 2603 | + roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | |
| 2604 | + V2_QPC_BYTE_56_DQPN_S, hr_qp->qpn); | |
| 2605 | + roce_set_field(qpc_mask->byte_56_dqpn_err, | |
| 2606 | + V2_QPC_BYTE_56_DQPN_M, V2_QPC_BYTE_56_DQPN_S, 0); | |
| 2607 | + } | |
| 2599 | 2608 | roce_set_field(context->byte_168_irrl_idx, |
| 2600 | 2609 | V2_QPC_BYTE_168_SQ_SHIFT_BAK_M, |
| 2601 | 2610 | V2_QPC_BYTE_168_SQ_SHIFT_BAK_S, |
| @@ -2650,8 +2659,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, · 48 unmodified lines | ||
| 2650 | 2659 | return -EINVAL; |
| 2651 | 2660 | } |
| 2652 | 2661 | |
| 2653 | − if ((attr_mask & IB_QP_ALT_PATH) || (attr_mask & IB_QP_ACCESS_FLAGS) || | |
| 2654 | − (attr_mask & IB_QP_PKEY_INDEX) || (attr_mask & IB_QP_QKEY)) { | |
| 2662 | + if (attr_mask & IB_QP_ALT_PATH) { | |
| 2655 | 2663 | dev_err(dev, "INIT2RTR attr_mask (0x%x) error\n", attr_mask); |
| 2656 | 2664 | return -EINVAL; |
| 2657 | 2665 | } |
| @@ -2800,10 +2808,12 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, · 142 unmodified lines | ||
| 2800 | 2808 | V2_QPC_BYTE_140_RR_MAX_S, 0); |
| 2801 | 2809 | } |
| 2802 | 2810 | |
| 2803 | − roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | |
| 2804 | − V2_QPC_BYTE_56_DQPN_S, attr->dest_qp_num); | |
| 2805 | − roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | |
| 2806 | − V2_QPC_BYTE_56_DQPN_S, 0); | |
| 2811 | + if (attr_mask & IB_QP_DEST_QPN) { | |
| 2812 | + roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_DQPN_M, | |
| 2813 | + V2_QPC_BYTE_56_DQPN_S, attr->dest_qp_num); | |
| 2814 | + roce_set_field(qpc_mask->byte_56_dqpn_err, | |
| 2815 | + V2_QPC_BYTE_56_DQPN_M, V2_QPC_BYTE_56_DQPN_S, 0); | |
| 2816 | + } | |
| 2807 | 2817 | |
| 2808 | 2818 | /* Configure GID index */ |
| 2809 | 2819 | port_num = rdma_ah_get_port_num(&attr->ah_attr); |
| @@ -2845,7 +2855,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, · 35 unmodified lines | ||
| 2845 | 2855 | if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_UD) |
| 2846 | 2856 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, |
| 2847 | 2857 | V2_QPC_BYTE_24_MTU_S, IB_MTU_4096); |
| 2848 | − else | |
| 2858 | + else if (attr_mask & IB_QP_PATH_MTU) | |
| 2849 | 2859 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, |
| 2850 | 2860 | V2_QPC_BYTE_24_MTU_S, attr->path_mtu); |
| 2851 | 2861 | |
| @@ -2922,11 +2932,9 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, · 70 unmodified lines | ||
| 2922 | 2932 | return -EINVAL; |
| 2923 | 2933 | } |
| 2924 | 2934 | |
| 2925 | − /* If exist optional param, return error */ | |
| 2926 | − if ((attr_mask & IB_QP_ALT_PATH) || (attr_mask & IB_QP_ACCESS_FLAGS) || | |
| 2927 | − (attr_mask & IB_QP_QKEY) || (attr_mask & IB_QP_PATH_MIG_STATE) || | |
| 2928 | − (attr_mask & IB_QP_CUR_STATE) || | |
| 2929 | − (attr_mask & IB_QP_MIN_RNR_TIMER)) { | |
| 2935 | + /* Not support alternate path and path migration */ | |
| 2936 | + if ((attr_mask & IB_QP_ALT_PATH) || | |
| 2937 | + (attr_mask & IB_QP_PATH_MIG_STATE)) { | |
| 2930 | 2938 | dev_err(dev, "RTR2RTS attr_mask (0x%x)error\n", attr_mask); |
| 2931 | 2939 | return -EINVAL; |
| 2932 | 2940 | } |
| @@ -3161,7 +3169,8 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp, · 228 unmodified lines | ||
| 3161 | 3169 | (cur_state == IB_QPS_RTR && new_state == IB_QPS_ERR) || |
| 3162 | 3170 | (cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) || |
| 3163 | 3171 | (cur_state == IB_QPS_SQD && new_state == IB_QPS_ERR) || |
| 3164 | − (cur_state == IB_QPS_SQE && new_state == IB_QPS_ERR)) { | |
| 3172 | + (cur_state == IB_QPS_SQE && new_state == IB_QPS_ERR) || | |
| 3173 | + (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR)) { | |
| 3165 | 3174 | /* Nothing */ |
| 3166 | 3175 | ; |
| 3167 | 3176 | } else { |
| @@ -4478,7 +4487,7 @@ static int hns_roce_v2_create_eq(struct hns_roce_dev *hr_dev, · 1310 unmodified lines | ||
| 4478 | 4487 | ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, eq->eqn, 0, |
| 4479 | 4488 | eq_cmd, HNS_ROCE_CMD_TIMEOUT_MSECS); |
| 4480 | 4489 | if (ret) { |
| 4481 | − dev_err(dev, "[mailbox cmd] creat eqc failed.\n"); | |
| 4490 | + dev_err(dev, "[mailbox cmd] create eqc failed.\n"); | |
| 4482 | 4491 | goto err_cmd_mbox; |
| 4483 | 4492 | } |
| 4484 | 4493 | |
| @@ -620,7 +620,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, · 619 unmodified lines | ||
| 620 | 620 | to_hr_ucontext(ib_pd->uobject->context), |
| 621 | 621 | ucmd.db_addr, &hr_qp->rdb); |
| 622 | 622 | if (ret) { |
| 623 | − dev_err(dev, "rp record doorbell map failed!\n"); | |
| 623 | + dev_err(dev, "rq record doorbell map failed!\n"); | |
| 624 | 624 | goto err_mtt; |
| 625 | 625 | } |
| 626 | 626 | } |
| @@ -346,7 +346,7 @@ int mlx4_ib_umem_calc_optimal_mtt_size(struct ib_umem *umem, u64 start_va, · 345 unmodified lines | ||
| 346 | 346 | /* Add to the first block the misalignment that it suffers from. */ |
| 347 | 347 | total_len += (first_block_start & ((1ULL << block_shift) - 1ULL)); |
| 348 | 348 | last_block_end = current_block_start + current_block_len; |
| 349 | − last_block_aligned_end = round_up(last_block_end, 1 << block_shift); | |
| 349 | + last_block_aligned_end = round_up(last_block_end, 1ULL << block_shift); | |
| 350 | 350 | total_len += (last_block_aligned_end - last_block_end); |
| 351 | 351 | |
| 352 | 352 | if (total_len & ((1ULL << block_shift) - 1ULL)) |
| @@ -673,7 +673,8 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, · 672 unmodified lines | ||
| 673 | 673 | MLX4_IB_RX_HASH_SRC_PORT_TCP | |
| 674 | 674 | MLX4_IB_RX_HASH_DST_PORT_TCP | |
| 675 | 675 | MLX4_IB_RX_HASH_SRC_PORT_UDP | |
| 676 | − MLX4_IB_RX_HASH_DST_PORT_UDP)) { | |
| 676 | + MLX4_IB_RX_HASH_DST_PORT_UDP | | |
| 677 | + MLX4_IB_RX_HASH_INNER)) { | |
| 677 | 678 | pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", |
| 678 | 679 | ucmd->rx_hash_fields_mask); |
| 679 | 680 | return (-EOPNOTSUPP); |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | config MLX5_INFINIBAND |
| 2 | 2 | tristate "Mellanox Connect-IB HCA support" |
| 3 | 3 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE |
| 4 | + depends on INFINIBAND_USER_ACCESS || INFINIBAND_USER_ACCESS=n | |
| 4 | 5 | ---help--- |
| 5 | 6 | This driver provides low-level InfiniBand support for |
| 6 | 7 | Mellanox Connect-IB PCI Express host channel adapters (HCAs). |
| @@ -52,7 +52,6 @@ · 51 unmodified lines | ||
| 52 | 52 | #include <linux/mlx5/port.h> |
| 53 | 53 | #include <linux/mlx5/vport.h> |
| 54 | 54 | #include <linux/mlx5/fs.h> |
| 55 | −#include <linux/mlx5/fs_helpers.h> | |
| 56 | 55 | #include <linux/list.h> |
| 57 | 56 | #include <rdma/ib_smi.h> |
| 58 | 57 | #include <rdma/ib_umem.h> |
| @@ -180,7 +179,7 @@ static int mlx5_netdev_event(struct notifier_block *this, · 121 unmodified lines | ||
| 180 | 179 | if (rep_ndev == ndev) |
| 181 | 180 | roce->netdev = (event == NETDEV_UNREGISTER) ? |
| 182 | 181 | NULL : ndev; |
| 183 | − } else if (ndev->dev.parent == &ibdev->mdev->pdev->dev) { | |
| 182 | + } else if (ndev->dev.parent == &mdev->pdev->dev) { | |
| 184 | 183 | roce->netdev = (event == NETDEV_UNREGISTER) ? |
| 185 | 184 | NULL : ndev; |
| 186 | 185 | } |
| @@ -4757,7 +4756,7 @@ mlx5_ib_get_vector_affinity(struct ib_device *ibdev, int comp_vector) · 4570 unmodified lines | ||
| 4757 | 4756 | { |
| 4758 | 4757 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
| 4759 | 4758 | |
| 4760 | − return mlx5_get_vector_affinity(dev->mdev, comp_vector); | |
| 4759 | + return mlx5_get_vector_affinity_hint(dev->mdev, comp_vector); | |
| 4761 | 4760 | } |
| 4762 | 4761 | |
| 4763 | 4762 | /* The mlx5_ib_multiport_mutex should be held when calling this function */ |
| @@ -5427,9 +5426,7 @@ static void mlx5_ib_stage_cong_debugfs_cleanup(struct mlx5_ib_dev *dev) · 663 unmodified lines | ||
| 5427 | 5426 | static int mlx5_ib_stage_uar_init(struct mlx5_ib_dev *dev) |
| 5428 | 5427 | { |
| 5429 | 5428 | dev->mdev->priv.uar = mlx5_get_uars_page(dev->mdev); |
| 5430 | − if (!dev->mdev->priv.uar) | |
| 5431 | − return -ENOMEM; | |
| 5432 | − return 0; | |
| 5429 | + return PTR_ERR_OR_ZERO(dev->mdev->priv.uar); | |
| 5433 | 5430 | } |
| 5434 | 5431 | |
| 5435 | 5432 | static void mlx5_ib_stage_uar_cleanup(struct mlx5_ib_dev *dev) |
| @@ -866,25 +866,28 @@ static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length, · 865 unmodified lines | ||
| 866 | 866 | int *order) |
| 867 | 867 | { |
| 868 | 868 | struct mlx5_ib_dev *dev = to_mdev(pd->device); |
| 869 | + struct ib_umem *u; | |
| 869 | 870 | int err; |
| 870 | 871 | |
| 871 | − *umem = ib_umem_get(pd->uobject->context, start, length, | |
| 872 | − access_flags, 0); | |
| 873 | − err = PTR_ERR_OR_ZERO(*umem); | |
| 872 | + *umem = NULL; | |
| 873 | + | |
| 874 | + u = ib_umem_get(pd->uobject->context, start, length, access_flags, 0); | |
| 875 | + err = PTR_ERR_OR_ZERO(u); | |
| 874 | 876 | if (err) { |
| 875 | − *umem = NULL; | |
| 876 | − mlx5_ib_err(dev, "umem get failed (%d)\n", err); | |
| 877 | + mlx5_ib_dbg(dev, "umem get failed (%d)\n", err); | |
| 877 | 878 | return err; |
| 878 | 879 | } |
| 879 | 880 | |
| 880 | − mlx5_ib_cont_pages(*umem, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages, | |
| 881 | + mlx5_ib_cont_pages(u, start, MLX5_MKEY_PAGE_SHIFT_MASK, npages, | |
| 881 | 882 | page_shift, ncont, order); |
| 882 | 883 | if (!*npages) { |
| 883 | 884 | mlx5_ib_warn(dev, "avoid zero region\n"); |
| 884 | − ib_umem_release(*umem); | |
| 885 | + ib_umem_release(u); | |
| 885 | 886 | return -EINVAL; |
| 886 | 887 | } |
| 887 | 888 | |
| 889 | + *umem = u; | |
| 890 | + | |
| 888 | 891 | mlx5_ib_dbg(dev, "npages %d, ncont %d, order %d, page_shift %d\n", |
| 889 | 892 | *npages, *ncont, *order, *page_shift); |
| 890 | 893 | |
| @@ -1458,13 +1461,12 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 567 unmodified lines | ||
| 1458 | 1461 | int access_flags = flags & IB_MR_REREG_ACCESS ? |
| 1459 | 1462 | new_access_flags : |
| 1460 | 1463 | mr->access_flags; |
| 1461 | − u64 addr = (flags & IB_MR_REREG_TRANS) ? virt_addr : mr->umem->address; | |
| 1462 | − u64 len = (flags & IB_MR_REREG_TRANS) ? length : mr->umem->length; | |
| 1463 | 1464 | int page_shift = 0; |
| 1464 | 1465 | int upd_flags = 0; |
| 1465 | 1466 | int npages = 0; |
| 1466 | 1467 | int ncont = 0; |
| 1467 | 1468 | int order = 0; |
| 1469 | + u64 addr, len; | |
| 1468 | 1470 | int err; |
| 1469 | 1471 | |
| 1470 | 1472 | mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx, access_flags 0x%x\n", |
| @@ -1472,6 +1474,17 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 1 unmodified line | ||
| 1472 | 1474 | |
| 1473 | 1475 | atomic_sub(mr->npages, &dev->mdev->priv.reg_pages); |
| 1474 | 1476 | |
| 1477 | + if (!mr->umem) | |
| 1478 | + return -EINVAL; | |
| 1479 | + | |
| 1480 | + if (flags & IB_MR_REREG_TRANS) { | |
| 1481 | + addr = virt_addr; | |
| 1482 | + len = length; | |
| 1483 | + } else { | |
| 1484 | + addr = mr->umem->address; | |
| 1485 | + len = mr->umem->length; | |
| 1486 | + } | |
| 1487 | + | |
| 1475 | 1488 | if (flags != IB_MR_REREG_PD) { |
| 1476 | 1489 | /* |
| 1477 | 1490 | * Replace umem. This needs to be done whether or not UMR is |
| @@ -1479,6 +1492,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 1 unmodified line | ||
| 1479 | 1492 | */ |
| 1480 | 1493 | flags |= IB_MR_REREG_TRANS; |
| 1481 | 1494 | ib_umem_release(mr->umem); |
| 1495 | + mr->umem = NULL; | |
| 1482 | 1496 | err = mr_umem_get(pd, addr, len, access_flags, &mr->umem, |
| 1483 | 1497 | &npages, &page_shift, &ncont, &order); |
| 1484 | 1498 | if (err) |
| @@ -259,7 +259,11 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap, · 258 unmodified lines | ||
| 259 | 259 | } else { |
| 260 | 260 | if (ucmd) { |
| 261 | 261 | qp->rq.wqe_cnt = ucmd->rq_wqe_count; |
| 262 | + if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift)) | |
| 263 | + return -EINVAL; | |
| 262 | 264 | qp->rq.wqe_shift = ucmd->rq_wqe_shift; |
| 265 | + if ((1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) < qp->wq_sig) | |
| 266 | + return -EINVAL; | |
| 263 | 267 | qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig; |
| 264 | 268 | qp->rq.max_post = qp->rq.wqe_cnt; |
| 265 | 269 | } else { |
| @@ -2451,18 +2455,18 @@ enum { · 2185 unmodified lines | ||
| 2451 | 2455 | |
| 2452 | 2456 | static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate) |
| 2453 | 2457 | { |
| 2454 | − if (rate == IB_RATE_PORT_CURRENT) { | |
| 2458 | + if (rate == IB_RATE_PORT_CURRENT) | |
| 2455 | 2459 | return 0; |
| 2456 | − } else if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) { | |
| 2460 | + | |
| 2461 | + if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) | |
| 2457 | 2462 | return -EINVAL; |
| 2458 | − } else { | |
| 2459 | − while (rate != IB_RATE_2_5_GBPS && | |
| 2460 | − !(1 << (rate + MLX5_STAT_RATE_OFFSET) & | |
| 2461 | − MLX5_CAP_GEN(dev->mdev, stat_rate_support))) | |
| 2462 | − --rate; | |
| 2463 | − } | |
| 2464 | 2463 | |
| 2465 | − return rate + MLX5_STAT_RATE_OFFSET; | |
| 2464 | + while (rate != IB_RATE_PORT_CURRENT && | |
| 2465 | + !(1 << (rate + MLX5_STAT_RATE_OFFSET) & | |
| 2466 | + MLX5_CAP_GEN(dev->mdev, stat_rate_support))) | |
| 2467 | + --rate; | |
| 2468 | + | |
| 2469 | + return rate ? rate + MLX5_STAT_RATE_OFFSET : rate; | |
| 2466 | 2470 | } |
| 2467 | 2471 | |
| 2468 | 2472 | static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev, |
| @@ -461,7 +461,7 @@ static bool nes_nic_send(struct sk_buff *skb, struct net_device *netdev) · 460 unmodified lines | ||
| 461 | 461 | /** |
| 462 | 462 | * nes_netdev_start_xmit |
| 463 | 463 | */ |
| 464 | −static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |
| 464 | +static netdev_tx_t nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |
| 465 | 465 | { |
| 466 | 466 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
| 467 | 467 | struct nes_device *nesdev = nesvnic->nesdev; |
| @@ -390,7 +390,7 @@ struct rxe_opcode_info rxe_opcode[RXE_NUM_OPCODE] = { · 389 unmodified lines | ||
| 390 | 390 | .name = "IB_OPCODE_RC_SEND_ONLY_INV", |
| 391 | 391 | .mask = RXE_IETH_MASK | RXE_PAYLOAD_MASK | RXE_REQ_MASK |
| 392 | 392 | | RXE_COMP_MASK | RXE_RWR_MASK | RXE_SEND_MASK |
| 393 | − | RXE_END_MASK, | |
| 393 | + | RXE_END_MASK | RXE_START_MASK, | |
| 394 | 394 | .length = RXE_BTH_BYTES + RXE_IETH_BYTES, |
| 395 | 395 | .offset = { |
| 396 | 396 | [RXE_BTH] = 0, |
| @@ -728,7 +728,6 @@ next_wqe: · 727 unmodified lines | ||
| 728 | 728 | rollback_state(wqe, qp, &rollback_wqe, rollback_psn); |
| 729 | 729 | |
| 730 | 730 | if (ret == -EAGAIN) { |
| 731 | − kfree_skb(skb); | |
| 732 | 731 | rxe_run_task(&qp->req.task, 1); |
| 733 | 732 | goto exit; |
| 734 | 733 | } |
| @@ -742,7 +742,6 @@ static enum resp_states read_reply(struct rxe_qp *qp, · 741 unmodified lines | ||
| 742 | 742 | err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); |
| 743 | 743 | if (err) { |
| 744 | 744 | pr_err("Failed sending RDMA reply.\n"); |
| 745 | − kfree_skb(skb); | |
| 746 | 745 | return RESPST_ERR_RNR; |
| 747 | 746 | } |
| 748 | 747 | |
| @@ -954,10 +953,8 @@ static int send_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, · 205 unmodified lines | ||
| 954 | 953 | } |
| 955 | 954 | |
| 956 | 955 | err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); |
| 957 | − if (err) { | |
| 956 | + if (err) | |
| 958 | 957 | pr_err_ratelimited("Failed sending ack\n"); |
| 959 | − kfree_skb(skb); | |
| 960 | − } | |
| 961 | 958 | |
| 962 | 959 | err1: |
| 963 | 960 | return err; |
| @@ -1141,7 +1138,6 @@ static enum resp_states duplicate_request(struct rxe_qp *qp, · 177 unmodified lines | ||
| 1141 | 1138 | if (rc) { |
| 1142 | 1139 | pr_err("Failed resending result. This flow is not handled - skb ignored\n"); |
| 1143 | 1140 | rxe_drop_ref(qp); |
| 1144 | − kfree_skb(skb_copy); | |
| 1145 | 1141 | rc = RESPST_CLEANUP; |
| 1146 | 1142 | goto out; |
| 1147 | 1143 | } |
| @@ -1094,7 +1094,7 @@ drop_and_unlock: · 1093 unmodified lines | ||
| 1094 | 1094 | spin_unlock_irqrestore(&priv->lock, flags); |
| 1095 | 1095 | } |
| 1096 | 1096 | |
| 1097 | −static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |
| 1097 | +static netdev_tx_t ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |
| 1098 | 1098 | { |
| 1099 | 1099 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
| 1100 | 1100 | struct rdma_netdev *rn = netdev_priv(dev); |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | config INFINIBAND_SRP |
| 2 | 2 | tristate "InfiniBand SCSI RDMA Protocol" |
| 3 | − depends on SCSI | |
| 3 | + depends on SCSI && INFINIBAND_ADDR_TRANS | |
| 4 | 4 | select SCSI_SRP_ATTRS |
| 5 | 5 | ---help--- |
| 6 | 6 | Support for the SCSI RDMA Protocol over InfiniBand. This |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | config INFINIBAND_SRPT |
| 2 | 2 | tristate "InfiniBand SCSI RDMA Protocol target support" |
| 3 | − depends on INFINIBAND && TARGET_CORE | |
| 3 | + depends on INFINIBAND && INFINIBAND_ADDR_TRANS && TARGET_CORE | |
| 4 | 4 | ---help--- |
| 5 | 5 | |
| 6 | 6 | Support for the SCSI RDMA Protocol (SRP) Target driver. The |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | enum evdev_clock_type { |
| 32 | 32 | EV_CLK_REAL = 0, |
| 33 | 33 | EV_CLK_MONO, |
| 34 | + EV_CLK_BOOT, | |
| 34 | 35 | EV_CLK_MAX |
| 35 | 36 | }; |
| 36 | 37 | |
| @@ -197,10 +198,12 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) · 160 unmodified lines | ||
| 197 | 198 | case CLOCK_REALTIME: |
| 198 | 199 | clk_type = EV_CLK_REAL; |
| 199 | 200 | break; |
| 200 | − case CLOCK_BOOTTIME: | |
| 201 | 201 | case CLOCK_MONOTONIC: |
| 202 | 202 | clk_type = EV_CLK_MONO; |
| 203 | 203 | break; |
| 204 | + case CLOCK_BOOTTIME: | |
| 205 | + clk_type = EV_CLK_BOOT; | |
| 206 | + break; | |
| 204 | 207 | default: |
| 205 | 208 | return -EINVAL; |
| 206 | 209 | } |
| @@ -311,6 +314,8 @@ static void evdev_events(struct input_handle *handle, · 104 unmodified lines | ||
| 311 | 314 | |
| 312 | 315 | ev_time[EV_CLK_MONO] = ktime_get(); |
| 313 | 316 | ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]); |
| 317 | + ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO], | |
| 318 | + TK_OFFS_BOOT); | |
| 314 | 319 | |
| 315 | 320 | rcu_read_lock(); |
| 316 | 321 | |
| @@ -88,6 +88,7 @@ static int input_leds_connect(struct input_handler *handler, · 87 unmodified lines | ||
| 88 | 88 | const struct input_device_id *id) |
| 89 | 89 | { |
| 90 | 90 | struct input_leds *leds; |
| 91 | + struct input_led *led; | |
| 91 | 92 | unsigned int num_leds; |
| 92 | 93 | unsigned int led_code; |
| 93 | 94 | int led_no; |
| @@ -119,14 +120,13 @@ static int input_leds_connect(struct input_handler *handler, · 25 unmodified lines | ||
| 119 | 120 | |
| 120 | 121 | led_no = 0; |
| 121 | 122 | for_each_set_bit(led_code, dev->ledbit, LED_CNT) { |
| 122 | − struct input_led *led = &leds->leds[led_no]; | |
| 123 | + if (!input_led_info[led_code].name) | |
| 124 | + continue; | |
| 123 | 125 | |
| 126 | + led = &leds->leds[led_no]; | |
| 124 | 127 | led->handle = &leds->handle; |
| 125 | 128 | led->code = led_code; |
| 126 | 129 | |
| 127 | − if (!input_led_info[led_code].name) | |
| 128 | − continue; | |
| 129 | − | |
| 130 | 130 | led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", |
| 131 | 131 | dev_name(&dev->dev), |
| 132 | 132 | input_led_info[led_code].name); |
| @@ -583,7 +583,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) · 582 unmodified lines | ||
| 583 | 583 | |
| 584 | 584 | x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f)); |
| 585 | 585 | y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f)); |
| 586 | − z = packet[4] & 0x7c; | |
| 586 | + z = packet[4] & 0x7f; | |
| 587 | 587 | |
| 588 | 588 | /* |
| 589 | 589 | * The x and y values tend to be quite large, and when used |
| @@ -147,8 +147,11 @@ static int rmi_spi_xfer(struct rmi_spi_xport *rmi_spi, · 146 unmodified lines | ||
| 147 | 147 | if (len > RMI_SPI_XFER_SIZE_LIMIT) |
| 148 | 148 | return -EINVAL; |
| 149 | 149 | |
| 150 | − if (rmi_spi->xfer_buf_size < len) | |
| 151 | − rmi_spi_manage_pools(rmi_spi, len); | |
| 150 | + if (rmi_spi->xfer_buf_size < len) { | |
| 151 | + ret = rmi_spi_manage_pools(rmi_spi, len); | |
| 152 | + if (ret < 0) | |
| 153 | + return ret; | |
| 154 | + } | |
| 152 | 155 | |
| 153 | 156 | if (addr == 0) |
| 154 | 157 | /* |
| @@ -362,7 +362,7 @@ config TOUCHSCREEN_HIDEEP · 361 unmodified lines | ||
| 362 | 362 | |
| 363 | 363 | If unsure, say N. |
| 364 | 364 | |
| 365 | − To compile this driver as a moudle, choose M here : the | |
| 365 | + To compile this driver as a module, choose M here : the | |
| 366 | 366 | module will be called hideep_ts. |
| 367 | 367 | |
| 368 | 368 | config TOUCHSCREEN_ILI210X |
| @@ -280,7 +280,8 @@ struct mxt_data { · 279 unmodified lines | ||
| 280 | 280 | struct input_dev *input_dev; |
| 281 | 281 | char phys[64]; /* device physical location */ |
| 282 | 282 | struct mxt_object *object_table; |
| 283 | − struct mxt_info info; | |
| 283 | + struct mxt_info *info; | |
| 284 | + void *raw_info_block; | |
| 284 | 285 | unsigned int irq; |
| 285 | 286 | unsigned int max_x; |
| 286 | 287 | unsigned int max_y; |
| @@ -460,12 +461,13 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry) · 173 unmodified lines | ||
| 460 | 461 | { |
| 461 | 462 | u8 appmode = data->client->addr; |
| 462 | 463 | u8 bootloader; |
| 464 | + u8 family_id = data->info ? data->info->family_id : 0; | |
| 463 | 465 | |
| 464 | 466 | switch (appmode) { |
| 465 | 467 | case 0x4a: |
| 466 | 468 | case 0x4b: |
| 467 | 469 | /* Chips after 1664S use different scheme */ |
| 468 | − if (retry || data->info.family_id >= 0xa2) { | |
| 470 | + if (retry || family_id >= 0xa2) { | |
| 469 | 471 | bootloader = appmode - 0x24; |
| 470 | 472 | break; |
| 471 | 473 | } |
| @@ -692,7 +694,7 @@ mxt_get_object(struct mxt_data *data, u8 type) · 220 unmodified lines | ||
| 692 | 694 | struct mxt_object *object; |
| 693 | 695 | int i; |
| 694 | 696 | |
| 695 | − for (i = 0; i < data->info.object_num; i++) { | |
| 697 | + for (i = 0; i < data->info->object_num; i++) { | |
| 696 | 698 | object = data->object_table + i; |
| 697 | 699 | if (object->type == type) |
| 698 | 700 | return object; |
| @@ -1462,12 +1464,12 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) · 763 unmodified lines | ||
| 1462 | 1464 | data_pos += offset; |
| 1463 | 1465 | } |
| 1464 | 1466 | |
| 1465 | − if (cfg_info.family_id != data->info.family_id) { | |
| 1467 | + if (cfg_info.family_id != data->info->family_id) { | |
| 1466 | 1468 | dev_err(dev, "Family ID mismatch!\n"); |
| 1467 | 1469 | return -EINVAL; |
| 1468 | 1470 | } |
| 1469 | 1471 | |
| 1470 | − if (cfg_info.variant_id != data->info.variant_id) { | |
| 1472 | + if (cfg_info.variant_id != data->info->variant_id) { | |
| 1471 | 1473 | dev_err(dev, "Variant ID mismatch!\n"); |
| 1472 | 1474 | return -EINVAL; |
| 1473 | 1475 | } |
| @@ -1512,7 +1514,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) · 38 unmodified lines | ||
| 1512 | 1514 | |
| 1513 | 1515 | /* Malloc memory to store configuration */ |
| 1514 | 1516 | cfg_start_ofs = MXT_OBJECT_START + |
| 1515 | − data->info.object_num * sizeof(struct mxt_object) + | |
| 1517 | + data->info->object_num * sizeof(struct mxt_object) + | |
| 1516 | 1518 | MXT_INFO_CHECKSUM_SIZE; |
| 1517 | 1519 | config_mem_size = data->mem_size - cfg_start_ofs; |
| 1518 | 1520 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); |
| @@ -1563,20 +1565,6 @@ release_mem: · 44 unmodified lines | ||
| 1563 | 1565 | return ret; |
| 1564 | 1566 | } |
| 1565 | 1567 | |
| 1566 | −static int mxt_get_info(struct mxt_data *data) | |
| 1567 | −{ | |
| 1568 | − struct i2c_client *client = data->client; | |
| 1569 | − struct mxt_info *info = &data->info; | |
| 1570 | − int error; | |
| 1571 | − | |
| 1572 | − /* Read 7-byte info block starting at address 0 */ | |
| 1573 | − error = __mxt_read_reg(client, 0, sizeof(*info), info); | |
| 1574 | − if (error) | |
| 1575 | − return error; | |
| 1576 | − | |
| 1577 | − return 0; | |
| 1578 | −} | |
| 1579 | − | |
| 1580 | 1568 | static void mxt_free_input_device(struct mxt_data *data) |
| 1581 | 1569 | { |
| 1582 | 1570 | if (data->input_dev) { |
| @@ -1591,9 +1579,10 @@ static void mxt_free_object_table(struct mxt_data *data) · 8 unmodified lines | ||
| 1591 | 1579 | video_unregister_device(&data->dbg.vdev); |
| 1592 | 1580 | v4l2_device_unregister(&data->dbg.v4l2); |
| 1593 | 1581 | #endif |
| 1594 | − | |
| 1595 | − kfree(data->object_table); | |
| 1596 | 1582 | data->object_table = NULL; |
| 1583 | + data->info = NULL; | |
| 1584 | + kfree(data->raw_info_block); | |
| 1585 | + data->raw_info_block = NULL; | |
| 1597 | 1586 | kfree(data->msg_buf); |
| 1598 | 1587 | data->msg_buf = NULL; |
| 1599 | 1588 | data->T5_address = 0; |
| @@ -1609,34 +1598,18 @@ static void mxt_free_object_table(struct mxt_data *data) · 9 unmodified lines | ||
| 1609 | 1598 | data->max_reportid = 0; |
| 1610 | 1599 | } |
| 1611 | 1600 | |
| 1612 | −static int mxt_get_object_table(struct mxt_data *data) | |
| 1601 | +static int mxt_parse_object_table(struct mxt_data *data, | |
| 1602 | + struct mxt_object *object_table) | |
| 1613 | 1603 | { |
| 1614 | 1604 | struct i2c_client *client = data->client; |
| 1615 | − size_t table_size; | |
| 1616 | − struct mxt_object *object_table; | |
| 1617 | − int error; | |
| 1618 | 1605 | int i; |
| 1619 | 1606 | u8 reportid; |
| 1620 | 1607 | u16 end_address; |
| 1621 | 1608 | |
| 1622 | − table_size = data->info.object_num * sizeof(struct mxt_object); | |
| 1623 | − object_table = kzalloc(table_size, GFP_KERNEL); | |
| 1624 | − if (!object_table) { | |
| 1625 | − dev_err(&data->client->dev, "Failed to allocate memory\n"); | |
| 1626 | − return -ENOMEM; | |
| 1627 | − } | |
| 1628 | − | |
| 1629 | − error = __mxt_read_reg(client, MXT_OBJECT_START, table_size, | |
| 1630 | − object_table); | |
| 1631 | − if (error) { | |
| 1632 | − kfree(object_table); | |
| 1633 | − return error; | |
| 1634 | − } | |
| 1635 | − | |
| 1636 | 1609 | /* Valid Report IDs start counting from 1 */ |
| 1637 | 1610 | reportid = 1; |
| 1638 | 1611 | data->mem_size = 0; |
| 1639 | − for (i = 0; i < data->info.object_num; i++) { | |
| 1612 | + for (i = 0; i < data->info->object_num; i++) { | |
| 1640 | 1613 | struct mxt_object *object = object_table + i; |
| 1641 | 1614 | u8 min_id, max_id; |
| 1642 | 1615 | |
| @@ -1660,8 +1633,8 @@ static int mxt_get_object_table(struct mxt_data *data) · 17 unmodified lines | ||
| 1660 | 1633 | |
| 1661 | 1634 | switch (object->type) { |
| 1662 | 1635 | case MXT_GEN_MESSAGE_T5: |
| 1663 | − if (data->info.family_id == 0x80 && | |
| 1664 | − data->info.version < 0x20) { | |
| 1636 | + if (data->info->family_id == 0x80 && | |
| 1637 | + data->info->version < 0x20) { | |
| 1665 | 1638 | /* |
| 1666 | 1639 | * On mXT224 firmware versions prior to V2.0 |
| 1667 | 1640 | * read and discard unused CRC byte otherwise |
| @@ -1716,24 +1689,102 @@ static int mxt_get_object_table(struct mxt_data *data) · 48 unmodified lines | ||
| 1716 | 1689 | /* If T44 exists, T5 position has to be directly after */ |
| 1717 | 1690 | if (data->T44_address && (data->T5_address != data->T44_address + 1)) { |
| 1718 | 1691 | dev_err(&client->dev, "Invalid T44 position\n"); |
| 1719 | − error = -EINVAL; | |
| 1720 | − goto free_object_table; | |
| 1692 | + return -EINVAL; | |
| 1721 | 1693 | } |
| 1722 | 1694 | |
| 1723 | 1695 | data->msg_buf = kcalloc(data->max_reportid, |
| 1724 | 1696 | data->T5_msg_size, GFP_KERNEL); |
| 1725 | − if (!data->msg_buf) { | |
| 1726 | − dev_err(&client->dev, "Failed to allocate message buffer\n"); | |
| 1697 | + if (!data->msg_buf) | |
| 1698 | + return -ENOMEM; | |
| 1699 | + | |
| 1700 | + return 0; | |
| 1701 | +} | |
| 1702 | + | |
| 1703 | +static int mxt_read_info_block(struct mxt_data *data) | |
| 1704 | +{ | |
| 1705 | + struct i2c_client *client = data->client; | |
| 1706 | + int error; | |
| 1707 | + size_t size; | |
| 1708 | + void *id_buf, *buf; | |
| 1709 | + uint8_t num_objects; | |
| 1710 | + u32 calculated_crc; | |
| 1711 | + u8 *crc_ptr; | |
| 1712 | + | |
| 1713 | + /* If info block already allocated, free it */ | |
| 1714 | + if (data->raw_info_block) | |
| 1715 | + mxt_free_object_table(data); | |
| 1716 | + | |
| 1717 | + /* Read 7-byte ID information block starting at address 0 */ | |
| 1718 | + size = sizeof(struct mxt_info); | |
| 1719 | + id_buf = kzalloc(size, GFP_KERNEL); | |
| 1720 | + if (!id_buf) | |
| 1721 | + return -ENOMEM; | |
| 1722 | + | |
| 1723 | + error = __mxt_read_reg(client, 0, size, id_buf); | |
| 1724 | + if (error) | |
| 1725 | + goto err_free_mem; | |
| 1726 | + | |
| 1727 | + /* Resize buffer to give space for rest of info block */ | |
| 1728 | + num_objects = ((struct mxt_info *)id_buf)->object_num; | |
| 1729 | + size += (num_objects * sizeof(struct mxt_object)) | |
| 1730 | + + MXT_INFO_CHECKSUM_SIZE; | |
| 1731 | + | |
| 1732 | + buf = krealloc(id_buf, size, GFP_KERNEL); | |
| 1733 | + if (!buf) { | |
| 1727 | 1734 | error = -ENOMEM; |
| 1728 | − goto free_object_table; | |
| 1735 | + goto err_free_mem; | |
| 1736 | + } | |
| 1737 | + id_buf = buf; | |
| 1738 | + | |
| 1739 | + /* Read rest of info block */ | |
| 1740 | + error = __mxt_read_reg(client, MXT_OBJECT_START, | |
| 1741 | + size - MXT_OBJECT_START, | |
| 1742 | + id_buf + MXT_OBJECT_START); | |
| 1743 | + if (error) | |
| 1744 | + goto err_free_mem; | |
| 1745 | + | |
| 1746 | + /* Extract & calculate checksum */ | |
| 1747 | + crc_ptr = id_buf + size - MXT_INFO_CHECKSUM_SIZE; | |
| 1748 | + data->info_crc = crc_ptr[0] | (crc_ptr[1] << 8) | (crc_ptr[2] << 16); | |
| 1749 | + | |
| 1750 | + calculated_crc = mxt_calculate_crc(id_buf, 0, | |
| 1751 | + size - MXT_INFO_CHECKSUM_SIZE); | |
| 1752 | + | |
| 1753 | + /* | |
| 1754 | + * CRC mismatch can be caused by data corruption due to I2C comms | |
| 1755 | + * issue or else device is not using Object Based Protocol (eg i2c-hid) | |
| 1756 | + */ | |
| 1757 | + if ((data->info_crc == 0) || (data->info_crc != calculated_crc)) { | |
| 1758 | + dev_err(&client->dev, | |
| 1759 | + "Info Block CRC error calculated=0x%06X read=0x%06X\n", | |
| 1760 | + calculated_crc, data->info_crc); | |
| 1761 | + error = -EIO; | |
| 1762 | + goto err_free_mem; | |
| 1763 | + } | |
| 1764 | + | |
| 1765 | + data->raw_info_block = id_buf; | |
| 1766 | + data->info = (struct mxt_info *)id_buf; | |
| 1767 | + | |
| 1768 | + dev_info(&client->dev, | |
| 1769 | + "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | |
| 1770 | + data->info->family_id, data->info->variant_id, | |
| 1771 | + data->info->version >> 4, data->info->version & 0xf, | |
| 1772 | + data->info->build, data->info->object_num); | |
| 1773 | + | |
| 1774 | + /* Parse object table information */ | |
| 1775 | + error = mxt_parse_object_table(data, id_buf + MXT_OBJECT_START); | |
| 1776 | + if (error) { | |
| 1777 | + dev_err(&client->dev, "Error %d parsing object table\n", error); | |
| 1778 | + mxt_free_object_table(data); | |
| 1779 | + goto err_free_mem; | |
| 1729 | 1780 | } |
| 1730 | 1781 | |
| 1731 | − data->object_table = object_table; | |
| 1782 | + data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START); | |
| 1732 | 1783 | |
| 1733 | 1784 | return 0; |
| 1734 | 1785 | |
| 1735 | −free_object_table: | |
| 1736 | − mxt_free_object_table(data); | |
| 1786 | +err_free_mem: | |
| 1787 | + kfree(id_buf); | |
| 1737 | 1788 | return error; |
| 1738 | 1789 | } |
| 1739 | 1790 | |
| @@ -2046,7 +2097,7 @@ static int mxt_initialize(struct mxt_data *data) · 306 unmodified lines | ||
| 2046 | 2097 | int error; |
| 2047 | 2098 | |
| 2048 | 2099 | while (1) { |
| 2049 | − error = mxt_get_info(data); | |
| 2100 | + error = mxt_read_info_block(data); | |
| 2050 | 2101 | if (!error) |
| 2051 | 2102 | break; |
| 2052 | 2103 | |
| @@ -2077,16 +2128,9 @@ static int mxt_initialize(struct mxt_data *data) · 24 unmodified lines | ||
| 2077 | 2128 | msleep(MXT_FW_RESET_TIME); |
| 2078 | 2129 | } |
| 2079 | 2130 | |
| 2080 | − /* Get object table information */ | |
| 2081 | − error = mxt_get_object_table(data); | |
| 2082 | − if (error) { | |
| 2083 | − dev_err(&client->dev, "Error %d reading object table\n", error); | |
| 2084 | − return error; | |
| 2085 | − } | |
| 2086 | − | |
| 2087 | 2131 | error = mxt_acquire_irq(data); |
| 2088 | 2132 | if (error) |
| 2089 | − goto err_free_object_table; | |
| 2133 | + return error; | |
| 2090 | 2134 | |
| 2091 | 2135 | error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, |
| 2092 | 2136 | &client->dev, GFP_KERNEL, data, |
| @@ -2094,14 +2138,10 @@ static int mxt_initialize(struct mxt_data *data) · 1 unmodified line | ||
| 2094 | 2138 | if (error) { |
| 2095 | 2139 | dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", |
| 2096 | 2140 | error); |
| 2097 | − goto err_free_object_table; | |
| 2141 | + return error; | |
| 2098 | 2142 | } |
| 2099 | 2143 | |
| 2100 | 2144 | return 0; |
| 2101 | − | |
| 2102 | −err_free_object_table: | |
| 2103 | − mxt_free_object_table(data); | |
| 2104 | − return error; | |
| 2105 | 2145 | } |
| 2106 | 2146 | |
| 2107 | 2147 | static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) |
| @@ -2162,7 +2202,7 @@ recheck: · 54 unmodified lines | ||
| 2162 | 2202 | static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x, |
| 2163 | 2203 | unsigned int y) |
| 2164 | 2204 | { |
| 2165 | − struct mxt_info *info = &data->info; | |
| 2205 | + struct mxt_info *info = data->info; | |
| 2166 | 2206 | struct mxt_dbg *dbg = &data->dbg; |
| 2167 | 2207 | unsigned int ofs, page; |
| 2168 | 2208 | unsigned int col = 0; |
| @@ -2490,7 +2530,7 @@ static const struct video_device mxt_video_device = { · 321 unmodified lines | ||
| 2490 | 2530 | |
| 2491 | 2531 | static void mxt_debug_init(struct mxt_data *data) |
| 2492 | 2532 | { |
| 2493 | − struct mxt_info *info = &data->info; | |
| 2533 | + struct mxt_info *info = data->info; | |
| 2494 | 2534 | struct mxt_dbg *dbg = &data->dbg; |
| 2495 | 2535 | struct mxt_object *object; |
| 2496 | 2536 | int error; |
| @@ -2576,7 +2616,6 @@ static int mxt_configure_objects(struct mxt_data *data, · 79 unmodified lines | ||
| 2576 | 2616 | const struct firmware *cfg) |
| 2577 | 2617 | { |
| 2578 | 2618 | struct device *dev = &data->client->dev; |
| 2579 | − struct mxt_info *info = &data->info; | |
| 2580 | 2619 | int error; |
| 2581 | 2620 | |
| 2582 | 2621 | error = mxt_init_t7_power_cfg(data); |
| @@ -2601,11 +2640,6 @@ static int mxt_configure_objects(struct mxt_data *data, · 18 unmodified lines | ||
| 2601 | 2640 | |
| 2602 | 2641 | mxt_debug_init(data); |
| 2603 | 2642 | |
| 2604 | − dev_info(dev, | |
| 2605 | − "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | |
| 2606 | − info->family_id, info->variant_id, info->version >> 4, | |
| 2607 | − info->version & 0xf, info->build, info->object_num); | |
| 2608 | − | |
| 2609 | 2643 | return 0; |
| 2610 | 2644 | } |
| 2611 | 2645 | |
| @@ -2614,7 +2648,7 @@ static ssize_t mxt_fw_version_show(struct device *dev, · 2 unmodified lines | ||
| 2614 | 2648 | struct device_attribute *attr, char *buf) |
| 2615 | 2649 | { |
| 2616 | 2650 | struct mxt_data *data = dev_get_drvdata(dev); |
| 2617 | − struct mxt_info *info = &data->info; | |
| 2651 | + struct mxt_info *info = data->info; | |
| 2618 | 2652 | return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n", |
| 2619 | 2653 | info->version >> 4, info->version & 0xf, info->build); |
| 2620 | 2654 | } |
| @@ -2624,7 +2658,7 @@ static ssize_t mxt_hw_version_show(struct device *dev, · 3 unmodified lines | ||
| 2624 | 2658 | struct device_attribute *attr, char *buf) |
| 2625 | 2659 | { |
| 2626 | 2660 | struct mxt_data *data = dev_get_drvdata(dev); |
| 2627 | − struct mxt_info *info = &data->info; | |
| 2661 | + struct mxt_info *info = data->info; | |
| 2628 | 2662 | return scnprintf(buf, PAGE_SIZE, "%u.%u\n", |
| 2629 | 2663 | info->family_id, info->variant_id); |
| 2630 | 2664 | } |
| @@ -2663,7 +2697,7 @@ static ssize_t mxt_object_show(struct device *dev, · 32 unmodified lines | ||
| 2663 | 2697 | return -ENOMEM; |
| 2664 | 2698 | |
| 2665 | 2699 | error = 0; |
| 2666 | − for (i = 0; i < data->info.object_num; i++) { | |
| 2700 | + for (i = 0; i < data->info->object_num; i++) { | |
| 2667 | 2701 | object = data->object_table + i; |
| 2668 | 2702 | |
| 2669 | 2703 | if (!mxt_object_readable(object->type)) |
| @@ -3034,6 +3068,15 @@ static const struct dmi_system_id mxt_dmi_table[] = { · 364 unmodified lines | ||
| 3034 | 3068 | }, |
| 3035 | 3069 | .driver_data = samus_platform_data, |
| 3036 | 3070 | }, |
| 3071 | + { | |
| 3072 | + /* Samsung Chromebook Pro */ | |
| 3073 | + .ident = "Samsung Chromebook Pro", | |
| 3074 | + .matches = { | |
| 3075 | + DMI_MATCH(DMI_SYS_VENDOR, "Google"), | |
| 3076 | + DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"), | |
| 3077 | + }, | |
| 3078 | + .driver_data = samus_platform_data, | |
| 3079 | + }, | |
| 3037 | 3080 | { |
| 3038 | 3081 | /* Other Google Chromebooks */ |
| 3039 | 3082 | .ident = "Chromebook", |
| @@ -3254,6 +3297,11 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); · 214 unmodified lines | ||
| 3254 | 3297 | |
| 3255 | 3298 | static const struct of_device_id mxt_of_match[] = { |
| 3256 | 3299 | { .compatible = "atmel,maxtouch", }, |
| 3300 | + /* Compatibles listed below are deprecated */ | |
| 3301 | + { .compatible = "atmel,qt602240_ts", }, | |
| 3302 | + { .compatible = "atmel,atmel_mxt_ts", }, | |
| 3303 | + { .compatible = "atmel,atmel_mxt_tp", }, | |
| 3304 | + { .compatible = "atmel,mXT224", }, | |
| 3257 | 3305 | {}, |
| 3258 | 3306 | }; |
| 3259 | 3307 | MODULE_DEVICE_TABLE(of, mxt_of_match); |
| @@ -83,7 +83,6 @@ · 82 unmodified lines | ||
| 83 | 83 | |
| 84 | 84 | static DEFINE_SPINLOCK(amd_iommu_devtable_lock); |
| 85 | 85 | static DEFINE_SPINLOCK(pd_bitmap_lock); |
| 86 | −static DEFINE_SPINLOCK(iommu_table_lock); | |
| 87 | 86 | |
| 88 | 87 | /* List of all available dev_data structures */ |
| 89 | 88 | static LLIST_HEAD(dev_data_list); |
| @@ -3562,6 +3561,7 @@ EXPORT_SYMBOL(amd_iommu_device_info); · 3472 unmodified lines | ||
| 3562 | 3561 | *****************************************************************************/ |
| 3563 | 3562 | |
| 3564 | 3563 | static struct irq_chip amd_ir_chip; |
| 3564 | +static DEFINE_SPINLOCK(iommu_table_lock); | |
| 3565 | 3565 | |
| 3566 | 3566 | static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) |
| 3567 | 3567 | { |
| @@ -167,40 +167,16 @@ EXPORT_SYMBOL(iommu_put_dma_cookie); · 166 unmodified lines | ||
| 167 | 167 | * @list: Reserved region list from iommu_get_resv_regions() |
| 168 | 168 | * |
| 169 | 169 | * IOMMU drivers can use this to implement their .get_resv_regions callback |
| 170 | − * for general non-IOMMU-specific reservations. Currently, this covers host | |
| 171 | − * bridge windows for PCI devices and GICv3 ITS region reservation on ACPI | |
| 172 | − * based ARM platforms that may require HW MSI reservation. | |
| 170 | + * for general non-IOMMU-specific reservations. Currently, this covers GICv3 | |
| 171 | + * ITS region reservation on ACPI based ARM platforms that may require HW MSI | |
| 172 | + * reservation. | |
| 173 | 173 | */ |
| 174 | 174 | void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list) |
| 175 | 175 | { |
| 176 | − struct pci_host_bridge *bridge; | |
| 177 | − struct resource_entry *window; | |
| 178 | − | |
| 179 | − if (!is_of_node(dev->iommu_fwspec->iommu_fwnode) && | |
| 180 | − iort_iommu_msi_get_resv_regions(dev, list) < 0) | |
| 181 | − return; | |
| 182 | − | |
| 183 | − if (!dev_is_pci(dev)) | |
| 184 | − return; | |
| 185 | − | |
| 186 | − bridge = pci_find_host_bridge(to_pci_dev(dev)->bus); | |
| 187 | − resource_list_for_each_entry(window, &bridge->windows) { | |
| 188 | − struct iommu_resv_region *region; | |
| 189 | − phys_addr_t start; | |
| 190 | − size_t length; | |
| 191 | − | |
| 192 | − if (resource_type(window->res) != IORESOURCE_MEM) | |
| 193 | − continue; | |
| 194 | 176 | |
| 195 | − start = window->res->start - window->offset; | |
| 196 | − length = window->res->end - window->res->start + 1; | |
| 197 | − region = iommu_alloc_resv_region(start, length, 0, | |
| 198 | − IOMMU_RESV_RESERVED); | |
| 199 | − if (!region) | |
| 200 | − return; | |
| 177 | + if (!is_of_node(dev->iommu_fwspec->iommu_fwnode)) | |
| 178 | + iort_iommu_msi_get_resv_regions(dev, list); | |
| 201 | 179 | |
| 202 | − list_add_tail(®ion->list, list); | |
| 203 | − } | |
| 204 | 180 | } |
| 205 | 181 | EXPORT_SYMBOL(iommu_dma_get_resv_regions); |
| 206 | 182 | |
| @@ -229,6 +205,23 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, · 22 unmodified lines | ||
| 229 | 205 | return 0; |
| 230 | 206 | } |
| 231 | 207 | |
| 208 | +static void iova_reserve_pci_windows(struct pci_dev *dev, | |
| 209 | + struct iova_domain *iovad) | |
| 210 | +{ | |
| 211 | + struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus); | |
| 212 | + struct resource_entry *window; | |
| 213 | + unsigned long lo, hi; | |
| 214 | + | |
| 215 | + resource_list_for_each_entry(window, &bridge->windows) { | |
| 216 | + if (resource_type(window->res) != IORESOURCE_MEM) | |
| 217 | + continue; | |
| 218 | + | |
| 219 | + lo = iova_pfn(iovad, window->res->start - window->offset); | |
| 220 | + hi = iova_pfn(iovad, window->res->end - window->offset); | |
| 221 | + reserve_iova(iovad, lo, hi); | |
| 222 | + } | |
| 223 | +} | |
| 224 | + | |
| 232 | 225 | static int iova_reserve_iommu_regions(struct device *dev, |
| 233 | 226 | struct iommu_domain *domain) |
| 234 | 227 | { |
| @@ -238,6 +231,9 @@ static int iova_reserve_iommu_regions(struct device *dev, · 3 unmodified lines | ||
| 238 | 231 | LIST_HEAD(resv_regions); |
| 239 | 232 | int ret = 0; |
| 240 | 233 | |
| 234 | + if (dev_is_pci(dev)) | |
| 235 | + iova_reserve_pci_windows(to_pci_dev(dev), iovad); | |
| 236 | + | |
| 241 | 237 | iommu_get_resv_regions(dev, &resv_regions); |
| 242 | 238 | list_for_each_entry(region, &resv_regions, list) { |
| 243 | 239 | unsigned long lo, hi; |
| @@ -1345,7 +1345,7 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep, · 1344 unmodified lines | ||
| 1345 | 1345 | struct qi_desc desc; |
| 1346 | 1346 | |
| 1347 | 1347 | if (mask) { |
| 1348 | − BUG_ON(addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1)); | |
| 1348 | + WARN_ON_ONCE(addr & ((1ULL << (VTD_PAGE_SHIFT + mask)) - 1)); | |
| 1349 | 1349 | addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; |
| 1350 | 1350 | desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; |
| 1351 | 1351 | } else |
| @@ -1136,7 +1136,7 @@ static void intel_ir_reconfigure_irte(struct irq_data *irqd, bool force) · 1135 unmodified lines | ||
| 1136 | 1136 | irte->dest_id = IRTE_DEST(cfg->dest_apicid); |
| 1137 | 1137 | |
| 1138 | 1138 | /* Update the hardware only if the interrupt is in remapped mode. */ |
| 1139 | − if (!force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING) | |
| 1139 | + if (force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING) | |
| 1140 | 1140 | modify_irte(&ir_data->irq_2_iommu, irte); |
| 1141 | 1141 | } |
| 1142 | 1142 | |
| @@ -1098,7 +1098,7 @@ static int rk_iommu_of_xlate(struct device *dev, · 1097 unmodified lines | ||
| 1098 | 1098 | data->iommu = platform_get_drvdata(iommu_dev); |
| 1099 | 1099 | dev->archdata.iommu = data; |
| 1100 | 1100 | |
| 1101 | − of_dev_put(iommu_dev); | |
| 1101 | + platform_device_put(iommu_dev); | |
| 1102 | 1102 | |
| 1103 | 1103 | return 0; |
| 1104 | 1104 | } |
| @@ -1175,8 +1175,15 @@ static int rk_iommu_probe(struct platform_device *pdev) · 70 unmodified lines | ||
| 1175 | 1175 | for (i = 0; i < iommu->num_clocks; ++i) |
| 1176 | 1176 | iommu->clocks[i].id = rk_iommu_clocks[i]; |
| 1177 | 1177 | |
| 1178 | + /* | |
| 1179 | + * iommu clocks should be present for all new devices and devicetrees | |
| 1180 | + * but there are older devicetrees without clocks out in the wild. | |
| 1181 | + * So clocks as optional for the time being. | |
| 1182 | + */ | |
| 1178 | 1183 | err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks); |
| 1179 | − if (err) | |
| 1184 | + if (err == -ENOENT) | |
| 1185 | + iommu->num_clocks = 0; | |
| 1186 | + else if (err) | |
| 1180 | 1187 | return err; |
| 1181 | 1188 | |
| 1182 | 1189 | err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. | |
| 1 | +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | |
| 2 | 2 | * |
| 3 | 3 | * This program is free software; you can redistribute it and/or modify |
| 4 | 4 | * it under the terms of the GNU General Public License version 2 and |
| @@ -68,7 +68,7 @@ static void combiner_handle_irq(struct irq_desc *desc) · 63 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | bit = readl_relaxed(combiner->regs[reg].addr); |
| 70 | 70 | status = bit & combiner->regs[reg].enabled; |
| 71 | − if (!status) | |
| 71 | + if (bit && !status) | |
| 72 | 72 | pr_warn_ratelimited("Unexpected IRQ on CPU%d: (%08x %08lx %p)\n", |
| 73 | 73 | smp_processor_id(), bit, |
| 74 | 74 | combiner->regs[reg].enabled, |
| @@ -68,12 +68,12 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg) · 67 unmodified lines | ||
| 68 | 68 | goto _do; |
| 69 | 69 | |
| 70 | 70 | { |
| 71 | − char _dup[len + 1]; | |
| 72 | 71 | char *dup, *tok, *name, *val; |
| 73 | 72 | int tmp; |
| 74 | 73 | |
| 75 | − strcpy(_dup, arg); | |
| 76 | − dup = _dup; | |
| 74 | + dup = kstrdup(arg, GFP_ATOMIC); | |
| 75 | + if (!dup) | |
| 76 | + return; | |
| 77 | 77 | |
| 78 | 78 | while ((tok = strsep(&dup, ","))) { |
| 79 | 79 | if (!strlen(tok)) |
| @@ -89,6 +89,8 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg) · 9 unmodified lines | ||
| 89 | 89 | deftaps = tmp; |
| 90 | 90 | } |
| 91 | 91 | } |
| 92 | + | |
| 93 | + kfree(dup); | |
| 92 | 94 | } |
| 93 | 95 | |
| 94 | 96 | _do: |
| @@ -279,7 +279,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, · 278 unmodified lines | ||
| 279 | 279 | u16 timebase, u8 *buf, int len) |
| 280 | 280 | { |
| 281 | 281 | u8 *p; |
| 282 | − u8 frame[len + 32]; | |
| 282 | + u8 frame[MAX_DFRAME_LEN_L1 + 32]; | |
| 283 | 283 | struct socket *socket = NULL; |
| 284 | 284 | |
| 285 | 285 | if (debug & DEBUG_L1OIP_MSG) |
| @@ -902,7 +902,11 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) · 616 unmodified lines | ||
| 902 | 902 | p = skb->data; |
| 903 | 903 | l = skb->len; |
| 904 | 904 | while (l) { |
| 905 | − ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME; | |
| 905 | + /* | |
| 906 | + * This is technically bounded by L1OIP_MAX_PERFRAME but | |
| 907 | + * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME | |
| 908 | + */ | |
| 909 | + ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1; | |
| 906 | 910 | l1oip_socket_send(hc, 0, dch->slot, 0, |
| 907 | 911 | hc->chan[dch->slot].tx_counter++, p, ll); |
| 908 | 912 | p += ll; |
| @@ -1140,7 +1144,11 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) · 231 unmodified lines | ||
| 1140 | 1144 | p = skb->data; |
| 1141 | 1145 | l = skb->len; |
| 1142 | 1146 | while (l) { |
| 1143 | − ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME; | |
| 1147 | + /* | |
| 1148 | + * This is technically bounded by L1OIP_MAX_PERFRAME but | |
| 1149 | + * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME | |
| 1150 | + */ | |
| 1151 | + ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1; | |
| 1144 | 1152 | l1oip_socket_send(hc, hc->codec, bch->slot, 0, |
| 1145 | 1153 | hc->chan[bch->slot].tx_counter, p, ll); |
| 1146 | 1154 | hc->chan[bch->slot].tx_counter += ll; |
| @@ -290,7 +290,7 @@ do { \ · 289 unmodified lines | ||
| 290 | 290 | if (kthread_should_stop() || \ |
| 291 | 291 | test_bit(CACHE_SET_IO_DISABLE, &ca->set->flags)) { \ |
| 292 | 292 | set_current_state(TASK_RUNNING); \ |
| 293 | − return 0; \ | |
| 293 | + goto out; \ | |
| 294 | 294 | } \ |
| 295 | 295 | \ |
| 296 | 296 | schedule(); \ |
| @@ -378,6 +378,9 @@ retry_invalidate: · 81 unmodified lines | ||
| 378 | 378 | bch_prio_write(ca); |
| 379 | 379 | } |
| 380 | 380 | } |
| 381 | +out: | |
| 382 | + wait_for_kthread_stop(); | |
| 383 | + return 0; | |
| 381 | 384 | } |
| 382 | 385 | |
| 383 | 386 | /* Allocation */ |
| @@ -392,6 +392,8 @@ struct cached_dev { · 391 unmodified lines | ||
| 392 | 392 | #define DEFAULT_CACHED_DEV_ERROR_LIMIT 64 |
| 393 | 393 | atomic_t io_errors; |
| 394 | 394 | unsigned error_limit; |
| 395 | + | |
| 396 | + char backing_dev_name[BDEVNAME_SIZE]; | |
| 395 | 397 | }; |
| 396 | 398 | |
| 397 | 399 | enum alloc_reserve { |
| @@ -464,6 +466,8 @@ struct cache { · 66 unmodified lines | ||
| 464 | 466 | atomic_long_t meta_sectors_written; |
| 465 | 467 | atomic_long_t btree_sectors_written; |
| 466 | 468 | atomic_long_t sectors_written; |
| 469 | + | |
| 470 | + char cache_dev_name[BDEVNAME_SIZE]; | |
| 467 | 471 | }; |
| 468 | 472 | |
| 469 | 473 | struct gc_stat { |
| @@ -106,7 +106,6 @@ void bch_btree_verify(struct btree *b) · 105 unmodified lines | ||
| 106 | 106 | |
| 107 | 107 | void bch_data_verify(struct cached_dev *dc, struct bio *bio) |
| 108 | 108 | { |
| 109 | − char name[BDEVNAME_SIZE]; | |
| 110 | 109 | struct bio *check; |
| 111 | 110 | struct bio_vec bv, cbv; |
| 112 | 111 | struct bvec_iter iter, citer = { 0 }; |
| @@ -134,7 +133,7 @@ void bch_data_verify(struct cached_dev *dc, struct bio *bio) · 21 unmodified lines | ||
| 134 | 133 | bv.bv_len), |
| 135 | 134 | dc->disk.c, |
| 136 | 135 | "verify failed at dev %s sector %llu", |
| 137 | − bdevname(dc->bdev, name), | |
| 136 | + dc->backing_dev_name, | |
| 138 | 137 | (uint64_t) bio->bi_iter.bi_sector); |
| 139 | 138 | |
| 140 | 139 | kunmap_atomic(p1); |
| @@ -52,7 +52,6 @@ void bch_submit_bbio(struct bio *bio, struct cache_set *c, · 51 unmodified lines | ||
| 52 | 52 | /* IO errors */ |
| 53 | 53 | void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio) |
| 54 | 54 | { |
| 55 | − char buf[BDEVNAME_SIZE]; | |
| 56 | 55 | unsigned errors; |
| 57 | 56 | |
| 58 | 57 | WARN_ONCE(!dc, "NULL pointer of struct cached_dev"); |
| @@ -60,7 +59,7 @@ void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio) · 1 unmodified line | ||
| 60 | 59 | errors = atomic_add_return(1, &dc->io_errors); |
| 61 | 60 | if (errors < dc->error_limit) |
| 62 | 61 | pr_err("%s: IO error on backing device, unrecoverable", |
| 63 | − bio_devname(bio, buf)); | |
| 62 | + dc->backing_dev_name); | |
| 64 | 63 | else |
| 65 | 64 | bch_cached_dev_error(dc); |
| 66 | 65 | } |
| @@ -105,19 +104,18 @@ void bch_count_io_errors(struct cache *ca, · 38 unmodified lines | ||
| 105 | 104 | } |
| 106 | 105 | |
| 107 | 106 | if (error) { |
| 108 | − char buf[BDEVNAME_SIZE]; | |
| 109 | 107 | unsigned errors = atomic_add_return(1 << IO_ERROR_SHIFT, |
| 110 | 108 | &ca->io_errors); |
| 111 | 109 | errors >>= IO_ERROR_SHIFT; |
| 112 | 110 | |
| 113 | 111 | if (errors < ca->set->error_limit) |
| 114 | 112 | pr_err("%s: IO error on %s%s", |
| 115 | − bdevname(ca->bdev, buf), m, | |
| 113 | + ca->cache_dev_name, m, | |
| 116 | 114 | is_read ? ", recovering." : "."); |
| 117 | 115 | else |
| 118 | 116 | bch_cache_set_error(ca->set, |
| 119 | 117 | "%s: too many IO errors %s", |
| 120 | − bdevname(ca->bdev, buf), m); | |
| 118 | + ca->cache_dev_name, m); | |
| 121 | 119 | } |
| 122 | 120 | } |
| 123 | 121 | |
| @@ -649,11 +649,8 @@ static void backing_request_endio(struct bio *bio) · 648 unmodified lines | ||
| 649 | 649 | */ |
| 650 | 650 | if (unlikely(s->iop.writeback && |
| 651 | 651 | bio->bi_opf & REQ_PREFLUSH)) { |
| 652 | − char buf[BDEVNAME_SIZE]; | |
| 653 | − | |
| 654 | − bio_devname(bio, buf); | |
| 655 | 652 | pr_err("Can't flush %s: returned bi_status %i", |
| 656 | − buf, bio->bi_status); | |
| 653 | + dc->backing_dev_name, bio->bi_status); | |
| 657 | 654 | } else { |
| 658 | 655 | /* set to orig_bio->bi_status in bio_complete() */ |
| 659 | 656 | s->iop.status = bio->bi_status; |
| @@ -936,7 +936,6 @@ static void cancel_writeback_rate_update_dwork(struct cached_dev *dc) · 935 unmodified lines | ||
| 936 | 936 | static void cached_dev_detach_finish(struct work_struct *w) |
| 937 | 937 | { |
| 938 | 938 | struct cached_dev *dc = container_of(w, struct cached_dev, detach); |
| 939 | − char buf[BDEVNAME_SIZE]; | |
| 940 | 939 | struct closure cl; |
| 941 | 940 | closure_init_stack(&cl); |
| 942 | 941 | |
| @@ -967,7 +966,7 @@ static void cached_dev_detach_finish(struct work_struct *w) · 24 unmodified lines | ||
| 967 | 966 | |
| 968 | 967 | mutex_unlock(&bch_register_lock); |
| 969 | 968 | |
| 970 | − pr_info("Caching disabled for %s", bdevname(dc->bdev, buf)); | |
| 969 | + pr_info("Caching disabled for %s", dc->backing_dev_name); | |
| 971 | 970 | |
| 972 | 971 | /* Drop ref we took in cached_dev_detach() */ |
| 973 | 972 | closure_put(&dc->disk.cl); |
| @@ -999,29 +998,28 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, · 25 unmodified lines | ||
| 999 | 998 | { |
| 1000 | 999 | uint32_t rtime = cpu_to_le32(get_seconds()); |
| 1001 | 1000 | struct uuid_entry *u; |
| 1002 | − char buf[BDEVNAME_SIZE]; | |
| 1003 | 1001 | struct cached_dev *exist_dc, *t; |
| 1004 | 1002 | |
| 1005 | − bdevname(dc->bdev, buf); | |
| 1006 | − | |
| 1007 | 1003 | if ((set_uuid && memcmp(set_uuid, c->sb.set_uuid, 16)) || |
| 1008 | 1004 | (!set_uuid && memcmp(dc->sb.set_uuid, c->sb.set_uuid, 16))) |
| 1009 | 1005 | return -ENOENT; |
| 1010 | 1006 | |
| 1011 | 1007 | if (dc->disk.c) { |
| 1012 | − pr_err("Can't attach %s: already attached", buf); | |
| 1008 | + pr_err("Can't attach %s: already attached", | |
| 1009 | + dc->backing_dev_name); | |
| 1013 | 1010 | return -EINVAL; |
| 1014 | 1011 | } |
| 1015 | 1012 | |
| 1016 | 1013 | if (test_bit(CACHE_SET_STOPPING, &c->flags)) { |
| 1017 | − pr_err("Can't attach %s: shutting down", buf); | |
| 1014 | + pr_err("Can't attach %s: shutting down", | |
| 1015 | + dc->backing_dev_name); | |
| 1018 | 1016 | return -EINVAL; |
| 1019 | 1017 | } |
| 1020 | 1018 | |
| 1021 | 1019 | if (dc->sb.block_size < c->sb.block_size) { |
| 1022 | 1020 | /* Will die */ |
| 1023 | 1021 | pr_err("Couldn't attach %s: block size less than set's block size", |
| 1024 | − buf); | |
| 1022 | + dc->backing_dev_name); | |
| 1025 | 1023 | return -EINVAL; |
| 1026 | 1024 | } |
| 1027 | 1025 | |
| @@ -1029,7 +1027,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, · 1 unmodified line | ||
| 1029 | 1027 | list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) { |
| 1030 | 1028 | if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) { |
| 1031 | 1029 | pr_err("Tried to attach %s but duplicate UUID already attached", |
| 1032 | − buf); | |
| 1030 | + dc->backing_dev_name); | |
| 1033 | 1031 | |
| 1034 | 1032 | return -EINVAL; |
| 1035 | 1033 | } |
| @@ -1047,13 +1045,15 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, · 11 unmodified lines | ||
| 1047 | 1045 | |
| 1048 | 1046 | if (!u) { |
| 1049 | 1047 | if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) { |
| 1050 | − pr_err("Couldn't find uuid for %s in set", buf); | |
| 1048 | + pr_err("Couldn't find uuid for %s in set", | |
| 1049 | + dc->backing_dev_name); | |
| 1051 | 1050 | return -ENOENT; |
| 1052 | 1051 | } |
| 1053 | 1052 | |
| 1054 | 1053 | u = uuid_find_empty(c); |
| 1055 | 1054 | if (!u) { |
| 1056 | − pr_err("Not caching %s, no room for UUID", buf); | |
| 1055 | + pr_err("Not caching %s, no room for UUID", | |
| 1056 | + dc->backing_dev_name); | |
| 1057 | 1057 | return -EINVAL; |
| 1058 | 1058 | } |
| 1059 | 1059 | } |
| @@ -1112,7 +1112,8 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, · 52 unmodified lines | ||
| 1112 | 1112 | up_write(&dc->writeback_lock); |
| 1113 | 1113 | |
| 1114 | 1114 | pr_info("Caching %s as %s on set %pU", |
| 1115 | − bdevname(dc->bdev, buf), dc->disk.disk->disk_name, | |
| 1115 | + dc->backing_dev_name, | |
| 1116 | + dc->disk.disk->disk_name, | |
| 1116 | 1117 | dc->disk.c->sb.set_uuid); |
| 1117 | 1118 | return 0; |
| 1118 | 1119 | } |
| @@ -1225,10 +1226,10 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, · 106 unmodified lines | ||
| 1225 | 1226 | struct block_device *bdev, |
| 1226 | 1227 | struct cached_dev *dc) |
| 1227 | 1228 | { |
| 1228 | − char name[BDEVNAME_SIZE]; | |
| 1229 | 1229 | const char *err = "cannot allocate memory"; |
| 1230 | 1230 | struct cache_set *c; |
| 1231 | 1231 | |
| 1232 | + bdevname(bdev, dc->backing_dev_name); | |
| 1232 | 1233 | memcpy(&dc->sb, sb, sizeof(struct cache_sb)); |
| 1233 | 1234 | dc->bdev = bdev; |
| 1234 | 1235 | dc->bdev->bd_holder = dc; |
| @@ -1237,6 +1238,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, · 2 unmodified lines | ||
| 1237 | 1238 | bio_first_bvec_all(&dc->sb_bio)->bv_page = sb_page; |
| 1238 | 1239 | get_page(sb_page); |
| 1239 | 1240 | |
| 1241 | + | |
| 1240 | 1242 | if (cached_dev_init(dc, sb->block_size << 9)) |
| 1241 | 1243 | goto err; |
| 1242 | 1244 | |
| @@ -1247,7 +1249,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, · 4 unmodified lines | ||
| 1247 | 1249 | if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj)) |
| 1248 | 1250 | goto err; |
| 1249 | 1251 | |
| 1250 | − pr_info("registered backing device %s", bdevname(bdev, name)); | |
| 1252 | + pr_info("registered backing device %s", dc->backing_dev_name); | |
| 1251 | 1253 | |
| 1252 | 1254 | list_add(&dc->list, &uncached_devices); |
| 1253 | 1255 | list_for_each_entry(c, &bch_cache_sets, list) |
| @@ -1259,7 +1261,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page, · 5 unmodified lines | ||
| 1259 | 1261 | |
| 1260 | 1262 | return; |
| 1261 | 1263 | err: |
| 1262 | − pr_notice("error %s: %s", bdevname(bdev, name), err); | |
| 1264 | + pr_notice("error %s: %s", dc->backing_dev_name, err); | |
| 1263 | 1265 | bcache_device_stop(&dc->disk); |
| 1264 | 1266 | } |
| 1265 | 1267 | |
| @@ -1367,7 +1369,7 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size) · 101 unmodified lines | ||
| 1367 | 1369 | |
| 1368 | 1370 | bool bch_cached_dev_error(struct cached_dev *dc) |
| 1369 | 1371 | { |
| 1370 | − char name[BDEVNAME_SIZE]; | |
| 1372 | + struct cache_set *c; | |
| 1371 | 1373 | |
| 1372 | 1374 | if (!dc || test_bit(BCACHE_DEV_CLOSING, &dc->disk.flags)) |
| 1373 | 1375 | return false; |
| @@ -1377,7 +1379,22 @@ bool bch_cached_dev_error(struct cached_dev *dc) · 3 unmodified lines | ||
| 1377 | 1379 | smp_mb(); |
| 1378 | 1380 | |
| 1379 | 1381 | pr_err("stop %s: too many IO errors on backing device %s\n", |
| 1380 | − dc->disk.disk->disk_name, bdevname(dc->bdev, name)); | |
| 1382 | + dc->disk.disk->disk_name, dc->backing_dev_name); | |
| 1383 | + | |
| 1384 | + /* | |
| 1385 | + * If the cached device is still attached to a cache set, | |
| 1386 | + * even dc->io_disable is true and no more I/O requests | |
| 1387 | + * accepted, cache device internal I/O (writeback scan or | |
| 1388 | + * garbage collection) may still prevent bcache device from | |
| 1389 | + * being stopped. So here CACHE_SET_IO_DISABLE should be | |
| 1390 | + * set to c->flags too, to make the internal I/O to cache | |
| 1391 | + * device rejected and stopped immediately. | |
| 1392 | + * If c is NULL, that means the bcache device is not attached | |
| 1393 | + * to any cache set, then no CACHE_SET_IO_DISABLE bit to set. | |
| 1394 | + */ | |
| 1395 | + c = dc->disk.c; | |
| 1396 | + if (c && test_and_set_bit(CACHE_SET_IO_DISABLE, &c->flags)) | |
| 1397 | + pr_info("CACHE_SET_IO_DISABLE already set"); | |
| 1381 | 1398 | |
| 1382 | 1399 | bcache_device_stop(&dc->disk); |
| 1383 | 1400 | return true; |
| @@ -1395,7 +1412,7 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...) · 11 unmodified lines | ||
| 1395 | 1412 | return false; |
| 1396 | 1413 | |
| 1397 | 1414 | if (test_and_set_bit(CACHE_SET_IO_DISABLE, &c->flags)) |
| 1398 | − pr_warn("CACHE_SET_IO_DISABLE already set"); | |
| 1415 | + pr_info("CACHE_SET_IO_DISABLE already set"); | |
| 1399 | 1416 | |
| 1400 | 1417 | /* XXX: we can be called from atomic context |
| 1401 | 1418 | acquire_console_sem(); |
| @@ -1539,6 +1556,20 @@ static void conditional_stop_bcache_device(struct cache_set *c, · 137 unmodified lines | ||
| 1539 | 1556 | */ |
| 1540 | 1557 | pr_warn("stop_when_cache_set_failed of %s is \"auto\" and cache is dirty, stop it to avoid potential data corruption.", |
| 1541 | 1558 | d->disk->disk_name); |
| 1559 | + /* | |
| 1560 | + * There might be a small time gap that cache set is | |
| 1561 | + * released but bcache device is not. Inside this time | |
| 1562 | + * gap, regular I/O requests will directly go into | |
| 1563 | + * backing device as no cache set attached to. This | |
| 1564 | + * behavior may also introduce potential inconsistence | |
| 1565 | + * data in writeback mode while cache is dirty. | |
| 1566 | + * Therefore before calling bcache_device_stop() due | |
| 1567 | + * to a broken cache device, dc->io_disable should be | |
| 1568 | + * explicitly set to true. | |
| 1569 | + */ | |
| 1570 | + dc->io_disable = true; | |
| 1571 | + /* make others know io_disable is true earlier */ | |
| 1572 | + smp_mb(); | |
| 1542 | 1573 | bcache_device_stop(d); |
| 1543 | 1574 | } else { |
| 1544 | 1575 | /* |
| @@ -2003,12 +2034,10 @@ static int cache_alloc(struct cache *ca) · 458 unmodified lines | ||
| 2003 | 2034 | static int register_cache(struct cache_sb *sb, struct page *sb_page, |
| 2004 | 2035 | struct block_device *bdev, struct cache *ca) |
| 2005 | 2036 | { |
| 2006 | − char name[BDEVNAME_SIZE]; | |
| 2007 | 2037 | const char *err = NULL; /* must be set for any error case */ |
| 2008 | 2038 | int ret = 0; |
| 2009 | 2039 | |
| 2010 | − bdevname(bdev, name); | |
| 2011 | − | |
| 2040 | + bdevname(bdev, ca->cache_dev_name); | |
| 2012 | 2041 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); |
| 2013 | 2042 | ca->bdev = bdev; |
| 2014 | 2043 | ca->bdev->bd_holder = ca; |
| @@ -2045,14 +2074,14 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, · 30 unmodified lines | ||
| 2045 | 2074 | goto out; |
| 2046 | 2075 | } |
| 2047 | 2076 | |
| 2048 | − pr_info("registered cache device %s", name); | |
| 2077 | + pr_info("registered cache device %s", ca->cache_dev_name); | |
| 2049 | 2078 | |
| 2050 | 2079 | out: |
| 2051 | 2080 | kobject_put(&ca->kobj); |
| 2052 | 2081 | |
| 2053 | 2082 | err: |
| 2054 | 2083 | if (err) |
| 2055 | − pr_notice("error %s: %s", name, err); | |
| 2084 | + pr_notice("error %s: %s", ca->cache_dev_name, err); | |
| 2056 | 2085 | |
| 2057 | 2086 | return ret; |
| 2058 | 2087 | } |
| @@ -244,8 +244,10 @@ static void dirty_endio(struct bio *bio) · 243 unmodified lines | ||
| 244 | 244 | struct keybuf_key *w = bio->bi_private; |
| 245 | 245 | struct dirty_io *io = w->private; |
| 246 | 246 | |
| 247 | − if (bio->bi_status) | |
| 247 | + if (bio->bi_status) { | |
| 248 | 248 | SET_KEY_DIRTY(&w->key, false); |
| 249 | + bch_count_backing_io_errors(io->dc, bio); | |
| 250 | + } | |
| 249 | 251 | |
| 250 | 252 | closure_put(&io->cl); |
| 251 | 253 | } |
| @@ -9256,8 +9256,10 @@ void md_reload_sb(struct mddev *mddev, int nr) · 9255 unmodified lines | ||
| 9256 | 9256 | check_sb_changes(mddev, rdev); |
| 9257 | 9257 | |
| 9258 | 9258 | /* Read all rdev's to update recovery_offset */ |
| 9259 | − rdev_for_each_rcu(rdev, mddev) | |
| 9260 | − read_rdev(mddev, rdev); | |
| 9259 | + rdev_for_each_rcu(rdev, mddev) { | |
| 9260 | + if (!test_bit(Faulty, &rdev->flags)) | |
| 9261 | + read_rdev(mddev, rdev); | |
| 9262 | + } | |
| 9261 | 9263 | } |
| 9262 | 9264 | EXPORT_SYMBOL(md_reload_sb); |
| 9263 | 9265 | |
| @@ -854,7 +854,7 @@ static void flush_pending_writes(struct r1conf *conf) · 853 unmodified lines | ||
| 854 | 854 | * there is no normal IO happeing. It must arrange to call |
| 855 | 855 | * lower_barrier when the particular background IO completes. |
| 856 | 856 | */ |
| 857 | −static void raise_barrier(struct r1conf *conf, sector_t sector_nr) | |
| 857 | +static sector_t raise_barrier(struct r1conf *conf, sector_t sector_nr) | |
| 858 | 858 | { |
| 859 | 859 | int idx = sector_to_idx(sector_nr); |
| 860 | 860 | |
| @@ -885,13 +885,23 @@ static void raise_barrier(struct r1conf *conf, sector_t sector_nr) · 24 unmodified lines | ||
| 885 | 885 | * max resync count which allowed on current I/O barrier bucket. |
| 886 | 886 | */ |
| 887 | 887 | wait_event_lock_irq(conf->wait_barrier, |
| 888 | − !conf->array_frozen && | |
| 888 | + (!conf->array_frozen && | |
| 889 | 889 | !atomic_read(&conf->nr_pending[idx]) && |
| 890 | − atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH, | |
| 890 | + atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH) || | |
| 891 | + test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery), | |
| 891 | 892 | conf->resync_lock); |
| 892 | 893 | |
| 894 | + if (test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { | |
| 895 | + atomic_dec(&conf->barrier[idx]); | |
| 896 | + spin_unlock_irq(&conf->resync_lock); | |
| 897 | + wake_up(&conf->wait_barrier); | |
| 898 | + return -EINTR; | |
| 899 | + } | |
| 900 | + | |
| 893 | 901 | atomic_inc(&conf->nr_sync_pending); |
| 894 | 902 | spin_unlock_irq(&conf->resync_lock); |
| 903 | + | |
| 904 | + return 0; | |
| 895 | 905 | } |
| 896 | 906 | |
| 897 | 907 | static void lower_barrier(struct r1conf *conf, sector_t sector_nr) |
| @@ -1092,6 +1102,8 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio, · 194 unmodified lines | ||
| 1092 | 1102 | goto skip_copy; |
| 1093 | 1103 | } |
| 1094 | 1104 | |
| 1105 | + behind_bio->bi_write_hint = bio->bi_write_hint; | |
| 1106 | + | |
| 1095 | 1107 | while (i < vcnt && size) { |
| 1096 | 1108 | struct page *page; |
| 1097 | 1109 | int len = min_t(int, PAGE_SIZE, size); |
| @@ -2662,9 +2674,12 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, · 1564 unmodified lines | ||
| 2662 | 2674 | |
| 2663 | 2675 | bitmap_cond_end_sync(mddev->bitmap, sector_nr, |
| 2664 | 2676 | mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high)); |
| 2665 | − r1_bio = raid1_alloc_init_r1buf(conf); | |
| 2666 | 2677 | |
| 2667 | − raise_barrier(conf, sector_nr); | |
| 2678 | + | |
| 2679 | + if (raise_barrier(conf, sector_nr)) | |
| 2680 | + return 0; | |
| 2681 | + | |
| 2682 | + r1_bio = raid1_alloc_init_r1buf(conf); | |
| 2668 | 2683 | |
| 2669 | 2684 | rcu_read_lock(); |
| 2670 | 2685 | /* |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | // |
| 21 | 21 | // VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> |
| 22 | 22 | // |
| 23 | −// Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 23 | +// Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 24 | 24 | // SAA7111, SAA7113 and SAA7118 support |
| 25 | 25 | |
| 26 | 26 | #include "saa711x_regs.h" |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * SPDX-License-Identifier: GPL-2.0+ |
| 3 | 3 | * saa711x - Philips SAA711x video decoder register specifications |
| 4 | 4 | * |
| 5 | − * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | + * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #define R_00_CHIP_VERSION 0x00 |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | * Muting and tone control by Jonathan Isom <jisom@ematic.com> |
| 9 | 9 | * |
| 10 | 10 | * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com> |
| 11 | − * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 11 | + * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 12 | 12 | * This code is placed under the terms of the GNU General Public License |
| 13 | 13 | * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) |
| 14 | 14 | * Which was based on tda8425.c by Greg Alexander (c) 1998 |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // |
| 3 | 3 | // tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver |
| 4 | 4 | // |
| 5 | −// Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | +// Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | |
| 7 | 7 | #include <dt-bindings/media/tvp5150.h> |
| 8 | 8 | #include <linux/i2c.h> |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * |
| 4 | 4 | * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers |
| 5 | 5 | * |
| 6 | − * Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 6 | + * Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */ |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> |
| 6 | 6 | * |
| 7 | 7 | * This code is partially based upon the TVP5150 driver |
| 8 | − * written by Mauro Carvalho Chehab (mchehab@infradead.org), | |
| 8 | + * written by Mauro Carvalho Chehab <mchehab@kernel.org>, | |
| 9 | 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> |
| 10 | 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by |
| 11 | 11 | * Muralidharan Karicheri and Snehaprabha Narnakaje (TI). |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com> |
| 6 | 6 | * |
| 7 | 7 | * This code is partially based upon the TVP5150 driver |
| 8 | − * written by Mauro Carvalho Chehab (mchehab@infradead.org), | |
| 8 | + * written by Mauro Carvalho Chehab <mchehab@kernel.org>, | |
| 9 | 9 | * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com> |
| 10 | 10 | * and the TVP7002 driver in the TI LSP 2.10.00.14 |
| 11 | 11 | * |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2010 Nokia Corporation |
| 5 | 5 | * |
| 6 | 6 | * Based on drivers/media/video/v4l2_dev.c code authored by |
| 7 | − * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) | |
| 7 | + * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) | |
| 8 | 8 | * Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
| 9 | 9 | * |
| 10 | 10 | * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Handlers for board audio hooks, splitted from bttv-cards |
| 3 | 3 | * |
| 4 | − * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org) | |
| 4 | + * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | * This code is placed under the terms of the GNU General Public License |
| 6 | 6 | */ |
| 7 | 7 | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Handlers for board audio hooks, splitted from bttv-cards |
| 3 | 3 | * |
| 4 | − * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org) | |
| 4 | + * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | * This code is placed under the terms of the GNU General Public License |
| 6 | 6 | */ |
| 7 | 7 | |
| @@ -2447,7 +2447,7 @@ struct tvcard bttv_tvcards[] = { · 2446 unmodified lines | ||
| 2447 | 2447 | }, |
| 2448 | 2448 | /* ---- card 0x88---------------------------------- */ |
| 2449 | 2449 | [BTTV_BOARD_ACORP_Y878F] = { |
| 2450 | − /* Mauro Carvalho Chehab <mchehab@infradead.org> */ | |
| 2450 | + /* Mauro Carvalho Chehab <mchehab@kernel.org> */ | |
| 2451 | 2451 | .name = "Acorp Y878F", |
| 2452 | 2452 | .video_inputs = 3, |
| 2453 | 2453 | /* .audio_inputs= 1, */ |
| @@ -2688,7 +2688,7 @@ struct tvcard bttv_tvcards[] = { · 234 unmodified lines | ||
| 2688 | 2688 | }, |
| 2689 | 2689 | [BTTV_BOARD_ENLTV_FM_2] = { |
| 2690 | 2690 | /* Encore TV Tuner Pro ENL TV-FM-2 |
| 2691 | − Mauro Carvalho Chehab <mchehab@infradead.org */ | |
| 2691 | + Mauro Carvalho Chehab <mchehab@kernel.org> */ | |
| 2692 | 2692 | .name = "Encore ENL TV-FM-2", |
| 2693 | 2693 | .video_inputs = 3, |
| 2694 | 2694 | /* .audio_inputs= 1, */ |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru> |
| 14 | 14 | |
| 15 | 15 | Fixes to be fully V4L2 compliant by |
| 16 | − (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 16 | + (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 17 | 17 | |
| 18 | 18 | Cropping and overscan support |
| 19 | 19 | Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at> |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
| 9 | 9 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
| 10 | 10 | |
| 11 | − (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 11 | + (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 12 | 12 | - Multituner support and i2c address binding |
| 13 | 13 | |
| 14 | 14 | This program is free software; you can redistribute it and/or modify |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | * Copyright (C) 2008 <srinivasa.deevi at conexant dot com> |
| 14 | 14 | * Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 15 | 15 | * Markus Rechberger <mrechberger@gmail.com> |
| 16 | − * Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 16 | + * Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 17 | 17 | * Sascha Sommer <saschasommer@freenet.de> |
| 18 | 18 | * Copyright (C) 2004, 2005 Chris Pascoe |
| 19 | 19 | * Copyright (C) 2003, 2004 Gerd Knorr |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * |
| 5 | 5 | * (c) 2007 Trent Piepho <xyzzy@speakeasy.org> |
| 6 | 6 | * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> |
| 7 | − * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 7 | + * (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 8 | 8 | * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> |
| 9 | 9 | * Based on dummy.c by Jaroslav Kysela <perex@perex.cz> |
| 10 | 10 | * |
| @@ -103,7 +103,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); · 92 unmodified lines | ||
| 103 | 103 | |
| 104 | 104 | MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); |
| 105 | 105 | MODULE_AUTHOR("Ricardo Cerqueira"); |
| 106 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 106 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 107 | 107 | MODULE_LICENSE("GPL"); |
| 108 | 108 | MODULE_VERSION(CX88_VERSION); |
| 109 | 109 | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * (c) 2004 Jelle Foks <jelle@foks.us> |
| 6 | 6 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> |
| 7 | 7 | * |
| 8 | − * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 8 | + * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 9 | 9 | * - video_ioctl2 conversion |
| 10 | 10 | * |
| 11 | 11 | * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/> |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * |
| 5 | 5 | * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
| 6 | 6 | * |
| 7 | − * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 7 | + * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 8 | 8 | * - Multituner support |
| 9 | 9 | * - video_ioctl2 conversion |
| 10 | 10 | * - PAL/M fixes |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | * (c) 2002 Yurij Sysoev <yurij@naturesoft.net> |
| 9 | 9 | * (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
| 10 | 10 | * |
| 11 | − * (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 11 | + * (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 12 | 12 | * - Multituner support and i2c address binding |
| 13 | 13 | * |
| 14 | 14 | * This program is free software; you can redistribute it and/or modify |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * |
| 6 | 6 | * (c) 2003-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
| 7 | 7 | * |
| 8 | − * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 8 | + * (c) 2005-2006 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 9 | 9 | * - Multituner support |
| 10 | 10 | * - video_ioctl2 conversion |
| 11 | 11 | * - PAL/M fixes |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright 1997 M. Kirkwood |
| 5 | 5 | * |
| 6 | 6 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 7 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 7 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 8 | 8 | * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> |
| 9 | 9 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
| 10 | 10 | * |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * radio-aztech.c - Aztech radio card driver |
| 3 | 3 | * |
| 4 | 4 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@xs4all.nl> |
| 5 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | * Adapted to support the Video for Linux API by |
| 7 | 7 | * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: |
| 8 | 8 | * |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
| 16 | 16 | * |
| 17 | 17 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 18 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 18 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 19 | 19 | * |
| 20 | 20 | * Note: this card seems to swap the left and right audio channels! |
| 21 | 21 | * |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | * BUGS: |
| 28 | 28 | * - card unmutes if you change frequency |
| 29 | 29 | * |
| 30 | − * (c) 2006, 2007 by Mauro Carvalho Chehab <mchehab@infradead.org>: | |
| 30 | + * (c) 2006, 2007 by Mauro Carvalho Chehab <mchehab@kernel.org>: | |
| 31 | 31 | * - Conversion to V4L2 API |
| 32 | 32 | * - Uses video_ioctl2 for parsing and to add debug support |
| 33 | 33 | */ |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
| 8 | 8 | * |
| 9 | 9 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 10 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 10 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 11 | 11 | * |
| 12 | 12 | * Fully tested with actual hardware and the v4l2-compliance tool. |
| 13 | 13 | */ |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | * No volume control - only mute/unmute - you have to use line volume |
| 14 | 14 | * control on SB-part of SF16-FMI/SF16-FMP/SF16-FMD |
| 15 | 15 | * |
| 16 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 16 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | 19 | #include <linux/kernel.h> /* __setup */ |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | * Volume Control is done digitally |
| 18 | 18 | * |
| 19 | 19 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 20 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 20 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 21 | 21 | */ |
| 22 | 22 | |
| 23 | 23 | #include <linux/module.h> /* Modules */ |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) |
| 13 | 13 | * William McGrath (wmcgrath@twilight.vtc.vsc.edu) |
| 14 | 14 | * |
| 15 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 15 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | 18 | #include <stdarg.h> |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | * The frequency change is necessary since the card never seems to be |
| 26 | 26 | * completely silent. |
| 27 | 27 | * |
| 28 | − * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 28 | + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 29 | 29 | */ |
| 30 | 30 | |
| 31 | 31 | #include <linux/module.h> /* Modules */ |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | * 2002-07-15 - Fix Stereo typo |
| 28 | 28 | * |
| 29 | 29 | * 2006-07-24 - Converted to V4L2 API |
| 30 | − * by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 30 | + * by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 31 | 31 | * |
| 32 | 32 | * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> |
| 33 | 33 | * |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | * |
| 13 | 13 | * On Avermedia M135A with IR model RM-JX, the same codes exist on both |
| 14 | 14 | * Positivo (BR) and original IR, initial version and remote control codes |
| 15 | − * added by Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 15 | + * added by Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 16 | 16 | * |
| 17 | 17 | * Positivo also ships Avermedia M135A with model RM-K6, extra control |
| 18 | 18 | * codes added by Herton Ronaldo Krzesinski <herton@mandriva.com.br> |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 10 | |
| 11 | 11 | /* Encore ENLTV-FM v5.3 |
| 12 | − Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 12 | + Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | 15 | static struct rc_map_table encore_enltv_fm53[] = { |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 10 | |
| 11 | 11 | /* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton |
| 12 | − Mauro Carvalho Chehab <mchehab@infradead.org> */ | |
| 12 | + Mauro Carvalho Chehab <mchehab@kernel.org> */ | |
| 13 | 13 | |
| 14 | 14 | static struct rc_map_table encore_enltv2[] = { |
| 15 | 15 | { 0x4c, KEY_POWER2 }, |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 10 | |
| 11 | 11 | /* Kaiomy TVnPC U2 |
| 12 | − Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 12 | + Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | 15 | static struct rc_map_table kaiomy[] = { |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 10 | |
| 11 | 11 | /* Kworld Plus TV Analog Lite PCI IR |
| 12 | − Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 12 | + Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | 15 | static struct rc_map_table kworld_plus_tv_analog[] = { |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 10 | |
| 11 | 11 | /* |
| 12 | − Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 12 | + Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 13 | 13 | present on PV MPEG 8000GT |
| 14 | 14 | */ |
| 15 | 15 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // For Philips TEA5761 FM Chip |
| 3 | 3 | // I2C address is always 0x20 (0x10 at 7-bit mode). |
| 4 | 4 | // |
| 5 | −// Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org) | |
| 5 | +// Copyright (c) 2005-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | |
| 7 | 7 | #include <linux/i2c.h> |
| 8 | 8 | #include <linux/slab.h> |
| @@ -337,5 +337,5 @@ EXPORT_SYMBOL_GPL(tea5761_attach); · 328 unmodified lines | ||
| 337 | 337 | EXPORT_SYMBOL_GPL(tea5761_autodetection); |
| 338 | 338 | |
| 339 | 339 | MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver"); |
| 340 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 340 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 341 | 341 | MODULE_LICENSE("GPL v2"); |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview |
| 3 | 3 | // I2C address is always 0xC0. |
| 4 | 4 | // |
| 5 | −// Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) | |
| 5 | +// Copyright (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | // |
| 7 | 7 | // tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa |
| 8 | 8 | // from their contributions on DScaler. |
| @@ -469,5 +469,5 @@ EXPORT_SYMBOL_GPL(tea5767_attach); · 460 unmodified lines | ||
| 469 | 469 | EXPORT_SYMBOL_GPL(tea5767_autodetection); |
| 470 | 470 | |
| 471 | 471 | MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver"); |
| 472 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 472 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 473 | 473 | MODULE_LICENSE("GPL v2"); |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * This file includes internal tipes to be used inside tuner-xc2028. |
| 6 | 6 | * Shouldn't be included outside tuner-xc2028 |
| 7 | 7 | * |
| 8 | − * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | |
| 8 | + * Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | 11 | /* xc3028 firmware types */ |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | // tuner-xc2028 |
| 3 | 3 | // |
| 4 | −// Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | |
| 4 | +// Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | // |
| 6 | 6 | // Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com) |
| 7 | 7 | // - frontend interface |
| @@ -1518,7 +1518,7 @@ EXPORT_SYMBOL(xc2028_attach); · 1510 unmodified lines | ||
| 1518 | 1518 | |
| 1519 | 1519 | MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver"); |
| 1520 | 1520 | MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>"); |
| 1521 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 1521 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 1522 | 1522 | MODULE_LICENSE("GPL v2"); |
| 1523 | 1523 | MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE); |
| 1524 | 1524 | MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE); |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | * tuner-xc2028 |
| 4 | 4 | * |
| 5 | − * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) | |
| 5 | + * Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #ifndef __TUNER_XC2028_H__ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // |
| 3 | 3 | // em28xx-camera.c - driver for Empia EM25xx/27xx/28xx USB video capture devices |
| 4 | 4 | // |
| 5 | −// Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | +// Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 7 | 7 | // |
| 8 | 8 | // This program is free software; you can redistribute it and/or modify |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | // |
| 6 | 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 7 | 7 | // Markus Rechberger <mrechberger@gmail.com> |
| 8 | −// Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 8 | +// Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 9 | 9 | // Sascha Sommer <saschasommer@freenet.de> |
| 10 | 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 11 | 11 | // |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | // |
| 5 | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 6 | 6 | // Markus Rechberger <mrechberger@gmail.com> |
| 7 | −// Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 7 | +// Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 8 | 8 | // Sascha Sommer <saschasommer@freenet.de> |
| 9 | 9 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 10 | 10 | // |
| @@ -32,7 +32,7 @@ · 21 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
| 34 | 34 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
| 35 | − "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | |
| 35 | + "Mauro Carvalho Chehab <mchehab@kernel.org>, " \ | |
| 36 | 36 | "Sascha Sommer <saschasommer@freenet.de>" |
| 37 | 37 | |
| 38 | 38 | MODULE_AUTHOR(DRIVER_AUTHOR); |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // |
| 3 | 3 | // DVB device driver for em28xx |
| 4 | 4 | // |
| 5 | −// (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | +// (c) 2008-2011 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | // |
| 7 | 7 | // (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> |
| 8 | 8 | // - Fixes for the driver to properly work with HVR-950 |
| @@ -63,7 +63,7 @@ · 54 unmodified lines | ||
| 63 | 63 | #include "tc90522.h" |
| 64 | 64 | #include "qm1d1c0042.h" |
| 65 | 65 | |
| 66 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 66 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 67 | 67 | MODULE_LICENSE("GPL v2"); |
| 68 | 68 | MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface"); |
| 69 | 69 | MODULE_VERSION(EM28XX_VERSION); |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | // |
| 5 | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 6 | 6 | // Markus Rechberger <mrechberger@gmail.com> |
| 7 | −// Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 7 | +// Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 8 | 8 | // Sascha Sommer <saschasommer@freenet.de> |
| 9 | 9 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 10 | 10 | // |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | // |
| 5 | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 6 | 6 | // Markus Rechberger <mrechberger@gmail.com> |
| 7 | −// Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 7 | +// Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 8 | 8 | // Sascha Sommer <saschasommer@freenet.de> |
| 9 | 9 | // |
| 10 | 10 | // This program is free software; you can redistribute it and/or modify |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | // |
| 6 | 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
| 7 | 7 | // Markus Rechberger <mrechberger@gmail.com> |
| 8 | −// Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 8 | +// Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 9 | 9 | // Sascha Sommer <saschasommer@freenet.de> |
| 10 | 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 11 | 11 | // |
| @@ -44,7 +44,7 @@ · 32 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
| 46 | 46 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
| 47 | − "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | |
| 47 | + "Mauro Carvalho Chehab <mchehab@kernel.org>, " \ | |
| 48 | 48 | "Sascha Sommer <saschasommer@freenet.de>" |
| 49 | 49 | |
| 50 | 50 | static unsigned int isoc_debug; |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * |
| 5 | 5 | * Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> |
| 6 | 6 | * Ludovico Cavedon <cavedon@sssup.it> |
| 7 | − * Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 7 | + * Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 8 | 8 | * Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
| 9 | 9 | * |
| 10 | 10 | * Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * zc030x registers |
| 3 | 3 | * |
| 4 | − * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 4 | + * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | * |
| 6 | 6 | * The register aliases used here came from this driver: |
| 7 | 7 | * http://zc0302.sourceforge.net/zc0302.php |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | // tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | 3 | // |
| 4 | −// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 4 | +// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | |
| 6 | 6 | #include <linux/init.h> |
| 7 | 7 | #include <linux/module.h> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | // tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | 3 | // |
| 4 | −// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 4 | +// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | // |
| 6 | 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 7 | 7 | // - DVB-T support |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | // tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | 3 | // |
| 4 | −// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 4 | +// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | // |
| 6 | 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 7 | 7 | // - Fix SMBus Read Byte command |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 4 | 4 | * |
| 5 | − * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | + * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | /* |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 4 | 4 | * |
| 5 | − * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | + * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include <linux/videodev2.h> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | // tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 3 | 3 | // |
| 4 | −// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 4 | +// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 5 | 5 | // |
| 6 | 6 | // Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 7 | 7 | // - Fixed module load/unload |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices |
| 4 | 4 | * |
| 5 | − * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | |
| 5 | + * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> | |
| 6 | 6 | * |
| 7 | 7 | * Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com> |
| 8 | 8 | * - DVB-T support |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | * 2 of the License, or (at your option) any later version. |
| 11 | 11 | * |
| 12 | 12 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
| 13 | − * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) | |
| 13 | + * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) | |
| 14 | 14 | * |
| 15 | 15 | * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com> |
| 16 | 16 | * - Added procfs support |
| @@ -1079,7 +1079,7 @@ static void __exit videodev_exit(void) · 1062 unmodified lines | ||
| 1079 | 1079 | subsys_initcall(videodev_init); |
| 1080 | 1080 | module_exit(videodev_exit) |
| 1081 | 1081 | |
| 1082 | −MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 1082 | +MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 1083 | 1083 | MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); |
| 1084 | 1084 | MODULE_LICENSE("GPL"); |
| 1085 | 1085 | MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR); |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | * 2 of the License, or (at your option) any later version. |
| 10 | 10 | * |
| 11 | 11 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
| 12 | − * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) | |
| 12 | + * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) | |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | 15 | #include <linux/mm.h> |
| @@ -1,11 +1,11 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * generic helper functions for handling video4linux capture buffers |
| 3 | 3 | * |
| 4 | − * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | |
| 4 | + * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> | |
| 5 | 5 | * |
| 6 | 6 | * Highly based on video-buf written originally by: |
| 7 | 7 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> |
| 8 | − * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org> | |
| 8 | + * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org> | |
| 9 | 9 | * (c) 2006 Ted Walther and John Sokol |
| 10 | 10 | * |
| 11 | 11 | * This program is free software; you can redistribute it and/or modify |
| @@ -38,7 +38,7 @@ static int debug; · 26 unmodified lines | ||
| 38 | 38 | module_param(debug, int, 0644); |
| 39 | 39 | |
| 40 | 40 | MODULE_DESCRIPTION("helper module to manage video4linux buffers"); |
| 41 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 41 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 42 | 42 | MODULE_LICENSE("GPL"); |
| 43 | 43 | |
| 44 | 44 | #define dprintk(level, fmt, arg...) \ |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * Copyright (c) 2008 Magnus Damm |
| 8 | 8 | * |
| 9 | 9 | * Based on videobuf-vmalloc.c, |
| 10 | − * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | |
| 10 | + * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> | |
| 11 | 11 | * |
| 12 | 12 | * This program is free software; you can redistribute it and/or modify |
| 13 | 13 | * it under the terms of the GNU General Public License as published by |
| @@ -6,11 +6,11 @@ · 5 unmodified lines | ||
| 6 | 6 | * into PAGE_SIZE chunks). They also assume the driver does not need |
| 7 | 7 | * to touch the video data. |
| 8 | 8 | * |
| 9 | − * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | |
| 9 | + * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> | |
| 10 | 10 | * |
| 11 | 11 | * Highly based on video-buf written originally by: |
| 12 | 12 | * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> |
| 13 | − * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org> | |
| 13 | + * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org> | |
| 14 | 14 | * (c) 2006 Ted Walther and John Sokol |
| 15 | 15 | * |
| 16 | 16 | * This program is free software; you can redistribute it and/or modify |
| @@ -48,7 +48,7 @@ static int debug; · 31 unmodified lines | ||
| 48 | 48 | module_param(debug, int, 0644); |
| 49 | 49 | |
| 50 | 50 | MODULE_DESCRIPTION("helper module to manage video4linux dma sg buffers"); |
| 51 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 51 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 52 | 52 | MODULE_LICENSE("GPL"); |
| 53 | 53 | |
| 54 | 54 | #define dprintk(level, fmt, arg...) \ |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * into PAGE_SIZE chunks). They also assume the driver does not need |
| 7 | 7 | * to touch the video data. |
| 8 | 8 | * |
| 9 | − * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org> | |
| 9 | + * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org> | |
| 10 | 10 | * |
| 11 | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | 12 | * it under the terms of the GNU General Public License as published by |
| @@ -41,7 +41,7 @@ static int debug; · 28 unmodified lines | ||
| 41 | 41 | module_param(debug, int, 0644); |
| 42 | 42 | |
| 43 | 43 | MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers"); |
| 44 | −MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | |
| 44 | +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); | |
| 45 | 45 | MODULE_LICENSE("GPL"); |
| 46 | 46 | |
| 47 | 47 | #define dprintk(level, fmt, arg...) \ |
| @@ -16,77 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | int main(void) |
| 18 | 18 | { |
| 19 | − DEFINE(EMIF_SDCFG_VAL_OFFSET, | |
| 20 | − offsetof(struct emif_regs_amx3, emif_sdcfg_val)); | |
| 21 | − DEFINE(EMIF_TIMING1_VAL_OFFSET, | |
| 22 | − offsetof(struct emif_regs_amx3, emif_timing1_val)); | |
| 23 | − DEFINE(EMIF_TIMING2_VAL_OFFSET, | |
| 24 | − offsetof(struct emif_regs_amx3, emif_timing2_val)); | |
| 25 | − DEFINE(EMIF_TIMING3_VAL_OFFSET, | |
| 26 | − offsetof(struct emif_regs_amx3, emif_timing3_val)); | |
| 27 | − DEFINE(EMIF_REF_CTRL_VAL_OFFSET, | |
| 28 | − offsetof(struct emif_regs_amx3, emif_ref_ctrl_val)); | |
| 29 | − DEFINE(EMIF_ZQCFG_VAL_OFFSET, | |
| 30 | − offsetof(struct emif_regs_amx3, emif_zqcfg_val)); | |
| 31 | − DEFINE(EMIF_PMCR_VAL_OFFSET, | |
| 32 | − offsetof(struct emif_regs_amx3, emif_pmcr_val)); | |
| 33 | − DEFINE(EMIF_PMCR_SHDW_VAL_OFFSET, | |
| 34 | − offsetof(struct emif_regs_amx3, emif_pmcr_shdw_val)); | |
| 35 | − DEFINE(EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET, | |
| 36 | − offsetof(struct emif_regs_amx3, emif_rd_wr_level_ramp_ctrl)); | |
| 37 | − DEFINE(EMIF_RD_WR_EXEC_THRESH_OFFSET, | |
| 38 | − offsetof(struct emif_regs_amx3, emif_rd_wr_exec_thresh)); | |
| 39 | − DEFINE(EMIF_COS_CONFIG_OFFSET, | |
| 40 | − offsetof(struct emif_regs_amx3, emif_cos_config)); | |
| 41 | − DEFINE(EMIF_PRIORITY_TO_COS_MAPPING_OFFSET, | |
| 42 | − offsetof(struct emif_regs_amx3, emif_priority_to_cos_mapping)); | |
| 43 | − DEFINE(EMIF_CONNECT_ID_SERV_1_MAP_OFFSET, | |
| 44 | − offsetof(struct emif_regs_amx3, emif_connect_id_serv_1_map)); | |
| 45 | − DEFINE(EMIF_CONNECT_ID_SERV_2_MAP_OFFSET, | |
| 46 | − offsetof(struct emif_regs_amx3, emif_connect_id_serv_2_map)); | |
| 47 | − DEFINE(EMIF_OCP_CONFIG_VAL_OFFSET, | |
| 48 | − offsetof(struct emif_regs_amx3, emif_ocp_config_val)); | |
| 49 | − DEFINE(EMIF_LPDDR2_NVM_TIM_OFFSET, | |
| 50 | − offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim)); | |
| 51 | − DEFINE(EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET, | |
| 52 | − offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim_shdw)); | |
| 53 | − DEFINE(EMIF_DLL_CALIB_CTRL_VAL_OFFSET, | |
| 54 | − offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val)); | |
| 55 | − DEFINE(EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET, | |
| 56 | − offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val_shdw)); | |
| 57 | − DEFINE(EMIF_DDR_PHY_CTLR_1_OFFSET, | |
| 58 | − offsetof(struct emif_regs_amx3, emif_ddr_phy_ctlr_1)); | |
| 59 | − DEFINE(EMIF_EXT_PHY_CTRL_VALS_OFFSET, | |
| 60 | − offsetof(struct emif_regs_amx3, emif_ext_phy_ctrl_vals)); | |
| 61 | − DEFINE(EMIF_REGS_AMX3_SIZE, sizeof(struct emif_regs_amx3)); | |
| 62 | − | |
| 63 | − BLANK(); | |
| 64 | − | |
| 65 | − DEFINE(EMIF_PM_BASE_ADDR_VIRT_OFFSET, | |
| 66 | − offsetof(struct ti_emif_pm_data, ti_emif_base_addr_virt)); | |
| 67 | − DEFINE(EMIF_PM_BASE_ADDR_PHYS_OFFSET, | |
| 68 | − offsetof(struct ti_emif_pm_data, ti_emif_base_addr_phys)); | |
| 69 | − DEFINE(EMIF_PM_CONFIG_OFFSET, | |
| 70 | − offsetof(struct ti_emif_pm_data, ti_emif_sram_config)); | |
| 71 | − DEFINE(EMIF_PM_REGS_VIRT_OFFSET, | |
| 72 | − offsetof(struct ti_emif_pm_data, regs_virt)); | |
| 73 | − DEFINE(EMIF_PM_REGS_PHYS_OFFSET, | |
| 74 | − offsetof(struct ti_emif_pm_data, regs_phys)); | |
| 75 | − DEFINE(EMIF_PM_DATA_SIZE, sizeof(struct ti_emif_pm_data)); | |
| 76 | − | |
| 77 | − BLANK(); | |
| 78 | − | |
| 79 | − DEFINE(EMIF_PM_SAVE_CONTEXT_OFFSET, | |
| 80 | − offsetof(struct ti_emif_pm_functions, save_context)); | |
| 81 | − DEFINE(EMIF_PM_RESTORE_CONTEXT_OFFSET, | |
| 82 | − offsetof(struct ti_emif_pm_functions, restore_context)); | |
| 83 | − DEFINE(EMIF_PM_ENTER_SR_OFFSET, | |
| 84 | − offsetof(struct ti_emif_pm_functions, enter_sr)); | |
| 85 | − DEFINE(EMIF_PM_EXIT_SR_OFFSET, | |
| 86 | − offsetof(struct ti_emif_pm_functions, exit_sr)); | |
| 87 | − DEFINE(EMIF_PM_ABORT_SR_OFFSET, | |
| 88 | − offsetof(struct ti_emif_pm_functions, abort_sr)); | |
| 89 | − DEFINE(EMIF_PM_FUNCTIONS_SIZE, sizeof(struct ti_emif_pm_functions)); | |
| 19 | + ti_emif_asm_offsets(); | |
| 90 | 20 | |
| 91 | 21 | return 0; |
| 92 | 22 | } |
| @@ -1994,6 +1994,7 @@ static struct scsi_host_template mptsas_driver_template = { · 1993 unmodified lines | ||
| 1994 | 1994 | .cmd_per_lun = 7, |
| 1995 | 1995 | .use_clustering = ENABLE_CLUSTERING, |
| 1996 | 1996 | .shost_attrs = mptscsih_host_attrs, |
| 1997 | + .no_write_same = 1, | |
| 1997 | 1998 | }; |
| 1998 | 1999 | |
| 1999 | 2000 | static int mptsas_get_linkerrors(struct sas_phy *phy) |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | * published by the Free Software Foundation. |
| 10 | 10 | */ |
| 11 | 11 | |
| 12 | +#include <linux/bitops.h> | |
| 12 | 13 | #include <linux/device.h> |
| 13 | 14 | #include <linux/dma-mapping.h> |
| 14 | 15 | #include <linux/io-64-nonatomic-hi-lo.h> |
| @@ -62,6 +63,17 @@ · 47 unmodified lines | ||
| 62 | 63 | * need a custom accessor. |
| 63 | 64 | */ |
| 64 | 65 | |
| 66 | +static unsigned long global_flags; | |
| 67 | +/* | |
| 68 | + * Workaround for avoiding to use RX DMAC by multiple channels. | |
| 69 | + * On R-Car H3 ES1.* and M3-W ES1.0, when multiple SDHI channels use | |
| 70 | + * RX DMAC simultaneously, sometimes hundreds of bytes data are not | |
| 71 | + * stored into the system memory even if the DMAC interrupt happened. | |
| 72 | + * So, this driver then uses one RX DMAC channel only. | |
| 73 | + */ | |
| 74 | +#define SDHI_INTERNAL_DMAC_ONE_RX_ONLY 0 | |
| 75 | +#define SDHI_INTERNAL_DMAC_RX_IN_USE 1 | |
| 76 | + | |
| 65 | 77 | /* Definitions for sampling clocks */ |
| 66 | 78 | static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = { |
| 67 | 79 | { |
| @@ -126,6 +138,9 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) { · 58 unmodified lines | ||
| 126 | 138 | renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST, |
| 127 | 139 | RST_RESERVED_BITS | val); |
| 128 | 140 | |
| 141 | + if (host->data && host->data->flags & MMC_DATA_READ) | |
| 142 | + clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags); | |
| 143 | + | |
| 129 | 144 | renesas_sdhi_internal_dmac_enable_dma(host, true); |
| 130 | 145 | } |
| 131 | 146 | |
| @@ -155,6 +170,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, · 23 unmodified lines | ||
| 155 | 170 | if (data->flags & MMC_DATA_READ) { |
| 156 | 171 | dtran_mode |= DTRAN_MODE_CH_NUM_CH1; |
| 157 | 172 | dir = DMA_FROM_DEVICE; |
| 173 | + if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && | |
| 174 | + test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) | |
| 175 | + goto force_pio; | |
| 158 | 176 | } else { |
| 159 | 177 | dtran_mode |= DTRAN_MODE_CH_NUM_CH0; |
| 160 | 178 | dir = DMA_TO_DEVICE; |
| @@ -208,6 +226,9 @@ static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg) · 47 unmodified lines | ||
| 208 | 226 | renesas_sdhi_internal_dmac_enable_dma(host, false); |
| 209 | 227 | dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->sg_len, dir); |
| 210 | 228 | |
| 229 | + if (dir == DMA_FROM_DEVICE) | |
| 230 | + clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags); | |
| 231 | + | |
| 211 | 232 | tmio_mmc_do_data_irq(host); |
| 212 | 233 | out: |
| 213 | 234 | spin_unlock_irq(&host->lock); |
| @@ -251,18 +272,24 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = { · 37 unmodified lines | ||
| 251 | 272 | * implementation as others may use a different implementation. |
| 252 | 273 | */ |
| 253 | 274 | static const struct soc_device_attribute gen3_soc_whitelist[] = { |
| 254 | − { .soc_id = "r8a7795", .revision = "ES1.*" }, | |
| 255 | − { .soc_id = "r8a7795", .revision = "ES2.0" }, | |
| 256 | − { .soc_id = "r8a7796", .revision = "ES1.0" }, | |
| 257 | − { .soc_id = "r8a77995", .revision = "ES1.0" }, | |
| 258 | − { /* sentinel */ } | |
| 275 | + { .soc_id = "r8a7795", .revision = "ES1.*", | |
| 276 | + .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, | |
| 277 | + { .soc_id = "r8a7795", .revision = "ES2.0" }, | |
| 278 | + { .soc_id = "r8a7796", .revision = "ES1.0", | |
| 279 | + .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, | |
| 280 | + { .soc_id = "r8a77995", .revision = "ES1.0" }, | |
| 281 | + { /* sentinel */ } | |
| 259 | 282 | }; |
| 260 | 283 | |
| 261 | 284 | static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev) |
| 262 | 285 | { |
| 263 | − if (!soc_device_match(gen3_soc_whitelist)) | |
| 286 | + const struct soc_device_attribute *soc = soc_device_match(gen3_soc_whitelist); | |
| 287 | + | |
| 288 | + if (!soc) | |
| 264 | 289 | return -ENODEV; |
| 265 | 290 | |
| 291 | + global_flags |= (unsigned long)soc->data; | |
| 292 | + | |
| 266 | 293 | return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops); |
| 267 | 294 | } |
| 268 | 295 | |
| @@ -1312,7 +1312,7 @@ static void amd_enable_manual_tuning(struct pci_dev *pdev) · 1311 unmodified lines | ||
| 1312 | 1312 | pci_write_config_dword(pdev, AMD_SD_MISC_CONTROL, val); |
| 1313 | 1313 | } |
| 1314 | 1314 | |
| 1315 | −static int amd_execute_tuning(struct sdhci_host *host, u32 opcode) | |
| 1315 | +static int amd_execute_tuning_hs200(struct sdhci_host *host, u32 opcode) | |
| 1316 | 1316 | { |
| 1317 | 1317 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
| 1318 | 1318 | struct pci_dev *pdev = slot->chip->pdev; |
| @@ -1351,6 +1351,27 @@ static int amd_execute_tuning(struct sdhci_host *host, u32 opcode) · 32 unmodified lines | ||
| 1351 | 1351 | return 0; |
| 1352 | 1352 | } |
| 1353 | 1353 | |
| 1354 | +static int amd_execute_tuning(struct mmc_host *mmc, u32 opcode) | |
| 1355 | +{ | |
| 1356 | + struct sdhci_host *host = mmc_priv(mmc); | |
| 1357 | + | |
| 1358 | + /* AMD requires custom HS200 tuning */ | |
| 1359 | + if (host->timing == MMC_TIMING_MMC_HS200) | |
| 1360 | + return amd_execute_tuning_hs200(host, opcode); | |
| 1361 | + | |
| 1362 | + /* Otherwise perform standard SDHCI tuning */ | |
| 1363 | + return sdhci_execute_tuning(mmc, opcode); | |
| 1364 | +} | |
| 1365 | + | |
| 1366 | +static int amd_probe_slot(struct sdhci_pci_slot *slot) | |
| 1367 | +{ | |
| 1368 | + struct mmc_host_ops *ops = &slot->host->mmc_host_ops; | |
| 1369 | + | |
| 1370 | + ops->execute_tuning = amd_execute_tuning; | |
| 1371 | + | |
| 1372 | + return 0; | |
| 1373 | +} | |
| 1374 | + | |
| 1354 | 1375 | static int amd_probe(struct sdhci_pci_chip *chip) |
| 1355 | 1376 | { |
| 1356 | 1377 | struct pci_dev *smbus_dev; |
| @@ -1385,12 +1406,12 @@ static const struct sdhci_ops amd_sdhci_pci_ops = { · 28 unmodified lines | ||
| 1385 | 1406 | .set_bus_width = sdhci_set_bus_width, |
| 1386 | 1407 | .reset = sdhci_reset, |
| 1387 | 1408 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 1388 | − .platform_execute_tuning = amd_execute_tuning, | |
| 1389 | 1409 | }; |
| 1390 | 1410 | |
| 1391 | 1411 | static const struct sdhci_pci_fixes sdhci_amd = { |
| 1392 | 1412 | .probe = amd_probe, |
| 1393 | 1413 | .ops = &amd_sdhci_pci_ops, |
| 1414 | + .probe_slot = amd_probe_slot, | |
| 1394 | 1415 | }; |
| 1395 | 1416 | |
| 1396 | 1417 | static const struct pci_device_id pci_ids[] = { |
| @@ -45,6 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | #define I82802AB 0x00ad |
| 46 | 46 | #define I82802AC 0x00ac |
| 47 | 47 | #define PF38F4476 0x881c |
| 48 | +#define M28F00AP30 0x8963 | |
| 48 | 49 | /* STMicroelectronics chips */ |
| 49 | 50 | #define M50LPW080 0x002F |
| 50 | 51 | #define M50FLW080A 0x0080 |
| @@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi, · 324 unmodified lines | ||
| 375 | 376 | extp->MinorVersion = '1'; |
| 376 | 377 | } |
| 377 | 378 | |
| 379 | +static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip) | |
| 380 | +{ | |
| 381 | + /* | |
| 382 | + * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t | |
| 383 | + * Erase Supend for their small Erase Blocks(0x8000) | |
| 384 | + */ | |
| 385 | + if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30) | |
| 386 | + return 1; | |
| 387 | + return 0; | |
| 388 | +} | |
| 389 | + | |
| 378 | 390 | static inline struct cfi_pri_intelext * |
| 379 | 391 | read_pri_intelext(struct map_info *map, __u16 adr) |
| 380 | 392 | { |
| @@ -831,21 +843,30 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long · 450 unmodified lines | ||
| 831 | 843 | (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) |
| 832 | 844 | goto sleep; |
| 833 | 845 | |
| 846 | + /* Do not allow suspend iff read/write to EB address */ | |
| 847 | + if ((adr & chip->in_progress_block_mask) == | |
| 848 | + chip->in_progress_block_addr) | |
| 849 | + goto sleep; | |
| 850 | + | |
| 851 | + /* do not suspend small EBs, buggy Micron Chips */ | |
| 852 | + if (cfi_is_micron_28F00AP30(cfi, chip) && | |
| 853 | + (chip->in_progress_block_mask == ~(0x8000-1))) | |
| 854 | + goto sleep; | |
| 834 | 855 | |
| 835 | 856 | /* Erase suspend */ |
| 836 | − map_write(map, CMD(0xB0), adr); | |
| 857 | + map_write(map, CMD(0xB0), chip->in_progress_block_addr); | |
| 837 | 858 | |
| 838 | 859 | /* If the flash has finished erasing, then 'erase suspend' |
| 839 | 860 | * appears to make some (28F320) flash devices switch to |
| 840 | 861 | * 'read' mode. Make sure that we switch to 'read status' |
| 841 | 862 | * mode so we get the right data. --rmk |
| 842 | 863 | */ |
| 843 | − map_write(map, CMD(0x70), adr); | |
| 864 | + map_write(map, CMD(0x70), chip->in_progress_block_addr); | |
| 844 | 865 | chip->oldstate = FL_ERASING; |
| 845 | 866 | chip->state = FL_ERASE_SUSPENDING; |
| 846 | 867 | chip->erase_suspended = 1; |
| 847 | 868 | for (;;) { |
| 848 | − status = map_read(map, adr); | |
| 869 | + status = map_read(map, chip->in_progress_block_addr); | |
| 849 | 870 | if (map_word_andequal(map, status, status_OK, status_OK)) |
| 850 | 871 | break; |
| 851 | 872 | |
| @@ -1041,8 +1062,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad · 189 unmodified lines | ||
| 1041 | 1062 | sending the 0x70 (Read Status) command to an erasing |
| 1042 | 1063 | chip and expecting it to be ignored, that's what we |
| 1043 | 1064 | do. */ |
| 1044 | − map_write(map, CMD(0xd0), adr); | |
| 1045 | − map_write(map, CMD(0x70), adr); | |
| 1065 | + map_write(map, CMD(0xd0), chip->in_progress_block_addr); | |
| 1066 | + map_write(map, CMD(0x70), chip->in_progress_block_addr); | |
| 1046 | 1067 | chip->oldstate = FL_READY; |
| 1047 | 1068 | chip->state = FL_ERASING; |
| 1048 | 1069 | break; |
| @@ -1933,6 +1954,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, · 884 unmodified lines | ||
| 1933 | 1954 | map_write(map, CMD(0xD0), adr); |
| 1934 | 1955 | chip->state = FL_ERASING; |
| 1935 | 1956 | chip->erase_suspended = 0; |
| 1957 | + chip->in_progress_block_addr = adr; | |
| 1958 | + chip->in_progress_block_mask = ~(len - 1); | |
| 1936 | 1959 | |
| 1937 | 1960 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
| 1938 | 1961 | adr, len, |
| @@ -816,9 +816,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr · 815 unmodified lines | ||
| 816 | 816 | (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) |
| 817 | 817 | goto sleep; |
| 818 | 818 | |
| 819 | − /* We could check to see if we're trying to access the sector | |
| 820 | − * that is currently being erased. However, no user will try | |
| 821 | − * anything like that so we just wait for the timeout. */ | |
| 819 | + /* Do not allow suspend iff read/write to EB address */ | |
| 820 | + if ((adr & chip->in_progress_block_mask) == | |
| 821 | + chip->in_progress_block_addr) | |
| 822 | + goto sleep; | |
| 822 | 823 | |
| 823 | 824 | /* Erase suspend */ |
| 824 | 825 | /* It's harmless to issue the Erase-Suspend and Erase-Resume |
| @@ -2267,6 +2268,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) · 1442 unmodified lines | ||
| 2267 | 2268 | chip->state = FL_ERASING; |
| 2268 | 2269 | chip->erase_suspended = 0; |
| 2269 | 2270 | chip->in_progress_block_addr = adr; |
| 2271 | + chip->in_progress_block_mask = ~(map->size - 1); | |
| 2270 | 2272 | |
| 2271 | 2273 | INVALIDATE_CACHE_UDELAY(map, chip, |
| 2272 | 2274 | adr, map->size, |
| @@ -2356,6 +2358,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, · 83 unmodified lines | ||
| 2356 | 2358 | chip->state = FL_ERASING; |
| 2357 | 2359 | chip->erase_suspended = 0; |
| 2358 | 2360 | chip->in_progress_block_addr = adr; |
| 2361 | + chip->in_progress_block_mask = ~(len - 1); | |
| 2359 | 2362 | |
| 2360 | 2363 | INVALIDATE_CACHE_UDELAY(map, chip, |
| 2361 | 2364 | adr, len, |
| @@ -162,7 +162,6 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) · 161 unmodified lines | ||
| 162 | 162 | ret = nanddev_erase(nand, &pos); |
| 163 | 163 | if (ret) { |
| 164 | 164 | einfo->fail_addr = nanddev_pos_to_offs(nand, &pos); |
| 165 | − einfo->state = MTD_ERASE_FAILED; | |
| 166 | 165 | |
| 167 | 166 | return ret; |
| 168 | 167 | } |
| @@ -170,8 +169,6 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) · 1 unmodified line | ||
| 170 | 169 | nanddev_pos_next_eraseblock(nand, &pos); |
| 171 | 170 | } |
| 172 | 171 | |
| 173 | − einfo->state = MTD_ERASE_DONE; | |
| 174 | − | |
| 175 | 172 | return 0; |
| 176 | 173 | } |
| 177 | 174 | EXPORT_SYMBOL_GPL(nanddev_mtd_erase); |
| @@ -2299,29 +2299,20 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, · 2298 unmodified lines | ||
| 2299 | 2299 | /* |
| 2300 | 2300 | * The legacy "num-cs" property indicates the number of CS on the only |
| 2301 | 2301 | * chip connected to the controller (legacy bindings does not support |
| 2302 | − * more than one chip). CS are only incremented one by one while the RB | |
| 2303 | − * pin is always the #0. | |
| 2302 | + * more than one chip). The CS and RB pins are always the #0. | |
| 2304 | 2303 | * |
| 2305 | 2304 | * When not using legacy bindings, a couple of "reg" and "nand-rb" |
| 2306 | 2305 | * properties must be filled. For each chip, expressed as a subnode, |
| 2307 | 2306 | * "reg" points to the CS lines and "nand-rb" to the RB line. |
| 2308 | 2307 | */ |
| 2309 | − if (pdata) { | |
| 2308 | + if (pdata || nfc->caps->legacy_of_bindings) { | |
| 2310 | 2309 | nsels = 1; |
| 2311 | − } else if (nfc->caps->legacy_of_bindings && | |
| 2312 | − !of_get_property(np, "num-cs", &nsels)) { | |
| 2313 | − dev_err(dev, "missing num-cs property\n"); | |
| 2314 | − return -EINVAL; | |
| 2315 | − } else if (!of_get_property(np, "reg", &nsels)) { | |
| 2316 | − dev_err(dev, "missing reg property\n"); | |
| 2317 | − return -EINVAL; | |
| 2318 | − } | |
| 2319 | − | |
| 2320 | − if (!pdata) | |
| 2321 | − nsels /= sizeof(u32); | |
| 2322 | − if (!nsels) { | |
| 2323 | − dev_err(dev, "invalid reg property size\n"); | |
| 2324 | − return -EINVAL; | |
| 2310 | + } else { | |
| 2311 | + nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32)); | |
| 2312 | + if (nsels <= 0) { | |
| 2313 | + dev_err(dev, "missing/invalid reg property\n"); | |
| 2314 | + return -EINVAL; | |
| 2315 | + } | |
| 2325 | 2316 | } |
| 2326 | 2317 | |
| 2327 | 2318 | /* Alloc the nand chip structure */ |
| @@ -645,7 +645,7 @@ static int tango_nand_probe(struct platform_device *pdev) · 644 unmodified lines | ||
| 645 | 645 | |
| 646 | 646 | writel_relaxed(MODE_RAW, nfc->pbus_base + PBUS_PAD_MODE); |
| 647 | 647 | |
| 648 | − clk = clk_get(&pdev->dev, NULL); | |
| 648 | + clk = devm_clk_get(&pdev->dev, NULL); | |
| 649 | 649 | if (IS_ERR(clk)) |
| 650 | 650 | return PTR_ERR(clk); |
| 651 | 651 | |
| @@ -501,7 +501,9 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf, · 500 unmodified lines | ||
| 501 | 501 | void __iomem *reg_base = cqspi->iobase; |
| 502 | 502 | void __iomem *ahb_base = cqspi->ahb_base; |
| 503 | 503 | unsigned int remaining = n_rx; |
| 504 | + unsigned int mod_bytes = n_rx % 4; | |
| 504 | 505 | unsigned int bytes_to_read = 0; |
| 506 | + u8 *rxbuf_end = rxbuf + n_rx; | |
| 505 | 507 | int ret = 0; |
| 506 | 508 | |
| 507 | 509 | writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR); |
| @@ -530,11 +532,24 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf, · 22 unmodified lines | ||
| 530 | 532 | } |
| 531 | 533 | |
| 532 | 534 | while (bytes_to_read != 0) { |
| 535 | + unsigned int word_remain = round_down(remaining, 4); | |
| 536 | + | |
| 533 | 537 | bytes_to_read *= cqspi->fifo_width; |
| 534 | 538 | bytes_to_read = bytes_to_read > remaining ? |
| 535 | 539 | remaining : bytes_to_read; |
| 536 | − ioread32_rep(ahb_base, rxbuf, | |
| 537 | − DIV_ROUND_UP(bytes_to_read, 4)); | |
| 540 | + bytes_to_read = round_down(bytes_to_read, 4); | |
| 541 | + /* Read 4 byte word chunks then single bytes */ | |
| 542 | + if (bytes_to_read) { | |
| 543 | + ioread32_rep(ahb_base, rxbuf, | |
| 544 | + (bytes_to_read / 4)); | |
| 545 | + } else if (!word_remain && mod_bytes) { | |
| 546 | + unsigned int temp = ioread32(ahb_base); | |
| 547 | + | |
| 548 | + bytes_to_read = mod_bytes; | |
| 549 | + memcpy(rxbuf, &temp, min((unsigned int) | |
| 550 | + (rxbuf_end - rxbuf), | |
| 551 | + bytes_to_read)); | |
| 552 | + } | |
| 538 | 553 | rxbuf += bytes_to_read; |
| 539 | 554 | remaining -= bytes_to_read; |
| 540 | 555 | bytes_to_read = cqspi_get_rd_sram_level(cqspi); |
| @@ -1660,8 +1660,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, · 1659 unmodified lines | ||
| 1660 | 1660 | } /* switch(bond_mode) */ |
| 1661 | 1661 | |
| 1662 | 1662 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 1663 | − slave_dev->npinfo = bond->dev->npinfo; | |
| 1664 | − if (slave_dev->npinfo) { | |
| 1663 | + if (bond->dev->npinfo) { | |
| 1665 | 1664 | if (slave_enable_netpoll(new_slave)) { |
| 1666 | 1665 | netdev_info(bond_dev, "master_dev is using netpoll, but new slave device does not support netpoll\n"); |
| 1667 | 1666 | res = -EBUSY; |
| @@ -285,10 +285,18 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip, · 284 unmodified lines | ||
| 285 | 285 | struct sk_buff_head *rxq) |
| 286 | 286 | { |
| 287 | 287 | u16 buf[4] = { 0 }, status, seq_id; |
| 288 | − u64 ns, timelo, timehi; | |
| 289 | 288 | struct skb_shared_hwtstamps *shwt; |
| 289 | + struct sk_buff_head received; | |
| 290 | + u64 ns, timelo, timehi; | |
| 291 | + unsigned long flags; | |
| 290 | 292 | int err; |
| 291 | 293 | |
| 294 | + /* The latched timestamp belongs to one of the received frames. */ | |
| 295 | + __skb_queue_head_init(&received); | |
| 296 | + spin_lock_irqsave(&rxq->lock, flags); | |
| 297 | + skb_queue_splice_tail_init(rxq, &received); | |
| 298 | + spin_unlock_irqrestore(&rxq->lock, flags); | |
| 299 | + | |
| 292 | 300 | mutex_lock(&chip->reg_lock); |
| 293 | 301 | err = mv88e6xxx_port_ptp_read(chip, ps->port_id, |
| 294 | 302 | reg, buf, ARRAY_SIZE(buf)); |
| @@ -311,7 +319,7 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip, · 16 unmodified lines | ||
| 311 | 319 | /* Since the device can only handle one time stamp at a time, |
| 312 | 320 | * we purge any extra frames from the queue. |
| 313 | 321 | */ |
| 314 | − for ( ; skb; skb = skb_dequeue(rxq)) { | |
| 322 | + for ( ; skb; skb = __skb_dequeue(&received)) { | |
| 315 | 323 | if (mv88e6xxx_ts_valid(status) && seq_match(skb, seq_id)) { |
| 316 | 324 | ns = timehi << 16 | timelo; |
| 317 | 325 | |
| @@ -1321,6 +1321,10 @@ · 1320 unmodified lines | ||
| 1321 | 1321 | #define MDIO_VEND2_AN_STAT 0x8002 |
| 1322 | 1322 | #endif |
| 1323 | 1323 | |
| 1324 | +#ifndef MDIO_VEND2_PMA_CDR_CONTROL | |
| 1325 | +#define MDIO_VEND2_PMA_CDR_CONTROL 0x8056 | |
| 1326 | +#endif | |
| 1327 | + | |
| 1324 | 1328 | #ifndef MDIO_CTRL1_SPEED1G |
| 1325 | 1329 | #define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100) |
| 1326 | 1330 | #endif |
| @@ -1369,6 +1373,10 @@ · 42 unmodified lines | ||
| 1369 | 1373 | #define XGBE_AN_CL37_TX_CONFIG_MASK 0x08 |
| 1370 | 1374 | #define XGBE_AN_CL37_MII_CTRL_8BIT 0x0100 |
| 1371 | 1375 | |
| 1376 | +#define XGBE_PMA_CDR_TRACK_EN_MASK 0x01 | |
| 1377 | +#define XGBE_PMA_CDR_TRACK_EN_OFF 0x00 | |
| 1378 | +#define XGBE_PMA_CDR_TRACK_EN_ON 0x01 | |
| 1379 | + | |
| 1372 | 1380 | /* Bit setting and getting macros |
| 1373 | 1381 | * The get macro will extract the current bit field value from within |
| 1374 | 1382 | * the variable |
| @@ -519,6 +519,22 @@ void xgbe_debugfs_init(struct xgbe_prv_data *pdata) · 518 unmodified lines | ||
| 519 | 519 | "debugfs_create_file failed\n"); |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | + if (pdata->vdata->an_cdr_workaround) { | |
| 523 | + pfile = debugfs_create_bool("an_cdr_workaround", 0600, | |
| 524 | + pdata->xgbe_debugfs, | |
| 525 | + &pdata->debugfs_an_cdr_workaround); | |
| 526 | + if (!pfile) | |
| 527 | + netdev_err(pdata->netdev, | |
| 528 | + "debugfs_create_bool failed\n"); | |
| 529 | + | |
| 530 | + pfile = debugfs_create_bool("an_cdr_track_early", 0600, | |
| 531 | + pdata->xgbe_debugfs, | |
| 532 | + &pdata->debugfs_an_cdr_track_early); | |
| 533 | + if (!pfile) | |
| 534 | + netdev_err(pdata->netdev, | |
| 535 | + "debugfs_create_bool failed\n"); | |
| 536 | + } | |
| 537 | + | |
| 522 | 538 | kfree(buf); |
| 523 | 539 | } |
| 524 | 540 | |
| @@ -349,6 +349,7 @@ int xgbe_config_netdev(struct xgbe_prv_data *pdata) · 348 unmodified lines | ||
| 349 | 349 | XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1); |
| 350 | 350 | |
| 351 | 351 | /* Call MDIO/PHY initialization routine */ |
| 352 | + pdata->debugfs_an_cdr_workaround = pdata->vdata->an_cdr_workaround; | |
| 352 | 353 | ret = pdata->phy_if.phy_init(pdata); |
| 353 | 354 | if (ret) |
| 354 | 355 | return ret; |
| @@ -432,11 +432,16 @@ static void xgbe_an73_disable(struct xgbe_prv_data *pdata) · 431 unmodified lines | ||
| 432 | 432 | xgbe_an73_set(pdata, false, false); |
| 433 | 433 | xgbe_an73_disable_interrupts(pdata); |
| 434 | 434 | |
| 435 | + pdata->an_start = 0; | |
| 436 | + | |
| 435 | 437 | netif_dbg(pdata, link, pdata->netdev, "CL73 AN disabled\n"); |
| 436 | 438 | } |
| 437 | 439 | |
| 438 | 440 | static void xgbe_an_restart(struct xgbe_prv_data *pdata) |
| 439 | 441 | { |
| 442 | + if (pdata->phy_if.phy_impl.an_pre) | |
| 443 | + pdata->phy_if.phy_impl.an_pre(pdata); | |
| 444 | + | |
| 440 | 445 | switch (pdata->an_mode) { |
| 441 | 446 | case XGBE_AN_MODE_CL73: |
| 442 | 447 | case XGBE_AN_MODE_CL73_REDRV: |
| @@ -453,6 +458,9 @@ static void xgbe_an_restart(struct xgbe_prv_data *pdata) · 10 unmodified lines | ||
| 453 | 458 | |
| 454 | 459 | static void xgbe_an_disable(struct xgbe_prv_data *pdata) |
| 455 | 460 | { |
| 461 | + if (pdata->phy_if.phy_impl.an_post) | |
| 462 | + pdata->phy_if.phy_impl.an_post(pdata); | |
| 463 | + | |
| 456 | 464 | switch (pdata->an_mode) { |
| 457 | 465 | case XGBE_AN_MODE_CL73: |
| 458 | 466 | case XGBE_AN_MODE_CL73_REDRV: |
| @@ -505,11 +513,11 @@ static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata, · 46 unmodified lines | ||
| 505 | 513 | XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, |
| 506 | 514 | reg); |
| 507 | 515 | |
| 508 | − if (pdata->phy_if.phy_impl.kr_training_post) | |
| 509 | − pdata->phy_if.phy_impl.kr_training_post(pdata); | |
| 510 | − | |
| 511 | 516 | netif_dbg(pdata, link, pdata->netdev, |
| 512 | 517 | "KR training initiated\n"); |
| 518 | + | |
| 519 | + if (pdata->phy_if.phy_impl.kr_training_post) | |
| 520 | + pdata->phy_if.phy_impl.kr_training_post(pdata); | |
| 513 | 521 | } |
| 514 | 522 | |
| 515 | 523 | return XGBE_AN_PAGE_RECEIVED; |
| @@ -637,11 +645,11 @@ static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata) · 121 unmodified lines | ||
| 637 | 645 | return XGBE_AN_NO_LINK; |
| 638 | 646 | } |
| 639 | 647 | |
| 640 | − xgbe_an73_disable(pdata); | |
| 648 | + xgbe_an_disable(pdata); | |
| 641 | 649 | |
| 642 | 650 | xgbe_switch_mode(pdata); |
| 643 | 651 | |
| 644 | − xgbe_an73_restart(pdata); | |
| 652 | + xgbe_an_restart(pdata); | |
| 645 | 653 | |
| 646 | 654 | return XGBE_AN_INCOMPAT_LINK; |
| 647 | 655 | } |
| @@ -820,6 +828,9 @@ static void xgbe_an37_state_machine(struct xgbe_prv_data *pdata) · 172 unmodified lines | ||
| 820 | 828 | pdata->an_result = pdata->an_state; |
| 821 | 829 | pdata->an_state = XGBE_AN_READY; |
| 822 | 830 | |
| 831 | + if (pdata->phy_if.phy_impl.an_post) | |
| 832 | + pdata->phy_if.phy_impl.an_post(pdata); | |
| 833 | + | |
| 823 | 834 | netif_dbg(pdata, link, pdata->netdev, "CL37 AN result: %s\n", |
| 824 | 835 | xgbe_state_as_string(pdata->an_result)); |
| 825 | 836 | } |
| @@ -903,6 +914,9 @@ again: · 77 unmodified lines | ||
| 903 | 914 | pdata->kx_state = XGBE_RX_BPA; |
| 904 | 915 | pdata->an_start = 0; |
| 905 | 916 | |
| 917 | + if (pdata->phy_if.phy_impl.an_post) | |
| 918 | + pdata->phy_if.phy_impl.an_post(pdata); | |
| 919 | + | |
| 906 | 920 | netif_dbg(pdata, link, pdata->netdev, "CL73 AN result: %s\n", |
| 907 | 921 | xgbe_state_as_string(pdata->an_result)); |
| 908 | 922 | } |
| @@ -456,6 +456,7 @@ static const struct xgbe_version_data xgbe_v2a = { · 455 unmodified lines | ||
| 456 | 456 | .irq_reissue_support = 1, |
| 457 | 457 | .tx_desc_prefetch = 5, |
| 458 | 458 | .rx_desc_prefetch = 5, |
| 459 | + .an_cdr_workaround = 1, | |
| 459 | 460 | }; |
| 460 | 461 | |
| 461 | 462 | static const struct xgbe_version_data xgbe_v2b = { |
| @@ -470,6 +471,7 @@ static const struct xgbe_version_data xgbe_v2b = { · 8 unmodified lines | ||
| 470 | 471 | .irq_reissue_support = 1, |
| 471 | 472 | .tx_desc_prefetch = 5, |
| 472 | 473 | .rx_desc_prefetch = 5, |
| 474 | + .an_cdr_workaround = 1, | |
| 473 | 475 | }; |
| 474 | 476 | |
| 475 | 477 | static const struct pci_device_id xgbe_pci_table[] = { |
| @@ -147,6 +147,14 @@ · 146 unmodified lines | ||
| 147 | 147 | /* Rate-change complete wait/retry count */ |
| 148 | 148 | #define XGBE_RATECHANGE_COUNT 500 |
| 149 | 149 | |
| 150 | +/* CDR delay values for KR support (in usec) */ | |
| 151 | +#define XGBE_CDR_DELAY_INIT 10000 | |
| 152 | +#define XGBE_CDR_DELAY_INC 10000 | |
| 153 | +#define XGBE_CDR_DELAY_MAX 100000 | |
| 154 | + | |
| 155 | +/* RRC frequency during link status check */ | |
| 156 | +#define XGBE_RRC_FREQUENCY 10 | |
| 157 | + | |
| 150 | 158 | enum xgbe_port_mode { |
| 151 | 159 | XGBE_PORT_MODE_RSVD = 0, |
| 152 | 160 | XGBE_PORT_MODE_BACKPLANE, |
| @@ -245,6 +253,10 @@ enum xgbe_sfp_speed { · 92 unmodified lines | ||
| 245 | 253 | #define XGBE_SFP_BASE_VENDOR_SN 4 |
| 246 | 254 | #define XGBE_SFP_BASE_VENDOR_SN_LEN 16 |
| 247 | 255 | |
| 256 | +#define XGBE_SFP_EXTD_OPT1 1 | |
| 257 | +#define XGBE_SFP_EXTD_OPT1_RX_LOS BIT(1) | |
| 258 | +#define XGBE_SFP_EXTD_OPT1_TX_FAULT BIT(3) | |
| 259 | + | |
| 248 | 260 | #define XGBE_SFP_EXTD_DIAG 28 |
| 249 | 261 | #define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2) |
| 250 | 262 | |
| @@ -324,6 +336,7 @@ struct xgbe_phy_data { · 73 unmodified lines | ||
| 324 | 336 | |
| 325 | 337 | unsigned int sfp_gpio_address; |
| 326 | 338 | unsigned int sfp_gpio_mask; |
| 339 | + unsigned int sfp_gpio_inputs; | |
| 327 | 340 | unsigned int sfp_gpio_rx_los; |
| 328 | 341 | unsigned int sfp_gpio_tx_fault; |
| 329 | 342 | unsigned int sfp_gpio_mod_absent; |
| @@ -355,6 +368,10 @@ struct xgbe_phy_data { · 25 unmodified lines | ||
| 355 | 368 | unsigned int redrv_addr; |
| 356 | 369 | unsigned int redrv_lane; |
| 357 | 370 | unsigned int redrv_model; |
| 371 | + | |
| 372 | + /* KR AN support */ | |
| 373 | + unsigned int phy_cdr_notrack; | |
| 374 | + unsigned int phy_cdr_delay; | |
| 358 | 375 | }; |
| 359 | 376 | |
| 360 | 377 | /* I2C, MDIO and GPIO lines are muxed, so only one device at a time */ |
| @@ -974,6 +991,49 @@ static void xgbe_phy_sfp_external_phy(struct xgbe_prv_data *pdata) · 613 unmodified lines | ||
| 974 | 991 | phy_data->sfp_phy_avail = 1; |
| 975 | 992 | } |
| 976 | 993 | |
| 994 | +static bool xgbe_phy_check_sfp_rx_los(struct xgbe_phy_data *phy_data) | |
| 995 | +{ | |
| 996 | + u8 *sfp_extd = phy_data->sfp_eeprom.extd; | |
| 997 | + | |
| 998 | + if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_RX_LOS)) | |
| 999 | + return false; | |
| 1000 | + | |
| 1001 | + if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS) | |
| 1002 | + return false; | |
| 1003 | + | |
| 1004 | + if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_rx_los)) | |
| 1005 | + return true; | |
| 1006 | + | |
| 1007 | + return false; | |
| 1008 | +} | |
| 1009 | + | |
| 1010 | +static bool xgbe_phy_check_sfp_tx_fault(struct xgbe_phy_data *phy_data) | |
| 1011 | +{ | |
| 1012 | + u8 *sfp_extd = phy_data->sfp_eeprom.extd; | |
| 1013 | + | |
| 1014 | + if (!(sfp_extd[XGBE_SFP_EXTD_OPT1] & XGBE_SFP_EXTD_OPT1_TX_FAULT)) | |
| 1015 | + return false; | |
| 1016 | + | |
| 1017 | + if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) | |
| 1018 | + return false; | |
| 1019 | + | |
| 1020 | + if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_tx_fault)) | |
| 1021 | + return true; | |
| 1022 | + | |
| 1023 | + return false; | |
| 1024 | +} | |
| 1025 | + | |
| 1026 | +static bool xgbe_phy_check_sfp_mod_absent(struct xgbe_phy_data *phy_data) | |
| 1027 | +{ | |
| 1028 | + if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT) | |
| 1029 | + return false; | |
| 1030 | + | |
| 1031 | + if (phy_data->sfp_gpio_inputs & (1 << phy_data->sfp_gpio_mod_absent)) | |
| 1032 | + return true; | |
| 1033 | + | |
| 1034 | + return false; | |
| 1035 | +} | |
| 1036 | + | |
| 977 | 1037 | static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata) |
| 978 | 1038 | { |
| 979 | 1039 | struct xgbe_phy_data *phy_data = pdata->phy_data; |
| @@ -1019,6 +1079,10 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata) · 39 unmodified lines | ||
| 1019 | 1079 | if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP) |
| 1020 | 1080 | return; |
| 1021 | 1081 | |
| 1082 | + /* Update transceiver signals (eeprom extd/options) */ | |
| 1083 | + phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data); | |
| 1084 | + phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data); | |
| 1085 | + | |
| 1022 | 1086 | if (xgbe_phy_sfp_parse_quirks(pdata)) |
| 1023 | 1087 | return; |
| 1024 | 1088 | |
| @@ -1184,7 +1248,6 @@ put: · 159 unmodified lines | ||
| 1184 | 1248 | static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata) |
| 1185 | 1249 | { |
| 1186 | 1250 | struct xgbe_phy_data *phy_data = pdata->phy_data; |
| 1187 | − unsigned int gpio_input; | |
| 1188 | 1251 | u8 gpio_reg, gpio_ports[2]; |
| 1189 | 1252 | int ret; |
| 1190 | 1253 | |
| @@ -1199,23 +1262,9 @@ static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata) · 8 unmodified lines | ||
| 1199 | 1262 | return; |
| 1200 | 1263 | } |
| 1201 | 1264 | |
| 1202 | − gpio_input = (gpio_ports[1] << 8) | gpio_ports[0]; | |
| 1203 | − | |
| 1204 | − if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT) { | |
| 1205 | − /* No GPIO, just assume the module is present for now */ | |
| 1206 | − phy_data->sfp_mod_absent = 0; | |
| 1207 | − } else { | |
| 1208 | − if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent))) | |
| 1209 | − phy_data->sfp_mod_absent = 0; | |
| 1210 | − } | |
| 1211 | − | |
| 1212 | − if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS) && | |
| 1213 | − (gpio_input & (1 << phy_data->sfp_gpio_rx_los))) | |
| 1214 | − phy_data->sfp_rx_los = 1; | |
| 1265 | + phy_data->sfp_gpio_inputs = (gpio_ports[1] << 8) | gpio_ports[0]; | |
| 1215 | 1266 | |
| 1216 | − if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) && | |
| 1217 | − (gpio_input & (1 << phy_data->sfp_gpio_tx_fault))) | |
| 1218 | − phy_data->sfp_tx_fault = 1; | |
| 1267 | + phy_data->sfp_mod_absent = xgbe_phy_check_sfp_mod_absent(phy_data); | |
| 1219 | 1268 | } |
| 1220 | 1269 | |
| 1221 | 1270 | static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata) |
| @@ -2361,7 +2410,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) · 1139 unmodified lines | ||
| 2361 | 2410 | return 1; |
| 2362 | 2411 | |
| 2363 | 2412 | /* No link, attempt a receiver reset cycle */ |
| 2364 | − if (phy_data->rrc_count++) { | |
| 2413 | + if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) { | |
| 2365 | 2414 | phy_data->rrc_count = 0; |
| 2366 | 2415 | xgbe_phy_rrc(pdata); |
| 2367 | 2416 | } |
| @@ -2669,6 +2718,103 @@ static bool xgbe_phy_port_enabled(struct xgbe_prv_data *pdata) · 301 unmodified lines | ||
| 2669 | 2718 | return true; |
| 2670 | 2719 | } |
| 2671 | 2720 | |
| 2721 | +static void xgbe_phy_cdr_track(struct xgbe_prv_data *pdata) | |
| 2722 | +{ | |
| 2723 | + struct xgbe_phy_data *phy_data = pdata->phy_data; | |
| 2724 | + | |
| 2725 | + if (!pdata->debugfs_an_cdr_workaround) | |
| 2726 | + return; | |
| 2727 | + | |
| 2728 | + if (!phy_data->phy_cdr_notrack) | |
| 2729 | + return; | |
| 2730 | + | |
| 2731 | + usleep_range(phy_data->phy_cdr_delay, | |
| 2732 | + phy_data->phy_cdr_delay + 500); | |
| 2733 | + | |
| 2734 | + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL, | |
| 2735 | + XGBE_PMA_CDR_TRACK_EN_MASK, | |
| 2736 | + XGBE_PMA_CDR_TRACK_EN_ON); | |
| 2737 | + | |
| 2738 | + phy_data->phy_cdr_notrack = 0; | |
| 2739 | +} | |
| 2740 | + | |
| 2741 | +static void xgbe_phy_cdr_notrack(struct xgbe_prv_data *pdata) | |
| 2742 | +{ | |
| 2743 | + struct xgbe_phy_data *phy_data = pdata->phy_data; | |
| 2744 | + | |
| 2745 | + if (!pdata->debugfs_an_cdr_workaround) | |
| 2746 | + return; | |
| 2747 | + | |
| 2748 | + if (phy_data->phy_cdr_notrack) | |
| 2749 | + return; | |
| 2750 | + | |
| 2751 | + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL, | |
| 2752 | + XGBE_PMA_CDR_TRACK_EN_MASK, | |
| 2753 | + XGBE_PMA_CDR_TRACK_EN_OFF); | |
| 2754 | + | |
| 2755 | + xgbe_phy_rrc(pdata); | |
| 2756 | + | |
| 2757 | + phy_data->phy_cdr_notrack = 1; | |
| 2758 | +} | |
| 2759 | + | |
| 2760 | +static void xgbe_phy_kr_training_post(struct xgbe_prv_data *pdata) | |
| 2761 | +{ | |
| 2762 | + if (!pdata->debugfs_an_cdr_track_early) | |
| 2763 | + xgbe_phy_cdr_track(pdata); | |
| 2764 | +} | |
| 2765 | + | |
| 2766 | +static void xgbe_phy_kr_training_pre(struct xgbe_prv_data *pdata) | |
| 2767 | +{ | |
| 2768 | + if (pdata->debugfs_an_cdr_track_early) | |
| 2769 | + xgbe_phy_cdr_track(pdata); | |
| 2770 | +} | |
| 2771 | + | |
| 2772 | +static void xgbe_phy_an_post(struct xgbe_prv_data *pdata) | |
| 2773 | +{ | |
| 2774 | + struct xgbe_phy_data *phy_data = pdata->phy_data; | |
| 2775 | + | |
| 2776 | + switch (pdata->an_mode) { | |
| 2777 | + case XGBE_AN_MODE_CL73: | |
| 2778 | + case XGBE_AN_MODE_CL73_REDRV: | |
| 2779 | + if (phy_data->cur_mode != XGBE_MODE_KR) | |
| 2780 | + break; | |
| 2781 | + | |
| 2782 | + xgbe_phy_cdr_track(pdata); | |
| 2783 | + | |
| 2784 | + switch (pdata->an_result) { | |
| 2785 | + case XGBE_AN_READY: | |
| 2786 | + case XGBE_AN_COMPLETE: | |
| 2787 | + break; | |
| 2788 | + default: | |
| 2789 | + if (phy_data->phy_cdr_delay < XGBE_CDR_DELAY_MAX) | |
| 2790 | + phy_data->phy_cdr_delay += XGBE_CDR_DELAY_INC; | |
| 2791 | + else | |
| 2792 | + phy_data->phy_cdr_delay = XGBE_CDR_DELAY_INIT; | |
| 2793 | + break; | |
| 2794 | + } | |
| 2795 | + break; | |
| 2796 | + default: | |
| 2797 | + break; | |
| 2798 | + } | |
| 2799 | +} | |
| 2800 | + | |
| 2801 | +static void xgbe_phy_an_pre(struct xgbe_prv_data *pdata) | |
| 2802 | +{ | |
| 2803 | + struct xgbe_phy_data *phy_data = pdata->phy_data; | |
| 2804 | + | |
| 2805 | + switch (pdata->an_mode) { | |
| 2806 | + case XGBE_AN_MODE_CL73: | |
| 2807 | + case XGBE_AN_MODE_CL73_REDRV: | |
| 2808 | + if (phy_data->cur_mode != XGBE_MODE_KR) | |
| 2809 | + break; | |
| 2810 | + | |
| 2811 | + xgbe_phy_cdr_notrack(pdata); | |
| 2812 | + break; | |
| 2813 | + default: | |
| 2814 | + break; | |
| 2815 | + } | |
| 2816 | +} | |
| 2817 | + | |
| 2672 | 2818 | static void xgbe_phy_stop(struct xgbe_prv_data *pdata) |
| 2673 | 2819 | { |
| 2674 | 2820 | struct xgbe_phy_data *phy_data = pdata->phy_data; |
| @@ -2680,6 +2826,9 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata) · 5 unmodified lines | ||
| 2680 | 2826 | xgbe_phy_sfp_reset(phy_data); |
| 2681 | 2827 | xgbe_phy_sfp_mod_absent(pdata); |
| 2682 | 2828 | |
| 2829 | + /* Reset CDR support */ | |
| 2830 | + xgbe_phy_cdr_track(pdata); | |
| 2831 | + | |
| 2683 | 2832 | /* Power off the PHY */ |
| 2684 | 2833 | xgbe_phy_power_off(pdata); |
| 2685 | 2834 | |
| @@ -2712,6 +2861,9 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata) · 26 unmodified lines | ||
| 2712 | 2861 | /* Start in highest supported mode */ |
| 2713 | 2862 | xgbe_phy_set_mode(pdata, phy_data->start_mode); |
| 2714 | 2863 | |
| 2864 | + /* Reset CDR support */ | |
| 2865 | + xgbe_phy_cdr_track(pdata); | |
| 2866 | + | |
| 2715 | 2867 | /* After starting the I2C controller, we can check for an SFP */ |
| 2716 | 2868 | switch (phy_data->port_mode) { |
| 2717 | 2869 | case XGBE_PORT_MODE_SFP: |
| @@ -3019,6 +3171,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) · 301 unmodified lines | ||
| 3019 | 3171 | } |
| 3020 | 3172 | } |
| 3021 | 3173 | |
| 3174 | + phy_data->phy_cdr_delay = XGBE_CDR_DELAY_INIT; | |
| 3175 | + | |
| 3022 | 3176 | /* Register for driving external PHYs */ |
| 3023 | 3177 | mii = devm_mdiobus_alloc(pdata->dev); |
| 3024 | 3178 | if (!mii) { |
| @@ -3071,4 +3225,10 @@ void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if *phy_if) · 46 unmodified lines | ||
| 3071 | 3225 | phy_impl->an_advertising = xgbe_phy_an_advertising; |
| 3072 | 3226 | |
| 3073 | 3227 | phy_impl->an_outcome = xgbe_phy_an_outcome; |
| 3228 | + | |
| 3229 | + phy_impl->an_pre = xgbe_phy_an_pre; | |
| 3230 | + phy_impl->an_post = xgbe_phy_an_post; | |
| 3231 | + | |
| 3232 | + phy_impl->kr_training_pre = xgbe_phy_kr_training_pre; | |
| 3233 | + phy_impl->kr_training_post = xgbe_phy_kr_training_post; | |
| 3074 | 3234 | } |
| @@ -833,6 +833,7 @@ struct xgbe_hw_if { · 832 unmodified lines | ||
| 833 | 833 | /* This structure represents implementation specific routines for an |
| 834 | 834 | * implementation of a PHY. All routines are required unless noted below. |
| 835 | 835 | * Optional routines: |
| 836 | + * an_pre, an_post | |
| 836 | 837 | * kr_training_pre, kr_training_post |
| 837 | 838 | */ |
| 838 | 839 | struct xgbe_phy_impl_if { |
| @@ -875,6 +876,10 @@ struct xgbe_phy_impl_if { · 36 unmodified lines | ||
| 875 | 876 | /* Process results of auto-negotiation */ |
| 876 | 877 | enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *); |
| 877 | 878 | |
| 879 | + /* Pre/Post auto-negotiation support */ | |
| 880 | + void (*an_pre)(struct xgbe_prv_data *); | |
| 881 | + void (*an_post)(struct xgbe_prv_data *); | |
| 882 | + | |
| 878 | 883 | /* Pre/Post KR training enablement support */ |
| 879 | 884 | void (*kr_training_pre)(struct xgbe_prv_data *); |
| 880 | 885 | void (*kr_training_post)(struct xgbe_prv_data *); |
| @@ -989,6 +994,7 @@ struct xgbe_version_data { · 108 unmodified lines | ||
| 989 | 994 | unsigned int irq_reissue_support; |
| 990 | 995 | unsigned int tx_desc_prefetch; |
| 991 | 996 | unsigned int rx_desc_prefetch; |
| 997 | + unsigned int an_cdr_workaround; | |
| 992 | 998 | }; |
| 993 | 999 | |
| 994 | 1000 | struct xgbe_vxlan_data { |
| @@ -1257,6 +1263,9 @@ struct xgbe_prv_data { · 262 unmodified lines | ||
| 1257 | 1263 | unsigned int debugfs_xprop_reg; |
| 1258 | 1264 | |
| 1259 | 1265 | unsigned int debugfs_xi2c_reg; |
| 1266 | + | |
| 1267 | + bool debugfs_an_cdr_workaround; | |
| 1268 | + bool debugfs_an_cdr_track_early; | |
| 1260 | 1269 | }; |
| 1261 | 1270 | |
| 1262 | 1271 | /* Function prototypes*/ |
| @@ -2144,14 +2144,21 @@ static const struct net_device_ops bcm_sysport_netdev_ops = { · 2143 unmodified lines | ||
| 2144 | 2144 | .ndo_select_queue = bcm_sysport_select_queue, |
| 2145 | 2145 | }; |
| 2146 | 2146 | |
| 2147 | −static int bcm_sysport_map_queues(struct net_device *dev, | |
| 2147 | +static int bcm_sysport_map_queues(struct notifier_block *nb, | |
| 2148 | 2148 | struct dsa_notifier_register_info *info) |
| 2149 | 2149 | { |
| 2150 | − struct bcm_sysport_priv *priv = netdev_priv(dev); | |
| 2151 | 2150 | struct bcm_sysport_tx_ring *ring; |
| 2151 | + struct bcm_sysport_priv *priv; | |
| 2152 | 2152 | struct net_device *slave_dev; |
| 2153 | 2153 | unsigned int num_tx_queues; |
| 2154 | 2154 | unsigned int q, start, port; |
| 2155 | + struct net_device *dev; | |
| 2156 | + | |
| 2157 | + priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier); | |
| 2158 | + if (priv->netdev != info->master) | |
| 2159 | + return 0; | |
| 2160 | + | |
| 2161 | + dev = info->master; | |
| 2155 | 2162 | |
| 2156 | 2163 | /* We can't be setting up queue inspection for non directly attached |
| 2157 | 2164 | * switches |
| @@ -2174,11 +2181,12 @@ static int bcm_sysport_map_queues(struct net_device *dev, · 16 unmodified lines | ||
| 2174 | 2181 | if (priv->is_lite) |
| 2175 | 2182 | netif_set_real_num_tx_queues(slave_dev, |
| 2176 | 2183 | slave_dev->num_tx_queues / 2); |
| 2184 | + | |
| 2177 | 2185 | num_tx_queues = slave_dev->real_num_tx_queues; |
| 2178 | 2186 | |
| 2179 | 2187 | if (priv->per_port_num_tx_queues && |
| 2180 | 2188 | priv->per_port_num_tx_queues != num_tx_queues) |
| 2181 | − netdev_warn(slave_dev, "asymetric number of per-port queues\n"); | |
| 2189 | + netdev_warn(slave_dev, "asymmetric number of per-port queues\n"); | |
| 2182 | 2190 | |
| 2183 | 2191 | priv->per_port_num_tx_queues = num_tx_queues; |
| 2184 | 2192 | |
| @@ -2201,7 +2209,7 @@ static int bcm_sysport_map_queues(struct net_device *dev, · 16 unmodified lines | ||
| 2201 | 2209 | return 0; |
| 2202 | 2210 | } |
| 2203 | 2211 | |
| 2204 | −static int bcm_sysport_dsa_notifier(struct notifier_block *unused, | |
| 2212 | +static int bcm_sysport_dsa_notifier(struct notifier_block *nb, | |
| 2205 | 2213 | unsigned long event, void *ptr) |
| 2206 | 2214 | { |
| 2207 | 2215 | struct dsa_notifier_register_info *info; |
| @@ -2211,7 +2219,7 @@ static int bcm_sysport_dsa_notifier(struct notifier_block *unused, · 3 unmodified lines | ||
| 2211 | 2219 | |
| 2212 | 2220 | info = ptr; |
| 2213 | 2221 | |
| 2214 | − return notifier_from_errno(bcm_sysport_map_queues(info->master, info)); | |
| 2222 | + return notifier_from_errno(bcm_sysport_map_queues(nb, info)); | |
| 2215 | 2223 | } |
| 2216 | 2224 | |
| 2217 | 2225 | #define REV_FMT "v%2x.%02x" |
| @@ -1927,22 +1927,39 @@ static char *bnxt_parse_pkglog(int desired_field, u8 *data, size_t datalen) · 1926 unmodified lines | ||
| 1927 | 1927 | return retval; |
| 1928 | 1928 | } |
| 1929 | 1929 | |
| 1930 | −static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen) | |
| 1930 | +static void bnxt_get_pkgver(struct net_device *dev) | |
| 1931 | 1931 | { |
| 1932 | + struct bnxt *bp = netdev_priv(dev); | |
| 1932 | 1933 | u16 index = 0; |
| 1933 | − u32 datalen; | |
| 1934 | + char *pkgver; | |
| 1935 | + u32 pkglen; | |
| 1936 | + u8 *pkgbuf; | |
| 1937 | + int len; | |
| 1934 | 1938 | |
| 1935 | 1939 | if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG, |
| 1936 | 1940 | BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE, |
| 1937 | − &index, NULL, &datalen) != 0) | |
| 1938 | − return NULL; | |
| 1941 | + &index, NULL, &pkglen) != 0) | |
| 1942 | + return; | |
| 1939 | 1943 | |
| 1940 | − memset(buf, 0, buflen); | |
| 1941 | − if (bnxt_get_nvram_item(dev, index, 0, datalen, buf) != 0) | |
| 1942 | − return NULL; | |
| 1944 | + pkgbuf = kzalloc(pkglen, GFP_KERNEL); | |
| 1945 | + if (!pkgbuf) { | |
| 1946 | + dev_err(&bp->pdev->dev, "Unable to allocate memory for pkg version, length = %u\n", | |
| 1947 | + pkglen); | |
| 1948 | + return; | |
| 1949 | + } | |
| 1950 | + | |
| 1951 | + if (bnxt_get_nvram_item(dev, index, 0, pkglen, pkgbuf)) | |
| 1952 | + goto err; | |
| 1943 | 1953 | |
| 1944 | − return bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, buf, | |
| 1945 | − datalen); | |
| 1954 | + pkgver = bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, pkgbuf, | |
| 1955 | + pkglen); | |
| 1956 | + if (pkgver && *pkgver != 0 && isdigit(*pkgver)) { | |
| 1957 | + len = strlen(bp->fw_ver_str); | |
| 1958 | + snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1, | |
| 1959 | + "/pkg %s", pkgver); | |
| 1960 | + } | |
| 1961 | +err: | |
| 1962 | + kfree(pkgbuf); | |
| 1946 | 1963 | } |
| 1947 | 1964 | |
| 1948 | 1965 | static int bnxt_get_eeprom(struct net_device *dev, |
| @@ -2615,22 +2632,10 @@ void bnxt_ethtool_init(struct bnxt *bp) · 666 unmodified lines | ||
| 2615 | 2632 | struct hwrm_selftest_qlist_input req = {0}; |
| 2616 | 2633 | struct bnxt_test_info *test_info; |
| 2617 | 2634 | struct net_device *dev = bp->dev; |
| 2618 | − char *pkglog; | |
| 2619 | 2635 | int i, rc; |
| 2620 | 2636 | |
| 2621 | − pkglog = kzalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL); | |
| 2622 | − if (pkglog) { | |
| 2623 | − char *pkgver; | |
| 2624 | − int len; | |
| 2637 | + bnxt_get_pkgver(dev); | |
| 2625 | 2638 | |
| 2626 | − pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH); | |
| 2627 | − if (pkgver && *pkgver != 0 && isdigit(*pkgver)) { | |
| 2628 | − len = strlen(bp->fw_ver_str); | |
| 2629 | − snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1, | |
| 2630 | − "/pkg %s", pkgver); | |
| 2631 | − } | |
| 2632 | − kfree(pkglog); | |
| 2633 | − } | |
| 2634 | 2639 | if (bp->hwrm_spec_code < 0x10704 || !BNXT_SINGLE_PF(bp)) |
| 2635 | 2640 | return; |
| 2636 | 2641 | |
| @@ -59,8 +59,6 @@ enum bnxt_nvm_directory_type { · 58 unmodified lines | ||
| 59 | 59 | #define BNX_DIR_ATTR_NO_CHKSUM (1 << 0) |
| 60 | 60 | #define BNX_DIR_ATTR_PROP_STREAM (1 << 1) |
| 61 | 61 | |
| 62 | −#define BNX_PKG_LOG_MAX_LENGTH 4096 | |
| 63 | − | |
| 64 | 62 | enum bnxnvm_pkglog_field_index { |
| 65 | 63 | BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP = 0, |
| 66 | 64 | BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION = 1, |
| @@ -61,7 +61,7 @@ static const char hw_stat_gstrings[][ETH_GSTRING_LEN] = { · 60 unmodified lines | ||
| 61 | 61 | static const char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { |
| 62 | 62 | "tx-single-collision", |
| 63 | 63 | "tx-multiple-collision", |
| 64 | − "tx-late-collsion", | |
| 64 | + "tx-late-collision", | |
| 65 | 65 | "tx-aborted-frames", |
| 66 | 66 | "tx-lost-frames", |
| 67 | 67 | "tx-carrier-sense-errors", |
| @@ -87,7 +87,7 @@ do { \ · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | #define HNAE_AE_REGISTER 0x1 |
| 89 | 89 | |
| 90 | −#define RCB_RING_NAME_LEN 16 | |
| 90 | +#define RCB_RING_NAME_LEN (IFNAMSIZ + 4) | |
| 91 | 91 | |
| 92 | 92 | #define HNAE_LOWEST_LATENCY_COAL_PARAM 30 |
| 93 | 93 | #define HNAE_LOW_LATENCY_COAL_PARAM 80 |
| @@ -794,46 +794,61 @@ static int ibmvnic_login(struct net_device *netdev) · 793 unmodified lines | ||
| 794 | 794 | { |
| 795 | 795 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 796 | 796 | unsigned long timeout = msecs_to_jiffies(30000); |
| 797 | − struct device *dev = &adapter->vdev->dev; | |
| 797 | + int retry_count = 0; | |
| 798 | 798 | int rc; |
| 799 | 799 | |
| 800 | 800 | do { |
| 801 | − if (adapter->renegotiate) { | |
| 802 | − adapter->renegotiate = false; | |
| 801 | + if (retry_count > IBMVNIC_MAX_QUEUES) { | |
| 802 | + netdev_warn(netdev, "Login attempts exceeded\n"); | |
| 803 | + return -1; | |
| 804 | + } | |
| 805 | + | |
| 806 | + adapter->init_done_rc = 0; | |
| 807 | + reinit_completion(&adapter->init_done); | |
| 808 | + rc = send_login(adapter); | |
| 809 | + if (rc) { | |
| 810 | + netdev_warn(netdev, "Unable to login\n"); | |
| 811 | + return rc; | |
| 812 | + } | |
| 813 | + | |
| 814 | + if (!wait_for_completion_timeout(&adapter->init_done, | |
| 815 | + timeout)) { | |
| 816 | + netdev_warn(netdev, "Login timed out\n"); | |
| 817 | + return -1; | |
| 818 | + } | |
| 819 | + | |
| 820 | + if (adapter->init_done_rc == PARTIALSUCCESS) { | |
| 821 | + retry_count++; | |
| 803 | 822 | release_sub_crqs(adapter, 1); |
| 804 | 823 | |
| 824 | + adapter->init_done_rc = 0; | |
| 805 | 825 | reinit_completion(&adapter->init_done); |
| 806 | 826 | send_cap_queries(adapter); |
| 807 | 827 | if (!wait_for_completion_timeout(&adapter->init_done, |
| 808 | 828 | timeout)) { |
| 809 | − dev_err(dev, "Capabilities query timeout\n"); | |
| 829 | + netdev_warn(netdev, | |
| 830 | + "Capabilities query timed out\n"); | |
| 810 | 831 | return -1; |
| 811 | 832 | } |
| 833 | + | |
| 812 | 834 | rc = init_sub_crqs(adapter); |
| 813 | 835 | if (rc) { |
| 814 | − dev_err(dev, | |
| 815 | − "Initialization of SCRQ's failed\n"); | |
| 836 | + netdev_warn(netdev, | |
| 837 | + "SCRQ initialization failed\n"); | |
| 816 | 838 | return -1; |
| 817 | 839 | } |
| 840 | + | |
| 818 | 841 | rc = init_sub_crq_irqs(adapter); |
| 819 | 842 | if (rc) { |
| 820 | − dev_err(dev, | |
| 821 | − "Initialization of SCRQ's irqs failed\n"); | |
| 843 | + netdev_warn(netdev, | |
| 844 | + "SCRQ irq initialization failed\n"); | |
| 822 | 845 | return -1; |
| 823 | 846 | } |
| 824 | − } | |
| 825 | − | |
| 826 | − reinit_completion(&adapter->init_done); | |
| 827 | − rc = send_login(adapter); | |
| 828 | − if (rc) { | |
| 829 | − dev_err(dev, "Unable to attempt device login\n"); | |
| 830 | − return rc; | |
| 831 | − } else if (!wait_for_completion_timeout(&adapter->init_done, | |
| 832 | − timeout)) { | |
| 833 | − dev_err(dev, "Login timeout\n"); | |
| 847 | + } else if (adapter->init_done_rc) { | |
| 848 | + netdev_warn(netdev, "Adapter login failed\n"); | |
| 834 | 849 | return -1; |
| 835 | 850 | } |
| 836 | − } while (adapter->renegotiate); | |
| 851 | + } while (adapter->init_done_rc == PARTIALSUCCESS); | |
| 837 | 852 | |
| 838 | 853 | /* handle pending MAC address changes after successful login */ |
| 839 | 854 | if (adapter->mac_change_pending) { |
| @@ -1034,16 +1049,14 @@ static int __ibmvnic_open(struct net_device *netdev) · 194 unmodified lines | ||
| 1034 | 1049 | netdev_dbg(netdev, "Enabling rx_scrq[%d] irq\n", i); |
| 1035 | 1050 | if (prev_state == VNIC_CLOSED) |
| 1036 | 1051 | enable_irq(adapter->rx_scrq[i]->irq); |
| 1037 | − else | |
| 1038 | − enable_scrq_irq(adapter, adapter->rx_scrq[i]); | |
| 1052 | + enable_scrq_irq(adapter, adapter->rx_scrq[i]); | |
| 1039 | 1053 | } |
| 1040 | 1054 | |
| 1041 | 1055 | for (i = 0; i < adapter->req_tx_queues; i++) { |
| 1042 | 1056 | netdev_dbg(netdev, "Enabling tx_scrq[%d] irq\n", i); |
| 1043 | 1057 | if (prev_state == VNIC_CLOSED) |
| 1044 | 1058 | enable_irq(adapter->tx_scrq[i]->irq); |
| 1045 | − else | |
| 1046 | − enable_scrq_irq(adapter, adapter->tx_scrq[i]); | |
| 1059 | + enable_scrq_irq(adapter, adapter->tx_scrq[i]); | |
| 1047 | 1060 | } |
| 1048 | 1061 | |
| 1049 | 1062 | rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP); |
| @@ -1115,7 +1128,7 @@ static void clean_rx_pools(struct ibmvnic_adapter *adapter) · 65 unmodified lines | ||
| 1115 | 1128 | if (!adapter->rx_pool) |
| 1116 | 1129 | return; |
| 1117 | 1130 | |
| 1118 | − rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs); | |
| 1131 | + rx_scrqs = adapter->num_active_rx_pools; | |
| 1119 | 1132 | rx_entries = adapter->req_rx_add_entries_per_subcrq; |
| 1120 | 1133 | |
| 1121 | 1134 | /* Free any remaining skbs in the rx buffer pools */ |
| @@ -1164,7 +1177,7 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter) · 42 unmodified lines | ||
| 1164 | 1177 | if (!adapter->tx_pool || !adapter->tso_pool) |
| 1165 | 1178 | return; |
| 1166 | 1179 | |
| 1167 | − tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); | |
| 1180 | + tx_scrqs = adapter->num_active_tx_pools; | |
| 1168 | 1181 | |
| 1169 | 1182 | /* Free any remaining skbs in the tx buffer pools */ |
| 1170 | 1183 | for (i = 0; i < tx_scrqs; i++) { |
| @@ -1184,6 +1197,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter) · 13 unmodified lines | ||
| 1184 | 1197 | if (adapter->tx_scrq[i]->irq) { |
| 1185 | 1198 | netdev_dbg(netdev, |
| 1186 | 1199 | "Disabling tx_scrq[%d] irq\n", i); |
| 1200 | + disable_scrq_irq(adapter, adapter->tx_scrq[i]); | |
| 1187 | 1201 | disable_irq(adapter->tx_scrq[i]->irq); |
| 1188 | 1202 | } |
| 1189 | 1203 | } |
| @@ -1193,6 +1207,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter) · 3 unmodified lines | ||
| 1193 | 1207 | if (adapter->rx_scrq[i]->irq) { |
| 1194 | 1208 | netdev_dbg(netdev, |
| 1195 | 1209 | "Disabling rx_scrq[%d] irq\n", i); |
| 1210 | + disable_scrq_irq(adapter, adapter->rx_scrq[i]); | |
| 1196 | 1211 | disable_irq(adapter->rx_scrq[i]->irq); |
| 1197 | 1212 | } |
| 1198 | 1213 | } |
| @@ -1828,7 +1843,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, · 629 unmodified lines | ||
| 1828 | 1843 | for (i = 0; i < adapter->req_rx_queues; i++) |
| 1829 | 1844 | napi_schedule(&adapter->napi[i]); |
| 1830 | 1845 | |
| 1831 | − if (adapter->reset_reason != VNIC_RESET_FAILOVER) | |
| 1846 | + if (adapter->reset_reason != VNIC_RESET_FAILOVER && | |
| 1847 | + adapter->reset_reason != VNIC_RESET_CHANGE_PARAM) | |
| 1832 | 1848 | netdev_notify_peers(netdev); |
| 1833 | 1849 | |
| 1834 | 1850 | netif_carrier_on(netdev); |
| @@ -2601,12 +2617,19 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter, · 766 unmodified lines | ||
| 2601 | 2617 | { |
| 2602 | 2618 | struct device *dev = &adapter->vdev->dev; |
| 2603 | 2619 | unsigned long rc; |
| 2620 | + u64 val; | |
| 2604 | 2621 | |
| 2605 | 2622 | if (scrq->hw_irq > 0x100000000ULL) { |
| 2606 | 2623 | dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq); |
| 2607 | 2624 | return 1; |
| 2608 | 2625 | } |
| 2609 | 2626 | |
| 2627 | + val = (0xff000000) | scrq->hw_irq; | |
| 2628 | + rc = plpar_hcall_norets(H_EOI, val); | |
| 2629 | + if (rc) | |
| 2630 | + dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n", | |
| 2631 | + val, rc); | |
| 2632 | + | |
| 2610 | 2633 | rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address, |
| 2611 | 2634 | H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0); |
| 2612 | 2635 | if (rc) |
| @@ -3170,7 +3193,7 @@ static int send_version_xchg(struct ibmvnic_adapter *adapter) · 557 unmodified lines | ||
| 3170 | 3193 | struct vnic_login_client_data { |
| 3171 | 3194 | u8 type; |
| 3172 | 3195 | __be16 len; |
| 3173 | − char name; | |
| 3196 | + char name[]; | |
| 3174 | 3197 | } __packed; |
| 3175 | 3198 | |
| 3176 | 3199 | static int vnic_client_data_len(struct ibmvnic_adapter *adapter) |
| @@ -3199,21 +3222,21 @@ static void vnic_add_client_data(struct ibmvnic_adapter *adapter, · 22 unmodified lines | ||
| 3199 | 3222 | vlcd->type = 1; |
| 3200 | 3223 | len = strlen(os_name) + 1; |
| 3201 | 3224 | vlcd->len = cpu_to_be16(len); |
| 3202 | − strncpy(&vlcd->name, os_name, len); | |
| 3203 | − vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len); | |
| 3225 | + strncpy(vlcd->name, os_name, len); | |
| 3226 | + vlcd = (struct vnic_login_client_data *)(vlcd->name + len); | |
| 3204 | 3227 | |
| 3205 | 3228 | /* Type 2 - LPAR name */ |
| 3206 | 3229 | vlcd->type = 2; |
| 3207 | 3230 | len = strlen(utsname()->nodename) + 1; |
| 3208 | 3231 | vlcd->len = cpu_to_be16(len); |
| 3209 | − strncpy(&vlcd->name, utsname()->nodename, len); | |
| 3210 | − vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len); | |
| 3232 | + strncpy(vlcd->name, utsname()->nodename, len); | |
| 3233 | + vlcd = (struct vnic_login_client_data *)(vlcd->name + len); | |
| 3211 | 3234 | |
| 3212 | 3235 | /* Type 3 - device name */ |
| 3213 | 3236 | vlcd->type = 3; |
| 3214 | 3237 | len = strlen(adapter->netdev->name) + 1; |
| 3215 | 3238 | vlcd->len = cpu_to_be16(len); |
| 3216 | − strncpy(&vlcd->name, adapter->netdev->name, len); | |
| 3239 | + strncpy(vlcd->name, adapter->netdev->name, len); | |
| 3217 | 3240 | } |
| 3218 | 3241 | |
| 3219 | 3242 | static int send_login(struct ibmvnic_adapter *adapter) |
| @@ -3942,7 +3965,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq, · 722 unmodified lines | ||
| 3942 | 3965 | * to resend the login buffer with fewer queues requested. |
| 3943 | 3966 | */ |
| 3944 | 3967 | if (login_rsp_crq->generic.rc.code) { |
| 3945 | − adapter->renegotiate = true; | |
| 3968 | + adapter->init_done_rc = login_rsp_crq->generic.rc.code; | |
| 3946 | 3969 | complete(&adapter->init_done); |
| 3947 | 3970 | return 0; |
| 3948 | 3971 | } |
| @@ -1035,7 +1035,6 @@ struct ibmvnic_adapter { · 1034 unmodified lines | ||
| 1035 | 1035 | |
| 1036 | 1036 | struct ibmvnic_sub_crq_queue **tx_scrq; |
| 1037 | 1037 | struct ibmvnic_sub_crq_queue **rx_scrq; |
| 1038 | − bool renegotiate; | |
| 1039 | 1038 | |
| 1040 | 1039 | /* rx structs */ |
| 1041 | 1040 | struct napi_struct *napi; |
| @@ -586,7 +586,7 @@ struct ice_sw_rule_lg_act { · 585 unmodified lines | ||
| 586 | 586 | #define ICE_LG_ACT_MIRROR_VSI_ID_S 3 |
| 587 | 587 | #define ICE_LG_ACT_MIRROR_VSI_ID_M (0x3FF << ICE_LG_ACT_MIRROR_VSI_ID_S) |
| 588 | 588 | |
| 589 | − /* Action type = 5 - Large Action */ | |
| 589 | + /* Action type = 5 - Generic Value */ | |
| 590 | 590 | #define ICE_LG_ACT_GENERIC 0x5 |
| 591 | 591 | #define ICE_LG_ACT_GENERIC_VALUE_S 3 |
| 592 | 592 | #define ICE_LG_ACT_GENERIC_VALUE_M (0xFFFF << ICE_LG_ACT_GENERIC_VALUE_S) |
| @@ -78,6 +78,7 @@ ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size, · 77 unmodified lines | ||
| 78 | 78 | struct ice_aq_desc desc; |
| 79 | 79 | enum ice_status status; |
| 80 | 80 | u16 flags; |
| 81 | + u8 i; | |
| 81 | 82 | |
| 82 | 83 | cmd = &desc.params.mac_read; |
| 83 | 84 | |
| @@ -98,8 +99,16 @@ ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size, · 14 unmodified lines | ||
| 98 | 99 | return ICE_ERR_CFG; |
| 99 | 100 | } |
| 100 | 101 | |
| 101 | − ether_addr_copy(hw->port_info->mac.lan_addr, resp->mac_addr); | |
| 102 | − ether_addr_copy(hw->port_info->mac.perm_addr, resp->mac_addr); | |
| 102 | + /* A single port can report up to two (LAN and WoL) addresses */ | |
| 103 | + for (i = 0; i < cmd->num_addr; i++) | |
| 104 | + if (resp[i].addr_type == ICE_AQC_MAN_MAC_ADDR_TYPE_LAN) { | |
| 105 | + ether_addr_copy(hw->port_info->mac.lan_addr, | |
| 106 | + resp[i].mac_addr); | |
| 107 | + ether_addr_copy(hw->port_info->mac.perm_addr, | |
| 108 | + resp[i].mac_addr); | |
| 109 | + break; | |
| 110 | + } | |
| 111 | + | |
| 103 | 112 | return 0; |
| 104 | 113 | } |
| 105 | 114 | |
| @@ -464,9 +473,12 @@ enum ice_status ice_init_hw(struct ice_hw *hw) · 358 unmodified lines | ||
| 464 | 473 | if (status) |
| 465 | 474 | goto err_unroll_sched; |
| 466 | 475 | |
| 467 | − /* Get port MAC information */ | |
| 468 | − mac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp); | |
| 469 | − mac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL); | |
| 476 | + /* Get MAC information */ | |
| 477 | + /* A single port can report up to two (LAN and WoL) addresses */ | |
| 478 | + mac_buf = devm_kcalloc(ice_hw_to_dev(hw), 2, | |
| 479 | + sizeof(struct ice_aqc_manage_mac_read_resp), | |
| 480 | + GFP_KERNEL); | |
| 481 | + mac_buf_len = 2 * sizeof(struct ice_aqc_manage_mac_read_resp); | |
| 470 | 482 | |
| 471 | 483 | if (!mac_buf) { |
| 472 | 484 | status = ICE_ERR_NO_MEMORY; |
| @@ -121,8 +121,6 @@ · 120 unmodified lines | ||
| 121 | 121 | #define PFINT_FW_CTL_CAUSE_ENA_S 30 |
| 122 | 122 | #define PFINT_FW_CTL_CAUSE_ENA_M BIT(PFINT_FW_CTL_CAUSE_ENA_S) |
| 123 | 123 | #define PFINT_OICR 0x0016CA00 |
| 124 | −#define PFINT_OICR_INTEVENT_S 0 | |
| 125 | −#define PFINT_OICR_INTEVENT_M BIT(PFINT_OICR_INTEVENT_S) | |
| 126 | 124 | #define PFINT_OICR_HLP_RDY_S 14 |
| 127 | 125 | #define PFINT_OICR_HLP_RDY_M BIT(PFINT_OICR_HLP_RDY_S) |
| 128 | 126 | #define PFINT_OICR_CPM_RDY_S 15 |
| @@ -1722,9 +1722,6 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data) · 1721 unmodified lines | ||
| 1722 | 1722 | oicr = rd32(hw, PFINT_OICR); |
| 1723 | 1723 | ena_mask = rd32(hw, PFINT_OICR_ENA); |
| 1724 | 1724 | |
| 1725 | − if (!(oicr & PFINT_OICR_INTEVENT_M)) | |
| 1726 | − goto ena_intr; | |
| 1727 | − | |
| 1728 | 1725 | if (oicr & PFINT_OICR_GRST_M) { |
| 1729 | 1726 | u32 reset; |
| 1730 | 1727 | /* we have a reset warning */ |
| @@ -1782,7 +1779,6 @@ static irqreturn_t ice_misc_intr(int __always_unused irq, void *data) · 51 unmodified lines | ||
| 1782 | 1779 | } |
| 1783 | 1780 | ret = IRQ_HANDLED; |
| 1784 | 1781 | |
| 1785 | −ena_intr: | |
| 1786 | 1782 | /* re-enable interrupt causes that are not handled during this pass */ |
| 1787 | 1783 | wr32(hw, PFINT_OICR_ENA, ena_mask); |
| 1788 | 1784 | if (!test_bit(__ICE_DOWN, pf->state)) { |
| @@ -751,14 +751,14 @@ ice_sched_add_nodes_to_layer(struct ice_port_info *pi, · 750 unmodified lines | ||
| 751 | 751 | u16 num_added = 0; |
| 752 | 752 | u32 temp; |
| 753 | 753 | |
| 754 | + *num_nodes_added = 0; | |
| 755 | + | |
| 754 | 756 | if (!num_nodes) |
| 755 | 757 | return status; |
| 756 | 758 | |
| 757 | 759 | if (!parent || layer < hw->sw_entry_point_layer) |
| 758 | 760 | return ICE_ERR_PARAM; |
| 759 | 761 | |
| 760 | − *num_nodes_added = 0; | |
| 761 | − | |
| 762 | 762 | /* max children per node per layer */ |
| 763 | 763 | max_child_nodes = |
| 764 | 764 | le16_to_cpu(hw->layer_info[parent->tx_sched_layer].max_children); |
| @@ -1700,7 +1700,22 @@ static void igb_configure_cbs(struct igb_adapter *adapter, int queue, · 1699 unmodified lines | ||
| 1700 | 1700 | WARN_ON(hw->mac.type != e1000_i210); |
| 1701 | 1701 | WARN_ON(queue < 0 || queue > 1); |
| 1702 | 1702 | |
| 1703 | − if (enable) { | |
| 1703 | + if (enable || queue == 0) { | |
| 1704 | + /* i210 does not allow the queue 0 to be in the Strict | |
| 1705 | + * Priority mode while the Qav mode is enabled, so, | |
| 1706 | + * instead of disabling strict priority mode, we give | |
| 1707 | + * queue 0 the maximum of credits possible. | |
| 1708 | + * | |
| 1709 | + * See section 8.12.19 of the i210 datasheet, "Note: | |
| 1710 | + * Queue0 QueueMode must be set to 1b when | |
| 1711 | + * TransmitMode is set to Qav." | |
| 1712 | + */ | |
| 1713 | + if (queue == 0 && !enable) { | |
| 1714 | + /* max "linkspeed" idleslope in kbps */ | |
| 1715 | + idleslope = 1000000; | |
| 1716 | + hicredit = ETH_FRAME_LEN; | |
| 1717 | + } | |
| 1718 | + | |
| 1704 | 1719 | set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_HIGH); |
| 1705 | 1720 | set_queue_mode(hw, queue, QUEUE_MODE_STREAM_RESERVATION); |
| 1706 | 1721 | |
| @@ -3420,7 +3420,7 @@ static int ixgbevf_setup_all_tx_resources(struct ixgbevf_adapter *adapter) · 3419 unmodified lines | ||
| 3420 | 3420 | if (!err) |
| 3421 | 3421 | continue; |
| 3422 | 3422 | hw_dbg(&adapter->hw, "Allocation for XDP Queue %u failed\n", j); |
| 3423 | − break; | |
| 3423 | + goto err_setup_tx; | |
| 3424 | 3424 | } |
| 3425 | 3425 | |
| 3426 | 3426 | return 0; |
| @@ -663,7 +663,7 @@ enum mvpp2_tag_type { · 662 unmodified lines | ||
| 663 | 663 | #define MVPP2_PE_VID_FILT_RANGE_END (MVPP2_PRS_TCAM_SRAM_SIZE - 31) |
| 664 | 664 | #define MVPP2_PE_VID_FILT_RANGE_START (MVPP2_PE_VID_FILT_RANGE_END - \ |
| 665 | 665 | MVPP2_PRS_VLAN_FILT_RANGE_SIZE + 1) |
| 666 | −#define MVPP2_PE_LAST_FREE_TID (MVPP2_PE_VID_FILT_RANGE_START - 1) | |
| 666 | +#define MVPP2_PE_LAST_FREE_TID (MVPP2_PE_MAC_RANGE_START - 1) | |
| 667 | 667 | #define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30) |
| 668 | 668 | #define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 29) |
| 669 | 669 | #define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28) |
| @@ -916,6 +916,8 @@ static struct { · 246 unmodified lines | ||
| 916 | 916 | |
| 917 | 917 | #define MVPP2_MIB_COUNTERS_STATS_DELAY (1 * HZ) |
| 918 | 918 | |
| 919 | +#define MVPP2_DESC_DMA_MASK DMA_BIT_MASK(40) | |
| 920 | + | |
| 919 | 921 | /* Definitions */ |
| 920 | 922 | |
| 921 | 923 | /* Shared Packet Processor resources */ |
| @@ -940,6 +942,7 @@ struct mvpp2 { · 18 unmodified lines | ||
| 940 | 942 | struct clk *pp_clk; |
| 941 | 943 | struct clk *gop_clk; |
| 942 | 944 | struct clk *mg_clk; |
| 945 | + struct clk *mg_core_clk; | |
| 943 | 946 | struct clk *axi_clk; |
| 944 | 947 | |
| 945 | 948 | /* List of pointers to port structures */ |
| @@ -1429,7 +1432,7 @@ static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port, · 483 unmodified lines | ||
| 1429 | 1432 | if (port->priv->hw_version == MVPP21) |
| 1430 | 1433 | return tx_desc->pp21.buf_dma_addr; |
| 1431 | 1434 | else |
| 1432 | − return tx_desc->pp22.buf_dma_addr_ptp & GENMASK_ULL(40, 0); | |
| 1435 | + return tx_desc->pp22.buf_dma_addr_ptp & MVPP2_DESC_DMA_MASK; | |
| 1433 | 1436 | } |
| 1434 | 1437 | |
| 1435 | 1438 | static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port, |
| @@ -1447,7 +1450,7 @@ static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port, · 11 unmodified lines | ||
| 1447 | 1450 | } else { |
| 1448 | 1451 | u64 val = (u64)addr; |
| 1449 | 1452 | |
| 1450 | − tx_desc->pp22.buf_dma_addr_ptp &= ~GENMASK_ULL(40, 0); | |
| 1453 | + tx_desc->pp22.buf_dma_addr_ptp &= ~MVPP2_DESC_DMA_MASK; | |
| 1451 | 1454 | tx_desc->pp22.buf_dma_addr_ptp |= val; |
| 1452 | 1455 | tx_desc->pp22.packet_offset = offset; |
| 1453 | 1456 | } |
| @@ -1507,7 +1510,7 @@ static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port, · 53 unmodified lines | ||
| 1507 | 1510 | if (port->priv->hw_version == MVPP21) |
| 1508 | 1511 | return rx_desc->pp21.buf_dma_addr; |
| 1509 | 1512 | else |
| 1510 | − return rx_desc->pp22.buf_dma_addr_key_hash & GENMASK_ULL(40, 0); | |
| 1513 | + return rx_desc->pp22.buf_dma_addr_key_hash & MVPP2_DESC_DMA_MASK; | |
| 1511 | 1514 | } |
| 1512 | 1515 | |
| 1513 | 1516 | static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port, |
| @@ -1516,7 +1519,7 @@ static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port, · 2 unmodified lines | ||
| 1516 | 1519 | if (port->priv->hw_version == MVPP21) |
| 1517 | 1520 | return rx_desc->pp21.buf_cookie; |
| 1518 | 1521 | else |
| 1519 | − return rx_desc->pp22.buf_cookie_misc & GENMASK_ULL(40, 0); | |
| 1522 | + return rx_desc->pp22.buf_cookie_misc & MVPP2_DESC_DMA_MASK; | |
| 1520 | 1523 | } |
| 1521 | 1524 | |
| 1522 | 1525 | static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port, |
| @@ -8766,18 +8769,27 @@ static int mvpp2_probe(struct platform_device *pdev) · 7243 unmodified lines | ||
| 8766 | 8769 | err = clk_prepare_enable(priv->mg_clk); |
| 8767 | 8770 | if (err < 0) |
| 8768 | 8771 | goto err_gop_clk; |
| 8772 | + | |
| 8773 | + priv->mg_core_clk = devm_clk_get(&pdev->dev, "mg_core_clk"); | |
| 8774 | + if (IS_ERR(priv->mg_core_clk)) { | |
| 8775 | + priv->mg_core_clk = NULL; | |
| 8776 | + } else { | |
| 8777 | + err = clk_prepare_enable(priv->mg_core_clk); | |
| 8778 | + if (err < 0) | |
| 8779 | + goto err_mg_clk; | |
| 8780 | + } | |
| 8769 | 8781 | } |
| 8770 | 8782 | |
| 8771 | 8783 | priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk"); |
| 8772 | 8784 | if (IS_ERR(priv->axi_clk)) { |
| 8773 | 8785 | err = PTR_ERR(priv->axi_clk); |
| 8774 | 8786 | if (err == -EPROBE_DEFER) |
| 8775 | − goto err_gop_clk; | |
| 8787 | + goto err_mg_core_clk; | |
| 8776 | 8788 | priv->axi_clk = NULL; |
| 8777 | 8789 | } else { |
| 8778 | 8790 | err = clk_prepare_enable(priv->axi_clk); |
| 8779 | 8791 | if (err < 0) |
| 8780 | − goto err_gop_clk; | |
| 8792 | + goto err_mg_core_clk; | |
| 8781 | 8793 | } |
| 8782 | 8794 | |
| 8783 | 8795 | /* Get system's tclk rate */ |
| @@ -8789,9 +8801,9 @@ static int mvpp2_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 8789 | 8801 | } |
| 8790 | 8802 | |
| 8791 | 8803 | if (priv->hw_version == MVPP22) { |
| 8792 | − err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); | |
| 8804 | + err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK); | |
| 8793 | 8805 | if (err) |
| 8794 | − goto err_mg_clk; | |
| 8806 | + goto err_axi_clk; | |
| 8795 | 8807 | /* Sadly, the BM pools all share the same register to |
| 8796 | 8808 | * store the high 32 bits of their address. So they |
| 8797 | 8809 | * must all have the same high 32 bits, which forces |
| @@ -8799,14 +8811,14 @@ static int mvpp2_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 8799 | 8811 | */ |
| 8800 | 8812 | err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); |
| 8801 | 8813 | if (err) |
| 8802 | − goto err_mg_clk; | |
| 8814 | + goto err_axi_clk; | |
| 8803 | 8815 | } |
| 8804 | 8816 | |
| 8805 | 8817 | /* Initialize network controller */ |
| 8806 | 8818 | err = mvpp2_init(pdev, priv); |
| 8807 | 8819 | if (err < 0) { |
| 8808 | 8820 | dev_err(&pdev->dev, "failed to initialize controller\n"); |
| 8809 | − goto err_mg_clk; | |
| 8821 | + goto err_axi_clk; | |
| 8810 | 8822 | } |
| 8811 | 8823 | |
| 8812 | 8824 | /* Initialize ports */ |
| @@ -8819,7 +8831,7 @@ static int mvpp2_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 8819 | 8831 | if (priv->port_count == 0) { |
| 8820 | 8832 | dev_err(&pdev->dev, "no ports enabled\n"); |
| 8821 | 8833 | err = -ENODEV; |
| 8822 | − goto err_mg_clk; | |
| 8834 | + goto err_axi_clk; | |
| 8823 | 8835 | } |
| 8824 | 8836 | |
| 8825 | 8837 | /* Statistics must be gathered regularly because some of them (like |
| @@ -8847,8 +8859,13 @@ err_port_probe: · 21 unmodified lines | ||
| 8847 | 8859 | mvpp2_port_remove(priv->port_list[i]); |
| 8848 | 8860 | i++; |
| 8849 | 8861 | } |
| 8850 | −err_mg_clk: | |
| 8862 | +err_axi_clk: | |
| 8851 | 8863 | clk_disable_unprepare(priv->axi_clk); |
| 8864 | + | |
| 8865 | +err_mg_core_clk: | |
| 8866 | + if (priv->hw_version == MVPP22) | |
| 8867 | + clk_disable_unprepare(priv->mg_core_clk); | |
| 8868 | +err_mg_clk: | |
| 8852 | 8869 | if (priv->hw_version == MVPP22) |
| 8853 | 8870 | clk_disable_unprepare(priv->mg_clk); |
| 8854 | 8871 | err_gop_clk: |
| @@ -8895,6 +8912,7 @@ static int mvpp2_remove(struct platform_device *pdev) · 40 unmodified lines | ||
| 8895 | 8912 | return 0; |
| 8896 | 8913 | |
| 8897 | 8914 | clk_disable_unprepare(priv->axi_clk); |
| 8915 | + clk_disable_unprepare(priv->mg_core_clk); | |
| 8898 | 8916 | clk_disable_unprepare(priv->mg_clk); |
| 8899 | 8917 | clk_disable_unprepare(priv->pp_clk); |
| 8900 | 8918 | clk_disable_unprepare(priv->gop_clk); |
| @@ -1317,7 +1317,7 @@ static int mlx4_mf_unbond(struct mlx4_dev *dev) · 1316 unmodified lines | ||
| 1317 | 1317 | |
| 1318 | 1318 | ret = mlx4_unbond_fs_rules(dev); |
| 1319 | 1319 | if (ret) |
| 1320 | − mlx4_warn(dev, "multifunction unbond for flow rules failedi (%d)\n", ret); | |
| 1320 | + mlx4_warn(dev, "multifunction unbond for flow rules failed (%d)\n", ret); | |
| 1321 | 1321 | ret1 = mlx4_unbond_mac_table(dev); |
| 1322 | 1322 | if (ret1) { |
| 1323 | 1323 | mlx4_warn(dev, "multifunction unbond for MAC table failed (%d)\n", ret1); |
| @@ -1007,12 +1007,14 @@ static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv) · 1006 unmodified lines | ||
| 1007 | 1007 | |
| 1008 | 1008 | mutex_lock(&priv->state_lock); |
| 1009 | 1009 | |
| 1010 | − if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) | |
| 1011 | − goto out; | |
| 1012 | − | |
| 1013 | 1010 | new_channels.params = priv->channels.params; |
| 1014 | 1011 | mlx5e_trust_update_tx_min_inline_mode(priv, &new_channels.params); |
| 1015 | 1012 | |
| 1013 | + if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { | |
| 1014 | + priv->channels.params = new_channels.params; | |
| 1015 | + goto out; | |
| 1016 | + } | |
| 1017 | + | |
| 1016 | 1018 | /* Skip if tx_min_inline is the same */ |
| 1017 | 1019 | if (new_channels.params.tx_min_inline_mode == |
| 1018 | 1020 | priv->channels.params.tx_min_inline_mode) |
| @@ -877,13 +877,14 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = { · 876 unmodified lines | ||
| 877 | 877 | }; |
| 878 | 878 | |
| 879 | 879 | static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev, |
| 880 | − struct mlx5e_params *params) | |
| 880 | + struct mlx5e_params *params, u16 mtu) | |
| 881 | 881 | { |
| 882 | 882 | u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? |
| 883 | 883 | MLX5_CQ_PERIOD_MODE_START_FROM_CQE : |
| 884 | 884 | MLX5_CQ_PERIOD_MODE_START_FROM_EQE; |
| 885 | 885 | |
| 886 | 886 | params->hard_mtu = MLX5E_ETH_HARD_MTU; |
| 887 | + params->sw_mtu = mtu; | |
| 887 | 888 | params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE; |
| 888 | 889 | params->rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST; |
| 889 | 890 | params->log_rq_mtu_frames = MLX5E_REP_PARAMS_LOG_RQ_SIZE; |
| @@ -931,7 +932,7 @@ static void mlx5e_init_rep(struct mlx5_core_dev *mdev, · 41 unmodified lines | ||
| 931 | 932 | |
| 932 | 933 | priv->channels.params.num_channels = profile->max_nch(mdev); |
| 933 | 934 | |
| 934 | − mlx5e_build_rep_params(mdev, &priv->channels.params); | |
| 935 | + mlx5e_build_rep_params(mdev, &priv->channels.params, netdev->mtu); | |
| 935 | 936 | mlx5e_build_rep_netdev(netdev); |
| 936 | 937 | |
| 937 | 938 | mlx5e_timestamp_init(priv); |
| @@ -290,7 +290,7 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv) · 289 unmodified lines | ||
| 290 | 290 | |
| 291 | 291 | if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { |
| 292 | 292 | netdev_err(priv->netdev, |
| 293 | − "\tCan't perform loobpack test while device is down\n"); | |
| 293 | + "\tCan't perform loopback test while device is down\n"); | |
| 294 | 294 | return -ENODEV; |
| 295 | 295 | } |
| 296 | 296 | |
| @@ -1864,7 +1864,8 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec, · 1863 unmodified lines | ||
| 1864 | 1864 | } |
| 1865 | 1865 | |
| 1866 | 1866 | ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); |
| 1867 | − if (modify_ip_header && ip_proto != IPPROTO_TCP && ip_proto != IPPROTO_UDP) { | |
| 1867 | + if (modify_ip_header && ip_proto != IPPROTO_TCP && | |
| 1868 | + ip_proto != IPPROTO_UDP && ip_proto != IPPROTO_ICMP) { | |
| 1868 | 1869 | pr_info("can't offload re-write of ip proto %d\n", ip_proto); |
| 1869 | 1870 | return false; |
| 1870 | 1871 | } |
| @@ -255,7 +255,7 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 254 unmodified lines | ||
| 255 | 255 | dma_addr = dma_map_single(sq->pdev, skb_data, headlen, |
| 256 | 256 | DMA_TO_DEVICE); |
| 257 | 257 | if (unlikely(dma_mapping_error(sq->pdev, dma_addr))) |
| 258 | − return -ENOMEM; | |
| 258 | + goto dma_unmap_wqe_err; | |
| 259 | 259 | |
| 260 | 260 | dseg->addr = cpu_to_be64(dma_addr); |
| 261 | 261 | dseg->lkey = sq->mkey_be; |
| @@ -273,7 +273,7 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 11 unmodified lines | ||
| 273 | 273 | dma_addr = skb_frag_dma_map(sq->pdev, frag, 0, fsz, |
| 274 | 274 | DMA_TO_DEVICE); |
| 275 | 275 | if (unlikely(dma_mapping_error(sq->pdev, dma_addr))) |
| 276 | − return -ENOMEM; | |
| 276 | + goto dma_unmap_wqe_err; | |
| 277 | 277 | |
| 278 | 278 | dseg->addr = cpu_to_be64(dma_addr); |
| 279 | 279 | dseg->lkey = sq->mkey_be; |
| @@ -285,6 +285,10 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 5 unmodified lines | ||
| 285 | 285 | } |
| 286 | 286 | |
| 287 | 287 | return num_dma; |
| 288 | + | |
| 289 | +dma_unmap_wqe_err: | |
| 290 | + mlx5e_dma_unmap_wqe_err(sq, num_dma); | |
| 291 | + return -ENOMEM; | |
| 288 | 292 | } |
| 289 | 293 | |
| 290 | 294 | static inline void |
| @@ -380,17 +384,15 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 89 unmodified lines | ||
| 380 | 384 | num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, |
| 381 | 385 | (struct mlx5_wqe_data_seg *)cseg + ds_cnt); |
| 382 | 386 | if (unlikely(num_dma < 0)) |
| 383 | − goto dma_unmap_wqe_err; | |
| 387 | + goto err_drop; | |
| 384 | 388 | |
| 385 | 389 | mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma, |
| 386 | 390 | num_bytes, num_dma, wi, cseg); |
| 387 | 391 | |
| 388 | 392 | return NETDEV_TX_OK; |
| 389 | 393 | |
| 390 | −dma_unmap_wqe_err: | |
| 394 | +err_drop: | |
| 391 | 395 | sq->stats.dropped++; |
| 392 | − mlx5e_dma_unmap_wqe_err(sq, wi->num_dma); | |
| 393 | − | |
| 394 | 396 | dev_kfree_skb_any(skb); |
| 395 | 397 | |
| 396 | 398 | return NETDEV_TX_OK; |
| @@ -645,17 +647,15 @@ netdev_tx_t mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 248 unmodified lines | ||
| 645 | 647 | num_dma = mlx5e_txwqe_build_dsegs(sq, skb, skb_data, headlen, |
| 646 | 648 | (struct mlx5_wqe_data_seg *)cseg + ds_cnt); |
| 647 | 649 | if (unlikely(num_dma < 0)) |
| 648 | − goto dma_unmap_wqe_err; | |
| 650 | + goto err_drop; | |
| 649 | 651 | |
| 650 | 652 | mlx5e_txwqe_complete(sq, skb, opcode, ds_cnt + num_dma, |
| 651 | 653 | num_bytes, num_dma, wi, cseg); |
| 652 | 654 | |
| 653 | 655 | return NETDEV_TX_OK; |
| 654 | 656 | |
| 655 | −dma_unmap_wqe_err: | |
| 657 | +err_drop: | |
| 656 | 658 | sq->stats.dropped++; |
| 657 | − mlx5e_dma_unmap_wqe_err(sq, wi->num_dma); | |
| 658 | − | |
| 659 | 659 | dev_kfree_skb_any(skb); |
| 660 | 660 | |
| 661 | 661 | return NETDEV_TX_OK; |
| @@ -187,6 +187,7 @@ static void del_sw_ns(struct fs_node *node); · 186 unmodified lines | ||
| 187 | 187 | static void del_sw_hw_rule(struct fs_node *node); |
| 188 | 188 | static bool mlx5_flow_dests_cmp(struct mlx5_flow_destination *d1, |
| 189 | 189 | struct mlx5_flow_destination *d2); |
| 190 | +static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns); | |
| 190 | 191 | static struct mlx5_flow_rule * |
| 191 | 192 | find_flow_rule(struct fs_fte *fte, |
| 192 | 193 | struct mlx5_flow_destination *dest); |
| @@ -481,7 +482,8 @@ static void del_sw_hw_rule(struct fs_node *node) · 288 unmodified lines | ||
| 481 | 482 | |
| 482 | 483 | if (rule->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER && |
| 483 | 484 | --fte->dests_size) { |
| 484 | − modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); | |
| 485 | + modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION) | | |
| 486 | + BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_FLOW_COUNTERS); | |
| 485 | 487 | fte->action.action &= ~MLX5_FLOW_CONTEXT_ACTION_COUNT; |
| 486 | 488 | update_fte = true; |
| 487 | 489 | goto out; |
| @@ -2351,23 +2353,27 @@ static int create_anchor_flow_table(struct mlx5_flow_steering *steering) · 1863 unmodified lines | ||
| 2351 | 2353 | |
| 2352 | 2354 | static int init_root_ns(struct mlx5_flow_steering *steering) |
| 2353 | 2355 | { |
| 2356 | + int err; | |
| 2357 | + | |
| 2354 | 2358 | steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); |
| 2355 | 2359 | if (!steering->root_ns) |
| 2356 | − goto cleanup; | |
| 2360 | + return -ENOMEM; | |
| 2357 | 2361 | |
| 2358 | − if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node)) | |
| 2359 | − goto cleanup; | |
| 2362 | + err = init_root_tree(steering, &root_fs, &steering->root_ns->ns.node); | |
| 2363 | + if (err) | |
| 2364 | + goto out_err; | |
| 2360 | 2365 | |
| 2361 | 2366 | set_prio_attrs(steering->root_ns); |
| 2362 | − | |
| 2363 | − if (create_anchor_flow_table(steering)) | |
| 2364 | − goto cleanup; | |
| 2367 | + err = create_anchor_flow_table(steering); | |
| 2368 | + if (err) | |
| 2369 | + goto out_err; | |
| 2365 | 2370 | |
| 2366 | 2371 | return 0; |
| 2367 | 2372 | |
| 2368 | −cleanup: | |
| 2369 | − mlx5_cleanup_fs(steering->dev); | |
| 2370 | − return -ENOMEM; | |
| 2373 | +out_err: | |
| 2374 | + cleanup_root_ns(steering->root_ns); | |
| 2375 | + steering->root_ns = NULL; | |
| 2376 | + return err; | |
| 2371 | 2377 | } |
| 2372 | 2378 | |
| 2373 | 2379 | static void clean_tree(struct fs_node *node) |
| @@ -1718,13 +1718,11 @@ __mlxsw_sp_port_mdb_del(struct mlxsw_sp_port *mlxsw_sp_port, · 1717 unmodified lines | ||
| 1718 | 1718 | struct net_device *dev = mlxsw_sp_port->dev; |
| 1719 | 1719 | int err; |
| 1720 | 1720 | |
| 1721 | − if (bridge_port->bridge_device->multicast_enabled) { | |
| 1722 | − if (bridge_port->bridge_device->multicast_enabled) { | |
| 1723 | − err = mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, | |
| 1724 | − false); | |
| 1725 | − if (err) | |
| 1726 | − netdev_err(dev, "Unable to remove port from SMID\n"); | |
| 1727 | − } | |
| 1721 | + if (bridge_port->bridge_device->multicast_enabled && | |
| 1722 | + !bridge_port->mrouter) { | |
| 1723 | + err = mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, false); | |
| 1724 | + if (err) | |
| 1725 | + netdev_err(dev, "Unable to remove port from SMID\n"); | |
| 1728 | 1726 | } |
| 1729 | 1727 | |
| 1730 | 1728 | err = mlxsw_sp_port_remove_from_mid(mlxsw_sp_port, mid); |
| @@ -183,17 +183,21 @@ static int · 182 unmodified lines | ||
| 183 | 183 | nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, |
| 184 | 184 | const struct tc_action *action, |
| 185 | 185 | struct nfp_fl_pre_tunnel *pre_tun, |
| 186 | − enum nfp_flower_tun_type tun_type) | |
| 186 | + enum nfp_flower_tun_type tun_type, | |
| 187 | + struct net_device *netdev) | |
| 187 | 188 | { |
| 188 | 189 | size_t act_size = sizeof(struct nfp_fl_set_ipv4_udp_tun); |
| 189 | 190 | struct ip_tunnel_info *ip_tun = tcf_tunnel_info(action); |
| 190 | 191 | u32 tmp_set_ip_tun_type_index = 0; |
| 191 | 192 | /* Currently support one pre-tunnel so index is always 0. */ |
| 192 | 193 | int pretun_idx = 0; |
| 194 | + struct net *net; | |
| 193 | 195 | |
| 194 | 196 | if (ip_tun->options_len) |
| 195 | 197 | return -EOPNOTSUPP; |
| 196 | 198 | |
| 199 | + net = dev_net(netdev); | |
| 200 | + | |
| 197 | 201 | set_tun->head.jump_id = NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL; |
| 198 | 202 | set_tun->head.len_lw = act_size >> NFP_FL_LW_SIZ; |
| 199 | 203 | |
| @@ -204,6 +208,7 @@ nfp_fl_set_ipv4_udp_tun(struct nfp_fl_set_ipv4_udp_tun *set_tun, · 4 unmodified lines | ||
| 204 | 208 | |
| 205 | 209 | set_tun->tun_type_index = cpu_to_be32(tmp_set_ip_tun_type_index); |
| 206 | 210 | set_tun->tun_id = ip_tun->key.tun_id; |
| 211 | + set_tun->ttl = net->ipv4.sysctl_ip_default_ttl; | |
| 207 | 212 | |
| 208 | 213 | /* Complete pre_tunnel action. */ |
| 209 | 214 | pre_tun->ipv4_dst = ip_tun->key.u.ipv4.dst; |
| @@ -511,7 +516,8 @@ nfp_flower_loop_action(const struct tc_action *a, · 301 unmodified lines | ||
| 511 | 516 | *a_len += sizeof(struct nfp_fl_pre_tunnel); |
| 512 | 517 | |
| 513 | 518 | set_tun = (void *)&nfp_fl->action_data[*a_len]; |
| 514 | − err = nfp_fl_set_ipv4_udp_tun(set_tun, a, pre_tun, *tun_type); | |
| 519 | + err = nfp_fl_set_ipv4_udp_tun(set_tun, a, pre_tun, *tun_type, | |
| 520 | + netdev); | |
| 515 | 521 | if (err) |
| 516 | 522 | return err; |
| 517 | 523 | *a_len += sizeof(struct nfp_fl_set_ipv4_udp_tun); |
| @@ -258,9 +258,6 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) · 257 unmodified lines | ||
| 258 | 258 | case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS: |
| 259 | 259 | nfp_tunnel_keep_alive(app, skb); |
| 260 | 260 | break; |
| 261 | − case NFP_FLOWER_CMSG_TYPE_TUN_NEIGH: | |
| 262 | − /* Acks from the NFP that the route is added - ignore. */ | |
| 263 | − break; | |
| 264 | 261 | default: |
| 265 | 262 | nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n", |
| 266 | 263 | type); |
| @@ -275,18 +272,49 @@ out: · 8 unmodified lines | ||
| 275 | 272 | |
| 276 | 273 | void nfp_flower_cmsg_process_rx(struct work_struct *work) |
| 277 | 274 | { |
| 275 | + struct sk_buff_head cmsg_joined; | |
| 278 | 276 | struct nfp_flower_priv *priv; |
| 279 | 277 | struct sk_buff *skb; |
| 280 | 278 | |
| 281 | 279 | priv = container_of(work, struct nfp_flower_priv, cmsg_work); |
| 280 | + skb_queue_head_init(&cmsg_joined); | |
| 281 | + | |
| 282 | + spin_lock_bh(&priv->cmsg_skbs_high.lock); | |
| 283 | + skb_queue_splice_tail_init(&priv->cmsg_skbs_high, &cmsg_joined); | |
| 284 | + spin_unlock_bh(&priv->cmsg_skbs_high.lock); | |
| 282 | 285 | |
| 283 | − while ((skb = skb_dequeue(&priv->cmsg_skbs))) | |
| 286 | + spin_lock_bh(&priv->cmsg_skbs_low.lock); | |
| 287 | + skb_queue_splice_tail_init(&priv->cmsg_skbs_low, &cmsg_joined); | |
| 288 | + spin_unlock_bh(&priv->cmsg_skbs_low.lock); | |
| 289 | + | |
| 290 | + while ((skb = __skb_dequeue(&cmsg_joined))) | |
| 284 | 291 | nfp_flower_cmsg_process_one_rx(priv->app, skb); |
| 285 | 292 | } |
| 286 | 293 | |
| 287 | −void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb) | |
| 294 | +static void | |
| 295 | +nfp_flower_queue_ctl_msg(struct nfp_app *app, struct sk_buff *skb, int type) | |
| 288 | 296 | { |
| 289 | 297 | struct nfp_flower_priv *priv = app->priv; |
| 298 | + struct sk_buff_head *skb_head; | |
| 299 | + | |
| 300 | + if (type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY || | |
| 301 | + type == NFP_FLOWER_CMSG_TYPE_PORT_MOD) | |
| 302 | + skb_head = &priv->cmsg_skbs_high; | |
| 303 | + else | |
| 304 | + skb_head = &priv->cmsg_skbs_low; | |
| 305 | + | |
| 306 | + if (skb_queue_len(skb_head) >= NFP_FLOWER_WORKQ_MAX_SKBS) { | |
| 307 | + nfp_flower_cmsg_warn(app, "Dropping queued control messages\n"); | |
| 308 | + dev_kfree_skb_any(skb); | |
| 309 | + return; | |
| 310 | + } | |
| 311 | + | |
| 312 | + skb_queue_tail(skb_head, skb); | |
| 313 | + schedule_work(&priv->cmsg_work); | |
| 314 | +} | |
| 315 | + | |
| 316 | +void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb) | |
| 317 | +{ | |
| 290 | 318 | struct nfp_flower_cmsg_hdr *cmsg_hdr; |
| 291 | 319 | |
| 292 | 320 | cmsg_hdr = nfp_flower_cmsg_get_hdr(skb); |
| @@ -306,8 +334,10 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb) · 13 unmodified lines | ||
| 306 | 334 | nfp_flower_process_mtu_ack(app, skb)) { |
| 307 | 335 | /* Handle MTU acks outside wq to prevent RTNL conflict. */ |
| 308 | 336 | dev_consume_skb_any(skb); |
| 337 | + } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH) { | |
| 338 | + /* Acks from the NFP that the route is added - ignore. */ | |
| 339 | + dev_consume_skb_any(skb); | |
| 309 | 340 | } else { |
| 310 | − skb_queue_tail(&priv->cmsg_skbs, skb); | |
| 311 | − schedule_work(&priv->cmsg_work); | |
| 341 | + nfp_flower_queue_ctl_msg(app, skb, cmsg_hdr->type); | |
| 312 | 342 | } |
| 313 | 343 | } |
| @@ -108,6 +108,8 @@ · 107 unmodified lines | ||
| 108 | 108 | #define NFP_FL_IPV4_TUNNEL_TYPE GENMASK(7, 4) |
| 109 | 109 | #define NFP_FL_IPV4_PRE_TUN_INDEX GENMASK(2, 0) |
| 110 | 110 | |
| 111 | +#define NFP_FLOWER_WORKQ_MAX_SKBS 30000 | |
| 112 | + | |
| 111 | 113 | #define nfp_flower_cmsg_warn(app, fmt, args...) \ |
| 112 | 114 | do { \ |
| 113 | 115 | if (net_ratelimit()) \ |
| @@ -188,7 +190,10 @@ struct nfp_fl_set_ipv4_udp_tun { · 74 unmodified lines | ||
| 188 | 190 | __be16 reserved; |
| 189 | 191 | __be64 tun_id __packed; |
| 190 | 192 | __be32 tun_type_index; |
| 191 | − __be32 extra[3]; | |
| 193 | + __be16 reserved2; | |
| 194 | + u8 ttl; | |
| 195 | + u8 reserved3; | |
| 196 | + __be32 extra[2]; | |
| 192 | 197 | }; |
| 193 | 198 | |
| 194 | 199 | /* Metadata with L2 (1W/4B) |
| @@ -360,7 +360,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv) · 359 unmodified lines | ||
| 360 | 360 | } |
| 361 | 361 | |
| 362 | 362 | SET_NETDEV_DEV(repr, &priv->nn->pdev->dev); |
| 363 | − nfp_net_get_mac_addr(app->pf, port); | |
| 363 | + nfp_net_get_mac_addr(app->pf, repr, port); | |
| 364 | 364 | |
| 365 | 365 | cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port); |
| 366 | 366 | err = nfp_repr_init(app, repr, |
| @@ -519,7 +519,8 @@ static int nfp_flower_init(struct nfp_app *app) · 152 unmodified lines | ||
| 519 | 519 | |
| 520 | 520 | app->priv = app_priv; |
| 521 | 521 | app_priv->app = app; |
| 522 | − skb_queue_head_init(&app_priv->cmsg_skbs); | |
| 522 | + skb_queue_head_init(&app_priv->cmsg_skbs_high); | |
| 523 | + skb_queue_head_init(&app_priv->cmsg_skbs_low); | |
| 523 | 524 | INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx); |
| 524 | 525 | init_waitqueue_head(&app_priv->reify_wait_queue); |
| 525 | 526 | |
| @@ -549,7 +550,8 @@ static void nfp_flower_clean(struct nfp_app *app) · 23 unmodified lines | ||
| 549 | 550 | { |
| 550 | 551 | struct nfp_flower_priv *app_priv = app->priv; |
| 551 | 552 | |
| 552 | − skb_queue_purge(&app_priv->cmsg_skbs); | |
| 553 | + skb_queue_purge(&app_priv->cmsg_skbs_high); | |
| 554 | + skb_queue_purge(&app_priv->cmsg_skbs_low); | |
| 553 | 555 | flush_work(&app_priv->cmsg_work); |
| 554 | 556 | |
| 555 | 557 | nfp_flower_metadata_cleanup(app); |
| @@ -107,7 +107,10 @@ struct nfp_mtu_conf { · 106 unmodified lines | ||
| 107 | 107 | * @mask_table: Hash table used to store masks |
| 108 | 108 | * @flow_table: Hash table used to store flower rules |
| 109 | 109 | * @cmsg_work: Workqueue for control messages processing |
| 110 | − * @cmsg_skbs: List of skbs for control message processing | |
| 110 | + * @cmsg_skbs_high: List of higher priority skbs for control message | |
| 111 | + * processing | |
| 112 | + * @cmsg_skbs_low: List of lower priority skbs for control message | |
| 113 | + * processing | |
| 111 | 114 | * @nfp_mac_off_list: List of MAC addresses to offload |
| 112 | 115 | * @nfp_mac_index_list: List of unique 8-bit indexes for non NFP netdevs |
| 113 | 116 | * @nfp_ipv4_off_list: List of IPv4 addresses to offload |
| @@ -136,7 +139,8 @@ struct nfp_flower_priv { · 22 unmodified lines | ||
| 136 | 139 | DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS); |
| 137 | 140 | DECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS); |
| 138 | 141 | struct work_struct cmsg_work; |
| 139 | − struct sk_buff_head cmsg_skbs; | |
| 142 | + struct sk_buff_head cmsg_skbs_high; | |
| 143 | + struct sk_buff_head cmsg_skbs_low; | |
| 140 | 144 | struct list_head nfp_mac_off_list; |
| 141 | 145 | struct list_head nfp_mac_index_list; |
| 142 | 146 | struct list_head nfp_ipv4_off_list; |
| @@ -69,7 +69,7 @@ int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, · 68 unmodified lines | ||
| 69 | 69 | if (err) |
| 70 | 70 | return err < 0 ? err : 0; |
| 71 | 71 | |
| 72 | − nfp_net_get_mac_addr(app->pf, nn->port); | |
| 72 | + nfp_net_get_mac_addr(app->pf, nn->dp.netdev, nn->port); | |
| 73 | 73 | |
| 74 | 74 | return 0; |
| 75 | 75 | } |
| @@ -171,7 +171,9 @@ void nfp_net_pci_remove(struct nfp_pf *pf); · 170 unmodified lines | ||
| 171 | 171 | int nfp_hwmon_register(struct nfp_pf *pf); |
| 172 | 172 | void nfp_hwmon_unregister(struct nfp_pf *pf); |
| 173 | 173 | |
| 174 | −void nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_port *port); | |
| 174 | +void | |
| 175 | +nfp_net_get_mac_addr(struct nfp_pf *pf, struct net_device *netdev, | |
| 176 | + struct nfp_port *port); | |
| 175 | 177 | |
| 176 | 178 | bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); |
| 177 | 179 | |
| @@ -67,23 +67,26 @@ · 66 unmodified lines | ||
| 67 | 67 | /** |
| 68 | 68 | * nfp_net_get_mac_addr() - Get the MAC address. |
| 69 | 69 | * @pf: NFP PF handle |
| 70 | + * @netdev: net_device to set MAC address on | |
| 70 | 71 | * @port: NFP port structure |
| 71 | 72 | * |
| 72 | 73 | * First try to get the MAC address from NSP ETH table. If that |
| 73 | 74 | * fails generate a random address. |
| 74 | 75 | */ |
| 75 | −void nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_port *port) | |
| 76 | +void | |
| 77 | +nfp_net_get_mac_addr(struct nfp_pf *pf, struct net_device *netdev, | |
| 78 | + struct nfp_port *port) | |
| 76 | 79 | { |
| 77 | 80 | struct nfp_eth_table_port *eth_port; |
| 78 | 81 | |
| 79 | 82 | eth_port = __nfp_port_get_eth_port(port); |
| 80 | 83 | if (!eth_port) { |
| 81 | − eth_hw_addr_random(port->netdev); | |
| 84 | + eth_hw_addr_random(netdev); | |
| 82 | 85 | return; |
| 83 | 86 | } |
| 84 | 87 | |
| 85 | − ether_addr_copy(port->netdev->dev_addr, eth_port->mac_addr); | |
| 86 | − ether_addr_copy(port->netdev->perm_addr, eth_port->mac_addr); | |
| 88 | + ether_addr_copy(netdev->dev_addr, eth_port->mac_addr); | |
| 89 | + ether_addr_copy(netdev->perm_addr, eth_port->mac_addr); | |
| 87 | 90 | } |
| 88 | 91 | |
| 89 | 92 | static struct nfp_eth_table_port * |
| @@ -511,16 +514,18 @@ static int nfp_net_pci_map_mem(struct nfp_pf *pf) · 421 unmodified lines | ||
| 511 | 514 | return PTR_ERR(mem); |
| 512 | 515 | } |
| 513 | 516 | |
| 514 | − min_size = NFP_MAC_STATS_SIZE * (pf->eth_tbl->max_index + 1); | |
| 515 | − pf->mac_stats_mem = nfp_rtsym_map(pf->rtbl, "_mac_stats", | |
| 516 | − "net.macstats", min_size, | |
| 517 | − &pf->mac_stats_bar); | |
| 518 | − if (IS_ERR(pf->mac_stats_mem)) { | |
| 519 | − if (PTR_ERR(pf->mac_stats_mem) != -ENOENT) { | |
| 520 | − err = PTR_ERR(pf->mac_stats_mem); | |
| 521 | − goto err_unmap_ctrl; | |
| 517 | + if (pf->eth_tbl) { | |
| 518 | + min_size = NFP_MAC_STATS_SIZE * (pf->eth_tbl->max_index + 1); | |
| 519 | + pf->mac_stats_mem = nfp_rtsym_map(pf->rtbl, "_mac_stats", | |
| 520 | + "net.macstats", min_size, | |
| 521 | + &pf->mac_stats_bar); | |
| 522 | + if (IS_ERR(pf->mac_stats_mem)) { | |
| 523 | + if (PTR_ERR(pf->mac_stats_mem) != -ENOENT) { | |
| 524 | + err = PTR_ERR(pf->mac_stats_mem); | |
| 525 | + goto err_unmap_ctrl; | |
| 526 | + } | |
| 527 | + pf->mac_stats_mem = NULL; | |
| 522 | 528 | } |
| 523 | − pf->mac_stats_mem = NULL; | |
| 524 | 529 | } |
| 525 | 530 | |
| 526 | 531 | pf->vf_cfg_mem = nfp_net_pf_map_rtsym(pf, "net.vfcfg", |
| @@ -211,8 +211,11 @@ int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex) · 210 unmodified lines | ||
| 211 | 211 | break; |
| 212 | 212 | |
| 213 | 213 | err = msleep_interruptible(timeout_ms); |
| 214 | − if (err != 0) | |
| 214 | + if (err != 0) { | |
| 215 | + nfp_info(mutex->cpp, | |
| 216 | + "interrupted waiting for NFP mutex\n"); | |
| 215 | 217 | return -ERESTARTSYS; |
| 218 | + } | |
| 216 | 219 | |
| 217 | 220 | if (time_is_before_eq_jiffies(warn_at)) { |
| 218 | 221 | warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ; |
| @@ -281,8 +281,7 @@ nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg, u32 nsp_cpp, u64 addr, · 280 unmodified lines | ||
| 281 | 281 | if ((*reg & mask) == val) |
| 282 | 282 | return 0; |
| 283 | 283 | |
| 284 | − if (msleep_interruptible(25)) | |
| 285 | − return -ERESTARTSYS; | |
| 284 | + msleep(25); | |
| 286 | 285 | |
| 287 | 286 | if (time_after(start_time, wait_until)) |
| 288 | 287 | return -ETIMEDOUT; |
| @@ -2370,7 +2370,7 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb) · 2369 unmodified lines | ||
| 2370 | 2370 | u8 flags = 0; |
| 2371 | 2371 | |
| 2372 | 2372 | if (unlikely(skb->ip_summed != CHECKSUM_NONE)) { |
| 2373 | − DP_INFO(cdev, "Cannot transmit a checksumed packet\n"); | |
| 2373 | + DP_INFO(cdev, "Cannot transmit a checksummed packet\n"); | |
| 2374 | 2374 | return -EINVAL; |
| 2375 | 2375 | } |
| 2376 | 2376 | |
| @@ -848,7 +848,7 @@ int qed_roce_query_qp(struct qed_hwfn *p_hwfn, · 847 unmodified lines | ||
| 848 | 848 | |
| 849 | 849 | if (!(qp->resp_offloaded)) { |
| 850 | 850 | DP_NOTICE(p_hwfn, |
| 851 | − "The responder's qp should be offloded before requester's\n"); | |
| 851 | + "The responder's qp should be offloaded before requester's\n"); | |
| 852 | 852 | return -EINVAL; |
| 853 | 853 | } |
| 854 | 854 | |
| @@ -350,15 +350,16 @@ static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev) · 349 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | real_dev = priv->real_dev; |
| 352 | 352 | |
| 353 | − if (!rmnet_is_real_dev_registered(real_dev)) | |
| 354 | − return -ENODEV; | |
| 355 | − | |
| 356 | 353 | if (nla_put_u16(skb, IFLA_RMNET_MUX_ID, priv->mux_id)) |
| 357 | 354 | goto nla_put_failure; |
| 358 | 355 | |
| 359 | − port = rmnet_get_port_rtnl(real_dev); | |
| 356 | + if (rmnet_is_real_dev_registered(real_dev)) { | |
| 357 | + port = rmnet_get_port_rtnl(real_dev); | |
| 358 | + f.flags = port->data_format; | |
| 359 | + } else { | |
| 360 | + f.flags = 0; | |
| 361 | + } | |
| 360 | 362 | |
| 361 | − f.flags = port->data_format; | |
| 362 | 363 | f.mask = ~0; |
| 363 | 364 | |
| 364 | 365 | if (nla_put(skb, IFLA_RMNET_FLAGS, sizeof(f), &f)) |
| @@ -2224,7 +2224,7 @@ static void rtl8139_poll_controller(struct net_device *dev) · 2223 unmodified lines | ||
| 2224 | 2224 | struct rtl8139_private *tp = netdev_priv(dev); |
| 2225 | 2225 | const int irq = tp->pci_dev->irq; |
| 2226 | 2226 | |
| 2227 | − disable_irq(irq); | |
| 2227 | + disable_irq_nosync(irq); | |
| 2228 | 2228 | rtl8139_interrupt(irq, dev); |
| 2229 | 2229 | enable_irq(irq); |
| 2230 | 2230 | } |
| @@ -3999,29 +3999,6 @@ static void efx_ef10_prepare_flr(struct efx_nic *efx) · 3998 unmodified lines | ||
| 3999 | 3999 | atomic_set(&efx->active_queues, 0); |
| 4000 | 4000 | } |
| 4001 | 4001 | |
| 4002 | −static bool efx_ef10_filter_equal(const struct efx_filter_spec *left, | |
| 4003 | − const struct efx_filter_spec *right) | |
| 4004 | −{ | |
| 4005 | − if ((left->match_flags ^ right->match_flags) | | |
| 4006 | − ((left->flags ^ right->flags) & | |
| 4007 | − (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX))) | |
| 4008 | − return false; | |
| 4009 | − | |
| 4010 | − return memcmp(&left->outer_vid, &right->outer_vid, | |
| 4011 | − sizeof(struct efx_filter_spec) - | |
| 4012 | − offsetof(struct efx_filter_spec, outer_vid)) == 0; | |
| 4013 | −} | |
| 4014 | − | |
| 4015 | −static unsigned int efx_ef10_filter_hash(const struct efx_filter_spec *spec) | |
| 4016 | −{ | |
| 4017 | − BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3); | |
| 4018 | − return jhash2((const u32 *)&spec->outer_vid, | |
| 4019 | − (sizeof(struct efx_filter_spec) - | |
| 4020 | − offsetof(struct efx_filter_spec, outer_vid)) / 4, | |
| 4021 | − 0); | |
| 4022 | − /* XXX should we randomise the initval? */ | |
| 4023 | −} | |
| 4024 | − | |
| 4025 | 4002 | /* Decide whether a filter should be exclusive or else should allow |
| 4026 | 4003 | * delivery to additional recipients. Currently we decide that |
| 4027 | 4004 | * filters for specific local unicast MAC and IP addresses are |
| @@ -4346,7 +4323,7 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx, · 318 unmodified lines | ||
| 4346 | 4323 | goto out_unlock; |
| 4347 | 4324 | match_pri = rc; |
| 4348 | 4325 | |
| 4349 | − hash = efx_ef10_filter_hash(spec); | |
| 4326 | + hash = efx_filter_spec_hash(spec); | |
| 4350 | 4327 | is_mc_recip = efx_filter_is_mc_recipient(spec); |
| 4351 | 4328 | if (is_mc_recip) |
| 4352 | 4329 | bitmap_zero(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT); |
| @@ -4378,7 +4355,7 @@ static s32 efx_ef10_filter_insert(struct efx_nic *efx, · 25 unmodified lines | ||
| 4378 | 4355 | if (!saved_spec) { |
| 4379 | 4356 | if (ins_index < 0) |
| 4380 | 4357 | ins_index = i; |
| 4381 | − } else if (efx_ef10_filter_equal(spec, saved_spec)) { | |
| 4358 | + } else if (efx_filter_spec_equal(spec, saved_spec)) { | |
| 4382 | 4359 | if (spec->priority < saved_spec->priority && |
| 4383 | 4360 | spec->priority != EFX_FILTER_PRI_AUTO) { |
| 4384 | 4361 | rc = -EPERM; |
| @@ -4762,28 +4739,63 @@ static s32 efx_ef10_filter_get_rx_ids(struct efx_nic *efx, · 377 unmodified lines | ||
| 4762 | 4739 | static bool efx_ef10_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, |
| 4763 | 4740 | unsigned int filter_idx) |
| 4764 | 4741 | { |
| 4742 | + struct efx_filter_spec *spec, saved_spec; | |
| 4765 | 4743 | struct efx_ef10_filter_table *table; |
| 4766 | − struct efx_filter_spec *spec; | |
| 4767 | − bool ret; | |
| 4744 | + struct efx_arfs_rule *rule = NULL; | |
| 4745 | + bool ret = true, force = false; | |
| 4746 | + u16 arfs_id; | |
| 4768 | 4747 | |
| 4769 | 4748 | down_read(&efx->filter_sem); |
| 4770 | 4749 | table = efx->filter_state; |
| 4771 | 4750 | down_write(&table->lock); |
| 4772 | 4751 | spec = efx_ef10_filter_entry_spec(table, filter_idx); |
| 4773 | 4752 | |
| 4774 | − if (!spec || spec->priority != EFX_FILTER_PRI_HINT) { | |
| 4775 | − ret = true; | |
| 4753 | + if (!spec || spec->priority != EFX_FILTER_PRI_HINT) | |
| 4776 | 4754 | goto out_unlock; |
| 4777 | − } | |
| 4778 | 4755 | |
| 4779 | − if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id, | |
| 4780 | − flow_id, filter_idx)) { | |
| 4756 | + spin_lock_bh(&efx->rps_hash_lock); | |
| 4757 | + if (!efx->rps_hash_table) { | |
| 4758 | + /* In the absence of the table, we always return 0 to ARFS. */ | |
| 4759 | + arfs_id = 0; | |
| 4760 | + } else { | |
| 4761 | + rule = efx_rps_hash_find(efx, spec); | |
| 4762 | + if (!rule) | |
| 4763 | + /* ARFS table doesn't know of this filter, so remove it */ | |
| 4764 | + goto expire; | |
| 4765 | + arfs_id = rule->arfs_id; | |
| 4766 | + ret = efx_rps_check_rule(rule, filter_idx, &force); | |
| 4767 | + if (force) | |
| 4768 | + goto expire; | |
| 4769 | + if (!ret) { | |
| 4770 | + spin_unlock_bh(&efx->rps_hash_lock); | |
| 4771 | + goto out_unlock; | |
| 4772 | + } | |
| 4773 | + } | |
| 4774 | + if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id, flow_id, arfs_id)) | |
| 4781 | 4775 | ret = false; |
| 4782 | − goto out_unlock; | |
| 4776 | + else if (rule) | |
| 4777 | + rule->filter_id = EFX_ARFS_FILTER_ID_REMOVING; | |
| 4778 | +expire: | |
| 4779 | + saved_spec = *spec; /* remove operation will kfree spec */ | |
| 4780 | + spin_unlock_bh(&efx->rps_hash_lock); | |
| 4781 | + /* At this point (since we dropped the lock), another thread might queue | |
| 4782 | + * up a fresh insertion request (but the actual insertion will be held | |
| 4783 | + * up by our possession of the filter table lock). In that case, it | |
| 4784 | + * will set rule->filter_id to EFX_ARFS_FILTER_ID_PENDING, meaning that | |
| 4785 | + * the rule is not removed by efx_rps_hash_del() below. | |
| 4786 | + */ | |
| 4787 | + if (ret) | |
| 4788 | + ret = efx_ef10_filter_remove_internal(efx, 1U << spec->priority, | |
| 4789 | + filter_idx, true) == 0; | |
| 4790 | + /* While we can't safely dereference rule (we dropped the lock), we can | |
| 4791 | + * still test it for NULL. | |
| 4792 | + */ | |
| 4793 | + if (ret && rule) { | |
| 4794 | + /* Expiring, so remove entry from ARFS table */ | |
| 4795 | + spin_lock_bh(&efx->rps_hash_lock); | |
| 4796 | + efx_rps_hash_del(efx, &saved_spec); | |
| 4797 | + spin_unlock_bh(&efx->rps_hash_lock); | |
| 4783 | 4798 | } |
| 4784 | − | |
| 4785 | − ret = efx_ef10_filter_remove_internal(efx, 1U << spec->priority, | |
| 4786 | − filter_idx, true) == 0; | |
| 4787 | 4799 | out_unlock: |
| 4788 | 4800 | up_write(&table->lock); |
| 4789 | 4801 | up_read(&efx->filter_sem); |
| @@ -5265,7 +5277,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx, · 475 unmodified lines | ||
| 5265 | 5277 | ids = vlan->uc; |
| 5266 | 5278 | } |
| 5267 | 5279 | |
| 5268 | − filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0; | |
| 5280 | + filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0; | |
| 5269 | 5281 | |
| 5270 | 5282 | /* Insert/renew filters */ |
| 5271 | 5283 | for (i = 0; i < addr_count; i++) { |
| @@ -5334,7 +5346,7 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx, · 62 unmodified lines | ||
| 5334 | 5346 | int rc; |
| 5335 | 5347 | u16 *id; |
| 5336 | 5348 | |
| 5337 | − filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0; | |
| 5349 | + filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0; | |
| 5338 | 5350 | |
| 5339 | 5351 | efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0); |
| 5340 | 5352 | |
| @@ -3027,6 +3027,10 @@ static int efx_init_struct(struct efx_nic *efx, · 3026 unmodified lines | ||
| 3027 | 3027 | mutex_init(&efx->mac_lock); |
| 3028 | 3028 | #ifdef CONFIG_RFS_ACCEL |
| 3029 | 3029 | mutex_init(&efx->rps_mutex); |
| 3030 | + spin_lock_init(&efx->rps_hash_lock); | |
| 3031 | + /* Failure to allocate is not fatal, but may degrade ARFS performance */ | |
| 3032 | + efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE, | |
| 3033 | + sizeof(*efx->rps_hash_table), GFP_KERNEL); | |
| 3030 | 3034 | #endif |
| 3031 | 3035 | efx->phy_op = &efx_dummy_phy_operations; |
| 3032 | 3036 | efx->mdio.dev = net_dev; |
| @@ -3070,6 +3074,10 @@ static void efx_fini_struct(struct efx_nic *efx) · 37 unmodified lines | ||
| 3070 | 3074 | { |
| 3071 | 3075 | int i; |
| 3072 | 3076 | |
| 3077 | +#ifdef CONFIG_RFS_ACCEL | |
| 3078 | + kfree(efx->rps_hash_table); | |
| 3079 | +#endif | |
| 3080 | + | |
| 3073 | 3081 | for (i = 0; i < EFX_MAX_CHANNELS; i++) |
| 3074 | 3082 | kfree(efx->channel[i]); |
| 3075 | 3083 | |
| @@ -3092,6 +3100,141 @@ void efx_update_sw_stats(struct efx_nic *efx, u64 *stats) · 16 unmodified lines | ||
| 3092 | 3100 | stats[GENERIC_STAT_rx_noskb_drops] = atomic_read(&efx->n_rx_noskb_drops); |
| 3093 | 3101 | } |
| 3094 | 3102 | |
| 3103 | +bool efx_filter_spec_equal(const struct efx_filter_spec *left, | |
| 3104 | + const struct efx_filter_spec *right) | |
| 3105 | +{ | |
| 3106 | + if ((left->match_flags ^ right->match_flags) | | |
| 3107 | + ((left->flags ^ right->flags) & | |
| 3108 | + (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX))) | |
| 3109 | + return false; | |
| 3110 | + | |
| 3111 | + return memcmp(&left->outer_vid, &right->outer_vid, | |
| 3112 | + sizeof(struct efx_filter_spec) - | |
| 3113 | + offsetof(struct efx_filter_spec, outer_vid)) == 0; | |
| 3114 | +} | |
| 3115 | + | |
| 3116 | +u32 efx_filter_spec_hash(const struct efx_filter_spec *spec) | |
| 3117 | +{ | |
| 3118 | + BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3); | |
| 3119 | + return jhash2((const u32 *)&spec->outer_vid, | |
| 3120 | + (sizeof(struct efx_filter_spec) - | |
| 3121 | + offsetof(struct efx_filter_spec, outer_vid)) / 4, | |
| 3122 | + 0); | |
| 3123 | +} | |
| 3124 | + | |
| 3125 | +#ifdef CONFIG_RFS_ACCEL | |
| 3126 | +bool efx_rps_check_rule(struct efx_arfs_rule *rule, unsigned int filter_idx, | |
| 3127 | + bool *force) | |
| 3128 | +{ | |
| 3129 | + if (rule->filter_id == EFX_ARFS_FILTER_ID_PENDING) { | |
| 3130 | + /* ARFS is currently updating this entry, leave it */ | |
| 3131 | + return false; | |
| 3132 | + } | |
| 3133 | + if (rule->filter_id == EFX_ARFS_FILTER_ID_ERROR) { | |
| 3134 | + /* ARFS tried and failed to update this, so it's probably out | |
| 3135 | + * of date. Remove the filter and the ARFS rule entry. | |
| 3136 | + */ | |
| 3137 | + rule->filter_id = EFX_ARFS_FILTER_ID_REMOVING; | |
| 3138 | + *force = true; | |
| 3139 | + return true; | |
| 3140 | + } else if (WARN_ON(rule->filter_id != filter_idx)) { /* can't happen */ | |
| 3141 | + /* ARFS has moved on, so old filter is not needed. Since we did | |
| 3142 | + * not mark the rule with EFX_ARFS_FILTER_ID_REMOVING, it will | |
| 3143 | + * not be removed by efx_rps_hash_del() subsequently. | |
| 3144 | + */ | |
| 3145 | + *force = true; | |
| 3146 | + return true; | |
| 3147 | + } | |
| 3148 | + /* Remove it iff ARFS wants to. */ | |
| 3149 | + return true; | |
| 3150 | +} | |
| 3151 | + | |
| 3152 | +struct hlist_head *efx_rps_hash_bucket(struct efx_nic *efx, | |
| 3153 | + const struct efx_filter_spec *spec) | |
| 3154 | +{ | |
| 3155 | + u32 hash = efx_filter_spec_hash(spec); | |
| 3156 | + | |
| 3157 | + WARN_ON(!spin_is_locked(&efx->rps_hash_lock)); | |
| 3158 | + if (!efx->rps_hash_table) | |
| 3159 | + return NULL; | |
| 3160 | + return &efx->rps_hash_table[hash % EFX_ARFS_HASH_TABLE_SIZE]; | |
| 3161 | +} | |
| 3162 | + | |
| 3163 | +struct efx_arfs_rule *efx_rps_hash_find(struct efx_nic *efx, | |
| 3164 | + const struct efx_filter_spec *spec) | |
| 3165 | +{ | |
| 3166 | + struct efx_arfs_rule *rule; | |
| 3167 | + struct hlist_head *head; | |
| 3168 | + struct hlist_node *node; | |
| 3169 | + | |
| 3170 | + head = efx_rps_hash_bucket(efx, spec); | |
| 3171 | + if (!head) | |
| 3172 | + return NULL; | |
| 3173 | + hlist_for_each(node, head) { | |
| 3174 | + rule = container_of(node, struct efx_arfs_rule, node); | |
| 3175 | + if (efx_filter_spec_equal(spec, &rule->spec)) | |
| 3176 | + return rule; | |
| 3177 | + } | |
| 3178 | + return NULL; | |
| 3179 | +} | |
| 3180 | + | |
| 3181 | +struct efx_arfs_rule *efx_rps_hash_add(struct efx_nic *efx, | |
| 3182 | + const struct efx_filter_spec *spec, | |
| 3183 | + bool *new) | |
| 3184 | +{ | |
| 3185 | + struct efx_arfs_rule *rule; | |
| 3186 | + struct hlist_head *head; | |
| 3187 | + struct hlist_node *node; | |
| 3188 | + | |
| 3189 | + head = efx_rps_hash_bucket(efx, spec); | |
| 3190 | + if (!head) | |
| 3191 | + return NULL; | |
| 3192 | + hlist_for_each(node, head) { | |
| 3193 | + rule = container_of(node, struct efx_arfs_rule, node); | |
| 3194 | + if (efx_filter_spec_equal(spec, &rule->spec)) { | |
| 3195 | + *new = false; | |
| 3196 | + return rule; | |
| 3197 | + } | |
| 3198 | + } | |
| 3199 | + rule = kmalloc(sizeof(*rule), GFP_ATOMIC); | |
| 3200 | + *new = true; | |
| 3201 | + if (rule) { | |
| 3202 | + memcpy(&rule->spec, spec, sizeof(rule->spec)); | |
| 3203 | + hlist_add_head(&rule->node, head); | |
| 3204 | + } | |
| 3205 | + return rule; | |
| 3206 | +} | |
| 3207 | + | |
| 3208 | +void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec) | |
| 3209 | +{ | |
| 3210 | + struct efx_arfs_rule *rule; | |
| 3211 | + struct hlist_head *head; | |
| 3212 | + struct hlist_node *node; | |
| 3213 | + | |
| 3214 | + head = efx_rps_hash_bucket(efx, spec); | |
| 3215 | + if (WARN_ON(!head)) | |
| 3216 | + return; | |
| 3217 | + hlist_for_each(node, head) { | |
| 3218 | + rule = container_of(node, struct efx_arfs_rule, node); | |
| 3219 | + if (efx_filter_spec_equal(spec, &rule->spec)) { | |
| 3220 | + /* Someone already reused the entry. We know that if | |
| 3221 | + * this check doesn't fire (i.e. filter_id == REMOVING) | |
| 3222 | + * then the REMOVING mark was put there by our caller, | |
| 3223 | + * because caller is holding a lock on filter table and | |
| 3224 | + * only holders of that lock set REMOVING. | |
| 3225 | + */ | |
| 3226 | + if (rule->filter_id != EFX_ARFS_FILTER_ID_REMOVING) | |
| 3227 | + return; | |
| 3228 | + hlist_del(node); | |
| 3229 | + kfree(rule); | |
| 3230 | + return; | |
| 3231 | + } | |
| 3232 | + } | |
| 3233 | + /* We didn't find it. */ | |
| 3234 | + WARN_ON(1); | |
| 3235 | +} | |
| 3236 | +#endif | |
| 3237 | + | |
| 3095 | 3238 | /* RSS contexts. We're using linked lists and crappy O(n) algorithms, because |
| 3096 | 3239 | * (a) this is an infrequent control-plane operation and (b) n is small (max 64) |
| 3097 | 3240 | */ |
| @@ -186,6 +186,27 @@ static inline void efx_filter_rfs_expire(struct work_struct *data) {} · 185 unmodified lines | ||
| 186 | 186 | #endif |
| 187 | 187 | bool efx_filter_is_mc_recipient(const struct efx_filter_spec *spec); |
| 188 | 188 | |
| 189 | +bool efx_filter_spec_equal(const struct efx_filter_spec *left, | |
| 190 | + const struct efx_filter_spec *right); | |
| 191 | +u32 efx_filter_spec_hash(const struct efx_filter_spec *spec); | |
| 192 | + | |
| 193 | +#ifdef CONFIG_RFS_ACCEL | |
| 194 | +bool efx_rps_check_rule(struct efx_arfs_rule *rule, unsigned int filter_idx, | |
| 195 | + bool *force); | |
| 196 | + | |
| 197 | +struct efx_arfs_rule *efx_rps_hash_find(struct efx_nic *efx, | |
| 198 | + const struct efx_filter_spec *spec); | |
| 199 | + | |
| 200 | +/* @new is written to indicate if entry was newly added (true) or if an old | |
| 201 | + * entry was found and returned (false). | |
| 202 | + */ | |
| 203 | +struct efx_arfs_rule *efx_rps_hash_add(struct efx_nic *efx, | |
| 204 | + const struct efx_filter_spec *spec, | |
| 205 | + bool *new); | |
| 206 | + | |
| 207 | +void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec); | |
| 208 | +#endif | |
| 209 | + | |
| 189 | 210 | /* RSS contexts */ |
| 190 | 211 | struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx); |
| 191 | 212 | struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id); |
| @@ -2905,18 +2905,45 @@ bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id, · 2904 unmodified lines | ||
| 2905 | 2905 | { |
| 2906 | 2906 | struct efx_farch_filter_state *state = efx->filter_state; |
| 2907 | 2907 | struct efx_farch_filter_table *table; |
| 2908 | − bool ret = false; | |
| 2908 | + bool ret = false, force = false; | |
| 2909 | + u16 arfs_id; | |
| 2909 | 2910 | |
| 2910 | 2911 | down_write(&state->lock); |
| 2912 | + spin_lock_bh(&efx->rps_hash_lock); | |
| 2911 | 2913 | table = &state->table[EFX_FARCH_FILTER_TABLE_RX_IP]; |
| 2912 | 2914 | if (test_bit(index, table->used_bitmap) && |
| 2913 | − table->spec[index].priority == EFX_FILTER_PRI_HINT && | |
| 2914 | − rps_may_expire_flow(efx->net_dev, table->spec[index].dmaq_id, | |
| 2915 | − flow_id, index)) { | |
| 2916 | − efx_farch_filter_table_clear_entry(efx, table, index); | |
| 2917 | − ret = true; | |
| 2915 | + table->spec[index].priority == EFX_FILTER_PRI_HINT) { | |
| 2916 | + struct efx_arfs_rule *rule = NULL; | |
| 2917 | + struct efx_filter_spec spec; | |
| 2918 | + | |
| 2919 | + efx_farch_filter_to_gen_spec(&spec, &table->spec[index]); | |
| 2920 | + if (!efx->rps_hash_table) { | |
| 2921 | + /* In the absence of the table, we always returned 0 to | |
| 2922 | + * ARFS, so use the same to query it. | |
| 2923 | + */ | |
| 2924 | + arfs_id = 0; | |
| 2925 | + } else { | |
| 2926 | + rule = efx_rps_hash_find(efx, &spec); | |
| 2927 | + if (!rule) { | |
| 2928 | + /* ARFS table doesn't know of this filter, remove it */ | |
| 2929 | + force = true; | |
| 2930 | + } else { | |
| 2931 | + arfs_id = rule->arfs_id; | |
| 2932 | + if (!efx_rps_check_rule(rule, index, &force)) | |
| 2933 | + goto out_unlock; | |
| 2934 | + } | |
| 2935 | + } | |
| 2936 | + if (force || rps_may_expire_flow(efx->net_dev, spec.dmaq_id, | |
| 2937 | + flow_id, arfs_id)) { | |
| 2938 | + if (rule) | |
| 2939 | + rule->filter_id = EFX_ARFS_FILTER_ID_REMOVING; | |
| 2940 | + efx_rps_hash_del(efx, &spec); | |
| 2941 | + efx_farch_filter_table_clear_entry(efx, table, index); | |
| 2942 | + ret = true; | |
| 2943 | + } | |
| 2918 | 2944 | } |
| 2919 | − | |
| 2945 | +out_unlock: | |
| 2946 | + spin_unlock_bh(&efx->rps_hash_lock); | |
| 2920 | 2947 | up_write(&state->lock); |
| 2921 | 2948 | return ret; |
| 2922 | 2949 | } |
| @@ -733,6 +733,56 @@ struct efx_rss_context { · 732 unmodified lines | ||
| 733 | 733 | u32 rx_indir_table[128]; |
| 734 | 734 | }; |
| 735 | 735 | |
| 736 | +#ifdef CONFIG_RFS_ACCEL | |
| 737 | +/* Order of these is important, since filter_id >= %EFX_ARFS_FILTER_ID_PENDING | |
| 738 | + * is used to test if filter does or will exist. | |
| 739 | + */ | |
| 740 | +#define EFX_ARFS_FILTER_ID_PENDING -1 | |
| 741 | +#define EFX_ARFS_FILTER_ID_ERROR -2 | |
| 742 | +#define EFX_ARFS_FILTER_ID_REMOVING -3 | |
| 743 | +/** | |
| 744 | + * struct efx_arfs_rule - record of an ARFS filter and its IDs | |
| 745 | + * @node: linkage into hash table | |
| 746 | + * @spec: details of the filter (used as key for hash table). Use efx->type to | |
| 747 | + * determine which member to use. | |
| 748 | + * @rxq_index: channel to which the filter will steer traffic. | |
| 749 | + * @arfs_id: filter ID which was returned to ARFS | |
| 750 | + * @filter_id: index in software filter table. May be | |
| 751 | + * %EFX_ARFS_FILTER_ID_PENDING if filter was not inserted yet, | |
| 752 | + * %EFX_ARFS_FILTER_ID_ERROR if filter insertion failed, or | |
| 753 | + * %EFX_ARFS_FILTER_ID_REMOVING if expiry is currently removing the filter. | |
| 754 | + */ | |
| 755 | +struct efx_arfs_rule { | |
| 756 | + struct hlist_node node; | |
| 757 | + struct efx_filter_spec spec; | |
| 758 | + u16 rxq_index; | |
| 759 | + u16 arfs_id; | |
| 760 | + s32 filter_id; | |
| 761 | +}; | |
| 762 | + | |
| 763 | +/* Size chosen so that the table is one page (4kB) */ | |
| 764 | +#define EFX_ARFS_HASH_TABLE_SIZE 512 | |
| 765 | + | |
| 766 | +/** | |
| 767 | + * struct efx_async_filter_insertion - Request to asynchronously insert a filter | |
| 768 | + * @net_dev: Reference to the netdevice | |
| 769 | + * @spec: The filter to insert | |
| 770 | + * @work: Workitem for this request | |
| 771 | + * @rxq_index: Identifies the channel for which this request was made | |
| 772 | + * @flow_id: Identifies the kernel-side flow for which this request was made | |
| 773 | + */ | |
| 774 | +struct efx_async_filter_insertion { | |
| 775 | + struct net_device *net_dev; | |
| 776 | + struct efx_filter_spec spec; | |
| 777 | + struct work_struct work; | |
| 778 | + u16 rxq_index; | |
| 779 | + u32 flow_id; | |
| 780 | +}; | |
| 781 | + | |
| 782 | +/* Maximum number of ARFS workitems that may be in flight on an efx_nic */ | |
| 783 | +#define EFX_RPS_MAX_IN_FLIGHT 8 | |
| 784 | +#endif /* CONFIG_RFS_ACCEL */ | |
| 785 | + | |
| 736 | 786 | /** |
| 737 | 787 | * struct efx_nic - an Efx NIC |
| 738 | 788 | * @name: Device name (net device name or bus id before net device registered) |
| @@ -850,6 +900,12 @@ struct efx_rss_context { · 111 unmodified lines | ||
| 850 | 900 | * @rps_expire_channel: Next channel to check for expiry |
| 851 | 901 | * @rps_expire_index: Next index to check for expiry in |
| 852 | 902 | * @rps_expire_channel's @rps_flow_id |
| 903 | + * @rps_slot_map: bitmap of in-flight entries in @rps_slot | |
| 904 | + * @rps_slot: array of ARFS insertion requests for efx_filter_rfs_work() | |
| 905 | + * @rps_hash_lock: Protects ARFS filter mapping state (@rps_hash_table and | |
| 906 | + * @rps_next_id). | |
| 907 | + * @rps_hash_table: Mapping between ARFS filters and their various IDs | |
| 908 | + * @rps_next_id: next arfs_id for an ARFS filter | |
| 853 | 909 | * @active_queues: Count of RX and TX queues that haven't been flushed and drained. |
| 854 | 910 | * @rxq_flush_pending: Count of number of receive queues that need to be flushed. |
| 855 | 911 | * Decremented when the efx_flush_rx_queue() is called. |
| @@ -1004,6 +1060,11 @@ struct efx_nic { · 148 unmodified lines | ||
| 1004 | 1060 | struct mutex rps_mutex; |
| 1005 | 1061 | unsigned int rps_expire_channel; |
| 1006 | 1062 | unsigned int rps_expire_index; |
| 1063 | + unsigned long rps_slot_map; | |
| 1064 | + struct efx_async_filter_insertion rps_slot[EFX_RPS_MAX_IN_FLIGHT]; | |
| 1065 | + spinlock_t rps_hash_lock; | |
| 1066 | + struct hlist_head *rps_hash_table; | |
| 1067 | + u32 rps_next_id; | |
| 1007 | 1068 | #endif |
| 1008 | 1069 | |
| 1009 | 1070 | atomic_t active_queues; |
| @@ -827,31 +827,38 @@ MODULE_PARM_DESC(rx_refill_threshold, · 826 unmodified lines | ||
| 827 | 827 | |
| 828 | 828 | #ifdef CONFIG_RFS_ACCEL |
| 829 | 829 | |
| 830 | −/** | |
| 831 | − * struct efx_async_filter_insertion - Request to asynchronously insert a filter | |
| 832 | − * @net_dev: Reference to the netdevice | |
| 833 | − * @spec: The filter to insert | |
| 834 | − * @work: Workitem for this request | |
| 835 | − * @rxq_index: Identifies the channel for which this request was made | |
| 836 | − * @flow_id: Identifies the kernel-side flow for which this request was made | |
| 837 | − */ | |
| 838 | −struct efx_async_filter_insertion { | |
| 839 | − struct net_device *net_dev; | |
| 840 | − struct efx_filter_spec spec; | |
| 841 | − struct work_struct work; | |
| 842 | − u16 rxq_index; | |
| 843 | − u32 flow_id; | |
| 844 | −}; | |
| 845 | − | |
| 846 | 830 | static void efx_filter_rfs_work(struct work_struct *data) |
| 847 | 831 | { |
| 848 | 832 | struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion, |
| 849 | 833 | work); |
| 850 | 834 | struct efx_nic *efx = netdev_priv(req->net_dev); |
| 851 | 835 | struct efx_channel *channel = efx_get_channel(efx, req->rxq_index); |
| 836 | + int slot_idx = req - efx->rps_slot; | |
| 837 | + struct efx_arfs_rule *rule; | |
| 838 | + u16 arfs_id = 0; | |
| 852 | 839 | int rc; |
| 853 | 840 | |
| 854 | − rc = efx->type->filter_insert(efx, &req->spec, false); | |
| 841 | + rc = efx->type->filter_insert(efx, &req->spec, true); | |
| 842 | + if (rc >= 0) | |
| 843 | + rc %= efx->type->max_rx_ip_filters; | |
| 844 | + if (efx->rps_hash_table) { | |
| 845 | + spin_lock_bh(&efx->rps_hash_lock); | |
| 846 | + rule = efx_rps_hash_find(efx, &req->spec); | |
| 847 | + /* The rule might have already gone, if someone else's request | |
| 848 | + * for the same spec was already worked and then expired before | |
| 849 | + * we got around to our work. In that case we have nothing | |
| 850 | + * tying us to an arfs_id, meaning that as soon as the filter | |
| 851 | + * is considered for expiry it will be removed. | |
| 852 | + */ | |
| 853 | + if (rule) { | |
| 854 | + if (rc < 0) | |
| 855 | + rule->filter_id = EFX_ARFS_FILTER_ID_ERROR; | |
| 856 | + else | |
| 857 | + rule->filter_id = rc; | |
| 858 | + arfs_id = rule->arfs_id; | |
| 859 | + } | |
| 860 | + spin_unlock_bh(&efx->rps_hash_lock); | |
| 861 | + } | |
| 855 | 862 | if (rc >= 0) { |
| 856 | 863 | /* Remember this so we can check whether to expire the filter |
| 857 | 864 | * later. |
| @@ -863,23 +870,23 @@ static void efx_filter_rfs_work(struct work_struct *data) · 5 unmodified lines | ||
| 863 | 870 | |
| 864 | 871 | if (req->spec.ether_type == htons(ETH_P_IP)) |
| 865 | 872 | netif_info(efx, rx_status, efx->net_dev, |
| 866 | − "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", | |
| 873 | + "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d id %u]\n", | |
| 867 | 874 | (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", |
| 868 | 875 | req->spec.rem_host, ntohs(req->spec.rem_port), |
| 869 | 876 | req->spec.loc_host, ntohs(req->spec.loc_port), |
| 870 | − req->rxq_index, req->flow_id, rc); | |
| 877 | + req->rxq_index, req->flow_id, rc, arfs_id); | |
| 871 | 878 | else |
| 872 | 879 | netif_info(efx, rx_status, efx->net_dev, |
| 873 | − "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d]\n", | |
| 880 | + "steering %s [%pI6]:%u:[%pI6]:%u to queue %u [flow %u filter %d id %u]\n", | |
| 874 | 881 | (req->spec.ip_proto == IPPROTO_TCP) ? "TCP" : "UDP", |
| 875 | 882 | req->spec.rem_host, ntohs(req->spec.rem_port), |
| 876 | 883 | req->spec.loc_host, ntohs(req->spec.loc_port), |
| 877 | − req->rxq_index, req->flow_id, rc); | |
| 884 | + req->rxq_index, req->flow_id, rc, arfs_id); | |
| 878 | 885 | } |
| 879 | 886 | |
| 880 | 887 | /* Release references */ |
| 888 | + clear_bit(slot_idx, &efx->rps_slot_map); | |
| 881 | 889 | dev_put(req->net_dev); |
| 882 | − kfree(req); | |
| 883 | 890 | } |
| 884 | 891 | |
| 885 | 892 | int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, |
| @@ -887,23 +894,39 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, · 1 unmodified line | ||
| 887 | 894 | { |
| 888 | 895 | struct efx_nic *efx = netdev_priv(net_dev); |
| 889 | 896 | struct efx_async_filter_insertion *req; |
| 897 | + struct efx_arfs_rule *rule; | |
| 890 | 898 | struct flow_keys fk; |
| 899 | + int slot_idx; | |
| 900 | + bool new; | |
| 901 | + int rc; | |
| 891 | 902 | |
| 892 | − if (flow_id == RPS_FLOW_ID_INVALID) | |
| 893 | − return -EINVAL; | |
| 903 | + /* find a free slot */ | |
| 904 | + for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++) | |
| 905 | + if (!test_and_set_bit(slot_idx, &efx->rps_slot_map)) | |
| 906 | + break; | |
| 907 | + if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT) | |
| 908 | + return -EBUSY; | |
| 894 | 909 | |
| 895 | − if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) | |
| 896 | − return -EPROTONOSUPPORT; | |
| 910 | + if (flow_id == RPS_FLOW_ID_INVALID) { | |
| 911 | + rc = -EINVAL; | |
| 912 | + goto out_clear; | |
| 913 | + } | |
| 897 | 914 | |
| 898 | − if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) | |
| 899 | − return -EPROTONOSUPPORT; | |
| 900 | − if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) | |
| 901 | − return -EPROTONOSUPPORT; | |
| 915 | + if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) { | |
| 916 | + rc = -EPROTONOSUPPORT; | |
| 917 | + goto out_clear; | |
| 918 | + } | |
| 902 | 919 | |
| 903 | − req = kmalloc(sizeof(*req), GFP_ATOMIC); | |
| 904 | − if (!req) | |
| 905 | − return -ENOMEM; | |
| 920 | + if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) { | |
| 921 | + rc = -EPROTONOSUPPORT; | |
| 922 | + goto out_clear; | |
| 923 | + } | |
| 924 | + if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) { | |
| 925 | + rc = -EPROTONOSUPPORT; | |
| 926 | + goto out_clear; | |
| 927 | + } | |
| 906 | 928 | |
| 929 | + req = efx->rps_slot + slot_idx; | |
| 907 | 930 | efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT, |
| 908 | 931 | efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0, |
| 909 | 932 | rxq_index); |
| @@ -927,12 +950,45 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, · 17 unmodified lines | ||
| 927 | 950 | req->spec.rem_port = fk.ports.src; |
| 928 | 951 | req->spec.loc_port = fk.ports.dst; |
| 929 | 952 | |
| 953 | + if (efx->rps_hash_table) { | |
| 954 | + /* Add it to ARFS hash table */ | |
| 955 | + spin_lock(&efx->rps_hash_lock); | |
| 956 | + rule = efx_rps_hash_add(efx, &req->spec, &new); | |
| 957 | + if (!rule) { | |
| 958 | + rc = -ENOMEM; | |
| 959 | + goto out_unlock; | |
| 960 | + } | |
| 961 | + if (new) | |
| 962 | + rule->arfs_id = efx->rps_next_id++ % RPS_NO_FILTER; | |
| 963 | + rc = rule->arfs_id; | |
| 964 | + /* Skip if existing or pending filter already does the right thing */ | |
| 965 | + if (!new && rule->rxq_index == rxq_index && | |
| 966 | + rule->filter_id >= EFX_ARFS_FILTER_ID_PENDING) | |
| 967 | + goto out_unlock; | |
| 968 | + rule->rxq_index = rxq_index; | |
| 969 | + rule->filter_id = EFX_ARFS_FILTER_ID_PENDING; | |
| 970 | + spin_unlock(&efx->rps_hash_lock); | |
| 971 | + } else { | |
| 972 | + /* Without an ARFS hash table, we just use arfs_id 0 for all | |
| 973 | + * filters. This means if multiple flows hash to the same | |
| 974 | + * flow_id, all but the most recently touched will be eligible | |
| 975 | + * for expiry. | |
| 976 | + */ | |
| 977 | + rc = 0; | |
| 978 | + } | |
| 979 | + | |
| 980 | + /* Queue the request */ | |
| 930 | 981 | dev_hold(req->net_dev = net_dev); |
| 931 | 982 | INIT_WORK(&req->work, efx_filter_rfs_work); |
| 932 | 983 | req->rxq_index = rxq_index; |
| 933 | 984 | req->flow_id = flow_id; |
| 934 | 985 | schedule_work(&req->work); |
| 935 | − return 0; | |
| 986 | + return rc; | |
| 987 | +out_unlock: | |
| 988 | + spin_unlock(&efx->rps_hash_lock); | |
| 989 | +out_clear: | |
| 990 | + clear_bit(slot_idx, &efx->rps_slot_map); | |
| 991 | + return rc; | |
| 936 | 992 | } |
| 937 | 993 | |
| 938 | 994 | bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned int quota) |
| @@ -347,7 +347,7 @@ enum power_event { · 346 unmodified lines | ||
| 347 | 347 | #define MTL_RX_OVERFLOW_INT BIT(16) |
| 348 | 348 | |
| 349 | 349 | /* Default operating mode of the MAC */ |
| 350 | −#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | GMAC_CONFIG_ACS | \ | |
| 350 | +#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | \ | |
| 351 | 351 | GMAC_CONFIG_BE | GMAC_CONFIG_DCRS) |
| 352 | 352 | |
| 353 | 353 | /* To dump the core regs excluding the Address Registers */ |
| @@ -31,13 +31,6 @@ static void dwmac4_core_init(struct mac_device_info *hw, · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | value |= GMAC_CORE_INIT; |
| 33 | 33 | |
| 34 | − /* Clear ACS bit because Ethernet switch tagging formats such as | |
| 35 | − * Broadcom tags can look like invalid LLC/SNAP packets and cause the | |
| 36 | − * hardware to truncate packets on reception. | |
| 37 | − */ | |
| 38 | − if (netdev_uses_dsa(dev)) | |
| 39 | − value &= ~GMAC_CONFIG_ACS; | |
| 40 | − | |
| 41 | 34 | if (mtu > 1500) |
| 42 | 35 | value |= GMAC_CONFIG_2K; |
| 43 | 36 | if (mtu > 2000) |
| @@ -3495,8 +3495,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) · 3494 unmodified lines | ||
| 3495 | 3495 | |
| 3496 | 3496 | /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 |
| 3497 | 3497 | * Type frames (LLC/LLC-SNAP) |
| 3498 | + * | |
| 3499 | + * llc_snap is never checked in GMAC >= 4, so this ACS | |
| 3500 | + * feature is always disabled and packets need to be | |
| 3501 | + * stripped manually. | |
| 3498 | 3502 | */ |
| 3499 | − if (unlikely(status != llc_snap)) | |
| 3503 | + if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) || | |
| 3504 | + unlikely(status != llc_snap)) | |
| 3500 | 3505 | frame_len -= ETH_FCS_LEN; |
| 3501 | 3506 | |
| 3502 | 3507 | if (netif_msg_rx_status(priv)) { |
| @@ -129,7 +129,7 @@ do { \ · 128 unmodified lines | ||
| 129 | 129 | |
| 130 | 130 | #define RX_PRIORITY_MAPPING 0x76543210 |
| 131 | 131 | #define TX_PRIORITY_MAPPING 0x33221100 |
| 132 | −#define CPDMA_TX_PRIORITY_MAP 0x01234567 | |
| 132 | +#define CPDMA_TX_PRIORITY_MAP 0x76543210 | |
| 133 | 133 | |
| 134 | 134 | #define CPSW_VLAN_AWARE BIT(1) |
| 135 | 135 | #define CPSW_RX_VLAN_ENCAP BIT(2) |
| @@ -1340,6 +1340,8 @@ static inline void cpsw_add_dual_emac_def_ale_entries( · 1204 unmodified lines | ||
| 1340 | 1340 | cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, |
| 1341 | 1341 | HOST_PORT_NUM, ALE_VLAN | |
| 1342 | 1342 | ALE_SECURE, slave->port_vlan); |
| 1343 | + cpsw_ale_control_set(cpsw->ale, slave_port, | |
| 1344 | + ALE_PORT_DROP_UNKNOWN_VLAN, 1); | |
| 1343 | 1345 | } |
| 1344 | 1346 | |
| 1345 | 1347 | static void soft_reset_slave(struct cpsw_slave *slave) |
| @@ -3277,7 +3277,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev, · 3276 unmodified lines | ||
| 3277 | 3277 | |
| 3278 | 3278 | err = netdev_upper_dev_link(real_dev, dev, extack); |
| 3279 | 3279 | if (err < 0) |
| 3280 | − goto put_dev; | |
| 3280 | + goto unregister; | |
| 3281 | 3281 | |
| 3282 | 3282 | /* need to be already registered so that ->init has run and |
| 3283 | 3283 | * the MAC addr is set |
| @@ -3316,8 +3316,7 @@ del_dev: · 32 unmodified lines | ||
| 3316 | 3316 | macsec_del_dev(macsec); |
| 3317 | 3317 | unlink: |
| 3318 | 3318 | netdev_upper_dev_unlink(real_dev, dev); |
| 3319 | −put_dev: | |
| 3320 | − dev_put(real_dev); | |
| 3319 | +unregister: | |
| 3321 | 3320 | unregister_netdevice(dev); |
| 3322 | 3321 | return err; |
| 3323 | 3322 | } |
| @@ -1393,6 +1393,15 @@ static int m88e1318_set_wol(struct phy_device *phydev, · 1392 unmodified lines | ||
| 1393 | 1393 | if (err < 0) |
| 1394 | 1394 | goto error; |
| 1395 | 1395 | |
| 1396 | + /* If WOL event happened once, the LED[2] interrupt pin | |
| 1397 | + * will not be cleared unless we reading the interrupt status | |
| 1398 | + * register. If interrupts are in use, the normal interrupt | |
| 1399 | + * handling will clear the WOL event. Clear the WOL event | |
| 1400 | + * before enabling it if !phy_interrupt_is_valid() | |
| 1401 | + */ | |
| 1402 | + if (!phy_interrupt_is_valid(phydev)) | |
| 1403 | + phy_read(phydev, MII_M1011_IEVENT); | |
| 1404 | + | |
| 1396 | 1405 | /* Enable the WOL interrupt */ |
| 1397 | 1406 | err = __phy_modify(phydev, MII_88E1318S_PHY_CSIER, 0, |
| 1398 | 1407 | MII_88E1318S_PHY_CSIER_WOL_EIE); |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/ethtool.h> |
| 21 | 21 | #include <linux/phy.h> |
| 22 | 22 | #include <linux/microchipphy.h> |
| 23 | +#include <linux/delay.h> | |
| 23 | 24 | |
| 24 | 25 | #define DRIVER_AUTHOR "WOOJUNG HUH <woojung.huh@microchip.com>" |
| 25 | 26 | #define DRIVER_DESC "Microchip LAN88XX PHY driver" |
| @@ -30,6 +31,16 @@ struct lan88xx_priv { · 4 unmodified lines | ||
| 30 | 31 | __u32 wolopts; |
| 31 | 32 | }; |
| 32 | 33 | |
| 34 | +static int lan88xx_read_page(struct phy_device *phydev) | |
| 35 | +{ | |
| 36 | + return __phy_read(phydev, LAN88XX_EXT_PAGE_ACCESS); | |
| 37 | +} | |
| 38 | + | |
| 39 | +static int lan88xx_write_page(struct phy_device *phydev, int page) | |
| 40 | +{ | |
| 41 | + return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page); | |
| 42 | +} | |
| 43 | + | |
| 33 | 44 | static int lan88xx_phy_config_intr(struct phy_device *phydev) |
| 34 | 45 | { |
| 35 | 46 | int rc; |
| @@ -66,6 +77,150 @@ static int lan88xx_suspend(struct phy_device *phydev) · 30 unmodified lines | ||
| 66 | 77 | return 0; |
| 67 | 78 | } |
| 68 | 79 | |
| 80 | +static int lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr, | |
| 81 | + u32 data) | |
| 82 | +{ | |
| 83 | + int val, save_page, ret = 0; | |
| 84 | + u16 buf; | |
| 85 | + | |
| 86 | + /* Save current page */ | |
| 87 | + save_page = phy_save_page(phydev); | |
| 88 | + if (save_page < 0) { | |
| 89 | + pr_warn("Failed to get current page\n"); | |
| 90 | + goto err; | |
| 91 | + } | |
| 92 | + | |
| 93 | + /* Switch to TR page */ | |
| 94 | + lan88xx_write_page(phydev, LAN88XX_EXT_PAGE_ACCESS_TR); | |
| 95 | + | |
| 96 | + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA, | |
| 97 | + (data & 0xFFFF)); | |
| 98 | + if (ret < 0) { | |
| 99 | + pr_warn("Failed to write TR low data\n"); | |
| 100 | + goto err; | |
| 101 | + } | |
| 102 | + | |
| 103 | + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA, | |
| 104 | + (data & 0x00FF0000) >> 16); | |
| 105 | + if (ret < 0) { | |
| 106 | + pr_warn("Failed to write TR high data\n"); | |
| 107 | + goto err; | |
| 108 | + } | |
| 109 | + | |
| 110 | + /* Config control bits [15:13] of register */ | |
| 111 | + buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */ | |
| 112 | + buf |= 0x8000; /* Set [15] to Packet transmit */ | |
| 113 | + | |
| 114 | + ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf); | |
| 115 | + if (ret < 0) { | |
| 116 | + pr_warn("Failed to write data in reg\n"); | |
| 117 | + goto err; | |
| 118 | + } | |
| 119 | + | |
| 120 | + usleep_range(1000, 2000);/* Wait for Data to be written */ | |
| 121 | + val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR); | |
| 122 | + if (!(val & 0x8000)) | |
| 123 | + pr_warn("TR Register[0x%X] configuration failed\n", regaddr); | |
| 124 | +err: | |
| 125 | + return phy_restore_page(phydev, save_page, ret); | |
| 126 | +} | |
| 127 | + | |
| 128 | +static void lan88xx_config_TR_regs(struct phy_device *phydev) | |
| 129 | +{ | |
| 130 | + int err; | |
| 131 | + | |
| 132 | + /* Get access to Channel 0x1, Node 0xF , Register 0x01. | |
| 133 | + * Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf, | |
| 134 | + * MrvlTrFix1000Kp, MasterEnableTR bits. | |
| 135 | + */ | |
| 136 | + err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A); | |
| 137 | + if (err < 0) | |
| 138 | + pr_warn("Failed to Set Register[0x0F82]\n"); | |
| 139 | + | |
| 140 | + /* Get access to Channel b'10, Node b'1101, Register 0x06. | |
| 141 | + * Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv, | |
| 142 | + * SSTrKp1000Mas bits. | |
| 143 | + */ | |
| 144 | + err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F); | |
| 145 | + if (err < 0) | |
| 146 | + pr_warn("Failed to Set Register[0x168C]\n"); | |
| 147 | + | |
| 148 | + /* Get access to Channel b'10, Node b'1111, Register 0x11. | |
| 149 | + * Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh | |
| 150 | + * bits | |
| 151 | + */ | |
| 152 | + err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620); | |
| 153 | + if (err < 0) | |
| 154 | + pr_warn("Failed to Set Register[0x17A2]\n"); | |
| 155 | + | |
| 156 | + /* Get access to Channel b'10, Node b'1101, Register 0x10. | |
| 157 | + * Write 24-bit value 0xEEFFDD to register. Setting | |
| 158 | + * eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000, | |
| 159 | + * eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits. | |
| 160 | + */ | |
| 161 | + err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD); | |
| 162 | + if (err < 0) | |
| 163 | + pr_warn("Failed to Set Register[0x16A0]\n"); | |
| 164 | + | |
| 165 | + /* Get access to Channel b'10, Node b'1101, Register 0x13. | |
| 166 | + * Write 24-bit value 0x071448 to register. Setting | |
| 167 | + * slv_lpi_tr_tmr_val1, slv_lpi_tr_tmr_val2 bits. | |
| 168 | + */ | |
| 169 | + err = lan88xx_TR_reg_set(phydev, 0x16A6, 0x071448); | |
| 170 | + if (err < 0) | |
| 171 | + pr_warn("Failed to Set Register[0x16A6]\n"); | |
| 172 | + | |
| 173 | + /* Get access to Channel b'10, Node b'1101, Register 0x12. | |
| 174 | + * Write 24-bit value 0x13132F to register. Setting | |
| 175 | + * slv_sigdet_timer_val1, slv_sigdet_timer_val2 bits. | |
| 176 | + */ | |
| 177 | + err = lan88xx_TR_reg_set(phydev, 0x16A4, 0x13132F); | |
| 178 | + if (err < 0) | |
| 179 | + pr_warn("Failed to Set Register[0x16A4]\n"); | |
| 180 | + | |
| 181 | + /* Get access to Channel b'10, Node b'1101, Register 0x14. | |
| 182 | + * Write 24-bit value 0x0 to register. Setting eee_3level_delay, | |
| 183 | + * eee_TrKf_freeze_delay bits. | |
| 184 | + */ | |
| 185 | + err = lan88xx_TR_reg_set(phydev, 0x16A8, 0x0); | |
| 186 | + if (err < 0) | |
| 187 | + pr_warn("Failed to Set Register[0x16A8]\n"); | |
| 188 | + | |
| 189 | + /* Get access to Channel b'01, Node b'1111, Register 0x34. | |
| 190 | + * Write 24-bit value 0x91B06C to register. Setting | |
| 191 | + * FastMseSearchThreshLong1000, FastMseSearchThreshShort1000, | |
| 192 | + * FastMseSearchUpdGain1000 bits. | |
| 193 | + */ | |
| 194 | + err = lan88xx_TR_reg_set(phydev, 0x0FE8, 0x91B06C); | |
| 195 | + if (err < 0) | |
| 196 | + pr_warn("Failed to Set Register[0x0FE8]\n"); | |
| 197 | + | |
| 198 | + /* Get access to Channel b'01, Node b'1111, Register 0x3E. | |
| 199 | + * Write 24-bit value 0xC0A028 to register. Setting | |
| 200 | + * FastMseKp2ThreshLong1000, FastMseKp2ThreshShort1000, | |
| 201 | + * FastMseKp2UpdGain1000, FastMseKp2ExitEn1000 bits. | |
| 202 | + */ | |
| 203 | + err = lan88xx_TR_reg_set(phydev, 0x0FFC, 0xC0A028); | |
| 204 | + if (err < 0) | |
| 205 | + pr_warn("Failed to Set Register[0x0FFC]\n"); | |
| 206 | + | |
| 207 | + /* Get access to Channel b'01, Node b'1111, Register 0x35. | |
| 208 | + * Write 24-bit value 0x041600 to register. Setting | |
| 209 | + * FastMseSearchPhShNum1000, FastMseSearchClksPerPh1000, | |
| 210 | + * FastMsePhChangeDelay1000 bits. | |
| 211 | + */ | |
| 212 | + err = lan88xx_TR_reg_set(phydev, 0x0FEA, 0x041600); | |
| 213 | + if (err < 0) | |
| 214 | + pr_warn("Failed to Set Register[0x0FEA]\n"); | |
| 215 | + | |
| 216 | + /* Get access to Channel b'10, Node b'1101, Register 0x03. | |
| 217 | + * Write 24-bit value 0x000004 to register. Setting TrFreeze bits. | |
| 218 | + */ | |
| 219 | + err = lan88xx_TR_reg_set(phydev, 0x1686, 0x000004); | |
| 220 | + if (err < 0) | |
| 221 | + pr_warn("Failed to Set Register[0x1686]\n"); | |
| 222 | +} | |
| 223 | + | |
| 69 | 224 | static int lan88xx_probe(struct phy_device *phydev) |
| 70 | 225 | { |
| 71 | 226 | struct device *dev = &phydev->mdio.dev; |
| @@ -132,6 +287,25 @@ static void lan88xx_set_mdix(struct phy_device *phydev) · 60 unmodified lines | ||
| 132 | 287 | phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_0); |
| 133 | 288 | } |
| 134 | 289 | |
| 290 | +static int lan88xx_config_init(struct phy_device *phydev) | |
| 291 | +{ | |
| 292 | + int val; | |
| 293 | + | |
| 294 | + genphy_config_init(phydev); | |
| 295 | + /*Zerodetect delay enable */ | |
| 296 | + val = phy_read_mmd(phydev, MDIO_MMD_PCS, | |
| 297 | + PHY_ARDENNES_MMD_DEV_3_PHY_CFG); | |
| 298 | + val |= PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_; | |
| 299 | + | |
| 300 | + phy_write_mmd(phydev, MDIO_MMD_PCS, PHY_ARDENNES_MMD_DEV_3_PHY_CFG, | |
| 301 | + val); | |
| 302 | + | |
| 303 | + /* Config DSP registers */ | |
| 304 | + lan88xx_config_TR_regs(phydev); | |
| 305 | + | |
| 306 | + return 0; | |
| 307 | +} | |
| 308 | + | |
| 135 | 309 | static int lan88xx_config_aneg(struct phy_device *phydev) |
| 136 | 310 | { |
| 137 | 311 | lan88xx_set_mdix(phydev); |
| @@ -151,7 +325,7 @@ static struct phy_driver microchip_phy_driver[] = { · 13 unmodified lines | ||
| 151 | 325 | .probe = lan88xx_probe, |
| 152 | 326 | .remove = lan88xx_remove, |
| 153 | 327 | |
| 154 | − .config_init = genphy_config_init, | |
| 328 | + .config_init = lan88xx_config_init, | |
| 155 | 329 | .config_aneg = lan88xx_config_aneg, |
| 156 | 330 | |
| 157 | 331 | .ack_interrupt = lan88xx_phy_ack_interrupt, |
| @@ -160,6 +334,8 @@ static struct phy_driver microchip_phy_driver[] = { · 2 unmodified lines | ||
| 160 | 334 | .suspend = lan88xx_suspend, |
| 161 | 335 | .resume = genphy_resume, |
| 162 | 336 | .set_wol = lan88xx_set_wol, |
| 337 | + .read_page = lan88xx_read_page, | |
| 338 | + .write_page = lan88xx_write_page, | |
| 163 | 339 | } }; |
| 164 | 340 | |
| 165 | 341 | module_phy_driver(microchip_phy_driver); |
| @@ -535,8 +535,17 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, · 534 unmodified lines | ||
| 535 | 535 | |
| 536 | 536 | /* Grab the bits from PHYIR1, and put them in the upper half */ |
| 537 | 537 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); |
| 538 | − if (phy_reg < 0) | |
| 538 | + if (phy_reg < 0) { | |
| 539 | + /* if there is no device, return without an error so scanning | |
| 540 | + * the bus works properly | |
| 541 | + */ | |
| 542 | + if (phy_reg == -EIO || phy_reg == -ENODEV) { | |
| 543 | + *phy_id = 0xffffffff; | |
| 544 | + return 0; | |
| 545 | + } | |
| 546 | + | |
| 539 | 547 | return -EIO; |
| 548 | + } | |
| 540 | 549 | |
| 541 | 550 | *phy_id = (phy_reg & 0xffff) << 16; |
| 542 | 551 | |
| @@ -620,6 +620,10 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, · 619 unmodified lines | ||
| 620 | 620 | lock_sock(sk); |
| 621 | 621 | |
| 622 | 622 | error = -EINVAL; |
| 623 | + | |
| 624 | + if (sockaddr_len != sizeof(struct sockaddr_pppox)) | |
| 625 | + goto end; | |
| 626 | + | |
| 623 | 627 | if (sp->sa_protocol != PX_PROTO_OE) |
| 624 | 628 | goto end; |
| 625 | 629 | |
| @@ -261,6 +261,17 @@ static void __team_option_inst_mark_removed_port(struct team *team, · 260 unmodified lines | ||
| 261 | 261 | } |
| 262 | 262 | } |
| 263 | 263 | |
| 264 | +static bool __team_option_inst_tmp_find(const struct list_head *opts, | |
| 265 | + const struct team_option_inst *needle) | |
| 266 | +{ | |
| 267 | + struct team_option_inst *opt_inst; | |
| 268 | + | |
| 269 | + list_for_each_entry(opt_inst, opts, tmp_list) | |
| 270 | + if (opt_inst == needle) | |
| 271 | + return true; | |
| 272 | + return false; | |
| 273 | +} | |
| 274 | + | |
| 264 | 275 | static int __team_options_register(struct team *team, |
| 265 | 276 | const struct team_option *option, |
| 266 | 277 | size_t option_count) |
| @@ -1061,14 +1072,11 @@ static void team_port_leave(struct team *team, struct team_port *port) · 794 unmodified lines | ||
| 1061 | 1072 | } |
| 1062 | 1073 | |
| 1063 | 1074 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 1064 | −static int team_port_enable_netpoll(struct team *team, struct team_port *port) | |
| 1075 | +static int __team_port_enable_netpoll(struct team_port *port) | |
| 1065 | 1076 | { |
| 1066 | 1077 | struct netpoll *np; |
| 1067 | 1078 | int err; |
| 1068 | 1079 | |
| 1069 | − if (!team->dev->npinfo) | |
| 1070 | − return 0; | |
| 1071 | − | |
| 1072 | 1080 | np = kzalloc(sizeof(*np), GFP_KERNEL); |
| 1073 | 1081 | if (!np) |
| 1074 | 1082 | return -ENOMEM; |
| @@ -1082,6 +1090,14 @@ static int team_port_enable_netpoll(struct team *team, struct team_port *port) · 7 unmodified lines | ||
| 1082 | 1090 | return err; |
| 1083 | 1091 | } |
| 1084 | 1092 | |
| 1093 | +static int team_port_enable_netpoll(struct team_port *port) | |
| 1094 | +{ | |
| 1095 | + if (!port->team->dev->npinfo) | |
| 1096 | + return 0; | |
| 1097 | + | |
| 1098 | + return __team_port_enable_netpoll(port); | |
| 1099 | +} | |
| 1100 | + | |
| 1085 | 1101 | static void team_port_disable_netpoll(struct team_port *port) |
| 1086 | 1102 | { |
| 1087 | 1103 | struct netpoll *np = port->np; |
| @@ -1096,7 +1112,7 @@ static void team_port_disable_netpoll(struct team_port *port) · 8 unmodified lines | ||
| 1096 | 1112 | kfree(np); |
| 1097 | 1113 | } |
| 1098 | 1114 | #else |
| 1099 | −static int team_port_enable_netpoll(struct team *team, struct team_port *port) | |
| 1115 | +static int team_port_enable_netpoll(struct team_port *port) | |
| 1100 | 1116 | { |
| 1101 | 1117 | return 0; |
| 1102 | 1118 | } |
| @@ -1210,7 +1226,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev, · 107 unmodified lines | ||
| 1210 | 1226 | goto err_vids_add; |
| 1211 | 1227 | } |
| 1212 | 1228 | |
| 1213 | − err = team_port_enable_netpoll(team, port); | |
| 1229 | + err = team_port_enable_netpoll(port); | |
| 1214 | 1230 | if (err) { |
| 1215 | 1231 | netdev_err(dev, "Failed to enable netpoll on device %s\n", |
| 1216 | 1232 | portname); |
| @@ -1907,7 +1923,7 @@ static int team_netpoll_setup(struct net_device *dev, · 690 unmodified lines | ||
| 1907 | 1923 | |
| 1908 | 1924 | mutex_lock(&team->lock); |
| 1909 | 1925 | list_for_each_entry(port, &team->port_list, list) { |
| 1910 | − err = team_port_enable_netpoll(team, port); | |
| 1926 | + err = __team_port_enable_netpoll(port); | |
| 1911 | 1927 | if (err) { |
| 1912 | 1928 | __team_netpoll_cleanup(team); |
| 1913 | 1929 | break; |
| @@ -2568,6 +2584,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) · 654 unmodified lines | ||
| 2568 | 2584 | if (err) |
| 2569 | 2585 | goto team_put; |
| 2570 | 2586 | opt_inst->changed = true; |
| 2587 | + | |
| 2588 | + /* dumb/evil user-space can send us duplicate opt, | |
| 2589 | + * keep only the last one | |
| 2590 | + */ | |
| 2591 | + if (__team_option_inst_tmp_find(&opt_inst_list, | |
| 2592 | + opt_inst)) | |
| 2593 | + continue; | |
| 2594 | + | |
| 2571 | 2595 | list_add(&opt_inst->tmp_list, &opt_inst_list); |
| 2572 | 2596 | } |
| 2573 | 2597 | if (!opt_found) { |
| @@ -1102,12 +1102,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) · 1101 unmodified lines | ||
| 1102 | 1102 | goto drop; |
| 1103 | 1103 | |
| 1104 | 1104 | len = run_ebpf_filter(tun, skb, len); |
| 1105 | − | |
| 1106 | − /* Trim extra bytes since we may insert vlan proto & TCI | |
| 1107 | − * in tun_put_user(). | |
| 1108 | − */ | |
| 1109 | − len -= skb_vlan_tag_present(skb) ? sizeof(struct veth) : 0; | |
| 1110 | − if (len <= 0 || pskb_trim(skb, len)) | |
| 1105 | + if (len == 0 || pskb_trim(skb, len)) | |
| 1111 | 1106 | goto drop; |
| 1112 | 1107 | |
| 1113 | 1108 | if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) |
| @@ -1098,6 +1098,7 @@ static const struct usb_device_id products[] = { · 1097 unmodified lines | ||
| 1098 | 1098 | {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, |
| 1099 | 1099 | {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, |
| 1100 | 1100 | {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, |
| 1101 | + {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)}, /* ublox R410M */ | |
| 1101 | 1102 | {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, |
| 1102 | 1103 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, |
| 1103 | 1104 | {QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */ |
| @@ -1107,6 +1108,7 @@ static const struct usb_device_id products[] = { · 3 unmodified lines | ||
| 1107 | 1108 | {QMI_FIXED_INTF(0x1435, 0xd181, 3)}, /* Wistron NeWeb D18Q1 */ |
| 1108 | 1109 | {QMI_FIXED_INTF(0x1435, 0xd181, 4)}, /* Wistron NeWeb D18Q1 */ |
| 1109 | 1110 | {QMI_FIXED_INTF(0x1435, 0xd181, 5)}, /* Wistron NeWeb D18Q1 */ |
| 1111 | + {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ | |
| 1110 | 1112 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ |
| 1111 | 1113 | {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */ |
| 1112 | 1114 | {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */ |
| @@ -1342,6 +1344,18 @@ static int qmi_wwan_probe(struct usb_interface *intf, · 229 unmodified lines | ||
| 1342 | 1344 | id->driver_info = (unsigned long)&qmi_wwan_info; |
| 1343 | 1345 | } |
| 1344 | 1346 | |
| 1347 | + /* There are devices where the same interface number can be | |
| 1348 | + * configured as different functions. We should only bind to | |
| 1349 | + * vendor specific functions when matching on interface number | |
| 1350 | + */ | |
| 1351 | + if (id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER && | |
| 1352 | + desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) { | |
| 1353 | + dev_dbg(&intf->dev, | |
| 1354 | + "Rejecting interface number match for class %02x\n", | |
| 1355 | + desc->bInterfaceClass); | |
| 1356 | + return -ENODEV; | |
| 1357 | + } | |
| 1358 | + | |
| 1345 | 1359 | /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */ |
| 1346 | 1360 | if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) { |
| 1347 | 1361 | dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n"); |
| @@ -147,6 +147,17 @@ struct receive_queue { · 146 unmodified lines | ||
| 147 | 147 | struct xdp_rxq_info xdp_rxq; |
| 148 | 148 | }; |
| 149 | 149 | |
| 150 | +/* Control VQ buffers: protected by the rtnl lock */ | |
| 151 | +struct control_buf { | |
| 152 | + struct virtio_net_ctrl_hdr hdr; | |
| 153 | + virtio_net_ctrl_ack status; | |
| 154 | + struct virtio_net_ctrl_mq mq; | |
| 155 | + u8 promisc; | |
| 156 | + u8 allmulti; | |
| 157 | + __virtio16 vid; | |
| 158 | + __virtio64 offloads; | |
| 159 | +}; | |
| 160 | + | |
| 150 | 161 | struct virtnet_info { |
| 151 | 162 | struct virtio_device *vdev; |
| 152 | 163 | struct virtqueue *cvq; |
| @@ -192,14 +203,7 @@ struct virtnet_info { · 39 unmodified lines | ||
| 192 | 203 | struct hlist_node node; |
| 193 | 204 | struct hlist_node node_dead; |
| 194 | 205 | |
| 195 | − /* Control VQ buffers: protected by the rtnl lock */ | |
| 196 | − struct virtio_net_ctrl_hdr ctrl_hdr; | |
| 197 | − virtio_net_ctrl_ack ctrl_status; | |
| 198 | − struct virtio_net_ctrl_mq ctrl_mq; | |
| 199 | − u8 ctrl_promisc; | |
| 200 | − u8 ctrl_allmulti; | |
| 201 | − u16 ctrl_vid; | |
| 202 | − u64 ctrl_offloads; | |
| 206 | + struct control_buf *ctrl; | |
| 203 | 207 | |
| 204 | 208 | /* Ethtool settings */ |
| 205 | 209 | u8 duplex; |
| @@ -1269,7 +1273,9 @@ static int virtnet_poll(struct napi_struct *napi, int budget) · 1063 unmodified lines | ||
| 1269 | 1273 | { |
| 1270 | 1274 | struct receive_queue *rq = |
| 1271 | 1275 | container_of(napi, struct receive_queue, napi); |
| 1272 | − unsigned int received; | |
| 1276 | + struct virtnet_info *vi = rq->vq->vdev->priv; | |
| 1277 | + struct send_queue *sq; | |
| 1278 | + unsigned int received, qp; | |
| 1273 | 1279 | bool xdp_xmit = false; |
| 1274 | 1280 | |
| 1275 | 1281 | virtnet_poll_cleantx(rq); |
| @@ -1280,8 +1286,13 @@ static int virtnet_poll(struct napi_struct *napi, int budget) · 4 unmodified lines | ||
| 1280 | 1286 | if (received < budget) |
| 1281 | 1287 | virtqueue_napi_complete(napi, rq->vq, received); |
| 1282 | 1288 | |
| 1283 | − if (xdp_xmit) | |
| 1289 | + if (xdp_xmit) { | |
| 1290 | + qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + | |
| 1291 | + smp_processor_id(); | |
| 1292 | + sq = &vi->sq[qp]; | |
| 1293 | + virtqueue_kick(sq->vq); | |
| 1284 | 1294 | xdp_do_flush_map(); |
| 1295 | + } | |
| 1285 | 1296 | |
| 1286 | 1297 | return received; |
| 1287 | 1298 | } |
| @@ -1454,25 +1465,25 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, · 166 unmodified lines | ||
| 1454 | 1465 | /* Caller should know better */ |
| 1455 | 1466 | BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)); |
| 1456 | 1467 | |
| 1457 | − vi->ctrl_status = ~0; | |
| 1458 | − vi->ctrl_hdr.class = class; | |
| 1459 | − vi->ctrl_hdr.cmd = cmd; | |
| 1468 | + vi->ctrl->status = ~0; | |
| 1469 | + vi->ctrl->hdr.class = class; | |
| 1470 | + vi->ctrl->hdr.cmd = cmd; | |
| 1460 | 1471 | /* Add header */ |
| 1461 | − sg_init_one(&hdr, &vi->ctrl_hdr, sizeof(vi->ctrl_hdr)); | |
| 1472 | + sg_init_one(&hdr, &vi->ctrl->hdr, sizeof(vi->ctrl->hdr)); | |
| 1462 | 1473 | sgs[out_num++] = &hdr; |
| 1463 | 1474 | |
| 1464 | 1475 | if (out) |
| 1465 | 1476 | sgs[out_num++] = out; |
| 1466 | 1477 | |
| 1467 | 1478 | /* Add return status. */ |
| 1468 | − sg_init_one(&stat, &vi->ctrl_status, sizeof(vi->ctrl_status)); | |
| 1479 | + sg_init_one(&stat, &vi->ctrl->status, sizeof(vi->ctrl->status)); | |
| 1469 | 1480 | sgs[out_num] = &stat; |
| 1470 | 1481 | |
| 1471 | 1482 | BUG_ON(out_num + 1 > ARRAY_SIZE(sgs)); |
| 1472 | 1483 | virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC); |
| 1473 | 1484 | |
| 1474 | 1485 | if (unlikely(!virtqueue_kick(vi->cvq))) |
| 1475 | − return vi->ctrl_status == VIRTIO_NET_OK; | |
| 1486 | + return vi->ctrl->status == VIRTIO_NET_OK; | |
| 1476 | 1487 | |
| 1477 | 1488 | /* Spin for a response, the kick causes an ioport write, trapping |
| 1478 | 1489 | * into the hypervisor, so the request should be handled immediately. |
| @@ -1481,7 +1492,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, · 2 unmodified lines | ||
| 1481 | 1492 | !virtqueue_is_broken(vi->cvq)) |
| 1482 | 1493 | cpu_relax(); |
| 1483 | 1494 | |
| 1484 | − return vi->ctrl_status == VIRTIO_NET_OK; | |
| 1495 | + return vi->ctrl->status == VIRTIO_NET_OK; | |
| 1485 | 1496 | } |
| 1486 | 1497 | |
| 1487 | 1498 | static int virtnet_set_mac_address(struct net_device *dev, void *p) |
| @@ -1593,8 +1604,8 @@ static int _virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs) · 105 unmodified lines | ||
| 1593 | 1604 | if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ)) |
| 1594 | 1605 | return 0; |
| 1595 | 1606 | |
| 1596 | − vi->ctrl_mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs); | |
| 1597 | − sg_init_one(&sg, &vi->ctrl_mq, sizeof(vi->ctrl_mq)); | |
| 1607 | + vi->ctrl->mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs); | |
| 1608 | + sg_init_one(&sg, &vi->ctrl->mq, sizeof(vi->ctrl->mq)); | |
| 1598 | 1609 | |
| 1599 | 1610 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ, |
| 1600 | 1611 | VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg)) { |
| @@ -1653,22 +1664,22 @@ static void virtnet_set_rx_mode(struct net_device *dev) · 52 unmodified lines | ||
| 1653 | 1664 | if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX)) |
| 1654 | 1665 | return; |
| 1655 | 1666 | |
| 1656 | − vi->ctrl_promisc = ((dev->flags & IFF_PROMISC) != 0); | |
| 1657 | − vi->ctrl_allmulti = ((dev->flags & IFF_ALLMULTI) != 0); | |
| 1667 | + vi->ctrl->promisc = ((dev->flags & IFF_PROMISC) != 0); | |
| 1668 | + vi->ctrl->allmulti = ((dev->flags & IFF_ALLMULTI) != 0); | |
| 1658 | 1669 | |
| 1659 | − sg_init_one(sg, &vi->ctrl_promisc, sizeof(vi->ctrl_promisc)); | |
| 1670 | + sg_init_one(sg, &vi->ctrl->promisc, sizeof(vi->ctrl->promisc)); | |
| 1660 | 1671 | |
| 1661 | 1672 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, |
| 1662 | 1673 | VIRTIO_NET_CTRL_RX_PROMISC, sg)) |
| 1663 | 1674 | dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", |
| 1664 | − vi->ctrl_promisc ? "en" : "dis"); | |
| 1675 | + vi->ctrl->promisc ? "en" : "dis"); | |
| 1665 | 1676 | |
| 1666 | − sg_init_one(sg, &vi->ctrl_allmulti, sizeof(vi->ctrl_allmulti)); | |
| 1677 | + sg_init_one(sg, &vi->ctrl->allmulti, sizeof(vi->ctrl->allmulti)); | |
| 1667 | 1678 | |
| 1668 | 1679 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, |
| 1669 | 1680 | VIRTIO_NET_CTRL_RX_ALLMULTI, sg)) |
| 1670 | 1681 | dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n", |
| 1671 | − vi->ctrl_allmulti ? "en" : "dis"); | |
| 1682 | + vi->ctrl->allmulti ? "en" : "dis"); | |
| 1672 | 1683 | |
| 1673 | 1684 | uc_count = netdev_uc_count(dev); |
| 1674 | 1685 | mc_count = netdev_mc_count(dev); |
| @@ -1714,8 +1725,8 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev, · 39 unmodified lines | ||
| 1714 | 1725 | struct virtnet_info *vi = netdev_priv(dev); |
| 1715 | 1726 | struct scatterlist sg; |
| 1716 | 1727 | |
| 1717 | − vi->ctrl_vid = vid; | |
| 1718 | − sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid)); | |
| 1728 | + vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid); | |
| 1729 | + sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid)); | |
| 1719 | 1730 | |
| 1720 | 1731 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, |
| 1721 | 1732 | VIRTIO_NET_CTRL_VLAN_ADD, &sg)) |
| @@ -1729,8 +1740,8 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, · 7 unmodified lines | ||
| 1729 | 1740 | struct virtnet_info *vi = netdev_priv(dev); |
| 1730 | 1741 | struct scatterlist sg; |
| 1731 | 1742 | |
| 1732 | − vi->ctrl_vid = vid; | |
| 1733 | − sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid)); | |
| 1743 | + vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid); | |
| 1744 | + sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid)); | |
| 1734 | 1745 | |
| 1735 | 1746 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, |
| 1736 | 1747 | VIRTIO_NET_CTRL_VLAN_DEL, &sg)) |
| @@ -2126,9 +2137,9 @@ static int virtnet_restore_up(struct virtio_device *vdev) · 389 unmodified lines | ||
| 2126 | 2137 | static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads) |
| 2127 | 2138 | { |
| 2128 | 2139 | struct scatterlist sg; |
| 2129 | − vi->ctrl_offloads = cpu_to_virtio64(vi->vdev, offloads); | |
| 2140 | + vi->ctrl->offloads = cpu_to_virtio64(vi->vdev, offloads); | |
| 2130 | 2141 | |
| 2131 | − sg_init_one(&sg, &vi->ctrl_offloads, sizeof(vi->ctrl_offloads)); | |
| 2142 | + sg_init_one(&sg, &vi->ctrl->offloads, sizeof(vi->ctrl->offloads)); | |
| 2132 | 2143 | |
| 2133 | 2144 | if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_GUEST_OFFLOADS, |
| 2134 | 2145 | VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, &sg)) { |
| @@ -2351,6 +2362,7 @@ static void virtnet_free_queues(struct virtnet_info *vi) · 216 unmodified lines | ||
| 2351 | 2362 | |
| 2352 | 2363 | kfree(vi->rq); |
| 2353 | 2364 | kfree(vi->sq); |
| 2365 | + kfree(vi->ctrl); | |
| 2354 | 2366 | } |
| 2355 | 2367 | |
| 2356 | 2368 | static void _free_receive_bufs(struct virtnet_info *vi) |
| @@ -2543,6 +2555,9 @@ static int virtnet_alloc_queues(struct virtnet_info *vi) · 186 unmodified lines | ||
| 2543 | 2555 | { |
| 2544 | 2556 | int i; |
| 2545 | 2557 | |
| 2558 | + vi->ctrl = kzalloc(sizeof(*vi->ctrl), GFP_KERNEL); | |
| 2559 | + if (!vi->ctrl) | |
| 2560 | + goto err_ctrl; | |
| 2546 | 2561 | vi->sq = kzalloc(sizeof(*vi->sq) * vi->max_queue_pairs, GFP_KERNEL); |
| 2547 | 2562 | if (!vi->sq) |
| 2548 | 2563 | goto err_sq; |
| @@ -2571,6 +2586,8 @@ static int virtnet_alloc_queues(struct virtnet_info *vi) · 22 unmodified lines | ||
| 2571 | 2586 | err_rq: |
| 2572 | 2587 | kfree(vi->sq); |
| 2573 | 2588 | err_sq: |
| 2589 | + kfree(vi->ctrl); | |
| 2590 | +err_ctrl: | |
| 2574 | 2591 | return -ENOMEM; |
| 2575 | 2592 | } |
| 2576 | 2593 | |
| @@ -1218,6 +1218,7 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb, · 1217 unmodified lines | ||
| 1218 | 1218 | union { |
| 1219 | 1219 | void *ptr; |
| 1220 | 1220 | struct ethhdr *eth; |
| 1221 | + struct vlan_ethhdr *veth; | |
| 1221 | 1222 | struct iphdr *ipv4; |
| 1222 | 1223 | struct ipv6hdr *ipv6; |
| 1223 | 1224 | struct tcphdr *tcp; |
| @@ -1228,16 +1229,24 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb, · 4 unmodified lines | ||
| 1228 | 1229 | if (unlikely(sizeof(struct iphdr) + sizeof(struct tcphdr) > maplen)) |
| 1229 | 1230 | return 0; |
| 1230 | 1231 | |
| 1232 | + if (skb->protocol == cpu_to_be16(ETH_P_8021Q) || | |
| 1233 | + skb->protocol == cpu_to_be16(ETH_P_8021AD)) | |
| 1234 | + hlen = sizeof(struct vlan_ethhdr); | |
| 1235 | + else | |
| 1236 | + hlen = sizeof(struct ethhdr); | |
| 1237 | + | |
| 1231 | 1238 | hdr.eth = eth_hdr(skb); |
| 1232 | 1239 | if (gdesc->rcd.v4) { |
| 1233 | − BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP)); | |
| 1234 | − hdr.ptr += sizeof(struct ethhdr); | |
| 1240 | + BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP) && | |
| 1241 | + hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IP)); | |
| 1242 | + hdr.ptr += hlen; | |
| 1235 | 1243 | BUG_ON(hdr.ipv4->protocol != IPPROTO_TCP); |
| 1236 | 1244 | hlen = hdr.ipv4->ihl << 2; |
| 1237 | 1245 | hdr.ptr += hdr.ipv4->ihl << 2; |
| 1238 | 1246 | } else if (gdesc->rcd.v6) { |
| 1239 | − BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6)); | |
| 1240 | − hdr.ptr += sizeof(struct ethhdr); | |
| 1247 | + BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6) && | |
| 1248 | + hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IPV6)); | |
| 1249 | + hdr.ptr += hlen; | |
| 1241 | 1250 | /* Use an estimated value, since we also need to handle |
| 1242 | 1251 | * TSO case. |
| 1243 | 1252 | */ |
| @@ -69,10 +69,10 @@ · 68 unmodified lines | ||
| 69 | 69 | /* |
| 70 | 70 | * Version numbers |
| 71 | 71 | */ |
| 72 | −#define VMXNET3_DRIVER_VERSION_STRING "1.4.13.0-k" | |
| 72 | +#define VMXNET3_DRIVER_VERSION_STRING "1.4.14.0-k" | |
| 73 | 73 | |
| 74 | 74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ |
| 75 | −#define VMXNET3_DRIVER_VERSION_NUM 0x01040d00 | |
| 75 | +#define VMXNET3_DRIVER_VERSION_NUM 0x01040e00 | |
| 76 | 76 | |
| 77 | 77 | #if defined(CONFIG_PCI_MSI) |
| 78 | 78 | /* RSS only makes sense if MSI-X is supported. */ |
| @@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct brcmf_fw_request *req) · 458 unmodified lines | ||
| 459 | 459 | kfree(req); |
| 460 | 460 | } |
| 461 | 461 | |
| 462 | −static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) | |
| 462 | +static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) | |
| 463 | 463 | { |
| 464 | 464 | struct brcmf_fw *fwctx = ctx; |
| 465 | 465 | struct brcmf_fw_item *cur; |
| @@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) · 32 unmodified lines | ||
| 498 | 498 | brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); |
| 499 | 499 | cur->nv_data.data = nvram; |
| 500 | 500 | cur->nv_data.len = nvram_length; |
| 501 | − return; | |
| 501 | + return 0; | |
| 502 | 502 | |
| 503 | 503 | fail: |
| 504 | − brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); | |
| 505 | − fwctx->done(fwctx->dev, -ENOENT, NULL); | |
| 506 | − brcmf_fw_free_request(fwctx->req); | |
| 507 | − kfree(fwctx); | |
| 504 | + return -ENOENT; | |
| 508 | 505 | } |
| 509 | 506 | |
| 510 | 507 | static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) |
| @@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) · 42 unmodified lines | ||
| 553 | 550 | brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, |
| 554 | 551 | fw ? "" : "not "); |
| 555 | 552 | |
| 556 | − if (fw) { | |
| 557 | − if (cur->type == BRCMF_FW_TYPE_BINARY) | |
| 558 | − cur->binary = fw; | |
| 559 | − else if (cur->type == BRCMF_FW_TYPE_NVRAM) | |
| 560 | − brcmf_fw_request_nvram_done(fw, fwctx); | |
| 561 | − else | |
| 562 | − release_firmware(fw); | |
| 563 | − } else if (cur->type == BRCMF_FW_TYPE_NVRAM) { | |
| 564 | − brcmf_fw_request_nvram_done(NULL, fwctx); | |
| 565 | − } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) { | |
| 553 | + if (!fw) | |
| 566 | 554 | ret = -ENOENT; |
| 555 | + | |
| 556 | + switch (cur->type) { | |
| 557 | + case BRCMF_FW_TYPE_NVRAM: | |
| 558 | + ret = brcmf_fw_request_nvram_done(fw, fwctx); | |
| 559 | + break; | |
| 560 | + case BRCMF_FW_TYPE_BINARY: | |
| 561 | + cur->binary = fw; | |
| 562 | + break; | |
| 563 | + default: | |
| 564 | + /* something fishy here so bail out early */ | |
| 565 | + brcmf_err("unknown fw type: %d\n", cur->type); | |
| 566 | + release_firmware(fw); | |
| 567 | + ret = -EINVAL; | |
| 567 | 568 | goto fail; |
| 568 | 569 | } |
| 569 | 570 | |
| 571 | + if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) | |
| 572 | + goto fail; | |
| 573 | + | |
| 570 | 574 | do { |
| 571 | 575 | if (++fwctx->curpos == fwctx->req->n_items) { |
| 572 | 576 | ret = 0; |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 9 | 9 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 10 | 10 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 11 | + * Copyright(c) 2018 Intel Corporation | |
| 11 | 12 | * |
| 12 | 13 | * This program is free software; you can redistribute it and/or modify |
| 13 | 14 | * it under the terms of version 2 of the GNU General Public License as |
| @@ -30,7 +31,7 @@ · 16 unmodified lines | ||
| 30 | 31 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
| 31 | 32 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
| 32 | 33 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
| 33 | − * Copyright(c) 2018 Intel Corporation | |
| 34 | + * Copyright(c) 2018 Intel Corporation | |
| 34 | 35 | * All rights reserved. |
| 35 | 36 | * |
| 36 | 37 | * Redistribution and use in source and binary forms, with or without |
| @@ -749,13 +750,9 @@ struct iwl_scan_req_umac { · 712 unmodified lines | ||
| 749 | 750 | } __packed; |
| 750 | 751 | |
| 751 | 752 | #define IWL_SCAN_REQ_UMAC_SIZE_V8 sizeof(struct iwl_scan_req_umac) |
| 752 | −#define IWL_SCAN_REQ_UMAC_SIZE_V7 (sizeof(struct iwl_scan_req_umac) - \ | |
| 753 | − 4 * sizeof(u8)) | |
| 754 | −#define IWL_SCAN_REQ_UMAC_SIZE_V6 (sizeof(struct iwl_scan_req_umac) - \ | |
| 755 | − 2 * sizeof(u8) - sizeof(__le16)) | |
| 756 | −#define IWL_SCAN_REQ_UMAC_SIZE_V1 (sizeof(struct iwl_scan_req_umac) - \ | |
| 757 | − 2 * sizeof(__le32) - 2 * sizeof(u8) - \ | |
| 758 | − sizeof(__le16)) | |
| 753 | +#define IWL_SCAN_REQ_UMAC_SIZE_V7 48 | |
| 754 | +#define IWL_SCAN_REQ_UMAC_SIZE_V6 44 | |
| 755 | +#define IWL_SCAN_REQ_UMAC_SIZE_V1 36 | |
| 759 | 756 | |
| 760 | 757 | /** |
| 761 | 758 | * struct iwl_umac_scan_abort |
| @@ -76,6 +76,7 @@ · 75 unmodified lines | ||
| 76 | 76 | #include "iwl-io.h" |
| 77 | 77 | #include "iwl-csr.h" |
| 78 | 78 | #include "fw/acpi.h" |
| 79 | +#include "fw/api/nvm-reg.h" | |
| 79 | 80 | |
| 80 | 81 | /* NVM offsets (in words) definitions */ |
| 81 | 82 | enum nvm_offsets { |
| @@ -146,8 +147,8 @@ static const u8 iwl_ext_nvm_channels[] = { · 64 unmodified lines | ||
| 146 | 147 | 149, 153, 157, 161, 165, 169, 173, 177, 181 |
| 147 | 148 | }; |
| 148 | 149 | |
| 149 | −#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels) | |
| 150 | −#define IWL_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels) | |
| 150 | +#define IWL_NVM_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels) | |
| 151 | +#define IWL_NVM_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels) | |
| 151 | 152 | #define NUM_2GHZ_CHANNELS 14 |
| 152 | 153 | #define NUM_2GHZ_CHANNELS_EXT 14 |
| 153 | 154 | #define FIRST_2GHZ_HT_MINUS 5 |
| @@ -301,11 +302,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, · 147 unmodified lines | ||
| 301 | 302 | const u8 *nvm_chan; |
| 302 | 303 | |
| 303 | 304 | if (cfg->nvm_type != IWL_NVM_EXT) { |
| 304 | − num_of_ch = IWL_NUM_CHANNELS; | |
| 305 | + num_of_ch = IWL_NVM_NUM_CHANNELS; | |
| 305 | 306 | nvm_chan = &iwl_nvm_channels[0]; |
| 306 | 307 | num_2ghz_channels = NUM_2GHZ_CHANNELS; |
| 307 | 308 | } else { |
| 308 | − num_of_ch = IWL_NUM_CHANNELS_EXT; | |
| 309 | + num_of_ch = IWL_NVM_NUM_CHANNELS_EXT; | |
| 309 | 310 | nvm_chan = &iwl_ext_nvm_channels[0]; |
| 310 | 311 | num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT; |
| 311 | 312 | } |
| @@ -720,12 +721,12 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, · 408 unmodified lines | ||
| 720 | 721 | if (cfg->nvm_type != IWL_NVM_EXT) |
| 721 | 722 | data = kzalloc(sizeof(*data) + |
| 722 | 723 | sizeof(struct ieee80211_channel) * |
| 723 | − IWL_NUM_CHANNELS, | |
| 724 | + IWL_NVM_NUM_CHANNELS, | |
| 724 | 725 | GFP_KERNEL); |
| 725 | 726 | else |
| 726 | 727 | data = kzalloc(sizeof(*data) + |
| 727 | 728 | sizeof(struct ieee80211_channel) * |
| 728 | − IWL_NUM_CHANNELS_EXT, | |
| 729 | + IWL_NVM_NUM_CHANNELS_EXT, | |
| 729 | 730 | GFP_KERNEL); |
| 730 | 731 | if (!data) |
| 731 | 732 | return NULL; |
| @@ -842,24 +843,34 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan, · 110 unmodified lines | ||
| 842 | 843 | return flags; |
| 843 | 844 | } |
| 844 | 845 | |
| 846 | +struct regdb_ptrs { | |
| 847 | + struct ieee80211_wmm_rule *rule; | |
| 848 | + u32 token; | |
| 849 | +}; | |
| 850 | + | |
| 845 | 851 | struct ieee80211_regdomain * |
| 846 | 852 | iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, |
| 847 | − int num_of_ch, __le32 *channels, u16 fw_mcc) | |
| 853 | + int num_of_ch, __le32 *channels, u16 fw_mcc, | |
| 854 | + u16 geo_info) | |
| 848 | 855 | { |
| 849 | 856 | int ch_idx; |
| 850 | 857 | u16 ch_flags; |
| 851 | 858 | u32 reg_rule_flags, prev_reg_rule_flags = 0; |
| 852 | 859 | const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ? |
| 853 | 860 | iwl_ext_nvm_channels : iwl_nvm_channels; |
| 854 | − struct ieee80211_regdomain *regd; | |
| 855 | − int size_of_regd; | |
| 861 | + struct ieee80211_regdomain *regd, *copy_rd; | |
| 862 | + int size_of_regd, regd_to_copy, wmms_to_copy; | |
| 863 | + int size_of_wmms = 0; | |
| 856 | 864 | struct ieee80211_reg_rule *rule; |
| 865 | + struct ieee80211_wmm_rule *wmm_rule, *d_wmm, *s_wmm; | |
| 866 | + struct regdb_ptrs *regdb_ptrs; | |
| 857 | 867 | enum nl80211_band band; |
| 858 | 868 | int center_freq, prev_center_freq = 0; |
| 859 | − int valid_rules = 0; | |
| 869 | + int valid_rules = 0, n_wmms = 0; | |
| 870 | + int i; | |
| 860 | 871 | bool new_rule; |
| 861 | 872 | int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? |
| 862 | − IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS; | |
| 873 | + IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS; | |
| 863 | 874 | |
| 864 | 875 | if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) |
| 865 | 876 | return ERR_PTR(-EINVAL); |
| @@ -875,10 +886,26 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, · 9 unmodified lines | ||
| 875 | 886 | sizeof(struct ieee80211_regdomain) + |
| 876 | 887 | num_of_ch * sizeof(struct ieee80211_reg_rule); |
| 877 | 888 | |
| 878 | − regd = kzalloc(size_of_regd, GFP_KERNEL); | |
| 889 | + if (geo_info & GEO_WMM_ETSI_5GHZ_INFO) | |
| 890 | + size_of_wmms = | |
| 891 | + num_of_ch * sizeof(struct ieee80211_wmm_rule); | |
| 892 | + | |
| 893 | + regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL); | |
| 879 | 894 | if (!regd) |
| 880 | 895 | return ERR_PTR(-ENOMEM); |
| 881 | 896 | |
| 897 | + regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL); | |
| 898 | + if (!regdb_ptrs) { | |
| 899 | + copy_rd = ERR_PTR(-ENOMEM); | |
| 900 | + goto out; | |
| 901 | + } | |
| 902 | + | |
| 903 | + /* set alpha2 from FW. */ | |
| 904 | + regd->alpha2[0] = fw_mcc >> 8; | |
| 905 | + regd->alpha2[1] = fw_mcc & 0xff; | |
| 906 | + | |
| 907 | + wmm_rule = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd); | |
| 908 | + | |
| 882 | 909 | for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { |
| 883 | 910 | ch_flags = (u16)__le32_to_cpup(channels + ch_idx); |
| 884 | 911 | band = (ch_idx < NUM_2GHZ_CHANNELS) ? |
| @@ -927,14 +954,66 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, · 42 unmodified lines | ||
| 927 | 954 | |
| 928 | 955 | iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, |
| 929 | 956 | nvm_chan[ch_idx], ch_flags); |
| 957 | + | |
| 958 | + if (!(geo_info & GEO_WMM_ETSI_5GHZ_INFO) || | |
| 959 | + band == NL80211_BAND_2GHZ) | |
| 960 | + continue; | |
| 961 | + | |
| 962 | + if (!reg_query_regdb_wmm(regd->alpha2, center_freq, | |
| 963 | + ®db_ptrs[n_wmms].token, wmm_rule)) { | |
| 964 | + /* Add only new rules */ | |
| 965 | + for (i = 0; i < n_wmms; i++) { | |
| 966 | + if (regdb_ptrs[i].token == | |
| 967 | + regdb_ptrs[n_wmms].token) { | |
| 968 | + rule->wmm_rule = regdb_ptrs[i].rule; | |
| 969 | + break; | |
| 970 | + } | |
| 971 | + } | |
| 972 | + if (i == n_wmms) { | |
| 973 | + rule->wmm_rule = wmm_rule; | |
| 974 | + regdb_ptrs[n_wmms++].rule = wmm_rule; | |
| 975 | + wmm_rule++; | |
| 976 | + } | |
| 977 | + } | |
| 930 | 978 | } |
| 931 | 979 | |
| 932 | 980 | regd->n_reg_rules = valid_rules; |
| 981 | + regd->n_wmm_rules = n_wmms; | |
| 933 | 982 | |
| 934 | − /* set alpha2 from FW. */ | |
| 935 | − regd->alpha2[0] = fw_mcc >> 8; | |
| 936 | − regd->alpha2[1] = fw_mcc & 0xff; | |
| 983 | + /* | |
| 984 | + * Narrow down regdom for unused regulatory rules to prevent hole | |
| 985 | + * between reg rules to wmm rules. | |
| 986 | + */ | |
| 987 | + regd_to_copy = sizeof(struct ieee80211_regdomain) + | |
| 988 | + valid_rules * sizeof(struct ieee80211_reg_rule); | |
| 989 | + | |
| 990 | + wmms_to_copy = sizeof(struct ieee80211_wmm_rule) * n_wmms; | |
| 991 | + | |
| 992 | + copy_rd = kzalloc(regd_to_copy + wmms_to_copy, GFP_KERNEL); | |
| 993 | + if (!copy_rd) { | |
| 994 | + copy_rd = ERR_PTR(-ENOMEM); | |
| 995 | + goto out; | |
| 996 | + } | |
| 997 | + | |
| 998 | + memcpy(copy_rd, regd, regd_to_copy); | |
| 999 | + memcpy((u8 *)copy_rd + regd_to_copy, (u8 *)regd + size_of_regd, | |
| 1000 | + wmms_to_copy); | |
| 1001 | + | |
| 1002 | + d_wmm = (struct ieee80211_wmm_rule *)((u8 *)copy_rd + regd_to_copy); | |
| 1003 | + s_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd); | |
| 1004 | + | |
| 1005 | + for (i = 0; i < regd->n_reg_rules; i++) { | |
| 1006 | + if (!regd->reg_rules[i].wmm_rule) | |
| 1007 | + continue; | |
| 1008 | + | |
| 1009 | + copy_rd->reg_rules[i].wmm_rule = d_wmm + | |
| 1010 | + (regd->reg_rules[i].wmm_rule - s_wmm) / | |
| 1011 | + sizeof(struct ieee80211_wmm_rule); | |
| 1012 | + } | |
| 937 | 1013 | |
| 938 | − return regd; | |
| 1014 | +out: | |
| 1015 | + kfree(regdb_ptrs); | |
| 1016 | + kfree(regd); | |
| 1017 | + return copy_rd; | |
| 939 | 1018 | } |
| 940 | 1019 | IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info); |
| @@ -101,12 +101,14 @@ void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, · 100 unmodified lines | ||
| 101 | 101 | * |
| 102 | 102 | * This function parses the regulatory channel data received as a |
| 103 | 103 | * MCC_UPDATE_CMD command. It returns a newly allocation regulatory domain, |
| 104 | − * to be fed into the regulatory core. An ERR_PTR is returned on error. | |
| 104 | + * to be fed into the regulatory core. In case the geo_info is set handle | |
| 105 | + * accordingly. An ERR_PTR is returned on error. | |
| 105 | 106 | * If not given to the regulatory core, the user is responsible for freeing |
| 106 | 107 | * the regdomain returned here with kfree. |
| 107 | 108 | */ |
| 108 | 109 | struct ieee80211_regdomain * |
| 109 | 110 | iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, |
| 110 | − int num_of_ch, __le32 *channels, u16 fw_mcc); | |
| 111 | + int num_of_ch, __le32 *channels, u16 fw_mcc, | |
| 112 | + u16 geo_info); | |
| 111 | 113 | |
| 112 | 114 | #endif /* __iwl_nvm_parse_h__ */ |
| @@ -311,7 +311,8 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy, · 310 unmodified lines | ||
| 311 | 311 | regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, |
| 312 | 312 | __le32_to_cpu(resp->n_channels), |
| 313 | 313 | resp->channels, |
| 314 | − __le16_to_cpu(resp->mcc)); | |
| 314 | + __le16_to_cpu(resp->mcc), | |
| 315 | + __le16_to_cpu(resp->geo_info)); | |
| 315 | 316 | /* Store the return source id */ |
| 316 | 317 | src_id = resp->source_id; |
| 317 | 318 | kfree(resp); |
| @@ -158,16 +158,6 @@ static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist) · 157 unmodified lines | ||
| 158 | 158 | |
| 159 | 159 | static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) |
| 160 | 160 | { |
| 161 | − struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; | |
| 162 | − | |
| 163 | − /* override ant_num / ant_path */ | |
| 164 | − if (mod_params->ant_sel) { | |
| 165 | − rtlpriv->btcoexist.btc_info.ant_num = | |
| 166 | − (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1); | |
| 167 | − | |
| 168 | − rtlpriv->btcoexist.btc_info.single_ant_path = | |
| 169 | − (mod_params->ant_sel == 1 ? 0 : 1); | |
| 170 | − } | |
| 171 | 161 | return rtlpriv->btcoexist.btc_info.single_ant_path; |
| 172 | 162 | } |
| 173 | 163 | |
| @@ -178,7 +168,6 @@ static u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv) · 4 unmodified lines | ||
| 178 | 168 | |
| 179 | 169 | static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) |
| 180 | 170 | { |
| 181 | − struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; | |
| 182 | 171 | u8 num; |
| 183 | 172 | |
| 184 | 173 | if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2) |
| @@ -186,10 +175,6 @@ static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) · 1 unmodified line | ||
| 186 | 175 | else |
| 187 | 176 | num = 1; |
| 188 | 177 | |
| 189 | − /* override ant_num / ant_path */ | |
| 190 | − if (mod_params->ant_sel) | |
| 191 | − num = (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1) + 1; | |
| 192 | − | |
| 193 | 178 | return num; |
| 194 | 179 | } |
| 195 | 180 | |
| @@ -848,6 +848,9 @@ static bool _rtl8723be_init_mac(struct ieee80211_hw *hw) · 847 unmodified lines | ||
| 848 | 848 | return false; |
| 849 | 849 | } |
| 850 | 850 | |
| 851 | + if (rtlpriv->cfg->ops->get_btc_status()) | |
| 852 | + rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv); | |
| 853 | + | |
| 851 | 854 | bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL); |
| 852 | 855 | rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3)); |
| 853 | 856 | |
| @@ -2696,21 +2699,21 @@ void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, · 1842 unmodified lines | ||
| 2696 | 2699 | rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; |
| 2697 | 2700 | rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1); |
| 2698 | 2701 | rtlpriv->btcoexist.btc_info.single_ant_path = |
| 2699 | − (value & 0x40); /*0xc3[6]*/ | |
| 2702 | + (value & 0x40 ? ANT_AUX : ANT_MAIN); /*0xc3[6]*/ | |
| 2700 | 2703 | } else { |
| 2701 | 2704 | rtlpriv->btcoexist.btc_info.btcoexist = 0; |
| 2702 | 2705 | rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; |
| 2703 | 2706 | rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; |
| 2704 | − rtlpriv->btcoexist.btc_info.single_ant_path = 0; | |
| 2707 | + rtlpriv->btcoexist.btc_info.single_ant_path = ANT_MAIN; | |
| 2705 | 2708 | } |
| 2706 | 2709 | |
| 2707 | 2710 | /* override ant_num / ant_path */ |
| 2708 | 2711 | if (mod_params->ant_sel) { |
| 2709 | 2712 | rtlpriv->btcoexist.btc_info.ant_num = |
| 2710 | − (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1); | |
| 2713 | + (mod_params->ant_sel == 1 ? ANT_X1 : ANT_X2); | |
| 2711 | 2714 | |
| 2712 | 2715 | rtlpriv->btcoexist.btc_info.single_ant_path = |
| 2713 | − (mod_params->ant_sel == 1 ? 0 : 1); | |
| 2716 | + (mod_params->ant_sel == 1 ? ANT_AUX : ANT_MAIN); | |
| 2714 | 2717 | } |
| 2715 | 2718 | } |
| 2716 | 2719 | |
| @@ -2823,6 +2823,11 @@ enum bt_ant_num { · 2822 unmodified lines | ||
| 2823 | 2823 | ANT_X1 = 1, |
| 2824 | 2824 | }; |
| 2825 | 2825 | |
| 2826 | +enum bt_ant_path { | |
| 2827 | + ANT_MAIN = 0, | |
| 2828 | + ANT_AUX = 1, | |
| 2829 | +}; | |
| 2830 | + | |
| 2826 | 2831 | enum bt_co_type { |
| 2827 | 2832 | BT_2WIRE = 0, |
| 2828 | 2833 | BT_ISSC_3WIRE = 1, |
| @@ -103,8 +103,7 @@ config NVDIMM_DAX · 102 unmodified lines | ||
| 103 | 103 | Select Y if unsure |
| 104 | 104 | |
| 105 | 105 | config OF_PMEM |
| 106 | − # FIXME: make tristate once OF_NUMA dependency removed | |
| 107 | − bool "Device-tree support for persistent memory regions" | |
| 106 | + tristate "Device-tree support for persistent memory regions" | |
| 108 | 107 | depends on OF |
| 109 | 108 | default LIBNVDIMM |
| 110 | 109 | help |
| @@ -88,9 +88,9 @@ int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd) · 87 unmodified lines | ||
| 88 | 88 | int nvdimm_init_config_data(struct nvdimm_drvdata *ndd) |
| 89 | 89 | { |
| 90 | 90 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); |
| 91 | + int rc = validate_dimm(ndd), cmd_rc = 0; | |
| 91 | 92 | struct nd_cmd_get_config_data_hdr *cmd; |
| 92 | 93 | struct nvdimm_bus_descriptor *nd_desc; |
| 93 | − int rc = validate_dimm(ndd); | |
| 94 | 94 | u32 max_cmd_size, config_size; |
| 95 | 95 | size_t offset; |
| 96 | 96 | |
| @@ -124,9 +124,11 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd) · 27 unmodified lines | ||
| 124 | 124 | cmd->in_offset = offset; |
| 125 | 125 | rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), |
| 126 | 126 | ND_CMD_GET_CONFIG_DATA, cmd, |
| 127 | − cmd->in_length + sizeof(*cmd), NULL); | |
| 128 | − if (rc || cmd->status) { | |
| 129 | − rc = -ENXIO; | |
| 127 | + cmd->in_length + sizeof(*cmd), &cmd_rc); | |
| 128 | + if (rc < 0) | |
| 129 | + break; | |
| 130 | + if (cmd_rc < 0) { | |
| 131 | + rc = cmd_rc; | |
| 130 | 132 | break; |
| 131 | 133 | } |
| 132 | 134 | memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length); |
| @@ -140,9 +142,9 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd) · 7 unmodified lines | ||
| 140 | 142 | int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset, |
| 141 | 143 | void *buf, size_t len) |
| 142 | 144 | { |
| 143 | − int rc = validate_dimm(ndd); | |
| 144 | 145 | size_t max_cmd_size, buf_offset; |
| 145 | 146 | struct nd_cmd_set_config_hdr *cmd; |
| 147 | + int rc = validate_dimm(ndd), cmd_rc = 0; | |
| 146 | 148 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); |
| 147 | 149 | struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; |
| 148 | 150 | |
| @@ -164,7 +166,6 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset, · 15 unmodified lines | ||
| 164 | 166 | for (buf_offset = 0; len; len -= cmd->in_length, |
| 165 | 167 | buf_offset += cmd->in_length) { |
| 166 | 168 | size_t cmd_size; |
| 167 | − u32 *status; | |
| 168 | 169 | |
| 169 | 170 | cmd->in_offset = offset + buf_offset; |
| 170 | 171 | cmd->in_length = min(max_cmd_size, len); |
| @@ -172,12 +173,13 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset, · 1 unmodified line | ||
| 172 | 173 | |
| 173 | 174 | /* status is output in the last 4-bytes of the command buffer */ |
| 174 | 175 | cmd_size = sizeof(*cmd) + cmd->in_length + sizeof(u32); |
| 175 | − status = ((void *) cmd) + cmd_size - sizeof(u32); | |
| 176 | 176 | |
| 177 | 177 | rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), |
| 178 | − ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, NULL); | |
| 179 | − if (rc || *status) { | |
| 180 | − rc = rc ? rc : -ENXIO; | |
| 178 | + ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, &cmd_rc); | |
| 179 | + if (rc < 0) | |
| 180 | + break; | |
| 181 | + if (cmd_rc < 0) { | |
| 182 | + rc = cmd_rc; | |
| 181 | 183 | break; |
| 182 | 184 | } |
| 183 | 185 | } |
| @@ -67,7 +67,7 @@ static int of_pmem_region_probe(struct platform_device *pdev) · 66 unmodified lines | ||
| 67 | 67 | */ |
| 68 | 68 | memset(&ndr_desc, 0, sizeof(ndr_desc)); |
| 69 | 69 | ndr_desc.attr_groups = region_attr_groups; |
| 70 | − ndr_desc.numa_node = of_node_to_nid(np); | |
| 70 | + ndr_desc.numa_node = dev_to_node(&pdev->dev); | |
| 71 | 71 | ndr_desc.res = &pdev->resource[i]; |
| 72 | 72 | ndr_desc.of_node = np; |
| 73 | 73 | set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags); |
| @@ -27,7 +27,7 @@ config NVME_FABRICS · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | config NVME_RDMA |
| 29 | 29 | tristate "NVM Express over Fabrics RDMA host driver" |
| 30 | − depends on INFINIBAND && BLOCK | |
| 30 | + depends on INFINIBAND && INFINIBAND_ADDR_TRANS && BLOCK | |
| 31 | 31 | select NVME_CORE |
| 32 | 32 | select NVME_FABRICS |
| 33 | 33 | select SG_POOL |
| @@ -764,6 +764,7 @@ static int nvme_submit_user_cmd(struct request_queue *q, · 763 unmodified lines | ||
| 764 | 764 | ret = PTR_ERR(meta); |
| 765 | 765 | goto out_unmap; |
| 766 | 766 | } |
| 767 | + req->cmd_flags |= REQ_INTEGRITY; | |
| 767 | 768 | } |
| 768 | 769 | } |
| 769 | 770 | |
| @@ -2997,31 +2998,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) · 2227 unmodified lines | ||
| 2997 | 2998 | if (nvme_init_ns_head(ns, nsid, id)) |
| 2998 | 2999 | goto out_free_id; |
| 2999 | 3000 | nvme_setup_streams_ns(ctrl, ns); |
| 3000 | − | |
| 3001 | −#ifdef CONFIG_NVME_MULTIPATH | |
| 3002 | − /* | |
| 3003 | − * If multipathing is enabled we need to always use the subsystem | |
| 3004 | − * instance number for numbering our devices to avoid conflicts | |
| 3005 | − * between subsystems that have multiple controllers and thus use | |
| 3006 | − * the multipath-aware subsystem node and those that have a single | |
| 3007 | − * controller and use the controller node directly. | |
| 3008 | − */ | |
| 3009 | − if (ns->head->disk) { | |
| 3010 | − sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance, | |
| 3011 | − ctrl->cntlid, ns->head->instance); | |
| 3012 | − flags = GENHD_FL_HIDDEN; | |
| 3013 | − } else { | |
| 3014 | − sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance, | |
| 3015 | − ns->head->instance); | |
| 3016 | − } | |
| 3017 | −#else | |
| 3018 | − /* | |
| 3019 | − * But without the multipath code enabled, multiple controller per | |
| 3020 | − * subsystems are visible as devices and thus we cannot use the | |
| 3021 | − * subsystem instance. | |
| 3022 | − */ | |
| 3023 | − sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance); | |
| 3024 | −#endif | |
| 3001 | + nvme_set_disk_name(disk_name, ns, ctrl, &flags); | |
| 3025 | 3002 | |
| 3026 | 3003 | if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) { |
| 3027 | 3004 | if (nvme_nvm_register(ns, disk_name, node)) { |
| @@ -668,6 +668,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 667 unmodified lines | ||
| 668 | 668 | ret = -ENOMEM; |
| 669 | 669 | goto out; |
| 670 | 670 | } |
| 671 | + kfree(opts->transport); | |
| 671 | 672 | opts->transport = p; |
| 672 | 673 | break; |
| 673 | 674 | case NVMF_OPT_NQN: |
| @@ -676,6 +677,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 2 unmodified lines | ||
| 676 | 677 | ret = -ENOMEM; |
| 677 | 678 | goto out; |
| 678 | 679 | } |
| 680 | + kfree(opts->subsysnqn); | |
| 679 | 681 | opts->subsysnqn = p; |
| 680 | 682 | nqnlen = strlen(opts->subsysnqn); |
| 681 | 683 | if (nqnlen >= NVMF_NQN_SIZE) { |
| @@ -698,6 +700,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 16 unmodified lines | ||
| 698 | 700 | ret = -ENOMEM; |
| 699 | 701 | goto out; |
| 700 | 702 | } |
| 703 | + kfree(opts->traddr); | |
| 701 | 704 | opts->traddr = p; |
| 702 | 705 | break; |
| 703 | 706 | case NVMF_OPT_TRSVCID: |
| @@ -706,6 +709,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 2 unmodified lines | ||
| 706 | 709 | ret = -ENOMEM; |
| 707 | 710 | goto out; |
| 708 | 711 | } |
| 712 | + kfree(opts->trsvcid); | |
| 709 | 713 | opts->trsvcid = p; |
| 710 | 714 | break; |
| 711 | 715 | case NVMF_OPT_QUEUE_SIZE: |
| @@ -792,6 +796,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 80 unmodified lines | ||
| 792 | 796 | ret = -EINVAL; |
| 793 | 797 | goto out; |
| 794 | 798 | } |
| 799 | + nvmf_host_put(opts->host); | |
| 795 | 800 | opts->host = nvmf_host_add(p); |
| 796 | 801 | kfree(p); |
| 797 | 802 | if (!opts->host) { |
| @@ -817,6 +822,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, · 19 unmodified lines | ||
| 817 | 822 | ret = -ENOMEM; |
| 818 | 823 | goto out; |
| 819 | 824 | } |
| 825 | + kfree(opts->host_traddr); | |
| 820 | 826 | opts->host_traddr = p; |
| 821 | 827 | break; |
| 822 | 828 | case NVMF_OPT_HOST_ID: |
| @@ -15,10 +15,32 @@ · 14 unmodified lines | ||
| 15 | 15 | #include "nvme.h" |
| 16 | 16 | |
| 17 | 17 | static bool multipath = true; |
| 18 | −module_param(multipath, bool, 0644); | |
| 18 | +module_param(multipath, bool, 0444); | |
| 19 | 19 | MODULE_PARM_DESC(multipath, |
| 20 | 20 | "turn on native support for multiple controllers per subsystem"); |
| 21 | 21 | |
| 22 | +/* | |
| 23 | + * If multipathing is enabled we need to always use the subsystem instance | |
| 24 | + * number for numbering our devices to avoid conflicts between subsystems that | |
| 25 | + * have multiple controllers and thus use the multipath-aware subsystem node | |
| 26 | + * and those that have a single controller and use the controller node | |
| 27 | + * directly. | |
| 28 | + */ | |
| 29 | +void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, | |
| 30 | + struct nvme_ctrl *ctrl, int *flags) | |
| 31 | +{ | |
| 32 | + if (!multipath) { | |
| 33 | + sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance); | |
| 34 | + } else if (ns->head->disk) { | |
| 35 | + sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance, | |
| 36 | + ctrl->cntlid, ns->head->instance); | |
| 37 | + *flags = GENHD_FL_HIDDEN; | |
| 38 | + } else { | |
| 39 | + sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance, | |
| 40 | + ns->head->instance); | |
| 41 | + } | |
| 42 | +} | |
| 43 | + | |
| 22 | 44 | void nvme_failover_req(struct request *req) |
| 23 | 45 | { |
| 24 | 46 | struct nvme_ns *ns = req->q->queuedata; |
| @@ -436,6 +436,8 @@ extern const struct attribute_group nvme_ns_id_attr_group; · 435 unmodified lines | ||
| 436 | 436 | extern const struct block_device_operations nvme_ns_head_ops; |
| 437 | 437 | |
| 438 | 438 | #ifdef CONFIG_NVME_MULTIPATH |
| 439 | +void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, | |
| 440 | + struct nvme_ctrl *ctrl, int *flags); | |
| 439 | 441 | void nvme_failover_req(struct request *req); |
| 440 | 442 | bool nvme_req_needs_failover(struct request *req, blk_status_t error); |
| 441 | 443 | void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); |
| @@ -461,6 +463,16 @@ static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) · 19 unmodified lines | ||
| 461 | 463 | } |
| 462 | 464 | |
| 463 | 465 | #else |
| 466 | +/* | |
| 467 | + * Without the multipath code enabled, multiple controller per subsystems are | |
| 468 | + * visible as devices and thus we cannot use the subsystem instance. | |
| 469 | + */ | |
| 470 | +static inline void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, | |
| 471 | + struct nvme_ctrl *ctrl, int *flags) | |
| 472 | +{ | |
| 473 | + sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance); | |
| 474 | +} | |
| 475 | + | |
| 464 | 476 | static inline void nvme_failover_req(struct request *req) |
| 465 | 477 | { |
| 466 | 478 | } |
| @@ -27,7 +27,7 @@ config NVME_TARGET_LOOP · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | config NVME_TARGET_RDMA |
| 29 | 29 | tristate "NVMe over Fabrics RDMA target support" |
| 30 | − depends on INFINIBAND | |
| 30 | + depends on INFINIBAND && INFINIBAND_ADDR_TRANS | |
| 31 | 31 | depends on NVME_TARGET |
| 32 | 32 | select SGL_ALLOC |
| 33 | 33 | help |
| @@ -469,6 +469,12 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work) · 468 unmodified lines | ||
| 469 | 469 | nvme_stop_ctrl(&ctrl->ctrl); |
| 470 | 470 | nvme_loop_shutdown_ctrl(ctrl); |
| 471 | 471 | |
| 472 | + if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { | |
| 473 | + /* state change failure should never happen */ | |
| 474 | + WARN_ON_ONCE(1); | |
| 475 | + return; | |
| 476 | + } | |
| 477 | + | |
| 472 | 478 | ret = nvme_loop_configure_admin_queue(ctrl); |
| 473 | 479 | if (ret) |
| 474 | 480 | goto out_disable; |
| @@ -942,7 +942,7 @@ int __init early_init_dt_scan_chosen_stdout(void) · 941 unmodified lines | ||
| 942 | 942 | int offset; |
| 943 | 943 | const char *p, *q, *options = NULL; |
| 944 | 944 | int l; |
| 945 | − const struct earlycon_id *match; | |
| 945 | + const struct earlycon_id **p_match; | |
| 946 | 946 | const void *fdt = initial_boot_params; |
| 947 | 947 | |
| 948 | 948 | offset = fdt_path_offset(fdt, "/chosen"); |
| @@ -969,7 +969,10 @@ int __init early_init_dt_scan_chosen_stdout(void) · 20 unmodified lines | ||
| 969 | 969 | return 0; |
| 970 | 970 | } |
| 971 | 971 | |
| 972 | − for (match = __earlycon_table; match < __earlycon_table_end; match++) { | |
| 972 | + for (p_match = __earlycon_table; p_match < __earlycon_table_end; | |
| 973 | + p_match++) { | |
| 974 | + const struct earlycon_id *match = *p_match; | |
| 975 | + | |
| 973 | 976 | if (!match->compatible[0]) |
| 974 | 977 | continue; |
| 975 | 978 | |
| @@ -1263,7 +1263,7 @@ static struct parisc_driver ccio_driver __refdata = { · 1262 unmodified lines | ||
| 1263 | 1263 | * I/O Page Directory, the resource map, and initalizing the |
| 1264 | 1264 | * U2/Uturn chip into virtual mode. |
| 1265 | 1265 | */ |
| 1266 | −static void | |
| 1266 | +static void __init | |
| 1267 | 1267 | ccio_ioc_init(struct ioc *ioc) |
| 1268 | 1268 | { |
| 1269 | 1269 | int i; |
| @@ -486,7 +486,7 @@ static int kirin_pcie_probe(struct platform_device *pdev) · 485 unmodified lines | ||
| 486 | 486 | return ret; |
| 487 | 487 | |
| 488 | 488 | kirin_pcie->gpio_id_reset = of_get_named_gpio(dev->of_node, |
| 489 | − "reset-gpio", 0); | |
| 489 | + "reset-gpios", 0); | |
| 490 | 490 | if (kirin_pcie->gpio_id_reset < 0) |
| 491 | 491 | return -ENODEV; |
| 492 | 492 | |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 |
| 30 | 30 | #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) |
| 31 | 31 | #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 |
| 32 | +#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2 | |
| 32 | 33 | #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 |
| 33 | 34 | #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) |
| 34 | 35 | #define PCIE_CORE_LINK_TRAINING BIT(5) |
| @@ -100,7 +101,8 @@ · 65 unmodified lines | ||
| 100 | 101 | #define PCIE_ISR1_MASK_REG (CONTROL_BASE_ADDR + 0x4C) |
| 101 | 102 | #define PCIE_ISR1_POWER_STATE_CHANGE BIT(4) |
| 102 | 103 | #define PCIE_ISR1_FLUSH BIT(5) |
| 103 | −#define PCIE_ISR1_ALL_MASK GENMASK(5, 4) | |
| 104 | +#define PCIE_ISR1_INTX_ASSERT(val) BIT(8 + (val)) | |
| 105 | +#define PCIE_ISR1_ALL_MASK GENMASK(11, 4) | |
| 104 | 106 | #define PCIE_MSI_ADDR_LOW_REG (CONTROL_BASE_ADDR + 0x50) |
| 105 | 107 | #define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54) |
| 106 | 108 | #define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58) |
| @@ -172,8 +174,6 @@ · 65 unmodified lines | ||
| 172 | 174 | #define PCIE_CONFIG_WR_TYPE0 0xa |
| 173 | 175 | #define PCIE_CONFIG_WR_TYPE1 0xb |
| 174 | 176 | |
| 175 | −/* PCI_BDF shifts 8bit, so we need extra 4bit shift */ | |
| 176 | −#define PCIE_BDF(dev) (dev << 4) | |
| 177 | 177 | #define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20) |
| 178 | 178 | #define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15) |
| 179 | 179 | #define PCIE_CONF_FUNC(fun) (((fun) & 0x7) << 12) |
| @@ -296,7 +296,8 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) · 116 unmodified lines | ||
| 296 | 296 | reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | |
| 297 | 297 | (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | |
| 298 | 298 | PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | |
| 299 | − PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT; | |
| 299 | + (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << | |
| 300 | + PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); | |
| 300 | 301 | advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); |
| 301 | 302 | |
| 302 | 303 | /* Program PCIe Control 2 to disable strict ordering */ |
| @@ -437,7 +438,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, · 134 unmodified lines | ||
| 437 | 438 | u32 reg; |
| 438 | 439 | int ret; |
| 439 | 440 | |
| 440 | − if (PCI_SLOT(devfn) != 0) { | |
| 441 | + if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) { | |
| 441 | 442 | *val = 0xffffffff; |
| 442 | 443 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 443 | 444 | } |
| @@ -456,7 +457,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, · 12 unmodified lines | ||
| 456 | 457 | advk_writel(pcie, reg, PIO_CTRL); |
| 457 | 458 | |
| 458 | 459 | /* Program the address registers */ |
| 459 | − reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where); | |
| 460 | + reg = PCIE_CONF_ADDR(bus->number, devfn, where); | |
| 460 | 461 | advk_writel(pcie, reg, PIO_ADDR_LS); |
| 461 | 462 | advk_writel(pcie, 0, PIO_ADDR_MS); |
| 462 | 463 | |
| @@ -491,7 +492,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, · 28 unmodified lines | ||
| 491 | 492 | int offset; |
| 492 | 493 | int ret; |
| 493 | 494 | |
| 494 | − if (PCI_SLOT(devfn) != 0) | |
| 495 | + if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) | |
| 495 | 496 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 496 | 497 | |
| 497 | 498 | if (where % size) |
| @@ -609,9 +610,9 @@ static void advk_pcie_irq_mask(struct irq_data *d) · 111 unmodified lines | ||
| 609 | 610 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
| 610 | 611 | u32 mask; |
| 611 | 612 | |
| 612 | − mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | |
| 613 | − mask |= PCIE_ISR0_INTX_ASSERT(hwirq); | |
| 614 | − advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | |
| 613 | + mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); | |
| 614 | + mask |= PCIE_ISR1_INTX_ASSERT(hwirq); | |
| 615 | + advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); | |
| 615 | 616 | } |
| 616 | 617 | |
| 617 | 618 | static void advk_pcie_irq_unmask(struct irq_data *d) |
| @@ -620,9 +621,9 @@ static void advk_pcie_irq_unmask(struct irq_data *d) · 2 unmodified lines | ||
| 620 | 621 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
| 621 | 622 | u32 mask; |
| 622 | 623 | |
| 623 | − mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | |
| 624 | − mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq); | |
| 625 | − advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | |
| 624 | + mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); | |
| 625 | + mask &= ~PCIE_ISR1_INTX_ASSERT(hwirq); | |
| 626 | + advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); | |
| 626 | 627 | } |
| 627 | 628 | |
| 628 | 629 | static int advk_pcie_irq_map(struct irq_domain *h, |
| @@ -765,29 +766,35 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie) · 136 unmodified lines | ||
| 765 | 766 | |
| 766 | 767 | static void advk_pcie_handle_int(struct advk_pcie *pcie) |
| 767 | 768 | { |
| 768 | − u32 val, mask, status; | |
| 769 | + u32 isr0_val, isr0_mask, isr0_status; | |
| 770 | + u32 isr1_val, isr1_mask, isr1_status; | |
| 769 | 771 | int i, virq; |
| 770 | 772 | |
| 771 | − val = advk_readl(pcie, PCIE_ISR0_REG); | |
| 772 | − mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | |
| 773 | − status = val & ((~mask) & PCIE_ISR0_ALL_MASK); | |
| 773 | + isr0_val = advk_readl(pcie, PCIE_ISR0_REG); | |
| 774 | + isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | |
| 775 | + isr0_status = isr0_val & ((~isr0_mask) & PCIE_ISR0_ALL_MASK); | |
| 776 | + | |
| 777 | + isr1_val = advk_readl(pcie, PCIE_ISR1_REG); | |
| 778 | + isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); | |
| 779 | + isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK); | |
| 774 | 780 | |
| 775 | − if (!status) { | |
| 776 | − advk_writel(pcie, val, PCIE_ISR0_REG); | |
| 781 | + if (!isr0_status && !isr1_status) { | |
| 782 | + advk_writel(pcie, isr0_val, PCIE_ISR0_REG); | |
| 783 | + advk_writel(pcie, isr1_val, PCIE_ISR1_REG); | |
| 777 | 784 | return; |
| 778 | 785 | } |
| 779 | 786 | |
| 780 | 787 | /* Process MSI interrupts */ |
| 781 | − if (status & PCIE_ISR0_MSI_INT_PENDING) | |
| 788 | + if (isr0_status & PCIE_ISR0_MSI_INT_PENDING) | |
| 782 | 789 | advk_pcie_handle_msi(pcie); |
| 783 | 790 | |
| 784 | 791 | /* Process legacy interrupts */ |
| 785 | 792 | for (i = 0; i < PCI_NUM_INTX; i++) { |
| 786 | − if (!(status & PCIE_ISR0_INTX_ASSERT(i))) | |
| 793 | + if (!(isr1_status & PCIE_ISR1_INTX_ASSERT(i))) | |
| 787 | 794 | continue; |
| 788 | 795 | |
| 789 | − advk_writel(pcie, PCIE_ISR0_INTX_ASSERT(i), | |
| 790 | − PCIE_ISR0_REG); | |
| 796 | + advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i), | |
| 797 | + PCIE_ISR1_REG); | |
| 791 | 798 | |
| 792 | 799 | virq = irq_find_mapping(pcie->irq_domain, i); |
| 793 | 800 | generic_handle_irq(virq); |
| @@ -958,10 +958,11 @@ static int pci_pm_freeze(struct device *dev) · 957 unmodified lines | ||
| 958 | 958 | * devices should not be touched during freeze/thaw transitions, |
| 959 | 959 | * however. |
| 960 | 960 | */ |
| 961 | − if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) | |
| 961 | + if (!dev_pm_smart_suspend_and_suspended(dev)) { | |
| 962 | 962 | pm_runtime_resume(dev); |
| 963 | + pci_dev->state_saved = false; | |
| 964 | + } | |
| 963 | 965 | |
| 964 | − pci_dev->state_saved = false; | |
| 965 | 966 | if (pm->freeze) { |
| 966 | 967 | int error; |
| 967 | 968 | |
| @@ -5273,11 +5273,11 @@ void pcie_print_link_status(struct pci_dev *dev) · 5272 unmodified lines | ||
| 5273 | 5273 | bw_avail = pcie_bandwidth_available(dev, &limiting_dev, &speed, &width); |
| 5274 | 5274 | |
| 5275 | 5275 | if (bw_avail >= bw_cap) |
| 5276 | − pci_info(dev, "%u.%03u Gb/s available bandwidth (%s x%d link)\n", | |
| 5276 | + pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth (%s x%d link)\n", | |
| 5277 | 5277 | bw_cap / 1000, bw_cap % 1000, |
| 5278 | 5278 | PCIE_SPEED2STR(speed_cap), width_cap); |
| 5279 | 5279 | else |
| 5280 | − pci_info(dev, "%u.%03u Gb/s available bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n", | |
| 5280 | + pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n", | |
| 5281 | 5281 | bw_avail / 1000, bw_avail % 1000, |
| 5282 | 5282 | PCIE_SPEED2STR(speed), width, |
| 5283 | 5283 | limiting_dev ? pci_name(limiting_dev) : "<unknown>", |
| @@ -154,7 +154,7 @@ config DELL_LAPTOP · 153 unmodified lines | ||
| 154 | 154 | depends on ACPI_VIDEO || ACPI_VIDEO = n |
| 155 | 155 | depends on RFKILL || RFKILL = n |
| 156 | 156 | depends on SERIO_I8042 |
| 157 | − select DELL_SMBIOS | |
| 157 | + depends on DELL_SMBIOS | |
| 158 | 158 | select POWER_SUPPLY |
| 159 | 159 | select LEDS_CLASS |
| 160 | 160 | select NEW_LEDS |
| @@ -178,8 +178,10 @@ static int asus_wireless_remove(struct acpi_device *adev) · 177 unmodified lines | ||
| 178 | 178 | { |
| 179 | 179 | struct asus_wireless_data *data = acpi_driver_data(adev); |
| 180 | 180 | |
| 181 | − if (data->wq) | |
| 181 | + if (data->wq) { | |
| 182 | + devm_led_classdev_unregister(&adev->dev, &data->led); | |
| 182 | 183 | destroy_workqueue(data->wq); |
| 184 | + } | |
| 183 | 185 | return 0; |
| 184 | 186 | } |
| 185 | 187 | |
| @@ -740,10 +740,7 @@ static int do_dma_request(struct mport_dma_req *req, · 739 unmodified lines | ||
| 740 | 740 | tx->callback = dma_xfer_callback; |
| 741 | 741 | tx->callback_param = req; |
| 742 | 742 | |
| 743 | − req->dmach = chan; | |
| 744 | − req->sync = sync; | |
| 745 | 743 | req->status = DMA_IN_PROGRESS; |
| 746 | − init_completion(&req->req_comp); | |
| 747 | 744 | kref_get(&req->refcount); |
| 748 | 745 | |
| 749 | 746 | cookie = dmaengine_submit(tx); |
| @@ -831,13 +828,20 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, · 81 unmodified lines | ||
| 831 | 828 | if (!req) |
| 832 | 829 | return -ENOMEM; |
| 833 | 830 | |
| 834 | − kref_init(&req->refcount); | |
| 835 | − | |
| 836 | 831 | ret = get_dma_channel(priv); |
| 837 | 832 | if (ret) { |
| 838 | 833 | kfree(req); |
| 839 | 834 | return ret; |
| 840 | 835 | } |
| 836 | + chan = priv->dmach; | |
| 837 | + | |
| 838 | + kref_init(&req->refcount); | |
| 839 | + init_completion(&req->req_comp); | |
| 840 | + req->dir = dir; | |
| 841 | + req->filp = filp; | |
| 842 | + req->priv = priv; | |
| 843 | + req->dmach = chan; | |
| 844 | + req->sync = sync; | |
| 841 | 845 | |
| 842 | 846 | /* |
| 843 | 847 | * If parameter loc_addr != NULL, we are transferring data from/to |
| @@ -925,11 +929,6 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, · 81 unmodified lines | ||
| 925 | 929 | xfer->offset, xfer->length); |
| 926 | 930 | } |
| 927 | 931 | |
| 928 | − req->dir = dir; | |
| 929 | − req->filp = filp; | |
| 930 | − req->priv = priv; | |
| 931 | − chan = priv->dmach; | |
| 932 | − | |
| 933 | 932 | nents = dma_map_sg(chan->device->dev, |
| 934 | 933 | req->sgt.sgl, req->sgt.nents, dir); |
| 935 | 934 | if (nents == 0) { |
| @@ -1083,6 +1083,7 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) · 1082 unmodified lines | ||
| 1083 | 1083 | dev_err(qproc->dev, "unable to resolve mba region\n"); |
| 1084 | 1084 | return ret; |
| 1085 | 1085 | } |
| 1086 | + of_node_put(node); | |
| 1086 | 1087 | |
| 1087 | 1088 | qproc->mba_phys = r.start; |
| 1088 | 1089 | qproc->mba_size = resource_size(&r); |
| @@ -1100,6 +1101,7 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) · 11 unmodified lines | ||
| 1100 | 1101 | dev_err(qproc->dev, "unable to resolve mpss region\n"); |
| 1101 | 1102 | return ret; |
| 1102 | 1103 | } |
| 1104 | + of_node_put(node); | |
| 1103 | 1105 | |
| 1104 | 1106 | qproc->mpss_phys = qproc->mpss_reloc = r.start; |
| 1105 | 1107 | qproc->mpss_size = resource_size(&r); |
| @@ -1163,7 +1163,7 @@ int rproc_trigger_recovery(struct rproc *rproc) · 1162 unmodified lines | ||
| 1163 | 1163 | if (ret) |
| 1164 | 1164 | return ret; |
| 1165 | 1165 | |
| 1166 | − ret = rproc_stop(rproc, false); | |
| 1166 | + ret = rproc_stop(rproc, true); | |
| 1167 | 1167 | if (ret) |
| 1168 | 1168 | goto unlock_mutex; |
| 1169 | 1169 | |
| @@ -1316,7 +1316,7 @@ void rproc_shutdown(struct rproc *rproc) · 146 unmodified lines | ||
| 1316 | 1316 | if (!atomic_dec_and_test(&rproc->power)) |
| 1317 | 1317 | goto out; |
| 1318 | 1318 | |
| 1319 | − ret = rproc_stop(rproc, true); | |
| 1319 | + ret = rproc_stop(rproc, false); | |
| 1320 | 1320 | if (ret) { |
| 1321 | 1321 | atomic_inc(&rproc->power); |
| 1322 | 1322 | goto out; |
| @@ -581,4 +581,6 @@ static void rpmsg_chrdev_exit(void) · 580 unmodified lines | ||
| 581 | 581 | unregister_chrdev_region(rpmsg_major, RPMSG_DEV_MAX); |
| 582 | 582 | } |
| 583 | 583 | module_exit(rpmsg_chrdev_exit); |
| 584 | + | |
| 585 | +MODULE_ALIAS("rpmsg:rpmsg_chrdev"); | |
| 584 | 586 | MODULE_LICENSE("GPL v2"); |
| @@ -57,7 +57,7 @@ static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms) · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) |
| 59 | 59 | { |
| 60 | − long rc = OPAL_BUSY; | |
| 60 | + s64 rc = OPAL_BUSY; | |
| 61 | 61 | int retries = 10; |
| 62 | 62 | u32 y_m_d; |
| 63 | 63 | u64 h_m_s_ms; |
| @@ -66,13 +66,17 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) · 2 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { |
| 68 | 68 | rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); |
| 69 | − if (rc == OPAL_BUSY_EVENT) | |
| 69 | + if (rc == OPAL_BUSY_EVENT) { | |
| 70 | + msleep(OPAL_BUSY_DELAY_MS); | |
| 70 | 71 | opal_poll_events(NULL); |
| 71 | − else if (retries-- && (rc == OPAL_HARDWARE | |
| 72 | − || rc == OPAL_INTERNAL_ERROR)) | |
| 73 | − msleep(10); | |
| 74 | − else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT) | |
| 75 | − break; | |
| 72 | + } else if (rc == OPAL_BUSY) { | |
| 73 | + msleep(OPAL_BUSY_DELAY_MS); | |
| 74 | + } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) { | |
| 75 | + if (retries--) { | |
| 76 | + msleep(10); /* Wait 10ms before retry */ | |
| 77 | + rc = OPAL_BUSY; /* go around again */ | |
| 78 | + } | |
| 79 | + } | |
| 76 | 80 | } |
| 77 | 81 | |
| 78 | 82 | if (rc != OPAL_SUCCESS) |
| @@ -87,21 +91,26 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm) · 8 unmodified lines | ||
| 87 | 91 | |
| 88 | 92 | static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm) |
| 89 | 93 | { |
| 90 | − long rc = OPAL_BUSY; | |
| 94 | + s64 rc = OPAL_BUSY; | |
| 91 | 95 | int retries = 10; |
| 92 | 96 | u32 y_m_d = 0; |
| 93 | 97 | u64 h_m_s_ms = 0; |
| 94 | 98 | |
| 95 | 99 | tm_to_opal(tm, &y_m_d, &h_m_s_ms); |
| 100 | + | |
| 96 | 101 | while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { |
| 97 | 102 | rc = opal_rtc_write(y_m_d, h_m_s_ms); |
| 98 | − if (rc == OPAL_BUSY_EVENT) | |
| 103 | + if (rc == OPAL_BUSY_EVENT) { | |
| 104 | + msleep(OPAL_BUSY_DELAY_MS); | |
| 99 | 105 | opal_poll_events(NULL); |
| 100 | − else if (retries-- && (rc == OPAL_HARDWARE | |
| 101 | − || rc == OPAL_INTERNAL_ERROR)) | |
| 102 | − msleep(10); | |
| 103 | − else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT) | |
| 104 | − break; | |
| 106 | + } else if (rc == OPAL_BUSY) { | |
| 107 | + msleep(OPAL_BUSY_DELAY_MS); | |
| 108 | + } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) { | |
| 109 | + if (retries--) { | |
| 110 | + msleep(10); /* Wait 10ms before retry */ | |
| 111 | + rc = OPAL_BUSY; /* go around again */ | |
| 112 | + } | |
| 113 | + } | |
| 105 | 114 | } |
| 106 | 115 | |
| 107 | 116 | return rc == OPAL_SUCCESS ? 0 : -EIO; |
| @@ -592,13 +592,22 @@ static int _schedule_lcu_update(struct alias_lcu *lcu, · 591 unmodified lines | ||
| 592 | 592 | int dasd_alias_add_device(struct dasd_device *device) |
| 593 | 593 | { |
| 594 | 594 | struct dasd_eckd_private *private = device->private; |
| 595 | − struct alias_lcu *lcu; | |
| 595 | + __u8 uaddr = private->uid.real_unit_addr; | |
| 596 | + struct alias_lcu *lcu = private->lcu; | |
| 596 | 597 | unsigned long flags; |
| 597 | 598 | int rc; |
| 598 | 599 | |
| 599 | − lcu = private->lcu; | |
| 600 | 600 | rc = 0; |
| 601 | 601 | spin_lock_irqsave(&lcu->lock, flags); |
| 602 | + /* | |
| 603 | + * Check if device and lcu type differ. If so, the uac data may be | |
| 604 | + * outdated and needs to be updated. | |
| 605 | + */ | |
| 606 | + if (private->uid.type != lcu->uac->unit[uaddr].ua_type) { | |
| 607 | + lcu->flags |= UPDATE_PENDING; | |
| 608 | + DBF_DEV_EVENT(DBF_WARNING, device, "%s", | |
| 609 | + "uid type mismatch - trigger rescan"); | |
| 610 | + } | |
| 602 | 611 | if (!(lcu->flags & UPDATE_PENDING)) { |
| 603 | 612 | rc = _add_device_to_lcu(lcu, device, device); |
| 604 | 613 | if (rc) |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <asm/io.h> |
| 28 | 28 | #include <asm/irq.h> |
| 29 | 29 | #include <asm/vtoc.h> |
| 30 | −#include <asm/diag.h> | |
| 31 | 30 | |
| 32 | 31 | #include "dasd_int.h" |
| 33 | 32 | #include "dasd_diag.h" |
| @@ -18,7 +18,7 @@ int sclp_init_state __section(.data) = sclp_init_state_uninitialized; · 17 unmodified lines | ||
| 18 | 18 | * Used to keep track of the size of the event masks. Qemu until version 2.11 |
| 19 | 19 | * only supports 4 and needs a workaround. |
| 20 | 20 | */ |
| 21 | −bool sclp_mask_compat_mode; | |
| 21 | +bool sclp_mask_compat_mode __section(.data); | |
| 22 | 22 | |
| 23 | 23 | void sclp_early_wait_irq(void) |
| 24 | 24 | { |
| @@ -452,6 +452,7 @@ static void chsc_process_sei_link_incident(struct chsc_sei_nt0_area *sei_area) · 451 unmodified lines | ||
| 452 | 452 | |
| 453 | 453 | static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area) |
| 454 | 454 | { |
| 455 | + struct channel_path *chp; | |
| 455 | 456 | struct chp_link link; |
| 456 | 457 | struct chp_id chpid; |
| 457 | 458 | int status; |
| @@ -464,10 +465,17 @@ static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area) · 6 unmodified lines | ||
| 464 | 465 | chpid.id = sei_area->rsid; |
| 465 | 466 | /* allocate a new channel path structure, if needed */ |
| 466 | 467 | status = chp_get_status(chpid); |
| 467 | − if (status < 0) | |
| 468 | − chp_new(chpid); | |
| 469 | − else if (!status) | |
| 468 | + if (!status) | |
| 470 | 469 | return; |
| 470 | + | |
| 471 | + if (status < 0) { | |
| 472 | + chp_new(chpid); | |
| 473 | + } else { | |
| 474 | + chp = chpid_to_chp(chpid); | |
| 475 | + mutex_lock(&chp->lock); | |
| 476 | + chp_update_desc(chp); | |
| 477 | + mutex_unlock(&chp->lock); | |
| 478 | + } | |
| 471 | 479 | memset(&link, 0, sizeof(struct chp_link)); |
| 472 | 480 | link.chpid = chpid; |
| 473 | 481 | if ((sei_area->vf & 0xc0) != 0) { |
| @@ -20,12 +20,12 @@ static int fsm_io_helper(struct vfio_ccw_private *private) · 19 unmodified lines | ||
| 20 | 20 | int ccode; |
| 21 | 21 | __u8 lpm; |
| 22 | 22 | unsigned long flags; |
| 23 | + int ret; | |
| 23 | 24 | |
| 24 | 25 | sch = private->sch; |
| 25 | 26 | |
| 26 | 27 | spin_lock_irqsave(sch->lock, flags); |
| 27 | 28 | private->state = VFIO_CCW_STATE_BUSY; |
| 28 | − spin_unlock_irqrestore(sch->lock, flags); | |
| 29 | 29 | |
| 30 | 30 | orb = cp_get_orb(&private->cp, (u32)(addr_t)sch, sch->lpm); |
| 31 | 31 | |
| @@ -38,10 +38,12 @@ static int fsm_io_helper(struct vfio_ccw_private *private) · 6 unmodified lines | ||
| 38 | 38 | * Initialize device status information |
| 39 | 39 | */ |
| 40 | 40 | sch->schib.scsw.cmd.actl |= SCSW_ACTL_START_PEND; |
| 41 | − return 0; | |
| 41 | + ret = 0; | |
| 42 | + break; | |
| 42 | 43 | case 1: /* Status pending */ |
| 43 | 44 | case 2: /* Busy */ |
| 44 | − return -EBUSY; | |
| 45 | + ret = -EBUSY; | |
| 46 | + break; | |
| 45 | 47 | case 3: /* Device/path not operational */ |
| 46 | 48 | { |
| 47 | 49 | lpm = orb->cmd.lpm; |
| @@ -51,13 +53,16 @@ static int fsm_io_helper(struct vfio_ccw_private *private) · 3 unmodified lines | ||
| 51 | 53 | sch->lpm = 0; |
| 52 | 54 | |
| 53 | 55 | if (cio_update_schib(sch)) |
| 54 | − return -ENODEV; | |
| 55 | − | |
| 56 | − return sch->lpm ? -EACCES : -ENODEV; | |
| 56 | + ret = -ENODEV; | |
| 57 | + else | |
| 58 | + ret = sch->lpm ? -EACCES : -ENODEV; | |
| 59 | + break; | |
| 57 | 60 | } |
| 58 | 61 | default: |
| 59 | − return ccode; | |
| 62 | + ret = ccode; | |
| 60 | 63 | } |
| 64 | + spin_unlock_irqrestore(sch->lock, flags); | |
| 65 | + return ret; | |
| 61 | 66 | } |
| 62 | 67 | |
| 63 | 68 | static void fsm_notoper(struct vfio_ccw_private *private, |
| @@ -557,7 +557,6 @@ enum qeth_prot_versions { · 556 unmodified lines | ||
| 557 | 557 | enum qeth_cmd_buffer_state { |
| 558 | 558 | BUF_STATE_FREE, |
| 559 | 559 | BUF_STATE_LOCKED, |
| 560 | − BUF_STATE_PROCESSED, | |
| 561 | 560 | }; |
| 562 | 561 | |
| 563 | 562 | enum qeth_cq { |
| @@ -601,7 +600,6 @@ struct qeth_channel { · 37 unmodified lines | ||
| 601 | 600 | struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO]; |
| 602 | 601 | atomic_t irq_pending; |
| 603 | 602 | int io_buf_no; |
| 604 | − int buf_no; | |
| 605 | 603 | }; |
| 606 | 604 | |
| 607 | 605 | /** |
| @@ -706,7 +706,6 @@ void qeth_clear_ipacmd_list(struct qeth_card *card) · 705 unmodified lines | ||
| 706 | 706 | qeth_put_reply(reply); |
| 707 | 707 | } |
| 708 | 708 | spin_unlock_irqrestore(&card->lock, flags); |
| 709 | − atomic_set(&card->write.irq_pending, 0); | |
| 710 | 709 | } |
| 711 | 710 | EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list); |
| 712 | 711 | |
| @@ -818,7 +817,6 @@ void qeth_clear_cmd_buffers(struct qeth_channel *channel) · 105 unmodified lines | ||
| 818 | 817 | |
| 819 | 818 | for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) |
| 820 | 819 | qeth_release_buffer(channel, &channel->iob[cnt]); |
| 821 | − channel->buf_no = 0; | |
| 822 | 820 | channel->io_buf_no = 0; |
| 823 | 821 | } |
| 824 | 822 | EXPORT_SYMBOL_GPL(qeth_clear_cmd_buffers); |
| @@ -924,7 +922,6 @@ static int qeth_setup_channel(struct qeth_channel *channel) · 99 unmodified lines | ||
| 924 | 922 | kfree(channel->iob[cnt].data); |
| 925 | 923 | return -ENOMEM; |
| 926 | 924 | } |
| 927 | − channel->buf_no = 0; | |
| 928 | 925 | channel->io_buf_no = 0; |
| 929 | 926 | atomic_set(&channel->irq_pending, 0); |
| 930 | 927 | spin_lock_init(&channel->iob_lock); |
| @@ -1100,16 +1097,9 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, · 169 unmodified lines | ||
| 1100 | 1097 | { |
| 1101 | 1098 | int rc; |
| 1102 | 1099 | int cstat, dstat; |
| 1103 | − struct qeth_cmd_buffer *buffer; | |
| 1100 | + struct qeth_cmd_buffer *iob = NULL; | |
| 1104 | 1101 | struct qeth_channel *channel; |
| 1105 | 1102 | struct qeth_card *card; |
| 1106 | − struct qeth_cmd_buffer *iob; | |
| 1107 | − __u8 index; | |
| 1108 | − | |
| 1109 | − if (__qeth_check_irb_error(cdev, intparm, irb)) | |
| 1110 | − return; | |
| 1111 | − cstat = irb->scsw.cmd.cstat; | |
| 1112 | − dstat = irb->scsw.cmd.dstat; | |
| 1113 | 1103 | |
| 1114 | 1104 | card = CARD_FROM_CDEV(cdev); |
| 1115 | 1105 | if (!card) |
| @@ -1127,6 +1117,19 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, · 11 unmodified lines | ||
| 1127 | 1117 | channel = &card->data; |
| 1128 | 1118 | QETH_CARD_TEXT(card, 5, "data"); |
| 1129 | 1119 | } |
| 1120 | + | |
| 1121 | + if (qeth_intparm_is_iob(intparm)) | |
| 1122 | + iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm); | |
| 1123 | + | |
| 1124 | + if (__qeth_check_irb_error(cdev, intparm, irb)) { | |
| 1125 | + /* IO was terminated, free its resources. */ | |
| 1126 | + if (iob) | |
| 1127 | + qeth_release_buffer(iob->channel, iob); | |
| 1128 | + atomic_set(&channel->irq_pending, 0); | |
| 1129 | + wake_up(&card->wait_q); | |
| 1130 | + return; | |
| 1131 | + } | |
| 1132 | + | |
| 1130 | 1133 | atomic_set(&channel->irq_pending, 0); |
| 1131 | 1134 | |
| 1132 | 1135 | if (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC)) |
| @@ -1150,6 +1153,10 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, · 17 unmodified lines | ||
| 1150 | 1153 | /* we don't have to handle this further */ |
| 1151 | 1154 | intparm = 0; |
| 1152 | 1155 | } |
| 1156 | + | |
| 1157 | + cstat = irb->scsw.cmd.cstat; | |
| 1158 | + dstat = irb->scsw.cmd.dstat; | |
| 1159 | + | |
| 1153 | 1160 | if ((dstat & DEV_STAT_UNIT_EXCEP) || |
| 1154 | 1161 | (dstat & DEV_STAT_UNIT_CHECK) || |
| 1155 | 1162 | (cstat)) { |
| @@ -1182,25 +1189,15 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, · 26 unmodified lines | ||
| 1182 | 1189 | channel->state = CH_STATE_RCD_DONE; |
| 1183 | 1190 | goto out; |
| 1184 | 1191 | } |
| 1185 | − if (intparm) { | |
| 1186 | − buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm); | |
| 1187 | − buffer->state = BUF_STATE_PROCESSED; | |
| 1188 | − } | |
| 1189 | 1192 | if (channel == &card->data) |
| 1190 | 1193 | return; |
| 1191 | 1194 | if (channel == &card->read && |
| 1192 | 1195 | channel->state == CH_STATE_UP) |
| 1193 | 1196 | __qeth_issue_next_read(card); |
| 1194 | 1197 | |
| 1195 | − iob = channel->iob; | |
| 1196 | − index = channel->buf_no; | |
| 1197 | − while (iob[index].state == BUF_STATE_PROCESSED) { | |
| 1198 | − if (iob[index].callback != NULL) | |
| 1199 | − iob[index].callback(channel, iob + index); | |
| 1198 | + if (iob && iob->callback) | |
| 1199 | + iob->callback(iob->channel, iob); | |
| 1200 | 1200 | |
| 1201 | − index = (index + 1) % QETH_CMD_BUFFER_NO; | |
| 1202 | − } | |
| 1203 | − channel->buf_no = index; | |
| 1204 | 1201 | out: |
| 1205 | 1202 | wake_up(&card->wait_q); |
| 1206 | 1203 | return; |
| @@ -1870,8 +1867,8 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, · 663 unmodified lines | ||
| 1870 | 1867 | atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0); |
| 1871 | 1868 | QETH_DBF_TEXT(SETUP, 6, "noirqpnd"); |
| 1872 | 1869 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); |
| 1873 | − rc = ccw_device_start(channel->ccwdev, | |
| 1874 | − &channel->ccw, (addr_t) iob, 0, 0); | |
| 1870 | + rc = ccw_device_start_timeout(channel->ccwdev, &channel->ccw, | |
| 1871 | + (addr_t) iob, 0, 0, QETH_TIMEOUT); | |
| 1875 | 1872 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); |
| 1876 | 1873 | |
| 1877 | 1874 | if (rc) { |
| @@ -1888,7 +1885,6 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, · 10 unmodified lines | ||
| 1888 | 1885 | if (channel->state != CH_STATE_UP) { |
| 1889 | 1886 | rc = -ETIME; |
| 1890 | 1887 | QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); |
| 1891 | − qeth_clear_cmd_buffers(channel); | |
| 1892 | 1888 | } else |
| 1893 | 1889 | rc = 0; |
| 1894 | 1890 | return rc; |
| @@ -1942,8 +1938,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, · 47 unmodified lines | ||
| 1942 | 1938 | atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0); |
| 1943 | 1939 | QETH_DBF_TEXT(SETUP, 6, "noirqpnd"); |
| 1944 | 1940 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); |
| 1945 | − rc = ccw_device_start(channel->ccwdev, | |
| 1946 | − &channel->ccw, (addr_t) iob, 0, 0); | |
| 1941 | + rc = ccw_device_start_timeout(channel->ccwdev, &channel->ccw, | |
| 1942 | + (addr_t) iob, 0, 0, QETH_TIMEOUT); | |
| 1947 | 1943 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); |
| 1948 | 1944 | |
| 1949 | 1945 | if (rc) { |
| @@ -1964,7 +1960,6 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, · 14 unmodified lines | ||
| 1964 | 1960 | QETH_DBF_MESSAGE(2, "%s IDX activate timed out\n", |
| 1965 | 1961 | dev_name(&channel->ccwdev->dev)); |
| 1966 | 1962 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", -ETIME); |
| 1967 | − qeth_clear_cmd_buffers(channel); | |
| 1968 | 1963 | return -ETIME; |
| 1969 | 1964 | } |
| 1970 | 1965 | return qeth_idx_activate_get_answer(channel, idx_reply_cb); |
| @@ -2166,8 +2161,8 @@ int qeth_send_control_data(struct qeth_card *card, int len, · 195 unmodified lines | ||
| 2166 | 2161 | |
| 2167 | 2162 | QETH_CARD_TEXT(card, 6, "noirqpnd"); |
| 2168 | 2163 | spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags); |
| 2169 | − rc = ccw_device_start(card->write.ccwdev, &card->write.ccw, | |
| 2170 | − (addr_t) iob, 0, 0); | |
| 2164 | + rc = ccw_device_start_timeout(CARD_WDEV(card), &card->write.ccw, | |
| 2165 | + (addr_t) iob, 0, 0, event_timeout); | |
| 2171 | 2166 | spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags); |
| 2172 | 2167 | if (rc) { |
| 2173 | 2168 | QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: " |
| @@ -2199,8 +2194,6 @@ int qeth_send_control_data(struct qeth_card *card, int len, · 25 unmodified lines | ||
| 2199 | 2194 | } |
| 2200 | 2195 | } |
| 2201 | 2196 | |
| 2202 | − if (reply->rc == -EIO) | |
| 2203 | − goto error; | |
| 2204 | 2197 | rc = reply->rc; |
| 2205 | 2198 | qeth_put_reply(reply); |
| 2206 | 2199 | return rc; |
| @@ -2211,10 +2204,6 @@ time_err: · 4 unmodified lines | ||
| 2211 | 2204 | list_del_init(&reply->list); |
| 2212 | 2205 | spin_unlock_irqrestore(&reply->card->lock, flags); |
| 2213 | 2206 | atomic_inc(&reply->received); |
| 2214 | −error: | |
| 2215 | − atomic_set(&card->write.irq_pending, 0); | |
| 2216 | − qeth_release_buffer(iob->channel, iob); | |
| 2217 | − card->write.buf_no = (card->write.buf_no + 1) % QETH_CMD_BUFFER_NO; | |
| 2218 | 2207 | rc = reply->rc; |
| 2219 | 2208 | qeth_put_reply(reply); |
| 2220 | 2209 | return rc; |
| @@ -3033,28 +3022,23 @@ static int qeth_send_startlan(struct qeth_card *card) · 812 unmodified lines | ||
| 3033 | 3022 | return rc; |
| 3034 | 3023 | } |
| 3035 | 3024 | |
| 3036 | −static int qeth_default_setadapterparms_cb(struct qeth_card *card, | |
| 3037 | − struct qeth_reply *reply, unsigned long data) | |
| 3025 | +static int qeth_setadpparms_inspect_rc(struct qeth_ipa_cmd *cmd) | |
| 3038 | 3026 | { |
| 3039 | − struct qeth_ipa_cmd *cmd; | |
| 3040 | − | |
| 3041 | − QETH_CARD_TEXT(card, 4, "defadpcb"); | |
| 3042 | − | |
| 3043 | − cmd = (struct qeth_ipa_cmd *) data; | |
| 3044 | − if (cmd->hdr.return_code == 0) | |
| 3027 | + if (!cmd->hdr.return_code) | |
| 3045 | 3028 | cmd->hdr.return_code = |
| 3046 | 3029 | cmd->data.setadapterparms.hdr.return_code; |
| 3047 | − return 0; | |
| 3030 | + return cmd->hdr.return_code; | |
| 3048 | 3031 | } |
| 3049 | 3032 | |
| 3050 | 3033 | static int qeth_query_setadapterparms_cb(struct qeth_card *card, |
| 3051 | 3034 | struct qeth_reply *reply, unsigned long data) |
| 3052 | 3035 | { |
| 3053 | − struct qeth_ipa_cmd *cmd; | |
| 3036 | + struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data; | |
| 3054 | 3037 | |
| 3055 | 3038 | QETH_CARD_TEXT(card, 3, "quyadpcb"); |
| 3039 | + if (qeth_setadpparms_inspect_rc(cmd)) | |
| 3040 | + return 0; | |
| 3056 | 3041 | |
| 3057 | − cmd = (struct qeth_ipa_cmd *) data; | |
| 3058 | 3042 | if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) { |
| 3059 | 3043 | card->info.link_type = |
| 3060 | 3044 | cmd->data.setadapterparms.data.query_cmds_supp.lan_type; |
| @@ -3062,7 +3046,7 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card, · 1 unmodified line | ||
| 3062 | 3046 | } |
| 3063 | 3047 | card->options.adp.supported_funcs = |
| 3064 | 3048 | cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds; |
| 3065 | − return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd); | |
| 3049 | + return 0; | |
| 3066 | 3050 | } |
| 3067 | 3051 | |
| 3068 | 3052 | static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, |
| @@ -3154,22 +3138,20 @@ EXPORT_SYMBOL_GPL(qeth_query_ipassists); · 85 unmodified lines | ||
| 3154 | 3138 | static int qeth_query_switch_attributes_cb(struct qeth_card *card, |
| 3155 | 3139 | struct qeth_reply *reply, unsigned long data) |
| 3156 | 3140 | { |
| 3157 | − struct qeth_ipa_cmd *cmd; | |
| 3158 | − struct qeth_switch_info *sw_info; | |
| 3141 | + struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data; | |
| 3159 | 3142 | struct qeth_query_switch_attributes *attrs; |
| 3143 | + struct qeth_switch_info *sw_info; | |
| 3160 | 3144 | |
| 3161 | 3145 | QETH_CARD_TEXT(card, 2, "qswiatcb"); |
| 3162 | − cmd = (struct qeth_ipa_cmd *) data; | |
| 3163 | − sw_info = (struct qeth_switch_info *)reply->param; | |
| 3164 | − if (cmd->data.setadapterparms.hdr.return_code == 0) { | |
| 3165 | − attrs = &cmd->data.setadapterparms.data.query_switch_attributes; | |
| 3166 | − sw_info->capabilities = attrs->capabilities; | |
| 3167 | − sw_info->settings = attrs->settings; | |
| 3168 | − QETH_CARD_TEXT_(card, 2, "%04x%04x", sw_info->capabilities, | |
| 3169 | − sw_info->settings); | |
| 3170 | − } | |
| 3171 | − qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); | |
| 3146 | + if (qeth_setadpparms_inspect_rc(cmd)) | |
| 3147 | + return 0; | |
| 3172 | 3148 | |
| 3149 | + sw_info = (struct qeth_switch_info *)reply->param; | |
| 3150 | + attrs = &cmd->data.setadapterparms.data.query_switch_attributes; | |
| 3151 | + sw_info->capabilities = attrs->capabilities; | |
| 3152 | + sw_info->settings = attrs->settings; | |
| 3153 | + QETH_CARD_TEXT_(card, 2, "%04x%04x", sw_info->capabilities, | |
| 3154 | + sw_info->settings); | |
| 3173 | 3155 | return 0; |
| 3174 | 3156 | } |
| 3175 | 3157 | |
| @@ -4207,16 +4189,13 @@ EXPORT_SYMBOL_GPL(qeth_do_send_packet); · 1031 unmodified lines | ||
| 4207 | 4189 | static int qeth_setadp_promisc_mode_cb(struct qeth_card *card, |
| 4208 | 4190 | struct qeth_reply *reply, unsigned long data) |
| 4209 | 4191 | { |
| 4210 | − struct qeth_ipa_cmd *cmd; | |
| 4192 | + struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data; | |
| 4211 | 4193 | struct qeth_ipacmd_setadpparms *setparms; |
| 4212 | 4194 | |
| 4213 | 4195 | QETH_CARD_TEXT(card, 4, "prmadpcb"); |
| 4214 | 4196 | |
| 4215 | − cmd = (struct qeth_ipa_cmd *) data; | |
138 more lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 232 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 483 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 234 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 175 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 380 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 202 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 99 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 738 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 495 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 244 lines aren’t shown here.
This diff is large: its 232 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.