Merge tag 'ASB-2024-12-05_11-5.4' of https://android.googlesource.com/kernel/common into android13-5.4-lahaina

https://source.android.com/docs/security/bulletin/2024-12-01

* tag 'ASB-2024-12-05_11-5.4' of https://android.googlesource.com/kernel/common: (552 commits)
  UPSTREAM: net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
  ANDROID: add file for recording allowed ABI breaks
  Revert "spi: Fix deadlock when adding SPI controllers on SPI buses"
  Revert "spi: fix use-after-free of the add_lock mutex"
  ANDROID: declare sp_in_global outside of CONFIG_FRAME_POINTER
  BACKPORT: RISC-V: Stop relying on GCC's register allocator's hueristics
  UPSTREAM: x86/percpu: Clean up percpu_add_op()
  UPSTREAM: x86/percpu: Clean up percpu_from_op()
  UPSTREAM: x86/percpu: Clean up percpu_to_op()
  UPSTREAM: x86/percpu: Introduce size abstraction macros
  BACKPORT: FROMGIT: binder: add delivered_freeze to debugfs output
  BACKPORT: FROMGIT: binder: fix memleak of proc->delivered_freeze
  FROMGIT: binder: allow freeze notification for dead nodes
  FROMGIT: binder: fix BINDER_WORK_CLEAR_FREEZE_NOTIFICATION debug logs
  FROMGIT: binder: fix BINDER_WORK_FROZEN_BINDER debug logs
  BACKPORT: FROMGIT: binder: fix freeze UAF in binder_release_work()
  FROMGIT: binder: fix OOB in binder_add_freeze_work()
  FROMGIT: binder: fix node UAF in binder_add_freeze_work()
  Linux 5.4.286
  mm: avoid leaving partial pfn mappings around in error case
  ...

 Conflicts:
	arch/arm64/boot/dts/vendor/bindings/gpu/samsung-rotator.txt
	arch/arm64/boot/dts/vendor/bindings/gpu/samsung-rotator.yaml
	drivers/clk/qcom/clk-rpmh.c
	drivers/usb/dwc3/core.c
	fs/erofs/decompressor.c
	net/qrtr/qrtr.c

Change-Id: Iae3a7502b304d7be66da795411c4f330eef8b693
This commit is contained in:
Michael Bestas 2024-12-16 01:08:23 +02:00
commit 0262d4e51f
No known key found for this signature in database
GPG key ID: CC95044519BE6669
480 changed files with 4407 additions and 2292 deletions

1
.gitignore vendored
View file

@ -120,7 +120,6 @@ GTAGS
# id-utils files # id-utils files
ID ID
*.orig
*~ *~
\#*# \#*#

View file

@ -518,7 +518,7 @@ at module load time (for a module) with::
[dbg_probe=1] [dbg_probe=1]
The addresses are normal I2C addresses. The adapter is the string The addresses are normal I2C addresses. The adapter is the string
name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name. name of the adapter, as shown in /sys/bus/i2c/devices/i2c-<n>/name.
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
spaces, so if the name is "This is an I2C chip" you can say spaces, so if the name is "This is an I2C chip" you can say
adapter_name=ThisisanI2cchip. This is because it's hard to pass in adapter_name=ThisisanI2cchip. This is because it's hard to pass in

View file

@ -3827,6 +3827,16 @@
printk.time= Show timing data prefixed to each printk message line printk.time= Show timing data prefixed to each printk message line
Format: <bool> (1/Y/y=enable, 0/N/n=disable) Format: <bool> (1/Y/y=enable, 0/N/n=disable)
proc_mem.force_override= [KNL]
Format: {always | ptrace | never}
Traditionally /proc/pid/mem allows memory permissions to be
overridden without restrictions. This option may be set to
restrict that. Can be one of:
- 'always': traditional behavior always allows mem overrides.
- 'ptrace': only allow mem overrides for active ptracers.
- 'never': never allow mem overrides.
If not specified, default is the CONFIG_PROC_MEM_* choice.
processor.max_cstate= [HW,ACPI] processor.max_cstate= [HW,ACPI]
Limit processor to maximum C-state Limit processor to maximum C-state
max_cstate=9 overrides any DMI blacklist limit. max_cstate=9 overrides any DMI blacklist limit.

View file

@ -98,6 +98,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
@ -124,6 +126,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |

View file

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 284 SUBLEVEL = 286
EXTRAVERSION = EXTRAVERSION =
NAME = Kleptomaniac Octopus NAME = Kleptomaniac Octopus

View file

@ -0,0 +1,98 @@
# How to use this file: http://go/approve-abi-break
# ABI freeze commit: ae37e86392ba5e33dc178c5ca16096029a2a3fe1
11 function symbol(s) removed
'struct phy_device* of_phy_find_device(struct device_node*)'
'int reset_control_status(struct reset_control*)'
'void rproc_add_carveout(struct rproc*, struct rproc_mem_entry*)'
'void* rproc_da_to_va(struct rproc*, u64, int)'
'struct resource_table* rproc_elf_find_loaded_rsc_table(struct rproc*, const struct firmware*)'
'int rproc_elf_load_rsc_table(struct rproc*, const struct firmware*)'
'int rproc_elf_load_segments(struct rproc*, const struct firmware*)'
'int rproc_elf_sanity_check(struct rproc*, const struct firmware*)'
'struct rproc_mem_entry* rproc_mem_entry_init(struct device*, void*, dma_addr_t, int, u32, int(*)(struct rproc*, struct rproc_mem_entry*), int(*)(struct rproc*, struct rproc_mem_entry*), const char*, ...)'
'struct rproc_mem_entry* rproc_of_resm_mem_entry_init(struct device*, u32, int, u32, const char*, ...)'
'irqreturn_t rproc_vq_interrupt(struct rproc*, int)'
type 'struct elevator_mq_ops' changed
member changed from 'bool(* bio_merge)(struct blk_mq_hw_ctx*, struct bio*, unsigned int)' to 'bool(* bio_merge)(struct request_queue*, struct bio*, unsigned int)'
type changed from 'bool(*)(struct blk_mq_hw_ctx*, struct bio*, unsigned int)' to 'bool(*)(struct request_queue*, struct bio*, unsigned int)'
pointed-to type changed from 'bool(struct blk_mq_hw_ctx*, struct bio*, unsigned int)' to 'bool(struct request_queue*, struct bio*, unsigned int)'
parameter 1 type changed from 'struct blk_mq_hw_ctx*' to 'struct request_queue*'
pointed-to type changed from 'struct blk_mq_hw_ctx' to 'struct request_queue'
type 'struct usbnet' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { struct { u32 rx_speed; u32 tx_speed; }; struct { u64 android_kabi_reserved1; }; union { }; }' was added
type 'struct inet_connection_sock' changed
member changed from 'struct { int enabled; int search_high; int search_low; int probe_size; u32 probe_timestamp; } icsk_mtup' to 'struct { int search_high; int search_low; int enabled; int probe_size; u32 probe_timestamp; } icsk_mtup'
type changed from 'struct { int enabled; int search_high; int search_low; int probe_size; u32 probe_timestamp; }' to 'struct { int search_high; int search_low; int enabled; int probe_size; u32 probe_timestamp; }'
byte size changed from 20 to 16
2 members ('int search_high' .. 'int search_low') changed
offset changed by -32
member 'int probe_size' changed
offset changed by -95
member 'u32 probe_timestamp' changed
offset changed by -32
member 'u32 icsk_probes_tstamp' was added
type 'struct usbnet' changed
member changed from 'union { struct { u32 rx_speed; u32 tx_speed; }; struct { u64 android_kabi_reserved1; } __UNIQUE_ID_android_kabi_hide213; union { }; }' to 'union { struct { u32 rx_speed; u32 tx_speed; }; struct { u64 android_kabi_reserved1; }; union { }; }'
type changed from 'union { struct { u32 rx_speed; u32 tx_speed; }; struct { u64 android_kabi_reserved1; } __UNIQUE_ID_android_kabi_hide213; union { }; }' to 'union { struct { u32 rx_speed; u32 tx_speed; }; struct { u64 android_kabi_reserved1; }; union { }; }'
member 'struct { u64 android_kabi_reserved1; } __UNIQUE_ID_android_kabi_hide213' was removed
member 'struct { u64 android_kabi_reserved1; }' was added
type 'struct sock' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { spinlock_t sk_peer_lock; struct { u64 android_kabi_reserved1; }; union { }; }' was added
type 'struct fib_rules_ops' changed
member changed from 'bool(* suppress)(struct fib_rule*, struct fib_lookup_arg*)' to 'bool(* suppress)(struct fib_rule*, int, struct fib_lookup_arg*)'
type changed from 'bool(*)(struct fib_rule*, struct fib_lookup_arg*)' to 'bool(*)(struct fib_rule*, int, struct fib_lookup_arg*)'
pointed-to type changed from 'bool(struct fib_rule*, struct fib_lookup_arg*)' to 'bool(struct fib_rule*, int, struct fib_lookup_arg*)'
parameter 2 type changed from 'struct fib_lookup_arg*' to 'int'
parameter 3 of type 'struct fib_lookup_arg*' was added
type 'struct snd_pcm_runtime' changed
byte size changed from 760 to 800
member 'struct mutex buffer_mutex' was added
member 'atomic_t buffer_accessing' was added
type 'struct snd_pcm_runtime' changed
byte size changed from 792 to 800
member 'atomic_t buffer_accessing' was added
function symbol changed from 'int hex_to_bin(char)' to 'int hex_to_bin(unsigned char)'
type changed from 'int(char)' to 'int(unsigned char)'
parameter 1 type changed from 'char' to 'unsigned char'
type 'struct tcp_sock' changed
member 'u8 unused' was removed
member 'u8 fastopen_client_fail' was added
member 'u32 max_packets_seq' was removed
member 'u32 cwnd_usage_seq' was added
type 'struct sk_buff' changed
member 'u64 android_kabi_reserved1' was removed
member 'union { struct { __u8 scm_io_uring; __u8 android_kabi_reserved1_padding1; __u16 android_kabi_reserved1_padding2; __u32 android_kabi_reserved1_padding3; }; struct { u64 android_kabi_reserved1; }; union { }; }' was added
type 'struct anon_vma' changed
byte size changed from 88 to 104
member 'unsigned long int num_children' was added
member 'unsigned long int num_active_vmas' was added
function symbol changed from 'struct irq_domain* __irq_domain_add(struct fwnode_handle*, int, irq_hw_number_t, int, const struct irq_domain_ops*, void*)' to 'struct irq_domain* __irq_domain_add(struct fwnode_handle*, unsigned int, irq_hw_number_t, int, const struct irq_domain_ops*, void*)'
type changed from 'struct irq_domain*(struct fwnode_handle*, int, irq_hw_number_t, int, const struct irq_domain_ops*, void*)' to 'struct irq_domain*(struct fwnode_handle*, unsigned int, irq_hw_number_t, int, const struct irq_domain_ops*, void*)'
parameter 2 type changed from 'int' to 'unsigned int'
type 'struct perf_event' changed
member 'unsigned int group_generation' was added
type 'struct usb_role_switch' changed
member 'bool registered' was added
type 'struct tcp_sock' changed
member 'u8 unused' was removed
member 'u8 fastopen_client_fail' was added

View file

@ -77,7 +77,7 @@
}; };
&hdmi { &hdmi {
hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>;
power-domains = <&power RPI_POWER_DOMAIN_HDMI>; power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
status = "okay"; status = "okay";
}; };

View file

@ -350,7 +350,7 @@
&iomuxc_lpsr { &iomuxc_lpsr {
pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp { pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp {
fsl,phy = < fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08 MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08
>; >;
}; };

View file

@ -300,8 +300,8 @@
&i2c2 { &i2c2 {
status = "okay"; status = "okay";
rt5616: rt5616@1b { rt5616: audio-codec@1b {
compatible = "rt5616"; compatible = "realtek,rt5616";
reg = <0x1b>; reg = <0x1b>;
clocks = <&cru SCLK_I2S_OUT>; clocks = <&cru SCLK_I2S_OUT>;
clock-names = "mclk"; clock-names = "mclk";

View file

@ -317,12 +317,13 @@
}; };
}; };
acodec: acodec-ana@20030000 { acodec: audio-codec@20030000 {
compatible = "rk3036-codec"; compatible = "rockchip,rk3036-codec";
reg = <0x20030000 0x4000>; reg = <0x20030000 0x4000>;
rockchip,grf = <&grf>;
clock-names = "acodec_pclk"; clock-names = "acodec_pclk";
clocks = <&cru PCLK_ACODEC>; clocks = <&cru PCLK_ACODEC>;
rockchip,grf = <&grf>;
#sound-dai-cells = <0>;
status = "disabled"; status = "disabled";
}; };
@ -332,7 +333,6 @@
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_HDMI>; clocks = <&cru PCLK_HDMI>;
clock-names = "pclk"; clock-names = "pclk";
rockchip,grf = <&grf>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&hdmi_ctl>; pinctrl-0 = <&hdmi_ctl>;
status = "disabled"; status = "disabled";
@ -489,11 +489,11 @@
}; };
spi: spi@20074000 { spi: spi@20074000 {
compatible = "rockchip,rockchip-spi"; compatible = "rockchip,rk3036-spi";
reg = <0x20074000 0x1000>; reg = <0x20074000 0x1000>;
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_SPI>, <&cru SCLK_SPI>; clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>;
clock-names = "apb-pclk","spi_pclk"; clock-names = "spiclk", "apb_pclk";
dmas = <&pdma 8>, <&pdma 9>; dmas = <&pdma 8>, <&pdma 9>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
pinctrl-names = "default"; pinctrl-names = "default";

View file

@ -66,6 +66,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
return; return;
} }
map = syscon_node_to_regmap(np); map = syscon_node_to_regmap(np);
of_node_put(np);
if (IS_ERR(map)) { if (IS_ERR(map)) {
pr_err("PLATSMP: No syscon regmap\n"); pr_err("PLATSMP: No syscon regmap\n");
return; return;

View file

@ -626,6 +626,7 @@ config ARM64_ERRATUM_3194386
* ARM Cortex-A78C erratum 3324346 * ARM Cortex-A78C erratum 3324346
* ARM Cortex-A78C erratum 3324347 * ARM Cortex-A78C erratum 3324347
* ARM Cortex-A710 erratam 3324338 * ARM Cortex-A710 erratam 3324338
* ARM Cortex-A715 errartum 3456084
* ARM Cortex-A720 erratum 3456091 * ARM Cortex-A720 erratum 3456091
* ARM Cortex-A725 erratum 3456106 * ARM Cortex-A725 erratum 3456106
* ARM Cortex-X1 erratum 3324344 * ARM Cortex-X1 erratum 3324344
@ -636,6 +637,7 @@ config ARM64_ERRATUM_3194386
* ARM Cortex-X925 erratum 3324334 * ARM Cortex-X925 erratum 3324334
* ARM Neoverse-N1 erratum 3324349 * ARM Neoverse-N1 erratum 3324349
* ARM Neoverse N2 erratum 3324339 * ARM Neoverse N2 erratum 3324339
* ARM Neoverse-N3 erratum 3456111
* ARM Neoverse-V1 erratum 3324341 * ARM Neoverse-V1 erratum 3324341
* ARM Neoverse V2 erratum 3324336 * ARM Neoverse V2 erratum 3324336
* ARM Neoverse-V3 erratum 3312417 * ARM Neoverse-V3 erratum 3312417

View file

@ -667,8 +667,7 @@
compatible = "rockchip,rk3328-dw-hdmi"; compatible = "rockchip,rk3328-dw-hdmi";
reg = <0x0 0xff3c0000 0x0 0x20000>; reg = <0x0 0xff3c0000 0x0 0x20000>;
reg-io-width = <4>; reg-io-width = <4>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>, interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
<GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_HDMI>, clocks = <&cru PCLK_HDMI>,
<&cru SCLK_HDMI_SFC>, <&cru SCLK_HDMI_SFC>,
<&cru SCLK_RTC32K>; <&cru SCLK_RTC32K>;

View file

@ -56,7 +56,6 @@
fan: fan@18 { fan: fan@18 {
compatible = "ti,amc6821"; compatible = "ti,amc6821";
reg = <0x18>; reg = <0x18>;
#cooling-cells = <2>;
}; };
rtc_twi: rtc@6f { rtc_twi: rtc@6f {

View file

@ -148,6 +148,22 @@
drive-impedance-ohm = <33>; drive-impedance-ohm = <33>;
}; };
&gpio3 {
/*
* The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module
* eMMC and SPI flash powered-down initially (in fact it keeps the
* reset signal asserted). BIOS_DISABLE_OVERRIDE pin allows to override
* that signal so that eMMC and SPI can be used regardless of the state
* of the signal.
*/
bios-disable-override-hog {
gpios = <RK_PD5 GPIO_ACTIVE_LOW>;
gpio-hog;
line-name = "bios_disable_override";
output-high;
};
};
&gmac { &gmac {
assigned-clocks = <&cru SCLK_RMII_SRC>; assigned-clocks = <&cru SCLK_RMII_SRC>;
assigned-clock-parents = <&clkin_gmac>; assigned-clock-parents = <&clkin_gmac>;
@ -432,9 +448,14 @@
&pinctrl { &pinctrl {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&q7_thermal_pin>; pinctrl-0 = <&q7_thermal_pin &bios_disable_override_hog_pin>;
gpios { gpios {
bios_disable_override_hog_pin: bios-disable-override-hog-pin {
rockchip,pins =
<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
};
q7_thermal_pin: q7-thermal-pin { q7_thermal_pin: q7-thermal-pin {
rockchip,pins = rockchip,pins =
<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;

View file

@ -557,7 +557,7 @@
bluetooth { bluetooth {
compatible = "brcm,bcm43438-bt"; compatible = "brcm,bcm43438-bt";
clocks = <&rk808 1>; clocks = <&rk808 1>;
clock-names = "ext_clock"; clock-names = "txco";
device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;

View file

@ -159,7 +159,7 @@
status = "okay"; status = "okay";
rt5651: rt5651@1a { rt5651: rt5651@1a {
compatible = "rockchip,rt5651"; compatible = "realtek,rt5651";
reg = <0x1a>; reg = <0x1a>;
clocks = <&cru SCLK_I2S_8CH_OUT>; clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = "mclk"; clock-names = "mclk";

View file

@ -1,28 +0,0 @@
* Samsung Image Rotator
Required properties:
- compatible : value should be one of the following:
* "samsung,s5pv210-rotator" for Rotator IP in S5PV210
* "samsung,exynos4210-rotator" for Rotator IP in Exynos4210
* "samsung,exynos4212-rotator" for Rotator IP in Exynos4212/4412
* "samsung,exynos5250-rotator" for Rotator IP in Exynos5250
- reg : Physical base address of the IP registers and length of memory
mapped region.
- interrupts : Interrupt specifier for rotator interrupt, according to format
specific to interrupt parent.
- clocks : Clock specifier for rotator clock, according to generic clock
bindings. (See Documentation/devicetree/bindings/clock/exynos*.txt)
- clock-names : Names of clocks. For exynos rotator, it should be "rotator".
Example:
rotator@12810000 {
compatible = "samsung,exynos4210-rotator";
reg = <0x12810000 0x1000>;
interrupts = <0 83 0>;
clocks = <&clock 278>;
clock-names = "rotator";
};

View file

@ -0,0 +1,48 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpu/samsung-rotator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung SoC Image Rotator
maintainers:
- Inki Dae <inki.dae@samsung.com>
properties:
compatible:
enum:
- "samsung,s5pv210-rotator"
- "samsung,exynos4210-rotator"
- "samsung,exynos4212-rotator"
- "samsung,exynos5250-rotator"
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
clock-names:
items:
- const: rotator
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
examples:
- |
rotator@12810000 {
compatible = "samsung,exynos4210-rotator";
reg = <0x12810000 0x1000>;
interrupts = <0 83 0>;
clocks = <&clock 278>;
clock-names = "rotator";
};

View file

@ -317,6 +317,7 @@ CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_SERIAL_8250_EXAR is not set # CONFIG_SERIAL_8250_EXAR is not set
CONFIG_SERIAL_8250_RUNTIME_UARTS=0 CONFIG_SERIAL_8250_RUNTIME_UARTS=0
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y

View file

@ -78,6 +78,7 @@
#define ARM_CPU_PART_CORTEX_A78 0xD41 #define ARM_CPU_PART_CORTEX_A78 0xD41
#define ARM_CPU_PART_CORTEX_X1 0xD44 #define ARM_CPU_PART_CORTEX_X1 0xD44
#define ARM_CPU_PART_CORTEX_A710 0xD47 #define ARM_CPU_PART_CORTEX_A710 0xD47
#define ARM_CPU_PART_CORTEX_A715 0xD4D
#define ARM_CPU_PART_CORTEX_X2 0xD48 #define ARM_CPU_PART_CORTEX_X2 0xD48
#define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define ARM_CPU_PART_NEOVERSE_N2 0xD49
#define ARM_CPU_PART_CORTEX_A78C 0xD4B #define ARM_CPU_PART_CORTEX_A78C 0xD4B
@ -89,6 +90,7 @@
#define ARM_CPU_PART_NEOVERSE_V3 0xD84 #define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define ARM_CPU_PART_CORTEX_X925 0xD85 #define ARM_CPU_PART_CORTEX_X925 0xD85
#define ARM_CPU_PART_CORTEX_A725 0xD87 #define ARM_CPU_PART_CORTEX_A725 0xD87
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
#define APM_CPU_PART_POTENZA 0x000 #define APM_CPU_PART_POTENZA 0x000
@ -128,6 +130,7 @@
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78) #define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
@ -139,6 +142,7 @@
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) #define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) #define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)

View file

@ -12,7 +12,7 @@
#define MAX_UINSN_BYTES AARCH64_INSN_SIZE #define MAX_UINSN_BYTES AARCH64_INSN_SIZE
#define UPROBE_SWBP_INSN BRK64_OPCODE_UPROBES #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES)
#define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE #define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE
#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES #define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES

View file

@ -848,6 +848,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
@ -858,6 +859,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),

View file

@ -96,10 +96,6 @@ arm_probe_decode_insn(probe_opcode_t insn, struct arch_probe_insn *api)
aarch64_insn_is_blr(insn) || aarch64_insn_is_blr(insn) ||
aarch64_insn_is_ret(insn)) { aarch64_insn_is_ret(insn)) {
api->handler = simulate_br_blr_ret; api->handler = simulate_br_blr_ret;
} else if (aarch64_insn_is_ldr_lit(insn)) {
api->handler = simulate_ldr_literal;
} else if (aarch64_insn_is_ldrsw_lit(insn)) {
api->handler = simulate_ldrsw_literal;
} else { } else {
/* /*
* Instruction cannot be stepped out-of-line and we don't * Instruction cannot be stepped out-of-line and we don't
@ -137,6 +133,17 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
probe_opcode_t insn = le32_to_cpu(*addr); probe_opcode_t insn = le32_to_cpu(*addr);
probe_opcode_t *scan_end = NULL; probe_opcode_t *scan_end = NULL;
unsigned long size = 0, offset = 0; unsigned long size = 0, offset = 0;
struct arch_probe_insn *api = &asi->api;
if (aarch64_insn_is_ldr_lit(insn)) {
api->handler = simulate_ldr_literal;
decoded = INSN_GOOD_NO_SLOT;
} else if (aarch64_insn_is_ldrsw_lit(insn)) {
api->handler = simulate_ldrsw_literal;
decoded = INSN_GOOD_NO_SLOT;
} else {
decoded = arm_probe_decode_insn(insn, &asi->api);
}
/* /*
* If there's a symbol defined in front of and near enough to * If there's a symbol defined in front of and near enough to
@ -154,7 +161,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
else else
scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
} }
decoded = arm_probe_decode_insn(insn, &asi->api);
if (decoded != INSN_REJECTED && scan_end) if (decoded != INSN_REJECTED && scan_end)
if (is_probed_address_atomic(addr - 1, scan_end)) if (is_probed_address_atomic(addr - 1, scan_end))

View file

@ -170,17 +170,15 @@ simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs)
void __kprobes void __kprobes
simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
{ {
u64 *load_addr; unsigned long load_addr;
int xn = opcode & 0x1f; int xn = opcode & 0x1f;
int disp;
disp = ldr_displacement(opcode); load_addr = addr + ldr_displacement(opcode);
load_addr = (u64 *) (addr + disp);
if (opcode & (1 << 30)) /* x0-x30 */ if (opcode & (1 << 30)) /* x0-x30 */
set_x_reg(regs, xn, *load_addr); set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr));
else /* w0-w30 */ else /* w0-w30 */
set_w_reg(regs, xn, *load_addr); set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr));
instruction_pointer_set(regs, instruction_pointer(regs) + 4); instruction_pointer_set(regs, instruction_pointer(regs) + 4);
} }
@ -188,14 +186,12 @@ simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
void __kprobes void __kprobes
simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs)
{ {
s32 *load_addr; unsigned long load_addr;
int xn = opcode & 0x1f; int xn = opcode & 0x1f;
int disp;
disp = ldr_displacement(opcode); load_addr = addr + ldr_displacement(opcode);
load_addr = (s32 *) (addr + disp);
set_x_reg(regs, xn, *load_addr); set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr));
instruction_pointer_set(regs, instruction_pointer(regs) + 4); instruction_pointer_set(regs, instruction_pointer(regs) + 4);
} }

View file

@ -276,11 +276,6 @@ asmlinkage void __init mmu_init(void)
{ {
unsigned int kstart, ksize; unsigned int kstart, ksize;
if (!memblock.reserved.cnt) {
pr_emerg("Error memory count\n");
machine_restart(NULL);
}
if ((u32) memblock.memory.regions[0].size < 0x400000) { if ((u32) memblock.memory.regions[0].size < 0x400000) {
pr_emerg("Memory must be greater than 4MB\n"); pr_emerg("Memory must be greater than 4MB\n");
machine_restart(NULL); machine_restart(NULL);

View file

@ -1078,8 +1078,7 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
STREG %r16, PT_ISR(%r29) STREG %r16, PT_ISR(%r29)
STREG %r17, PT_IOR(%r29) STREG %r17, PT_IOR(%r29)
#if 0 && defined(CONFIG_64BIT) #if defined(CONFIG_64BIT)
/* Revisit when we have 64-bit code above 4Gb */
b,n intr_save2 b,n intr_save2
skip_save_ior: skip_save_ior:
@ -1087,8 +1086,7 @@ skip_save_ior:
* need to adjust iasq/iaoq here in the same way we adjusted isr/ior * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
* above. * above.
*/ */
extrd,u,* %r8,PSW_W_BIT,1,%r1 bb,COND(>=),n %r8,PSW_W_BIT,intr_save2
cmpib,COND(=),n 1,%r1,intr_save2
LDREG PT_IASQ0(%r29), %r16 LDREG PT_IASQ0(%r29), %r16
LDREG PT_IAOQ0(%r29), %r17 LDREG PT_IAOQ0(%r29), %r17
/* adjust iasq/iaoq */ /* adjust iasq/iaoq */

View file

@ -217,10 +217,10 @@ linux_gateway_entry:
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldil L%sys_call_table, %r1 ldil L%sys_call_table, %r1
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
addil L%(sys_call_table64-sys_call_table), %r1 ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19 ldo R%sys_call_table(%r1), %r19
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19 ldo R%sys_call_table64(%r1), %r19
#else #else
load32 sys_call_table, %r19 load32 sys_call_table, %r19
@ -355,10 +355,10 @@ tracesys_next:
extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */
ldil L%sys_call_table, %r1 ldil L%sys_call_table, %r1
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
addil L%(sys_call_table64-sys_call_table), %r1 ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19 ldo R%sys_call_table(%r1), %r19
or,= %r2,%r2,%r2 or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19 ldo R%sys_call_table64(%r1), %r19
#else #else
load32 sys_call_table, %r19 load32 sys_call_table, %r19
@ -931,6 +931,8 @@ ENTRY(sys_call_table)
END(sys_call_table) END(sys_call_table)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#undef __SYSCALL_WITH_COMPAT
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
.align 8 .align 8
ENTRY(sys_call_table64) ENTRY(sys_call_table64)
#include <asm/syscall_table_64.h> /* 64-bit native syscalls */ #include <asm/syscall_table_64.h> /* 64-bit native syscalls */

View file

@ -285,6 +285,7 @@ int __init opal_event_init(void)
name, NULL); name, NULL);
if (rc) { if (rc) {
pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start);
kfree(name);
continue; continue;
} }
} }

View file

@ -139,6 +139,11 @@ config GENERIC_HWEIGHT
config FIX_EARLYCON_MEM config FIX_EARLYCON_MEM
def_bool y def_bool y
config ILLEGAL_POINTER_VALUE
hex
default 0 if 32BIT
default 0xdead000000000000 if 64BIT
config PGTABLE_LEVELS config PGTABLE_LEVELS
int int
default 3 if 64BIT default 3 if 64BIT

View file

@ -17,6 +17,8 @@
struct task_struct; struct task_struct;
register struct task_struct *riscv_current_is_tp __asm__("tp");
/* /*
* This only works because "struct thread_info" is at offset 0 from "struct * This only works because "struct thread_info" is at offset 0 from "struct
* task_struct". This constraint seems to be necessary on other architectures * task_struct". This constraint seems to be necessary on other architectures
@ -26,8 +28,7 @@ struct task_struct;
*/ */
static __always_inline struct task_struct *get_current(void) static __always_inline struct task_struct *get_current(void)
{ {
register struct task_struct *tp __asm__("tp"); return riscv_current_is_tp;
return tp;
} }
#define current get_current() #define current get_current()

View file

@ -4,8 +4,6 @@
* Copyright (C) 2017 SiFive * Copyright (C) 2017 SiFive
*/ */
#define GENERATING_ASM_OFFSETS
#include <linux/kbuild.h> #include <linux/kbuild.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>

View file

@ -71,7 +71,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
perf_callchain_store(entry, regs->sepc); perf_callchain_store(entry, regs->sepc);
fp = user_backtrace(entry, fp, regs->ra); fp = user_backtrace(entry, fp, regs->ra);
while (fp && !(fp & 0x3) && entry->nr < entry->max_stack) while (fp && !(fp & 0x7) && entry->nr < entry->max_stack)
fp = user_backtrace(entry, fp, 0); fp = user_backtrace(entry, fp, 0);
} }

View file

@ -22,6 +22,8 @@
#include <asm/switch_to.h> #include <asm/switch_to.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
unsigned long gp_in_global __asm__("gp");
extern asmlinkage void ret_from_fork(void); extern asmlinkage void ret_from_fork(void);
extern asmlinkage void ret_from_kernel_thread(void); extern asmlinkage void ret_from_kernel_thread(void);
@ -109,9 +111,8 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
/* p->thread holds context to be restored by __switch_to() */ /* p->thread holds context to be restored by __switch_to() */
if (unlikely(p->flags & PF_KTHREAD)) { if (unlikely(p->flags & PF_KTHREAD)) {
/* Kernel thread */ /* Kernel thread */
const register unsigned long gp __asm__ ("gp");
memset(childregs, 0, sizeof(struct pt_regs)); memset(childregs, 0, sizeof(struct pt_regs));
childregs->gp = gp; childregs->gp = gp_in_global;
childregs->sstatus = SR_SPP | SR_SPIE; /* Supervisor, irqs on */ childregs->sstatus = SR_SPP | SR_SPIE; /* Supervisor, irqs on */
p->thread.ra = (unsigned long)ret_from_kernel_thread; p->thread.ra = (unsigned long)ret_from_kernel_thread;

View file

@ -12,6 +12,8 @@
#include <linux/stacktrace.h> #include <linux/stacktrace.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
register unsigned long sp_in_global __asm__("sp");
#ifdef CONFIG_FRAME_POINTER #ifdef CONFIG_FRAME_POINTER
struct stackframe { struct stackframe {
@ -29,7 +31,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
sp = user_stack_pointer(regs); sp = user_stack_pointer(regs);
pc = instruction_pointer(regs); pc = instruction_pointer(regs);
} else if (task == NULL || task == current) { } else if (task == NULL || task == current) {
const register unsigned long current_sp __asm__ ("sp"); const register unsigned long current_sp = sp_in_global;
fp = (unsigned long)__builtin_frame_address(0); fp = (unsigned long)__builtin_frame_address(0);
sp = current_sp; sp = current_sp;
pc = (unsigned long)walk_stackframe; pc = (unsigned long)walk_stackframe;
@ -73,8 +75,7 @@ void notrace walk_stackframe(struct task_struct *task,
sp = user_stack_pointer(regs); sp = user_stack_pointer(regs);
pc = instruction_pointer(regs); pc = instruction_pointer(regs);
} else if (task == NULL || task == current) { } else if (task == NULL || task == current) {
const register unsigned long current_sp __asm__ ("sp"); sp = sp_in_global;
sp = current_sp;
pc = (unsigned long)walk_stackframe; pc = (unsigned long)walk_stackframe;
} else { } else {
/* task blocked in __switch_to */ /* task blocked in __switch_to */

View file

@ -53,8 +53,10 @@ static inline int test_facility(unsigned long nr)
unsigned long facilities_als[] = { FACILITIES_ALS }; unsigned long facilities_als[] = { FACILITIES_ALS };
if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) { if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
if (__test_facility(nr, &facilities_als)) if (__test_facility(nr, &facilities_als)) {
return 1; if (!__is_defined(__DECOMPRESSOR))
return 1;
}
} }
return __test_facility(nr, &S390_lowcore.stfle_fac_list); return __test_facility(nr, &S390_lowcore.stfle_fac_list);
} }

View file

@ -1412,7 +1412,7 @@ static int aux_output_begin(struct perf_output_handle *handle,
unsigned long head, base, offset; unsigned long head, base, offset;
struct hws_trailer_entry *te; struct hws_trailer_entry *te;
if (WARN_ON_ONCE(handle->head & ~PAGE_MASK)) if (handle->head & ~PAGE_MASK)
return -EINVAL; return -EINVAL;
aux->head = handle->head >> PAGE_SHIFT; aux->head = handle->head >> PAGE_SHIFT;
@ -1580,7 +1580,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
unsigned long num_sdb; unsigned long num_sdb;
aux = perf_get_aux(handle); aux = perf_get_aux(handle);
if (WARN_ON_ONCE(!aux)) if (!aux)
return; return;
/* Inform user space new data arrived */ /* Inform user space new data arrived */
@ -1599,7 +1599,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
debug_sprintf_event(sfdbg, 1, "AUX buffer used up\n"); debug_sprintf_event(sfdbg, 1, "AUX buffer used up\n");
break; break;
} }
if (WARN_ON_ONCE(!aux)) if (!aux)
return; return;
/* Update head and alert_mark to new position */ /* Update head and alert_mark to new position */
@ -1836,12 +1836,8 @@ static void cpumsf_pmu_start(struct perf_event *event, int flags)
{ {
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf); struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) if (!(event->hw.state & PERF_HES_STOPPED))
return; return;
if (flags & PERF_EF_RELOAD)
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
perf_pmu_disable(event->pmu); perf_pmu_disable(event->pmu);
event->hw.state = 0; event->hw.state = 0;
cpuhw->lsctl.cs = 1; cpuhw->lsctl.cs = 1;

View file

@ -78,7 +78,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu)
vcpu->stat.diagnose_258++; vcpu->stat.diagnose_258++;
if (vcpu->run->s.regs.gprs[rx] & 7) if (vcpu->run->s.regs.gprs[rx] & 7)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm)); rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm));
if (rc) if (rc)
return kvm_s390_inject_prog_cond(vcpu, rc); return kvm_s390_inject_prog_cond(vcpu, rc);
if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258)

View file

@ -794,46 +794,102 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
return 1; return 1;
} }
static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, /**
unsigned long *pages, unsigned long nr_pages, * guest_range_to_gpas() - Calculate guest physical addresses of page fragments
const union asce asce, enum gacc_mode mode) * covering a logical range
* @vcpu: virtual cpu
* @ga: guest address, start of range
* @ar: access register
* @gpas: output argument, may be NULL
* @len: length of range in bytes
* @asce: address-space-control element to use for translation
* @mode: access mode
*
* Translate a logical range to a series of guest absolute addresses,
* such that the concatenation of page fragments starting at each gpa make up
* the whole range.
* The translation is performed as if done by the cpu for the given @asce, @ar,
* @mode and state of the @vcpu.
* If the translation causes an exception, its program interruption code is
* returned and the &struct kvm_s390_pgm_info pgm member of @vcpu is modified
* such that a subsequent call to kvm_s390_inject_prog_vcpu() will inject
* a correct exception into the guest.
* The resulting gpas are stored into @gpas, unless it is NULL.
*
* Note: All fragments except the first one start at the beginning of a page.
* When deriving the boundaries of a fragment from a gpa, all but the last
* fragment end at the end of the page.
*
* Return:
* * 0 - success
* * <0 - translation could not be performed, for example if guest
* memory could not be accessed
* * >0 - an access exception occurred. In this case the returned value
* is the program interruption code and the contents of pgm may
* be used to inject an exception into the guest.
*/
static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
unsigned long *gpas, unsigned long len,
const union asce asce, enum gacc_mode mode)
{ {
psw_t *psw = &vcpu->arch.sie_block->gpsw; psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned int offset = offset_in_page(ga);
unsigned int fragment_len;
int lap_enabled, rc = 0; int lap_enabled, rc = 0;
enum prot_type prot; enum prot_type prot;
unsigned long gpa;
lap_enabled = low_address_protection_enabled(vcpu, asce); lap_enabled = low_address_protection_enabled(vcpu, asce);
while (nr_pages) { while (min(PAGE_SIZE - offset, len) > 0) {
fragment_len = min(PAGE_SIZE - offset, len);
ga = kvm_s390_logical_to_effective(vcpu, ga); ga = kvm_s390_logical_to_effective(vcpu, ga);
if (mode == GACC_STORE && lap_enabled && is_low_address(ga)) if (mode == GACC_STORE && lap_enabled && is_low_address(ga))
return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode, return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode,
PROT_TYPE_LA); PROT_TYPE_LA);
ga &= PAGE_MASK;
if (psw_bits(*psw).dat) { if (psw_bits(*psw).dat) {
rc = guest_translate(vcpu, ga, pages, asce, mode, &prot); rc = guest_translate(vcpu, ga, &gpa, asce, mode, &prot);
if (rc < 0) if (rc < 0)
return rc; return rc;
} else { } else {
*pages = kvm_s390_real_to_abs(vcpu, ga); gpa = kvm_s390_real_to_abs(vcpu, ga);
if (kvm_is_error_gpa(vcpu->kvm, *pages)) if (kvm_is_error_gpa(vcpu->kvm, gpa))
rc = PGM_ADDRESSING; rc = PGM_ADDRESSING;
} }
if (rc) if (rc)
return trans_exc(vcpu, rc, ga, ar, mode, prot); return trans_exc(vcpu, rc, ga, ar, mode, prot);
ga += PAGE_SIZE; if (gpas)
pages++; *gpas++ = gpa;
nr_pages--; offset = 0;
ga += fragment_len;
len -= fragment_len;
} }
return 0; return 0;
} }
static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
void *data, unsigned int len)
{
const unsigned int offset = offset_in_page(gpa);
const gfn_t gfn = gpa_to_gfn(gpa);
int rc;
if (!gfn_to_memslot(kvm, gfn))
return PGM_ADDRESSING;
if (mode == GACC_STORE)
rc = kvm_write_guest_page(kvm, gfn, data, offset, len);
else
rc = kvm_read_guest_page(kvm, gfn, data, offset, len);
return rc;
}
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data, int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
unsigned long len, enum gacc_mode mode) unsigned long len, enum gacc_mode mode)
{ {
psw_t *psw = &vcpu->arch.sie_block->gpsw; psw_t *psw = &vcpu->arch.sie_block->gpsw;
unsigned long _len, nr_pages, gpa, idx; unsigned long nr_pages, idx;
unsigned long pages_array[2]; unsigned long gpa_array[2];
unsigned long *pages; unsigned int fragment_len;
unsigned long *gpas;
int need_ipte_lock; int need_ipte_lock;
union asce asce; union asce asce;
int rc; int rc;
@ -845,50 +901,45 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
if (rc) if (rc)
return rc; return rc;
nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
pages = pages_array; gpas = gpa_array;
if (nr_pages > ARRAY_SIZE(pages_array)) if (nr_pages > ARRAY_SIZE(gpa_array))
pages = vmalloc(array_size(nr_pages, sizeof(unsigned long))); gpas = vmalloc(array_size(nr_pages, sizeof(unsigned long)));
if (!pages) if (!gpas)
return -ENOMEM; return -ENOMEM;
need_ipte_lock = psw_bits(*psw).dat && !asce.r; need_ipte_lock = psw_bits(*psw).dat && !asce.r;
if (need_ipte_lock) if (need_ipte_lock)
ipte_lock(vcpu); ipte_lock(vcpu);
rc = guest_page_range(vcpu, ga, ar, pages, nr_pages, asce, mode); rc = guest_range_to_gpas(vcpu, ga, ar, gpas, len, asce, mode);
for (idx = 0; idx < nr_pages && !rc; idx++) { for (idx = 0; idx < nr_pages && !rc; idx++) {
gpa = *(pages + idx) + (ga & ~PAGE_MASK); fragment_len = min(PAGE_SIZE - offset_in_page(gpas[idx]), len);
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); rc = access_guest_page(vcpu->kvm, mode, gpas[idx], data, fragment_len);
if (mode == GACC_STORE) len -= fragment_len;
rc = kvm_write_guest(vcpu->kvm, gpa, data, _len); data += fragment_len;
else
rc = kvm_read_guest(vcpu->kvm, gpa, data, _len);
len -= _len;
ga += _len;
data += _len;
} }
if (need_ipte_lock) if (need_ipte_lock)
ipte_unlock(vcpu); ipte_unlock(vcpu);
if (nr_pages > ARRAY_SIZE(pages_array)) if (nr_pages > ARRAY_SIZE(gpa_array))
vfree(pages); vfree(gpas);
return rc; return rc;
} }
int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
void *data, unsigned long len, enum gacc_mode mode) void *data, unsigned long len, enum gacc_mode mode)
{ {
unsigned long _len, gpa; unsigned int fragment_len;
unsigned long gpa;
int rc = 0; int rc = 0;
while (len && !rc) { while (len && !rc) {
gpa = kvm_s390_real_to_abs(vcpu, gra); gpa = kvm_s390_real_to_abs(vcpu, gra);
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); fragment_len = min(PAGE_SIZE - offset_in_page(gpa), len);
if (mode) rc = access_guest_page(vcpu->kvm, mode, gpa, data, fragment_len);
rc = write_guest_abs(vcpu, gpa, data, _len); len -= fragment_len;
else gra += fragment_len;
rc = read_guest_abs(vcpu, gpa, data, _len); data += fragment_len;
len -= _len;
gra += _len;
data += _len;
} }
if (rc > 0)
vcpu->arch.pgm.code = rc;
return rc; return rc;
} }
@ -904,8 +955,6 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
unsigned long *gpa, enum gacc_mode mode) unsigned long *gpa, enum gacc_mode mode)
{ {
psw_t *psw = &vcpu->arch.sie_block->gpsw;
enum prot_type prot;
union asce asce; union asce asce;
int rc; int rc;
@ -913,23 +962,7 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode); rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
if (rc) if (rc)
return rc; return rc;
if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) { return guest_range_to_gpas(vcpu, gva, ar, gpa, 1, asce, mode);
if (mode == GACC_STORE)
return trans_exc(vcpu, PGM_PROTECTION, gva, 0,
mode, PROT_TYPE_LA);
}
if (psw_bits(*psw).dat && !asce.r) { /* Use DAT? */
rc = guest_translate(vcpu, gva, gpa, asce, mode, &prot);
if (rc > 0)
return trans_exc(vcpu, rc, gva, 0, mode, prot);
} else {
*gpa = kvm_s390_real_to_abs(vcpu, gva);
if (kvm_is_error_gpa(vcpu->kvm, *gpa))
return trans_exc(vcpu, rc, gva, PGM_ADDRESSING, mode, 0);
}
return rc;
} }
/** /**
@ -938,17 +971,14 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
unsigned long length, enum gacc_mode mode) unsigned long length, enum gacc_mode mode)
{ {
unsigned long gpa; union asce asce;
unsigned long currlen;
int rc = 0; int rc = 0;
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
if (rc)
return rc;
ipte_lock(vcpu); ipte_lock(vcpu);
while (length > 0 && !rc) { rc = guest_range_to_gpas(vcpu, gva, ar, NULL, length, asce, mode);
currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE));
rc = guest_translate_address(vcpu, gva, ar, &gpa, mode);
gva += currlen;
length -= currlen;
}
ipte_unlock(vcpu); ipte_unlock(vcpu);
return rc; return rc;

View file

@ -344,11 +344,12 @@ int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
* @len: number of bytes to copy * @len: number of bytes to copy
* *
* Copy @len bytes from @data (kernel space) to @gra (guest real address). * Copy @len bytes from @data (kernel space) to @gra (guest real address).
* It is up to the caller to ensure that the entire guest memory range is
* valid memory before calling this function.
* Guest low address and key protection are not checked. * Guest low address and key protection are not checked.
* *
* Returns zero on success or -EFAULT on error. * Returns zero on success, -EFAULT when copying from @data failed, or
* PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
* is also stored to allow injecting into the guest (if applicable) using
* kvm_s390_inject_prog_cond().
* *
* If an error occurs data may have been copied partially to guest memory. * If an error occurs data may have been copied partially to guest memory.
*/ */
@ -367,11 +368,12 @@ int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
* @len: number of bytes to copy * @len: number of bytes to copy
* *
* Copy @len bytes from @gra (guest real address) to @data (kernel space). * Copy @len bytes from @gra (guest real address) to @data (kernel space).
* It is up to the caller to ensure that the entire guest memory range is
* valid memory before calling this function.
* Guest key protection is not checked. * Guest key protection is not checked.
* *
* Returns zero on success or -EFAULT on error. * Returns zero on success, -EFAULT when copying to @data failed, or
* PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
* is also stored to allow injecting into the guest (if applicable) using
* kvm_s390_inject_prog_cond().
* *
* If an error occurs data may have been copied partially to kernel space. * If an error occurs data may have been copied partially to kernel space.
*/ */

View file

@ -98,11 +98,12 @@ static long cmm_alloc_pages(long nr, long *counter,
(*counter)++; (*counter)++;
spin_unlock(&cmm_lock); spin_unlock(&cmm_lock);
nr--; nr--;
cond_resched();
} }
return nr; return nr;
} }
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
{ {
struct cmm_page_array *pa; struct cmm_page_array *pa;
unsigned long addr; unsigned long addr;
@ -126,6 +127,21 @@ static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
return nr; return nr;
} }
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
{
long inc = 0;
while (nr) {
inc = min(256L, nr);
nr -= inc;
inc = __cmm_free_pages(inc, counter, list);
if (inc)
break;
cond_resched();
}
return nr + inc;
}
static int cmm_oom_notify(struct notifier_block *self, static int cmm_oom_notify(struct notifier_block *self,
unsigned long dummy, void *parm) unsigned long dummy, void *parm)
{ {

View file

@ -290,6 +290,7 @@ CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_RUNTIME_UARTS=0 CONFIG_SERIAL_8250_RUNTIME_UARTS=0
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_BUS=y
CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM=y

View file

@ -217,7 +217,7 @@
#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */ #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */ #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */
#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */ #define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ #define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier without a guaranteed RSB flush */
#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ #define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ #define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */ #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
@ -308,6 +308,7 @@
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
#define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */ #define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */
#define X86_FEATURE_AMD_IBPB_RET (13*32+30) /* "" IBPB clears return address predictor */
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */

View file

@ -87,126 +87,84 @@
* don't give an lvalue though). */ * don't give an lvalue though). */
extern void __bad_percpu_size(void); extern void __bad_percpu_size(void);
#define percpu_to_op(qual, op, var, val) \ #define __pcpu_type_1 u8
do { \ #define __pcpu_type_2 u16
typedef typeof(var) pto_T__; \ #define __pcpu_type_4 u32
if (0) { \ #define __pcpu_type_8 u64
pto_T__ pto_tmp__; \
pto_tmp__ = (val); \ #define __pcpu_cast_1(val) ((u8)(((unsigned long) val) & 0xff))
(void)pto_tmp__; \ #define __pcpu_cast_2(val) ((u16)(((unsigned long) val) & 0xffff))
} \ #define __pcpu_cast_4(val) ((u32)(((unsigned long) val) & 0xffffffff))
switch (sizeof(var)) { \ #define __pcpu_cast_8(val) ((u64)(val))
case 1: \
asm qual (op "b %1,"__percpu_arg(0) \ #define __pcpu_op1_1(op, dst) op "b " dst
: "+m" (var) \ #define __pcpu_op1_2(op, dst) op "w " dst
: "qi" ((pto_T__)(val))); \ #define __pcpu_op1_4(op, dst) op "l " dst
break; \ #define __pcpu_op1_8(op, dst) op "q " dst
case 2: \
asm qual (op "w %1,"__percpu_arg(0) \ #define __pcpu_op2_1(op, src, dst) op "b " src ", " dst
: "+m" (var) \ #define __pcpu_op2_2(op, src, dst) op "w " src ", " dst
: "ri" ((pto_T__)(val))); \ #define __pcpu_op2_4(op, src, dst) op "l " src ", " dst
break; \ #define __pcpu_op2_8(op, src, dst) op "q " src ", " dst
case 4: \
asm qual (op "l %1,"__percpu_arg(0) \ #define __pcpu_reg_1(mod, x) mod "q" (x)
: "+m" (var) \ #define __pcpu_reg_2(mod, x) mod "r" (x)
: "ri" ((pto_T__)(val))); \ #define __pcpu_reg_4(mod, x) mod "r" (x)
break; \ #define __pcpu_reg_8(mod, x) mod "r" (x)
case 8: \
asm qual (op "q %1,"__percpu_arg(0) \ #define __pcpu_reg_imm_1(x) "qi" (x)
: "+m" (var) \ #define __pcpu_reg_imm_2(x) "ri" (x)
: "re" ((pto_T__)(val))); \ #define __pcpu_reg_imm_4(x) "ri" (x)
break; \ #define __pcpu_reg_imm_8(x) "re" (x)
default: __bad_percpu_size(); \
} \ #define percpu_to_op(size, qual, op, _var, _val) \
do { \
__pcpu_type_##size pto_val__ = __pcpu_cast_##size(_val); \
if (0) { \
typeof(_var) pto_tmp__; \
pto_tmp__ = (_val); \
(void)pto_tmp__; \
} \
asm qual(__pcpu_op2_##size(op, "%[val]", __percpu_arg([var])) \
: [var] "+m" (_var) \
: [val] __pcpu_reg_imm_##size(pto_val__)); \
} while (0) } while (0)
#define percpu_unary_op(size, qual, op, _var) \
({ \
asm qual (__pcpu_op1_##size(op, __percpu_arg([var])) \
: [var] "+m" (_var)); \
})
/* /*
* Generate a percpu add to memory instruction and optimize code * Generate a percpu add to memory instruction and optimize code
* if one is added or subtracted. * if one is added or subtracted.
*/ */
#define percpu_add_op(qual, var, val) \ #define percpu_add_op(size, qual, var, val) \
do { \ do { \
typedef typeof(var) pao_T__; \
const int pao_ID__ = (__builtin_constant_p(val) && \ const int pao_ID__ = (__builtin_constant_p(val) && \
((val) == 1 || (val) == -1)) ? \ ((val) == 1 || (val) == -1)) ? \
(int)(val) : 0; \ (int)(val) : 0; \
if (0) { \ if (0) { \
pao_T__ pao_tmp__; \ typeof(var) pao_tmp__; \
pao_tmp__ = (val); \ pao_tmp__ = (val); \
(void)pao_tmp__; \ (void)pao_tmp__; \
} \ } \
switch (sizeof(var)) { \ if (pao_ID__ == 1) \
case 1: \ percpu_unary_op(size, qual, "inc", var); \
if (pao_ID__ == 1) \ else if (pao_ID__ == -1) \
asm qual ("incb "__percpu_arg(0) : "+m" (var)); \ percpu_unary_op(size, qual, "dec", var); \
else if (pao_ID__ == -1) \ else \
asm qual ("decb "__percpu_arg(0) : "+m" (var)); \ percpu_to_op(size, qual, "add", var, val); \
else \
asm qual ("addb %1, "__percpu_arg(0) \
: "+m" (var) \
: "qi" ((pao_T__)(val))); \
break; \
case 2: \
if (pao_ID__ == 1) \
asm qual ("incw "__percpu_arg(0) : "+m" (var)); \
else if (pao_ID__ == -1) \
asm qual ("decw "__percpu_arg(0) : "+m" (var)); \
else \
asm qual ("addw %1, "__percpu_arg(0) \
: "+m" (var) \
: "ri" ((pao_T__)(val))); \
break; \
case 4: \
if (pao_ID__ == 1) \
asm qual ("incl "__percpu_arg(0) : "+m" (var)); \
else if (pao_ID__ == -1) \
asm qual ("decl "__percpu_arg(0) : "+m" (var)); \
else \
asm qual ("addl %1, "__percpu_arg(0) \
: "+m" (var) \
: "ri" ((pao_T__)(val))); \
break; \
case 8: \
if (pao_ID__ == 1) \
asm qual ("incq "__percpu_arg(0) : "+m" (var)); \
else if (pao_ID__ == -1) \
asm qual ("decq "__percpu_arg(0) : "+m" (var)); \
else \
asm qual ("addq %1, "__percpu_arg(0) \
: "+m" (var) \
: "re" ((pao_T__)(val))); \
break; \
default: __bad_percpu_size(); \
} \
} while (0) } while (0)
#define percpu_from_op(qual, op, var) \ #define percpu_from_op(size, qual, op, _var) \
({ \ ({ \
typeof(var) pfo_ret__; \ __pcpu_type_##size pfo_val__; \
switch (sizeof(var)) { \ asm qual (__pcpu_op2_##size(op, __percpu_arg([var]), "%[val]") \
case 1: \ : [val] __pcpu_reg_##size("=", pfo_val__) \
asm qual (op "b "__percpu_arg(1)",%0" \ : [var] "m" (_var)); \
: "=q" (pfo_ret__) \ (typeof(_var))(unsigned long) pfo_val__; \
: "m" (var)); \
break; \
case 2: \
asm qual (op "w "__percpu_arg(1)",%0" \
: "=r" (pfo_ret__) \
: "m" (var)); \
break; \
case 4: \
asm qual (op "l "__percpu_arg(1)",%0" \
: "=r" (pfo_ret__) \
: "m" (var)); \
break; \
case 8: \
asm qual (op "q "__percpu_arg(1)",%0" \
: "=r" (pfo_ret__) \
: "m" (var)); \
break; \
default: __bad_percpu_size(); \
} \
pfo_ret__; \
}) })
#define percpu_stable_op(op, var) \ #define percpu_stable_op(op, var) \
@ -238,29 +196,6 @@ do { \
pfo_ret__; \ pfo_ret__; \
}) })
#define percpu_unary_op(qual, op, var) \
({ \
switch (sizeof(var)) { \
case 1: \
asm qual (op "b "__percpu_arg(0) \
: "+m" (var)); \
break; \
case 2: \
asm qual (op "w "__percpu_arg(0) \
: "+m" (var)); \
break; \
case 4: \
asm qual (op "l "__percpu_arg(0) \
: "+m" (var)); \
break; \
case 8: \
asm qual (op "q "__percpu_arg(0) \
: "+m" (var)); \
break; \
default: __bad_percpu_size(); \
} \
})
/* /*
* Add return operation * Add return operation
*/ */
@ -391,22 +326,22 @@ do { \
*/ */
#define this_cpu_read_stable(var) percpu_stable_op("mov", var) #define this_cpu_read_stable(var) percpu_stable_op("mov", var)
#define raw_cpu_read_1(pcp) percpu_from_op(, "mov", pcp) #define raw_cpu_read_1(pcp) percpu_from_op(1, , "mov", pcp)
#define raw_cpu_read_2(pcp) percpu_from_op(, "mov", pcp) #define raw_cpu_read_2(pcp) percpu_from_op(2, , "mov", pcp)
#define raw_cpu_read_4(pcp) percpu_from_op(, "mov", pcp) #define raw_cpu_read_4(pcp) percpu_from_op(4, , "mov", pcp)
#define raw_cpu_write_1(pcp, val) percpu_to_op(, "mov", (pcp), val) #define raw_cpu_write_1(pcp, val) percpu_to_op(1, , "mov", (pcp), val)
#define raw_cpu_write_2(pcp, val) percpu_to_op(, "mov", (pcp), val) #define raw_cpu_write_2(pcp, val) percpu_to_op(2, , "mov", (pcp), val)
#define raw_cpu_write_4(pcp, val) percpu_to_op(, "mov", (pcp), val) #define raw_cpu_write_4(pcp, val) percpu_to_op(4, , "mov", (pcp), val)
#define raw_cpu_add_1(pcp, val) percpu_add_op(, (pcp), val) #define raw_cpu_add_1(pcp, val) percpu_add_op(1, , (pcp), val)
#define raw_cpu_add_2(pcp, val) percpu_add_op(, (pcp), val) #define raw_cpu_add_2(pcp, val) percpu_add_op(2, , (pcp), val)
#define raw_cpu_add_4(pcp, val) percpu_add_op(, (pcp), val) #define raw_cpu_add_4(pcp, val) percpu_add_op(4, , (pcp), val)
#define raw_cpu_and_1(pcp, val) percpu_to_op(, "and", (pcp), val) #define raw_cpu_and_1(pcp, val) percpu_to_op(1, , "and", (pcp), val)
#define raw_cpu_and_2(pcp, val) percpu_to_op(, "and", (pcp), val) #define raw_cpu_and_2(pcp, val) percpu_to_op(2, , "and", (pcp), val)
#define raw_cpu_and_4(pcp, val) percpu_to_op(, "and", (pcp), val) #define raw_cpu_and_4(pcp, val) percpu_to_op(4, , "and", (pcp), val)
#define raw_cpu_or_1(pcp, val) percpu_to_op(, "or", (pcp), val) #define raw_cpu_or_1(pcp, val) percpu_to_op(1, , "or", (pcp), val)
#define raw_cpu_or_2(pcp, val) percpu_to_op(, "or", (pcp), val) #define raw_cpu_or_2(pcp, val) percpu_to_op(2, , "or", (pcp), val)
#define raw_cpu_or_4(pcp, val) percpu_to_op(, "or", (pcp), val) #define raw_cpu_or_4(pcp, val) percpu_to_op(4, , "or", (pcp), val)
/* /*
* raw_cpu_xchg() can use a load-store since it is not required to be * raw_cpu_xchg() can use a load-store since it is not required to be
@ -423,21 +358,21 @@ do { \
#define raw_cpu_xchg_2(pcp, val) raw_percpu_xchg_op(pcp, val) #define raw_cpu_xchg_2(pcp, val) raw_percpu_xchg_op(pcp, val)
#define raw_cpu_xchg_4(pcp, val) raw_percpu_xchg_op(pcp, val) #define raw_cpu_xchg_4(pcp, val) raw_percpu_xchg_op(pcp, val)
#define this_cpu_read_1(pcp) percpu_from_op(volatile, "mov", pcp) #define this_cpu_read_1(pcp) percpu_from_op(1, volatile, "mov", pcp)
#define this_cpu_read_2(pcp) percpu_from_op(volatile, "mov", pcp) #define this_cpu_read_2(pcp) percpu_from_op(2, volatile, "mov", pcp)
#define this_cpu_read_4(pcp) percpu_from_op(volatile, "mov", pcp) #define this_cpu_read_4(pcp) percpu_from_op(4, volatile, "mov", pcp)
#define this_cpu_write_1(pcp, val) percpu_to_op(volatile, "mov", (pcp), val) #define this_cpu_write_1(pcp, val) percpu_to_op(1, volatile, "mov", (pcp), val)
#define this_cpu_write_2(pcp, val) percpu_to_op(volatile, "mov", (pcp), val) #define this_cpu_write_2(pcp, val) percpu_to_op(2, volatile, "mov", (pcp), val)
#define this_cpu_write_4(pcp, val) percpu_to_op(volatile, "mov", (pcp), val) #define this_cpu_write_4(pcp, val) percpu_to_op(4, volatile, "mov", (pcp), val)
#define this_cpu_add_1(pcp, val) percpu_add_op(volatile, (pcp), val) #define this_cpu_add_1(pcp, val) percpu_add_op(1, volatile, (pcp), val)
#define this_cpu_add_2(pcp, val) percpu_add_op(volatile, (pcp), val) #define this_cpu_add_2(pcp, val) percpu_add_op(2, volatile, (pcp), val)
#define this_cpu_add_4(pcp, val) percpu_add_op(volatile, (pcp), val) #define this_cpu_add_4(pcp, val) percpu_add_op(4, volatile, (pcp), val)
#define this_cpu_and_1(pcp, val) percpu_to_op(volatile, "and", (pcp), val) #define this_cpu_and_1(pcp, val) percpu_to_op(1, volatile, "and", (pcp), val)
#define this_cpu_and_2(pcp, val) percpu_to_op(volatile, "and", (pcp), val) #define this_cpu_and_2(pcp, val) percpu_to_op(2, volatile, "and", (pcp), val)
#define this_cpu_and_4(pcp, val) percpu_to_op(volatile, "and", (pcp), val) #define this_cpu_and_4(pcp, val) percpu_to_op(4, volatile, "and", (pcp), val)
#define this_cpu_or_1(pcp, val) percpu_to_op(volatile, "or", (pcp), val) #define this_cpu_or_1(pcp, val) percpu_to_op(1, volatile, "or", (pcp), val)
#define this_cpu_or_2(pcp, val) percpu_to_op(volatile, "or", (pcp), val) #define this_cpu_or_2(pcp, val) percpu_to_op(2, volatile, "or", (pcp), val)
#define this_cpu_or_4(pcp, val) percpu_to_op(volatile, "or", (pcp), val) #define this_cpu_or_4(pcp, val) percpu_to_op(4, volatile, "or", (pcp), val)
#define this_cpu_xchg_1(pcp, nval) percpu_xchg_op(volatile, pcp, nval) #define this_cpu_xchg_1(pcp, nval) percpu_xchg_op(volatile, pcp, nval)
#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(volatile, pcp, nval) #define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(volatile, pcp, nval)
#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(volatile, pcp, nval) #define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(volatile, pcp, nval)
@ -478,20 +413,20 @@ do { \
* 32 bit must fall back to generic operations. * 32 bit must fall back to generic operations.
*/ */
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#define raw_cpu_read_8(pcp) percpu_from_op(, "mov", pcp) #define raw_cpu_read_8(pcp) percpu_from_op(8, , "mov", pcp)
#define raw_cpu_write_8(pcp, val) percpu_to_op(, "mov", (pcp), val) #define raw_cpu_write_8(pcp, val) percpu_to_op(8, , "mov", (pcp), val)
#define raw_cpu_add_8(pcp, val) percpu_add_op(, (pcp), val) #define raw_cpu_add_8(pcp, val) percpu_add_op(8, , (pcp), val)
#define raw_cpu_and_8(pcp, val) percpu_to_op(, "and", (pcp), val) #define raw_cpu_and_8(pcp, val) percpu_to_op(8, , "and", (pcp), val)
#define raw_cpu_or_8(pcp, val) percpu_to_op(, "or", (pcp), val) #define raw_cpu_or_8(pcp, val) percpu_to_op(8, , "or", (pcp), val)
#define raw_cpu_add_return_8(pcp, val) percpu_add_return_op(, pcp, val) #define raw_cpu_add_return_8(pcp, val) percpu_add_return_op(, pcp, val)
#define raw_cpu_xchg_8(pcp, nval) raw_percpu_xchg_op(pcp, nval) #define raw_cpu_xchg_8(pcp, nval) raw_percpu_xchg_op(pcp, nval)
#define raw_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(, pcp, oval, nval) #define raw_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(, pcp, oval, nval)
#define this_cpu_read_8(pcp) percpu_from_op(volatile, "mov", pcp) #define this_cpu_read_8(pcp) percpu_from_op(8, volatile, "mov", pcp)
#define this_cpu_write_8(pcp, val) percpu_to_op(volatile, "mov", (pcp), val) #define this_cpu_write_8(pcp, val) percpu_to_op(8, volatile, "mov", (pcp), val)
#define this_cpu_add_8(pcp, val) percpu_add_op(volatile, (pcp), val) #define this_cpu_add_8(pcp, val) percpu_add_op(8, volatile, (pcp), val)
#define this_cpu_and_8(pcp, val) percpu_to_op(volatile, "and", (pcp), val) #define this_cpu_and_8(pcp, val) percpu_to_op(8, volatile, "and", (pcp), val)
#define this_cpu_or_8(pcp, val) percpu_to_op(volatile, "or", (pcp), val) #define this_cpu_or_8(pcp, val) percpu_to_op(8, volatile, "or", (pcp), val)
#define this_cpu_add_return_8(pcp, val) percpu_add_return_op(volatile, pcp, val) #define this_cpu_add_return_8(pcp, val) percpu_add_return_op(volatile, pcp, val)
#define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(volatile, pcp, nval) #define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(volatile, pcp, nval)
#define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(volatile, pcp, oval, nval) #define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(volatile, pcp, oval, nval)

View file

@ -94,7 +94,12 @@ static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs, struct pt_regs *regs,
unsigned long *args) unsigned long *args)
{ {
memcpy(args, &regs->bx, 6 * sizeof(args[0])); args[0] = regs->bx;
args[1] = regs->cx;
args[2] = regs->dx;
args[3] = regs->si;
args[4] = regs->di;
args[5] = regs->bp;
} }
static inline void syscall_set_arguments(struct task_struct *task, static inline void syscall_set_arguments(struct task_struct *task,

View file

@ -491,7 +491,19 @@ static int lapic_timer_shutdown(struct clock_event_device *evt)
v = apic_read(APIC_LVTT); v = apic_read(APIC_LVTT);
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
apic_write(APIC_LVTT, v); apic_write(APIC_LVTT, v);
apic_write(APIC_TMICT, 0);
/*
* Setting APIC_LVT_MASKED (above) should be enough to tell
* the hardware that this timer will never fire. But AMD
* erratum 411 and some Intel CPU behavior circa 2024 say
* otherwise. Time for belt and suspenders programming: mask
* the timer _and_ zero the counter registers:
*/
if (v & APIC_LVT_TIMER_TSCDEADLINE)
wrmsrl(MSR_IA32_TSC_DEADLINE, 0);
else
apic_write(APIC_TMICT, 0);
return 0; return 0;
} }

View file

@ -256,6 +256,7 @@ static void __init ms_hyperv_init_platform(void)
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
x86_platform.calibrate_tsc = hv_get_tsc_khz; x86_platform.calibrate_tsc = hv_get_tsc_khz;
x86_platform.calibrate_cpu = hv_get_tsc_khz; x86_platform.calibrate_cpu = hv_get_tsc_khz;
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
} }
if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) { if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) {

View file

@ -250,7 +250,7 @@ static inline bool rdt_get_mb_table(struct rdt_resource *r)
return false; return false;
} }
static bool __get_mem_config_intel(struct rdt_resource *r) static __init bool __get_mem_config_intel(struct rdt_resource *r)
{ {
union cpuid_0x10_3_eax eax; union cpuid_0x10_3_eax eax;
union cpuid_0x10_x_edx edx; union cpuid_0x10_x_edx edx;
@ -277,7 +277,7 @@ static bool __get_mem_config_intel(struct rdt_resource *r)
return true; return true;
} }
static bool __rdt_get_mem_config_amd(struct rdt_resource *r) static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)
{ {
union cpuid_0x10_3_eax eax; union cpuid_0x10_3_eax eax;
union cpuid_0x10_x_edx edx; union cpuid_0x10_x_edx edx;

View file

@ -875,7 +875,7 @@ char * __init xen_memory_setup(void)
* to relocating (and even reusing) pages with kernel text or data. * to relocating (and even reusing) pages with kernel text or data.
*/ */
if (xen_is_e820_reserved(__pa_symbol(_text), if (xen_is_e820_reserved(__pa_symbol(_text),
__pa_symbol(__bss_stop) - __pa_symbol(_text))) { __pa_symbol(_end) - __pa_symbol(_text))) {
xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n"); xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
BUG(); BUG();
} }

View file

@ -2610,8 +2610,12 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
struct bfq_queue *in_service_bfqq, *new_bfqq; struct bfq_queue *in_service_bfqq, *new_bfqq;
/* if a merge has already been setup, then proceed with that first */ /* if a merge has already been setup, then proceed with that first */
if (bfqq->new_bfqq) new_bfqq = bfqq->new_bfqq;
return bfqq->new_bfqq; if (new_bfqq) {
while (new_bfqq->new_bfqq)
new_bfqq = new_bfqq->new_bfqq;
return new_bfqq;
}
/* /*
* Do not perform queue merging if the device is non * Do not perform queue merging if the device is non
@ -5990,7 +5994,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
{ {
bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
if (bfqq_process_refs(bfqq) == 1) { if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
bfqq->pid = current->pid; bfqq->pid = current->pid;
bfq_clear_bfqq_coop(bfqq); bfq_clear_bfqq_coop(bfqq);
bfq_clear_bfqq_split_coop(bfqq); bfq_clear_bfqq_split_coop(bfqq);
@ -6175,7 +6179,8 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
* addition, if the queue has also just been split, we have to * addition, if the queue has also just been split, we have to
* resume its state. * resume its state.
*/ */
if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { if (likely(bfqq != &bfqd->oom_bfqq) && !bfqq->new_bfqq &&
bfqq_process_refs(bfqq) == 1) {
bfqq->bic = bic; bfqq->bic = bic;
if (split) { if (split) {
/* /*

View file

@ -225,8 +225,8 @@ static int rq_qos_wake_function(struct wait_queue_entry *curr,
data->got_token = true; data->got_token = true;
smp_wmb(); smp_wmb();
list_del_init(&curr->entry);
wake_up_process(data->task); wake_up_process(data->task);
list_del_init_careful(&curr->entry);
return 1; return 1;
} }

View file

@ -40,8 +40,7 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen); memcpy(alignbuffer, key, keylen);
ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen); ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen);
memset(alignbuffer, 0, keylen); kzfree(buffer);
kfree(buffer);
return ret; return ret;
} }

View file

@ -33,8 +33,7 @@ static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen); memcpy(alignbuffer, key, keylen);
ret = cia->cia_setkey(tfm, alignbuffer, keylen); ret = cia->cia_setkey(tfm, alignbuffer, keylen);
memset(alignbuffer, 0, keylen); kzfree(buffer);
kfree(buffer);
return ret; return ret;
} }

View file

@ -170,6 +170,8 @@ acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object)
elements = elements =
ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS * ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
sizeof(union acpi_object)); sizeof(union acpi_object));
if (!elements)
return (AE_NO_MEMORY);
this = string; this = string;
for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) { for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {

View file

@ -437,6 +437,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
if (info->connection_node) { if (info->connection_node) {
second_desc = info->connection_node->object; second_desc = info->connection_node->object;
if (second_desc == NULL) {
break;
}
if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) { if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
status = status =
acpi_ds_get_buffer_arguments(second_desc); acpi_ds_get_buffer_arguments(second_desc);

View file

@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
*parser_state); *parser_state);
static void acpi_ps_free_field_list(union acpi_parse_object *start);
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ps_get_next_package_length * FUNCTION: acpi_ps_get_next_package_length
@ -683,6 +685,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
return_PTR(field); return_PTR(field);
} }
/*******************************************************************************
*
* FUNCTION: acpi_ps_free_field_list
*
* PARAMETERS: start - First Op in field list
*
* RETURN: None.
*
* DESCRIPTION: Free all Op objects inside a field list.
*
******************************************************************************/
static void acpi_ps_free_field_list(union acpi_parse_object *start)
{
union acpi_parse_object *cur = start;
union acpi_parse_object *next;
union acpi_parse_object *arg;
while (cur) {
next = cur->common.next;
/* AML_INT_CONNECTION_OP can have a single argument */
arg = acpi_ps_get_arg(cur, 0);
if (arg) {
acpi_ps_free_op(arg);
}
acpi_ps_free_op(cur);
cur = next;
}
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ps_get_next_arg * FUNCTION: acpi_ps_get_next_arg
@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
while (parser_state->aml < parser_state->pkg_end) { while (parser_state->aml < parser_state->pkg_end) {
field = acpi_ps_get_next_field(parser_state); field = acpi_ps_get_next_field(parser_state);
if (!field) { if (!field) {
if (arg) {
acpi_ps_free_field_list(arg);
}
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
@ -820,6 +859,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
acpi_ps_get_next_namepath(walk_state, parser_state, acpi_ps_get_next_namepath(walk_state, parser_state,
arg, arg,
ACPI_NOT_METHOD_CALL); ACPI_NOT_METHOD_CALL);
if (ACPI_FAILURE(status)) {
acpi_ps_free_op(arg);
return_ACPI_STATUS(status);
}
} else { } else {
/* Single complex argument, nothing returned */ /* Single complex argument, nothing returned */
@ -854,6 +897,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
acpi_ps_get_next_namepath(walk_state, parser_state, acpi_ps_get_next_namepath(walk_state, parser_state,
arg, arg,
ACPI_POSSIBLE_METHOD_CALL); ACPI_POSSIBLE_METHOD_CALL);
if (ACPI_FAILURE(status)) {
acpi_ps_free_op(arg);
return_ACPI_STATUS(status);
}
if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) { if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {

View file

@ -706,27 +706,34 @@ static LIST_HEAD(acpi_battery_list);
static LIST_HEAD(battery_hook_list); static LIST_HEAD(battery_hook_list);
static DEFINE_MUTEX(hook_mutex); static DEFINE_MUTEX(hook_mutex);
static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
{ {
struct acpi_battery *battery; struct acpi_battery *battery;
/* /*
* In order to remove a hook, we first need to * In order to remove a hook, we first need to
* de-register all the batteries that are registered. * de-register all the batteries that are registered.
*/ */
if (lock)
mutex_lock(&hook_mutex);
list_for_each_entry(battery, &acpi_battery_list, list) { list_for_each_entry(battery, &acpi_battery_list, list) {
hook->remove_battery(battery->bat); hook->remove_battery(battery->bat);
} }
list_del(&hook->list); list_del_init(&hook->list);
if (lock)
mutex_unlock(&hook_mutex);
pr_info("extension unregistered: %s\n", hook->name); pr_info("extension unregistered: %s\n", hook->name);
} }
void battery_hook_unregister(struct acpi_battery_hook *hook) void battery_hook_unregister(struct acpi_battery_hook *hook)
{ {
__battery_hook_unregister(hook, 1); mutex_lock(&hook_mutex);
/*
* Ignore already unregistered battery hooks. This might happen
* if a battery hook was previously unloaded due to an error when
* adding a new battery.
*/
if (!list_empty(&hook->list))
battery_hook_unregister_unlocked(hook);
mutex_unlock(&hook_mutex);
} }
EXPORT_SYMBOL_GPL(battery_hook_unregister); EXPORT_SYMBOL_GPL(battery_hook_unregister);
@ -735,7 +742,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)
struct acpi_battery *battery; struct acpi_battery *battery;
mutex_lock(&hook_mutex); mutex_lock(&hook_mutex);
INIT_LIST_HEAD(&hook->list);
list_add(&hook->list, &battery_hook_list); list_add(&hook->list, &battery_hook_list);
/* /*
* Now that the driver is registered, we need * Now that the driver is registered, we need
@ -752,7 +758,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)
* hooks. * hooks.
*/ */
pr_err("extension failed to load: %s", hook->name); pr_err("extension failed to load: %s", hook->name);
__battery_hook_unregister(hook, 0); battery_hook_unregister_unlocked(hook);
goto end; goto end;
} }
} }
@ -789,7 +795,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
*/ */
pr_err("error in extension, unloading: %s", pr_err("error in extension, unloading: %s",
hook_node->name); hook_node->name);
__battery_hook_unregister(hook_node, 0); battery_hook_unregister_unlocked(hook_node);
} }
} }
mutex_unlock(&hook_mutex); mutex_unlock(&hook_mutex);
@ -822,7 +828,7 @@ static void __exit battery_hook_exit(void)
* need to remove the hooks. * need to remove the hooks.
*/ */
list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
__battery_hook_unregister(hook, 1); battery_hook_unregister(hook);
} }
mutex_destroy(&hook_mutex); mutex_destroy(&hook_mutex);
} }

View file

@ -111,6 +111,17 @@ static const struct dmi_system_id lid_blacklst[] = {
}, },
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
}, },
{
/*
* Samsung galaxybook2 ,initial _LID device notification returns
* lid closed.
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
DMI_MATCH(DMI_PRODUCT_NAME, "750XED"),
},
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
},
{} {}
}; };

View file

@ -533,8 +533,9 @@ int acpi_device_setup_files(struct acpi_device *dev)
* If device has _STR, 'description' file is created * If device has _STR, 'description' file is created
*/ */
if (acpi_has_method(dev->handle, "_STR")) { if (acpi_has_method(dev->handle, "_STR")) {
status = acpi_evaluate_object(dev->handle, "_STR", status = acpi_evaluate_object_typed(dev->handle, "_STR",
NULL, &buffer); NULL, &buffer,
ACPI_TYPE_BUFFER);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
buffer.pointer = NULL; buffer.pointer = NULL;
dev->pnp.str_obj = buffer.pointer; dev->pnp.str_obj = buffer.pointer;

View file

@ -790,6 +790,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
unsigned long tmp; unsigned long tmp;
int ret = 0; int ret = 0;
if (t->rdata)
memset(t->rdata, 0, t->rlen);
/* start transaction */ /* start transaction */
spin_lock_irqsave(&ec->lock, tmp); spin_lock_irqsave(&ec->lock, tmp);
/* Enable GPE for command processing (IBF=0/OBF=1) */ /* Enable GPE for command processing (IBF=0/OBF=1) */
@ -826,8 +829,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
return -EINVAL; return -EINVAL;
if (t->rdata)
memset(t->rdata, 0, t->rlen);
mutex_lock(&ec->mutex); mutex_lock(&ec->mutex);
if (ec->global_lock) { if (ec->global_lock) {
@ -854,7 +855,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec)
.wdata = NULL, .rdata = &d, .wdata = NULL, .rdata = &d,
.wlen = 0, .rlen = 1}; .wlen = 0, .rlen = 1};
return acpi_ec_transaction(ec, &t); return acpi_ec_transaction_unlocked(ec, &t);
} }
static int acpi_ec_burst_disable(struct acpi_ec *ec) static int acpi_ec_burst_disable(struct acpi_ec *ec)
@ -864,7 +865,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec)
.wlen = 0, .rlen = 0}; .wlen = 0, .rlen = 0};
return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
acpi_ec_transaction(ec, &t) : 0; acpi_ec_transaction_unlocked(ec, &t) : 0;
} }
static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
@ -880,6 +881,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
return result; return result;
} }
static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data)
{
int result;
u8 d;
struct transaction t = {.command = ACPI_EC_COMMAND_READ,
.wdata = &address, .rdata = &d,
.wlen = 1, .rlen = 1};
result = acpi_ec_transaction_unlocked(ec, &t);
*data = d;
return result;
}
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
{ {
u8 wdata[2] = { address, data }; u8 wdata[2] = { address, data };
@ -890,6 +904,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
return acpi_ec_transaction(ec, &t); return acpi_ec_transaction(ec, &t);
} }
static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data)
{
u8 wdata[2] = { address, data };
struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
.wdata = wdata, .rdata = NULL,
.wlen = 2, .rlen = 0};
return acpi_ec_transaction_unlocked(ec, &t);
}
int ec_read(u8 addr, u8 *val) int ec_read(u8 addr, u8 *val)
{ {
int err; int err;
@ -1300,6 +1324,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
struct acpi_ec *ec = handler_context; struct acpi_ec *ec = handler_context;
int result = 0, i, bytes = bits / 8; int result = 0, i, bytes = bits / 8;
u8 *value = (u8 *)value64; u8 *value = (u8 *)value64;
u32 glk;
if ((address > 0xFF) || !value || !handler_context) if ((address > 0xFF) || !value || !handler_context)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
@ -1307,13 +1332,25 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
if (function != ACPI_READ && function != ACPI_WRITE) if (function != ACPI_READ && function != ACPI_WRITE)
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;
mutex_lock(&ec->mutex);
if (ec->global_lock) {
acpi_status status;
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
if (ACPI_FAILURE(status)) {
result = -ENODEV;
goto unlock;
}
}
if (ec->busy_polling || bits > 8) if (ec->busy_polling || bits > 8)
acpi_ec_burst_enable(ec); acpi_ec_burst_enable(ec);
for (i = 0; i < bytes; ++i, ++address, ++value) { for (i = 0; i < bytes; ++i, ++address, ++value) {
result = (function == ACPI_READ) ? result = (function == ACPI_READ) ?
acpi_ec_read(ec, address, value) : acpi_ec_read_unlocked(ec, address, value) :
acpi_ec_write(ec, address, *value); acpi_ec_write_unlocked(ec, address, *value);
if (result < 0) if (result < 0)
break; break;
} }
@ -1321,6 +1358,12 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
if (ec->busy_polling || bits > 8) if (ec->busy_polling || bits > 8)
acpi_ec_burst_disable(ec); acpi_ec_burst_disable(ec);
if (ec->global_lock)
acpi_release_global_lock(glk);
unlock:
mutex_unlock(&ec->mutex);
switch (result) { switch (result) {
case -EINVAL: case -EINVAL:
return AE_BAD_PARAMETER; return AE_BAD_PARAMETER;

View file

@ -376,10 +376,8 @@ static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
struct tps68470_pmic_opregion *opregion; struct tps68470_pmic_opregion *opregion;
acpi_status status; acpi_status status;
if (!dev || !tps68470_regmap) { if (!tps68470_regmap)
dev_warn(dev, "dev or regmap is NULL\n"); return dev_err_probe(dev, -EINVAL, "regmap is missing\n");
return -EINVAL;
}
if (!handle) { if (!handle) {
dev_warn(dev, "acpi handle is NULL\n"); dev_warn(dev, "acpi handle is NULL\n");

View file

@ -442,6 +442,13 @@ static const struct dmi_system_id asus_laptop[] = {
DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"), DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"),
}, },
}, },
{
/* Asus Vivobook X1704VAP */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"),
},
},
{ {
/* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */ /* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */
.matches = { .matches = {
@ -455,6 +462,12 @@ static const struct dmi_system_id asus_laptop[] = {
DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"), DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"),
}, },
}, },
{
/* TongFang GMxXGxX/TUXEDO Polaris 15 Gen5 AMD */
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"),
},
},
{ {
/* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */ /* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */
.matches = { .matches = {
@ -481,12 +494,26 @@ static const struct dmi_system_id asus_laptop[] = {
DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"), DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"),
}, },
}, },
{
/* Asus ExpertBook B2502CVA */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"),
},
},
{ {
/* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */ /* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */
.matches = { .matches = {
DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
}, },
}, },
{
/* LG Electronics 16T90SP */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
DMI_MATCH(DMI_BOARD_NAME, "16T90SP"),
},
},
{ } { }
}; };

View file

@ -1310,6 +1310,10 @@ static void binder_cleanup_ref_olocked(struct binder_ref *ref)
binder_dequeue_work(ref->proc, &ref->death->work); binder_dequeue_work(ref->proc, &ref->death->work);
binder_stats_deleted(BINDER_STAT_DEATH); binder_stats_deleted(BINDER_STAT_DEATH);
} }
if (ref->freeze)
binder_dequeue_work(ref->proc, &ref->freeze->work);
binder_stats_deleted(BINDER_STAT_REF); binder_stats_deleted(BINDER_STAT_REF);
} }
@ -3841,7 +3845,6 @@ binder_request_freeze_notification(struct binder_proc *proc,
{ {
struct binder_ref_freeze *freeze; struct binder_ref_freeze *freeze;
struct binder_ref *ref; struct binder_ref *ref;
bool is_frozen;
freeze = kzalloc(sizeof(*freeze), GFP_KERNEL); freeze = kzalloc(sizeof(*freeze), GFP_KERNEL);
if (!freeze) if (!freeze)
@ -3857,31 +3860,30 @@ binder_request_freeze_notification(struct binder_proc *proc,
} }
binder_node_lock(ref->node); binder_node_lock(ref->node);
if (ref->freeze) {
if (ref->freeze || !ref->node->proc) { binder_user_error("%d:%d BC_REQUEST_FREEZE_NOTIFICATION already set\n",
binder_user_error("%d:%d invalid BC_REQUEST_FREEZE_NOTIFICATION %s\n", proc->pid, thread->pid);
proc->pid, thread->pid,
ref->freeze ? "already set" : "dead node");
binder_node_unlock(ref->node); binder_node_unlock(ref->node);
binder_proc_unlock(proc); binder_proc_unlock(proc);
kfree(freeze); kfree(freeze);
return -EINVAL; return -EINVAL;
} }
binder_inner_proc_lock(ref->node->proc);
is_frozen = ref->node->proc->is_frozen;
binder_inner_proc_unlock(ref->node->proc);
INIT_LIST_HEAD(&freeze->work.entry); INIT_LIST_HEAD(&freeze->work.entry);
freeze->cookie = handle_cookie->cookie; freeze->cookie = handle_cookie->cookie;
freeze->work.type = BINDER_WORK_FROZEN_BINDER; freeze->work.type = BINDER_WORK_FROZEN_BINDER;
freeze->is_frozen = is_frozen;
ref->freeze = freeze; ref->freeze = freeze;
binder_inner_proc_lock(proc); if (ref->node->proc) {
binder_enqueue_work_ilocked(&ref->freeze->work, &proc->todo); binder_inner_proc_lock(ref->node->proc);
binder_wakeup_proc_ilocked(proc); freeze->is_frozen = ref->node->proc->is_frozen;
binder_inner_proc_unlock(proc); binder_inner_proc_unlock(ref->node->proc);
binder_inner_proc_lock(proc);
binder_enqueue_work_ilocked(&freeze->work, &proc->todo);
binder_wakeup_proc_ilocked(proc);
binder_inner_proc_unlock(proc);
}
binder_node_unlock(ref->node); binder_node_unlock(ref->node);
binder_proc_unlock(proc); binder_proc_unlock(proc);
@ -5141,6 +5143,15 @@ static void binder_release_work(struct binder_proc *proc,
} break; } break;
case BINDER_WORK_NODE: case BINDER_WORK_NODE:
break; break;
case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION: {
struct binder_ref_freeze *freeze;
freeze = container_of(w, struct binder_ref_freeze, work);
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
"undelivered freeze notification, %016llx\n",
(u64)freeze->cookie);
kfree(freeze);
} break;
default: default:
pr_err("unexpected work type, %d, not freed\n", pr_err("unexpected work type, %d, not freed\n",
wtype); wtype);
@ -5553,6 +5564,7 @@ static bool binder_txns_pending_ilocked(struct binder_proc *proc)
static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen)
{ {
struct binder_node *prev = NULL;
struct rb_node *n; struct rb_node *n;
struct binder_ref *ref; struct binder_ref *ref;
@ -5561,7 +5573,10 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen)
struct binder_node *node; struct binder_node *node;
node = rb_entry(n, struct binder_node, rb_node); node = rb_entry(n, struct binder_node, rb_node);
binder_inc_node_tmpref_ilocked(node);
binder_inner_proc_unlock(proc); binder_inner_proc_unlock(proc);
if (prev)
binder_put_node(prev);
binder_node_lock(node); binder_node_lock(node);
hlist_for_each_entry(ref, &node->refs, node_entry) { hlist_for_each_entry(ref, &node->refs, node_entry) {
/* /*
@ -5587,10 +5602,15 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen)
} }
binder_inner_proc_unlock(ref->proc); binder_inner_proc_unlock(ref->proc);
} }
prev = node;
binder_node_unlock(node); binder_node_unlock(node);
binder_inner_proc_lock(proc); binder_inner_proc_lock(proc);
if (proc->is_dead)
break;
} }
binder_inner_proc_unlock(proc); binder_inner_proc_unlock(proc);
if (prev)
binder_put_node(prev);
} }
static int binder_ioctl_freeze(struct binder_freeze_info *info, static int binder_ioctl_freeze(struct binder_freeze_info *info,
@ -6263,6 +6283,7 @@ static void binder_deferred_release(struct binder_proc *proc)
binder_release_work(proc, &proc->todo); binder_release_work(proc, &proc->todo);
binder_release_work(proc, &proc->delivered_death); binder_release_work(proc, &proc->delivered_death);
binder_release_work(proc, &proc_wrapper(proc)->delivered_freeze);
binder_debug(BINDER_DEBUG_OPEN_CLOSE, binder_debug(BINDER_DEBUG_OPEN_CLOSE,
"%s: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d\n", "%s: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d\n",
@ -6395,6 +6416,12 @@ static void print_binder_work_ilocked(struct seq_file *m,
case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: case BINDER_WORK_CLEAR_DEATH_NOTIFICATION:
seq_printf(m, "%shas cleared death notification\n", prefix); seq_printf(m, "%shas cleared death notification\n", prefix);
break; break;
case BINDER_WORK_FROZEN_BINDER:
seq_printf(m, "%shas frozen binder\n", prefix);
break;
case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION:
seq_printf(m, "%shas cleared freeze notification\n", prefix);
break;
default: default:
seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); seq_printf(m, "%sunknown work: type %d\n", prefix, w->type);
break; break;
@ -6544,6 +6571,10 @@ static void print_binder_proc(struct seq_file *m,
seq_puts(m, " has delivered dead binder\n"); seq_puts(m, " has delivered dead binder\n");
break; break;
} }
list_for_each_entry(w, &proc_wrapper(proc)->delivered_freeze, entry) {
seq_puts(m, " has delivered freeze binder\n");
break;
}
binder_inner_proc_unlock(proc); binder_inner_proc_unlock(proc);
if (!print_all && m->count == header_pos) if (!print_all && m->count == header_pos)
m->count = start_pos; m->count = start_pos;

View file

@ -128,7 +128,7 @@ static const struct pci_device_id sil_pci_tbl[] = {
static const struct sil_drivelist { static const struct sil_drivelist {
const char *product; const char *product;
unsigned int quirk; unsigned int quirk;
} sil_blacklist [] = { } sil_quirks[] = {
{ "ST320012AS", SIL_QUIRK_MOD15WRITE }, { "ST320012AS", SIL_QUIRK_MOD15WRITE },
{ "ST330013AS", SIL_QUIRK_MOD15WRITE }, { "ST330013AS", SIL_QUIRK_MOD15WRITE },
{ "ST340017AS", SIL_QUIRK_MOD15WRITE }, { "ST340017AS", SIL_QUIRK_MOD15WRITE },
@ -601,8 +601,8 @@ static void sil_thaw(struct ata_port *ap)
* list, and apply the fixups to only the specific * list, and apply the fixups to only the specific
* devices/hosts/firmwares that need it. * devices/hosts/firmwares that need it.
* *
* 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted * 20040111 - Seagate drives affected by the Mod15Write bug are quirked
* The Maxtor quirk is in the blacklist, but I'm keeping the original * The Maxtor quirk is in sil_quirks, but I'm keeping the original
* pessimistic fix for the following reasons... * pessimistic fix for the following reasons...
* - There seems to be less info on it, only one device gleaned off the * - There seems to be less info on it, only one device gleaned off the
* Windows driver, maybe only one is affected. More info would be greatly * Windows driver, maybe only one is affected. More info would be greatly
@ -621,9 +621,9 @@ static void sil_dev_config(struct ata_device *dev)
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
for (n = 0; sil_blacklist[n].product; n++) for (n = 0; sil_quirks[n].product; n++)
if (!strcmp(sil_blacklist[n].product, model_num)) { if (!strcmp(sil_quirks[n].product, model_num)) {
quirks = sil_blacklist[n].quirk; quirks = sil_quirks[n].quirk;
break; break;
} }

View file

@ -103,7 +103,8 @@ static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,
{ {
struct bus_attribute *bus_attr = to_bus_attr(attr); struct bus_attribute *bus_attr = to_bus_attr(attr);
struct subsys_private *subsys_priv = to_subsys_private(kobj); struct subsys_private *subsys_priv = to_subsys_private(kobj);
ssize_t ret = 0; /* return -EIO for reading a bus attribute without show() */
ssize_t ret = -EIO;
if (bus_attr->show) if (bus_attr->show)
ret = bus_attr->show(subsys_priv->bus, buf); ret = bus_attr->show(subsys_priv->bus, buf);
@ -115,7 +116,8 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,
{ {
struct bus_attribute *bus_attr = to_bus_attr(attr); struct bus_attribute *bus_attr = to_bus_attr(attr);
struct subsys_private *subsys_priv = to_subsys_private(kobj); struct subsys_private *subsys_priv = to_subsys_private(kobj);
ssize_t ret = 0; /* return -EIO for writing a bus attribute without store() */
ssize_t ret = -EIO;
if (bus_attr->store) if (bus_attr->store)
ret = bus_attr->store(subsys_priv->bus, buf, count); ret = bus_attr->store(subsys_priv->bus, buf, count);

View file

@ -25,7 +25,6 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
@ -1844,7 +1843,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env) struct kobj_uevent_env *env)
{ {
struct device *dev = kobj_to_dev(kobj); struct device *dev = kobj_to_dev(kobj);
struct device_driver *driver;
int retval = 0; int retval = 0;
/* add device node properties if present */ /* add device node properties if present */
@ -1873,12 +1871,8 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
if (dev->type && dev->type->name) if (dev->type && dev->type->name)
add_uevent_var(env, "DEVTYPE=%s", dev->type->name); add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
/* Synchronize with module_remove_driver() */ if (dev->driver)
rcu_read_lock(); add_uevent_var(env, "DRIVER=%s", dev->driver->name);
driver = READ_ONCE(dev->driver);
if (driver)
add_uevent_var(env, "DRIVER=%s", driver->name);
rcu_read_unlock();
/* Add common DT information about the device */ /* Add common DT information about the device */
of_device_uevent(dev, env); of_device_uevent(dev, env);
@ -1948,8 +1942,11 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
if (!env) if (!env)
return -ENOMEM; return -ENOMEM;
/* Synchronize with really_probe() */
device_lock(dev);
/* let the kset specific function add its keys */ /* let the kset specific function add its keys */
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
device_unlock(dev);
if (retval) if (retval)
goto out; goto out;

View file

@ -755,6 +755,26 @@ static void fw_abort_batch_reqs(struct firmware *fw)
mutex_unlock(&fw_lock); mutex_unlock(&fw_lock);
} }
/*
* Reject firmware file names with ".." path components.
* There are drivers that construct firmware file names from device-supplied
* strings, and we don't want some device to be able to tell us "I would like to
* be sent my firmware from ../../../etc/shadow, please".
*
* Search for ".." surrounded by either '/' or start/end of string.
*
* This intentionally only looks at the firmware name, not at the firmware base
* directory or at symlink contents.
*/
static bool name_contains_dotdot(const char *name)
{
size_t name_len = strlen(name);
return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 ||
strstr(name, "/../") != NULL ||
(name_len >= 3 && strcmp(name+name_len-3, "/..") == 0);
}
/* called from request_firmware() and request_firmware_work_func() */ /* called from request_firmware() and request_firmware_work_func() */
static int static int
_request_firmware(const struct firmware **firmware_p, const char *name, _request_firmware(const struct firmware **firmware_p, const char *name,
@ -774,6 +794,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
goto out; goto out;
} }
if (name_contains_dotdot(name)) {
dev_warn(device,
"Firmware load for '%s' refused, path contains '..' component\n",
name);
ret = -EINVAL;
goto out;
}
ret = _request_firmware_prepare(&fw, name, device, buf, size, ret = _request_firmware_prepare(&fw, name, device, buf, size,
opt_flags); opt_flags);
if (ret <= 0) /* error or already assigned */ if (ret <= 0) /* error or already assigned */
@ -835,6 +863,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
* @name will be used as $FIRMWARE in the uevent environment and * @name will be used as $FIRMWARE in the uevent environment and
* should be distinctive enough not to be confused with any other * should be distinctive enough not to be confused with any other
* firmware image for this or any other device. * firmware image for this or any other device.
* It must not contain any ".." path components - "foo/bar..bin" is
* allowed, but "foo/../bar.bin" is not.
* *
* Caller must hold the reference count of @device. * Caller must hold the reference count of @device.
* *

View file

@ -7,7 +7,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/rcupdate.h>
#include "base.h" #include "base.h"
static char *make_driver_name(struct device_driver *drv) static char *make_driver_name(struct device_driver *drv)
@ -78,9 +77,6 @@ void module_remove_driver(struct device_driver *drv)
if (!drv) if (!drv)
return; return;
/* Synchronize with dev_uevent() */
synchronize_rcu();
sysfs_remove_link(&drv->p->kobj, "module"); sysfs_remove_link(&drv->p->kobj, "module");
if (drv->owner) if (drv->owner)

View file

@ -362,6 +362,7 @@ ata_rw_frameinit(struct frame *f)
} }
ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
} }
@ -402,6 +403,8 @@ aoecmd_ata_rw(struct aoedev *d)
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
aoenet_xmit(&queue); aoenet_xmit(&queue);
} else {
dev_put(f->t->ifp->nd);
} }
return 1; return 1;
} }
@ -484,10 +487,13 @@ resend(struct aoedev *d, struct frame *f)
memcpy(h->dst, t->addr, sizeof h->dst); memcpy(h->dst, t->addr, sizeof h->dst);
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
skb = skb_clone(skb, GFP_ATOMIC); skb = skb_clone(skb, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL) {
dev_put(t->ifp->nd);
return; return;
}
f->sent = ktime_get(); f->sent = ktime_get();
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
@ -618,6 +624,8 @@ probe(struct aoetgt *t)
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb); __skb_queue_tail(&queue, skb);
aoenet_xmit(&queue); aoenet_xmit(&queue);
} else {
dev_put(f->t->ifp->nd);
} }
} }
@ -1405,6 +1413,7 @@ aoecmd_ata_id(struct aoedev *d)
ah->cmdstat = ATA_CMD_ID_ATA; ah->cmdstat = ATA_CMD_ID_ATA;
ah->lba3 = 0xa0; ah->lba3 = 0xa0;
dev_hold(t->ifp->nd);
skb->dev = t->ifp->nd; skb->dev = t->ifp->nd;
d->rttavg = RTTAVG_INIT; d->rttavg = RTTAVG_INIT;
@ -1414,6 +1423,8 @@ aoecmd_ata_id(struct aoedev *d)
skb = skb_clone(skb, GFP_ATOMIC); skb = skb_clone(skb, GFP_ATOMIC);
if (skb) if (skb)
f->sent = ktime_get(); f->sent = ktime_get();
else
dev_put(t->ifp->nd);
return skb; return skb;
} }

View file

@ -3509,10 +3509,12 @@ void drbd_uuid_new_current(struct drbd_device *device) __must_hold(local)
void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local) void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local)
{ {
unsigned long flags; unsigned long flags;
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0)
return;
spin_lock_irqsave(&device->ldev->md.uuid_lock, flags); spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0) {
spin_unlock_irqrestore(&device->ldev->md.uuid_lock, flags);
return;
}
if (val == 0) { if (val == 0) {
drbd_uuid_move_history(device); drbd_uuid_move_history(device);
device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP]; device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP];

View file

@ -876,7 +876,7 @@ is_valid_state(struct drbd_device *device, union drbd_state ns)
ns.disk == D_OUTDATED) ns.disk == D_OUTDATED)
rv = SS_CONNECTED_OUTDATES; rv = SS_CONNECTED_OUTDATES;
else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
(nc->verify_alg[0] == 0)) (nc->verify_alg[0] == 0))
rv = SS_NO_VERIFY_ALG; rv = SS_NO_VERIFY_ALG;

View file

@ -105,13 +105,15 @@ static int btmrvl_sdio_probe_of(struct device *dev,
} else { } else {
ret = devm_request_irq(dev, cfg->irq_bt, ret = devm_request_irq(dev, cfg->irq_bt,
btmrvl_wake_irq_bt, btmrvl_wake_irq_bt,
0, "bt_wake", card); IRQF_NO_AUTOEN, "bt_wake", card);
if (ret) { if (ret) {
dev_err(dev, dev_err(dev,
"Failed to request irq_bt %d (%d)\n", "Failed to request irq_bt %d (%d)\n",
cfg->irq_bt, ret); cfg->irq_bt, ret);
} }
disable_irq(cfg->irq_bt);
/* Configure wakeup (enabled by default) */
device_init_wakeup(dev, true);
} }
} }
@ -1654,6 +1656,7 @@ static void btmrvl_sdio_remove(struct sdio_func *func)
MODULE_SHUTDOWN_REQ); MODULE_SHUTDOWN_REQ);
btmrvl_sdio_disable_host_int(card); btmrvl_sdio_disable_host_int(card);
} }
BT_DBG("unregister dev"); BT_DBG("unregister dev");
card->priv->surprise_removed = true; card->priv->surprise_removed = true;
btmrvl_sdio_unregister_dev(card); btmrvl_sdio_unregister_dev(card);
@ -1690,7 +1693,8 @@ static int btmrvl_sdio_suspend(struct device *dev)
} }
/* Enable platform specific wakeup interrupt */ /* Enable platform specific wakeup interrupt */
if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) { if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
device_may_wakeup(dev)) {
card->plt_wake_cfg->wake_by_bt = false; card->plt_wake_cfg->wake_by_bt = false;
enable_irq(card->plt_wake_cfg->irq_bt); enable_irq(card->plt_wake_cfg->irq_bt);
enable_irq_wake(card->plt_wake_cfg->irq_bt); enable_irq_wake(card->plt_wake_cfg->irq_bt);
@ -1707,7 +1711,8 @@ static int btmrvl_sdio_suspend(struct device *dev)
BT_ERR("HS not activated, suspend failed!"); BT_ERR("HS not activated, suspend failed!");
/* Disable platform specific wakeup interrupt */ /* Disable platform specific wakeup interrupt */
if (card->plt_wake_cfg && if (card->plt_wake_cfg &&
card->plt_wake_cfg->irq_bt >= 0) { card->plt_wake_cfg->irq_bt >= 0 &&
device_may_wakeup(dev)) {
disable_irq_wake(card->plt_wake_cfg->irq_bt); disable_irq_wake(card->plt_wake_cfg->irq_bt);
disable_irq(card->plt_wake_cfg->irq_bt); disable_irq(card->plt_wake_cfg->irq_bt);
} }
@ -1767,7 +1772,8 @@ static int btmrvl_sdio_resume(struct device *dev)
hci_resume_dev(hcidev); hci_resume_dev(hcidev);
/* Disable platform specific wakeup interrupt */ /* Disable platform specific wakeup interrupt */
if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) { if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
device_may_wakeup(dev)) {
disable_irq_wake(card->plt_wake_cfg->irq_bt); disable_irq_wake(card->plt_wake_cfg->irq_bt);
disable_irq(card->plt_wake_cfg->irq_bt); disable_irq(card->plt_wake_cfg->irq_bt);
if (card->plt_wake_cfg->wake_by_bt) if (card->plt_wake_cfg->wake_by_bt)

View file

@ -834,7 +834,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
if (!urb) if (!urb)
return -ENOMEM; return -ENOMEM;
size = le16_to_cpu(data->intr_ep->wMaxPacketSize); if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 &&
le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001)
/* Fake CSR devices don't seem to support sort-transter */
size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
else
/* Use maximum HCI Event size so the USB stack handles
* ZPL/short-transfer automatically.
*/
size = HCI_MAX_EVENT_SIZE;
buf = kmalloc(size, mem_flags); buf = kmalloc(size, mem_flags);
if (!buf) { if (!buf) {

View file

@ -149,7 +149,7 @@ static int mtk_rng_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, priv); dev_set_drvdata(&pdev->dev, priv);
pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT); pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev); devm_pm_runtime_enable(&pdev->dev);
dev_info(&pdev->dev, "registered RNG driver\n"); dev_info(&pdev->dev, "registered RNG driver\n");

View file

@ -48,6 +48,8 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space,
if (!ret) if (!ret)
ret = tpm2_commit_space(chip, space, buf, &len); ret = tpm2_commit_space(chip, space, buf, &len);
else
tpm2_flush_space(chip);
out_rc: out_rc:
return ret ? ret : len; return ret ? ret : len;

View file

@ -166,6 +166,9 @@ void tpm2_flush_space(struct tpm_chip *chip)
struct tpm_space *space = &chip->work_space; struct tpm_space *space = &chip->work_space;
int i; int i;
if (!space)
return;
for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++) for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
if (space->context_tbl[i] && ~space->context_tbl[i]) if (space->context_tbl[i] && ~space->context_tbl[i])
tpm2_flush_context(chip, space->context_tbl[i]); tpm2_flush_context(chip, space->context_tbl[i]);

View file

@ -2051,25 +2051,27 @@ static int virtcons_probe(struct virtio_device *vdev)
multiport = true; multiport = true;
} }
err = init_vqs(portdev);
if (err < 0) {
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
goto free_chrdev;
}
spin_lock_init(&portdev->ports_lock); spin_lock_init(&portdev->ports_lock);
INIT_LIST_HEAD(&portdev->ports); INIT_LIST_HEAD(&portdev->ports);
INIT_LIST_HEAD(&portdev->list); INIT_LIST_HEAD(&portdev->list);
virtio_device_ready(portdev->vdev);
INIT_WORK(&portdev->config_work, &config_work_handler); INIT_WORK(&portdev->config_work, &config_work_handler);
INIT_WORK(&portdev->control_work, &control_work_handler); INIT_WORK(&portdev->control_work, &control_work_handler);
if (multiport) { if (multiport) {
spin_lock_init(&portdev->c_ivq_lock); spin_lock_init(&portdev->c_ivq_lock);
spin_lock_init(&portdev->c_ovq_lock); spin_lock_init(&portdev->c_ovq_lock);
}
err = init_vqs(portdev);
if (err < 0) {
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
goto free_chrdev;
}
virtio_device_ready(portdev->vdev);
if (multiport) {
err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
if (err < 0) { if (err < 0) {
dev_err(&vdev->dev, dev_err(&vdev->dev,

View file

@ -112,7 +112,7 @@ static void bcm53573_ilp_init(struct device_node *np)
goto err_free_ilp; goto err_free_ilp;
} }
ilp->regmap = syscon_node_to_regmap(of_get_parent(np)); ilp->regmap = syscon_node_to_regmap(np->parent);
if (IS_ERR(ilp->regmap)) { if (IS_ERR(ilp->regmap)) {
err = PTR_ERR(ilp->regmap); err = PTR_ERR(ilp->regmap);
goto err_free_ilp; goto err_free_ilp;

View file

@ -269,41 +269,36 @@ static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable)
{ {
struct tcs_cmd cmd = { 0 }; struct tcs_cmd cmd = { 0 };
u32 cmd_state; u32 cmd_state;
int ret; int ret = 0;
mutex_lock(&rpmh_clk_lock); mutex_lock(&rpmh_clk_lock);
cmd_state = 0;
if (enable) { if (enable) {
cmd_state = 1; cmd_state = 1;
if (c->aggr_state) if (c->aggr_state)
cmd_state = c->aggr_state; cmd_state = c->aggr_state;
} else {
cmd_state = 0;
} }
if (cmd_state > BCM_TCS_CMD_VOTE_MASK) if (cmd_state > BCM_TCS_CMD_VOTE_MASK)
cmd_state = BCM_TCS_CMD_VOTE_MASK; cmd_state = BCM_TCS_CMD_VOTE_MASK;
if (c->last_sent_aggr_state == cmd_state) { if (c->last_sent_aggr_state != cmd_state) {
mutex_unlock(&rpmh_clk_lock); cmd.addr = c->res_addr;
return 0; cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state);
ret = clk_rpmh_send(c, RPMH_ACTIVE_ONLY_STATE, &cmd, enable);
if (ret) {
dev_err(c->dev, "set active state of %s failed: (%d)\n",
c->res_name, ret);
} else {
c->last_sent_aggr_state = cmd_state;
}
} }
cmd.addr = c->res_addr;
cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state);
ret = clk_rpmh_send(c, RPMH_ACTIVE_ONLY_STATE, &cmd, enable);
if (ret) {
dev_err(c->dev, "set active state of %s failed: (%d)\n",
c->res_name, ret);
mutex_unlock(&rpmh_clk_lock);
return ret;
}
c->last_sent_aggr_state = cmd_state;
mutex_unlock(&rpmh_clk_lock); mutex_unlock(&rpmh_clk_lock);
return 0; return ret;
} }
static int clk_rpmh_bcm_prepare(struct clk_hw *hw) static int clk_rpmh_bcm_prepare(struct clk_hw *hw)

View file

@ -408,7 +408,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
FACTOR(0, "xin12m", "xin24m", 0, 1, 2), FACTOR(0, "xin12m", "xin24m", 0, 1, 2),

View file

@ -439,12 +439,13 @@ void __init rockchip_clk_register_branches(
struct rockchip_clk_branch *list, struct rockchip_clk_branch *list,
unsigned int nr_clk) unsigned int nr_clk)
{ {
struct clk *clk = NULL; struct clk *clk;
unsigned int idx; unsigned int idx;
unsigned long flags; unsigned long flags;
for (idx = 0; idx < nr_clk; idx++, list++) { for (idx = 0; idx < nr_clk; idx++, list++) {
flags = list->flags; flags = list->flags;
clk = NULL;
/* catch simple muxes */ /* catch simple muxes */
switch (list->branch_type) { switch (list->branch_type) {

View file

@ -257,6 +257,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
} }
clk = of_clk_get_from_provider(&clkspec); clk = of_clk_get_from_provider(&clkspec);
of_node_put(clkspec.np);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("%s: failed to get atl clock %d from provider\n", pr_err("%s: failed to get atl clock %d from provider\n",
__func__, i); __func__, i);

View file

@ -233,6 +233,7 @@ static int __init msm_dt_timer_init(struct device_node *np)
} }
if (of_property_read_u32(np, "clock-frequency", &freq)) { if (of_property_read_u32(np, "clock-frequency", &freq)) {
iounmap(cpu0_base);
pr_err("Unknown frequency\n"); pr_err("Unknown frequency\n");
return -EINVAL; return -EINVAL;
} }
@ -243,7 +244,11 @@ static int __init msm_dt_timer_init(struct device_node *np)
freq /= 4; freq /= 4;
writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
return msm_timer_init(freq, 32, irq, !!percpu_offset); ret = msm_timer_init(freq, 32, irq, !!percpu_offset);
if (ret)
iounmap(cpu0_base);
return ret;
} }
TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);

View file

@ -24,12 +24,6 @@
#define MSG_RING BIT(1) #define MSG_RING BIT(1)
#define TAG_SZ 32 #define TAG_SZ 32
static inline struct tegra_bpmp *
mbox_client_to_bpmp(struct mbox_client *client)
{
return container_of(client, struct tegra_bpmp, mbox.client);
}
static inline const struct tegra_bpmp_ops * static inline const struct tegra_bpmp_ops *
channel_to_ops(struct tegra_bpmp_channel *channel) channel_to_ops(struct tegra_bpmp_channel *channel)
{ {

View file

@ -404,6 +404,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
gpio->dcache[GPIO_BANK(offset)] = reg; gpio->dcache[GPIO_BANK(offset)] = reg;
iowrite32(reg, addr); iowrite32(reg, addr);
/* Flush write */
ioread32(addr);
} }
static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
@ -1157,7 +1159,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
if (!gpio_id) if (!gpio_id)
return -EINVAL; return -EINVAL;
gpio->clk = of_clk_get(pdev->dev.of_node, 0); gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(gpio->clk)) { if (IS_ERR(gpio->clk)) {
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"Failed to get clock from devicetree, debouncing disabled\n"); "Failed to get clock from devicetree, debouncing disabled\n");

View file

@ -300,7 +300,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
* serve as EDMA event triggers. * serve as EDMA event triggers.
*/ */
static void gpio_irq_disable(struct irq_data *d) static void gpio_irq_mask(struct irq_data *d)
{ {
struct davinci_gpio_regs __iomem *g = irq2regs(d); struct davinci_gpio_regs __iomem *g = irq2regs(d);
uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
@ -309,7 +309,7 @@ static void gpio_irq_disable(struct irq_data *d)
writel_relaxed(mask, &g->clr_rising); writel_relaxed(mask, &g->clr_rising);
} }
static void gpio_irq_enable(struct irq_data *d) static void gpio_irq_unmask(struct irq_data *d)
{ {
struct davinci_gpio_regs __iomem *g = irq2regs(d); struct davinci_gpio_regs __iomem *g = irq2regs(d);
uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
@ -335,8 +335,8 @@ static int gpio_irq_type(struct irq_data *d, unsigned trigger)
static struct irq_chip gpio_irqchip = { static struct irq_chip gpio_irqchip = {
.name = "GPIO", .name = "GPIO",
.irq_enable = gpio_irq_enable, .irq_unmask = gpio_irq_unmask,
.irq_disable = gpio_irq_disable, .irq_mask = gpio_irq_mask,
.irq_set_type = gpio_irq_type, .irq_set_type = gpio_irq_type,
.flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE, .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
}; };

View file

@ -4,6 +4,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/nospec.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/device.h> #include <linux/device.h>
@ -147,7 +148,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
if (hwnum >= gdev->ngpio) if (hwnum >= gdev->ngpio)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
return &gdev->descs[hwnum]; return &gdev->descs[array_index_nospec(hwnum, gdev->ngpio)];
} }
/** /**

View file

@ -85,6 +85,7 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
struct acpi_buffer *params) struct acpi_buffer *params)
{ {
acpi_status status; acpi_status status;
union acpi_object *obj;
union acpi_object atif_arg_elements[2]; union acpi_object atif_arg_elements[2];
struct acpi_object_list atif_arg; struct acpi_object_list atif_arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@ -107,16 +108,24 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
status = acpi_evaluate_object(atif->handle, NULL, &atif_arg, status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
&buffer); &buffer);
obj = (union acpi_object *)buffer.pointer;
/* Fail only if calling the method fails and ATIF is supported */ /* Fail if calling the method fails */
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status)) {
DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
acpi_format_exception(status)); acpi_format_exception(status));
kfree(buffer.pointer); kfree(obj);
return NULL; return NULL;
} }
return buffer.pointer; if (obj->type != ACPI_TYPE_BUFFER) {
DRM_DEBUG_DRIVER("bad object returned from ATIF: %d\n",
obj->type);
kfree(obj);
return NULL;
}
return obj;
} }
/** /**

View file

@ -395,7 +395,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
if (!adev->smc_rreg) if (!adev->smc_rreg)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (size & 0x3 || *pos & 0x3) if (size > 4096 || size & 0x3 || *pos & 0x3)
return -EINVAL; return -EINVAL;
while (size) { while (size) {

View file

@ -2098,23 +2098,29 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
if (fake_edid_record->ucFakeEDIDLength) { if (fake_edid_record->ucFakeEDIDLength) {
struct edid *edid; struct edid *edid;
int edid_size = int edid_size;
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
edid = kmalloc(edid_size, GFP_KERNEL);
if (edid) {
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
fake_edid_record->ucFakeEDIDLength);
if (fake_edid_record->ucFakeEDIDLength == 128)
edid_size = fake_edid_record->ucFakeEDIDLength;
else
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
edid_size, GFP_KERNEL);
if (edid) {
if (drm_edid_is_valid(edid)) { if (drm_edid_is_valid(edid)) {
adev->mode_info.bios_hardcoded_edid = edid; adev->mode_info.bios_hardcoded_edid = edid;
adev->mode_info.bios_hardcoded_edid_size = edid_size; adev->mode_info.bios_hardcoded_edid_size = edid_size;
} else } else {
kfree(edid); kfree(edid);
}
} }
record += struct_size(fake_edid_record,
ucFakeEDIDString,
edid_size);
} else {
/* empty fake edid record must be 3 bytes long */
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
} }
record += fake_edid_record->ucFakeEDIDLength ?
fake_edid_record->ucFakeEDIDLength + 2 :
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
break; break;
case LCD_PANEL_RESOLUTION_RECORD_TYPE: case LCD_PANEL_RESOLUTION_RECORD_TYPE:
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;

View file

@ -1542,6 +1542,8 @@ static bool are_stream_backends_same(
bool dc_is_stream_unchanged( bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream) struct dc_stream_state *old_stream, struct dc_stream_state *stream)
{ {
if (!old_stream || !stream)
return false;
if (!are_stream_backends_same(old_stream, stream)) if (!are_stream_backends_same(old_stream, stream))
return false; return false;

View file

@ -551,6 +551,8 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
i += increment) { i += increment) {
if (j == hw_points - 1) if (j == hw_points - 1)
break; break;
if (i >= TRANSFER_FUNC_POINTS)
return false;
rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].red = output_tf->tf_pts.red[i];
rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i];
rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i];

View file

@ -78,7 +78,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
{ {
unsigned int ret_val = 0; unsigned int ret_val = 1;
if (source_format == dm_444_16) { if (source_format == dm_444_16) {
if (!is_chroma) if (!is_chroma)

View file

@ -54,7 +54,7 @@ static void calculate_ttu_cursor(
static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
{ {
unsigned int ret_val = 0; unsigned int ret_val = 1;
if (source_format == dm_444_16) { if (source_format == dm_444_16) {
if (!is_chroma) if (!is_chroma)

View file

@ -131,7 +131,7 @@ static unsigned int calc_v_total_from_refresh(
v_total = div64_u64(div64_u64(((unsigned long long)( v_total = div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)), frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total), 1000000); stream->timing.h_total) + 500000, 1000000);
/* v_total cannot be less than nominal */ /* v_total cannot be less than nominal */
if (v_total < stream->timing.v_total) { if (v_total < stream->timing.v_total) {

View file

@ -4107,7 +4107,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
{ {
UCHAR ucRecordType; UCHAR ucRecordType;
UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128 UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
} ATOM_FAKE_EDID_PATCH_RECORD; } ATOM_FAKE_EDID_PATCH_RECORD;
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD

View file

@ -148,6 +148,7 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
struct drm_plane *plane; struct drm_plane *plane;
struct list_head zorder_list; struct list_head zorder_list;
int order = 0, err; int order = 0, err;
u32 slave_zpos = 0;
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
@ -187,10 +188,13 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
plane_st->zpos, plane_st->normalized_zpos); plane_st->zpos, plane_st->normalized_zpos);
/* calculate max slave zorder */ /* calculate max slave zorder */
if (has_bit(drm_plane_index(plane), kcrtc->slave_planes)) if (has_bit(drm_plane_index(plane), kcrtc->slave_planes)) {
slave_zpos = plane_st->normalized_zpos;
if (to_kplane_st(plane_st)->layer_split)
slave_zpos++;
kcrtc_st->max_slave_zorder = kcrtc_st->max_slave_zorder =
max(plane_st->normalized_zpos, max(slave_zpos, kcrtc_st->max_slave_zorder);
kcrtc_st->max_slave_zorder); }
} }
crtc_st->zpos_changed = true; crtc_st->zpos_changed = true;

View file

@ -582,7 +582,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
&state->fb_damage_clips, &state->fb_damage_clips,
val, val,
-1, -1,
sizeof(struct drm_rect), sizeof(struct drm_mode_rect),
&replaced); &replaced);
return ret; return ret;
} else if (plane->funcs->atomic_set_property) { } else if (plane->funcs->atomic_set_property) {

View file

@ -727,6 +727,7 @@ out:
connector_set = NULL; connector_set = NULL;
fb = NULL; fb = NULL;
mode = NULL; mode = NULL;
num_connectors = 0;
DRM_MODESET_LOCK_ALL_END(ctx, ret); DRM_MODESET_LOCK_ALL_END(ctx, ret);
mutex_unlock(&crtc->dev->mode_config.mutex); mutex_unlock(&crtc->dev->mode_config.mutex);

View file

@ -221,7 +221,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
return dsi; return dsi;
} }
device_set_node(&dsi->dev, of_fwnode_handle(info->node)); dsi->dev.of_node = info->node;
dsi->channel = info->channel; dsi->channel = info->channel;
strlcpy(dsi->name, info->type, sizeof(dsi->name)); strlcpy(dsi->name, info->type, sizeof(dsi->name));

Some files were not shown because too many files have changed in this diff Show more