diff options
43 files changed, 422 insertions, 290 deletions
@@ -62,6 +62,7 @@ Frank Zago <fzago@systemfabricworks.com> | |||
62 | Greg Kroah-Hartman <greg@echidna.(none)> | 62 | Greg Kroah-Hartman <greg@echidna.(none)> |
63 | Greg Kroah-Hartman <gregkh@suse.de> | 63 | Greg Kroah-Hartman <gregkh@suse.de> |
64 | Greg Kroah-Hartman <greg@kroah.com> | 64 | Greg Kroah-Hartman <greg@kroah.com> |
65 | Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com> | ||
65 | Henk Vergonet <Henk.Vergonet@gmail.com> | 66 | Henk Vergonet <Henk.Vergonet@gmail.com> |
66 | Henrik Kretzschmar <henne@nachtwindheim.de> | 67 | Henrik Kretzschmar <henne@nachtwindheim.de> |
67 | Henrik Rydberg <rydberg@bitmath.org> | 68 | Henrik Rydberg <rydberg@bitmath.org> |
diff --git a/MAINTAINERS b/MAINTAINERS index c2df576114c3..6e950b8b4a41 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1153,7 +1153,7 @@ S: Maintained | |||
1153 | F: drivers/clk/sunxi/ | 1153 | F: drivers/clk/sunxi/ |
1154 | 1154 | ||
1155 | ARM/Allwinner sunXi SoC support | 1155 | ARM/Allwinner sunXi SoC support |
1156 | M: Maxime Ripard <maxime.ripard@free-electrons.com> | 1156 | M: Maxime Ripard <maxime.ripard@bootlin.com> |
1157 | M: Chen-Yu Tsai <wens@csie.org> | 1157 | M: Chen-Yu Tsai <wens@csie.org> |
1158 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1158 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1159 | S: Maintained | 1159 | S: Maintained |
@@ -4627,7 +4627,7 @@ F: include/uapi/drm/drm* | |||
4627 | F: include/linux/vga* | 4627 | F: include/linux/vga* |
4628 | 4628 | ||
4629 | DRM DRIVERS FOR ALLWINNER A10 | 4629 | DRM DRIVERS FOR ALLWINNER A10 |
4630 | M: Maxime Ripard <maxime.ripard@free-electrons.com> | 4630 | M: Maxime Ripard <maxime.ripard@bootlin.com> |
4631 | L: dri-devel@lists.freedesktop.org | 4631 | L: dri-devel@lists.freedesktop.org |
4632 | S: Supported | 4632 | S: Supported |
4633 | F: drivers/gpu/drm/sun4i/ | 4633 | F: drivers/gpu/drm/sun4i/ |
@@ -13658,7 +13658,8 @@ S: Supported | |||
13658 | F: drivers/i2c/busses/i2c-tegra.c | 13658 | F: drivers/i2c/busses/i2c-tegra.c |
13659 | 13659 | ||
13660 | TEGRA IOMMU DRIVERS | 13660 | TEGRA IOMMU DRIVERS |
13661 | M: Hiroshi Doyu <hdoyu@nvidia.com> | 13661 | M: Thierry Reding <thierry.reding@gmail.com> |
13662 | L: linux-tegra@vger.kernel.org | ||
13662 | S: Supported | 13663 | S: Supported |
13663 | F: drivers/iommu/tegra* | 13664 | F: drivers/iommu/tegra* |
13664 | 13665 | ||
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 78a647080ebc..199ebc1c4538 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -22,6 +22,7 @@ config ARM_PTDUMP_DEBUGFS | |||
22 | 22 | ||
23 | config DEBUG_WX | 23 | config DEBUG_WX |
24 | bool "Warn on W+X mappings at boot" | 24 | bool "Warn on W+X mappings at boot" |
25 | depends on MMU | ||
25 | select ARM_PTDUMP_CORE | 26 | select ARM_PTDUMP_CORE |
26 | ---help--- | 27 | ---help--- |
27 | Generate a warning if any W+X mappings are found at boot. | 28 | Generate a warning if any W+X mappings are found at boot. |
diff --git a/arch/arm/boot/deflate_xip_data.sh b/arch/arm/boot/deflate_xip_data.sh index 1189598a25eb..5e7d758ebdd6 100755 --- a/arch/arm/boot/deflate_xip_data.sh +++ b/arch/arm/boot/deflate_xip_data.sh | |||
@@ -30,7 +30,7 @@ esac | |||
30 | 30 | ||
31 | sym_val() { | 31 | sym_val() { |
32 | # extract hex value for symbol in $1 | 32 | # extract hex value for symbol in $1 |
33 | local val=$($NM "$VMLINUX" | sed -n "/ $1$/{s/ .*$//p;q}") | 33 | local val=$($NM "$VMLINUX" 2>/dev/null | sed -n "/ $1\$/{s/ .*$//p;q}") |
34 | [ "$val" ] || { echo "can't find $1 in $VMLINUX" 1>&2; exit 1; } | 34 | [ "$val" ] || { echo "can't find $1 in $VMLINUX" 1>&2; exit 1; } |
35 | # convert from hex to decimal | 35 | # convert from hex to decimal |
36 | echo $((0x$val)) | 36 | echo $((0x$val)) |
@@ -48,12 +48,12 @@ data_end=$(($_edata_loc - $base_offset)) | |||
48 | file_end=$(stat -c "%s" "$XIPIMAGE") | 48 | file_end=$(stat -c "%s" "$XIPIMAGE") |
49 | if [ "$file_end" != "$data_end" ]; then | 49 | if [ "$file_end" != "$data_end" ]; then |
50 | printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \ | 50 | printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \ |
51 | $(($file_end + $base_offset)) $_edata_loc 2>&1 | 51 | $(($file_end + $base_offset)) $_edata_loc 1>&2 |
52 | exit 1; | 52 | exit 1; |
53 | fi | 53 | fi |
54 | 54 | ||
55 | # be ready to clean up | 55 | # be ready to clean up |
56 | trap 'rm -f "$XIPIMAGE.tmp"' 0 1 2 3 | 56 | trap 'rm -f "$XIPIMAGE.tmp"; exit 1' 1 2 3 |
57 | 57 | ||
58 | # substitute the data section by a compressed version | 58 | # substitute the data section by a compressed version |
59 | $DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp" | 59 | $DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp" |
diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index b0d8431a3700..ae2b8c952e80 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi | |||
@@ -42,6 +42,11 @@ | |||
42 | }; | 42 | }; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | memory@40000000 { | ||
46 | device_type = "memory"; | ||
47 | reg = <0x40000000 0>; | ||
48 | }; | ||
49 | |||
45 | ahb { | 50 | ahb { |
46 | compatible = "simple-bus"; | 51 | compatible = "simple-bus"; |
47 | #address-cells = <1>; | 52 | #address-cells = <1>; |
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 40de3b66c33f..2477ebc11d9d 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi | |||
@@ -42,6 +42,11 @@ | |||
42 | }; | 42 | }; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | memory@80000000 { | ||
46 | device_type = "memory"; | ||
47 | reg = <0x80000000 0>; | ||
48 | }; | ||
49 | |||
45 | ahb { | 50 | ahb { |
46 | compatible = "simple-bus"; | 51 | compatible = "simple-bus"; |
47 | #address-cells = <1>; | 52 | #address-cells = <1>; |
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index a7a5dc7b2700..e7d2db839d70 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts | |||
@@ -82,7 +82,7 @@ | |||
82 | enable-active-high; | 82 | enable-active-high; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | reg_usb_otg2_vbus: regulator-usb-otg1-vbus { | 85 | reg_usb_otg2_vbus: regulator-usb-otg2-vbus { |
86 | compatible = "regulator-fixed"; | 86 | compatible = "regulator-fixed"; |
87 | regulator-name = "usb_otg2_vbus"; | 87 | regulator-name = "usb_otg2_vbus"; |
88 | regulator-min-microvolt = <5000000>; | 88 | regulator-min-microvolt = <5000000>; |
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 6102e4e7f35c..354aff45c1af 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi | |||
@@ -927,6 +927,7 @@ | |||
927 | i2s: i2s@ff890000 { | 927 | i2s: i2s@ff890000 { |
928 | compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; | 928 | compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; |
929 | reg = <0x0 0xff890000 0x0 0x10000>; | 929 | reg = <0x0 0xff890000 0x0 0x10000>; |
930 | #sound-dai-cells = <0>; | ||
930 | interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; | 931 | interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; |
931 | #address-cells = <1>; | 932 | #address-cells = <1>; |
932 | #size-cells = <0>; | 933 | #size-cells = <0>; |
@@ -1176,6 +1177,7 @@ | |||
1176 | compatible = "rockchip,rk3288-dw-hdmi"; | 1177 | compatible = "rockchip,rk3288-dw-hdmi"; |
1177 | reg = <0x0 0xff980000 0x0 0x20000>; | 1178 | reg = <0x0 0xff980000 0x0 0x20000>; |
1178 | reg-io-width = <4>; | 1179 | reg-io-width = <4>; |
1180 | #sound-dai-cells = <0>; | ||
1179 | rockchip,grf = <&grf>; | 1181 | rockchip,grf = <&grf>; |
1180 | interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; | 1182 | interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; |
1181 | clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>; | 1183 | clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>; |
diff --git a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts index 51e6f1d21c32..b2758dd8ce43 100644 --- a/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts +++ b/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts | |||
@@ -42,7 +42,6 @@ | |||
42 | 42 | ||
43 | /dts-v1/; | 43 | /dts-v1/; |
44 | #include "sun6i-a31s.dtsi" | 44 | #include "sun6i-a31s.dtsi" |
45 | #include "sunxi-common-regulators.dtsi" | ||
46 | #include <dt-bindings/gpio/gpio.h> | 45 | #include <dt-bindings/gpio/gpio.h> |
47 | 46 | ||
48 | / { | 47 | / { |
@@ -99,6 +98,7 @@ | |||
99 | pinctrl-0 = <&gmac_pins_rgmii_a>, <&gmac_phy_reset_pin_bpi_m2>; | 98 | pinctrl-0 = <&gmac_pins_rgmii_a>, <&gmac_phy_reset_pin_bpi_m2>; |
100 | phy = <&phy1>; | 99 | phy = <&phy1>; |
101 | phy-mode = "rgmii"; | 100 | phy-mode = "rgmii"; |
101 | phy-supply = <®_dldo1>; | ||
102 | snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>; /* PA21 */ | 102 | snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>; /* PA21 */ |
103 | snps,reset-active-low; | 103 | snps,reset-active-low; |
104 | snps,reset-delays-us = <0 10000 30000>; | 104 | snps,reset-delays-us = <0 10000 30000>; |
@@ -118,7 +118,7 @@ | |||
118 | &mmc0 { | 118 | &mmc0 { |
119 | pinctrl-names = "default"; | 119 | pinctrl-names = "default"; |
120 | pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bpi_m2>; | 120 | pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bpi_m2>; |
121 | vmmc-supply = <®_vcc3v0>; | 121 | vmmc-supply = <®_dcdc1>; |
122 | bus-width = <4>; | 122 | bus-width = <4>; |
123 | cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */ | 123 | cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */ |
124 | cd-inverted; | 124 | cd-inverted; |
@@ -132,7 +132,7 @@ | |||
132 | &mmc2 { | 132 | &mmc2 { |
133 | pinctrl-names = "default"; | 133 | pinctrl-names = "default"; |
134 | pinctrl-0 = <&mmc2_pins_a>; | 134 | pinctrl-0 = <&mmc2_pins_a>; |
135 | vmmc-supply = <®_vcc3v0>; | 135 | vmmc-supply = <®_aldo1>; |
136 | mmc-pwrseq = <&mmc2_pwrseq>; | 136 | mmc-pwrseq = <&mmc2_pwrseq>; |
137 | bus-width = <4>; | 137 | bus-width = <4>; |
138 | non-removable; | 138 | non-removable; |
@@ -163,6 +163,8 @@ | |||
163 | reg = <0x68>; | 163 | reg = <0x68>; |
164 | interrupt-parent = <&nmi_intc>; | 164 | interrupt-parent = <&nmi_intc>; |
165 | interrupts = <0 IRQ_TYPE_LEVEL_LOW>; | 165 | interrupts = <0 IRQ_TYPE_LEVEL_LOW>; |
166 | eldoin-supply = <®_dcdc1>; | ||
167 | x-powers,drive-vbus-en; | ||
166 | }; | 168 | }; |
167 | }; | 169 | }; |
168 | 170 | ||
@@ -193,7 +195,28 @@ | |||
193 | 195 | ||
194 | #include "axp22x.dtsi" | 196 | #include "axp22x.dtsi" |
195 | 197 | ||
198 | ®_aldo1 { | ||
199 | regulator-min-microvolt = <3300000>; | ||
200 | regulator-max-microvolt = <3300000>; | ||
201 | regulator-name = "vcc-wifi"; | ||
202 | }; | ||
203 | |||
204 | ®_aldo2 { | ||
205 | regulator-always-on; | ||
206 | regulator-min-microvolt = <2500000>; | ||
207 | regulator-max-microvolt = <2500000>; | ||
208 | regulator-name = "vcc-gmac"; | ||
209 | }; | ||
210 | |||
211 | ®_aldo3 { | ||
212 | regulator-always-on; | ||
213 | regulator-min-microvolt = <3000000>; | ||
214 | regulator-max-microvolt = <3000000>; | ||
215 | regulator-name = "avcc"; | ||
216 | }; | ||
217 | |||
196 | ®_dc5ldo { | 218 | ®_dc5ldo { |
219 | regulator-always-on; | ||
197 | regulator-min-microvolt = <700000>; | 220 | regulator-min-microvolt = <700000>; |
198 | regulator-max-microvolt = <1320000>; | 221 | regulator-max-microvolt = <1320000>; |
199 | regulator-name = "vdd-cpus"; | 222 | regulator-name = "vdd-cpus"; |
@@ -233,6 +256,40 @@ | |||
233 | regulator-name = "vcc-dram"; | 256 | regulator-name = "vcc-dram"; |
234 | }; | 257 | }; |
235 | 258 | ||
259 | ®_dldo1 { | ||
260 | regulator-min-microvolt = <3000000>; | ||
261 | regulator-max-microvolt = <3000000>; | ||
262 | regulator-name = "vcc-mac"; | ||
263 | }; | ||
264 | |||
265 | ®_dldo2 { | ||
266 | regulator-min-microvolt = <2800000>; | ||
267 | regulator-max-microvolt = <2800000>; | ||
268 | regulator-name = "avdd-csi"; | ||
269 | }; | ||
270 | |||
271 | ®_dldo3 { | ||
272 | regulator-always-on; | ||
273 | regulator-min-microvolt = <3300000>; | ||
274 | regulator-max-microvolt = <3300000>; | ||
275 | regulator-name = "vcc-pb"; | ||
276 | }; | ||
277 | |||
278 | ®_eldo1 { | ||
279 | regulator-min-microvolt = <1800000>; | ||
280 | regulator-max-microvolt = <1800000>; | ||
281 | regulator-name = "vdd-csi"; | ||
282 | status = "okay"; | ||
283 | }; | ||
284 | |||
285 | ®_ldo_io1 { | ||
286 | regulator-always-on; | ||
287 | regulator-min-microvolt = <1800000>; | ||
288 | regulator-max-microvolt = <1800000>; | ||
289 | regulator-name = "vcc-pm-cpus"; | ||
290 | status = "okay"; | ||
291 | }; | ||
292 | |||
236 | &uart0 { | 293 | &uart0 { |
237 | pinctrl-names = "default"; | 294 | pinctrl-names = "default"; |
238 | pinctrl-0 = <&uart0_pins_a>; | 295 | pinctrl-0 = <&uart0_pins_a>; |
diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h index 9c99e817535e..5b85889f82ee 100644 --- a/arch/arm/include/asm/vdso.h +++ b/arch/arm/include/asm/vdso.h | |||
@@ -12,8 +12,6 @@ struct mm_struct; | |||
12 | 12 | ||
13 | void arm_install_vdso(struct mm_struct *mm, unsigned long addr); | 13 | void arm_install_vdso(struct mm_struct *mm, unsigned long addr); |
14 | 14 | ||
15 | extern char vdso_start, vdso_end; | ||
16 | |||
17 | extern unsigned int vdso_total_pages; | 15 | extern unsigned int vdso_total_pages; |
18 | 16 | ||
19 | #else /* CONFIG_VDSO */ | 17 | #else /* CONFIG_VDSO */ |
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index a4d6dc0f2427..f4dd7f9663c1 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c | |||
@@ -39,6 +39,8 @@ | |||
39 | 39 | ||
40 | static struct page **vdso_text_pagelist; | 40 | static struct page **vdso_text_pagelist; |
41 | 41 | ||
42 | extern char vdso_start[], vdso_end[]; | ||
43 | |||
42 | /* Total number of pages needed for the data and text portions of the VDSO. */ | 44 | /* Total number of pages needed for the data and text portions of the VDSO. */ |
43 | unsigned int vdso_total_pages __ro_after_init; | 45 | unsigned int vdso_total_pages __ro_after_init; |
44 | 46 | ||
@@ -197,13 +199,13 @@ static int __init vdso_init(void) | |||
197 | unsigned int text_pages; | 199 | unsigned int text_pages; |
198 | int i; | 200 | int i; |
199 | 201 | ||
200 | if (memcmp(&vdso_start, "\177ELF", 4)) { | 202 | if (memcmp(vdso_start, "\177ELF", 4)) { |
201 | pr_err("VDSO is not a valid ELF object!\n"); | 203 | pr_err("VDSO is not a valid ELF object!\n"); |
202 | return -ENOEXEC; | 204 | return -ENOEXEC; |
203 | } | 205 | } |
204 | 206 | ||
205 | text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; | 207 | text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; |
206 | pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start); | 208 | pr_debug("vdso: %i text pages at base %p\n", text_pages, vdso_start); |
207 | 209 | ||
208 | /* Allocate the VDSO text pagelist */ | 210 | /* Allocate the VDSO text pagelist */ |
209 | vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *), | 211 | vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *), |
@@ -218,7 +220,7 @@ static int __init vdso_init(void) | |||
218 | for (i = 0; i < text_pages; i++) { | 220 | for (i = 0; i < text_pages; i++) { |
219 | struct page *page; | 221 | struct page *page; |
220 | 222 | ||
221 | page = virt_to_page(&vdso_start + i * PAGE_SIZE); | 223 | page = virt_to_page(vdso_start + i * PAGE_SIZE); |
222 | vdso_text_pagelist[i] = page; | 224 | vdso_text_pagelist[i] = page; |
223 | } | 225 | } |
224 | 226 | ||
@@ -229,7 +231,7 @@ static int __init vdso_init(void) | |||
229 | 231 | ||
230 | cntvct_ok = cntvct_functional(); | 232 | cntvct_ok = cntvct_functional(); |
231 | 233 | ||
232 | patch_vdso(&vdso_start); | 234 | patch_vdso(vdso_start); |
233 | 235 | ||
234 | return 0; | 236 | return 0; |
235 | } | 237 | } |
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index a3e78074be70..62eb7d668890 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c | |||
@@ -127,8 +127,8 @@ static struct gpiod_lookup_table mmc_gpios_table = { | |||
127 | .dev_id = "da830-mmc.0", | 127 | .dev_id = "da830-mmc.0", |
128 | .table = { | 128 | .table = { |
129 | /* CD: gpio3_12: gpio60: chip 1 contains gpio range 32-63*/ | 129 | /* CD: gpio3_12: gpio60: chip 1 contains gpio range 32-63*/ |
130 | GPIO_LOOKUP("davinci_gpio.1", 28, "cd", GPIO_ACTIVE_LOW), | 130 | GPIO_LOOKUP("davinci_gpio.0", 28, "cd", GPIO_ACTIVE_LOW), |
131 | GPIO_LOOKUP("davinci_gpio.1", 29, "wp", GPIO_ACTIVE_LOW), | 131 | GPIO_LOOKUP("davinci_gpio.0", 29, "wp", GPIO_ACTIVE_LOW), |
132 | }, | 132 | }, |
133 | }; | 133 | }; |
134 | 134 | ||
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 7e5d7a083707..36cd23c8be9b 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -133,6 +133,9 @@ static void __init u8500_init_machine(void) | |||
133 | if (of_machine_is_compatible("st-ericsson,u8540")) | 133 | if (of_machine_is_compatible("st-ericsson,u8540")) |
134 | of_platform_populate(NULL, u8500_local_bus_nodes, | 134 | of_platform_populate(NULL, u8500_local_bus_nodes, |
135 | u8540_auxdata_lookup, NULL); | 135 | u8540_auxdata_lookup, NULL); |
136 | else | ||
137 | of_platform_populate(NULL, u8500_local_bus_nodes, | ||
138 | NULL, NULL); | ||
136 | } | 139 | } |
137 | 140 | ||
138 | static const char * stericsson_dt_platform_compat[] = { | 141 | static const char * stericsson_dt_platform_compat[] = { |
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index d443e481c3e9..8805a59bae53 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -888,11 +888,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev) | |||
888 | timer->irq = irq->start; | 888 | timer->irq = irq->start; |
889 | timer->pdev = pdev; | 889 | timer->pdev = pdev; |
890 | 890 | ||
891 | /* Skip pm_runtime_enable for OMAP1 */ | 891 | pm_runtime_enable(dev); |
892 | if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { | 892 | pm_runtime_irq_safe(dev); |
893 | pm_runtime_enable(dev); | ||
894 | pm_runtime_irq_safe(dev); | ||
895 | } | ||
896 | 893 | ||
897 | if (!timer->reserved) { | 894 | if (!timer->reserved) { |
898 | ret = pm_runtime_get_sync(dev); | 895 | ret = pm_runtime_get_sync(dev); |
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h index fb061cf0d736..30a07730807a 100644 --- a/arch/arm/plat-omap/include/plat/sram.h +++ b/arch/arm/plat-omap/include/plat/sram.h | |||
@@ -5,13 +5,4 @@ void omap_map_sram(unsigned long start, unsigned long size, | |||
5 | unsigned long skip, int cached); | 5 | unsigned long skip, int cached); |
6 | void omap_sram_reset(void); | 6 | void omap_sram_reset(void); |
7 | 7 | ||
8 | extern void *omap_sram_push_address(unsigned long size); | 8 | extern void *omap_sram_push(void *funcp, unsigned long size); |
9 | |||
10 | /* Macro to push a function to the internal SRAM, using the fncpy API */ | ||
11 | #define omap_sram_push(funcp, size) ({ \ | ||
12 | typeof(&(funcp)) _res = NULL; \ | ||
13 | void *_sram_address = omap_sram_push_address(size); \ | ||
14 | if (_sram_address) \ | ||
15 | _res = fncpy(_sram_address, &(funcp), size); \ | ||
16 | _res; \ | ||
17 | }) | ||
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index a5bc92d7e476..921840acf65c 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <asm/fncpy.h> | 23 | #include <asm/fncpy.h> |
24 | #include <asm/tlb.h> | 24 | #include <asm/tlb.h> |
25 | #include <asm/cacheflush.h> | 25 | #include <asm/cacheflush.h> |
26 | #include <asm/set_memory.h> | ||
26 | 27 | ||
27 | #include <asm/mach/map.h> | 28 | #include <asm/mach/map.h> |
28 | 29 | ||
@@ -42,7 +43,7 @@ static void __iomem *omap_sram_ceil; | |||
42 | * Note that fncpy requires the returned address to be aligned | 43 | * Note that fncpy requires the returned address to be aligned |
43 | * to an 8-byte boundary. | 44 | * to an 8-byte boundary. |
44 | */ | 45 | */ |
45 | void *omap_sram_push_address(unsigned long size) | 46 | static void *omap_sram_push_address(unsigned long size) |
46 | { | 47 | { |
47 | unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; | 48 | unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; |
48 | 49 | ||
@@ -60,6 +61,30 @@ void *omap_sram_push_address(unsigned long size) | |||
60 | return (void *)omap_sram_ceil; | 61 | return (void *)omap_sram_ceil; |
61 | } | 62 | } |
62 | 63 | ||
64 | void *omap_sram_push(void *funcp, unsigned long size) | ||
65 | { | ||
66 | void *sram; | ||
67 | unsigned long base; | ||
68 | int pages; | ||
69 | void *dst = NULL; | ||
70 | |||
71 | sram = omap_sram_push_address(size); | ||
72 | if (!sram) | ||
73 | return NULL; | ||
74 | |||
75 | base = (unsigned long)sram & PAGE_MASK; | ||
76 | pages = PAGE_ALIGN(size) / PAGE_SIZE; | ||
77 | |||
78 | set_memory_rw(base, pages); | ||
79 | |||
80 | dst = fncpy(sram, funcp, size); | ||
81 | |||
82 | set_memory_ro(base, pages); | ||
83 | set_memory_x(base, pages); | ||
84 | |||
85 | return dst; | ||
86 | } | ||
87 | |||
63 | /* | 88 | /* |
64 | * The SRAM context is lost during off-idle and stack | 89 | * The SRAM context is lost during off-idle and stack |
65 | * needs to be reset. | 90 | * needs to be reset. |
@@ -75,6 +100,9 @@ void omap_sram_reset(void) | |||
75 | void __init omap_map_sram(unsigned long start, unsigned long size, | 100 | void __init omap_map_sram(unsigned long start, unsigned long size, |
76 | unsigned long skip, int cached) | 101 | unsigned long skip, int cached) |
77 | { | 102 | { |
103 | unsigned long base; | ||
104 | int pages; | ||
105 | |||
78 | if (size == 0) | 106 | if (size == 0) |
79 | return; | 107 | return; |
80 | 108 | ||
@@ -95,4 +123,10 @@ void __init omap_map_sram(unsigned long start, unsigned long size, | |||
95 | */ | 123 | */ |
96 | memset_io(omap_sram_base + omap_sram_skip, 0, | 124 | memset_io(omap_sram_base + omap_sram_skip, 0, |
97 | omap_sram_size - omap_sram_skip); | 125 | omap_sram_size - omap_sram_skip); |
126 | |||
127 | base = (unsigned long)omap_sram_base; | ||
128 | pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE; | ||
129 | |||
130 | set_memory_ro(base, pages); | ||
131 | set_memory_x(base, pages); | ||
98 | } | 132 | } |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 03c6a3c72f9c..4c375e11ae95 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -648,7 +648,7 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, | |||
648 | */ | 648 | */ |
649 | static int vfp_dying_cpu(unsigned int cpu) | 649 | static int vfp_dying_cpu(unsigned int cpu) |
650 | { | 650 | { |
651 | vfp_force_reload(cpu, current_thread_info()); | 651 | vfp_current_hw_state[cpu] = NULL; |
652 | return 0; | 652 | return 0; |
653 | } | 653 | } |
654 | 654 | ||
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi index 03f195025390..204bdb9857b9 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | |||
@@ -406,8 +406,9 @@ | |||
406 | wlan_pd_n: wlan-pd-n { | 406 | wlan_pd_n: wlan-pd-n { |
407 | compatible = "regulator-fixed"; | 407 | compatible = "regulator-fixed"; |
408 | regulator-name = "wlan_pd_n"; | 408 | regulator-name = "wlan_pd_n"; |
409 | pinctrl-names = "default"; | ||
410 | pinctrl-0 = <&wlan_module_reset_l>; | ||
409 | 411 | ||
410 | /* Note the wlan_module_reset_l pinctrl */ | ||
411 | enable-active-high; | 412 | enable-active-high; |
412 | gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>; | 413 | gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>; |
413 | 414 | ||
@@ -983,12 +984,6 @@ ap_i2c_audio: &i2c8 { | |||
983 | pinctrl-0 = < | 984 | pinctrl-0 = < |
984 | &ap_pwroff /* AP will auto-assert this when in S3 */ | 985 | &ap_pwroff /* AP will auto-assert this when in S3 */ |
985 | &clk_32k /* This pin is always 32k on gru boards */ | 986 | &clk_32k /* This pin is always 32k on gru boards */ |
986 | |||
987 | /* | ||
988 | * We want this driven low ASAP; firmware should help us, but | ||
989 | * we can help ourselves too. | ||
990 | */ | ||
991 | &wlan_module_reset_l | ||
992 | >; | 987 | >; |
993 | 988 | ||
994 | pcfg_output_low: pcfg-output-low { | 989 | pcfg_output_low: pcfg-output-low { |
@@ -1168,12 +1163,7 @@ ap_i2c_audio: &i2c8 { | |||
1168 | }; | 1163 | }; |
1169 | 1164 | ||
1170 | wlan_module_reset_l: wlan-module-reset-l { | 1165 | wlan_module_reset_l: wlan-module-reset-l { |
1171 | /* | 1166 | rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_pull_none>; |
1172 | * We want this driven low ASAP (As {Soon,Strongly} As | ||
1173 | * Possible), to avoid leakage through the powered-down | ||
1174 | * WiFi. | ||
1175 | */ | ||
1176 | rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_output_low>; | ||
1177 | }; | 1167 | }; |
1178 | 1168 | ||
1179 | bt_host_wake_l: bt-host-wake-l { | 1169 | bt_host_wake_l: bt-host-wake-l { |
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 2605118d4b4c..0b81ca1d07e7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi | |||
@@ -411,8 +411,8 @@ | |||
411 | reg = <0x0 0xfe800000 0x0 0x100000>; | 411 | reg = <0x0 0xfe800000 0x0 0x100000>; |
412 | interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>; | 412 | interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>; |
413 | dr_mode = "otg"; | 413 | dr_mode = "otg"; |
414 | phys = <&u2phy0_otg>, <&tcphy0_usb3>; | 414 | phys = <&u2phy0_otg>; |
415 | phy-names = "usb2-phy", "usb3-phy"; | 415 | phy-names = "usb2-phy"; |
416 | phy_type = "utmi_wide"; | 416 | phy_type = "utmi_wide"; |
417 | snps,dis_enblslpm_quirk; | 417 | snps,dis_enblslpm_quirk; |
418 | snps,dis-u2-freeclk-exists-quirk; | 418 | snps,dis-u2-freeclk-exists-quirk; |
@@ -444,8 +444,8 @@ | |||
444 | reg = <0x0 0xfe900000 0x0 0x100000>; | 444 | reg = <0x0 0xfe900000 0x0 0x100000>; |
445 | interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>; | 445 | interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>; |
446 | dr_mode = "otg"; | 446 | dr_mode = "otg"; |
447 | phys = <&u2phy1_otg>, <&tcphy1_usb3>; | 447 | phys = <&u2phy1_otg>; |
448 | phy-names = "usb2-phy", "usb3-phy"; | 448 | phy-names = "usb2-phy"; |
449 | phy_type = "utmi_wide"; | 449 | phy_type = "utmi_wide"; |
450 | snps,dis_enblslpm_quirk; | 450 | snps,dis_enblslpm_quirk; |
451 | snps,dis-u2-freeclk-exists-quirk; | 451 | snps,dis-u2-freeclk-exists-quirk; |
diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 0abeb0e2d616..37671feb2bf6 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h | |||
@@ -87,6 +87,9 @@ typedef struct { | |||
87 | /* Number of bits in the mm_cpumask */ | 87 | /* Number of bits in the mm_cpumask */ |
88 | atomic_t active_cpus; | 88 | atomic_t active_cpus; |
89 | 89 | ||
90 | /* Number of users of the external (Nest) MMU */ | ||
91 | atomic_t copros; | ||
92 | |||
90 | /* NPU NMMU context */ | 93 | /* NPU NMMU context */ |
91 | struct npu_context *npu_context; | 94 | struct npu_context *npu_context; |
92 | 95 | ||
diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h index 8eea90f80e45..19b45ba6caf9 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h | |||
@@ -47,9 +47,6 @@ extern void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmad | |||
47 | #endif | 47 | #endif |
48 | extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); | 48 | extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); |
49 | extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr); | 49 | extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr); |
50 | extern void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa, | ||
51 | unsigned long page_size); | ||
52 | extern void radix__flush_tlb_lpid(unsigned long lpid); | ||
53 | extern void radix__flush_tlb_all(void); | 50 | extern void radix__flush_tlb_all(void); |
54 | extern void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm, | 51 | extern void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm, |
55 | unsigned long address); | 52 | unsigned long address); |
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index a2c5c95882cf..2e2bacbdf6ed 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
@@ -203,6 +203,7 @@ static inline void cpu_feature_keys_init(void) { } | |||
203 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) | 203 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) |
204 | #define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) | 204 | #define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) |
205 | #define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000) | 205 | #define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000) |
206 | #define CPU_FTR_P9_TLBIE_BUG LONG_ASM_CONST(0x2000000000000000) | ||
206 | #define CPU_FTR_POWER9_DD1 LONG_ASM_CONST(0x4000000000000000) | 207 | #define CPU_FTR_POWER9_DD1 LONG_ASM_CONST(0x4000000000000000) |
207 | #define CPU_FTR_POWER9_DD2_1 LONG_ASM_CONST(0x8000000000000000) | 208 | #define CPU_FTR_POWER9_DD2_1 LONG_ASM_CONST(0x8000000000000000) |
208 | 209 | ||
@@ -465,7 +466,7 @@ static inline void cpu_feature_keys_init(void) { } | |||
465 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | 466 | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
466 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ | 467 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ |
467 | CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | \ | 468 | CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | \ |
468 | CPU_FTR_PKEY) | 469 | CPU_FTR_PKEY | CPU_FTR_P9_TLBIE_BUG) |
469 | #define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \ | 470 | #define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \ |
470 | (~CPU_FTR_SAO)) | 471 | (~CPU_FTR_SAO)) |
471 | #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9 | 472 | #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9 |
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 051b3d63afe3..3a15b6db9501 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h | |||
@@ -92,15 +92,23 @@ static inline void dec_mm_active_cpus(struct mm_struct *mm) | |||
92 | static inline void mm_context_add_copro(struct mm_struct *mm) | 92 | static inline void mm_context_add_copro(struct mm_struct *mm) |
93 | { | 93 | { |
94 | /* | 94 | /* |
95 | * On hash, should only be called once over the lifetime of | 95 | * If any copro is in use, increment the active CPU count |
96 | * the context, as we can't decrement the active cpus count | 96 | * in order to force TLB invalidations to be global as to |
97 | * and flush properly for the time being. | 97 | * propagate to the Nest MMU. |
98 | */ | 98 | */ |
99 | inc_mm_active_cpus(mm); | 99 | if (atomic_inc_return(&mm->context.copros) == 1) |
100 | inc_mm_active_cpus(mm); | ||
100 | } | 101 | } |
101 | 102 | ||
102 | static inline void mm_context_remove_copro(struct mm_struct *mm) | 103 | static inline void mm_context_remove_copro(struct mm_struct *mm) |
103 | { | 104 | { |
105 | int c; | ||
106 | |||
107 | c = atomic_dec_if_positive(&mm->context.copros); | ||
108 | |||
109 | /* Detect imbalance between add and remove */ | ||
110 | WARN_ON(c < 0); | ||
111 | |||
104 | /* | 112 | /* |
105 | * Need to broadcast a global flush of the full mm before | 113 | * Need to broadcast a global flush of the full mm before |
106 | * decrementing active_cpus count, as the next TLBI may be | 114 | * decrementing active_cpus count, as the next TLBI may be |
@@ -111,7 +119,7 @@ static inline void mm_context_remove_copro(struct mm_struct *mm) | |||
111 | * for the time being. Invalidations will remain global if | 119 | * for the time being. Invalidations will remain global if |
112 | * used on hash. | 120 | * used on hash. |
113 | */ | 121 | */ |
114 | if (radix_enabled()) { | 122 | if (c == 0 && radix_enabled()) { |
115 | flush_all_mm(mm); | 123 | flush_all_mm(mm); |
116 | dec_mm_active_cpus(mm); | 124 | dec_mm_active_cpus(mm); |
117 | } | 125 | } |
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 945e2c29ad2d..8ca5d5b74618 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c | |||
@@ -709,6 +709,9 @@ static __init void cpufeatures_cpu_quirks(void) | |||
709 | cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD1; | 709 | cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD1; |
710 | else if ((version & 0xffffefff) == 0x004e0201) | 710 | else if ((version & 0xffffefff) == 0x004e0201) |
711 | cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1; | 711 | cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1; |
712 | |||
713 | if ((version & 0xffff0000) == 0x004e0000) | ||
714 | cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_BUG; | ||
712 | } | 715 | } |
713 | 716 | ||
714 | static void __init cpufeatures_setup_finished(void) | 717 | static void __init cpufeatures_setup_finished(void) |
@@ -720,6 +723,9 @@ static void __init cpufeatures_setup_finished(void) | |||
720 | cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE; | 723 | cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE; |
721 | } | 724 | } |
722 | 725 | ||
726 | /* Make sure powerpc_base_platform is non-NULL */ | ||
727 | powerpc_base_platform = cur_cpu_spec->platform; | ||
728 | |||
723 | system_registers.lpcr = mfspr(SPRN_LPCR); | 729 | system_registers.lpcr = mfspr(SPRN_LPCR); |
724 | system_registers.hfscr = mfspr(SPRN_HFSCR); | 730 | system_registers.hfscr = mfspr(SPRN_HFSCR); |
725 | system_registers.fscr = mfspr(SPRN_FSCR); | 731 | system_registers.fscr = mfspr(SPRN_FSCR); |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3ac87e53b3da..1ecfd8ffb098 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -706,7 +706,7 @@ EXC_COMMON_BEGIN(bad_addr_slb) | |||
706 | ld r3, PACA_EXSLB+EX_DAR(r13) | 706 | ld r3, PACA_EXSLB+EX_DAR(r13) |
707 | std r3, _DAR(r1) | 707 | std r3, _DAR(r1) |
708 | beq cr6, 2f | 708 | beq cr6, 2f |
709 | li r10, 0x480 /* fix trap number for I-SLB miss */ | 709 | li r10, 0x481 /* fix trap number for I-SLB miss */ |
710 | std r10, _TRAP(r1) | 710 | std r10, _TRAP(r1) |
711 | 2: bl save_nvgprs | 711 | 2: bl save_nvgprs |
712 | addi r3, r1, STACK_FRAME_OVERHEAD | 712 | addi r3, r1, STACK_FRAME_OVERHEAD |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index f88038847790..061aa0f47bb1 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -476,6 +476,14 @@ void force_external_irq_replay(void) | |||
476 | */ | 476 | */ |
477 | WARN_ON(!arch_irqs_disabled()); | 477 | WARN_ON(!arch_irqs_disabled()); |
478 | 478 | ||
479 | /* | ||
480 | * Interrupts must always be hard disabled before irq_happened is | ||
481 | * modified (to prevent lost update in case of interrupt between | ||
482 | * load and store). | ||
483 | */ | ||
484 | __hard_irq_disable(); | ||
485 | local_paca->irq_happened |= PACA_IRQ_HARD_DIS; | ||
486 | |||
479 | /* Indicate in the PACA that we have an interrupt to replay */ | 487 | /* Indicate in the PACA that we have an interrupt to replay */ |
480 | local_paca->irq_happened |= PACA_IRQ_EE; | 488 | local_paca->irq_happened |= PACA_IRQ_EE; |
481 | } | 489 | } |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index 5cb4e4687107..5d9bafe9a371 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c | |||
@@ -157,6 +157,9 @@ static void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr, | |||
157 | asm volatile("ptesync": : :"memory"); | 157 | asm volatile("ptesync": : :"memory"); |
158 | asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1) | 158 | asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1) |
159 | : : "r" (addr), "r" (kvm->arch.lpid) : "memory"); | 159 | : : "r" (addr), "r" (kvm->arch.lpid) : "memory"); |
160 | if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) | ||
161 | asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1) | ||
162 | : : "r" (addr), "r" (kvm->arch.lpid) : "memory"); | ||
160 | asm volatile("ptesync": : :"memory"); | 163 | asm volatile("ptesync": : :"memory"); |
161 | } | 164 | } |
162 | 165 | ||
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 8888e625a999..e1c083fbe434 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -473,6 +473,17 @@ static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues, | |||
473 | trace_tlbie(kvm->arch.lpid, 0, rbvalues[i], | 473 | trace_tlbie(kvm->arch.lpid, 0, rbvalues[i], |
474 | kvm->arch.lpid, 0, 0, 0); | 474 | kvm->arch.lpid, 0, 0, 0); |
475 | } | 475 | } |
476 | |||
477 | if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) { | ||
478 | /* | ||
479 | * Need the extra ptesync to make sure we don't | ||
480 | * re-order the tlbie | ||
481 | */ | ||
482 | asm volatile("ptesync": : :"memory"); | ||
483 | asm volatile(PPC_TLBIE_5(%0,%1,0,0,0) : : | ||
484 | "r" (rbvalues[0]), "r" (kvm->arch.lpid)); | ||
485 | } | ||
486 | |||
476 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); | 487 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); |
477 | kvm->arch.tlbie_lock = 0; | 488 | kvm->arch.tlbie_lock = 0; |
478 | } else { | 489 | } else { |
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index a0675e91ad7d..656933c85925 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -201,6 +201,15 @@ static inline unsigned long ___tlbie(unsigned long vpn, int psize, | |||
201 | return va; | 201 | return va; |
202 | } | 202 | } |
203 | 203 | ||
204 | static inline void fixup_tlbie(unsigned long vpn, int psize, int apsize, int ssize) | ||
205 | { | ||
206 | if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) { | ||
207 | /* Need the extra ptesync to ensure we don't reorder tlbie*/ | ||
208 | asm volatile("ptesync": : :"memory"); | ||
209 | ___tlbie(vpn, psize, apsize, ssize); | ||
210 | } | ||
211 | } | ||
212 | |||
204 | static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize) | 213 | static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize) |
205 | { | 214 | { |
206 | unsigned long rb; | 215 | unsigned long rb; |
@@ -278,6 +287,7 @@ static inline void tlbie(unsigned long vpn, int psize, int apsize, | |||
278 | asm volatile("ptesync": : :"memory"); | 287 | asm volatile("ptesync": : :"memory"); |
279 | } else { | 288 | } else { |
280 | __tlbie(vpn, psize, apsize, ssize); | 289 | __tlbie(vpn, psize, apsize, ssize); |
290 | fixup_tlbie(vpn, psize, apsize, ssize); | ||
281 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | 291 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); |
282 | } | 292 | } |
283 | if (lock_tlbie && !use_local) | 293 | if (lock_tlbie && !use_local) |
@@ -771,7 +781,7 @@ static void native_hpte_clear(void) | |||
771 | */ | 781 | */ |
772 | static void native_flush_hash_range(unsigned long number, int local) | 782 | static void native_flush_hash_range(unsigned long number, int local) |
773 | { | 783 | { |
774 | unsigned long vpn; | 784 | unsigned long vpn = 0; |
775 | unsigned long hash, index, hidx, shift, slot; | 785 | unsigned long hash, index, hidx, shift, slot; |
776 | struct hash_pte *hptep; | 786 | struct hash_pte *hptep; |
777 | unsigned long hpte_v; | 787 | unsigned long hpte_v; |
@@ -843,6 +853,10 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
843 | __tlbie(vpn, psize, psize, ssize); | 853 | __tlbie(vpn, psize, psize, ssize); |
844 | } pte_iterate_hashed_end(); | 854 | } pte_iterate_hashed_end(); |
845 | } | 855 | } |
856 | /* | ||
857 | * Just do one more with the last used values. | ||
858 | */ | ||
859 | fixup_tlbie(vpn, psize, psize, ssize); | ||
846 | asm volatile("eieio; tlbsync; ptesync":::"memory"); | 860 | asm volatile("eieio; tlbsync; ptesync":::"memory"); |
847 | 861 | ||
848 | if (lock_tlbie) | 862 | if (lock_tlbie) |
diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index 929d9ef7083f..3f980baade4c 100644 --- a/arch/powerpc/mm/mmu_context_book3s64.c +++ b/arch/powerpc/mm/mmu_context_book3s64.c | |||
@@ -173,6 +173,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) | |||
173 | mm_iommu_init(mm); | 173 | mm_iommu_init(mm); |
174 | #endif | 174 | #endif |
175 | atomic_set(&mm->context.active_cpus, 0); | 175 | atomic_set(&mm->context.active_cpus, 0); |
176 | atomic_set(&mm->context.copros, 0); | ||
176 | 177 | ||
177 | return 0; | 178 | return 0; |
178 | } | 179 | } |
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 28c980eb4422..adf469f312f2 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c | |||
@@ -481,6 +481,7 @@ void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0, | |||
481 | "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid)); | 481 | "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid)); |
482 | trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0); | 482 | trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0); |
483 | } | 483 | } |
484 | /* do we need fixup here ?*/ | ||
484 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); | 485 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); |
485 | } | 486 | } |
486 | EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry); | 487 | EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry); |
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c index 71d1b19ad1c0..a07f5372a4bf 100644 --- a/arch/powerpc/mm/tlb-radix.c +++ b/arch/powerpc/mm/tlb-radix.c | |||
@@ -119,6 +119,49 @@ static inline void __tlbie_pid(unsigned long pid, unsigned long ric) | |||
119 | trace_tlbie(0, 0, rb, rs, ric, prs, r); | 119 | trace_tlbie(0, 0, rb, rs, ric, prs, r); |
120 | } | 120 | } |
121 | 121 | ||
122 | static inline void __tlbiel_va(unsigned long va, unsigned long pid, | ||
123 | unsigned long ap, unsigned long ric) | ||
124 | { | ||
125 | unsigned long rb,rs,prs,r; | ||
126 | |||
127 | rb = va & ~(PPC_BITMASK(52, 63)); | ||
128 | rb |= ap << PPC_BITLSHIFT(58); | ||
129 | rs = pid << PPC_BITLSHIFT(31); | ||
130 | prs = 1; /* process scoped */ | ||
131 | r = 1; /* raidx format */ | ||
132 | |||
133 | asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) | ||
134 | : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); | ||
135 | trace_tlbie(0, 1, rb, rs, ric, prs, r); | ||
136 | } | ||
137 | |||
138 | static inline void __tlbie_va(unsigned long va, unsigned long pid, | ||
139 | unsigned long ap, unsigned long ric) | ||
140 | { | ||
141 | unsigned long rb,rs,prs,r; | ||
142 | |||
143 | rb = va & ~(PPC_BITMASK(52, 63)); | ||
144 | rb |= ap << PPC_BITLSHIFT(58); | ||
145 | rs = pid << PPC_BITLSHIFT(31); | ||
146 | prs = 1; /* process scoped */ | ||
147 | r = 1; /* raidx format */ | ||
148 | |||
149 | asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) | ||
150 | : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); | ||
151 | trace_tlbie(0, 0, rb, rs, ric, prs, r); | ||
152 | } | ||
153 | |||
154 | static inline void fixup_tlbie(void) | ||
155 | { | ||
156 | unsigned long pid = 0; | ||
157 | unsigned long va = ((1UL << 52) - 1); | ||
158 | |||
159 | if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) { | ||
160 | asm volatile("ptesync": : :"memory"); | ||
161 | __tlbie_va(va, pid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB); | ||
162 | } | ||
163 | } | ||
164 | |||
122 | /* | 165 | /* |
123 | * We use 128 set in radix mode and 256 set in hpt mode. | 166 | * We use 128 set in radix mode and 256 set in hpt mode. |
124 | */ | 167 | */ |
@@ -151,24 +194,25 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) | |||
151 | static inline void _tlbie_pid(unsigned long pid, unsigned long ric) | 194 | static inline void _tlbie_pid(unsigned long pid, unsigned long ric) |
152 | { | 195 | { |
153 | asm volatile("ptesync": : :"memory"); | 196 | asm volatile("ptesync": : :"memory"); |
154 | __tlbie_pid(pid, ric); | ||
155 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | ||
156 | } | ||
157 | 197 | ||
158 | static inline void __tlbiel_va(unsigned long va, unsigned long pid, | 198 | /* |
159 | unsigned long ap, unsigned long ric) | 199 | * Workaround the fact that the "ric" argument to __tlbie_pid |
160 | { | 200 | * must be a compile-time contraint to match the "i" constraint |
161 | unsigned long rb,rs,prs,r; | 201 | * in the asm statement. |
162 | 202 | */ | |
163 | rb = va & ~(PPC_BITMASK(52, 63)); | 203 | switch (ric) { |
164 | rb |= ap << PPC_BITLSHIFT(58); | 204 | case RIC_FLUSH_TLB: |
165 | rs = pid << PPC_BITLSHIFT(31); | 205 | __tlbie_pid(pid, RIC_FLUSH_TLB); |
166 | prs = 1; /* process scoped */ | 206 | break; |
167 | r = 1; /* raidx format */ | 207 | case RIC_FLUSH_PWC: |
168 | 208 | __tlbie_pid(pid, RIC_FLUSH_PWC); | |
169 | asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) | 209 | break; |
170 | : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); | 210 | case RIC_FLUSH_ALL: |
171 | trace_tlbie(0, 1, rb, rs, ric, prs, r); | 211 | default: |
212 | __tlbie_pid(pid, RIC_FLUSH_ALL); | ||
213 | } | ||
214 | fixup_tlbie(); | ||
215 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | ||
172 | } | 216 | } |
173 | 217 | ||
174 | static inline void __tlbiel_va_range(unsigned long start, unsigned long end, | 218 | static inline void __tlbiel_va_range(unsigned long start, unsigned long end, |
@@ -203,22 +247,6 @@ static inline void _tlbiel_va_range(unsigned long start, unsigned long end, | |||
203 | asm volatile("ptesync": : :"memory"); | 247 | asm volatile("ptesync": : :"memory"); |
204 | } | 248 | } |
205 | 249 | ||
206 | static inline void __tlbie_va(unsigned long va, unsigned long pid, | ||
207 | unsigned long ap, unsigned long ric) | ||
208 | { | ||
209 | unsigned long rb,rs,prs,r; | ||
210 | |||
211 | rb = va & ~(PPC_BITMASK(52, 63)); | ||
212 | rb |= ap << PPC_BITLSHIFT(58); | ||
213 | rs = pid << PPC_BITLSHIFT(31); | ||
214 | prs = 1; /* process scoped */ | ||
215 | r = 1; /* raidx format */ | ||
216 | |||
217 | asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) | ||
218 | : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); | ||
219 | trace_tlbie(0, 0, rb, rs, ric, prs, r); | ||
220 | } | ||
221 | |||
222 | static inline void __tlbie_va_range(unsigned long start, unsigned long end, | 250 | static inline void __tlbie_va_range(unsigned long start, unsigned long end, |
223 | unsigned long pid, unsigned long page_size, | 251 | unsigned long pid, unsigned long page_size, |
224 | unsigned long psize) | 252 | unsigned long psize) |
@@ -237,6 +265,7 @@ static inline void _tlbie_va(unsigned long va, unsigned long pid, | |||
237 | 265 | ||
238 | asm volatile("ptesync": : :"memory"); | 266 | asm volatile("ptesync": : :"memory"); |
239 | __tlbie_va(va, pid, ap, ric); | 267 | __tlbie_va(va, pid, ap, ric); |
268 | fixup_tlbie(); | ||
240 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | 269 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); |
241 | } | 270 | } |
242 | 271 | ||
@@ -248,6 +277,7 @@ static inline void _tlbie_va_range(unsigned long start, unsigned long end, | |||
248 | if (also_pwc) | 277 | if (also_pwc) |
249 | __tlbie_pid(pid, RIC_FLUSH_PWC); | 278 | __tlbie_pid(pid, RIC_FLUSH_PWC); |
250 | __tlbie_va_range(start, end, pid, page_size, psize); | 279 | __tlbie_va_range(start, end, pid, page_size, psize); |
280 | fixup_tlbie(); | ||
251 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | 281 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); |
252 | } | 282 | } |
253 | 283 | ||
@@ -311,6 +341,16 @@ void radix__local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmadd | |||
311 | } | 341 | } |
312 | EXPORT_SYMBOL(radix__local_flush_tlb_page); | 342 | EXPORT_SYMBOL(radix__local_flush_tlb_page); |
313 | 343 | ||
344 | static bool mm_needs_flush_escalation(struct mm_struct *mm) | ||
345 | { | ||
346 | /* | ||
347 | * P9 nest MMU has issues with the page walk cache | ||
348 | * caching PTEs and not flushing them properly when | ||
349 | * RIC = 0 for a PID/LPID invalidate | ||
350 | */ | ||
351 | return atomic_read(&mm->context.copros) != 0; | ||
352 | } | ||
353 | |||
314 | #ifdef CONFIG_SMP | 354 | #ifdef CONFIG_SMP |
315 | void radix__flush_tlb_mm(struct mm_struct *mm) | 355 | void radix__flush_tlb_mm(struct mm_struct *mm) |
316 | { | 356 | { |
@@ -321,9 +361,12 @@ void radix__flush_tlb_mm(struct mm_struct *mm) | |||
321 | return; | 361 | return; |
322 | 362 | ||
323 | preempt_disable(); | 363 | preempt_disable(); |
324 | if (!mm_is_thread_local(mm)) | 364 | if (!mm_is_thread_local(mm)) { |
325 | _tlbie_pid(pid, RIC_FLUSH_TLB); | 365 | if (mm_needs_flush_escalation(mm)) |
326 | else | 366 | _tlbie_pid(pid, RIC_FLUSH_ALL); |
367 | else | ||
368 | _tlbie_pid(pid, RIC_FLUSH_TLB); | ||
369 | } else | ||
327 | _tlbiel_pid(pid, RIC_FLUSH_TLB); | 370 | _tlbiel_pid(pid, RIC_FLUSH_TLB); |
328 | preempt_enable(); | 371 | preempt_enable(); |
329 | } | 372 | } |
@@ -435,10 +478,14 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
435 | } | 478 | } |
436 | 479 | ||
437 | if (full) { | 480 | if (full) { |
438 | if (local) | 481 | if (local) { |
439 | _tlbiel_pid(pid, RIC_FLUSH_TLB); | 482 | _tlbiel_pid(pid, RIC_FLUSH_TLB); |
440 | else | 483 | } else { |
441 | _tlbie_pid(pid, RIC_FLUSH_TLB); | 484 | if (mm_needs_flush_escalation(mm)) |
485 | _tlbie_pid(pid, RIC_FLUSH_ALL); | ||
486 | else | ||
487 | _tlbie_pid(pid, RIC_FLUSH_TLB); | ||
488 | } | ||
442 | } else { | 489 | } else { |
443 | bool hflush = false; | 490 | bool hflush = false; |
444 | unsigned long hstart, hend; | 491 | unsigned long hstart, hend; |
@@ -465,6 +512,7 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
465 | if (hflush) | 512 | if (hflush) |
466 | __tlbie_va_range(hstart, hend, pid, | 513 | __tlbie_va_range(hstart, hend, pid, |
467 | HPAGE_PMD_SIZE, MMU_PAGE_2M); | 514 | HPAGE_PMD_SIZE, MMU_PAGE_2M); |
515 | fixup_tlbie(); | ||
468 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | 516 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); |
469 | } | 517 | } |
470 | } | 518 | } |
@@ -548,6 +596,9 @@ static inline void __radix__flush_tlb_range_psize(struct mm_struct *mm, | |||
548 | } | 596 | } |
549 | 597 | ||
550 | if (full) { | 598 | if (full) { |
599 | if (!local && mm_needs_flush_escalation(mm)) | ||
600 | also_pwc = true; | ||
601 | |||
551 | if (local) | 602 | if (local) |
552 | _tlbiel_pid(pid, also_pwc ? RIC_FLUSH_ALL : RIC_FLUSH_TLB); | 603 | _tlbiel_pid(pid, also_pwc ? RIC_FLUSH_ALL : RIC_FLUSH_TLB); |
553 | else | 604 | else |
@@ -603,46 +654,6 @@ void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr) | |||
603 | } | 654 | } |
604 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 655 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
605 | 656 | ||
606 | void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa, | ||
607 | unsigned long page_size) | ||
608 | { | ||
609 | unsigned long rb,rs,prs,r; | ||
610 | unsigned long ap; | ||
611 | unsigned long ric = RIC_FLUSH_TLB; | ||
612 | |||
613 | ap = mmu_get_ap(radix_get_mmu_psize(page_size)); | ||
614 | rb = gpa & ~(PPC_BITMASK(52, 63)); | ||
615 | rb |= ap << PPC_BITLSHIFT(58); | ||
616 | rs = lpid & ((1UL << 32) - 1); | ||
617 | prs = 0; /* process scoped */ | ||
618 | r = 1; /* raidx format */ | ||
619 | |||
620 | asm volatile("ptesync": : :"memory"); | ||
621 | asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) | ||
622 | : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); | ||
623 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | ||
624 | trace_tlbie(lpid, 0, rb, rs, ric, prs, r); | ||
625 | } | ||
626 | EXPORT_SYMBOL(radix__flush_tlb_lpid_va); | ||
627 | |||
628 | void radix__flush_tlb_lpid(unsigned long lpid) | ||
629 | { | ||
630 | unsigned long rb,rs,prs,r; | ||
631 | unsigned long ric = RIC_FLUSH_ALL; | ||
632 | |||
633 | rb = 0x2 << PPC_BITLSHIFT(53); /* IS = 2 */ | ||
634 | rs = lpid & ((1UL << 32) - 1); | ||
635 | prs = 0; /* partition scoped */ | ||
636 | r = 1; /* raidx format */ | ||
637 | |||
638 | asm volatile("ptesync": : :"memory"); | ||
639 | asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) | ||
640 | : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); | ||
641 | asm volatile("eieio; tlbsync; ptesync": : :"memory"); | ||
642 | trace_tlbie(lpid, 0, rb, rs, ric, prs, r); | ||
643 | } | ||
644 | EXPORT_SYMBOL(radix__flush_tlb_lpid); | ||
645 | |||
646 | void radix__flush_pmd_tlb_range(struct vm_area_struct *vma, | 657 | void radix__flush_pmd_tlb_range(struct vm_area_struct *vma, |
647 | unsigned long start, unsigned long end) | 658 | unsigned long start, unsigned long end) |
648 | { | 659 | { |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index dd9464920456..ef22b275d050 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -474,6 +474,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
474 | shost->dma_boundary = 0xffffffff; | 474 | shost->dma_boundary = 0xffffffff; |
475 | 475 | ||
476 | shost->use_blk_mq = scsi_use_blk_mq; | 476 | shost->use_blk_mq = scsi_use_blk_mq; |
477 | shost->use_blk_mq = scsi_use_blk_mq || shost->hostt->force_blk_mq; | ||
477 | 478 | ||
478 | device_initialize(&shost->shost_gendev); | 479 | device_initialize(&shost->shost_gendev); |
479 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); | 480 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 5293e6827ce5..3a9eca163db8 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -1045,11 +1045,7 @@ static void set_performant_mode(struct ctlr_info *h, struct CommandList *c, | |||
1045 | c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); | 1045 | c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); |
1046 | if (unlikely(!h->msix_vectors)) | 1046 | if (unlikely(!h->msix_vectors)) |
1047 | return; | 1047 | return; |
1048 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1048 | c->Header.ReplyQueue = reply_queue; |
1049 | c->Header.ReplyQueue = | ||
1050 | raw_smp_processor_id() % h->nreply_queues; | ||
1051 | else | ||
1052 | c->Header.ReplyQueue = reply_queue % h->nreply_queues; | ||
1053 | } | 1049 | } |
1054 | } | 1050 | } |
1055 | 1051 | ||
@@ -1063,10 +1059,7 @@ static void set_ioaccel1_performant_mode(struct ctlr_info *h, | |||
1063 | * Tell the controller to post the reply to the queue for this | 1059 | * Tell the controller to post the reply to the queue for this |
1064 | * processor. This seems to give the best I/O throughput. | 1060 | * processor. This seems to give the best I/O throughput. |
1065 | */ | 1061 | */ |
1066 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1062 | cp->ReplyQueue = reply_queue; |
1067 | cp->ReplyQueue = smp_processor_id() % h->nreply_queues; | ||
1068 | else | ||
1069 | cp->ReplyQueue = reply_queue % h->nreply_queues; | ||
1070 | /* | 1063 | /* |
1071 | * Set the bits in the address sent down to include: | 1064 | * Set the bits in the address sent down to include: |
1072 | * - performant mode bit (bit 0) | 1065 | * - performant mode bit (bit 0) |
@@ -1087,10 +1080,7 @@ static void set_ioaccel2_tmf_performant_mode(struct ctlr_info *h, | |||
1087 | /* Tell the controller to post the reply to the queue for this | 1080 | /* Tell the controller to post the reply to the queue for this |
1088 | * processor. This seems to give the best I/O throughput. | 1081 | * processor. This seems to give the best I/O throughput. |
1089 | */ | 1082 | */ |
1090 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1083 | cp->reply_queue = reply_queue; |
1091 | cp->reply_queue = smp_processor_id() % h->nreply_queues; | ||
1092 | else | ||
1093 | cp->reply_queue = reply_queue % h->nreply_queues; | ||
1094 | /* Set the bits in the address sent down to include: | 1084 | /* Set the bits in the address sent down to include: |
1095 | * - performant mode bit not used in ioaccel mode 2 | 1085 | * - performant mode bit not used in ioaccel mode 2 |
1096 | * - pull count (bits 0-3) | 1086 | * - pull count (bits 0-3) |
@@ -1109,10 +1099,7 @@ static void set_ioaccel2_performant_mode(struct ctlr_info *h, | |||
1109 | * Tell the controller to post the reply to the queue for this | 1099 | * Tell the controller to post the reply to the queue for this |
1110 | * processor. This seems to give the best I/O throughput. | 1100 | * processor. This seems to give the best I/O throughput. |
1111 | */ | 1101 | */ |
1112 | if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) | 1102 | cp->reply_queue = reply_queue; |
1113 | cp->reply_queue = smp_processor_id() % h->nreply_queues; | ||
1114 | else | ||
1115 | cp->reply_queue = reply_queue % h->nreply_queues; | ||
1116 | /* | 1103 | /* |
1117 | * Set the bits in the address sent down to include: | 1104 | * Set the bits in the address sent down to include: |
1118 | * - performant mode bit not used in ioaccel mode 2 | 1105 | * - performant mode bit not used in ioaccel mode 2 |
@@ -1157,6 +1144,8 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h, | |||
1157 | { | 1144 | { |
1158 | dial_down_lockup_detection_during_fw_flash(h, c); | 1145 | dial_down_lockup_detection_during_fw_flash(h, c); |
1159 | atomic_inc(&h->commands_outstanding); | 1146 | atomic_inc(&h->commands_outstanding); |
1147 | |||
1148 | reply_queue = h->reply_map[raw_smp_processor_id()]; | ||
1160 | switch (c->cmd_type) { | 1149 | switch (c->cmd_type) { |
1161 | case CMD_IOACCEL1: | 1150 | case CMD_IOACCEL1: |
1162 | set_ioaccel1_performant_mode(h, c, reply_queue); | 1151 | set_ioaccel1_performant_mode(h, c, reply_queue); |
@@ -7376,6 +7365,26 @@ static void hpsa_disable_interrupt_mode(struct ctlr_info *h) | |||
7376 | h->msix_vectors = 0; | 7365 | h->msix_vectors = 0; |
7377 | } | 7366 | } |
7378 | 7367 | ||
7368 | static void hpsa_setup_reply_map(struct ctlr_info *h) | ||
7369 | { | ||
7370 | const struct cpumask *mask; | ||
7371 | unsigned int queue, cpu; | ||
7372 | |||
7373 | for (queue = 0; queue < h->msix_vectors; queue++) { | ||
7374 | mask = pci_irq_get_affinity(h->pdev, queue); | ||
7375 | if (!mask) | ||
7376 | goto fallback; | ||
7377 | |||
7378 | for_each_cpu(cpu, mask) | ||
7379 | h->reply_map[cpu] = queue; | ||
7380 | } | ||
7381 | return; | ||
7382 | |||
7383 | fallback: | ||
7384 | for_each_possible_cpu(cpu) | ||
7385 | h->reply_map[cpu] = 0; | ||
7386 | } | ||
7387 | |||
7379 | /* If MSI/MSI-X is supported by the kernel we will try to enable it on | 7388 | /* If MSI/MSI-X is supported by the kernel we will try to enable it on |
7380 | * controllers that are capable. If not, we use legacy INTx mode. | 7389 | * controllers that are capable. If not, we use legacy INTx mode. |
7381 | */ | 7390 | */ |
@@ -7771,6 +7780,10 @@ static int hpsa_pci_init(struct ctlr_info *h) | |||
7771 | err = hpsa_interrupt_mode(h); | 7780 | err = hpsa_interrupt_mode(h); |
7772 | if (err) | 7781 | if (err) |
7773 | goto clean1; | 7782 | goto clean1; |
7783 | |||
7784 | /* setup mapping between CPU and reply queue */ | ||
7785 | hpsa_setup_reply_map(h); | ||
7786 | |||
7774 | err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr); | 7787 | err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr); |
7775 | if (err) | 7788 | if (err) |
7776 | goto clean2; /* intmode+region, pci */ | 7789 | goto clean2; /* intmode+region, pci */ |
@@ -8480,6 +8493,28 @@ static struct workqueue_struct *hpsa_create_controller_wq(struct ctlr_info *h, | |||
8480 | return wq; | 8493 | return wq; |
8481 | } | 8494 | } |
8482 | 8495 | ||
8496 | static void hpda_free_ctlr_info(struct ctlr_info *h) | ||
8497 | { | ||
8498 | kfree(h->reply_map); | ||
8499 | kfree(h); | ||
8500 | } | ||
8501 | |||
8502 | static struct ctlr_info *hpda_alloc_ctlr_info(void) | ||
8503 | { | ||
8504 | struct ctlr_info *h; | ||
8505 | |||
8506 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
8507 | if (!h) | ||
8508 | return NULL; | ||
8509 | |||
8510 | h->reply_map = kzalloc(sizeof(*h->reply_map) * nr_cpu_ids, GFP_KERNEL); | ||
8511 | if (!h->reply_map) { | ||
8512 | kfree(h); | ||
8513 | return NULL; | ||
8514 | } | ||
8515 | return h; | ||
8516 | } | ||
8517 | |||
8483 | static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 8518 | static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
8484 | { | 8519 | { |
8485 | int dac, rc; | 8520 | int dac, rc; |
@@ -8517,7 +8552,7 @@ reinit_after_soft_reset: | |||
8517 | * the driver. See comments in hpsa.h for more info. | 8552 | * the driver. See comments in hpsa.h for more info. |
8518 | */ | 8553 | */ |
8519 | BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT); | 8554 | BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT); |
8520 | h = kzalloc(sizeof(*h), GFP_KERNEL); | 8555 | h = hpda_alloc_ctlr_info(); |
8521 | if (!h) { | 8556 | if (!h) { |
8522 | dev_err(&pdev->dev, "Failed to allocate controller head\n"); | 8557 | dev_err(&pdev->dev, "Failed to allocate controller head\n"); |
8523 | return -ENOMEM; | 8558 | return -ENOMEM; |
@@ -8916,7 +8951,7 @@ static void hpsa_remove_one(struct pci_dev *pdev) | |||
8916 | h->lockup_detected = NULL; /* init_one 2 */ | 8951 | h->lockup_detected = NULL; /* init_one 2 */ |
8917 | /* (void) pci_disable_pcie_error_reporting(pdev); */ /* init_one 1 */ | 8952 | /* (void) pci_disable_pcie_error_reporting(pdev); */ /* init_one 1 */ |
8918 | 8953 | ||
8919 | kfree(h); /* init_one 1 */ | 8954 | hpda_free_ctlr_info(h); /* init_one 1 */ |
8920 | } | 8955 | } |
8921 | 8956 | ||
8922 | static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev, | 8957 | static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev, |
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index 018f980a701c..fb9f5e7f8209 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h | |||
@@ -158,6 +158,7 @@ struct bmic_controller_parameters { | |||
158 | #pragma pack() | 158 | #pragma pack() |
159 | 159 | ||
160 | struct ctlr_info { | 160 | struct ctlr_info { |
161 | unsigned int *reply_map; | ||
161 | int ctlr; | 162 | int ctlr; |
162 | char devname[8]; | 163 | char devname[8]; |
163 | char *product_name; | 164 | char *product_name; |
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index b1b1d3a3b173..daefe8172b04 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -3579,11 +3579,9 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt) | |||
3579 | static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad, | 3579 | static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad, |
3580 | struct ibmvfc_target *tgt) | 3580 | struct ibmvfc_target *tgt) |
3581 | { | 3581 | { |
3582 | if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name, | 3582 | if (wwn_to_u64((u8 *)&mad->fc_iu.response[2]) != tgt->ids.port_name) |
3583 | sizeof(tgt->ids.port_name))) | ||
3584 | return 1; | 3583 | return 1; |
3585 | if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name, | 3584 | if (wwn_to_u64((u8 *)&mad->fc_iu.response[4]) != tgt->ids.node_name) |
3586 | sizeof(tgt->ids.node_name))) | ||
3587 | return 1; | 3585 | return 1; |
3588 | if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id) | 3586 | if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id) |
3589 | return 1; | 3587 | return 1; |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 6198559abbd8..dd66c11399a2 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/kfifo.h> | 37 | #include <linux/kfifo.h> |
38 | #include <linux/scatterlist.h> | 38 | #include <linux/scatterlist.h> |
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/backing-dev.h> | ||
40 | #include <net/tcp.h> | 41 | #include <net/tcp.h> |
41 | #include <scsi/scsi_cmnd.h> | 42 | #include <scsi/scsi_cmnd.h> |
42 | #include <scsi/scsi_device.h> | 43 | #include <scsi/scsi_device.h> |
@@ -954,6 +955,13 @@ static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev) | |||
954 | 955 | ||
955 | static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) | 956 | static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) |
956 | { | 957 | { |
958 | struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host); | ||
959 | struct iscsi_session *session = tcp_sw_host->session; | ||
960 | struct iscsi_conn *conn = session->leadconn; | ||
961 | |||
962 | if (conn->datadgst_en) | ||
963 | sdev->request_queue->backing_dev_info->capabilities | ||
964 | |= BDI_CAP_STABLE_WRITES; | ||
957 | blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); | 965 | blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); |
958 | blk_queue_dma_alignment(sdev->request_queue, 0); | 966 | blk_queue_dma_alignment(sdev->request_queue, 0); |
959 | return 0; | 967 | return 0; |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ba6503f37756..27fab8235ea5 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -2128,6 +2128,7 @@ enum MR_PD_TYPE { | |||
2128 | 2128 | ||
2129 | struct megasas_instance { | 2129 | struct megasas_instance { |
2130 | 2130 | ||
2131 | unsigned int *reply_map; | ||
2131 | __le32 *producer; | 2132 | __le32 *producer; |
2132 | dma_addr_t producer_h; | 2133 | dma_addr_t producer_h; |
2133 | __le32 *consumer; | 2134 | __le32 *consumer; |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index a71ee67df084..dde0798b8a91 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -5165,6 +5165,26 @@ skip_alloc: | |||
5165 | instance->use_seqnum_jbod_fp = false; | 5165 | instance->use_seqnum_jbod_fp = false; |
5166 | } | 5166 | } |
5167 | 5167 | ||
5168 | static void megasas_setup_reply_map(struct megasas_instance *instance) | ||
5169 | { | ||
5170 | const struct cpumask *mask; | ||
5171 | unsigned int queue, cpu; | ||
5172 | |||
5173 | for (queue = 0; queue < instance->msix_vectors; queue++) { | ||
5174 | mask = pci_irq_get_affinity(instance->pdev, queue); | ||
5175 | if (!mask) | ||
5176 | goto fallback; | ||
5177 | |||
5178 | for_each_cpu(cpu, mask) | ||
5179 | instance->reply_map[cpu] = queue; | ||
5180 | } | ||
5181 | return; | ||
5182 | |||
5183 | fallback: | ||
5184 | for_each_possible_cpu(cpu) | ||
5185 | instance->reply_map[cpu] = cpu % instance->msix_vectors; | ||
5186 | } | ||
5187 | |||
5168 | /** | 5188 | /** |
5169 | * megasas_init_fw - Initializes the FW | 5189 | * megasas_init_fw - Initializes the FW |
5170 | * @instance: Adapter soft state | 5190 | * @instance: Adapter soft state |
@@ -5343,6 +5363,8 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
5343 | goto fail_setup_irqs; | 5363 | goto fail_setup_irqs; |
5344 | } | 5364 | } |
5345 | 5365 | ||
5366 | megasas_setup_reply_map(instance); | ||
5367 | |||
5346 | dev_info(&instance->pdev->dev, | 5368 | dev_info(&instance->pdev->dev, |
5347 | "firmware supports msix\t: (%d)", fw_msix_count); | 5369 | "firmware supports msix\t: (%d)", fw_msix_count); |
5348 | dev_info(&instance->pdev->dev, | 5370 | dev_info(&instance->pdev->dev, |
@@ -6123,20 +6145,29 @@ static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance) | |||
6123 | */ | 6145 | */ |
6124 | static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) | 6146 | static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) |
6125 | { | 6147 | { |
6148 | instance->reply_map = kzalloc(sizeof(unsigned int) * nr_cpu_ids, | ||
6149 | GFP_KERNEL); | ||
6150 | if (!instance->reply_map) | ||
6151 | return -ENOMEM; | ||
6152 | |||
6126 | switch (instance->adapter_type) { | 6153 | switch (instance->adapter_type) { |
6127 | case MFI_SERIES: | 6154 | case MFI_SERIES: |
6128 | if (megasas_alloc_mfi_ctrl_mem(instance)) | 6155 | if (megasas_alloc_mfi_ctrl_mem(instance)) |
6129 | return -ENOMEM; | 6156 | goto fail; |
6130 | break; | 6157 | break; |
6131 | case VENTURA_SERIES: | 6158 | case VENTURA_SERIES: |
6132 | case THUNDERBOLT_SERIES: | 6159 | case THUNDERBOLT_SERIES: |
6133 | case INVADER_SERIES: | 6160 | case INVADER_SERIES: |
6134 | if (megasas_alloc_fusion_context(instance)) | 6161 | if (megasas_alloc_fusion_context(instance)) |
6135 | return -ENOMEM; | 6162 | goto fail; |
6136 | break; | 6163 | break; |
6137 | } | 6164 | } |
6138 | 6165 | ||
6139 | return 0; | 6166 | return 0; |
6167 | fail: | ||
6168 | kfree(instance->reply_map); | ||
6169 | instance->reply_map = NULL; | ||
6170 | return -ENOMEM; | ||
6140 | } | 6171 | } |
6141 | 6172 | ||
6142 | /* | 6173 | /* |
@@ -6148,6 +6179,7 @@ static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) | |||
6148 | */ | 6179 | */ |
6149 | static inline void megasas_free_ctrl_mem(struct megasas_instance *instance) | 6180 | static inline void megasas_free_ctrl_mem(struct megasas_instance *instance) |
6150 | { | 6181 | { |
6182 | kfree(instance->reply_map); | ||
6151 | if (instance->adapter_type == MFI_SERIES) { | 6183 | if (instance->adapter_type == MFI_SERIES) { |
6152 | if (instance->producer) | 6184 | if (instance->producer) |
6153 | pci_free_consistent(instance->pdev, sizeof(u32), | 6185 | pci_free_consistent(instance->pdev, sizeof(u32), |
@@ -6540,7 +6572,6 @@ fail_io_attach: | |||
6540 | pci_free_irq_vectors(instance->pdev); | 6572 | pci_free_irq_vectors(instance->pdev); |
6541 | fail_init_mfi: | 6573 | fail_init_mfi: |
6542 | scsi_host_put(host); | 6574 | scsi_host_put(host); |
6543 | |||
6544 | fail_alloc_instance: | 6575 | fail_alloc_instance: |
6545 | pci_disable_device(pdev); | 6576 | pci_disable_device(pdev); |
6546 | 6577 | ||
@@ -6746,6 +6777,8 @@ megasas_resume(struct pci_dev *pdev) | |||
6746 | if (rval < 0) | 6777 | if (rval < 0) |
6747 | goto fail_reenable_msix; | 6778 | goto fail_reenable_msix; |
6748 | 6779 | ||
6780 | megasas_setup_reply_map(instance); | ||
6781 | |||
6749 | if (instance->adapter_type != MFI_SERIES) { | 6782 | if (instance->adapter_type != MFI_SERIES) { |
6750 | megasas_reset_reply_desc(instance); | 6783 | megasas_reset_reply_desc(instance); |
6751 | if (megasas_ioc_init_fusion(instance)) { | 6784 | if (megasas_ioc_init_fusion(instance)) { |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index dc8e850fbfd2..5ec3b74e8aed 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
@@ -2641,11 +2641,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, | |||
2641 | fp_possible = (io_info.fpOkForIo > 0) ? true : false; | 2641 | fp_possible = (io_info.fpOkForIo > 0) ? true : false; |
2642 | } | 2642 | } |
2643 | 2643 | ||
2644 | /* Use raw_smp_processor_id() for now until cmd->request->cpu is CPU | 2644 | cmd->request_desc->SCSIIO.MSIxIndex = |
2645 | id by default, not CPU group id, otherwise all MSI-X queues won't | 2645 | instance->reply_map[raw_smp_processor_id()]; |
2646 | be utilized */ | ||
2647 | cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ? | ||
2648 | raw_smp_processor_id() % instance->msix_vectors : 0; | ||
2649 | 2646 | ||
2650 | praid_context = &io_request->RaidContext; | 2647 | praid_context = &io_request->RaidContext; |
2651 | 2648 | ||
@@ -2971,10 +2968,9 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, | |||
2971 | } | 2968 | } |
2972 | 2969 | ||
2973 | cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle; | 2970 | cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle; |
2974 | cmd->request_desc->SCSIIO.MSIxIndex = | ||
2975 | instance->msix_vectors ? | ||
2976 | (raw_smp_processor_id() % instance->msix_vectors) : 0; | ||
2977 | 2971 | ||
2972 | cmd->request_desc->SCSIIO.MSIxIndex = | ||
2973 | instance->reply_map[raw_smp_processor_id()]; | ||
2978 | 2974 | ||
2979 | if (!fp_possible) { | 2975 | if (!fp_possible) { |
2980 | /* system pd firmware path */ | 2976 | /* system pd firmware path */ |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3541caf3fceb..1fa84d6a0f8b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -2484,6 +2484,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) | |||
2484 | sector_size = old_sector_size; | 2484 | sector_size = old_sector_size; |
2485 | goto got_data; | 2485 | goto got_data; |
2486 | } | 2486 | } |
2487 | /* Remember that READ CAPACITY(16) succeeded */ | ||
2488 | sdp->try_rc_10_first = 0; | ||
2487 | } | 2489 | } |
2488 | } | 2490 | } |
2489 | 2491 | ||
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 7c28e8d4955a..45d04631888a 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -91,9 +91,6 @@ struct virtio_scsi_vq { | |||
91 | struct virtio_scsi_target_state { | 91 | struct virtio_scsi_target_state { |
92 | seqcount_t tgt_seq; | 92 | seqcount_t tgt_seq; |
93 | 93 | ||
94 | /* Count of outstanding requests. */ | ||
95 | atomic_t reqs; | ||
96 | |||
97 | /* Currently active virtqueue for requests sent to this target. */ | 94 | /* Currently active virtqueue for requests sent to this target. */ |
98 | struct virtio_scsi_vq *req_vq; | 95 | struct virtio_scsi_vq *req_vq; |
99 | }; | 96 | }; |
@@ -152,8 +149,6 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf) | |||
152 | struct virtio_scsi_cmd *cmd = buf; | 149 | struct virtio_scsi_cmd *cmd = buf; |
153 | struct scsi_cmnd *sc = cmd->sc; | 150 | struct scsi_cmnd *sc = cmd->sc; |
154 | struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd; | 151 | struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd; |
155 | struct virtio_scsi_target_state *tgt = | ||
156 | scsi_target(sc->device)->hostdata; | ||
157 | 152 | ||
158 | dev_dbg(&sc->device->sdev_gendev, | 153 | dev_dbg(&sc->device->sdev_gendev, |
159 | "cmd %p response %u status %#02x sense_len %u\n", | 154 | "cmd %p response %u status %#02x sense_len %u\n", |
@@ -210,8 +205,6 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf) | |||
210 | } | 205 | } |
211 | 206 | ||
212 | sc->scsi_done(sc); | 207 | sc->scsi_done(sc); |
213 | |||
214 | atomic_dec(&tgt->reqs); | ||
215 | } | 208 | } |
216 | 209 | ||
217 | static void virtscsi_vq_done(struct virtio_scsi *vscsi, | 210 | static void virtscsi_vq_done(struct virtio_scsi *vscsi, |
@@ -529,11 +522,20 @@ static void virtio_scsi_init_hdr_pi(struct virtio_device *vdev, | |||
529 | } | 522 | } |
530 | #endif | 523 | #endif |
531 | 524 | ||
532 | static int virtscsi_queuecommand(struct virtio_scsi *vscsi, | 525 | static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi, |
533 | struct virtio_scsi_vq *req_vq, | 526 | struct scsi_cmnd *sc) |
527 | { | ||
528 | u32 tag = blk_mq_unique_tag(sc->request); | ||
529 | u16 hwq = blk_mq_unique_tag_to_hwq(tag); | ||
530 | |||
531 | return &vscsi->req_vqs[hwq]; | ||
532 | } | ||
533 | |||
534 | static int virtscsi_queuecommand(struct Scsi_Host *shost, | ||
534 | struct scsi_cmnd *sc) | 535 | struct scsi_cmnd *sc) |
535 | { | 536 | { |
536 | struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev); | 537 | struct virtio_scsi *vscsi = shost_priv(shost); |
538 | struct virtio_scsi_vq *req_vq = virtscsi_pick_vq_mq(vscsi, sc); | ||
537 | struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc); | 539 | struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc); |
538 | unsigned long flags; | 540 | unsigned long flags; |
539 | int req_size; | 541 | int req_size; |
@@ -576,79 +578,6 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi, | |||
576 | return 0; | 578 | return 0; |
577 | } | 579 | } |
578 | 580 | ||
579 | static int virtscsi_queuecommand_single(struct Scsi_Host *sh, | ||
580 | struct scsi_cmnd *sc) | ||
581 | { | ||
582 | struct virtio_scsi *vscsi = shost_priv(sh); | ||
583 | struct virtio_scsi_target_state *tgt = | ||
584 | scsi_target(sc->device)->hostdata; | ||
585 | |||
586 | atomic_inc(&tgt->reqs); | ||
587 | return virtscsi_queuecommand(vscsi, &vscsi->req_vqs[0], sc); | ||
588 | } | ||
589 | |||
590 | static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi, | ||
591 | struct scsi_cmnd *sc) | ||
592 | { | ||
593 | u32 tag = blk_mq_unique_tag(sc->request); | ||
594 | u16 hwq = blk_mq_unique_tag_to_hwq(tag); | ||
595 | |||
596 | return &vscsi->req_vqs[hwq]; | ||
597 | } | ||
598 | |||
599 | static struct virtio_scsi_vq *virtscsi_pick_vq(struct virtio_scsi *vscsi, | ||
600 | struct virtio_scsi_target_state *tgt) | ||
601 | { | ||
602 | struct virtio_scsi_vq *vq; | ||
603 | unsigned long flags; | ||
604 | u32 queue_num; | ||
605 | |||
606 | local_irq_save(flags); | ||
607 | if (atomic_inc_return(&tgt->reqs) > 1) { | ||
608 | unsigned long seq; | ||
609 | |||
610 | do { | ||
611 | seq = read_seqcount_begin(&tgt->tgt_seq); | ||
612 | vq = tgt->req_vq; | ||
613 | } while (read_seqcount_retry(&tgt->tgt_seq, seq)); | ||
614 | } else { | ||
615 | /* no writes can be concurrent because of atomic_t */ | ||
616 | write_seqcount_begin(&tgt->tgt_seq); | ||
617 | |||
618 | /* keep previous req_vq if a reader just arrived */ | ||
619 | if (unlikely(atomic_read(&tgt->reqs) > 1)) { | ||
620 | vq = tgt->req_vq; | ||
621 | goto unlock; | ||
622 | } | ||
623 | |||
624 | queue_num = smp_processor_id(); | ||
625 | while (unlikely(queue_num >= vscsi->num_queues)) | ||
626 | queue_num -= vscsi->num_queues; | ||
627 | tgt->req_vq = vq = &vscsi->req_vqs[queue_num]; | ||
628 | unlock: | ||
629 | write_seqcount_end(&tgt->tgt_seq); | ||
630 | } | ||
631 | local_irq_restore(flags); | ||
632 | |||
633 | return vq; | ||
634 | } | ||
635 | |||
636 | static int virtscsi_queuecommand_multi(struct Scsi_Host *sh, | ||
637 | struct scsi_cmnd *sc) | ||
638 | { | ||
639 | struct virtio_scsi *vscsi = shost_priv(sh); | ||
640 | struct virtio_scsi_target_state *tgt = | ||
641 | scsi_target(sc->device)->hostdata; | ||
642 | struct virtio_scsi_vq *req_vq; | ||
643 | |||
644 | if (shost_use_blk_mq(sh)) | ||
645 | req_vq = virtscsi_pick_vq_mq(vscsi, sc); | ||
646 | else | ||
647 | req_vq = virtscsi_pick_vq(vscsi, tgt); | ||
648 | |||
649 | return virtscsi_queuecommand(vscsi, req_vq, sc); | ||
650 | } | ||
651 | |||
652 | static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) | 581 | static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) |
653 | { | 582 | { |
654 | DECLARE_COMPLETION_ONSTACK(comp); | 583 | DECLARE_COMPLETION_ONSTACK(comp); |
@@ -775,7 +704,6 @@ static int virtscsi_target_alloc(struct scsi_target *starget) | |||
775 | return -ENOMEM; | 704 | return -ENOMEM; |
776 | 705 | ||
777 | seqcount_init(&tgt->tgt_seq); | 706 | seqcount_init(&tgt->tgt_seq); |
778 | atomic_set(&tgt->reqs, 0); | ||
779 | tgt->req_vq = &vscsi->req_vqs[0]; | 707 | tgt->req_vq = &vscsi->req_vqs[0]; |
780 | 708 | ||
781 | starget->hostdata = tgt; | 709 | starget->hostdata = tgt; |
@@ -805,33 +733,13 @@ static enum blk_eh_timer_return virtscsi_eh_timed_out(struct scsi_cmnd *scmnd) | |||
805 | return BLK_EH_RESET_TIMER; | 733 | return BLK_EH_RESET_TIMER; |
806 | } | 734 | } |
807 | 735 | ||
808 | static struct scsi_host_template virtscsi_host_template_single = { | 736 | static struct scsi_host_template virtscsi_host_template = { |
809 | .module = THIS_MODULE, | ||
810 | .name = "Virtio SCSI HBA", | ||
811 | .proc_name = "virtio_scsi", | ||
812 | .this_id = -1, | ||
813 | .cmd_size = sizeof(struct virtio_scsi_cmd), | ||
814 | .queuecommand = virtscsi_queuecommand_single, | ||
815 | .change_queue_depth = virtscsi_change_queue_depth, | ||
816 | .eh_abort_handler = virtscsi_abort, | ||
817 | .eh_device_reset_handler = virtscsi_device_reset, | ||
818 | .eh_timed_out = virtscsi_eh_timed_out, | ||
819 | .slave_alloc = virtscsi_device_alloc, | ||
820 | |||
821 | .dma_boundary = UINT_MAX, | ||
822 | .use_clustering = ENABLE_CLUSTERING, | ||
823 | .target_alloc = virtscsi_target_alloc, | ||
824 | .target_destroy = virtscsi_target_destroy, | ||
825 | .track_queue_depth = 1, | ||
826 | }; | ||
827 | |||
828 | static struct scsi_host_template virtscsi_host_template_multi = { | ||
829 | .module = THIS_MODULE, | 737 | .module = THIS_MODULE, |
830 | .name = "Virtio SCSI HBA", | 738 | .name = "Virtio SCSI HBA", |
831 | .proc_name = "virtio_scsi", | 739 | .proc_name = "virtio_scsi", |
832 | .this_id = -1, | 740 | .this_id = -1, |
833 | .cmd_size = sizeof(struct virtio_scsi_cmd), | 741 | .cmd_size = sizeof(struct virtio_scsi_cmd), |
834 | .queuecommand = virtscsi_queuecommand_multi, | 742 | .queuecommand = virtscsi_queuecommand, |
835 | .change_queue_depth = virtscsi_change_queue_depth, | 743 | .change_queue_depth = virtscsi_change_queue_depth, |
836 | .eh_abort_handler = virtscsi_abort, | 744 | .eh_abort_handler = virtscsi_abort, |
837 | .eh_device_reset_handler = virtscsi_device_reset, | 745 | .eh_device_reset_handler = virtscsi_device_reset, |
@@ -844,6 +752,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { | |||
844 | .target_destroy = virtscsi_target_destroy, | 752 | .target_destroy = virtscsi_target_destroy, |
845 | .map_queues = virtscsi_map_queues, | 753 | .map_queues = virtscsi_map_queues, |
846 | .track_queue_depth = 1, | 754 | .track_queue_depth = 1, |
755 | .force_blk_mq = 1, | ||
847 | }; | 756 | }; |
848 | 757 | ||
849 | #define virtscsi_config_get(vdev, fld) \ | 758 | #define virtscsi_config_get(vdev, fld) \ |
@@ -936,7 +845,6 @@ static int virtscsi_probe(struct virtio_device *vdev) | |||
936 | u32 sg_elems, num_targets; | 845 | u32 sg_elems, num_targets; |
937 | u32 cmd_per_lun; | 846 | u32 cmd_per_lun; |
938 | u32 num_queues; | 847 | u32 num_queues; |
939 | struct scsi_host_template *hostt; | ||
940 | 848 | ||
941 | if (!vdev->config->get) { | 849 | if (!vdev->config->get) { |
942 | dev_err(&vdev->dev, "%s failure: config access disabled\n", | 850 | dev_err(&vdev->dev, "%s failure: config access disabled\n", |
@@ -949,12 +857,7 @@ static int virtscsi_probe(struct virtio_device *vdev) | |||
949 | 857 | ||
950 | num_targets = virtscsi_config_get(vdev, max_target) + 1; | 858 | num_targets = virtscsi_config_get(vdev, max_target) + 1; |
951 | 859 | ||
952 | if (num_queues == 1) | 860 | shost = scsi_host_alloc(&virtscsi_host_template, |
953 | hostt = &virtscsi_host_template_single; | ||
954 | else | ||
955 | hostt = &virtscsi_host_template_multi; | ||
956 | |||
957 | shost = scsi_host_alloc(hostt, | ||
958 | sizeof(*vscsi) + sizeof(vscsi->req_vqs[0]) * num_queues); | 861 | sizeof(*vscsi) + sizeof(vscsi->req_vqs[0]) * num_queues); |
959 | if (!shost) | 862 | if (!shost) |
960 | return -ENOMEM; | 863 | return -ENOMEM; |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index a8b7bf879ced..9c1e4bad6581 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -452,6 +452,9 @@ struct scsi_host_template { | |||
452 | /* True if the controller does not support WRITE SAME */ | 452 | /* True if the controller does not support WRITE SAME */ |
453 | unsigned no_write_same:1; | 453 | unsigned no_write_same:1; |
454 | 454 | ||
455 | /* True if the low-level driver supports blk-mq only */ | ||
456 | unsigned force_blk_mq:1; | ||
457 | |||
455 | /* | 458 | /* |
456 | * Countdown for host blocking with no commands outstanding. | 459 | * Countdown for host blocking with no commands outstanding. |
457 | */ | 460 | */ |