Merge 6.1.105 into android14-6.1-lts

Changes in 6.1.105
	irqchip/mbigen: Fix mbigen node address layout
	platform/x86/intel/ifs: Gen2 Scan test support
	platform/x86/intel/ifs: Initialize union ifs_status to zero
	jump_label: Fix the fix, brown paper bags galore
	x86/mm: Fix pti_clone_pgtable() alignment assumption
	x86/mm: Fix pti_clone_entry_text() for i386
	sctp: Fix null-ptr-deref in reuseport_add_sock().
	net: usb: qmi_wwan: fix memory leak for not ip packets
	net: bridge: mcast: wait for previous gc cycles when removing port
	net: linkwatch: use system_unbound_wq
	Bluetooth: l2cap: always unlock channel in l2cap_conless_channel()
	Bluetooth: hci_sync: avoid dup filtering when passive scanning with adv monitor
	net: dsa: bcm_sf2: Fix a possible memory leak in bcm_sf2_mdio_register()
	l2tp: fix lockdep splat
	net: fec: Stop PPS on driver remove
	rcutorture: Fix rcu_torture_fwd_cb_cr() data race
	md: do not delete safemode_timer in mddev_suspend
	md/raid5: avoid BUG_ON() while continue reshape after reassembling
	block: change rq_integrity_vec to respect the iterator
	rcu: Fix rcu_barrier() VS post CPUHP_TEARDOWN_CPU invocation
	clocksource/drivers/sh_cmt: Address race condition for clock events
	ACPI: battery: create alarm sysfs attribute atomically
	ACPI: SBS: manage alarm sysfs attribute through psy core
	wifi: nl80211: disallow setting special AP channel widths
	net/mlx5e: SHAMPO, Fix invalid WQ linked list unlink
	selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT
	af_unix: Don't retry after unix_state_lock_nested() in unix_stream_connect().
	PCI: Add Edimax Vendor ID to pci_ids.h
	udf: prevent integer overflow in udf_bitmap_free_blocks()
	wifi: nl80211: don't give key data to userspace
	can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index erratum
	can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of mcp2518fd
	btrfs: fix bitmap leak when loading free space cache on duplicate entry
	drm/amdgpu/pm: Fix the param type of set_power_profile_mode
	drm/amdgpu/pm: Fix the null pointer dereference for smu7
	drm/amdgpu: Fix the null pointer dereference to ras_manager
	drm/amdgpu/pm: Fix the null pointer dereference in apply_state_adjust_rules
	drm/amdgpu: Add lock around VF RLCG interface
	drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr
	media: amphion: Remove lock in s_ctrl callback
	drm/amd/display: Add NULL check for 'afb' before dereferencing in amdgpu_dm_plane_handle_cursor_update
	drm/amd/display: Add null checker before passing variables
	media: uvcvideo: Ignore empty TS packets
	media: uvcvideo: Fix the bandwdith quirk on USB 3.x
	media: xc2028: avoid use-after-free in load_firmware_cb()
	ext4: fix uninitialized variable in ext4_inlinedir_to_tree
	jbd2: avoid memleak in jbd2_journal_write_metadata_buffer
	s390/sclp: Prevent release of buffer in I/O
	SUNRPC: Fix a race to wake a sync task
	bus: mhi: host: pci_generic: add support for Telit FE990 modem
	Revert "bpftool: Mount bpffs when pinmaps path not under the bpffs"
	profiling: remove profile=sleep support
	scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES
	irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to 'raw_spinlock_t'
	irqchip/loongarch-cpu: Fix return value of lpic_gsi_to_irq()
	sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime
	ext4: fix wrong unit use in ext4_mb_find_by_goal
	arm64: Add Neoverse-V2 part
	arm64: barrier: Restore spec_bar() macro
	arm64: cputype: Add Cortex-X4 definitions
	arm64: cputype: Add Neoverse-V3 definitions
	arm64: errata: Add workaround for Arm errata 3194386 and 3312417
	arm64: cputype: Add Cortex-X3 definitions
	arm64: cputype: Add Cortex-A720 definitions
	arm64: cputype: Add Cortex-X925 definitions
	arm64: errata: Unify speculative SSBS errata logic
	arm64: errata: Expand speculative SSBS workaround
	arm64: cputype: Add Cortex-X1C definitions
	arm64: cputype: Add Cortex-A725 definitions
	arm64: errata: Expand speculative SSBS workaround (again)
	i2c: smbus: Improve handling of stuck alerts
	ASoC: codecs: wcd938x-sdw: Correct Soundwire ports mask
	ASoC: codecs: wsa881x: Correct Soundwire ports mask
	ASoC: codecs: wsa883x: parse port-mapping information
	ASoC: codecs: wsa883x: Correct Soundwire ports mask
	spi: spidev: Add missing spi_device_id for bh2228fv
	ASoC: SOF: Remove libraries from topology lookups
	i2c: smbus: Send alert notifications to all devices if source not found
	bpf: kprobe: remove unused declaring of bpf_kprobe_override
	kprobes: Fix to check symbol prefixes correctly
	i2c: qcom-geni: add desc struct to prepare support for I2C Master Hub variant
	i2c: qcom-geni: Add missing clk_disable_unprepare in geni_i2c_runtime_resume
	i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume
	spi: spi-fsl-lpspi: Fix scldiv calculation
	ALSA: usb-audio: Re-add ScratchAmp quirk entries
	ASoC: meson: axg-fifo: fix irq scheduling issue with PREEMPT_RT
	drm/amd/display: Skip Recompute DSC Params if no Stream on Link
	drm/client: fix null pointer dereference in drm_client_modeset_probe
	ALSA: line6: Fix racy access to midibuf
	ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list
	ALSA: hda/realtek: Add Framework Laptop 13 (Intel Core Ultra) to quirks
	ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4
	usb: vhci-hcd: Do not drop references before new references are gained
	USB: serial: debug: do not echo input by default
	usb: gadget: core: Check for unset descriptor
	usb: gadget: u_serial: Set start_delayed during suspend
	usb: gadget: u_audio: Check return codes from usb_ep_enable and config_ep_by_speed.
	scsi: mpi3mr: Avoid IOMMU page faults on REPORT ZONES
	scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic
	tick/broadcast: Move per CPU pointer access into the atomic section
	vhost-vdpa: switch to use vmf_insert_pfn() in the fault handler
	ntp: Clamp maxerror and esterror to operating range
	torture: Enable clocksource watchdog with "tsc=watchdog"
	clocksource: Scale the watchdog read retries automatically
	clocksource: Fix brown-bag boolean thinko in cs_watchdog_read()
	driver core: Fix uevent_show() vs driver detach race
	ntp: Safeguard against time_constant overflow
	timekeeping: Fix bogus clock_was_set() invocation in do_adjtimex()
	serial: core: check uartclk for zero to avoid divide by zero
	ASoC: amd: yc: Add quirk entry for OMEN by HP Gaming Laptop 16-n0xxx
	kcov: properly check for softirq context
	irqchip/xilinx: Fix shift out of bounds
	genirq/irqdesc: Honor caller provided affinity in alloc_desc()
	power: supply: axp288_charger: Fix constant_charge_voltage writes
	power: supply: axp288_charger: Round constant_charge_voltage writes down
	tracing: Fix overflow in get_free_elt()
	padata: Fix possible divide-by-0 panic in padata_mt_helper()
	smb3: fix setting SecurityFlags when encryption is required
	btrfs: avoid using fixed char array size for tree names
	x86/mtrr: Check if fixed MTRRs exist before saving them
	sched/smt: Introduce sched_smt_present_inc/dec() helper
	sched/smt: Fix unbalance sched_smt_present dec/inc
	drm/bridge: analogix_dp: properly handle zero sized AUX transactions
	drm/dp_mst: Skip CSN if topology probing is not done yet
	drm/lima: Mark simple_ondemand governor as softdep
	drm/mgag200: Set DDC timeout in milliseconds
	drm/mgag200: Bind I2C lifetime to DRM device
	mptcp: mib: count MPJ with backup flag
	mptcp: export local_address
	mptcp: pm: fix backup support in signal endpoints
	selftests: mptcp: join: validate backup in MPJ
	selftests: mptcp: join: check backup support in signal endp
	mptcp: pm: deny endp with signal + subflow + port
	block: use the right type for stub rq_integrity_vec()
	Revert "drm/amd/display: Add NULL check for 'afb' before dereferencing in amdgpu_dm_plane_handle_cursor_update"
	mm: huge_memory: use !CONFIG_64BIT to relax huge page alignment on 32 bit machines
	btrfs: fix corruption after buffer fault in during direct IO append write
	ipv6: fix source address selection with route leak
	tools headers arm64: Sync arm64's cputype.h with the kernel sources
	mm/hugetlb: fix potential race in __update_and_free_hugetlb_folio()
	block: Call .limit_depth() after .hctx has been set
	block/mq-deadline: Fix the tag reservation code
	xfs: fix log recovery buffer allocation for the legacy h_size fixup
	netfilter: nf_tables: bail out if stateful expression provides no .clone
	netfilter: nf_tables: allow clone callbacks to sleep
	netfilter: nf_tables: prefer nft_chain_validate
	i2c: qcom-geni: fix missing clk_disable_unprepare() and geni_se_resources_off()
	btrfs: fix double inode unlock for direct IO sync writes
	Linux 6.1.105

Change-Id: I63c645dee46d43a3f1b166622e1858afba6ae3a8
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-09-10 11:18:17 +00:00
153 changed files with 1347 additions and 699 deletions

View File

@@ -741,7 +741,7 @@ SecurityFlags Flags which control security negotiation and
may use NTLMSSP 0x00080 may use NTLMSSP 0x00080
must use NTLMSSP 0x80080 must use NTLMSSP 0x80080
seal (packet encryption) 0x00040 seal (packet encryption) 0x00040
must seal (not implemented yet) 0x40040 must seal 0x40040
cifsFYI If set to non-zero value, additional debug information cifsFYI If set to non-zero value, additional debug information
will be logged to the system error log. This field will be logged to the system error log. This field

View File

@@ -637,12 +637,6 @@
loops can be debugged more effectively on production loops can be debugged more effectively on production
systems. systems.
clocksource.max_cswd_read_retries= [KNL]
Number of clocksource_watchdog() retries due to
external delays before the clock will be marked
unstable. Defaults to two retries, that is,
three attempts to read the clock under test.
clocksource.verify_n_cpus= [KNL] clocksource.verify_n_cpus= [KNL]
Limit the number of CPUs checked for clocksources Limit the number of CPUs checked for clocksources
marked with CLOCK_SOURCE_VERIFY_PERCPU that marked with CLOCK_SOURCE_VERIFY_PERCPU that
@@ -4604,11 +4598,9 @@
profile= [KNL] Enable kernel profiling via /proc/profile profile= [KNL] Enable kernel profiling via /proc/profile
Format: [<profiletype>,]<number> Format: [<profiletype>,]<number>
Param: <profiletype>: "schedule", "sleep", or "kvm" Param: <profiletype>: "schedule" or "kvm"
[defaults to kernel profiling] [defaults to kernel profiling]
Param: "schedule" - profile schedule points. Param: "schedule" - profile schedule points.
Param: "sleep" - profile D-state sleeping (millisecs).
Requires CONFIG_SCHEDSTATS
Param: "kvm" - profile VM exits. Param: "kvm" - profile VM exits.
Param: <number> - step/bucket size as a power of 2 for Param: <number> - step/bucket size as a power of 2 for
statistical time based profiling. statistical time based profiling.

View File

@@ -104,8 +104,16 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 | | ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A510 | #2077057 | ARM64_ERRATUM_2077057 | | ARM | Cortex-A510 | #2077057 | ARM64_ERRATUM_2077057 |
@@ -120,22 +128,50 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 | | ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 | | ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 | | ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1349291 | N/A | | ARM | Neoverse-N1 | #1349291 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 | | ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 | | ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #2253138 | ARM64_ERRATUM_2253138 | | ARM | Neoverse-N2 | #2253138 | ARM64_ERRATUM_2253138 |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-500 | #841119,826419 | N/A | | ARM | MMU-500 | #841119,826419 | N/A |
+----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU-600 | #1076982,1209401| N/A | | ARM | MMU-600 | #1076982,1209401| N/A |

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 6 VERSION = 6
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 104 SUBLEVEL = 105
EXTRAVERSION = EXTRAVERSION =
NAME = Curry Ramen NAME = Curry Ramen

View File

@@ -987,6 +987,44 @@ config ARM64_ERRATUM_2966298
If unsure, say Y. If unsure, say Y.
config ARM64_ERRATUM_3194386
bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing"
default y
help
This option adds the workaround for the following errata:
* ARM Cortex-A76 erratum 3324349
* ARM Cortex-A77 erratum 3324348
* ARM Cortex-A78 erratum 3324344
* ARM Cortex-A78C erratum 3324346
* ARM Cortex-A78C erratum 3324347
* ARM Cortex-A710 erratam 3324338
* ARM Cortex-A720 erratum 3456091
* ARM Cortex-A725 erratum 3456106
* ARM Cortex-X1 erratum 3324344
* ARM Cortex-X1C erratum 3324346
* ARM Cortex-X2 erratum 3324338
* ARM Cortex-X3 erratum 3324335
* ARM Cortex-X4 erratum 3194386
* ARM Cortex-X925 erratum 3324334
* ARM Neoverse-N1 erratum 3324349
* ARM Neoverse N2 erratum 3324339
* ARM Neoverse-V1 erratum 3324341
* ARM Neoverse V2 erratum 3324336
* ARM Neoverse-V3 erratum 3312417
On affected cores "MSR SSBS, #0" instructions may not affect
subsequent speculative instructions, which may permit unexepected
speculative store bypassing.
Work around this problem by placing a Speculation Barrier (SB) or
Instruction Synchronization Barrier (ISB) after kernel changes to
SSBS. The presence of the SSBS special-purpose register is hidden
from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace
will use the PR_SPEC_STORE_BYPASS prctl to change SSBS.
If unsure, say Y.
config CAVIUM_ERRATUM_22375 config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313" bool "Cavium erratum 22375, 24313"
default y default y

View File

@@ -38,6 +38,10 @@
*/ */
#define dgh() asm volatile("hint #6" : : : "memory") #define dgh() asm volatile("hint #6" : : : "memory")
#define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \
SB_BARRIER_INSN"nop\n", \
ARM64_HAS_SB))
#ifdef CONFIG_ARM64_PSEUDO_NMI #ifdef CONFIG_ARM64_PSEUDO_NMI
#define pmr_sync() \ #define pmr_sync() \
do { \ do { \

View File

@@ -85,6 +85,14 @@
#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
#define ARM_CPU_PART_CORTEX_X1C 0xD4C
#define ARM_CPU_PART_CORTEX_X3 0xD4E
#define ARM_CPU_PART_NEOVERSE_V2 0xD4F
#define ARM_CPU_PART_CORTEX_A720 0xD81
#define ARM_CPU_PART_CORTEX_X4 0xD82
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define ARM_CPU_PART_CORTEX_X925 0xD85
#define ARM_CPU_PART_CORTEX_A725 0xD87
#define APM_CPU_PART_XGENE 0x000 #define APM_CPU_PART_XGENE 0x000
#define APM_CPU_VAR_POTENZA 0x00 #define APM_CPU_VAR_POTENZA 0x00
@@ -151,6 +159,14 @@
#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)
#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)
#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)
#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)
#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
#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_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
#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

@@ -435,6 +435,30 @@ static struct midr_range broken_aarch32_aes[] = {
}; };
#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */ #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
#ifdef CONFIG_ARM64_ERRATUM_3194386
static const struct midr_range erratum_spec_ssbs_list[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
{}
};
#endif
const struct arm64_cpu_capabilities arm64_errata[] = { const struct arm64_cpu_capabilities arm64_errata[] = {
#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
{ {
@@ -726,6 +750,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.cpu_enable = cpu_clear_bf16_from_user_emulation, .cpu_enable = cpu_clear_bf16_from_user_emulation,
}, },
#endif #endif
#ifdef CONFIG_ARM64_ERRATUM_3194386
{
.desc = "SSBS not fully self-synchronizing",
.capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
},
#endif
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
{ {
.desc = "ARM erratum 2966298", .desc = "ARM erratum 2966298",

View File

@@ -2085,6 +2085,17 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
} }
#endif /* CONFIG_ARM64_MTE */ #endif /* CONFIG_ARM64_MTE */
static void user_feature_fixup(void)
{
if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) {
struct arm64_ftr_reg *regp;
regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1);
if (regp)
regp->user_mask &= ~ID_AA64PFR1_EL1_SSBS_MASK;
}
}
static void elf_hwcap_fixup(void) static void elf_hwcap_fixup(void)
{ {
#ifdef CONFIG_ARM64_ERRATUM_1742098 #ifdef CONFIG_ARM64_ERRATUM_1742098
@@ -3285,6 +3296,7 @@ void __init setup_cpu_features(void)
u32 cwg; u32 cwg;
setup_system_capabilities(); setup_system_capabilities();
user_feature_fixup();
setup_elf_hwcaps(arm64_elf_hwcaps); setup_elf_hwcaps(arm64_elf_hwcaps);
if (system_supports_32bit_el0()) { if (system_supports_32bit_el0()) {

View File

@@ -570,6 +570,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void)
/* SCTLR_EL1.DSSBS was initialised to 0 during boot */ /* SCTLR_EL1.DSSBS was initialised to 0 during boot */
set_pstate_ssbs(0); set_pstate_ssbs(0);
/*
* SSBS is self-synchronizing and is intended to affect subsequent
* speculative instructions, but some CPUs can speculate with a stale
* value of SSBS.
*
* Mitigate this with an unconditional speculation barrier, as CPUs
* could mis-speculate branches and bypass a conditional barrier.
*/
if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386))
spec_bar();
return SPECTRE_MITIGATED; return SPECTRE_MITIGATED;
} }

View File

@@ -86,6 +86,7 @@ WORKAROUND_NXP_ERR050104
WORKAROUND_QCOM_FALKOR_E1003 WORKAROUND_QCOM_FALKOR_E1003
WORKAROUND_REPEAT_TLBI WORKAROUND_REPEAT_TLBI
WORKAROUND_SPECULATIVE_AT WORKAROUND_SPECULATIVE_AT
WORKAROUND_SPECULATIVE_SSBS
WORKAROUND_SPECULATIVE_UNPRIV_LOAD WORKAROUND_SPECULATIVE_UNPRIV_LOAD
ANDROID_KABI_RESERVE_02 ANDROID_KABI_RESERVE_02
ANDROID_KABI_RESERVE_03 ANDROID_KABI_RESERVE_03

View File

@@ -816,7 +816,7 @@ void mtrr_save_state(void)
{ {
int first_cpu; int first_cpu;
if (!mtrr_enabled()) if (!mtrr_enabled() || !mtrr_state.have_fixed)
return; return;
first_cpu = cpumask_first(cpu_online_mask); first_cpu = cpumask_first(cpu_online_mask);

View File

@@ -374,14 +374,14 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
*/ */
*target_pmd = *pmd; *target_pmd = *pmd;
addr += PMD_SIZE; addr = round_up(addr + 1, PMD_SIZE);
} else if (level == PTI_CLONE_PTE) { } else if (level == PTI_CLONE_PTE) {
/* Walk the page-table down to the pte level */ /* Walk the page-table down to the pte level */
pte = pte_offset_kernel(pmd, addr); pte = pte_offset_kernel(pmd, addr);
if (pte_none(*pte)) { if (pte_none(*pte)) {
addr += PAGE_SIZE; addr = round_up(addr + 1, PAGE_SIZE);
continue; continue;
} }
@@ -401,7 +401,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
/* Clone the PTE */ /* Clone the PTE */
*target_pte = *pte; *target_pte = *pte;
addr += PAGE_SIZE; addr = round_up(addr + 1, PAGE_SIZE);
} else { } else {
BUG(); BUG();
@@ -496,7 +496,7 @@ static void pti_clone_entry_text(void)
{ {
pti_clone_pgtable((unsigned long) __entry_text_start, pti_clone_pgtable((unsigned long) __entry_text_start,
(unsigned long) __entry_text_end, (unsigned long) __entry_text_end,
PTI_CLONE_PMD); PTI_LEVEL_KERNEL_IMAGE);
} }
/* /*

View File

@@ -439,6 +439,7 @@ __blk_mq_alloc_requests_batch(struct blk_mq_alloc_data *data,
static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data) static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data)
{ {
void (*limit_depth)(blk_opf_t, struct blk_mq_alloc_data *) = NULL;
struct request_queue *q = data->q; struct request_queue *q = data->q;
u64 alloc_time_ns = 0; u64 alloc_time_ns = 0;
struct request *rq; struct request *rq;
@@ -465,7 +466,7 @@ static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data)
!blk_op_is_passthrough(data->cmd_flags) && !blk_op_is_passthrough(data->cmd_flags) &&
e->type->ops.limit_depth && e->type->ops.limit_depth &&
!(data->flags & BLK_MQ_REQ_RESERVED)) !(data->flags & BLK_MQ_REQ_RESERVED))
e->type->ops.limit_depth(data->cmd_flags, data); limit_depth = e->type->ops.limit_depth;
} }
retry: retry:
@@ -477,6 +478,9 @@ retry:
if (data->flags & BLK_MQ_REQ_RESERVED) if (data->flags & BLK_MQ_REQ_RESERVED)
data->rq_flags |= RQF_RESV; data->rq_flags |= RQF_RESV;
if (limit_depth)
limit_depth(data->cmd_flags, data);
/* /*
* Try batched alloc if we want more than 1 tag. * Try batched alloc if we want more than 1 tag.
*/ */

View File

@@ -597,6 +597,20 @@ unlock:
return rq; return rq;
} }
/*
* 'depth' is a number in the range 1..INT_MAX representing a number of
* requests. Scale it with a factor (1 << bt->sb.shift) / q->nr_requests since
* 1..(1 << bt->sb.shift) is the range expected by sbitmap_get_shallow().
* Values larger than q->nr_requests have the same effect as q->nr_requests.
*/
static int dd_to_word_depth(struct blk_mq_hw_ctx *hctx, unsigned int qdepth)
{
struct sbitmap_queue *bt = &hctx->sched_tags->bitmap_tags;
const unsigned int nrr = hctx->queue->nr_requests;
return ((qdepth << bt->sb.shift) + nrr - 1) / nrr;
}
/* /*
* Called by __blk_mq_alloc_request(). The shallow_depth value set by this * Called by __blk_mq_alloc_request(). The shallow_depth value set by this
* function is used by __blk_mq_get_tag(). * function is used by __blk_mq_get_tag().
@@ -613,7 +627,7 @@ static void dd_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
* Throttle asynchronous requests and writes such that these requests * Throttle asynchronous requests and writes such that these requests
* do not block the allocation of synchronous requests. * do not block the allocation of synchronous requests.
*/ */
data->shallow_depth = dd->async_depth; data->shallow_depth = dd_to_word_depth(data->hctx, dd->async_depth);
} }
/* Called by blk_mq_update_nr_requests(). */ /* Called by blk_mq_update_nr_requests(). */
@@ -623,9 +637,9 @@ static void dd_depth_updated(struct blk_mq_hw_ctx *hctx)
struct deadline_data *dd = q->elevator->elevator_data; struct deadline_data *dd = q->elevator->elevator_data;
struct blk_mq_tags *tags = hctx->sched_tags; struct blk_mq_tags *tags = hctx->sched_tags;
dd->async_depth = max(1UL, 3 * q->nr_requests / 4); dd->async_depth = q->nr_requests;
sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth); sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, 1);
} }
/* Called by blk_mq_init_hctx() and blk_mq_init_sched(). */ /* Called by blk_mq_init_hctx() and blk_mq_init_sched(). */

View File

@@ -667,12 +667,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
return count; return count;
} }
static const struct device_attribute alarm_attr = { static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644}, .attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show, .show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store, .store = acpi_battery_alarm_store,
}; };
static struct attribute *acpi_battery_attrs[] = {
&alarm_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(acpi_battery);
/* /*
* The Battery Hooking API * The Battery Hooking API
* *
@@ -809,7 +815,10 @@ static void __exit battery_hook_exit(void)
static int sysfs_add_battery(struct acpi_battery *battery) static int sysfs_add_battery(struct acpi_battery *battery)
{ {
struct power_supply_config psy_cfg = { .drv_data = battery, }; struct power_supply_config psy_cfg = {
.drv_data = battery,
.attr_grp = acpi_battery_groups,
};
bool full_cap_broken = false; bool full_cap_broken = false;
if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
@@ -854,7 +863,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
return result; return result;
} }
battery_hook_add_battery(battery); battery_hook_add_battery(battery);
return device_create_file(&battery->bat->dev, &alarm_attr); return 0;
} }
static void sysfs_remove_battery(struct acpi_battery *battery) static void sysfs_remove_battery(struct acpi_battery *battery)
@@ -865,7 +874,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
return; return;
} }
battery_hook_remove_battery(battery); battery_hook_remove_battery(battery);
device_remove_file(&battery->bat->dev, &alarm_attr);
power_supply_unregister(battery->bat); power_supply_unregister(battery->bat);
battery->bat = NULL; battery->bat = NULL;
mutex_unlock(&battery->sysfs_lock); mutex_unlock(&battery->sysfs_lock);

View File

@@ -77,7 +77,6 @@ struct acpi_battery {
u16 spec; u16 spec;
u8 id; u8 id;
u8 present:1; u8 present:1;
u8 have_sysfs_alarm:1;
}; };
#define to_acpi_battery(x) power_supply_get_drvdata(x) #define to_acpi_battery(x) power_supply_get_drvdata(x)
@@ -462,12 +461,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
return count; return count;
} }
static const struct device_attribute alarm_attr = { static struct device_attribute alarm_attr = {
.attr = {.name = "alarm", .mode = 0644}, .attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show, .show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store, .store = acpi_battery_alarm_store,
}; };
static struct attribute *acpi_battery_attrs[] = {
&alarm_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(acpi_battery);
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Driver Interface Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@@ -509,7 +514,10 @@ static int acpi_battery_read(struct acpi_battery *battery)
static int acpi_battery_add(struct acpi_sbs *sbs, int id) static int acpi_battery_add(struct acpi_sbs *sbs, int id)
{ {
struct acpi_battery *battery = &sbs->battery[id]; struct acpi_battery *battery = &sbs->battery[id];
struct power_supply_config psy_cfg = { .drv_data = battery, }; struct power_supply_config psy_cfg = {
.drv_data = battery,
.attr_grp = acpi_battery_groups,
};
int result; int result;
battery->id = id; battery->id = id;
@@ -539,10 +547,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
goto end; goto end;
} }
result = device_create_file(&battery->bat->dev, &alarm_attr);
if (result)
goto end;
battery->have_sysfs_alarm = 1;
end: end:
pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n", pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
@@ -554,11 +558,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
{ {
struct acpi_battery *battery = &sbs->battery[id]; struct acpi_battery *battery = &sbs->battery[id];
if (battery->bat) { if (battery->bat)
if (battery->have_sysfs_alarm)
device_remove_file(&battery->bat->dev, &alarm_attr);
power_supply_unregister(battery->bat); power_supply_unregister(battery->bat);
}
} }
static int acpi_charger_add(struct acpi_sbs *sbs) static int acpi_charger_add(struct acpi_sbs *sbs)

View File

@@ -25,6 +25,7 @@
#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/sched/mm.h> #include <linux/sched/mm.h>
#include <linux/swiotlb.h> #include <linux/swiotlb.h>
@@ -2558,6 +2559,7 @@ static const char *dev_uevent_name(struct kobject *kobj)
static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env) static int dev_uevent(struct kobject *kobj, 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 */
@@ -2586,8 +2588,12 @@ static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env)
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);
if (dev->driver) /* Synchronize with module_remove_driver() */
add_uevent_var(env, "DRIVER=%s", dev->driver->name); rcu_read_lock();
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);
@@ -2657,11 +2663,8 @@ 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(&dev->kobj, env); retval = kset->uevent_ops->uevent(&dev->kobj, env);
device_unlock(dev);
if (retval) if (retval)
goto out; goto out;

View File

@@ -7,6 +7,7 @@
#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)
@@ -77,6 +78,9 @@ 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

@@ -553,6 +553,9 @@ static const struct pci_device_id mhi_pci_id_table[] = {
/* Telit FN990 */ /* Telit FN990 */
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010), { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),
.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info }, .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
/* Telit FE990 */
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),
.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308), { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info }, .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
{ PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */ { PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */

View File

@@ -529,6 +529,7 @@ static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
{ {
struct sh_cmt_channel *ch = dev_id; struct sh_cmt_channel *ch = dev_id;
unsigned long flags;
/* clear flags */ /* clear flags */
sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
@@ -559,6 +560,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
ch->flags &= ~FLAG_SKIPEVENT; ch->flags &= ~FLAG_SKIPEVENT;
raw_spin_lock_irqsave(&ch->lock, flags);
if (ch->flags & FLAG_REPROGRAM) { if (ch->flags & FLAG_REPROGRAM) {
ch->flags &= ~FLAG_REPROGRAM; ch->flags &= ~FLAG_REPROGRAM;
sh_cmt_clock_event_program_verify(ch, 1); sh_cmt_clock_event_program_verify(ch, 1);
@@ -571,6 +574,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
ch->flags &= ~FLAG_IRQCONTEXT; ch->flags &= ~FLAG_IRQCONTEXT;
raw_spin_unlock_irqrestore(&ch->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@@ -781,12 +786,18 @@ static int sh_cmt_clock_event_next(unsigned long delta,
struct clock_event_device *ced) struct clock_event_device *ced)
{ {
struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
unsigned long flags;
BUG_ON(!clockevent_state_oneshot(ced)); BUG_ON(!clockevent_state_oneshot(ced));
raw_spin_lock_irqsave(&ch->lock, flags);
if (likely(ch->flags & FLAG_IRQCONTEXT)) if (likely(ch->flags & FLAG_IRQCONTEXT))
ch->next_match_value = delta - 1; ch->next_match_value = delta - 1;
else else
sh_cmt_set_next(ch, delta - 1); __sh_cmt_set_next(ch, delta - 1);
raw_spin_unlock_irqrestore(&ch->lock, flags);
return 0; return 0;
} }

View File

@@ -3631,6 +3631,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
mutex_init(&adev->grbm_idx_mutex); mutex_init(&adev->grbm_idx_mutex);
mutex_init(&adev->mn_lock); mutex_init(&adev->mn_lock);
mutex_init(&adev->virt.vf_errors.lock); mutex_init(&adev->virt.vf_errors.lock);
mutex_init(&adev->virt.rlcg_reg_lock);
hash_init(adev->mn_hash); hash_init(adev->mn_hash);
mutex_init(&adev->psp.mutex); mutex_init(&adev->psp.mutex);
mutex_init(&adev->notifier_lock); mutex_init(&adev->notifier_lock);

View File

@@ -1679,12 +1679,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work)
int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev, int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev,
struct ras_dispatch_if *info) struct ras_dispatch_if *info)
{ {
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head); struct ras_manager *obj;
struct ras_ih_data *data = &obj->ih_data; struct ras_ih_data *data;
obj = amdgpu_ras_find_obj(adev, &info->head);
if (!obj) if (!obj)
return -EINVAL; return -EINVAL;
data = &obj->ih_data;
if (data->inuse == 0) if (data->inuse == 0)
return 0; return 0;

View File

@@ -956,6 +956,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2; scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3; scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
mutex_lock(&adev->virt.rlcg_reg_lock);
if (reg_access_ctrl->spare_int) if (reg_access_ctrl->spare_int)
spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int; spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
@@ -1009,6 +1012,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
} }
ret = readl(scratch_reg0); ret = readl(scratch_reg0);
mutex_unlock(&adev->virt.rlcg_reg_lock);
return ret; return ret;
} }

View File

@@ -260,6 +260,8 @@ struct amdgpu_virt {
/* the ucode id to signal the autoload */ /* the ucode id to signal the autoload */
uint32_t autoload_ucode_id; uint32_t autoload_ucode_id;
struct mutex rlcg_reg_lock;
}; };
struct amdgpu_video_codec_info; struct amdgpu_video_codec_info;

View File

@@ -2636,7 +2636,8 @@ static int dm_suspend(void *handle)
dm->cached_dc_state = dc_copy_state(dm->dc->current_state); dm->cached_dc_state = dc_copy_state(dm->dc->current_state);
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); if (dm->cached_dc_state)
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
amdgpu_dm_commit_zero_streams(dm->dc); amdgpu_dm_commit_zero_streams(dm->dc);
@@ -6388,7 +6389,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
aconnector->dc_sink = aconnector->dc_link->local_sink ? aconnector->dc_sink = aconnector->dc_link->local_sink ?
aconnector->dc_link->local_sink : aconnector->dc_link->local_sink :
aconnector->dc_em_sink; aconnector->dc_em_sink;
dc_sink_retain(aconnector->dc_sink); if (aconnector->dc_sink)
dc_sink_retain(aconnector->dc_sink);
} }
} }
@@ -7121,7 +7123,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
drm_add_modes_noedid(connector, 640, 480); drm_add_modes_noedid(connector, 640, 480);
} else { } else {
amdgpu_dm_connector_ddc_get_modes(connector, edid); amdgpu_dm_connector_ddc_get_modes(connector, edid);
amdgpu_dm_connector_add_common_modes(encoder, connector); if (encoder)
amdgpu_dm_connector_add_common_modes(encoder, connector);
amdgpu_dm_connector_add_freesync_modes(connector, edid); amdgpu_dm_connector_add_freesync_modes(connector, edid);
} }
amdgpu_dm_fbc_init(connector); amdgpu_dm_fbc_init(connector);

View File

@@ -1255,6 +1255,9 @@ static bool is_dsc_need_re_compute(
} }
} }
if (new_stream_on_link_num == 0)
return false;
/* check current_state if there stream on link but it is not in /* check current_state if there stream on link but it is not in
* new request state * new request state
*/ */

View File

@@ -928,7 +928,7 @@ static int pp_dpm_switch_power_profile(void *handle,
enum PP_SMC_POWER_PROFILE type, bool en) enum PP_SMC_POWER_PROFILE type, bool en)
{ {
struct pp_hwmgr *hwmgr = handle; struct pp_hwmgr *hwmgr = handle;
long workload; long workload[1];
uint32_t index; uint32_t index;
if (!hwmgr || !hwmgr->pm_en) if (!hwmgr || !hwmgr->pm_en)
@@ -946,12 +946,12 @@ static int pp_dpm_switch_power_profile(void *handle,
hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]);
index = fls(hwmgr->workload_mask); index = fls(hwmgr->workload_mask);
index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
workload = hwmgr->workload_setting[index]; workload[0] = hwmgr->workload_setting[index];
} else { } else {
hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]);
index = fls(hwmgr->workload_mask); index = fls(hwmgr->workload_mask);
index = index <= Workload_Policy_Max ? index - 1 : 0; index = index <= Workload_Policy_Max ? index - 1 : 0;
workload = hwmgr->workload_setting[index]; workload[0] = hwmgr->workload_setting[index];
} }
if (type == PP_SMC_POWER_PROFILE_COMPUTE && if (type == PP_SMC_POWER_PROFILE_COMPUTE &&
@@ -961,7 +961,7 @@ static int pp_dpm_switch_power_profile(void *handle,
} }
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
return 0; return 0;
} }

View File

@@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
struct pp_power_state *new_ps) struct pp_power_state *new_ps)
{ {
uint32_t index; uint32_t index;
long workload; long workload[1];
if (hwmgr->not_vf) { if (hwmgr->not_vf) {
if (!skip_display_settings) if (!skip_display_settings)
@@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
index = fls(hwmgr->workload_mask); index = fls(hwmgr->workload_mask);
index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
workload = hwmgr->workload_setting[index]; workload[0] = hwmgr->workload_setting[index];
if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode)
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
} }
return 0; return 0;

View File

@@ -2970,6 +2970,7 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr)
static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
{ {
struct amdgpu_device *adev = hwmgr->adev;
struct smu7_hwmgr *data; struct smu7_hwmgr *data;
int result = 0; int result = 0;
@@ -3006,40 +3007,37 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
/* Initalize Dynamic State Adjustment Rule Settings */ /* Initalize Dynamic State Adjustment Rule Settings */
result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr); result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr);
if (0 == result) { if (result)
struct amdgpu_device *adev = hwmgr->adev; goto fail;
data->is_tlu_enabled = false; data->is_tlu_enabled = false;
hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
SMU7_MAX_HARDWARE_POWERLEVELS; SMU7_MAX_HARDWARE_POWERLEVELS;
hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
data->pcie_gen_cap = adev->pm.pcie_gen_mask; data->pcie_gen_cap = adev->pm.pcie_gen_mask;
if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
data->pcie_spc_cap = 20; data->pcie_spc_cap = 20;
else else
data->pcie_spc_cap = 16; data->pcie_spc_cap = 16;
data->pcie_lane_cap = adev->pm.pcie_mlw_mask; data->pcie_lane_cap = adev->pm.pcie_mlw_mask;
hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */
/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
hwmgr->platform_descriptor.clockStep.engineClock = 500; hwmgr->platform_descriptor.clockStep.engineClock = 500;
hwmgr->platform_descriptor.clockStep.memoryClock = 500; hwmgr->platform_descriptor.clockStep.memoryClock = 500;
smu7_thermal_parameter_init(hwmgr); smu7_thermal_parameter_init(hwmgr);
} else {
/* Ignore return value in here, we are cleaning up a mess. */
smu7_hwmgr_backend_fini(hwmgr);
}
result = smu7_update_edc_leakage_table(hwmgr); result = smu7_update_edc_leakage_table(hwmgr);
if (result) { if (result)
smu7_hwmgr_backend_fini(hwmgr); goto fail;
return result;
}
return 0; return 0;
fail:
smu7_hwmgr_backend_fini(hwmgr);
return result;
} }
static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr) static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)
@@ -3329,8 +3327,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
const struct pp_power_state *current_ps) const struct pp_power_state *current_ps)
{ {
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
struct smu7_power_state *smu7_ps = struct smu7_power_state *smu7_ps;
cast_phw_smu7_power_state(&request_ps->hardware);
uint32_t sclk; uint32_t sclk;
uint32_t mclk; uint32_t mclk;
struct PP_Clocks minimum_clocks = {0}; struct PP_Clocks minimum_clocks = {0};
@@ -3347,6 +3344,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
uint32_t latency; uint32_t latency;
bool latency_allowed = false; bool latency_allowed = false;
smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware);
if (!smu7_ps)
return -EINVAL;
data->battery_state = (PP_StateUILabel_Battery == data->battery_state = (PP_StateUILabel_Battery ==
request_ps->classification.ui_label); request_ps->classification.ui_label);
data->mclk_ignore_signal = false; data->mclk_ignore_signal = false;

View File

@@ -1065,16 +1065,18 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
struct pp_power_state *prequest_ps, struct pp_power_state *prequest_ps,
const struct pp_power_state *pcurrent_ps) const struct pp_power_state *pcurrent_ps)
{ {
struct smu8_power_state *smu8_ps = struct smu8_power_state *smu8_ps;
cast_smu8_power_state(&prequest_ps->hardware); const struct smu8_power_state *smu8_current_ps;
const struct smu8_power_state *smu8_current_ps =
cast_const_smu8_power_state(&pcurrent_ps->hardware);
struct smu8_hwmgr *data = hwmgr->backend; struct smu8_hwmgr *data = hwmgr->backend;
struct PP_Clocks clocks = {0, 0, 0, 0}; struct PP_Clocks clocks = {0, 0, 0, 0};
bool force_high; bool force_high;
smu8_ps = cast_smu8_power_state(&prequest_ps->hardware);
smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware);
if (!smu8_ps || !smu8_current_ps)
return -EINVAL;
smu8_ps->need_dfs_bypass = true; smu8_ps->need_dfs_bypass = true;
data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);

View File

@@ -3263,8 +3263,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
const struct pp_power_state *current_ps) const struct pp_power_state *current_ps)
{ {
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
struct vega10_power_state *vega10_ps = struct vega10_power_state *vega10_ps;
cast_phw_vega10_power_state(&request_ps->hardware);
uint32_t sclk; uint32_t sclk;
uint32_t mclk; uint32_t mclk;
struct PP_Clocks minimum_clocks = {0}; struct PP_Clocks minimum_clocks = {0};
@@ -3282,6 +3281,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
uint32_t latency; uint32_t latency;
vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware);
if (!vega10_ps)
return -EINVAL;
data->battery_state = (PP_StateUILabel_Battery == data->battery_state = (PP_StateUILabel_Battery ==
request_ps->classification.ui_label); request_ps->classification.ui_label);
@@ -3419,13 +3422,17 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co
const struct vega10_power_state *vega10_ps = const struct vega10_power_state *vega10_ps =
cast_const_phw_vega10_power_state(states->pnew_state); cast_const_phw_vega10_power_state(states->pnew_state);
struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
uint32_t sclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock;
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
uint32_t mclk = vega10_ps->performance_levels uint32_t sclk, mclk;
[vega10_ps->performance_level_count - 1].mem_clock;
uint32_t i; uint32_t i;
if (vega10_ps == NULL)
return -EINVAL;
sclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock;
mclk = vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].mem_clock;
for (i = 0; i < sclk_table->count; i++) { for (i = 0; i < sclk_table->count; i++) {
if (sclk == sclk_table->dpm_levels[i].value) if (sclk == sclk_table->dpm_levels[i].value)
break; break;
@@ -3732,6 +3739,9 @@ static int vega10_generate_dpm_level_enable_mask(
cast_const_phw_vega10_power_state(states->pnew_state); cast_const_phw_vega10_power_state(states->pnew_state);
int i; int i;
if (vega10_ps == NULL)
return -EINVAL;
PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps), PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps),
"Attempt to Trim DPM States Failed!", "Attempt to Trim DPM States Failed!",
return -1); return -1);
@@ -4999,6 +5009,8 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr,
vega10_psa = cast_const_phw_vega10_power_state(pstate1); vega10_psa = cast_const_phw_vega10_power_state(pstate1);
vega10_psb = cast_const_phw_vega10_power_state(pstate2); vega10_psb = cast_const_phw_vega10_power_state(pstate2);
if (vega10_psa == NULL || vega10_psb == NULL)
return -EINVAL;
/* If the two states don't even have the same number of performance levels /* If the two states don't even have the same number of performance levels
* they cannot be the same state. * they cannot be the same state.
@@ -5132,6 +5144,8 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
return -EINVAL; return -EINVAL;
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return -EINVAL;
vega10_ps->performance_levels vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].gfx_clock = [vega10_ps->performance_level_count - 1].gfx_clock =
@@ -5183,6 +5197,8 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
return -EINVAL; return -EINVAL;
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return -EINVAL;
vega10_ps->performance_levels vega10_ps->performance_levels
[vega10_ps->performance_level_count - 1].mem_clock = [vega10_ps->performance_level_count - 1].mem_clock =
@@ -5424,6 +5440,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr)
return; return;
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return;
max_level = vega10_ps->performance_level_count - 1; max_level = vega10_ps->performance_level_count - 1;
if (vega10_ps->performance_levels[max_level].gfx_clock != if (vega10_ps->performance_levels[max_level].gfx_clock !=
@@ -5446,6 +5465,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr)
ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1)); ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1));
vega10_ps = cast_phw_vega10_power_state(&ps->hardware); vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
if (vega10_ps == NULL)
return;
max_level = vega10_ps->performance_level_count - 1; max_level = vega10_ps->performance_level_count - 1;
if (vega10_ps->performance_levels[max_level].gfx_clock != if (vega10_ps->performance_levels[max_level].gfx_clock !=
@@ -5636,6 +5658,8 @@ static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_
return -EINVAL; return -EINVAL;
vega10_ps = cast_const_phw_vega10_power_state(state); vega10_ps = cast_const_phw_vega10_power_state(state);
if (vega10_ps == NULL)
return -EINVAL;
i = index > vega10_ps->performance_level_count - 1 ? i = index > vega10_ps->performance_level_count - 1 ?
vega10_ps->performance_level_count - 1 : index; vega10_ps->performance_level_count - 1 : index;

View File

@@ -1834,7 +1834,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
{ {
int ret = 0; int ret = 0;
int index = 0; int index = 0;
long workload; long workload[1];
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
if (!skip_display_settings) { if (!skip_display_settings) {
@@ -1874,10 +1874,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
index = fls(smu->workload_mask); index = fls(smu->workload_mask);
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
workload = smu->workload_setting[index]; workload[0] = smu->workload_setting[index];
if (smu->power_profile_mode != workload) if (smu->power_profile_mode != workload[0])
smu_bump_power_profile_mode(smu, &workload, 0); smu_bump_power_profile_mode(smu, workload, 0);
} }
return ret; return ret;
@@ -1927,7 +1927,7 @@ static int smu_switch_power_profile(void *handle,
{ {
struct smu_context *smu = handle; struct smu_context *smu = handle;
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
long workload; long workload[1];
uint32_t index; uint32_t index;
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
@@ -1940,17 +1940,17 @@ static int smu_switch_power_profile(void *handle,
smu->workload_mask &= ~(1 << smu->workload_prority[type]); smu->workload_mask &= ~(1 << smu->workload_prority[type]);
index = fls(smu->workload_mask); index = fls(smu->workload_mask);
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
workload = smu->workload_setting[index]; workload[0] = smu->workload_setting[index];
} else { } else {
smu->workload_mask |= (1 << smu->workload_prority[type]); smu->workload_mask |= (1 << smu->workload_prority[type]);
index = fls(smu->workload_mask); index = fls(smu->workload_mask);
index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
workload = smu->workload_setting[index]; workload[0] = smu->workload_setting[index];
} }
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
smu_bump_power_profile_mode(smu, &workload, 0); smu_bump_power_profile_mode(smu, workload, 0);
return 0; return 0;
} }

View File

@@ -1027,7 +1027,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
u32 status_reg; u32 status_reg;
u8 *buffer = msg->buffer; u8 *buffer = msg->buffer;
unsigned int i; unsigned int i;
int num_transferred = 0;
int ret; int ret;
/* Buffer size of AUX CH is 16 bytes */ /* Buffer size of AUX CH is 16 bytes */
@@ -1079,7 +1078,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
reg = buffer[i]; reg = buffer[i];
writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
4 * i); 4 * i);
num_transferred++;
} }
} }
@@ -1127,7 +1125,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
4 * i); 4 * i);
buffer[i] = (unsigned char)reg; buffer[i] = (unsigned char)reg;
num_transferred++;
} }
} }
@@ -1144,7 +1141,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
(msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
msg->reply = DP_AUX_NATIVE_REPLY_ACK; msg->reply = DP_AUX_NATIVE_REPLY_ACK;
return num_transferred > 0 ? num_transferred : -EBUSY; return msg->size;
aux_error: aux_error:
/* if aux err happen, reset aux */ /* if aux err happen, reset aux */

View File

@@ -4024,6 +4024,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
const struct drm_dp_connection_status_notify *conn_stat = const struct drm_dp_connection_status_notify *conn_stat =
&up_req->msg.u.conn_stat; &up_req->msg.u.conn_stat;
bool handle_csn;
drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n",
conn_stat->port_number, conn_stat->port_number,
@@ -4032,6 +4033,16 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
conn_stat->message_capability_status, conn_stat->message_capability_status,
conn_stat->input_port, conn_stat->input_port,
conn_stat->peer_device_type); conn_stat->peer_device_type);
mutex_lock(&mgr->probe_lock);
handle_csn = mgr->mst_primary->link_address_sent;
mutex_unlock(&mgr->probe_lock);
if (!handle_csn) {
drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");
kfree(up_req);
goto out;
}
} else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
const struct drm_dp_resource_status_notify *res_stat = const struct drm_dp_resource_status_notify *res_stat =
&up_req->msg.u.resource_stat; &up_req->msg.u.resource_stat;

View File

@@ -873,6 +873,11 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
kfree(modeset->mode); kfree(modeset->mode);
modeset->mode = drm_mode_duplicate(dev, mode); modeset->mode = drm_mode_duplicate(dev, mode);
if (!modeset->mode) {
ret = -ENOMEM;
break;
}
drm_connector_get(connector); drm_connector_get(connector);
modeset->connectors[modeset->num_connectors++] = connector; modeset->connectors[modeset->num_connectors++] = connector;
modeset->x = offset->x; modeset->x = offset->x;

View File

@@ -489,3 +489,4 @@ module_platform_driver(lima_platform_driver);
MODULE_AUTHOR("Lima Project Developers"); MODULE_AUTHOR("Lima Project Developers");
MODULE_DESCRIPTION("Lima DRM Driver"); MODULE_DESCRIPTION("Lima DRM Driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_SOFTDEP("pre: governor_simpleondemand");

View File

@@ -31,6 +31,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <drm/drm_managed.h>
#include "mgag200_drv.h" #include "mgag200_drv.h"
static int mga_i2c_read_gpio(struct mga_device *mdev) static int mga_i2c_read_gpio(struct mga_device *mdev)
@@ -86,7 +88,7 @@ static int mga_gpio_getscl(void *data)
return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0; return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
} }
static void mgag200_i2c_release(void *res) static void mgag200_i2c_release(struct drm_device *dev, void *res)
{ {
struct mga_i2c_chan *i2c = res; struct mga_i2c_chan *i2c = res;
@@ -115,7 +117,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
i2c->adapter.algo_data = &i2c->bit; i2c->adapter.algo_data = &i2c->bit;
i2c->bit.udelay = 10; i2c->bit.udelay = 10;
i2c->bit.timeout = 2; i2c->bit.timeout = usecs_to_jiffies(2200);
i2c->bit.data = i2c; i2c->bit.data = i2c;
i2c->bit.setsda = mga_gpio_setsda; i2c->bit.setsda = mga_gpio_setsda;
i2c->bit.setscl = mga_gpio_setscl; i2c->bit.setscl = mga_gpio_setscl;
@@ -126,5 +128,5 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
if (ret) if (ret)
return ret; return ret;
return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c); return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c);
} }

View File

@@ -88,6 +88,7 @@ struct geni_i2c_dev {
int cur_wr; int cur_wr;
int cur_rd; int cur_rd;
spinlock_t lock; spinlock_t lock;
struct clk *core_clk;
u32 clk_freq_out; u32 clk_freq_out;
const struct geni_i2c_clk_fld *clk_fld; const struct geni_i2c_clk_fld *clk_fld;
int suspended; int suspended;
@@ -100,6 +101,13 @@ struct geni_i2c_dev {
bool abort_done; bool abort_done;
}; };
struct geni_i2c_desc {
bool has_core_clk;
char *icc_ddr;
bool no_dma_support;
unsigned int tx_fifo_depth;
};
struct geni_i2c_err_log { struct geni_i2c_err_log {
int err; int err;
const char *msg; const char *msg;
@@ -763,6 +771,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
u32 proto, tx_depth, fifo_disable; u32 proto, tx_depth, fifo_disable;
int ret; int ret;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct geni_i2c_desc *desc = NULL;
gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL); gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL);
if (!gi2c) if (!gi2c)
@@ -775,6 +784,14 @@ static int geni_i2c_probe(struct platform_device *pdev)
if (IS_ERR(gi2c->se.base)) if (IS_ERR(gi2c->se.base))
return PTR_ERR(gi2c->se.base); return PTR_ERR(gi2c->se.base);
desc = device_get_match_data(&pdev->dev);
if (desc && desc->has_core_clk) {
gi2c->core_clk = devm_clk_get(dev, "core");
if (IS_ERR(gi2c->core_clk))
return PTR_ERR(gi2c->core_clk);
}
gi2c->se.clk = devm_clk_get(dev, "se"); gi2c->se.clk = devm_clk_get(dev, "se");
if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(dev)) if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(dev))
return PTR_ERR(gi2c->se.clk); return PTR_ERR(gi2c->se.clk);
@@ -818,7 +835,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
gi2c->adap.dev.of_node = dev->of_node; gi2c->adap.dev.of_node = dev->of_node;
strscpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name)); strscpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
ret = geni_icc_get(&gi2c->se, "qup-memory"); ret = geni_icc_get(&gi2c->se, desc ? desc->icc_ddr : "qup-memory");
if (ret) if (ret)
return ret; return ret;
/* /*
@@ -828,36 +845,62 @@ static int geni_i2c_probe(struct platform_device *pdev)
*/ */
gi2c->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW; gi2c->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW;
gi2c->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; gi2c->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out); if (!desc || desc->icc_ddr)
gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out);
ret = geni_icc_set_bw(&gi2c->se); ret = geni_icc_set_bw(&gi2c->se);
if (ret) if (ret)
return ret; return ret;
ret = clk_prepare_enable(gi2c->core_clk);
if (ret)
return ret;
ret = geni_se_resources_on(&gi2c->se); ret = geni_se_resources_on(&gi2c->se);
if (ret) { if (ret) {
dev_err(dev, "Error turning on resources %d\n", ret); dev_err(dev, "Error turning on resources %d\n", ret);
clk_disable_unprepare(gi2c->core_clk);
return ret; return ret;
} }
proto = geni_se_read_proto(&gi2c->se); proto = geni_se_read_proto(&gi2c->se);
if (proto != GENI_SE_I2C) { if (proto != GENI_SE_I2C) {
dev_err(dev, "Invalid proto %d\n", proto); dev_err(dev, "Invalid proto %d\n", proto);
geni_se_resources_off(&gi2c->se); geni_se_resources_off(&gi2c->se);
clk_disable_unprepare(gi2c->core_clk);
return -ENXIO; return -ENXIO;
} }
fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; if (desc && desc->no_dma_support)
fifo_disable = false;
else
fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE;
if (fifo_disable) { if (fifo_disable) {
/* FIFO is disabled, so we can only use GPI DMA */ /* FIFO is disabled, so we can only use GPI DMA */
gi2c->gpi_mode = true; gi2c->gpi_mode = true;
ret = setup_gpi_dma(gi2c); ret = setup_gpi_dma(gi2c);
if (ret) if (ret) {
geni_se_resources_off(&gi2c->se);
clk_disable_unprepare(gi2c->core_clk);
return dev_err_probe(dev, ret, "Failed to setup GPI DMA mode\n"); return dev_err_probe(dev, ret, "Failed to setup GPI DMA mode\n");
}
dev_dbg(dev, "Using GPI DMA mode for I2C\n"); dev_dbg(dev, "Using GPI DMA mode for I2C\n");
} else { } else {
gi2c->gpi_mode = false; gi2c->gpi_mode = false;
tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se);
/* I2C Master Hub Serial Elements doesn't have the HW_PARAM_0 register */
if (!tx_depth && desc)
tx_depth = desc->tx_fifo_depth;
if (!tx_depth) {
dev_err(dev, "Invalid TX FIFO depth\n");
geni_se_resources_off(&gi2c->se);
clk_disable_unprepare(gi2c->core_clk);
return -EINVAL;
}
gi2c->tx_wm = tx_depth - 1; gi2c->tx_wm = tx_depth - 1;
geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth); geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth);
geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, geni_se_config_packing(&gi2c->se, BITS_PER_BYTE,
@@ -866,6 +909,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
} }
clk_disable_unprepare(gi2c->core_clk);
ret = geni_se_resources_off(&gi2c->se); ret = geni_se_resources_off(&gi2c->se);
if (ret) { if (ret) {
dev_err(dev, "Error turning off resources %d\n", ret); dev_err(dev, "Error turning off resources %d\n", ret);
@@ -931,6 +975,8 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
gi2c->suspended = 1; gi2c->suspended = 1;
} }
clk_disable_unprepare(gi2c->core_clk);
return geni_icc_disable(&gi2c->se); return geni_icc_disable(&gi2c->se);
} }
@@ -943,10 +989,17 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
if (ret) if (ret)
return ret; return ret;
ret = geni_se_resources_on(&gi2c->se); ret = clk_prepare_enable(gi2c->core_clk);
if (ret) if (ret)
return ret; return ret;
ret = geni_se_resources_on(&gi2c->se);
if (ret) {
clk_disable_unprepare(gi2c->core_clk);
geni_icc_disable(&gi2c->se);
return ret;
}
enable_irq(gi2c->irq); enable_irq(gi2c->irq);
gi2c->suspended = 0; gi2c->suspended = 0;
return 0; return 0;

View File

@@ -34,6 +34,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)
struct i2c_client *client = i2c_verify_client(dev); struct i2c_client *client = i2c_verify_client(dev);
struct alert_data *data = addrp; struct alert_data *data = addrp;
struct i2c_driver *driver; struct i2c_driver *driver;
int ret;
if (!client || client->addr != data->addr) if (!client || client->addr != data->addr)
return 0; return 0;
@@ -47,16 +48,47 @@ static int smbus_do_alert(struct device *dev, void *addrp)
device_lock(dev); device_lock(dev);
if (client->dev.driver) { if (client->dev.driver) {
driver = to_i2c_driver(client->dev.driver); driver = to_i2c_driver(client->dev.driver);
if (driver->alert) if (driver->alert) {
/* Stop iterating after we find the device */
driver->alert(client, data->type, data->data); driver->alert(client, data->type, data->data);
else ret = -EBUSY;
} else {
dev_warn(&client->dev, "no driver alert()!\n"); dev_warn(&client->dev, "no driver alert()!\n");
} else ret = -EOPNOTSUPP;
}
} else {
dev_dbg(&client->dev, "alert with no driver\n"); dev_dbg(&client->dev, "alert with no driver\n");
ret = -ENODEV;
}
device_unlock(dev); device_unlock(dev);
/* Stop iterating after we find the device */ return ret;
return -EBUSY; }
/* Same as above, but call back all drivers with alert handler */
static int smbus_do_alert_force(struct device *dev, void *addrp)
{
struct i2c_client *client = i2c_verify_client(dev);
struct alert_data *data = addrp;
struct i2c_driver *driver;
if (!client || (client->flags & I2C_CLIENT_TEN))
return 0;
/*
* Drivers should either disable alerts, or provide at least
* a minimal handler. Lock so the driver won't change.
*/
device_lock(dev);
if (client->dev.driver) {
driver = to_i2c_driver(client->dev.driver);
if (driver->alert)
driver->alert(client, data->type, data->data);
}
device_unlock(dev);
return 0;
} }
/* /*
@@ -67,6 +99,7 @@ static irqreturn_t smbus_alert(int irq, void *d)
{ {
struct i2c_smbus_alert *alert = d; struct i2c_smbus_alert *alert = d;
struct i2c_client *ara; struct i2c_client *ara;
unsigned short prev_addr = I2C_CLIENT_END; /* Not a valid address */
ara = alert->ara; ara = alert->ara;
@@ -94,8 +127,25 @@ static irqreturn_t smbus_alert(int irq, void *d)
data.addr, data.data); data.addr, data.data);
/* Notify driver for the device which issued the alert */ /* Notify driver for the device which issued the alert */
device_for_each_child(&ara->adapter->dev, &data, status = device_for_each_child(&ara->adapter->dev, &data,
smbus_do_alert); smbus_do_alert);
/*
* If we read the same address more than once, and the alert
* was not handled by a driver, it won't do any good to repeat
* the loop because it will never terminate. Try again, this
* time calling the alert handlers of all devices connected to
* the bus, and abort the loop afterwards. If this helps, we
* are all set. If it doesn't, there is nothing else we can do,
* so we might as well abort the loop.
* Note: This assumes that a driver with alert handler handles
* the alert properly and clears it if necessary.
*/
if (data.addr == prev_addr && status != -EBUSY) {
device_for_each_child(&ara->adapter->dev, &data,
smbus_do_alert_force);
break;
}
prev_addr = data.addr;
} }
return IRQ_HANDLED; return IRQ_HANDLED;

View File

@@ -18,11 +18,13 @@ struct fwnode_handle *cpuintc_handle;
static u32 lpic_gsi_to_irq(u32 gsi) static u32 lpic_gsi_to_irq(u32 gsi)
{ {
int irq = 0;
/* Only pch irqdomain transferring is required for LoongArch. */ /* Only pch irqdomain transferring is required for LoongArch. */
if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ) if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ)
return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
return 0; return (irq > 0) ? irq : 0;
} }
static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi) static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi)

View File

@@ -64,6 +64,20 @@ struct mbigen_device {
void __iomem *base; void __iomem *base;
}; };
static inline unsigned int get_mbigen_node_offset(unsigned int nid)
{
unsigned int offset = nid * MBIGEN_NODE_OFFSET;
/*
* To avoid touched clear register in unexpected way, we need to directly
* skip clear register when access to more than 10 mbigen nodes.
*/
if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET))
offset += MBIGEN_NODE_OFFSET;
return offset;
}
static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
{ {
unsigned int nid, pin; unsigned int nid, pin;
@@ -72,8 +86,7 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
nid = hwirq / IRQS_PER_MBIGEN_NODE + 1; nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
pin = hwirq % IRQS_PER_MBIGEN_NODE; pin = hwirq % IRQS_PER_MBIGEN_NODE;
return pin * 4 + nid * MBIGEN_NODE_OFFSET return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET;
+ REG_MBIGEN_VEC_OFFSET;
} }
static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
@@ -88,8 +101,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
*mask = 1 << (irq_ofst % 32); *mask = 1 << (irq_ofst % 32);
ofst = irq_ofst / 32 * 4; ofst = irq_ofst / 32 * 4;
*addr = ofst + nid * MBIGEN_NODE_OFFSET *addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET;
+ REG_MBIGEN_TYPE_OFFSET;
} }
static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,

View File

@@ -168,7 +168,7 @@ struct meson_gpio_irq_controller {
void __iomem *base; void __iomem *base;
u32 channel_irqs[MAX_NUM_CHANNEL]; u32 channel_irqs[MAX_NUM_CHANNEL];
DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL); DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL);
spinlock_t lock; raw_spinlock_t lock;
}; };
static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl, static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
@@ -177,14 +177,14 @@ static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
unsigned long flags; unsigned long flags;
u32 tmp; u32 tmp;
spin_lock_irqsave(&ctl->lock, flags); raw_spin_lock_irqsave(&ctl->lock, flags);
tmp = readl_relaxed(ctl->base + reg); tmp = readl_relaxed(ctl->base + reg);
tmp &= ~mask; tmp &= ~mask;
tmp |= val; tmp |= val;
writel_relaxed(tmp, ctl->base + reg); writel_relaxed(tmp, ctl->base + reg);
spin_unlock_irqrestore(&ctl->lock, flags); raw_spin_unlock_irqrestore(&ctl->lock, flags);
} }
static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl) static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
@@ -234,12 +234,12 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
unsigned long flags; unsigned long flags;
unsigned int idx; unsigned int idx;
spin_lock_irqsave(&ctl->lock, flags); raw_spin_lock_irqsave(&ctl->lock, flags);
/* Find a free channel */ /* Find a free channel */
idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels); idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
if (idx >= ctl->params->nr_channels) { if (idx >= ctl->params->nr_channels) {
spin_unlock_irqrestore(&ctl->lock, flags); raw_spin_unlock_irqrestore(&ctl->lock, flags);
pr_err("No channel available\n"); pr_err("No channel available\n");
return -ENOSPC; return -ENOSPC;
} }
@@ -247,7 +247,7 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
/* Mark the channel as used */ /* Mark the channel as used */
set_bit(idx, ctl->channel_map); set_bit(idx, ctl->channel_map);
spin_unlock_irqrestore(&ctl->lock, flags); raw_spin_unlock_irqrestore(&ctl->lock, flags);
/* /*
* Setup the mux of the channel to route the signal of the pad * Setup the mux of the channel to route the signal of the pad
@@ -557,7 +557,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
if (!ctl) if (!ctl)
return -ENOMEM; return -ENOMEM;
spin_lock_init(&ctl->lock); raw_spin_lock_init(&ctl->lock);
ctl->base = of_iomap(node, 0); ctl->base = of_iomap(node, 0);
if (!ctl->base) { if (!ctl->base) {

View File

@@ -189,7 +189,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
irqc->intr_mask = 0; irqc->intr_mask = 0;
} }
if (irqc->intr_mask >> irqc->nr_irq) if ((u64)irqc->intr_mask >> irqc->nr_irq)
pr_warn("irq-xilinx: mismatch in kind-of-intr param\n"); pr_warn("irq-xilinx: mismatch in kind-of-intr param\n");
pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n", pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n",

View File

@@ -489,7 +489,6 @@ void mddev_suspend(struct mddev *mddev)
clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags); clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags);
wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags)); wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags));
del_timer_sync(&mddev->safemode_timer);
/* restrict memory reclaim I/O during raid array is suspend */ /* restrict memory reclaim I/O during raid array is suspend */
mddev->noio_flag = memalloc_noio_save(); mddev->noio_flag = memalloc_noio_save();
} }

View File

@@ -6316,7 +6316,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
safepos = conf->reshape_safe; safepos = conf->reshape_safe;
sector_div(safepos, data_disks); sector_div(safepos, data_disks);
if (mddev->reshape_backwards) { if (mddev->reshape_backwards) {
BUG_ON(writepos < reshape_sectors); if (WARN_ON(writepos < reshape_sectors))
return MaxSector;
writepos -= reshape_sectors; writepos -= reshape_sectors;
readpos += reshape_sectors; readpos += reshape_sectors;
safepos += reshape_sectors; safepos += reshape_sectors;
@@ -6334,14 +6336,18 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
* to set 'stripe_addr' which is where we will write to. * to set 'stripe_addr' which is where we will write to.
*/ */
if (mddev->reshape_backwards) { if (mddev->reshape_backwards) {
BUG_ON(conf->reshape_progress == 0); if (WARN_ON(conf->reshape_progress == 0))
return MaxSector;
stripe_addr = writepos; stripe_addr = writepos;
BUG_ON((mddev->dev_sectors & if (WARN_ON((mddev->dev_sectors &
~((sector_t)reshape_sectors - 1)) ~((sector_t)reshape_sectors - 1)) -
- reshape_sectors - stripe_addr reshape_sectors - stripe_addr != sector_nr))
!= sector_nr); return MaxSector;
} else { } else {
BUG_ON(writepos != sector_nr + reshape_sectors); if (WARN_ON(writepos != sector_nr + reshape_sectors))
return MaxSector;
stripe_addr = sector_nr; stripe_addr = sector_nr;
} }

View File

@@ -145,7 +145,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
struct vdec_t *vdec = inst->priv; struct vdec_t *vdec = inst->priv;
int ret = 0; int ret = 0;
vpu_inst_lock(inst);
switch (ctrl->id) { switch (ctrl->id) {
case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE:
vdec->params.display_delay_enable = ctrl->val; vdec->params.display_delay_enable = ctrl->val;
@@ -157,7 +156,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
vpu_inst_unlock(inst);
return ret; return ret;
} }

View File

@@ -528,7 +528,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
struct venc_t *venc = inst->priv; struct venc_t *venc = inst->priv;
int ret = 0; int ret = 0;
vpu_inst_lock(inst);
switch (ctrl->id) { switch (ctrl->id) {
case V4L2_CID_MPEG_VIDEO_H264_PROFILE: case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
venc->params.profile = ctrl->val; venc->params.profile = ctrl->val;
@@ -589,7 +588,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
vpu_inst_unlock(inst);
return ret; return ret;
} }

View File

@@ -1361,9 +1361,16 @@ static void load_firmware_cb(const struct firmware *fw,
void *context) void *context)
{ {
struct dvb_frontend *fe = context; struct dvb_frontend *fe = context;
struct xc2028_data *priv = fe->tuner_priv; struct xc2028_data *priv;
int rc; int rc;
if (!fe) {
pr_warn("xc2028: No frontend in %s\n", __func__);
return;
}
priv = fe->tuner_priv;
tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
if (!fw) { if (!fw) {
tuner_err("Could not load firmware %s.\n", priv->fname); tuner_err("Could not load firmware %s.\n", priv->fname);

View File

@@ -212,13 +212,13 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
* Compute a bandwidth estimation by multiplying the frame * Compute a bandwidth estimation by multiplying the frame
* size by the number of video frames per second, divide the * size by the number of video frames per second, divide the
* result by the number of USB frames (or micro-frames for * result by the number of USB frames (or micro-frames for
* high-speed devices) per second and add the UVC header size * high- and super-speed devices) per second and add the UVC
* (assumed to be 12 bytes long). * header size (assumed to be 12 bytes long).
*/ */
bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
bandwidth *= 10000000 / interval + 1; bandwidth *= 10000000 / interval + 1;
bandwidth /= 1000; bandwidth /= 1000;
if (stream->dev->udev->speed == USB_SPEED_HIGH) if (stream->dev->udev->speed >= USB_SPEED_HIGH)
bandwidth /= 8; bandwidth /= 8;
bandwidth += 12; bandwidth += 12;
@@ -476,6 +476,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
ktime_t time; ktime_t time;
u16 host_sof; u16 host_sof;
u16 dev_sof; u16 dev_sof;
u32 dev_stc;
switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) { switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
case UVC_STREAM_PTS | UVC_STREAM_SCR: case UVC_STREAM_PTS | UVC_STREAM_SCR:
@@ -522,6 +523,34 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
if (dev_sof == stream->clock.last_sof) if (dev_sof == stream->clock.last_sof)
return; return;
dev_stc = get_unaligned_le32(&data[header_size - 6]);
/*
* STC (Source Time Clock) is the clock used by the camera. The UVC 1.5
* standard states that it "must be captured when the first video data
* of a video frame is put on the USB bus". This is generally understood
* as requiring devices to clear the payload header's SCR bit before
* the first packet containing video data.
*
* Most vendors follow that interpretation, but some (namely SunplusIT
* on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR
* field with 0's,and expect that the driver only processes the SCR if
* there is data in the packet.
*
* Ignore all the hardware timestamp information if we haven't received
* any data for this frame yet, the packet contains no data, and both
* STC and SOF are zero. This heuristics should be safe on compliant
* devices. This should be safe with compliant devices, as in the very
* unlikely case where a UVC 1.1 device would send timing information
* only before the first packet containing data, and both STC and SOF
* happen to be zero for a particular frame, we would only miss one
* clock sample from many and the clock recovery algorithm wouldn't
* suffer from this condition.
*/
if (buf && buf->bytesused == 0 && len == header_size &&
dev_stc == 0 && dev_sof == 0)
return;
stream->clock.last_sof = dev_sof; stream->clock.last_sof = dev_sof;
host_sof = usb_get_current_frame_number(stream->dev->udev); host_sof = usb_get_current_frame_number(stream->dev->udev);
@@ -560,7 +589,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
spin_lock_irqsave(&stream->clock.lock, flags); spin_lock_irqsave(&stream->clock.lock, flags);
sample = &stream->clock.samples[stream->clock.head]; sample = &stream->clock.samples[stream->clock.head];
sample->dev_stc = get_unaligned_le32(&data[header_size - 6]); sample->dev_stc = dev_stc;
sample->dev_sof = dev_sof; sample->dev_sof = dev_sof;
sample->host_sof = host_sof; sample->host_sof = host_sof;
sample->host_time = time; sample->host_time = time;

View File

@@ -475,6 +475,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags); clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags);
} }
tx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(tx_ring->obj_num) -
ilog2(tx_ring->obj_num);
tx_ring->obj_size = tx_obj_size; tx_ring->obj_size = tx_obj_size;
rem = priv->rx_obj_num; rem = priv->rx_obj_num;

View File

@@ -2,7 +2,7 @@
// //
// mcp251xfd - Microchip MCP251xFD Family CAN controller driver // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
// //
// Copyright (c) 2019, 2020, 2021 Pengutronix, // Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
// Marc Kleine-Budde <kernel@pengutronix.de> // Marc Kleine-Budde <kernel@pengutronix.de>
// //
// Based on: // Based on:
@@ -16,6 +16,11 @@
#include "mcp251xfd.h" #include "mcp251xfd.h"
static inline bool mcp251xfd_tx_fifo_sta_full(u32 fifo_sta)
{
return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF);
}
static inline int static inline int
mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv,
u8 *tef_tail) u8 *tef_tail)
@@ -55,56 +60,39 @@ static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv)
return 0; return 0;
} }
static int
mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
{
const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
u32 tef_sta;
int err;
err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta);
if (err)
return err;
if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) {
netdev_err(priv->ndev,
"Transmit Event FIFO buffer overflow.\n");
return -ENOBUFS;
}
netdev_info(priv->ndev,
"Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n",
tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ?
"full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ?
"not empty" : "empty",
seq, priv->tef->tail, priv->tef->head, tx_ring->head);
/* The Sequence Number in the TEF doesn't match our tef_tail. */
return -EAGAIN;
}
static int static int
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
const struct mcp251xfd_hw_tef_obj *hw_tef_obj, const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
unsigned int *frame_len_ptr) unsigned int *frame_len_ptr)
{ {
struct net_device_stats *stats = &priv->ndev->stats; struct net_device_stats *stats = &priv->ndev->stats;
u32 seq, tef_tail_masked, tef_tail;
struct sk_buff *skb; struct sk_buff *skb;
u32 seq, seq_masked, tef_tail_masked, tef_tail;
seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, /* Use the MCP2517FD mask on the MCP2518FD, too. We only
* compare 7 bits, this is enough to detect old TEF objects.
*/
seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK,
hw_tef_obj->flags); hw_tef_obj->flags);
/* Use the MCP2517FD mask on the MCP2518FD, too. We only
* compare 7 bits, this should be enough to detect
* net-yet-completed, i.e. old TEF objects.
*/
seq_masked = seq &
field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
tef_tail_masked = priv->tef->tail & tef_tail_masked = priv->tef->tail &
field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
if (seq_masked != tef_tail_masked)
return mcp251xfd_handle_tefif_recover(priv, seq); /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
* bits of a FIFOSTA register, here the TX FIFO tail index
* might be corrupted and we might process past the TEF FIFO's
* head into old CAN frames.
*
* Compare the sequence number of the currently processed CAN
* frame with the expected sequence number. Abort with
* -EBADMSG if an old CAN frame is detected.
*/
if (seq != tef_tail_masked) {
netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__,
seq, tef_tail_masked);
stats->tx_fifo_errors++;
return -EBADMSG;
}
tef_tail = mcp251xfd_get_tef_tail(priv); tef_tail = mcp251xfd_get_tef_tail(priv);
skb = priv->can.echo_skb[tef_tail]; skb = priv->can.echo_skb[tef_tail];
@@ -120,28 +108,44 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
return 0; return 0;
} }
static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv) static int
mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p)
{ {
const struct mcp251xfd_tx_ring *tx_ring = priv->tx; const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
unsigned int new_head; const u8 shift = tx_ring->obj_num_shift_to_u8;
u8 chip_tx_tail; u8 chip_tx_tail, tail, len;
u32 fifo_sta;
int err; int err;
err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail); err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr),
&fifo_sta);
if (err) if (err)
return err; return err;
/* chip_tx_tail, is the next TX-Object send by the HW. if (mcp251xfd_tx_fifo_sta_full(fifo_sta)) {
* The new TEF head must be >= the old head, ... *len_p = tx_ring->obj_num;
return 0;
}
chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
err = mcp251xfd_check_tef_tail(priv);
if (err)
return err;
tail = mcp251xfd_get_tef_tail(priv);
/* First shift to full u8. The subtraction works on signed
* values, that keeps the difference steady around the u8
* overflow. The right shift acts on len, which is an u8.
*/ */
new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail; BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail));
if (new_head <= priv->tef->head) BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail));
new_head += tx_ring->obj_num; BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len));
/* ... but it cannot exceed the TX head. */ len = (chip_tx_tail << shift) - (tail << shift);
priv->tef->head = min(new_head, tx_ring->head); *len_p = len >> shift;
return mcp251xfd_check_tef_tail(priv); return 0;
} }
static inline int static inline int
@@ -182,13 +186,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
u8 tef_tail, len, l; u8 tef_tail, len, l;
int err, i; int err, i;
err = mcp251xfd_tef_ring_update(priv); err = mcp251xfd_get_tef_len(priv, &len);
if (err) if (err)
return err; return err;
tef_tail = mcp251xfd_get_tef_tail(priv); tef_tail = mcp251xfd_get_tef_tail(priv);
len = mcp251xfd_get_tef_len(priv); l = mcp251xfd_get_tef_linear_len(priv, len);
l = mcp251xfd_get_tef_linear_len(priv);
err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l); err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l);
if (err) if (err)
return err; return err;
@@ -203,12 +206,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
unsigned int frame_len = 0; unsigned int frame_len = 0;
err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
/* -EAGAIN means the Sequence Number in the TEF /* -EBADMSG means we're affected by mcp2518fd erratum
* doesn't match our tef_tail. This can happen if we * DS80000789E 6., i.e. the Sequence Number in the TEF
* read the TEF objects too early. Leave loop let the * doesn't match our tef_tail. Don't process any
* interrupt handler call us again. * further and mark processed frames as good.
*/ */
if (err == -EAGAIN) if (err == -EBADMSG)
goto out_netif_wake_queue; goto out_netif_wake_queue;
if (err) if (err)
return err; return err;
@@ -223,6 +226,8 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
struct mcp251xfd_tx_ring *tx_ring = priv->tx; struct mcp251xfd_tx_ring *tx_ring = priv->tx;
int offset; int offset;
ring->head += len;
/* Increment the TEF FIFO tail pointer 'len' times in /* Increment the TEF FIFO tail pointer 'len' times in
* a single SPI message. * a single SPI message.
* *

View File

@@ -519,6 +519,7 @@ struct mcp251xfd_tef_ring {
/* u8 obj_num equals tx_ring->obj_num */ /* u8 obj_num equals tx_ring->obj_num */
/* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */
/* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */
union mcp251xfd_write_reg_buf irq_enable_buf; union mcp251xfd_write_reg_buf irq_enable_buf;
struct spi_transfer irq_enable_xfer; struct spi_transfer irq_enable_xfer;
@@ -537,6 +538,7 @@ struct mcp251xfd_tx_ring {
u8 nr; u8 nr;
u8 fifo_nr; u8 fifo_nr;
u8 obj_num; u8 obj_num;
u8 obj_num_shift_to_u8;
u8 obj_size; u8 obj_size;
struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX]; struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX];
@@ -843,17 +845,8 @@ static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv)
return priv->tef->tail & (priv->tx->obj_num - 1); return priv->tef->tail & (priv->tx->obj_num - 1);
} }
static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv) static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len)
{ {
return priv->tef->head - priv->tef->tail;
}
static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv)
{
u8 len;
len = mcp251xfd_get_tef_len(priv);
return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv)); return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv));
} }

View File

@@ -678,8 +678,10 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
of_remove_property(child, prop); of_remove_property(child, prop);
phydev = of_phy_find_device(child); phydev = of_phy_find_device(child);
if (phydev) if (phydev) {
phy_device_remove(phydev); phy_device_remove(phydev);
phy_device_free(phydev);
}
} }
err = mdiobus_register(priv->slave_mii_bus); err = mdiobus_register(priv->slave_mii_bus);

View File

@@ -635,6 +635,9 @@ void fec_ptp_stop(struct platform_device *pdev)
struct net_device *ndev = platform_get_drvdata(pdev); struct net_device *ndev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(ndev); struct fec_enet_private *fep = netdev_priv(ndev);
if (fep->pps_enable)
fec_ptp_enable_pps(fep, 0);
cancel_delayed_work_sync(&fep->time_keep); cancel_delayed_work_sync(&fep->time_keep);
if (fep->ptp_clock) if (fep->ptp_clock)
ptp_clock_unregister(fep->ptp_clock); ptp_clock_unregister(fep->ptp_clock);

View File

@@ -2146,6 +2146,9 @@ mpwrq_cqe_out:
if (likely(wi->consumed_strides < rq->mpwqe.num_strides)) if (likely(wi->consumed_strides < rq->mpwqe.num_strides))
return; return;
if (unlikely(!cstrides))
return;
wq = &rq->mpwqe.wq; wq = &rq->mpwqe.wq;
wqe = mlx5_wq_ll_get_wqe(wq, wqe_id); wqe = mlx5_wq_ll_get_wqe(wq, wqe_id);
mlx5e_free_rx_mpwqe(rq, wi, true); mlx5e_free_rx_mpwqe(rq, wi, true);

View File

@@ -200,6 +200,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
break; break;
default: default:
/* not ip - do not know what to do */ /* not ip - do not know what to do */
kfree_skb(skbn);
goto skip; goto skip;
} }

View File

@@ -873,9 +873,9 @@ static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req,
struct nvme_command *cmnd) struct nvme_command *cmnd)
{ {
struct nvme_iod *iod = blk_mq_rq_to_pdu(req); struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
struct bio_vec bv = rq_integrity_vec(req);
iod->meta_dma = dma_map_bvec(dev->dev, rq_integrity_vec(req), iod->meta_dma = dma_map_bvec(dev->dev, &bv, rq_dma_dir(req), 0);
rq_dma_dir(req), 0);
if (dma_mapping_error(dev->dev, iod->meta_dma)) if (dma_mapping_error(dev->dev, iod->meta_dma))
return BLK_STS_IOERR; return BLK_STS_IOERR;
cmnd->rw.metadata = cpu_to_le64(iod->meta_dma); cmnd->rw.metadata = cpu_to_le64(iod->meta_dma);
@@ -1016,7 +1016,7 @@ static __always_inline void nvme_pci_unmap_rq(struct request *req)
struct nvme_iod *iod = blk_mq_rq_to_pdu(req); struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
dma_unmap_page(dev->dev, iod->meta_dma, dma_unmap_page(dev->dev, iod->meta_dma,
rq_integrity_vec(req)->bv_len, rq_dma_dir(req)); rq_integrity_vec(req).bv_len, rq_dma_dir(req));
} }
if (blk_rq_nr_phys_segments(req)) if (blk_rq_nr_phys_segments(req))

View File

@@ -157,9 +157,17 @@ union ifs_chunks_auth_status {
union ifs_scan { union ifs_scan {
u64 data; u64 data;
struct { struct {
u32 start :8; union {
u32 stop :8; struct {
u32 rsvd :16; u8 start;
u8 stop;
u16 rsvd;
} gen0;
struct {
u16 start;
u16 stop;
} gen2;
};
u32 delay :31; u32 delay :31;
u32 sigmce :1; u32 sigmce :1;
}; };
@@ -169,9 +177,17 @@ union ifs_scan {
union ifs_status { union ifs_status {
u64 data; u64 data;
struct { struct {
u32 chunk_num :8; union {
u32 chunk_stop_index :8; struct {
u32 rsvd1 :16; u8 chunk_num;
u8 chunk_stop_index;
u16 rsvd1;
} gen0;
struct {
u16 chunk_num;
u16 chunk_stop_index;
} gen2;
};
u32 error_code :8; u32 error_code :8;
u32 rsvd2 :22; u32 rsvd2 :22;
u32 control_error :1; u32 control_error :1;

View File

@@ -165,25 +165,35 @@ static int doscan(void *data)
*/ */
static void ifs_test_core(int cpu, struct device *dev) static void ifs_test_core(int cpu, struct device *dev)
{ {
union ifs_status status = {};
union ifs_scan activate; union ifs_scan activate;
union ifs_status status;
unsigned long timeout; unsigned long timeout;
struct ifs_data *ifsd; struct ifs_data *ifsd;
int to_start, to_stop;
int status_chunk;
u64 msrvals[2]; u64 msrvals[2];
int retries; int retries;
ifsd = ifs_get_data(dev); ifsd = ifs_get_data(dev);
activate.rsvd = 0; activate.gen0.rsvd = 0;
activate.delay = IFS_THREAD_WAIT; activate.delay = IFS_THREAD_WAIT;
activate.sigmce = 0; activate.sigmce = 0;
activate.start = 0; to_start = 0;
activate.stop = ifsd->valid_chunks - 1; to_stop = ifsd->valid_chunks - 1;
if (ifsd->generation) {
activate.gen2.start = to_start;
activate.gen2.stop = to_stop;
} else {
activate.gen0.start = to_start;
activate.gen0.stop = to_stop;
}
timeout = jiffies + HZ / 2; timeout = jiffies + HZ / 2;
retries = MAX_IFS_RETRIES; retries = MAX_IFS_RETRIES;
while (activate.start <= activate.stop) { while (to_start <= to_stop) {
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
status.error_code = IFS_SW_TIMEOUT; status.error_code = IFS_SW_TIMEOUT;
break; break;
@@ -194,13 +204,14 @@ static void ifs_test_core(int cpu, struct device *dev)
status.data = msrvals[1]; status.data = msrvals[1];
trace_ifs_status(cpu, activate, status); trace_ifs_status(cpu, to_start, to_stop, status.data);
/* Some cases can be retried, give up for others */ /* Some cases can be retried, give up for others */
if (!can_restart(status)) if (!can_restart(status))
break; break;
if (status.chunk_num == activate.start) { status_chunk = ifsd->generation ? status.gen2.chunk_num : status.gen0.chunk_num;
if (status_chunk == to_start) {
/* Check for forward progress */ /* Check for forward progress */
if (--retries == 0) { if (--retries == 0) {
if (status.error_code == IFS_NO_ERROR) if (status.error_code == IFS_NO_ERROR)
@@ -209,7 +220,11 @@ static void ifs_test_core(int cpu, struct device *dev)
} }
} else { } else {
retries = MAX_IFS_RETRIES; retries = MAX_IFS_RETRIES;
activate.start = status.chunk_num; if (ifsd->generation)
activate.gen2.start = status_chunk;
else
activate.gen0.start = status_chunk;
to_start = status_chunk;
} }
} }

View File

@@ -178,18 +178,18 @@ static inline int axp288_charger_set_cv(struct axp288_chrg_info *info, int cv)
u8 reg_val; u8 reg_val;
int ret; int ret;
if (cv <= CV_4100MV) { if (cv >= CV_4350MV) {
reg_val = CHRG_CCCV_CV_4100MV;
cv = CV_4100MV;
} else if (cv <= CV_4150MV) {
reg_val = CHRG_CCCV_CV_4150MV;
cv = CV_4150MV;
} else if (cv <= CV_4200MV) {
reg_val = CHRG_CCCV_CV_4200MV;
cv = CV_4200MV;
} else {
reg_val = CHRG_CCCV_CV_4350MV; reg_val = CHRG_CCCV_CV_4350MV;
cv = CV_4350MV; cv = CV_4350MV;
} else if (cv >= CV_4200MV) {
reg_val = CHRG_CCCV_CV_4200MV;
cv = CV_4200MV;
} else if (cv >= CV_4150MV) {
reg_val = CHRG_CCCV_CV_4150MV;
cv = CV_4150MV;
} else {
reg_val = CHRG_CCCV_CV_4100MV;
cv = CV_4100MV;
} }
reg_val = reg_val << CHRG_CCCV_CV_BIT_POS; reg_val = reg_val << CHRG_CCCV_CV_BIT_POS;
@@ -337,8 +337,8 @@ static int axp288_charger_usb_set_property(struct power_supply *psy,
} }
break; break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
scaled_val = min(val->intval, info->max_cv); scaled_val = DIV_ROUND_CLOSEST(val->intval, 1000);
scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); scaled_val = min(scaled_val, info->max_cv);
ret = axp288_charger_set_cv(info, scaled_val); ret = axp288_charger_set_cv(info, scaled_val);
if (ret < 0) { if (ret < 0) {
dev_warn(&info->pdev->dev, "set charge voltage failed\n"); dev_warn(&info->pdev->dev, "set charge voltage failed\n");

View File

@@ -320,8 +320,14 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di)
&esize); &esize);
if (rc) { if (rc) {
/* Cancel running request if interrupted */ /* Cancel running request if interrupted */
if (rc == -ERESTARTSYS) if (rc == -ERESTARTSYS) {
sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL); if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) {
pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n",
(size_t)dsize * PAGE_SIZE);
data = NULL;
asce = 0;
}
}
vfree(data); vfree(data);
goto out; goto out;
} }

View File

@@ -3389,6 +3389,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc,
scmd->sc_data_direction); scmd->sc_data_direction);
priv->meta_sg_valid = 1; /* To unmap meta sg DMA */ priv->meta_sg_valid = 1; /* To unmap meta sg DMA */
} else { } else {
/*
* Some firmware versions byte-swap the REPORT ZONES command
* reply from ATA-ZAC devices by directly accessing in the host
* buffer. This does not respect the default command DMA
* direction and causes IOMMU page faults on some architectures
* with an IOMMU enforcing write mappings (e.g. AMD hosts).
* Avoid such issue by making the REPORT ZONES buffer mapping
* bi-directional.
*/
if (scmd->cmnd[0] == ZBC_IN && scmd->cmnd[1] == ZI_REPORT_ZONES)
scmd->sc_data_direction = DMA_BIDIRECTIONAL;
sg_scmd = scsi_sglist(scmd); sg_scmd = scsi_sglist(scmd);
sges_left = scsi_dma_map(scmd); sges_left = scsi_dma_map(scmd);
} }

View File

@@ -2672,6 +2672,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
_base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1); _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
} }
static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd)
{
/*
* Some firmware versions byte-swap the REPORT ZONES command reply from
* ATA-ZAC devices by directly accessing in the host buffer. This does
* not respect the default command DMA direction and causes IOMMU page
* faults on some architectures with an IOMMU enforcing write mappings
* (e.g. AMD hosts). Avoid such issue by making the report zones buffer
* mapping bi-directional.
*/
if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES)
cmd->sc_data_direction = DMA_BIDIRECTIONAL;
return scsi_dma_map(cmd);
}
/** /**
* _base_build_sg_scmd - main sg creation routine * _base_build_sg_scmd - main sg creation routine
* pcie_device is unused here! * pcie_device is unused here!
@@ -2718,7 +2734,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
sg_scmd = scsi_sglist(scmd); sg_scmd = scsi_sglist(scmd);
sges_left = scsi_dma_map(scmd); sges_left = _base_scsi_dma_map(scmd);
if (sges_left < 0) if (sges_left < 0)
return -ENOMEM; return -ENOMEM;
@@ -2862,7 +2878,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
} }
sg_scmd = scsi_sglist(scmd); sg_scmd = scsi_sglist(scmd);
sges_left = scsi_dma_map(scmd); sges_left = _base_scsi_dma_map(scmd);
if (sges_left < 0) if (sges_left < 0)
return -ENOMEM; return -ENOMEM;

View File

@@ -297,7 +297,7 @@ static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
{ {
struct lpspi_config config = fsl_lpspi->config; struct lpspi_config config = fsl_lpspi->config;
unsigned int perclk_rate, scldiv; unsigned int perclk_rate, scldiv, div;
u8 prescale; u8 prescale;
perclk_rate = clk_get_rate(fsl_lpspi->clk_per); perclk_rate = clk_get_rate(fsl_lpspi->clk_per);
@@ -308,8 +308,10 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
return -EINVAL; return -EINVAL;
} }
div = DIV_ROUND_UP(perclk_rate, config.speed_hz);
for (prescale = 0; prescale < 8; prescale++) { for (prescale = 0; prescale < 8; prescale++) {
scldiv = perclk_rate / config.speed_hz / (1 << prescale) - 2; scldiv = div / (1 << prescale) - 2;
if (scldiv < 256) { if (scldiv < 256) {
fsl_lpspi->config.prescale = prescale; fsl_lpspi->config.prescale = prescale;
break; break;

View File

@@ -692,6 +692,7 @@ static const struct file_operations spidev_fops = {
static struct class *spidev_class; static struct class *spidev_class;
static const struct spi_device_id spidev_spi_ids[] = { static const struct spi_device_id spidev_spi_ids[] = {
{ .name = "bh2228fv" },
{ .name = "dh2228fv" }, { .name = "dh2228fv" },
{ .name = "ltc2488" }, { .name = "ltc2488" },
{ .name = "sx1301" }, { .name = "sx1301" },

View File

@@ -846,6 +846,14 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
new_flags = (__force upf_t)new_info->flags; new_flags = (__force upf_t)new_info->flags;
old_custom_divisor = uport->custom_divisor; old_custom_divisor = uport->custom_divisor;
if (!(uport->flags & UPF_FIXED_PORT)) {
unsigned int uartclk = new_info->baud_base * 16;
/* check needs to be done here before other settings made */
if (uartclk == 0) {
retval = -EINVAL;
goto exit;
}
}
if (!capable(CAP_SYS_ADMIN)) { if (!capable(CAP_SYS_ADMIN)) {
retval = -EPERM; retval = -EPERM;
if (change_irq || change_port || if (change_irq || change_port ||

View File

@@ -4074,11 +4074,16 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba)
min_sleep_time_us = min_sleep_time_us =
MIN_DELAY_BEFORE_DME_CMDS_US - delta; MIN_DELAY_BEFORE_DME_CMDS_US - delta;
else else
return; /* no more delay required */ min_sleep_time_us = 0; /* no more delay required */
} }
/* allow sleep for extra 50us if needed */ if (min_sleep_time_us > 0) {
usleep_range(min_sleep_time_us, min_sleep_time_us + 50); /* allow sleep for extra 50us if needed */
usleep_range(min_sleep_time_us, min_sleep_time_us + 50);
}
/* update the last_dme_cmd_tstamp */
hba->last_dme_cmd_tstamp = ktime_get();
} }
/** /**

View File

@@ -592,16 +592,25 @@ int u_audio_start_capture(struct g_audio *audio_dev)
struct usb_ep *ep, *ep_fback; struct usb_ep *ep, *ep_fback;
struct uac_rtd_params *prm; struct uac_rtd_params *prm;
struct uac_params *params = &audio_dev->params; struct uac_params *params = &audio_dev->params;
int req_len, i; int req_len, i, ret;
prm = &uac->c_prm; prm = &uac->c_prm;
dev_dbg(dev, "start capture with rate %d\n", prm->srate); dev_dbg(dev, "start capture with rate %d\n", prm->srate);
ep = audio_dev->out_ep; ep = audio_dev->out_ep;
config_ep_by_speed(gadget, &audio_dev->func, ep); ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
if (ret < 0) {
dev_err(dev, "config_ep_by_speed for out_ep failed (%d)\n", ret);
return ret;
}
req_len = ep->maxpacket; req_len = ep->maxpacket;
prm->ep_enabled = true; prm->ep_enabled = true;
usb_ep_enable(ep); ret = usb_ep_enable(ep);
if (ret < 0) {
dev_err(dev, "usb_ep_enable failed for out_ep (%d)\n", ret);
return ret;
}
for (i = 0; i < params->req_number; i++) { for (i = 0; i < params->req_number; i++) {
if (!prm->reqs[i]) { if (!prm->reqs[i]) {
@@ -629,9 +638,18 @@ int u_audio_start_capture(struct g_audio *audio_dev)
return 0; return 0;
/* Setup feedback endpoint */ /* Setup feedback endpoint */
config_ep_by_speed(gadget, &audio_dev->func, ep_fback); ret = config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
if (ret < 0) {
dev_err(dev, "config_ep_by_speed in_ep_fback failed (%d)\n", ret);
return ret; // TODO: Clean up out_ep
}
prm->fb_ep_enabled = true; prm->fb_ep_enabled = true;
usb_ep_enable(ep_fback); ret = usb_ep_enable(ep_fback);
if (ret < 0) {
dev_err(dev, "usb_ep_enable failed for in_ep_fback (%d)\n", ret);
return ret; // TODO: Clean up out_ep
}
req_len = ep_fback->maxpacket; req_len = ep_fback->maxpacket;
req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC); req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC);
@@ -687,13 +705,17 @@ int u_audio_start_playback(struct g_audio *audio_dev)
struct uac_params *params = &audio_dev->params; struct uac_params *params = &audio_dev->params;
unsigned int factor; unsigned int factor;
const struct usb_endpoint_descriptor *ep_desc; const struct usb_endpoint_descriptor *ep_desc;
int req_len, i; int req_len, i, ret;
unsigned int p_pktsize; unsigned int p_pktsize;
prm = &uac->p_prm; prm = &uac->p_prm;
dev_dbg(dev, "start playback with rate %d\n", prm->srate); dev_dbg(dev, "start playback with rate %d\n", prm->srate);
ep = audio_dev->in_ep; ep = audio_dev->in_ep;
config_ep_by_speed(gadget, &audio_dev->func, ep); ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
if (ret < 0) {
dev_err(dev, "config_ep_by_speed for in_ep failed (%d)\n", ret);
return ret;
}
ep_desc = ep->desc; ep_desc = ep->desc;
/* /*
@@ -720,7 +742,11 @@ int u_audio_start_playback(struct g_audio *audio_dev)
uac->p_residue_mil = 0; uac->p_residue_mil = 0;
prm->ep_enabled = true; prm->ep_enabled = true;
usb_ep_enable(ep); ret = usb_ep_enable(ep);
if (ret < 0) {
dev_err(dev, "usb_ep_enable failed for in_ep (%d)\n", ret);
return ret;
}
for (i = 0; i < params->req_number; i++) { for (i = 0; i < params->req_number; i++) {
if (!prm->reqs[i]) { if (!prm->reqs[i]) {

View File

@@ -1446,6 +1446,7 @@ void gserial_suspend(struct gserial *gser)
spin_lock(&port->port_lock); spin_lock(&port->port_lock);
spin_unlock(&serial_port_lock); spin_unlock(&serial_port_lock);
port->suspended = true; port->suspended = true;
port->start_delayed = true;
spin_unlock_irqrestore(&port->port_lock, flags); spin_unlock_irqrestore(&port->port_lock, flags);
} }
EXPORT_SYMBOL_GPL(gserial_suspend); EXPORT_SYMBOL_GPL(gserial_suspend);

View File

@@ -118,12 +118,10 @@ int usb_ep_enable(struct usb_ep *ep)
goto out; goto out;
/* UDC drivers can't handle endpoints with maxpacket size 0 */ /* UDC drivers can't handle endpoints with maxpacket size 0 */
if (usb_endpoint_maxp(ep->desc) == 0) { if (!ep->desc || usb_endpoint_maxp(ep->desc) == 0) {
/* WARN_ONCE(1, "%s: ep%d (%s) has %s\n", __func__, ep->address, ep->name,
* We should log an error message here, but we can't call (!ep->desc) ? "NULL descriptor" : "maxpacket 0");
* dev_err() because there's no way to find the gadget
* given only ep.
*/
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }

View File

@@ -69,6 +69,11 @@ static void usb_debug_process_read_urb(struct urb *urb)
usb_serial_generic_process_read_urb(urb); usb_serial_generic_process_read_urb(urb);
} }
static void usb_debug_init_termios(struct tty_struct *tty)
{
tty->termios.c_lflag &= ~(ECHO | ECHONL);
}
static struct usb_serial_driver debug_device = { static struct usb_serial_driver debug_device = {
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
@@ -78,6 +83,7 @@ static struct usb_serial_driver debug_device = {
.num_ports = 1, .num_ports = 1,
.bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE,
.break_ctl = usb_debug_break_ctl, .break_ctl = usb_debug_break_ctl,
.init_termios = usb_debug_init_termios,
.process_read_urb = usb_debug_process_read_urb, .process_read_urb = usb_debug_process_read_urb,
}; };
@@ -89,6 +95,7 @@ static struct usb_serial_driver dbc_device = {
.id_table = dbc_id_table, .id_table = dbc_id_table,
.num_ports = 1, .num_ports = 1,
.break_ctl = usb_debug_break_ctl, .break_ctl = usb_debug_break_ctl,
.init_termios = usb_debug_init_termios,
.process_read_urb = usb_debug_process_read_urb, .process_read_urb = usb_debug_process_read_urb,
}; };

View File

@@ -745,6 +745,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
* *
*/ */
if (usb_pipedevice(urb->pipe) == 0) { if (usb_pipedevice(urb->pipe) == 0) {
struct usb_device *old;
__u8 type = usb_pipetype(urb->pipe); __u8 type = usb_pipetype(urb->pipe);
struct usb_ctrlrequest *ctrlreq = struct usb_ctrlrequest *ctrlreq =
(struct usb_ctrlrequest *) urb->setup_packet; (struct usb_ctrlrequest *) urb->setup_packet;
@@ -755,14 +756,15 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
goto no_need_xmit; goto no_need_xmit;
} }
old = vdev->udev;
switch (ctrlreq->bRequest) { switch (ctrlreq->bRequest) {
case USB_REQ_SET_ADDRESS: case USB_REQ_SET_ADDRESS:
/* set_address may come when a device is reset */ /* set_address may come when a device is reset */
dev_info(dev, "SetAddress Request (%d) to port %d\n", dev_info(dev, "SetAddress Request (%d) to port %d\n",
ctrlreq->wValue, vdev->rhport); ctrlreq->wValue, vdev->rhport);
usb_put_dev(vdev->udev);
vdev->udev = usb_get_dev(urb->dev); vdev->udev = usb_get_dev(urb->dev);
usb_put_dev(old);
spin_lock(&vdev->ud.lock); spin_lock(&vdev->ud.lock);
vdev->ud.status = VDEV_ST_USED; vdev->ud.status = VDEV_ST_USED;
@@ -781,8 +783,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
usbip_dbg_vhci_hc( usbip_dbg_vhci_hc(
"Not yet?:Get_Descriptor to device 0 (get max pipe size)\n"); "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n");
usb_put_dev(vdev->udev);
vdev->udev = usb_get_dev(urb->dev); vdev->udev = usb_get_dev(urb->dev);
usb_put_dev(old);
goto out; goto out;
default: default:
@@ -1067,6 +1069,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
static void vhci_device_reset(struct usbip_device *ud) static void vhci_device_reset(struct usbip_device *ud)
{ {
struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
struct usb_device *old = vdev->udev;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ud->lock, flags); spin_lock_irqsave(&ud->lock, flags);
@@ -1074,8 +1077,8 @@ static void vhci_device_reset(struct usbip_device *ud)
vdev->speed = 0; vdev->speed = 0;
vdev->devid = 0; vdev->devid = 0;
usb_put_dev(vdev->udev);
vdev->udev = NULL; vdev->udev = NULL;
usb_put_dev(old);
if (ud->tcp_socket) { if (ud->tcp_socket) {
sockfd_put(ud->tcp_socket); sockfd_put(ud->tcp_socket);

View File

@@ -1294,13 +1294,7 @@ static vm_fault_t vhost_vdpa_fault(struct vm_fault *vmf)
notify = ops->get_vq_notification(vdpa, index); notify = ops->get_vq_notification(vdpa, index);
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); return vmf_insert_pfn(vma, vmf->address & PAGE_MASK, PFN_DOWN(notify.addr));
if (remap_pfn_range(vma, vmf->address & PAGE_MASK,
PFN_DOWN(notify.addr), PAGE_SIZE,
vma->vm_page_prot))
return VM_FAULT_SIGBUS;
return VM_FAULT_NOPAGE;
} }
static const struct vm_operations_struct vhost_vdpa_vm_ops = { static const struct vm_operations_struct vhost_vdpa_vm_ops = {

View File

@@ -1553,6 +1553,7 @@ struct btrfs_drop_extents_args {
struct btrfs_file_private { struct btrfs_file_private {
void *filldir_buf; void *filldir_buf;
u64 last_index; u64 last_index;
bool fsync_skip_inode_lock;
}; };

View File

@@ -1526,21 +1526,37 @@ relock:
* So here we disable page faults in the iov_iter and then retry if we * So here we disable page faults in the iov_iter and then retry if we
* got -EFAULT, faulting in the pages before the retry. * got -EFAULT, faulting in the pages before the retry.
*/ */
again:
from->nofault = true; from->nofault = true;
dio = btrfs_dio_write(iocb, from, written); dio = btrfs_dio_write(iocb, from, written);
from->nofault = false; from->nofault = false;
/* if (IS_ERR_OR_NULL(dio)) {
* iomap_dio_complete() will call btrfs_sync_file() if we have a dsync
* iocb, and that needs to lock the inode. So unlock it before calling
* iomap_dio_complete() to avoid a deadlock.
*/
btrfs_inode_unlock(inode, ilock_flags);
if (IS_ERR_OR_NULL(dio))
err = PTR_ERR_OR_ZERO(dio); err = PTR_ERR_OR_ZERO(dio);
else } else {
struct btrfs_file_private stack_private = { 0 };
struct btrfs_file_private *private;
const bool have_private = (file->private_data != NULL);
if (!have_private)
file->private_data = &stack_private;
/*
* If we have a synchoronous write, we must make sure the fsync
* triggered by the iomap_dio_complete() call below doesn't
* deadlock on the inode lock - we are already holding it and we
* can't call it after unlocking because we may need to complete
* partial writes due to the input buffer (or parts of it) not
* being already faulted in.
*/
private = file->private_data;
private->fsync_skip_inode_lock = true;
err = iomap_dio_complete(dio); err = iomap_dio_complete(dio);
private->fsync_skip_inode_lock = false;
if (!have_private)
file->private_data = NULL;
}
/* No increment (+=) because iomap returns a cumulative value. */ /* No increment (+=) because iomap returns a cumulative value. */
if (err > 0) if (err > 0)
@@ -1567,10 +1583,12 @@ relock:
} else { } else {
fault_in_iov_iter_readable(from, left); fault_in_iov_iter_readable(from, left);
prev_left = left; prev_left = left;
goto relock; goto again;
} }
} }
btrfs_inode_unlock(inode, ilock_flags);
/* /*
* If 'err' is -ENOTBLK or we have not written all data, then it means * If 'err' is -ENOTBLK or we have not written all data, then it means
* we must fallback to buffered IO. * we must fallback to buffered IO.
@@ -1777,6 +1795,7 @@ static inline bool skip_inode_logging(const struct btrfs_log_ctx *ctx)
*/ */
int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
{ {
struct btrfs_file_private *private = file->private_data;
struct dentry *dentry = file_dentry(file); struct dentry *dentry = file_dentry(file);
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -1786,6 +1805,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
int ret = 0, err; int ret = 0, err;
u64 len; u64 len;
bool full_sync; bool full_sync;
const bool skip_ilock = (private ? private->fsync_skip_inode_lock : false);
trace_btrfs_sync_file(file, datasync); trace_btrfs_sync_file(file, datasync);
@@ -1813,7 +1833,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
if (ret) if (ret)
goto out; goto out;
btrfs_inode_lock(inode, BTRFS_ILOCK_MMAP); if (skip_ilock)
down_write(&BTRFS_I(inode)->i_mmap_lock);
else
btrfs_inode_lock(inode, BTRFS_ILOCK_MMAP);
atomic_inc(&root->log_batch); atomic_inc(&root->log_batch);
@@ -1837,7 +1860,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
*/ */
ret = start_ordered_ops(inode, start, end); ret = start_ordered_ops(inode, start, end);
if (ret) { if (ret) {
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP); if (skip_ilock)
up_write(&BTRFS_I(inode)->i_mmap_lock);
else
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
goto out; goto out;
} }
@@ -1940,7 +1966,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
* file again, but that will end up using the synchronization * file again, but that will end up using the synchronization
* inside btrfs_sync_log to keep things safe. * inside btrfs_sync_log to keep things safe.
*/ */
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP); if (skip_ilock)
up_write(&BTRFS_I(inode)->i_mmap_lock);
else
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
if (ret == BTRFS_NO_LOG_SYNC) { if (ret == BTRFS_NO_LOG_SYNC) {
ret = btrfs_end_transaction(trans); ret = btrfs_end_transaction(trans);
@@ -2008,7 +2037,10 @@ out:
out_release_extents: out_release_extents:
btrfs_release_log_ctx_extents(&ctx); btrfs_release_log_ctx_extents(&ctx);
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP); if (skip_ilock)
up_write(&BTRFS_I(inode)->i_mmap_lock);
else
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
goto out; goto out;
} }

View File

@@ -865,6 +865,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
spin_unlock(&ctl->tree_lock); spin_unlock(&ctl->tree_lock);
btrfs_err(fs_info, btrfs_err(fs_info,
"Duplicate entries in free space cache, dumping"); "Duplicate entries in free space cache, dumping");
kmem_cache_free(btrfs_free_space_bitmap_cachep, e->bitmap);
kmem_cache_free(btrfs_free_space_cachep, e); kmem_cache_free(btrfs_free_space_cachep, e);
goto free_cache; goto free_cache;
} }

View File

@@ -9,7 +9,7 @@
struct root_name_map { struct root_name_map {
u64 id; u64 id;
char name[16]; const char *name;
}; };
static const struct root_name_map root_map[] = { static const struct root_name_map root_map[] = {

View File

@@ -1439,7 +1439,11 @@ int ext4_inlinedir_to_tree(struct file *dir_file,
hinfo->hash = EXT4_DIRENT_HASH(de); hinfo->hash = EXT4_DIRENT_HASH(de);
hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de); hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de);
} else { } else {
ext4fs_dirhash(dir, de->name, de->name_len, hinfo); err = ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
if (err) {
ret = err;
goto out;
}
} }
if ((hinfo->hash < start_hash) || if ((hinfo->hash < start_hash) ||
((hinfo->hash == start_hash) && ((hinfo->hash == start_hash) &&

View File

@@ -2226,8 +2226,7 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) { if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {
ext4_fsblk_t start; ext4_fsblk_t start;
start = ext4_group_first_block_no(ac->ac_sb, e4b->bd_group) + start = ext4_grp_offs_to_block(ac->ac_sb, &ex);
ex.fe_start;
/* use do_div to get remainder (would be 64-bit modulo) */ /* use do_div to get remainder (would be 64-bit modulo) */
if (do_div(start, sbi->s_stripe) == 0) { if (do_div(start, sbi->s_stripe) == 0) {
ac->ac_found++; ac->ac_found++;

View File

@@ -409,6 +409,7 @@ repeat:
tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
if (!tmp) { if (!tmp) {
brelse(new_bh); brelse(new_bh);
free_buffer_head(new_bh);
return -ENOMEM; return -ENOMEM;
} }
spin_lock(&jh_in->b_state_lock); spin_lock(&jh_in->b_state_lock);

View File

@@ -960,7 +960,7 @@ static int cifs_security_flags_proc_open(struct inode *inode, struct file *file)
static void static void
cifs_security_flags_handle_must_flags(unsigned int *flags) cifs_security_flags_handle_must_flags(unsigned int *flags)
{ {
unsigned int signflags = *flags & CIFSSEC_MUST_SIGN; unsigned int signflags = *flags & (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL);
if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
*flags = CIFSSEC_MUST_KRB5; *flags = CIFSSEC_MUST_KRB5;

View File

@@ -1820,7 +1820,7 @@ static inline bool is_retryable_error(int error)
#define CIFSSEC_MAY_SIGN 0x00001 #define CIFSSEC_MAY_SIGN 0x00001
#define CIFSSEC_MAY_NTLMV2 0x00004 #define CIFSSEC_MAY_NTLMV2 0x00004
#define CIFSSEC_MAY_KRB5 0x00008 #define CIFSSEC_MAY_KRB5 0x00008
#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ #define CIFSSEC_MAY_SEAL 0x00040
#define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */ #define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */
#define CIFSSEC_MUST_SIGN 0x01001 #define CIFSSEC_MUST_SIGN 0x01001
@@ -1830,11 +1830,11 @@ require use of the stronger protocol */
#define CIFSSEC_MUST_NTLMV2 0x04004 #define CIFSSEC_MUST_NTLMV2 0x04004
#define CIFSSEC_MUST_KRB5 0x08008 #define CIFSSEC_MUST_KRB5 0x08008
#ifdef CONFIG_CIFS_UPCALL #ifdef CONFIG_CIFS_UPCALL
#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */ #define CIFSSEC_MASK 0xCF0CF /* flags supported if no weak allowed */
#else #else
#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */ #define CIFSSEC_MASK 0xC70C7 /* flags supported if no weak allowed */
#endif /* UPCALL */ #endif /* UPCALL */
#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ #define CIFSSEC_MUST_SEAL 0x40040
#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */ #define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP | CIFSSEC_MAY_SEAL) #define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP | CIFSSEC_MAY_SEAL)

View File

@@ -80,6 +80,9 @@ int smb3_encryption_required(const struct cifs_tcon *tcon)
if (tcon->seal && if (tcon->seal &&
(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
return 1; return 1;
if (((global_secflags & CIFSSEC_MUST_SEAL) == CIFSSEC_MUST_SEAL) &&
(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
return 1;
return 0; return 0;
} }

View File

@@ -22,6 +22,7 @@
#include "udfdecl.h" #include "udfdecl.h"
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/overflow.h>
#include "udf_i.h" #include "udf_i.h"
#include "udf_sb.h" #include "udf_sb.h"
@@ -144,7 +145,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
struct udf_part_map *partmap;
unsigned long block; unsigned long block;
unsigned long block_group; unsigned long block_group;
unsigned long bit; unsigned long bit;
@@ -153,19 +153,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
unsigned long overflow; unsigned long overflow;
mutex_lock(&sbi->s_alloc_mutex); mutex_lock(&sbi->s_alloc_mutex);
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; /* We make sure this cannot overflow when mounting the filesystem */
if (bloc->logicalBlockNum + count < count ||
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
udf_debug("%u < %d || %u + %u > %u\n",
bloc->logicalBlockNum, 0,
bloc->logicalBlockNum, count,
partmap->s_partition_len);
goto error_return;
}
block = bloc->logicalBlockNum + offset + block = bloc->logicalBlockNum + offset +
(sizeof(struct spaceBitmapDesc) << 3); (sizeof(struct spaceBitmapDesc) << 3);
do { do {
overflow = 0; overflow = 0;
block_group = block >> (sb->s_blocksize_bits + 3); block_group = block >> (sb->s_blocksize_bits + 3);
@@ -395,7 +385,6 @@ static void udf_table_free_blocks(struct super_block *sb,
uint32_t count) uint32_t count)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *partmap;
uint32_t start, end; uint32_t start, end;
uint32_t elen; uint32_t elen;
struct kernel_lb_addr eloc; struct kernel_lb_addr eloc;
@@ -404,16 +393,6 @@ static void udf_table_free_blocks(struct super_block *sb,
struct udf_inode_info *iinfo; struct udf_inode_info *iinfo;
mutex_lock(&sbi->s_alloc_mutex); mutex_lock(&sbi->s_alloc_mutex);
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
if (bloc->logicalBlockNum + count < count ||
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
udf_debug("%u < %d || %u + %u > %u\n",
bloc->logicalBlockNum, 0,
bloc->logicalBlockNum, count,
partmap->s_partition_len);
goto error_return;
}
iinfo = UDF_I(table); iinfo = UDF_I(table);
udf_add_free_space(sb, sbi->s_partition, count); udf_add_free_space(sb, sbi->s_partition, count);
@@ -688,6 +667,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,
{ {
uint16_t partition = bloc->partitionReferenceNum; uint16_t partition = bloc->partitionReferenceNum;
struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
uint32_t blk;
if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) ||
check_add_overflow(blk, count, &blk) ||
bloc->logicalBlockNum + count > map->s_partition_len) {
udf_debug("Invalid request to free blocks: (%d, %u), off %u, "
"len %u, partition len %u\n",
partition, bloc->logicalBlockNum, offset, count,
map->s_partition_len);
return;
}
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap,

View File

@@ -2960,7 +2960,7 @@ xlog_do_recovery_pass(
int error = 0, h_size, h_len; int error = 0, h_size, h_len;
int error2 = 0; int error2 = 0;
int bblks, split_bblks; int bblks, split_bblks;
int hblks, split_hblks, wrapped_hblks; int hblks = 1, split_hblks, wrapped_hblks;
int i; int i;
struct hlist_head rhash[XLOG_RHASH_SIZE]; struct hlist_head rhash[XLOG_RHASH_SIZE];
LIST_HEAD (buffer_list); LIST_HEAD (buffer_list);
@@ -3016,14 +3016,22 @@ xlog_do_recovery_pass(
if (error) if (error)
goto bread_err1; goto bread_err1;
hblks = xlog_logrec_hblks(log, rhead); /*
if (hblks != 1) { * This open codes xlog_logrec_hblks so that we can reuse the
kmem_free(hbp); * fixed up h_size value calculated above. Without that we'd
hbp = xlog_alloc_buffer(log, hblks); * still allocate the buffer based on the incorrect on-disk
* size.
*/
if (h_size > XLOG_HEADER_CYCLE_SIZE &&
(rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) {
hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE);
if (hblks > 1) {
kmem_free(hbp);
hbp = xlog_alloc_buffer(log, hblks);
}
} }
} else { } else {
ASSERT(log->l_sectBBsize == 1); ASSERT(log->l_sectBBsize == 1);
hblks = 1;
hbp = xlog_alloc_buffer(log, 1); hbp = xlog_alloc_buffer(log, 1);
h_size = XLOG_BIG_RECORD_BSIZE; h_size = XLOG_BIG_RECORD_BSIZE;
} }

View File

@@ -105,14 +105,13 @@ static inline bool blk_integrity_rq(struct request *rq)
} }
/* /*
* Return the first bvec that contains integrity data. Only drivers that are * Return the current bvec that contains the integrity data. bip_iter may be
* limited to a single integrity segment should use this helper. * advanced to iterate over the integrity data.
*/ */
static inline struct bio_vec *rq_integrity_vec(struct request *rq) static inline struct bio_vec rq_integrity_vec(struct request *rq)
{ {
if (WARN_ON_ONCE(queue_max_integrity_segments(rq->q) > 1)) return mp_bvec_iter_bvec(rq->bio->bi_integrity->bip_vec,
return NULL; rq->bio->bi_integrity->bip_iter);
return rq->bio->bi_integrity->bip_vec;
} }
#else /* CONFIG_BLK_DEV_INTEGRITY */ #else /* CONFIG_BLK_DEV_INTEGRITY */
static inline int blk_rq_count_integrity_sg(struct request_queue *q, static inline int blk_rq_count_integrity_sg(struct request_queue *q,
@@ -176,9 +175,10 @@ static inline int blk_integrity_rq(struct request *rq)
return 0; return 0;
} }
static inline struct bio_vec *rq_integrity_vec(struct request *rq) static inline struct bio_vec rq_integrity_vec(struct request *rq)
{ {
return NULL; /* the optimizer will remove all calls to this function */
return (struct bio_vec){ };
} }
#endif /* CONFIG_BLK_DEV_INTEGRITY */ #endif /* CONFIG_BLK_DEV_INTEGRITY */
#endif /* _LINUX_BLK_INTEGRITY_H */ #endif /* _LINUX_BLK_INTEGRITY_H */

View File

@@ -291,7 +291,19 @@ static inline void timer_probe(void) {}
#define TIMER_ACPI_DECLARE(name, table_id, fn) \ #define TIMER_ACPI_DECLARE(name, table_id, fn) \
ACPI_DECLARE_PROBE_ENTRY(timer, name, table_id, 0, NULL, 0, fn) ACPI_DECLARE_PROBE_ENTRY(timer, name, table_id, 0, NULL, 0, fn)
extern ulong max_cswd_read_retries; static inline unsigned int clocksource_get_max_watchdog_retry(void)
{
/*
* When system is in the boot phase or under heavy workload, there
* can be random big latencies during the clocksource/watchdog
* read, so allow retries to filter the noise latency. As the
* latency's frequency and maximum value goes up with the number of
* CPUs, scale the number of retries with the number of online
* CPUs.
*/
return (ilog2(num_online_cpus()) / 2) + 1;
}
void clocksource_verify_percpu(struct clocksource *cs); void clocksource_verify_percpu(struct clocksource *cs);
#endif /* _LINUX_CLOCKSOURCE_H */ #endif /* _LINUX_CLOCKSOURCE_H */

View File

@@ -2109,6 +2109,8 @@
#define PCI_VENDOR_ID_CHELSIO 0x1425 #define PCI_VENDOR_ID_CHELSIO 0x1425
#define PCI_VENDOR_ID_EDIMAX 0x1432
#define PCI_VENDOR_ID_ADLINK 0x144a #define PCI_VENDOR_ID_ADLINK 0x144a
#define PCI_VENDOR_ID_SAMSUNG 0x144d #define PCI_VENDOR_ID_SAMSUNG 0x144d

View File

@@ -11,7 +11,6 @@
#define CPU_PROFILING 1 #define CPU_PROFILING 1
#define SCHED_PROFILING 2 #define SCHED_PROFILING 2
#define SLEEP_PROFILING 3
#define KVM_PROFILING 4 #define KVM_PROFILING 4
struct proc_dir_entry; struct proc_dir_entry;

View File

@@ -843,7 +843,6 @@ do { \
struct perf_event; struct perf_event;
DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); DECLARE_PER_CPU(struct pt_regs, perf_trace_regs);
DECLARE_PER_CPU(int, bpf_kprobe_override);
extern int perf_trace_init(struct perf_event *event); extern int perf_trace_init(struct perf_event *event);
extern void perf_trace_destroy(struct perf_event *event); extern void perf_trace_destroy(struct perf_event *event);

View File

@@ -132,18 +132,26 @@ void rt6_age_exceptions(struct fib6_info *f6i, struct fib6_gc_args *gc_args,
static inline int ip6_route_get_saddr(struct net *net, struct fib6_info *f6i, static inline int ip6_route_get_saddr(struct net *net, struct fib6_info *f6i,
const struct in6_addr *daddr, const struct in6_addr *daddr,
unsigned int prefs, unsigned int prefs, int l3mdev_index,
struct in6_addr *saddr) struct in6_addr *saddr)
{ {
struct net_device *l3mdev;
struct net_device *dev;
bool same_vrf;
int err = 0; int err = 0;
if (f6i && f6i->fib6_prefsrc.plen) { rcu_read_lock();
*saddr = f6i->fib6_prefsrc.addr;
} else {
struct net_device *dev = f6i ? fib6_info_nh_dev(f6i) : NULL;
err = ipv6_dev_get_saddr(net, dev, daddr, prefs, saddr); l3mdev = dev_get_by_index_rcu(net, l3mdev_index);
} if (!f6i || !f6i->fib6_prefsrc.plen || l3mdev)
dev = f6i ? fib6_info_nh_dev(f6i) : NULL;
same_vrf = !l3mdev || l3mdev_master_dev_rcu(dev) == l3mdev;
if (f6i && f6i->fib6_prefsrc.plen && same_vrf)
*saddr = f6i->fib6_prefsrc.addr;
else
err = ipv6_dev_get_saddr(net, same_vrf ? dev : l3mdev, daddr, prefs, saddr);
rcu_read_unlock();
return err; return err;
} }

View File

@@ -387,7 +387,7 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
return (void *)expr->data; return (void *)expr->data;
} }
int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src); int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src, gfp_t gfp);
void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr); void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
int nft_expr_dump(struct sk_buff *skb, unsigned int attr, int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
const struct nft_expr *expr); const struct nft_expr *expr);
@@ -889,7 +889,7 @@ struct nft_expr_ops {
struct nft_regs *regs, struct nft_regs *regs,
const struct nft_pktinfo *pkt); const struct nft_pktinfo *pkt);
int (*clone)(struct nft_expr *dst, int (*clone)(struct nft_expr *dst,
const struct nft_expr *src); const struct nft_expr *src, gfp_t gfp);
unsigned int size; unsigned int size;
int (*init)(const struct nft_ctx *ctx, int (*init)(const struct nft_ctx *ctx,

View File

@@ -10,25 +10,25 @@
TRACE_EVENT(ifs_status, TRACE_EVENT(ifs_status,
TP_PROTO(int cpu, union ifs_scan activate, union ifs_status status), TP_PROTO(int cpu, int start, int stop, u64 status),
TP_ARGS(cpu, activate, status), TP_ARGS(cpu, start, stop, status),
TP_STRUCT__entry( TP_STRUCT__entry(
__field( u64, status ) __field( u64, status )
__field( int, cpu ) __field( int, cpu )
__field( u8, start ) __field( u16, start )
__field( u8, stop ) __field( u16, stop )
), ),
TP_fast_assign( TP_fast_assign(
__entry->cpu = cpu; __entry->cpu = cpu;
__entry->start = activate.start; __entry->start = start;
__entry->stop = activate.stop; __entry->stop = stop;
__entry->status = status.data; __entry->status = status;
), ),
TP_printk("cpu: %d, start: %.2x, stop: %.2x, status: %llx", TP_printk("cpu: %d, start: %.4x, stop: %.4x, status: %.16llx",
__entry->cpu, __entry->cpu,
__entry->start, __entry->start,
__entry->stop, __entry->stop,

View File

@@ -491,6 +491,7 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node,
flags = IRQD_AFFINITY_MANAGED | flags = IRQD_AFFINITY_MANAGED |
IRQD_MANAGED_SHUTDOWN; IRQD_MANAGED_SHUTDOWN;
} }
flags |= IRQD_AFFINITY_SET;
mask = &affinity->mask; mask = &affinity->mask;
node = cpu_to_node(cpumask_first(mask)); node = cpu_to_node(cpumask_first(mask));
affinity++; affinity++;

View File

@@ -199,7 +199,7 @@ void static_key_disable_cpuslocked(struct static_key *key)
} }
jump_label_lock(); jump_label_lock();
if (atomic_cmpxchg(&key->enabled, 1, 0)) if (atomic_cmpxchg(&key->enabled, 1, 0) == 1)
jump_label_update(key); jump_label_update(key);
jump_label_unlock(); jump_label_unlock();
} }

View File

@@ -161,6 +161,15 @@ static void kcov_remote_area_put(struct kcov_remote_area *area,
kmsan_unpoison_memory(&area->list, sizeof(area->list)); kmsan_unpoison_memory(&area->list, sizeof(area->list));
} }
/*
* Unlike in_serving_softirq(), this function returns false when called during
* a hardirq or an NMI that happened in the softirq context.
*/
static inline bool in_softirq_really(void)
{
return in_serving_softirq() && !in_hardirq() && !in_nmi();
}
static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t) static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t)
{ {
unsigned int mode; unsigned int mode;
@@ -170,7 +179,7 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru
* so we ignore code executed in interrupts, unless we are in a remote * so we ignore code executed in interrupts, unless we are in a remote
* coverage collection section in a softirq. * coverage collection section in a softirq.
*/ */
if (!in_task() && !(in_serving_softirq() && t->kcov_softirq)) if (!in_task() && !(in_softirq_really() && t->kcov_softirq))
return false; return false;
mode = READ_ONCE(t->kcov_mode); mode = READ_ONCE(t->kcov_mode);
/* /*
@@ -847,7 +856,7 @@ void kcov_remote_start(u64 handle)
if (WARN_ON(!kcov_check_handle(handle, true, true, true))) if (WARN_ON(!kcov_check_handle(handle, true, true, true)))
return; return;
if (!in_task() && !in_serving_softirq()) if (!in_task() && !in_softirq_really())
return; return;
local_lock_irqsave(&kcov_percpu_data.lock, flags); local_lock_irqsave(&kcov_percpu_data.lock, flags);
@@ -989,7 +998,7 @@ void kcov_remote_stop(void)
int sequence; int sequence;
unsigned long flags; unsigned long flags;
if (!in_task() && !in_serving_softirq()) if (!in_task() && !in_softirq_really())
return; return;
local_lock_irqsave(&kcov_percpu_data.lock, flags); local_lock_irqsave(&kcov_percpu_data.lock, flags);

View File

@@ -1552,8 +1552,8 @@ static bool is_cfi_preamble_symbol(unsigned long addr)
if (lookup_symbol_name(addr, symbuf)) if (lookup_symbol_name(addr, symbuf))
return false; return false;
return str_has_prefix("__cfi_", symbuf) || return str_has_prefix(symbuf, "__cfi_") ||
str_has_prefix("__pfx_", symbuf); str_has_prefix(symbuf, "__pfx_");
} }
static int check_kprobe_address_safe(struct kprobe *p, static int check_kprobe_address_safe(struct kprobe *p,

View File

@@ -508,6 +508,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
ps.chunk_size = max(ps.chunk_size, job->min_chunk); ps.chunk_size = max(ps.chunk_size, job->min_chunk);
ps.chunk_size = roundup(ps.chunk_size, job->align); ps.chunk_size = roundup(ps.chunk_size, job->align);
/*
* chunk_size can be 0 if the caller sets min_chunk to 0. So force it
* to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
*/
if (!ps.chunk_size)
ps.chunk_size = 1U;
list_for_each_entry(pw, &works, pw_list) list_for_each_entry(pw, &works, pw_list)
queue_work(system_unbound_wq, &pw->pw_work); queue_work(system_unbound_wq, &pw->pw_work);

View File

@@ -57,20 +57,11 @@ static DEFINE_MUTEX(profile_flip_mutex);
int profile_setup(char *str) int profile_setup(char *str)
{ {
static const char schedstr[] = "schedule"; static const char schedstr[] = "schedule";
static const char sleepstr[] = "sleep";
static const char kvmstr[] = "kvm"; static const char kvmstr[] = "kvm";
const char *select = NULL; const char *select = NULL;
int par; int par;
if (!strncmp(str, sleepstr, strlen(sleepstr))) { if (!strncmp(str, schedstr, strlen(schedstr))) {
#ifdef CONFIG_SCHEDSTATS
force_schedstat_enabled();
prof_on = SLEEP_PROFILING;
select = sleepstr;
#else
pr_warn("kernel sleep profiling requires CONFIG_SCHEDSTATS\n");
#endif /* CONFIG_SCHEDSTATS */
} else if (!strncmp(str, schedstr, strlen(schedstr))) {
prof_on = SCHED_PROFILING; prof_on = SCHED_PROFILING;
select = schedstr; select = schedstr;
} else if (!strncmp(str, kvmstr, strlen(kvmstr))) { } else if (!strncmp(str, kvmstr, strlen(kvmstr))) {

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