6.11.2-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 538/695 KVM: Use dedicated mutex to protect kvm_usage_count to avoid deadlock
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 44d17459626052a2390457e550a12cb973506b2f upstream.
Use a dedicated mutex to guard kvm_usage_count to fix a potential deadlock on x86 due to a chain of locks and SRCU synchronizations. Translating the below lockdep splat, CPU1 #6 will wait on CPU0 #1, CPU0 #8 will wait on CPU2 #3, and CPU2 #7 will wait on CPU1 #4 (if there's a writer, due to the fairness of r/w semaphores).
CPU0 CPU1 CPU2
1 lock(&kvm->slots_lock);
2 lock(&vcpu->mutex);
3 lock(&kvm->srcu);
4 lock(cpu_hotplug_lock); 5 lock(kvm_lock); 6 lock(&kvm->slots_lock);
7 lock(cpu_hotplug_lock);
8 sync(&kvm->srcu);
Note, there are likely more potential deadlocks in KVM x86, e.g. the same pattern of taking cpu_hotplug_lock outside of kvm_lock likely exists with __kvmclock_cpufreq_notifier():
cpuhp_cpufreq_online()
|
-> cpufreq_online()
|
-> cpufreq_gov_performance_limits()
|
-> __cpufreq_driver_target()
|
-> __target_index()
|
-> cpufreq_freq_transition_begin()
|
-> cpufreq_notify_transition()
|
-> ... __kvmclock_cpufreq_notifier()But, actually triggering such deadlocks is beyond rare due to the combination of dependencies and timings involved. E.g. the cpufreq notifier is only used on older CPUs without a constant TSC, mucking with the NX hugepage mitigation while VMs are running is very uncommon, and doing so while also onlining/offlining a CPU (necessary to generate contention on cpu_hotplug_lock) would be even more unusual.
The most robust solution to the general cpu_hotplug_lock issue is likely to switch vm_list to be an RCU-protected list, e.g. so that x86's cpufreq notifier doesn't to take kvm_lock. For now, settle for fixing the most blatant deadlock, as switching to an RCU-protected list is a much more involved change, but add a comment in locking.rst to call out that care needs to be taken when walking holding kvm_lock and walking vm_list.
======================================================
WARNING: possible circular locking dependency detected
6.10.0-smp--c257535a0c9d-pip #330 Tainted: G S O
------------------------------------------------------
tee/35048 is trying to acquire lock:
ff6a80eced71e0a8 (&kvm->slots_lock){+.+.}-{3:3}, at: set_nx_huge_pages+0x179/0x1e0 [kvm]
but task is already holding lock:
ffffffffc07abb08 (kvm_lock){+.+.}-{3:3}, at: set_nx_huge_pages+0x14a/0x1e0 [kvm]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (kvm_lock){+.+.}-{3:3}:
__mutex_lock+0x6a/0xb40
mutex_lock_nested+0x1f/0x30
kvm_dev_ioctl+0x4fb/0xe50 [kvm]
__se_sys_ioctl+0x7b/0xd0
__x64_sys_ioctl+0x21/0x30
x64_sys_call+0x15d0/0x2e60
do_syscall_64+0x83/0x160
entry_SYSCALL_64_after_hwframe+0x76/0x7e-> #2 (cpu_hotplug_lock){++++}-{0:0}:
cpus_read_lock+0x2e/0xb0
static_key_slow_inc+0x16/0x30
kvm_lapic_set_base+0x6a/0x1c0 [kvm]
kvm_set_apic_base+0x8f/0xe0 [kvm]
kvm_set_msr_common+0x9ae/0xf80 [kvm]
vmx_set_msr+0xa54/0xbe0 [kvm_intel]
__kvm_set_msr+0xb6/0x1a0 [kvm]
kvm_arch_vcpu_ioctl+0xeca/0x10c0 [kvm]
kvm_vcpu_ioctl+0x485/0x5b0 [kvm]
__se_sys_ioctl+0x7b/0xd0
__x64_sys_ioctl+0x21/0x30
x64_sys_call+0x15d0/0x2e60
do_syscall_64+0x83/0x160
entry_SYSCALL_64_after_hwframe+0x76/0x7e-> #1 (&kvm->srcu){.+.+}-{0:0}:
__synchronize_srcu+0x44/0x1a0
synchronize_srcu_expedited+0x21/0x30
kvm_swap_active_memslots+0x110/0x1c0 [kvm]
kvm_set_memslot+0x360/0x620 [kvm]
__kvm_set_memory_region+0x27b/0x300 [kvm]
kvm_vm_ioctl_set_memory_region+0x43/0x60 [kvm]
kvm_vm_ioctl+0x295/0x650 [kvm]
__se_sys_ioctl+0x7b/0xd0
__x64_sys_ioctl+0x21/0x30
x64_sys_call+0x15d0/0x2e60
do_syscall_64+0x83/0x160
entry_SYSCALL_64_after_hwframe+0x76/0x7e-> #0 (&kvm->slots_lock){+.+.}-{3:3}:
__lock_acquire+0x15ef/0x2e30
lock_acquire+0xe0/0x260
__mutex_lock+0x6a/0xb40
mutex_lock_nested+0x1f/0x30
set_nx_huge_pages+0x179/0x1e0 [kvm]
param_attr_store+0x93/0x100
module_attr_store+0x22/0x40
sysfs_kf_write+0x81/0xb0
kernfs_fop_write_iter+0x133/0x1d0
vfs_write+0x28d/0x380
ksys_write+0x70/0xe0
__x64_sys_write+0x1f/0x30
x64_sys_call+0x281b/0x2e60
do_syscall_64+0x83/0x160
entry_SYSCALL_64_after_hwframe+0x76/0x7eMessage-ID: <[email protected]>
--- Documentation/virt/kvm/locking.rst | 32 +++++++++++++++++++++++--------- virt/kvm/kvm_main.c | 31 ++++++++++++++++--------------- 2 files changed, 39 insertions(+), 24 deletions(-)
Documentation/virt/kvm/locking.rst +23 -9
@@ -9,7 +9,7 @@ KVM Lock Overview The acquisition orders for mutexes are as follows: -- cpus_read_lock() is taken outside kvm_lock +- cpus_read_lock() is taken outside kvm_lock and kvm_usage_lock - kvm->lock is taken outside vcpu->mutex
@@ -24,6 +24,12 @@ The acquisition orders for mutexes are a are taken on the waiting side when modifying memslots, so MMU notifiers must not take either kvm->slots_lock or kvm->slots_arch_lock. +cpus_read_lock() vs kvm_lock: +- Taking cpus_read_lock() outside of kvm_lock is problematic, despite that + being the official ordering, as it is quite easy to unknowingly trigger + cpus_read_lock() while holding kvm_lock. Use caution when walking vm_list, + e.g. avoid complex operations when possible. + For SRCU: - ``synchronize_srcu(&kvm->srcu)`` is called inside critical sections
@@ -227,10 +233,17 @@ time it will be set using the Dirty trac :Type: mutex :Arch: any :Protects: - vm_list - - kvm_usage_count + +``kvm_usage_lock`` +^^^^^^^^^^^^^^^^^^ + +:Type: mutex +:Arch: any +:Protects: - kvm_usage_count - hardware virtualization enable/disable -:Comment: KVM also disables CPU hotplug via cpus_read_lock() during - enable/disable. +:Comment: Exists because using kvm_lock leads to deadlock (see earlier comment + on cpus_read_lock() vs kvm_lock). Note, KVM also disables CPU hotplug via + cpus_read_lock() when enabling/disabling virtualization. ``kvm->mn_invalidate_lock`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -290,11 +303,12 @@ time it will be set using the Dirty trac wakeup. ``vendor_module_lock`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^ :Type: mutex :Arch: x86 :Protects: loading a vendor module (kvm_amd or kvm_intel) -:Comment: Exists because using kvm_lock leads to deadlock. cpu_hotplug_lock is - taken outside of kvm_lock, e.g. in KVM's CPU online/offline callbacks, and - many operations need to take cpu_hotplug_lock when loading a vendor module, - e.g. updating static calls. +:Comment: Exists because using kvm_lock leads to deadlock. kvm_lock is taken + in notifiers, e.g. __kvmclock_cpufreq_notifier(), that may be invoked while + cpu_hotplug_lock is held, e.g. from cpufreq_boost_trigger_state(), and many + operations need to take cpu_hotplug_lock when loading a vendor module, e.g. + updating static calls.
virt/kvm/kvm_main.c +16 -15
@@ -5575,6 +5575,7 @@ __visible bool kvm_rebooting;EXPORT_SYMBOL_GPL (kvm_rebooting); static DEFINE_PER_CPU(bool, hardware_enabled); +static DEFINE_MUTEX (kvm_usage_lock);static int kvm_usage_count;static int __hardware_enable_nolock (void )
@@ -5607,10 +5608,10 @@ static int kvm_online_cpu(unsigned int c* be enabled. Otherwise running VMs would encounter unrecoverable * errors when scheduled to this CPU. */ -mutex_lock (&kvm_lock); +mutex_lock (&kvm_usage_lock);if (kvm_usage_count) ret =__hardware_enable_nolock (); -mutex_unlock (&kvm_lock); +mutex_unlock (&kvm_usage_lock);return ret; }
@@ -5630,10 +5631,10 @@ static void hardware_disable_nolock(voidstatic int kvm_offline_cpu (unsigned int cpu) { -mutex_lock (&kvm_lock); +mutex_lock (&kvm_usage_lock);if (kvm_usage_count)hardware_disable_nolock (NULL ); -mutex_unlock (&kvm_lock); +mutex_unlock (&kvm_usage_lock);return 0 ; }
@@ -5649,9 +5650,9 @@ static void hardware_disable_all_nolock(static void hardware_disable_all (void ) {cpus_read_lock (); -mutex_lock (&kvm_lock); +mutex_lock (&kvm_usage_lock);hardware_disable_all_nolock (); -mutex_unlock (&kvm_lock); +mutex_unlock (&kvm_usage_lock);cpus_read_unlock (); }
@@ -5682,7 +5683,7 @@ static int hardware_enable_all(void)* enable hardware multiple times. */ cpus_read_lock (); -mutex_lock (&kvm_lock); +mutex_lock (&kvm_usage_lock); r =0 ;
@@ -5696,7 +5697,7 @@ static int hardware_enable_all(void) } } -mutex_unlock (&kvm_lock); +mutex_unlock (&kvm_usage_lock);cpus_read_unlock ();return r;
@@ -5724,13 +5725,13 @@ static int kvm_suspend(void) {/* * Secondary CPUs and CPU hotplug are disabled across the suspend/resume -* callbacks, i.e. no need to acquire kvm_lock to ensure the usage count -* is stable. Assert that kvm_lock is not held to ensure the system -* isn't suspended while KVM is enabling hardware. Hardware enabling -* can be preempted, but the task cannot be frozen until it has dropped -* all locks (userspace tasks are frozen via a fake signal). +* callbacks, i.e. no need to acquire kvm_usage_lock to ensure the usage +* count is stable. Assert that kvm_usage_lock is not held to ensure +* the system isn't suspended while KVM is enabling hardware. Hardware +* enabling can be preempted, but the task cannot be frozen until it has +* dropped all locks (userspace tasks are frozen via a fake signal). */ -lockdep_assert_not_held (&kvm_lock); +lockdep_assert_not_held (&kvm_usage_lock);lockdep_assert_irqs_disabled ();if (kvm_usage_count)
@@ -5740,7 +5741,7 @@ static int kvm_suspend(void)static void kvm_resume (void ) { -lockdep_assert_not_held (&kvm_lock); +lockdep_assert_not_held (&kvm_usage_lock);lockdep_assert_irqs_disabled ();if (kvm_usage_count)
Greg Kroah-Hartman
maintainerPATCH 539/695 drm/amd/display: Skip Recompute DSC Params if no Stream on Link
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
commit 8151a6c13111b465dbabe07c19f572f7cbd16fef upstream.
[why]
Encounter NULL pointer dereference uner mst + dsc setup.
BUG: kernel NULL pointer dereference, address: 0000000000000008
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP NOPTI
CPU: 4 PID: 917 Comm: sway Not tainted 6.3.9-arch1-1 #1 124dc55df4f5272ccb409f39ef4872fc2b3376a2
Hardware name: LENOVO 20NKS01Y00/20NKS01Y00, BIOS R12ET61W(1.31 ) 07/28/2022
RIP: 0010:drm_dp_atomic_find_time_slots+0x5e/0x260 [drm_display_helper]
Code: 01 00 00 48 8b 85 60 05 00 00 48 63 80 88 00 00 00 3b 43 28 0f 8d 2e 01 00 00 48 8b 53 30 48 8d 04 80 48 8d 04 c2 48 8b 40 18 <48> 8>
RSP: 0018:ffff960cc2df77d8 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff8afb87e81280 RCX: 0000000000000224
RDX: ffff8afb9ee37c00 RSI: ffff8afb8da1a578 RDI: ffff8afb87e81280
RBP: ffff8afb83d67000 R08: 0000000000000001 R09: ffff8afb9652f850
R10: ffff960cc2df7908 R11: 0000000000000002 R12: 0000000000000000
R13: ffff8afb8d7688a0 R14: ffff8afb8da1a578 R15: 0000000000000224
FS: 00007f4dac35ce00(0000) GS:ffff8afe30b00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000008 CR3: 000000010ddc6000 CR4: 00000000003506e0
Call Trace:
<TASK>
? __die+0x23/0x70
? page_fault_oops+0x171/0x4e0
? plist_add+0xbe/0x100
? exc_page_fault+0x7c/0x180
? asm_exc_page_fault+0x26/0x30
? drm_dp_atomic_find_time_slots+0x5e/0x260 [drm_display_helper 0e67723696438d8e02b741593dd50d80b44c2026]
? drm_dp_atomic_find_time_slots+0x28/0x260 [drm_display_helper 0e67723696438d8e02b741593dd50d80b44c2026]
compute_mst_dsc_configs_for_link+0x2ff/0xa40 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054]
? fill_plane_buffer_attributes+0x419/0x510 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054]
compute_mst_dsc_configs_for_state+0x1e1/0x250 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054]
amdgpu_dm_atomic_check+0xecd/0x1190 [amdgpu 62e600d2a75e9158e1cd0a243bdc8e6da040c054]
drm_atomic_check_only+0x5c5/0xa40
drm_mode_atomic_ioctl+0x76e/0xbc0[how]
dsc recompute should be skipped if no mode change detected on the new request. If detected, keep checking whether the stream is already on current state or not.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +3 -0
@@ -1344,6 +1344,9 @@ static bool is_dsc_need_re_compute(DRM_DEBUG_DRIVER ("%s: MST_DSC check on %d streams in current dc_state\n" , __func__, dc->current_state->stream_count); +if (new_stream_on_link_num ==0 ) +return false; +/* check current_state if there stream on link but it is not in * new request state */
Greg Kroah-Hartman
maintainerPATCH 540/695 drm/amdgpu/mes12: reduce timeout
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 84f76408abe989809de19d02e476b044fd985adc upstream.
The firmware timeout is 2s. Reduce the driver timeout to 2.1 seconds to avoid back pressure on queue submissions.
--- drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +1 -1
@@ -146,7 +146,7 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, int api_status_off) {union MESAPI__QUERY_MES_STATUS mes_status_pkt; -signed long timeout =3000000 ;/* 3000 ms */ +signed long timeout =2100000 ;/* 2100 ms */ struct amdgpu_device *adev = mes->adev;struct amdgpu_ring *ring = &mes->ring[pipe];spinlock_t *ring_lock = &mes->ring_lock[pipe];
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 541/695 drm/amdgpu/mes11: reduce timeout
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 856265caa94a3c78feaa23ec1acd799fe1989201 upstream.
The firmware timeout is 2s. Reduce the driver timeout to 2.1 seconds to avoid back pressure on queue submissions.
--- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +1 -1
@@ -160,7 +160,7 @@ static int mes_v11_0_submit_pkt_and_poll int api_status_off) {union MESAPI__QUERY_MES_STATUS mes_status_pkt; -signed long timeout =3000000 ;/* 3000 ms */ +signed long timeout =2100000 ;/* 2100 ms */ struct amdgpu_device *adev = mes->adev;struct amdgpu_ring *ring = &mes->ring[0 ];struct MES_API_STATUS *api_status;
Greg Kroah-Hartman
maintainerPATCH 542/695 drm/amdkfd: Add SDMA queue quantum support for GFX12
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sreekant Somasekharan <[email protected]>
commit d52ac79053a2f3eba04c1e7b56334df84d1d289f upstream.
program SDMAx_QUEUEx_SCHEDULE_CNTL for context switch due to quantum in KFD for GFX12.
--- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c +4 -0
@@ -341,6 +341,10 @@ static void update_mqd_sdma(struct mqd_m m->sdmax_rlcx_doorbell_offset = q->doorbell_off <<SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT ; + m->sdmax_rlcx_sched_cntl = (amdgpu_sdma_phase_quantum + <<SDMA0_QUEUE0_SCHEDULE_CNTL__CONTEXT_QUANTUM__SHIFT ) + &SDMA0_QUEUE0_SCHEDULE_CNTL__CONTEXT_QUANTUM_MASK ; + m->sdma_engine_id = q->sdma_engine_id; m->sdma_queue_id = q->sdma_queue_id;
Greg Kroah-Hartman
maintainerPATCH 543/695 drm/amdgpu: update golden regs for gfx12
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Min <[email protected]>
commit 7b6df1d73290961ff0a00fd0022f28dd19e37181 upstream.
update golden regs for gfx12
--- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +11 -3
@@ -202,12 +202,16 @@ static const struct amdgpu_hwip_reg_entr SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_BUFSZ) }; -static const struct soc15_reg_golden golden_settings_gc_12_0[] = { +static const struct soc15_reg_golden golden_settings_gc_12_0_rev0[] = {SOC15_REG_GOLDEN_VALUE (GC ,0 , regDB_MEM_CONFIG,0x0000000f ,0x0000000f ),SOC15_REG_GOLDEN_VALUE (GC ,0 , regCB_HW_CONTROL_1,0x03000000 ,0x03000000 ),SOC15_REG_GOLDEN_VALUE (GC ,0 , regGL2C_CTRL5,0x00000070 ,0x00000020 ) }; +static const struct soc15_reg_golden golden_settings_gc_12_0[] = { +SOC15_REG_GOLDEN_VALUE (GC ,0 , regDB_MEM_CONFIG,0x00008000 ,0x00008000 ), +}; +#define DEFAULT_SH_MEM_CONFIG \ ((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \ (SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
@@ -3446,10 +3450,14 @@ static void gfx_v12_0_init_golden_registswitch (amdgpu_ip_version (adev,GC_HWIP ,0 )) {case IP_VERSION (12 ,0 ,0 ):case IP_VERSION (12 ,0 ,1 ): +soc15_program_register_sequence (adev, + golden_settings_gc_12_0, + (const u32 )ARRAY_SIZE (golden_settings_gc_12_0)); +if (adev->rev_id ==0 )soc15_program_register_sequence (adev, - golden_settings_gc_12_0, - (const u32 )ARRAY_SIZE (golden_settings_gc_12_0)); + golden_settings_gc_12_0_rev0, + (const u32 )ARRAY_SIZE (golden_settings_gc_12_0_rev0));break ;default :break ;
Greg Kroah-Hartman
maintainerPATCH 544/695 drm/amdgpu/mes12: set enable_level_process_quantum_check
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jack Xiao <[email protected]>
commit 4771d2ecb7b9e4c2c73ede2908d7e7c989460981 upstream.
enable_level_process_quantum_check is requried to enable process quantum based scheduling.
--- drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +1 -0
@@ -582,6 +582,7 @@ static int mes_v12_0_set_hw_resources(st mes_set_hw_res_pkt.disable_mes_log =1 ; mes_set_hw_res_pkt.use_different_vmid_compute =1 ; mes_set_hw_res_pkt.enable_reg_active_poll =1 ; + mes_set_hw_res_pkt.enable_level_process_quantum_check =1 ;/* * Keep oversubscribe timer for sdma . When we have unmapped doorbell
Greg Kroah-Hartman
maintainerPATCH 545/695 drm/amdgpu/vcn: enable AV1 on both instances
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saleemkhan Jamadar <[email protected]>
commit 8048e5ade8224969023902b0b3f64470f9c250a7 upstream.
v1 - remove cs parse code (Christian)
On VCN v4_0_6 AV1 is supported on both the instances. Remove cs IB parse code since explict handling of AV1 schedule is not required.
--- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 165 -------------------------------- 1 file changed, 165 deletions(-)
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +0 -165
@@ -1347,170 +1347,6 @@ static void vcn_v4_0_5_unified_ring_set_ } } -static int vcn_v4_0_5_limit_sched (struct amdgpu_cs_parser *p, -struct amdgpu_job *job) -{ -struct drm_gpu_scheduler **scheds; - -/* The create msg must be in the first IB submitted */ -if (atomic_read (&job->base.entity->fence_seq)) -return -EINVAL ; - -/* if VCN0 is harvested, we can't support AV1 */ -if (p->adev->vcn.harvest_config &AMDGPU_VCN_HARVEST_VCN0 ) -return -EINVAL ; - - scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_ENC ] - [AMDGPU_RING_PRIO_0 ].sched; -drm_sched_entity_modify_sched (job->base.entity, scheds,1 ); -return 0 ; -} - -static int vcn_v4_0_5_dec_msg (struct amdgpu_cs_parser *p,struct amdgpu_job *job, -uint64_t addr) -{ -struct ttm_operation_ctx ctx = { false, false }; -struct amdgpu_bo_va_mapping *map; -uint32_t *msg, num_buffers; -struct amdgpu_bo *bo; -uint64_t start, end; -unsigned int i; -void *ptr; -int r; - - addr &=AMDGPU_GMC_HOLE_MASK ; - r =amdgpu_cs_find_mapping (p, addr, &bo, &map); -if (r) { -DRM_ERROR ("Can't find BO for addr 0x%08llx\n" , addr); -return r; - } - - start = map->start *AMDGPU_GPU_PAGE_SIZE ; - end = (map->last +1 ) *AMDGPU_GPU_PAGE_SIZE ; -if (addr &0x7 ) { -DRM_ERROR ("VCN messages must be 8 byte aligned!\n" ); -return -EINVAL ; - } - - bo->flags |=AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED ; -amdgpu_bo_placement_from_domain (bo, bo->allowed_domains); - r =ttm_bo_validate (&bo->tbo, &bo->placement, &ctx); -if (r) { -DRM_ERROR ("Failed validating the VCN message BO (%d)!\n" , r); -return r; - } - - r =amdgpu_bo_kmap (bo, &ptr); -if (r) { -DRM_ERROR ("Failed mapping the VCN message (%d)!\n" , r); -return r; - } - - msg = ptr + addr - start; - -/* Check length */ -if (msg[1 ] > end - addr) { - r = -EINVAL ; - goto out; - } - -if (msg[3 ] !=RDECODE_MSG_CREATE ) - goto out; - - num_buffers = msg[2 ]; -for (i =0 , msg = &msg[6 ]; i < num_buffers; ++i, msg +=4 ) { -uint32_t offset, size, *create; - -if (msg[0 ] !=RDECODE_MESSAGE_CREATE ) -continue ; - - offset = msg[1 ]; - size = msg[2 ]; - -if (offset + size > end) { - r = -EINVAL ; - goto out; - } - - create = ptr + addr + offset - start; - -/* H264, HEVC and VP9 can run on any instance */ -if (create[0 ] ==0x7 || create[0 ] ==0x10 || create[0 ] ==0x11 ) -continue ; - - r =vcn_v4_0_5_limit_sched (p, job); -if (r) - goto out; - } - -out: -amdgpu_bo_kunmap (bo); -return r; -} - -#define RADEON_VCN_ENGINE_TYPE_ENCODE (0x00000002) -#define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003) - -#define RADEON_VCN_ENGINE_INFO (0x30000001) -#define RADEON_VCN_ENGINE_INFO_MAX_OFFSET 16 - -#define RENCODE_ENCODE_STANDARD_AV1 2 -#define RENCODE_IB_PARAM_SESSION_INIT 0x00000003 -#define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET 64 - -/* return the offset in ib if id is found, -1 otherwise -* to speed up the searching we only search upto max_offset -*/ -static int vcn_v4_0_5_enc_find_ib_param (struct amdgpu_ib *ib,uint32_t id,int max_offset) -{ -int i; - -for (i =0 ; i < ib->length_dw && i < max_offset && ib->ptr[i] >=8 ; i += ib->ptr[i]/4 ) { -if (ib->ptr[i +1 ] == id) -return i; - } -return -1 ; -} - -static int vcn_v4_0_5_ring_patch_cs_in_place (struct amdgpu_cs_parser *p, -struct amdgpu_job *job, -struct amdgpu_ib *ib) -{ -struct amdgpu_ring *ring =amdgpu_job_ring (job); -struct amdgpu_vcn_decode_buffer *decode_buffer; -uint64_t addr; -uint32_t val; -int idx; - -/* The first instance can decode anything */ -if (!ring->me) -return 0 ; - -/* RADEON_VCN_ENGINE_INFO is at the top of ib block */ - idx =vcn_v4_0_5_enc_find_ib_param (ib,RADEON_VCN_ENGINE_INFO , -RADEON_VCN_ENGINE_INFO_MAX_OFFSET ); -if (idx <0 )/* engine info is missing */ -return 0 ; - - val =amdgpu_ib_get_value (ib, idx +2 );/* RADEON_VCN_ENGINE_TYPE */ -if (val ==RADEON_VCN_ENGINE_TYPE_DECODE ) { - decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx +6 ]; - -if (!(decode_buffer->valid_buf_flag &0x1 )) -return 0 ; - - addr = ((u64 )decode_buffer->msg_buffer_address_hi) <<32 | - decode_buffer->msg_buffer_address_lo; -return vcn_v4_0_5_dec_msg (p, job, addr); - }else if (val ==RADEON_VCN_ENGINE_TYPE_ENCODE ) { - idx =vcn_v4_0_5_enc_find_ib_param (ib,RENCODE_IB_PARAM_SESSION_INIT , -RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET ); -if (idx >=0 && ib->ptr[idx +2 ] ==RENCODE_ENCODE_STANDARD_AV1 ) -return vcn_v4_0_5_limit_sched (p, job); - } -return 0 ; -} -static const struct amdgpu_ring_funcs vcn_v4_0_5_unified_ring_vm_funcs = { .type =AMDGPU_RING_TYPE_VCN_ENC , .align_mask =0x3f ,
@@ -1518,7 +1354,6 @@ static const struct amdgpu_ring_funcs vc .get_rptr = vcn_v4_0_5_unified_ring_get_rptr, .get_wptr = vcn_v4_0_5_unified_ring_get_wptr, .set_wptr = vcn_v4_0_5_unified_ring_set_wptr, - .patch_cs_in_place = vcn_v4_0_5_ring_patch_cs_in_place, .emit_frame_size =SOC15_FLUSH_GPU_TLB_NUM_WREG *3 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
Greg Kroah-Hartman
maintainerPATCH 546/695 drm/amd/pm: update workload mask after the setting
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kenneth Feng <[email protected]>
commit d7d2688bf4ea58734d73e18edcbf4684b1496d30 upstream.
update workload mask after the setting.
--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 6 +++++- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 3 +++ drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 6 +++++- 3 files changed, 13 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +5 -1
@@ -2569,10 +2569,14 @@ static int smu_v13_0_0_set_power_profile } } -return smu_cmn_send_smc_msg_with_param (smu, + ret =smu_cmn_send_smc_msg_with_param (smu, SMU_MSG_SetWorkloadMask, workload_mask,NULL ); +if (!ret) + smu->workload_mask = workload_mask; + +return ret; }static bool smu_v13_0_0_is_mode1_reset_supported (struct smu_context *smu)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +3 -0
@@ -2501,8 +2501,11 @@ static int smu_v13_0_7_set_power_profilereturn -EINVAL ; ret =smu_cmn_send_smc_msg_with_param (smu, SMU_MSG_SetWorkloadMask,1 << workload_type,NULL ); +if (ret)dev_err (smu->adev->dev,"[%s] Failed to set work load mask!" , __func__); +else + smu->workload_mask = (1 << workload_type);return ret; }
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +5 -1
@@ -1570,10 +1570,14 @@ static int smu_v14_0_2_set_power_profileif (workload_type <0 )return -EINVAL ; -return smu_cmn_send_smc_msg_with_param (smu, + ret =smu_cmn_send_smc_msg_with_param (smu, SMU_MSG_SetWorkloadMask,1 << workload_type,NULL ); +if (!ret) + smu->workload_mask =1 << workload_type; + +return ret; }static int smu_v14_0_2_baco_enter (struct smu_context *smu)
Greg Kroah-Hartman
maintainerPATCH 547/695 drm/amdgpu: fix PTE copy corruption for sdma 7
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Min <[email protected]>
commit 3cb576bc6dfb8940228b8130638860b631dd428a upstream.
Without setting dcc bit, there is ramdon PTE copy corruption on sdma 7.
so add this bit and update the packet format accordingly.
--- drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +5 -2
@@ -1022,13 +1022,16 @@ static void sdma_v7_0_vm_copy_pte(structunsigned bytes = count *8 ; ib->ptr[ib->length_dw++] =SDMA_PKT_COPY_LINEAR_HEADER_OP (SDMA_OP_COPY ) | -SDMA_PKT_COPY_LINEAR_HEADER_SUB_OP (SDMA_SUBOP_COPY_LINEAR ); +SDMA_PKT_COPY_LINEAR_HEADER_SUB_OP (SDMA_SUBOP_COPY_LINEAR ) | +SDMA_PKT_COPY_LINEAR_HEADER_CPV (1 ); + ib->ptr[ib->length_dw++] = bytes -1 ; ib->ptr[ib->length_dw++] =0 ;/* src/dst endian swap */ ib->ptr[ib->length_dw++] =lower_32_bits (src); ib->ptr[ib->length_dw++] =upper_32_bits (src); ib->ptr[ib->length_dw++] =lower_32_bits (pe); ib->ptr[ib->length_dw++] =upper_32_bits (pe); + ib->ptr[ib->length_dw++] =0 ; }
@@ -1631,7 +1634,7 @@ static void sdma_v7_0_set_buffer_funcs(s }static const struct amdgpu_vm_pte_funcs sdma_v7_0_vm_pte_funcs = { - .copy_pte_num_dw =7 , + .copy_pte_num_dw =8 , .copy_pte = sdma_v7_0_vm_copy_pte, .write_pte = sdma_v7_0_vm_write_pte, .set_pte_pde = sdma_v7_0_vm_set_pte_pde,
Greg Kroah-Hartman
maintainerPATCH 548/695 drm/amdgpu: bump driver version for cleared VRAM
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 34ad56a467c320d07db22146cfb99ee01704a5de upstream.
Driver now clears VRAM on allocation. Bump the driver version so mesa knows when it will get cleared vram by default.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +2 -1
@@ -117,9 +117,10 @@* - 3.56.0 - Update IB start address and size alignment for decode and encode * - 3.57.0 - Compute tunneling on GFX10+ * - 3.58.0 - Add GFX12 DCC support +* - 3.59.0 - Cleared VRAM */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 58 +#define KMS_DRIVER_MINOR 59#define KMS_DRIVER_PATCHLEVEL 0/*
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 549/695 drm/amdgpu/mes12: switch SET_SHADER_DEBUGGER pkt to mes schq pipe
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jack Xiao <[email protected]>
commit 3c75518cf27aa5a7e22e1f8f33339ded3779079b upstream.
The SET_SHADER_DEBUGGER packet must work with the added hardware queue, switch the packet submitting to mes schq pipe.
--- drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +6 -5
@@ -453,6 +453,11 @@ static int mes_v12_0_misc_op(struct amdgunion MESAPI__MISC misc_pkt;int pipe; +if (mes->adev->enable_uni_mes) + pipe =AMDGPU_MES_KIQ_PIPE ; +else + pipe =AMDGPU_MES_SCHED_PIPE ; +memset (&misc_pkt,0 ,sizeof (misc_pkt)); misc_pkt.header.type =MES_API_TYPE_SCHEDULER ;
@@ -487,6 +492,7 @@ static int mes_v12_0_misc_op(struct amdg misc_pkt.wait_reg_mem.reg_offset2 = input->wrm_reg.reg1;break ;case MES_MISC_OP_SET_SHADER_DEBUGGER : + pipe =AMDGPU_MES_SCHED_PIPE ; misc_pkt.opcode =MESAPI_MISC__SET_SHADER_DEBUGGER ; misc_pkt.set_shader_debugger.process_context_addr = input->set_shader_debugger.process_context_addr;
@@ -504,11 +510,6 @@ static int mes_v12_0_misc_op(struct amdgreturn -EINVAL ; } -if (mes->adev->enable_uni_mes) - pipe =AMDGPU_MES_KIQ_PIPE ; -else - pipe =AMDGPU_MES_SCHED_PIPE ; -return mes_v12_0_submit_pkt_and_poll_completion (mes, pipe, &misc_pkt,sizeof (misc_pkt), offsetof(union MESAPI__MISC , api_status));
Greg Kroah-Hartman
maintainerPATCH 550/695 drm/amdgpu: Fix selfring initialization sequence on soc24
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Belanger <[email protected]>
commit 03b5038c0ad069380fab7e251d2bf3f1540d20f4 upstream.
Move enable_doorbell_selfring_aperture from common_hw_init to common_late_init in soc24, otherwise selfring aperture is initialized with an incorrect doorbell aperture base.
Port changes from this commit from soc21 to soc24:
commit 1c312e816c40 ("drm/amdgpu: Enable doorbell selfring after resize FB BAR")
--- drivers/gpu/drm/amd/amdgpu/soc24.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/amdgpu/soc24.c +13 -10
@@ -250,13 +250,6 @@ static void soc24_program_aspm(struct amdgpu_device *adev) adev->nbio.funcs->program_aspm (adev); } -static void soc24_enable_doorbell_aperture (struct amdgpu_device *adev, -bool enable) -{ - adev->nbio.funcs->enable_doorbell_aperture (adev, enable); - adev->nbio.funcs->enable_doorbell_selfring_aperture (adev, enable); -} -const struct amdgpu_ip_block_version soc24_common_ip_block = { .type =AMD_IP_BLOCK_TYPE_COMMON , .major =1 ,
@@ -454,6 +447,11 @@ static int soc24_common_late_init(void *handle)if (amdgpu_sriov_vf (adev))xgpu_nv_mailbox_get_irq (adev); +/* Enable selfring doorbell aperture late because doorbell BAR +* aperture will change if resize BAR successfully in gmc sw_init. +*/ + adev->nbio.funcs->enable_doorbell_selfring_aperture (adev, true); +return 0 ; }
@@ -491,7 +489,7 @@ static int soc24_common_hw_init(void *handle) adev->df.funcs->hw_init (adev);/* enable the doorbell aperture */ -soc24_enable_doorbell_aperture (adev, true); + adev->nbio.funcs->enable_doorbell_aperture (adev, true);return 0 ; }
@@ -500,8 +498,13 @@ static int soc24_common_hw_fini(void *handle) {struct amdgpu_device *adev = (struct amdgpu_device *)handle; -/* disable the doorbell aperture */ -soc24_enable_doorbell_aperture (adev, false); +/* Disable the doorbell aperture and selfring doorbell aperture +* separately in hw_fini because soc21_enable_doorbell_aperture +* has been removed and there is no need to delay disabling +* selfring doorbell. +*/ + adev->nbio.funcs->enable_doorbell_aperture (adev, false); + adev->nbio.funcs->enable_doorbell_selfring_aperture (adev, false);if (amdgpu_sriov_vf (adev))xgpu_nv_mailbox_put_irq (adev);
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 551/695 drm/amd/display: Add HDMI DSC native YCbCr422 support
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Ma <[email protected]>
commit 07bfa9cdbf3cd2daadfaaba0601f126f45951ffa upstream.
[WHY && HOW]
For some HDMI OVT timing, YCbCr422 encoding fails at the DSC bandwidth check. The root cause is our DSC policy for timing doesn't account for HDMI YCbCr422 native support.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 4 ++-- drivers/gpu/drm/amd/display/dc/dc_dsc.h | 3 ++- drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +2 -2
@@ -1147,7 +1147,7 @@ static int compute_mst_dsc_configs_for_l params[count].num_slices_v = aconnector->dsc_settings.dsc_num_slices_v; params[count].bpp_overwrite = aconnector->dsc_settings.dsc_bits_per_pixel; params[count].compression_possible = stream->sink->dsc_caps.dsc_dec_caps.is_dsc_supported; -dc_dsc_get_policy_for_timing (params[count].timing,0 , &dsc_policy); +dc_dsc_get_policy_for_timing (params[count].timing,0 , &dsc_policy,dc_link_get_highest_encoding_format (stream->link)); if (!dc_dsc_compute_bandwidth_range( stream->sink->ctx->dc->res_pool->dscs[0], stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
@@ -1684,7 +1684,7 @@ static bool is_dsc_common_config_possibl {struct dc_dsc_policy dsc_policy = {0 }; -dc_dsc_get_policy_for_timing (&stream->timing,0 , &dsc_policy); +dc_dsc_get_policy_for_timing (&stream->timing,0 , &dsc_policy,dc_link_get_highest_encoding_format (stream->link)); dc_dsc_compute_bandwidth_range(stream->sink->ctx->dc->res_pool->dscs[0], stream->sink->ctx->dc->debug.dsc_min_slice_height_override, dsc_policy.min_target_bpp * 16,
drivers/gpu/drm/amd/display/dc/dc_dsc.h +2 -1
@@ -100,7 +100,8 @@ uint32_t dc_dsc_stream_bandwidth_overhea*/ void dc_dsc_get_policy_for_timing (const struct dc_crtc_timing *timing,uint32_t max_target_bpp_limit_override_x16, -struct dc_dsc_policy *policy); +struct dc_dsc_policy *policy, +const enum dc_link_encoding_format link_encoding);void dc_dsc_policy_set_max_target_bpp_limit (uint32_t limit);
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +3 -2
@@ -882,7 +882,7 @@ static bool setup_dsc_config(memset (dsc_cfg,0 ,sizeof (struct dc_dsc_config )); -dc_dsc_get_policy_for_timing (timing, options->max_target_bpp_limit_override_x16, &policy); +dc_dsc_get_policy_for_timing (timing, options->max_target_bpp_limit_override_x16, &policy, link_encoding); pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right; pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
@@ -1171,7 +1171,8 @@ uint32_t dc_dsc_stream_bandwidth_overheavoid dc_dsc_get_policy_for_timing (const struct dc_crtc_timing *timing,uint32_t max_target_bpp_limit_override_x16, -struct dc_dsc_policy *policy) +struct dc_dsc_policy *policy, +const enum dc_link_encoding_format link_encoding) {uint32_t bpc =0 ;
Greg Kroah-Hartman
maintainerPATCH 552/695 drm/amd/display: Round calculated vtotal
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Chen <[email protected]>
commit c03fca619fc687338a3b6511fdbed94096abdf79 upstream.
[WHY]
The calculated vtotal may has 1 line deviation. To get precisely vtotal number, round the vtotal result.
--- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/modules/freesync/freesync.c +1 -1
@@ -134,7 +134,7 @@ unsigned int mod_freesync_calc_v_total_f v_total =div64_u64 (div64_u64 (((unsigned long long )( frame_duration_in_ns) * (stream->timing.pix_clk_100hz /10 )), - stream->timing.h_total),1000000 ); + stream->timing.h_total) +500000 ,1000000 );/* v_total cannot be less than nominal */ if (v_total < stream->timing.v_total) {
Greg Kroah-Hartman
maintainerPATCH 553/695 drm/amd/display: Clean up dsc blocks in accelerated mode
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Tsai <[email protected]>
commit 3766a840e093d30e1a2522f650d8a6ac892a8719 upstream.
[WHY]
DSC on eDP could be enabled during VBIOS post. The enabled DSC may not be disabled when enter to OS, once the system was in second screen only mode before entering to S4. In this case, OS will not send setTimings to reset eDP path again.
The enabled DSC HW will make a new stream without DSC cannot output normally if it reused this pipe with enabled DSC.
[HOW]
In accelerated mode, to clean up DSC blocks if eDP is on link but not active when we are not in fast boot and seamless boot.
--- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 50 ++++++++++++++ 1 file changed, 50 insertions(+)
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +50 -0
@@ -57,6 +57,7 @@#include "panel_cntl.h" #include "dc_state_priv.h" #include "dpcd_defs.h" +#include "dsc.h" /* include DCE11 register header files */ #include "dce/dce_11_0_d.h" #include "dce/dce_11_0_sh_mask.h"
@@ -1815,6 +1816,48 @@ static void get_edp_links_with_sink( } } +static void clean_up_dsc_blocks (struct dc *dc) +{ +struct display_stream_compressor *dsc =NULL ; +struct timing_generator *tg =NULL ; +struct stream_encoder *se =NULL ; +struct dccg *dccg = dc->res_pool->dccg; +struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl; +int i; + +if (dc->ctx->dce_version !=DCN_VERSION_3_5 && + dc->ctx->dce_version !=DCN_VERSION_3_51 ) +return ; + +for (i =0 ; i < dc->res_pool->res_cap->num_dsc; i++) { +struct dcn_dsc_state s = {0 }; + + dsc = dc->res_pool->dscs[i]; + dsc->funcs->dsc_read_state (dsc, &s); +if (s.dsc_fw_en) { +/* disable DSC in OPTC */ +if (i < dc->res_pool->timing_generator_count) { + tg = dc->res_pool->timing_generators[i]; + tg->funcs->set_dsc_config (tg,OPTC_DSC_DISABLED ,0 ,0 ); + } +/* disable DSC in stream encoder */ +if (i < dc->res_pool->stream_enc_count) { + se = dc->res_pool->stream_enc[i]; + se->funcs->dp_set_dsc_config (se,OPTC_DSC_DISABLED ,0 ,0 ); + se->funcs->dp_set_dsc_pps_info_packet (se, false,NULL , true); + } +/* disable DSC block */ +if (dccg->funcs->set_ref_dscclk) + dccg->funcs->set_ref_dscclk (dccg, dsc->inst); + dsc->funcs->dsc_disable (dsc); + +/* power down DSC */ +if (pg_cntl !=NULL ) + pg_cntl->funcs->dsc_pg_control (pg_cntl, dsc->inst, false); + } + } +} +/* * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: * 1. Power down all DC HW blocks
@@ -1917,6 +1960,13 @@ void dce110_enable_accelerated_mode(struclk_mgr_exit_optimized_pwr_state (dc, dc->clk_mgr);power_down_all_hw_blocks (dc); + +/* DSC could be enabled on eDP during VBIOS post. +* To clean up dsc blocks if eDP is in link but not active. +*/ +if (edp_link_with_sink && (edp_stream_num ==0 )) +clean_up_dsc_blocks (dc); +disable_vga_and_power_gate_all_controllers (dc);if (edp_link_with_sink && !keep_edp_vdd_on) dc->hwss.edp_power_control (edp_link_with_sink, false);
Greg Kroah-Hartman
maintainerPATCH 554/695 drm/amd/display: Block timing sync for different output formats in pmo
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dillon Varone <[email protected]>
commit 0765b2afc1118a6ab5fee624e206c782d70db28a upstream.
[WHY & HOW]
If the output format is different for HDMI TMDS signals, they are not synchronizable.
--- drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c +5 -3
@@ -810,9 +810,11 @@ static void build_synchronized_timing_gr/* find synchronizable timing groups */ for (j = i +1 ; j < display_config->display_config.num_streams; j++) {if (memcmp (master_timing, - &display_config->display_config.stream_descriptors[j].timing, -sizeof (struct dml2_timing_cfg )) ==0 && - display_config->display_config.stream_descriptors[i].output.output_encoder == display_config->display_config.stream_descriptors[j].output.output_encoder) { + &display_config->display_config.stream_descriptors[j].timing, +sizeof (struct dml2_timing_cfg )) ==0 && + display_config->display_config.stream_descriptors[i].output.output_encoder == display_config->display_config.stream_descriptors[j].output.output_encoder && + (display_config->display_config.stream_descriptors[i].output.output_encoder != dml2_hdmi ||//hdmi requires formats match + display_config->display_config.stream_descriptors[i].output.output_format == display_config->display_config.stream_descriptors[j].output.output_format)) {set_bit_in_bitfield (&pmo->scratch.pmo_dcn4.synchronized_timing_group_masks[timing_group_idx], j);set_bit_in_bitfield (&stream_mapped_mask, j); }
Greg Kroah-Hartman
maintainerPATCH 555/695 drm/amd/display: Validate backlight caps are sane
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 327e62f47eb57ae5ff63de82b0815557104e439a upstream.
Currently amdgpu takes backlight caps provided by the ACPI tables on systems as is. If the firmware sets maximums that are too low this means that users don't get a good experience.
To avoid having to maintain a quirk list of such systems, do a sanity check on the values. Check that the spread is at least half of the values that amdgpu would use if no ACPI table was found and if not use the amdgpu defaults.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +16 -0
@@ -4441,6 +4441,7 @@ static int amdgpu_dm_mode_config_init(st#define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 12#define AMDGPU_DM_DEFAULT_MAX_BACKLIGHT 255 +#define AMDGPU_DM_MIN_SPREAD ((AMDGPU_DM_DEFAULT_MAX_BACKLIGHT - AMDGPU_DM_DEFAULT_MIN_BACKLIGHT) / 2)#define AUX_BL_DEFAULT_TRANSITION_TIME_MS 50 static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm,
@@ -4455,6 +4456,21 @@ static void amdgpu_dm_update_backlight_creturn ;amdgpu_acpi_get_backlight_caps (&caps); + +/* validate the firmware value is sane */ +if (caps.caps_valid) { +int spread = caps.max_input_signal - caps.min_input_signal; + +if (caps.max_input_signal >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || + caps.min_input_signal <AMDGPU_DM_DEFAULT_MIN_BACKLIGHT || + spread >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || + spread <AMDGPU_DM_MIN_SPREAD ) { +DRM_DEBUG_KMS ("DM: Invalid backlight caps: min=%d, max=%d\n" , + caps.min_input_signal, caps.max_input_signal); + caps.caps_valid = false; + } + } +if (caps.caps_valid) { dm->backlight_caps[bl_idx].caps_valid = true;if (caps.aux_support)
Greg Kroah-Hartman
maintainerPATCH 556/695 drm/amd/display: Disable SYMCLK32_LE root clock gating
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sung Joon Kim <[email protected]>
commit ae5100805f98641ea4112241e350485c97936bbe upstream.
[WHY & HOW]
On display on sequence, enabling SYMCLK32_LE root clock gating causes issue in link training so disabling it is needed.
--- drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +1 -1
@@ -736,7 +736,7 @@ static const struct dc_debug_options deb .hdmichar = true, .dpstream = true, .symclk32_se = true, - .symclk32_le = true, + .symclk32_le = false, .symclk_fe = true, .physymclk = false, .dpiasymclk = true,
Greg Kroah-Hartman
maintainerPATCH 557/695 drm/amd/display: Block dynamic IPS2 on DCN35 for incompatible FW versions
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Kazlauskas <[email protected]>
commit 401c90c4d64f2227fc2f4c02d2ad23296bf5ca6f upstream.
[WHY]
Hangs with Z8 can occur if running an older unfixed PMFW version.
[HOW]
Fallback to RCG only for dynamic IPS2 states if it's not newer than 93.12. Limit to DCN35.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +6 -0
@@ -1204,6 +1204,12 @@ void dcn35_clk_mgr_construct( ctx->dc->debug.disable_dpp_power_gate = false; ctx->dc->debug.disable_hubp_power_gate = false; ctx->dc->debug.disable_dsc_power_gate = false; + +/* Disable dynamic IPS2 in older PMFW (93.12) for Z8 interop. */ +if (ctx->dc->config.disable_ips ==DMUB_IPS_ENABLE && + ctx->dce_version ==DCN_VERSION_3_5 && + ((clk_mgr->base.smu_ver &0x00FFFFFF ) <=0x005d0c00 )) + ctx->dc->config.disable_ips =DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF ; }else {/*let's reset the config control flag*/ ctx->dc->config.disable_ips =DMUB_IPS_DISABLE_ALL ;/*pmfw not support it, disable it all*/
Greg Kroah-Hartman
maintainerPATCH 558/695 drm/amd/display: Enable DML2 override_det_buffer_size_kbytes
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yihan Zhu <[email protected]>
commit f57b77d667dc6bd2b114d08d04b03869539209f6 upstream.
[WHY]
Corrupted screen will be observed when 4k144 DP/HDMI display and 4k144 eDP are connected, changing eDP refresh rate from 60Hz to 144Hz.
[HOW]override_det_buffer_size_kbytes should be true for DCN35/DCN351.
--- drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 1 + drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 1 + 2 files changed, 2 insertions(+)
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +1 -0
@@ -2153,6 +2153,7 @@ static bool dcn35_resource_construct( dc->dml2_options.max_segments_per_hubp =24 ; dc->dml2_options.det_segment_size =DCN3_2_DET_SEG_SIZE ;/*todo*/ + dc->dml2_options.override_det_buffer_size_kbytes = true;if (dc->config.sdpif_request_limit_words_per_umc ==0 ) dc->config.sdpif_request_limit_words_per_umc =16 ;/*todo*/
drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +1 -0
@@ -2133,6 +2133,7 @@ static bool dcn351_resource_construct( dc->dml2_options.max_segments_per_hubp =24 ; dc->dml2_options.det_segment_size =DCN3_2_DET_SEG_SIZE ;/*todo*/ + dc->dml2_options.override_det_buffer_size_kbytes = true;if (dc->config.sdpif_request_limit_words_per_umc ==0 ) dc->config.sdpif_request_limit_words_per_umc =16 ;/*todo*/
Greg Kroah-Hartman
maintainerPATCH 559/695 drm/amd/display: Skip to enable dsc if it has been off
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhikai Zhai <[email protected]>
commit 4bdc5b504af7de1f649004cfdd37445d36db6703 upstream.
[WHY]
It makes DSC enable when we commit the stream which need keep power off, and then it will skip to disable DSC if pipe reset at this situation as power has been off. It may cause the DSC unexpected enable on the pipe with the next new stream which doesn't support DSC.
[HOW]
Check the DSC used on current pipe status when update stream. Skip to enable if it has been off. The operation enable DSC should happen when set power on.
--- drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 14 ++++++++++++++ drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 13 +++++++++++++ 2 files changed, 27 insertions(+)
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +14 -0
@@ -1029,6 +1029,20 @@ void dcn32_update_dsc_on_stream(struct pstruct dsc_config dsc_cfg;struct dsc_optc_config dsc_optc_cfg = {0 };enum optc_dsc_mode optc_dsc_mode; +struct dcn_dsc_state dsc_state = {0 }; + +if (!dsc) { +DC_LOG_DSC ("DSC is NULL for tg instance %d:" , pipe_ctx->stream_res.tg->inst); +return ; + } + +if (dsc->funcs->dsc_read_state) { + dsc->funcs->dsc_read_state (dsc, &dsc_state); +if (!dsc_state.dsc_fw_en) { +DC_LOG_DSC ("DSC has been disabled for tg instance %d:" , pipe_ctx->stream_res.tg->inst); +return ; + } + }/* Enable DSC hw block */ dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +13 -0
@@ -375,7 +375,20 @@ static void update_dsc_on_stream(structstruct dsc_config dsc_cfg;struct dsc_optc_config dsc_optc_cfg = {0 };enum optc_dsc_mode optc_dsc_mode; +struct dcn_dsc_state dsc_state = {0 }; +if (!dsc) { +DC_LOG_DSC ("DSC is NULL for tg instance %d:" , pipe_ctx->stream_res.tg->inst); +return ; + } + +if (dsc->funcs->dsc_read_state) { + dsc->funcs->dsc_read_state (dsc, &dsc_state); +if (!dsc_state.dsc_fw_en) { +DC_LOG_DSC ("DSC has been disabled for tg instance %d:" , pipe_ctx->stream_res.tg->inst); +return ; + } + }/* Enable DSC hw block */ dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt; dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
Greg Kroah-Hartman
maintainerPATCH 560/695 drm/amd/display: Fix underflow when setting underscan on DCN401
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurabindo Pillai <[email protected]>
commit f510dd5c210bf8cc22e4be48cbbda3cb754219f5 upstream.
[WHY & HOW]
When underscan is set through xrandr, it causes the stream destination rect to change in a way it becomes complicated to handle the calculations for subvp. Since this is a corner case, disable subvp when underscan is set.
Fix the existing check that is supposed to catch this corner case by adding a check based on the parameters in the stream
--- drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c +3 -1
@@ -859,7 +859,9 @@ static void populate_dml21_plane_config_ plane->immediate_flip = plane_state->flip_immediate; - plane->composition.rect_out_height_spans_vactive = plane_state->dst_rect.height >= stream->timing.v_addressable; + plane->composition.rect_out_height_spans_vactive = + plane_state->dst_rect.height >= stream->timing.v_addressable && + stream->dst.height >= stream->timing.v_addressable; }//TODO : Could be possibly moved to a common helper layer.
Greg Kroah-Hartman
maintainerPATCH 561/695 drm/amd/display: Update IPS default mode for DCN35/DCN351
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Li <[email protected]>
commit 199888aa25b3a3315360224bda9134a9b58c9306 upstream.
[WHY]
RCG state of IPX in idle is more stable for DCN351 and some variants of DCN35 than IPS2.
[HOW]
Rework dm_get_default_ips_mode() to specify default per ASIC and update DCN35/DCN351 defaults accordingly.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 50 ++++++++++++++-------- 1 file changed, 33 insertions(+), 17 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +33 -17
@@ -1756,25 +1756,41 @@ static struct dml2_soc_bb *dm_dmub_get_vstatic enum dmub_ips_disable_type dm_get_default_ips_mode (struct amdgpu_device *adev) { -/* -* On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to -* cause a hard hang. A fix exists for newer PMFW. -* -* As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest -* IPS state in all cases, except for s0ix and all displays off (DPMS), -* where IPS2 is allowed. -* -* When checking pmfw version, use the major and minor only. -*/ -if (amdgpu_ip_version (adev,DCE_HWIP ,0 ) ==IP_VERSION (3 ,5 ,0 ) && - (adev->pm.fw_version &0x00FFFF00 ) <0x005D6300 ) -return DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF ; +enum dmub_ips_disable_type ret =DMUB_IPS_ENABLE ; -if (amdgpu_ip_version (adev,DCE_HWIP ,0 ) >=IP_VERSION (3 ,5 ,0 )) -return DMUB_IPS_ENABLE ; +switch (amdgpu_ip_version (adev,DCE_HWIP ,0 )) { +case IP_VERSION (3 ,5 ,0 ): +/* +* On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to +* cause a hard hang. A fix exists for newer PMFW. +* +* As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest +* IPS state in all cases, except for s0ix and all displays off (DPMS), +* where IPS2 is allowed. +* +* When checking pmfw version, use the major and minor only. +*/ +if ((adev->pm.fw_version &0x00FFFF00 ) <0x005D6300 ) + ret =DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF ; +else if (amdgpu_ip_version (adev,GC_HWIP ,0 ) >IP_VERSION (11 ,5 ,0 )) +/* +* Other ASICs with DCN35 that have residency issues with +* IPS2 in idle. +* We want them to use IPS2 only in display off cases. +*/ + ret =DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF ; +break ; +case IP_VERSION (3 ,5 ,1 ): + ret =DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF ; +break ; +default : +/* ASICs older than DCN35 do not have IPSs */ +if (amdgpu_ip_version (adev,DCE_HWIP ,0 ) <IP_VERSION (3 ,5 ,0 )) + ret =DMUB_IPS_DISABLE_ALL ; +break ; + } -/* ASICs older than DCN35 do not have IPSs */ -return DMUB_IPS_DISABLE_ALL ; +return ret; }static int amdgpu_dm_init (struct amdgpu_device *adev)
Greg Kroah-Hartman
maintainerPATCH 562/695 objtool: Handle frame pointer related instructions
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
commit da5b2ad1c2f18834cb1ce429e2e5a5cf5cbdf21b upstream.
After commit a0f7085f6a63 ("LoongArch: Add RANDOMIZE_KSTACK_OFFSET support"), there are three new instructions "addi.d $fp, $sp, 32", "sub.d $sp, $sp, $t0" and "addi.d $sp, $fp, -32" for the secondary stack in do_syscall(), then there is a objtool warning "return with modified stack frame" and no handle_syscall() which is the previous frame of do_syscall() in the call trace when executing the command "echo l > /proc/sysrq-trigger".
objdump shows something like this:
0000000000000000 <do_syscall>:
0: 02ff8063 addi.d $sp, $sp, -32 4: 29c04076 st.d $fp, $sp, 16 8: 29c02077 st.d $s0, $sp, 8 c: 29c06061 st.d $ra, $sp, 24 10: 02c08076 addi.d $fp, $sp, 32 ... 74: 0011b063 sub.d $sp, $sp, $t0 ... a8: 4c000181 jirl $ra, $t0, 0 ... dc: 02ff82c3 addi.d $sp, $fp, -32 e0: 28c06061 ld.d $ra, $sp, 24 e4: 28c04076 ld.d $fp, $sp, 16 e8: 28c02077 ld.d $s0, $sp, 8 ec: 02c08063 addi.d $sp, $sp, 32 f0: 4c000020 jirl $zero, $ra, 0
The instruction "sub.d $sp, $sp, $t0" changes the stack bottom and the new stack size is a random value, in order to find the return address of do_syscall() which is stored in the original stack frame after executing "jirl $ra, $t0, 0", it should use fp which points to the original stack top.
At the beginning, the thought is tended to decode the secondary stack instruction "sub.d $sp, $sp, $t0" and set it as a label, then check this label for the two frame pointer instructions to change the cfa base and cfa offset during the period of secondary stack in update_cfi_state(). This is valid for GCC but invalid for Clang due to there are different secondary stack instructions for ClangBuiltLinux on LoongArch, something like this:
0000000000000000 <do_syscall>:
...
88: 00119064 sub.d $a0, $sp, $a0 8c: 00150083 or $sp, $a0, $zero
...
Actually, it equals to a single instruction "sub.d $sp, $sp, $a0", but there is no proper condition to check it as a label like GCC, and so the beginning thought is not a good way.
Essentially, there are two special frame pointer instructions which are "addi.d $fp, $sp, imm" and "addi.d $sp, $fp, imm", the first one points fp to the original stack top and the second one restores the original stack bottom from fp.
Based on the above analysis, in order to avoid adding an arch-specific update_cfi_state(), we just add a member "frame_pointer" in the "struct symbol" as a label to avoid affecting the current normal case, then set it as true only if there is "addi.d $sp, $fp, imm". The last is to check this label for the two frame pointer instructions to change the cfa base and cfa offset in update_cfi_state().
Tested with the following two configs:
(1) CONFIG_RANDOMIZE_KSTACK_OFFSET=y &&
CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=n
(2) CONFIG_RANDOMIZE_KSTACK_OFFSET=y &&
CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y
By the way, there is no effect for x86 with this patch, tested on the x86 machine with Fedora 40 system.
--- tools/objtool/arch/loongarch/decode.c | 11 ++++++++++- tools/objtool/check.c | 23 ++++++++++++++++++++--- tools/objtool/include/objtool/elf.h | 1 + 3 files changed, 31 insertions(+), 4 deletions(-)
tools/objtool/arch/loongarch/decode.c +10 -1
@@ -122,7 +122,7 @@ static bool decode_insn_reg2i12_fomat(unswitch (inst.reg2i12_format.opcode) {case addid_op:if ((inst.reg2i12_format.rd ==CFI_SP ) || (inst.reg2i12_format.rj ==CFI_SP )) { -/* addi.d sp,sp,si12 or addi.d fp,sp,si12 */ +/* addi.d sp,sp,si12 or addi.d fp,sp,si12 or addi.d sp,fp,si12 */ insn->immediate =sign_extend64 (inst.reg2i12_format.immediate,11 );ADD_OP (op) { op->src.type =OP_SRC_ADD ;
@@ -132,6 +132,15 @@ static bool decode_insn_reg2i12_fomat(un op->dest.reg = inst.reg2i12_format.rd; } } +if ((inst.reg2i12_format.rd ==CFI_SP ) && (inst.reg2i12_format.rj ==CFI_FP )) { +/* addi.d sp,fp,si12 */ +struct symbol *func =find_func_containing (insn->sec, insn->offset); + +if (!func) +return false; + + func->frame_pointer = true; + }break ;case ldd_op:if (inst.reg2i12_format.rj ==CFI_SP ) {
tools/objtool/check.c +20 -3
@@ -2993,10 +2993,27 @@ static int update_cfi_state(struct instrbreak ; } -if (op->dest.reg ==CFI_SP && op->src.reg ==CFI_BP ) { +if (op->dest.reg ==CFI_BP && op->src.reg ==CFI_SP && + insn->sym->frame_pointer) { +/* addi.d fp,sp,imm on LoongArch */ +if (cfa->base ==CFI_SP && cfa->offset == op->src.offset) { + cfa->base =CFI_BP ; + cfa->offset =0 ; + } +break ; + } -/* lea disp(%rbp), %rsp */ - cfi->stack_size = -(op->src.offset + regs[CFI_BP ].offset); +if (op->dest.reg ==CFI_SP && op->src.reg ==CFI_BP ) { +/* addi.d sp,fp,imm on LoongArch */ +if (cfa->base ==CFI_BP && cfa->offset ==0 ) { +if (insn->sym->frame_pointer) { + cfa->base =CFI_SP ; + cfa->offset = -op->src.offset; + } + }else { +/* lea disp(%rbp), %rsp */ + cfi->stack_size = -(op->src.offset + regs[CFI_BP ].offset); + }break ; }
tools/objtool/include/objtool/elf.h +1 -0
@@ -68,6 +68,7 @@ struct symbol { u8 warned : 1; u8 embedded_insn : 1; u8 local_label : 1; + u8 frame_pointer : 1;struct list_head pv_target;struct reloc *relocs; };
Greg Kroah-Hartman
maintainerPATCH 563/695 x86/tdx: Fix "in-kernel MMIO" check
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Gladkov (Intel) <[email protected]>
commit d4fc4d01471528da8a9797a065982e05090e1d81 upstream.
TDX only supports kernel-initiated MMIO operations. The handle_mmio() function checks if the #VE exception occurred in the kernel and rejects the operation if it did not.
However, userspace can deceive the kernel into performing MMIO on its behalf. For example, if userspace can point a syscall to an MMIO address, syscall does get_user() or put_user() on it, triggering MMIO #VE. The kernel will treat the #VE as in-kernel MMIO.
Ensure that the target MMIO address is within the kernel before decoding instruction.
--- arch/x86/coco/tdx/tdx.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/x86/coco/tdx/tdx.c +6 -0
@@ -16,6 +16,7 @@#include <asm/insn-eval.h> #include <asm/pgtable.h> #include <asm/set_memory.h> +#include <asm/traps.h> /* MMIO direction */ #define EPT_READ 0
@@ -433,6 +434,11 @@ static int handle_mmio(struct pt_regs *rreturn -EINVAL ; } +if (!fault_in_kernel_space (ve->gla)) { +WARN_ONCE (1 ,"Access to userspace address is not supported" ); +return -EINVAL ; + } +/* * Reject EPT violation #VEs that split pages. *
Greg Kroah-Hartman
maintainerPATCH 564/695 KEYS: prevent NULL pointer dereference in find_asymmetric_key()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Smirnov <[email protected]>
commit 70fd1966c93bf3bfe3fe6d753eb3d83a76597eef upstream.
In find_asymmetric_key(), if all NULLs are passed in the id_{0,1,2} arguments, the kernel will first emit WARN but then have an oops because id_2 gets dereferenced anyway.
Add the missing id_2 check and move WARN_ON() to the final else branch to avoid duplicate NULL checks.
Found by Linux Verification Center (linuxtesting.org) with Svace static analysis tool.
--- crypto/asymmetric_keys/asymmetric_type.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
crypto/asymmetric_keys/asymmetric_type.c +4 -3
@@ -60,17 +60,18 @@ struct key *find_asymmetric_key(struct kchar *req, *p;int len; -WARN_ON (!id_0 && !id_1 && !id_2); -if (id_0) { lookup = id_0->data; len = id_0->len; }else if (id_1) { lookup = id_1->data; len = id_1->len; - }else { + }else if (id_2) { lookup = id_2->data; len = id_2->len; + }else { +WARN_ON (1 ); +return ERR_PTR (-EINVAL ); }/* Construct an identifier "id:<keyid>". */
Greg Kroah-Hartman
maintainerPATCH 565/695 powerpc/atomic: Use YZ constraints for DS-form instructions
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
commit 39190ac7cff1fd15135fa8e658030d9646fdb5f2 upstream.
The 'ld' and 'std' instructions require a 4-byte aligned displacement because they are DS-form instructions. But the "m" asm constraint doesn't enforce that.
That can lead to build errors if the compiler chooses a non-aligned displacement, as seen with GCC 14:
/tmp/ccuSzwiR.s: Assembler messages:
/tmp/ccuSzwiR.s:2579: Error: operand out of domain (39 is not a multiple of 4) make[5]: *** [scripts/Makefile.build:229: net/core/page_pool.o] Error 1
Dumping the generated assembler shows:
ld 8,39(8) # MEM[(const struct atomic64_t *)_29].counter, t
Use the YZ constraints to tell the compiler either to generate a DS-form displacement, or use an X-form instruction, either of which prevents the build error.
See commit 2d43cc701b96 ("powerpc/uaccess: Fix build errors seen with GCC 13/14") for more details on the constraint letters.
--- arch/powerpc/include/asm/asm-compat.h | 6 ++++++ arch/powerpc/include/asm/atomic.h | 5 +++-- arch/powerpc/include/asm/uaccess.h | 7 +------ 3 files changed, 10 insertions(+), 8 deletions(-)
arch/powerpc/include/asm/asm-compat.h +6 -0
@@ -39,6 +39,12 @@#define STDX_BE stringify_in_c(stdbrx)#endif +#ifdef CONFIG_CC_IS_CLANG +#define DS_FORM_CONSTRAINT "Z<>" +#else +#define DS_FORM_CONSTRAINT "YZ<>" +#endif +#else /* 32-bit */ /* operations for longs and pointers */
arch/powerpc/include/asm/atomic.h +3 -2
@@ -11,6 +11,7 @@#include <asm/cmpxchg.h> #include <asm/barrier.h> #include <asm/asm-const.h> +#include <asm/asm-compat.h> /* * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
@@ -197,7 +198,7 @@ static __inline__ s64 arch_atomic64_readif (IS_ENABLED (CONFIG_PPC_KERNEL_PREFIXED )) __asm__ __volatile__("ld %0,0(%1)" :"=r" (t) :"b" (&v->counter));else - __asm__ __volatile__("ld%U1%X1 %0,%1" :"=r" (t) :"m<>" (v->counter)); + __asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : DS_FORM_CONSTRAINT (v->counter));return t; }
@@ -208,7 +209,7 @@ static __inline__ void arch_atomic64_setif (IS_ENABLED (CONFIG_PPC_KERNEL_PREFIXED )) __asm__ __volatile__("std %1,0(%2)" :"=m" (v->counter) :"r" (i),"b" (&v->counter));else - __asm__ __volatile__("std%U0%X0 %1,%0" :"=m<>" (v->counter) :"r" (i)); + __asm__ __volatile__("std%U0%X0 %1,%0" : "=" DS_FORM_CONSTRAINT (v->counter) : "r"(i)); }#define ATOMIC64_OP (op, asm_op) \
arch/powerpc/include/asm/uaccess.h +1 -6
@@ -6,6 +6,7 @@#include <asm/page.h> #include <asm/extable.h> #include <asm/kup.h> +#include <asm/asm-compat.h> #ifdef __powerpc64__/* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
@@ -92,12 +93,6 @@ __pu_failed: \ : label)#endif -#ifdef CONFIG_CC_IS_CLANG -#define DS_FORM_CONSTRAINT "Z<>" -#else -#define DS_FORM_CONSTRAINT "YZ<>" -#endif -#ifdef __powerpc64__#ifdef CONFIG_PPC_KERNEL_PREFIXED #define __put_user_asm2_goto (x, ptr, label) \
Greg Kroah-Hartman
maintainerPATCH 566/695 ksmbd: make __dir_empty() compatible with POSIX
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hobin Woo <[email protected]>
commit ca4974ca954561e79f8871d220bb08f14f64f57c upstream.
Some file systems may not provide dot (.) and dot-dot (..) as they are optional in POSIX. ksmbd can misjudge emptiness of a directory in those file systems, since it assumes there are always at least two entries:
dot and dot-dot.
Just don't count dot and dot-dot.
--- fs/smb/server/vfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/smb/server/vfs.c +4 -3
@@ -1115,9 +1115,10 @@ static bool __dir_empty(struct dir_contestruct ksmbd_readdir_data *buf; buf = container_of(ctx, struct ksmbd_readdir_data, ctx); - buf->dirent_count++; +if (!is_dot_dotdot (name, namlen)) + buf->dirent_count++; -return buf->dirent_count <=2 ; +return !buf->dirent_count; }/**
@@ -1137,7 +1138,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_fil readdir_data.dirent_count =0 ; err =iterate_dir (fp->filp, &readdir_data.ctx); -if (readdir_data.dirent_count >2 ) +if (readdir_data.dirent_count) err = -ENOTEMPTY ;else err =0 ;
Greg Kroah-Hartman
maintainerPATCH 567/695 ksmbd: allow write with FILE_APPEND_DATA
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
commit 2fb9b5dc80cabcee636a6ccd020740dd925b4580 upstream.
Windows client write with FILE_APPEND_DATA when using git. ksmbd should allow write it with this flags.
Z:\test>git commit -m "test"
fatal: cannot update the ref 'HEAD': unable to append to
'.git/logs/HEAD': Bad file descriptor
--- fs/smb/server/vfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/server/vfs.c +1 -1
@@ -496,7 +496,7 @@ int ksmbd_vfs_write(struct ksmbd_work *wint err =0 ;if (work->conn->connection_type) { -if (!(fp->daccess &FILE_WRITE_DATA_LE )) { +if (!(fp->daccess & (FILE_WRITE_DATA_LE |FILE_APPEND_DATA_LE ))) {pr_err ("no right to write(%pD)\n" , fp->filp); err = -EACCES ; goto out;
Greg Kroah-Hartman
maintainerPATCH 568/695 ksmbd: handle caseless file creation
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
commit c5a709f08d40b1a082e44ffcde1aea4d2822ddd5 upstream.
Ray Zhang reported ksmbd can not create file if parent filename is caseless.
Y:\>mkdir A
Y:\>echo 123 >a\b.txt
The system cannot find the path specified. Y:\>echo 123 >A\b.txt
This patch convert name obtained by caseless lookup to parent name.
--- fs/smb/server/vfs.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
fs/smb/server/vfs.c +3 -7
@@ -1167,7 +1167,7 @@ static bool __caseless_lookup(struct dirif (cmp <0 ) cmp =strncasecmp ((char *)buf->private, name, namlen);if (!cmp) { -memcpy ((char *)buf->private, name, namlen); +memcpy ((char *)buf->private, name, buf->used); buf->dirent_count =1 ;return false; }
@@ -1235,10 +1235,7 @@ int ksmbd_vfs_kern_path_locked(struct kschar *filepath;size_t path_len, remain_len; - filepath =kstrdup (name,GFP_KERNEL ); -if (!filepath) -return -ENOMEM ; - + filepath = name; path_len =strlen (filepath); remain_len = path_len;
@@ -1281,10 +1278,9 @@ int ksmbd_vfs_kern_path_locked(struct ks err = -EINVAL ; out2:path_put (parent_path); -out1: -kfree (filepath); } +out1:if (!err) { err =mnt_want_write (parent_path->mnt);if (err) {
Greg Kroah-Hartman
maintainerPATCH 569/695 ata: libata-scsi: Fix ata_msense_control() CDL page reporting
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 0e9a2990a93f27daa643b6fa73cfa47b128947a7 upstream.
When the user requests the ALL_SUB_MPAGES mode sense page, ata_msense_control() adds the CDL_T2A_SUB_MPAGE twice instead of adding the CDL_T2A_SUB_MPAGE and CDL_T2B_SUB_MPAGE pages information. Correct the second call to ata_msense_control_spgt2() to report the CDL_T2B_SUB_MPAGE page.
--- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/libata-scsi.c +1 -1
@@ -2356,7 +2356,7 @@ static unsigned int ata_msense_control(scase ALL_SUB_MPAGES : n =ata_msense_control_spg0 (dev, buf, changeable); n +=ata_msense_control_spgt2 (dev, buf + n,CDL_T2A_SUB_MPAGE ); - n +=ata_msense_control_spgt2 (dev, buf + n,CDL_T2A_SUB_MPAGE ); + n +=ata_msense_control_spgt2 (dev, buf + n,CDL_T2B_SUB_MPAGE ); n +=ata_msense_control_ata_feature (dev, buf + n);return n;default :
Greg Kroah-Hartman
maintainerPATCH 570/695 scsi: sd: Fix off-by-one error in sd_read_block_characteristics()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Wilck <[email protected]>
commit f81eaf08385ddd474a2f41595a7757502870c0eb upstream.
Ff the device returns page 0xb1 with length 8 (happens with qemu v2.x, for example), sd_read_block_characteristics() may attempt an out-of-bounds memory access when accessing the zoned field at offset 8.
--- drivers/scsi/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/sd.c +1 -1
@@ -3404,7 +3404,7 @@ static void sd_read_block_characteristicrcu_read_lock (); vpd =rcu_dereference (sdkp->device->vpd_pgb1); -if (!vpd || vpd->len <8 ) { +if (!vpd || vpd->len <=8 ) {rcu_read_unlock ();return ; }
Greg Kroah-Hartman
maintainerPATCH 571/695 scsi: ufs: qcom: Update MODE_MAX cfg_bw value
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manish Pandey <[email protected]>
commit 0c40f079f1c808e7e480c795a79009f200366eb1 upstream.
Commit 8db8f6ce556a ("scsi: ufs: qcom: Add missing interconnect bandwidth values for Gear 5") updated the ufs_qcom_bw_table for Gear 5. However, it missed updating the cfg_bw value for the max mode.
Hence update the cfg_bw value for the max mode for UFS 4.x devices.
--- drivers/ufs/host/ufs-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ufs/host/ufs-qcom.c +1 -1
@@ -93,7 +93,7 @@ static const struct __ufs_qcom_bw_table [MODE_HS_RB][UFS_HS_G3][UFS_LANE_2] = { 1492582, 204800 }, [MODE_HS_RB][UFS_HS_G4][UFS_LANE_2] = { 2915200, 409600 }, [MODE_HS_RB][UFS_HS_G5][UFS_LANE_2] = { 5836800, 819200 }, - [MODE_MAX][0][0] = { 7643136, 307200 }, + [MODE_MAX][0][0] = { 7643136, 819200 }, };static void ufs_qcom_get_default_testbus_cfg (struct ufs_qcom_host *host);
Greg Kroah-Hartman
maintainerPATCH 572/695 scsi: lpfc: Restrict support for 32 byte CDBs to specific HBAs
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
commit 05ab4e7846f1103377133c00295a9a910cc6dfc2 upstream.
An older generation of HBAs are failing FCP discovery due to usage of an outdated field in FCP command WQEs.
Fix by checking the SLI Interface Type register for applicable support of 32 Byte CDB commands, and restore a setting for a WQE path using normal 16 byte CDBs.
--- drivers/scsi/lpfc/lpfc_hw4.h | 3 +++ drivers/scsi/lpfc/lpfc_init.c | 21 ++++++++++++++++++--- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-)
drivers/scsi/lpfc/lpfc_hw4.h +3 -0
@@ -4847,6 +4847,7 @@ struct fcp_iwrite64_wqe {#define cmd_buff_len_SHIFT 16#define cmd_buff_len_MASK 0x00000ffff#define cmd_buff_len_WORD word3 +/* Note: payload_offset_len field depends on ASIC support */ #define payload_offset_len_SHIFT 0#define payload_offset_len_MASK 0x0000ffff#define payload_offset_len_WORD word3
@@ -4863,6 +4864,7 @@ struct fcp_iread64_wqe {#define cmd_buff_len_SHIFT 16#define cmd_buff_len_MASK 0x00000ffff#define cmd_buff_len_WORD word3 +/* Note: payload_offset_len field depends on ASIC support */ #define payload_offset_len_SHIFT 0#define payload_offset_len_MASK 0x0000ffff#define payload_offset_len_WORD word3
@@ -4879,6 +4881,7 @@ struct fcp_icmnd64_wqe {#define cmd_buff_len_SHIFT 16#define cmd_buff_len_MASK 0x00000ffff#define cmd_buff_len_WORD word3 +/* Note: payload_offset_len field depends on ASIC support */ #define payload_offset_len_SHIFT 0#define payload_offset_len_MASK 0x0000ffff#define payload_offset_len_WORD word3
drivers/scsi/lpfc/lpfc_init.c +18 -3
@@ -4699,6 +4699,7 @@ lpfc_create_port(struct lpfc_hba *phba,uint64_t wwn;bool use_no_reset_hba = false;int rc; +u8 if_type;if (lpfc_no_hba_reset_cnt) { if (phba->sli_rev < LPFC_SLI_REV4 &&
@@ -4773,10 +4774,24 @@ lpfc_create_port(struct lpfc_hba *phba, shost->max_id =LPFC_MAX_TARGET ; shost->max_lun = vport->cfg_max_luns; shost->this_id =-1 ; -if (phba->sli_rev ==LPFC_SLI_REV4 ) - shost->max_cmd_len =LPFC_FCP_CDB_LEN_32 ; -else + +/* Set max_cmd_len applicable to ASIC support */ +if (phba->sli_rev ==LPFC_SLI_REV4 ) { + if_type =bf_get (lpfc_sli_intf_if_type, + &phba->sli4_hba.sli_intf); +switch (if_type) { +case LPFC_SLI_INTF_IF_TYPE_2 : + fallthrough; +case LPFC_SLI_INTF_IF_TYPE_6 : + shost->max_cmd_len =LPFC_FCP_CDB_LEN_32 ; +break ; +default : + shost->max_cmd_len =LPFC_FCP_CDB_LEN ; +break ; + } + }else { shost->max_cmd_len =LPFC_FCP_CDB_LEN ; + }if (phba->sli_rev ==LPFC_SLI_REV4 ) { if (!phba->cfg_fcp_mq_threshold ||
drivers/scsi/lpfc/lpfc_scsi.c +1 -1
@@ -4760,7 +4760,7 @@ static int lpfc_scsi_prep_cmnd_buf_s4(st/* Word 3 */ bf_set (payload_offset_len, &wqe->fcp_icmd, -sizeof (struct fcp_cmnd32 ) +sizeof (struct fcp_rsp )); +sizeof (struct fcp_cmnd ) +sizeof (struct fcp_rsp ));/* Word 6 */ bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com,
Greg Kroah-Hartman
maintainerPATCH 573/695 scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
commit 5ec4f820cb9766e4583df947150a6febce8da794 upstream.
After a bus fault, capture and log the chip registers immediately, if the NDEBUG_PSEUDO_DMA macro is defined. Remove some printk(KERN_DEBUG ...) messages that aren't needed any more. Don't skip the debug message when bytes == 0. Show all of the byte counters in the debug messages.
--- drivers/scsi/mac_scsi.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-)
drivers/scsi/mac_scsi.c +22 -20
@@ -286,13 +286,14 @@ static inline int macscsi_pread(struct Nwhile (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG ,BASR_DRQ |BASR_PHASE_MATCH ,BASR_DRQ |BASR_PHASE_MATCH ,0 )) { -int bytes; +int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )write_ctrl_reg (hostdata,CTRL_HANDSHAKE_MODE |CTRL_INTERRUPTS_ENABLE ); - bytes =mac_pdma_recv (s, d,min (hostdata->pdma_residual,512 )); + chunk_bytes =min (hostdata->pdma_residual,512 ); + bytes =mac_pdma_recv (s, d, chunk_bytes);if (bytes >0 ) { d += bytes;
@@ -302,23 +303,23 @@ static inline int macscsi_pread(struct Nif (hostdata->pdma_residual ==0 ) goto out; -if (NCR5380_poll_politely2 (hostdata,STATUS_REG ,SR_REQ ,SR_REQ , -BUS_AND_STATUS_REG ,BASR_ACK , -BASR_ACK ,0 ) <0 ) -scmd_printk (KERN_DEBUG , hostdata->connected, -"%s: !REQ and !ACK\n" , __func__);if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) goto out;if (bytes ==0 )udelay (MAC_PDMA_DELAY ); -if (bytes >=0 ) +if (bytes >0 )continue ; -dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, -"%s: bus error (%d/%d)\n" , __func__, d - dst, len);NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); +dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, +"%s: bus error [%d/%d] (%d/%d)\n" , + __func__, d - dst, len, bytes, chunk_bytes); + +if (bytes ==0 ) +continue ; + result =-1 ; goto out; }
@@ -345,13 +346,14 @@ static inline int macscsi_pwrite(structwhile (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG ,BASR_DRQ |BASR_PHASE_MATCH ,BASR_DRQ |BASR_PHASE_MATCH ,0 )) { -int bytes; +int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )write_ctrl_reg (hostdata,CTRL_HANDSHAKE_MODE |CTRL_INTERRUPTS_ENABLE ); - bytes =mac_pdma_send (s, d,min (hostdata->pdma_residual,512 )); + chunk_bytes =min (hostdata->pdma_residual,512 ); + bytes =mac_pdma_send (s, d, chunk_bytes);if (bytes >0 ) { s += bytes;
@@ -370,23 +372,23 @@ static inline int macscsi_pwrite(struct goto out; } -if (NCR5380_poll_politely2 (hostdata,STATUS_REG ,SR_REQ ,SR_REQ , -BUS_AND_STATUS_REG ,BASR_ACK , -BASR_ACK ,0 ) <0 ) -scmd_printk (KERN_DEBUG , hostdata->connected, -"%s: !REQ and !ACK\n" , __func__);if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) goto out;if (bytes ==0 )udelay (MAC_PDMA_DELAY ); -if (bytes >=0 ) +if (bytes >0 )continue ; -dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, -"%s: bus error (%d/%d)\n" , __func__, s - src, len);NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); +dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, +"%s: bus error [%d/%d] (%d/%d)\n" , + __func__, s - src, len, bytes, chunk_bytes); + +if (bytes ==0 ) +continue ; + result =-1 ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 574/695 scsi: mac_scsi: Refactor polling loop
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
commit 5545c3165cbc98615fe65a44f41167cbb557e410 upstream.
Before the error handling can be revised, some preparation is needed. Refactor the polling loop with a new function, macscsi_wait_for_drq(). This function will gain more call sites in the next patch.
--- drivers/scsi/mac_scsi.c | 80 +++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 38 deletions(-)
drivers/scsi/mac_scsi.c +42 -38
@@ -208,8 +208,6 @@ __setup("mac5380=", mac_scsi_setup);".previous \n" \ : "+a" (addr), "+r" (n), "+r" (result) : "a" (io)) -#define MAC_PDMA_DELAY 32 - static inline int mac_pdma_recv(void __iomem *io, unsigned char *start, int n) {unsigned char *addr = start;
@@ -274,6 +272,36 @@ static inline void write_ctrl_reg(structout_be32 (hostdata->io + (CTRL_REG <<4 ), value); } +static inline int macscsi_wait_for_drq (struct NCR5380_hostdata *hostdata) +{ +unsigned int n =1 ;/* effectively multiplies NCR5380_REG_POLL_TIME */ +unsigned char basr; + +again: + basr =NCR5380_read (BUS_AND_STATUS_REG ); + +if (!(basr &BASR_PHASE_MATCH )) +return 1 ; + +if (basr &BASR_IRQ ) +return -1 ; + +if (basr &BASR_DRQ ) +return 0 ; + +if (n-- ==0 ) { +NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); +dsprintk (NDEBUG_PSEUDO_DMA , hostdata->host, +"%s: DRQ timeout\n" , __func__); +return -1 ; + } + +NCR5380_poll_politely2 (hostdata, +BUS_AND_STATUS_REG ,BASR_DRQ ,BASR_DRQ , +BUS_AND_STATUS_REG ,BASR_PHASE_MATCH ,0 ,0 ); + goto again; +} +static inline int macscsi_pread (struct NCR5380_hostdata *hostdata,unsigned char *dst,int len) {
@@ -283,9 +311,7 @@ static inline int macscsi_pread(struct N hostdata->pdma_residual = len; -while (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG , -BASR_DRQ |BASR_PHASE_MATCH , -BASR_DRQ |BASR_PHASE_MATCH ,0 )) { +while (macscsi_wait_for_drq (hostdata) ==0 ) {int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )
@@ -295,19 +321,16 @@ static inline int macscsi_pread(struct N chunk_bytes =min (hostdata->pdma_residual,512 ); bytes =mac_pdma_recv (s, d, chunk_bytes); +if (macintosh_config->ident ==MAC_MODEL_IIFX ) +write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE ); +if (bytes >0 ) { d += bytes; hostdata->pdma_residual -= bytes; }if (hostdata->pdma_residual ==0 ) - goto out; - -if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) - goto out; - -if (bytes ==0 ) -udelay (MAC_PDMA_DELAY ); +break ;if (bytes >0 )continue ;
@@ -321,16 +344,9 @@ static inline int macscsi_pread(struct Ncontinue ; result =-1 ; - goto out; +break ; } -scmd_printk (KERN_ERR , hostdata->connected, -"%s: phase mismatch or !DRQ\n" , __func__); -NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); - result =-1 ; -out: -if (macintosh_config->ident ==MAC_MODEL_IIFX ) -write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE );return result; }
@@ -343,9 +359,7 @@ static inline int macscsi_pwrite(struct hostdata->pdma_residual = len; -while (!NCR5380_poll_politely (hostdata,BUS_AND_STATUS_REG , -BASR_DRQ |BASR_PHASE_MATCH , -BASR_DRQ |BASR_PHASE_MATCH ,0 )) { +while (macscsi_wait_for_drq (hostdata) ==0 ) {int bytes, chunk_bytes;if (macintosh_config->ident ==MAC_MODEL_IIFX )
@@ -355,6 +369,9 @@ static inline int macscsi_pwrite(struct chunk_bytes =min (hostdata->pdma_residual,512 ); bytes =mac_pdma_send (s, d, chunk_bytes); +if (macintosh_config->ident ==MAC_MODEL_IIFX ) +write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE ); +if (bytes >0 ) { s += bytes; hostdata->pdma_residual -= bytes;
@@ -369,15 +386,9 @@ static inline int macscsi_pwrite(struct "%s: Last Byte Sent timeout\n", __func__); result =-1 ; } - goto out; +break ; } -if (!(NCR5380_read (BUS_AND_STATUS_REG ) &BASR_PHASE_MATCH )) - goto out; - -if (bytes ==0 ) -udelay (MAC_PDMA_DELAY ); -if (bytes >0 )continue ;
@@ -390,16 +401,9 @@ static inline int macscsi_pwrite(structcontinue ; result =-1 ; - goto out; +break ; } -scmd_printk (KERN_ERR , hostdata->connected, -"%s: phase mismatch or !DRQ\n" , __func__); -NCR5380_dprint (NDEBUG_PSEUDO_DMA , hostdata->host); - result =-1 ; -out: -if (macintosh_config->ident ==MAC_MODEL_IIFX ) -write_ctrl_reg (hostdata,CTRL_INTERRUPTS_ENABLE );return result; }
Greg Kroah-Hartman
maintainerPATCH 575/695 scsi: mac_scsi: Disallow bus errors during PDMA send
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
commit 5551bc30e4a69ad86d0d008e2f56cd59b6583476 upstream.
SD cards can produce write latency spikes on the order of a hundred milliseconds. If the target firmware does not hide that latency during DATA IN and OUT phases it can cause the PDMA circuitry to raise a processor bus fault which in turn leads to an unreliable byte count and a DMA overrun.
The Last Byte Sent flag is used to detect the overrun but this mechanism is unreliable on some systems. Instead, set a DID_ERROR result whenever there is a bus fault during a PDMA send, unless the cause was a phase mismatch.
--- drivers/scsi/mac_scsi.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-)
drivers/scsi/mac_scsi.c +19 -25
@@ -102,11 +102,15 @@ __setup("mac5380=", mac_scsi_setup);* Linux SCSI drivers lack knowledge of the timing behaviour of SCSI targets * so bus errors are unavoidable. * -* If a MOVE.B instruction faults, we assume that zero bytes were transferred -* and simply retry. That assumption probably depends on target behaviour but -* seems to hold up okay. The NOP provides synchronization: without it the -* fault can sometimes occur after the program counter has moved past the -* offending instruction. Post-increment addressing can't be used. +* If a MOVE.B instruction faults during a receive operation, we assume the +* target sent nothing and try again. That assumption probably depends on +* target firmware but it seems to hold up okay. If a fault happens during a +* send operation, the target may or may not have seen /ACK and got the byte. +* It's uncertain so the whole SCSI command gets retried. +* +* The NOP is needed for synchronization because the fault address in the +* exception stack frame may or may not be the instruction that actually +* caused the bus error. Post-increment addressing can't be used. */ #define MOVE_BYTE (operands) \
@@ -243,22 +247,21 @@ static inline int mac_pdma_send(unsignedif (n >=1 ) {MOVE_BYTE ("%0@,%3@" );if (result) - goto out; +return -1 ; }if (n >=1 && ((unsigned long )addr &1 )) {MOVE_BYTE ("%0@,%3@" );if (result) - goto out; +return -2 ; }while (n >=32 )MOVE_16_WORDS ("%0@+,%3@" );while (n >=2 )MOVE_WORD ("%0@+,%3@" );if (result) -return start - addr;/* Negated to indicate uncertain length */ +return start - addr -1 ;/* Negated to indicate uncertain length */ if (n ==1 )MOVE_BYTE ("%0@,%3@" ); -out:return addr - start; }
@@ -307,7 +310,6 @@ static inline int macscsi_pread(struct N {u8 __iomem *s = hostdata->pdma_io + (INPUT_DATA_REG <<4 );unsigned char *d = dst; -int result =0 ; hostdata->pdma_residual = len;
@@ -343,11 +345,12 @@ static inline int macscsi_pread(struct Nif (bytes ==0 )continue ; - result =-1 ; +if (macscsi_wait_for_drq (hostdata) <=0 ) +set_host_byte (hostdata->connected,DID_ERROR );break ; } -return result; +return 0 ; } static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
@@ -355,7 +358,6 @@ static inline int macscsi_pwrite(struct {unsigned char *s = src;u8 __iomem *d = hostdata->pdma_io + (OUTPUT_DATA_REG <<4 ); -int result =0 ; hostdata->pdma_residual = len;
@@ -377,17 +379,8 @@ static inline int macscsi_pwrite(struct hostdata->pdma_residual -= bytes; } -if (hostdata->pdma_residual ==0 ) { -if (NCR5380_poll_politely (hostdata,TARGET_COMMAND_REG , -TCR_LAST_BYTE_SENT , -TCR_LAST_BYTE_SENT , -0 ) <0 ) { -scmd_printk (KERN_ERR , hostdata->connected, -"%s: Last Byte Sent timeout\n" , __func__); - result =-1 ; - } +if (hostdata->pdma_residual ==0 )break ; - }if (bytes >0 )continue ;
@@ -400,11 +393,12 @@ static inline int macscsi_pwrite(structif (bytes ==0 )continue ; - result =-1 ; +if (macscsi_wait_for_drq (hostdata) <=0 ) +set_host_byte (hostdata->connected,DID_ERROR );break ; } -return result; +return 0 ; } static int macscsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
Greg Kroah-Hartman
maintainerPATCH 576/695 can: esd_usb: Remove CAN_CTRLMODE_3_SAMPLES for CAN-USB/3-FD
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Mätje <[email protected]>
commit 75b3189540578f96b4996e4849b6649998f49455 upstream.
Remove the CAN_CTRLMODE_3_SAMPLES announcement for CAN-USB/3-FD devices because these devices don't support it.
The hardware has a Microchip SAM E70 microcontroller that uses a Bosch MCAN IP core as CAN FD controller. But this MCAN core doesn't support triple sampling.
--- drivers/net/can/usb/esd_usb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/net/can/usb/esd_usb.c +1 -5
@@ -3,7 +3,7 @@* CAN driver for esd electronics gmbh CAN-USB/2, CAN-USB/3 and CAN-USB/Micro * * Copyright (C) 2010-2012 esd electronic system design gmbh, Matthias Fuchs <[email protected]> -* Copyright (C) 2022-2023 esd electronics gmbh, Frank Jungclaus <[email protected]> +* Copyright (C) 2022-2024 esd electronics gmbh, Frank Jungclaus <[email protected]> */ #include <linux/can.h>
@@ -1116,9 +1116,6 @@ static int esd_usb_3_set_bittiming(strucif (priv->can.ctrlmode &CAN_CTRLMODE_LISTENONLY ) flags |=ESD_USB_3_BAUDRATE_FLAG_LOM ; -if (priv->can.ctrlmode &CAN_CTRLMODE_3_SAMPLES ) - flags |=ESD_USB_3_BAUDRATE_FLAG_TRS ; - baud_x->nom.brp =cpu_to_le16 (nom_bt->brp & (nom_btc->brp_max -1 )); baud_x->nom.sjw =cpu_to_le16 (nom_bt->sjw & (nom_btc->sjw_max -1 )); baud_x->nom.tseg1 = cpu_to_le16((nom_bt->prop_seg + nom_bt->phase_seg1)
@@ -1219,7 +1216,6 @@ static int esd_usb_probe_one_net(structswitch (le16_to_cpu (dev->udev->descriptor.idProduct)) {case ESD_USB_CANUSB3_PRODUCT_ID : priv->can.clock.freq =ESD_USB_3_CAN_CLOCK ; - priv->can.ctrlmode_supported |=CAN_CTRLMODE_3_SAMPLES ; priv->can.ctrlmode_supported |=CAN_CTRLMODE_FD ; priv->can.bittiming_const = &esd_usb_3_nom_bittiming_const; priv->can.data_bittiming_const = &esd_usb_3_data_bittiming_const;
Greg Kroah-Hartman
maintainerPATCH 577/695 wifi: rtw88: Fix USB/SDIO devices not transmitting beacons
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <[email protected]>
commit faa2e484b393c56bc1243dca6676a70bc485f775 upstream.
All USB devices supported by rtw88 have the same problem: they don't transmit beacons in AP mode. (Some?) SDIO devices are also affected. The cause appears to be clearing BIT_EN_BCNQ_DL of REG_FWHW_TXQ_CTRL before uploading the beacon reserved page, so don't clear the bit for USB and SDIO devices.
Tested with RTL8811CU and RTL8723DU.
--- drivers/net/wireless/realtek/rtw88/fw.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/net/wireless/realtek/rtw88/fw.c +8 -5
@@ -1468,10 +1468,12 @@ int rtw_fw_write_data_rsvd_page(struct r val |=BIT_ENSWBCN >>8 ;rtw_write8 (rtwdev,REG_CR +1 , val); - val =rtw_read8 (rtwdev,REG_FWHW_TXQ_CTRL +2 ); - bckp[1 ] = val; - val &= ~(BIT_EN_BCNQ_DL >>16 ); -rtw_write8 (rtwdev,REG_FWHW_TXQ_CTRL +2 , val); +if (rtw_hci_type (rtwdev) ==RTW_HCI_TYPE_PCIE ) { + val =rtw_read8 (rtwdev,REG_FWHW_TXQ_CTRL +2 ); + bckp[1 ] = val; + val &= ~(BIT_EN_BCNQ_DL >>16 ); +rtw_write8 (rtwdev,REG_FWHW_TXQ_CTRL +2 , val); + } ret =rtw_hci_write_data_rsvd_page (rtwdev, buf, size);if (ret) {
@@ -1496,7 +1498,8 @@ restore: rsvd_pg_head = rtwdev->fifo.rsvd_boundary;rtw_write16 (rtwdev,REG_FIFOPAGE_CTRL_2 , rsvd_pg_head |BIT_BCN_VALID_V1 ); -rtw_write8 (rtwdev,REG_FWHW_TXQ_CTRL +2 , bckp[1 ]); +if (rtw_hci_type (rtwdev) ==RTW_HCI_TYPE_PCIE ) +rtw_write8 (rtwdev,REG_FWHW_TXQ_CTRL +2 , bckp[1 ]);rtw_write8 (rtwdev,REG_CR +1 , bckp[0 ]);return ret;
Greg Kroah-Hartman
maintainerPATCH 578/695 usbnet: fix cyclical race on disconnect with work queue
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 04e906839a053f092ef53f4fb2d610983412b904 upstream.
The work can submit URBs and the URBs can schedule the work. This cycle needs to be broken, when a device is to be stopped. Use a flag to do so.
This is a design issue as old as the driver.
--- drivers/net/usb/usbnet.c | 37 ++++++++++++++++++++++++++++--------- include/linux/usb/usbnet.h | 15 +++++++++++++++ 2 files changed, 43 insertions(+), 9 deletions(-)
drivers/net/usb/usbnet.c +28 -9
@@ -464,10 +464,15 @@ static enum skb_state defer_bh(struct usvoid usbnet_defer_kevent (struct usbnet *dev,int work) {set_bit (work, &dev->flags); -if (!schedule_work (&dev->kevent)) -netdev_dbg (dev->net,"kevent %s may have been dropped\n" , usbnet_event_names[work]); -else -netdev_dbg (dev->net,"kevent %s scheduled\n" , usbnet_event_names[work]); +if (!usbnet_going_away (dev)) { +if (!schedule_work (&dev->kevent)) +netdev_dbg (dev->net, +"kevent %s may have been dropped\n" , + usbnet_event_names[work]); +else +netdev_dbg (dev->net, +"kevent %s scheduled\n" , usbnet_event_names[work]); + } }EXPORT_SYMBOL_GPL (usbnet_defer_kevent);
@@ -535,7 +540,8 @@ static int rx_submit (struct usbnet *devtasklet_schedule (&dev->bh);break ;case 0 : -__usbnet_queue_skb (&dev->rxq, skb, rx_start); +if (!usbnet_going_away (dev)) +__usbnet_queue_skb (&dev->rxq, skb, rx_start); } }else {netif_dbg (dev, ifdown, dev->net,"rx: stopped\n" );
@@ -843,9 +849,18 @@ int usbnet_stop (struct net_device *net)/* deferred work (timer, softirq, task) must also stop */ dev->flags =0 ; -del_timer_sync (&dev->delay); -tasklet_kill (&dev->bh); +del_timer_sync (&dev->delay); +tasklet_kill (&dev->bh);cancel_work_sync (&dev->kevent); + +/* We have cyclic dependencies. Those calls are needed +* to break a cycle. We cannot fall into the gaps because +* we have a flag +*/ +tasklet_kill (&dev->bh); +del_timer_sync (&dev->delay); +cancel_work_sync (&dev->kevent); +if (!pm)usb_autopm_put_interface (dev->intf);
@@ -1171,7 +1186,8 @@ fail_halt: status); }else {clear_bit (EVENT_RX_HALT , &dev->flags); -tasklet_schedule (&dev->bh); +if (!usbnet_going_away (dev)) +tasklet_schedule (&dev->bh); } }
@@ -1196,7 +1212,8 @@ fail_halt:usb_autopm_put_interface (dev->intf); fail_lowmem:if (resched) -tasklet_schedule (&dev->bh); +if (!usbnet_going_away (dev)) +tasklet_schedule (&dev->bh); } }
@@ -1559,6 +1576,7 @@ static void usbnet_bh (struct timer_list }else if (netif_running (dev->net) &&netif_device_present (dev->net) &&netif_carrier_ok (dev->net) && + !usbnet_going_away (dev) && !timer_pending (&dev->delay) && !test_bit (EVENT_RX_PAUSED , &dev->flags) && !test_bit (EVENT_RX_HALT , &dev->flags)) {
@@ -1606,6 +1624,7 @@ void usbnet_disconnect (struct usb_interusb_set_intfdata (intf,NULL );if (!dev)return ; +usbnet_mark_going_away (dev); xdev =interface_to_usbdev (intf);
include/linux/usb/usbnet.h +15 -0
@@ -76,8 +76,23 @@ struct usbnet {# define EVENT_LINK_CHANGE 11# define EVENT_SET_RX_MODE 12# define EVENT_NO_IP_ALIGN 13 +/* This one is special, as it indicates that the device is going away +* there are cyclic dependencies between tasklet, timer and bh +* that must be broken +*/ +# define EVENT_UNPLUG 31 }; +static inline bool usbnet_going_away (struct usbnet *ubn) +{ +return test_bit (EVENT_UNPLUG , &ubn->flags); +} + +static inline void usbnet_mark_going_away (struct usbnet *ubn) +{ +set_bit (EVENT_UNPLUG , &ubn->flags); +} +static inline struct usb_driver *driver_of (struct usb_interface *intf) {return to_usb_driver (intf->dev.driver);
Greg Kroah-Hartman
maintainerPATCH 579/695 arm64: dts: mediatek: mt8195-cherry: Mark USB 3.0 on xhci1 as disabled
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
commit 09d385679487c58f0859c1ad4f404ba3df2f8830 upstream.
USB 3.0 on xhci1 is not used, as the controller shares the same PHY as pcie1. The latter is enabled to support the M.2 PCIe WLAN card on this design.
Mark USB 3.0 as disabled on this controller using the "mediatek,u3p-dis-msk" property.
--- arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +1 -0
@@ -1404,6 +1404,7 @@ rx-fifo-depth = <3072>; vusb33-supply = <&mt6359_vusb_ldo_reg>; vbus-supply = <&usb_vbus>; + mediatek,u3p-dis-msk = <1>; }; &xhci2 {
Greg Kroah-Hartman
maintainerPATCH 580/695 arm64: dts: mediatek: mt8395-nio-12l: Mark USB 3.0 on xhci1 as disabled
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
commit be985531a5dd9ca50fc9f3f85b8adeb2a4a75a58 upstream.
USB 3.0 on xhci1 is not used, as the controller shares the same PHY as pcie1. The latter is enabled to support the M.2 PCIe WLAN card on this design.
Mark USB 3.0 as disabled on this controller using the "mediatek,u3p-dis-msk" property.
--- arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts | 1 + 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts +1 -0
@@ -898,6 +898,7 @@ usb2-lpm-disable; vusb33-supply = <&mt6359_vusb_ldo_reg>; vbus-supply = <&vsys>; + mediatek,u3p-dis-msk = <1>; status = "okay"; };
Greg Kroah-Hartman
maintainerPATCH 581/695 USB: appledisplay: close race between probe and completion handler
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 8265d06b7794493d82c5c21a12d7ba43eccc30cb upstream.
There is a small window during probing when IO is running but the backlight is not registered. Processing events during that time will crash. The completion handler needs to check for a backlight before scheduling work.
The bug is as old as the driver.
--- drivers/usb/misc/appledisplay.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/usb/misc/appledisplay.c +11 -4
@@ -107,7 +107,12 @@ static void appledisplay_complete(structcase ACD_BTN_BRIGHT_UP :case ACD_BTN_BRIGHT_DOWN : pdata->button_pressed =1 ; -schedule_delayed_work (&pdata->work,0 ); +/* +* there is a window during which no device +* is registered +*/ +if (pdata->bd ) +schedule_delayed_work (&pdata->work,0 );break ;case ACD_BTN_NONE :default :
@@ -202,6 +207,7 @@ static int appledisplay_probe(struct usb const struct usb_device_id *id) {struct backlight_properties props; +struct backlight_device *backlight;struct appledisplay *pdata;struct usb_device *udev =interface_to_usbdev (iface);struct usb_endpoint_descriptor *endpoint;
@@ -272,13 +278,14 @@ static int appledisplay_probe(struct usbmemset (&props,0 ,sizeof (struct backlight_properties )); props.type =BACKLIGHT_RAW ; props.max_brightness =0xff ; - pdata->bd =backlight_device_register (bl_name,NULL , pdata, + backlight =backlight_device_register (bl_name,NULL , pdata, &appledisplay_bl_data, &props); -if (IS_ERR (pdata->bd)) { +if (IS_ERR (backlight)) {dev_err (&iface->dev,"Backlight registration failed\n" ); - retval =PTR_ERR (pdata->bd); + retval =PTR_ERR (backlight); goto error; } + pdata->bd = backlight;/* Try to get brightness */ brightness =appledisplay_bl_get_brightness (pdata->bd);
Greg Kroah-Hartman
maintainerPATCH 582/695 USB: misc: cypress_cy7c63: check for short transfer
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 49cd2f4d747eeb3050b76245a7f72aa99dbd3310 upstream.
As we process the second byte of a control transfer, transfers of less than 2 bytes must be discarded.
This bug is as old as the driver.
--- drivers/usb/misc/cypress_cy7c63.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/misc/cypress_cy7c63.c +4 -0
@@ -88,6 +88,9 @@ static int vendor_command(struct cypressUSB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_OTHER , address, data, iobuf,CYPRESS_MAX_REQSIZE , USB_CTRL_GET_TIMEOUT); +/* we must not process garbage */ +if (retval <2 ) + goto err_buf;/* store returned data (more READs to be added) */ switch (request) {
@@ -107,6 +110,7 @@ static int vendor_command(struct cypressbreak ; } +err_buf:kfree (iobuf); error:return retval;
Greg Kroah-Hartman
maintainerPATCH 583/695 USB: class: CDC-ACM: fix race between get_serial and set_serial
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit b41c1fa155ba56d125885b0191aabaf3c508d0a3 upstream.
TIOCGSERIAL is an ioctl. Thus it must be atomic. It returns two values. Racing with set_serial it can return an inconsistent result. The mutex must be taken.
In terms of logic the bug is as old as the driver. In terms of code it goes back to the conversion to the get_serial and set_serial methods.
--- drivers/usb/class/cdc-acm.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/class/cdc-acm.c +2 -0
@@ -962,10 +962,12 @@ static int get_serial_info(struct tty_ststruct acm *acm = tty->driver_data; ss->line = acm->minor; +mutex_lock (&acm->port.mutex); ss->close_delay =jiffies_to_msecs (acm->port.close_delay) /10 ; ss->closing_wait = acm->port.closing_wait ==ASYNC_CLOSING_WAIT_NONE ?ASYNC_CLOSING_WAIT_NONE :jiffies_to_msecs (acm->port.closing_wait) /10 ; +mutex_unlock (&acm->port.mutex);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 584/695 USB: misc: yurex: fix race between read and write
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit 93907620b308609c72ba4b95b09a6aa2658bb553 upstream.
The write code path touches the bbu member in a non atomic manner without taking the spinlock. Fix it.
The bug is as old as the driver.
--- drivers/usb/misc/yurex.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/misc/yurex.c +6 -4
@@ -404,7 +404,6 @@ static ssize_t yurex_read(struct file *fstruct usb_yurex *dev;int len =0 ;char in_buffer[MAX_S64_STRLEN ]; -unsigned long flags; dev = file->private_data;
@@ -419,9 +418,9 @@ static ssize_t yurex_read(struct file *freturn -EIO ; } -spin_lock_irqsave (&dev->lock, flags); +spin_lock_irq (&dev->lock);scnprintf (in_buffer,MAX_S64_STRLEN ,"%lld\n" , dev->bbu); -spin_unlock_irqrestore (&dev->lock, flags); +spin_unlock_irq (&dev->lock);mutex_unlock (&dev->io_mutex);return simple_read_from_buffer (buffer, count, ppos, in_buffer, len);
@@ -511,8 +510,11 @@ static ssize_t yurex_write(struct file * __func__, retval); goto error; } -if (set && timeout) +if (set && timeout) { +spin_lock_irq (&dev->lock); dev->bbu = c2; +spin_unlock_irq (&dev->lock); + }return timeout ? count : -EIO ; error:
Greg Kroah-Hartman
maintainerPATCH 585/695 usb: xhci: fix loss of data on Cadence xHC
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Laszczak <[email protected]>
commit e5fa8db0be3e8757e8641600c518425a4589b85c upstream.
Streams should flush their TRB cache, re-read TRBs, and start executing TRBs from the beginning of the new dequeue pointer after a 'Set TR Dequeue Pointer' command.
Cadence controllers may fail to start from the beginning of the dequeue TRB as it doesn't clear the Opaque 'RsvdO' field of the stream context during 'Set TR Dequeue' command. This stream context area is where xHC stores information about the last partially executed TD when a stream is stopped. xHC uses this information to resume the transfer where it left mid TD, when the stream is restarted.
Patch fixes this by clearing out all RsvdO fields before initializing new Stream transfer using a 'Set TR Dequeue Pointer' command.
--- drivers/usb/cdns3/host.c | 4 +++- drivers/usb/host/xhci-pci.c | 7 +++++++ drivers/usb/host/xhci-ring.c | 14 ++++++++++++++ drivers/usb/host/xhci.h | 1 + 4 files changed, 25 insertions(+), 1 deletion(-)
drivers/usb/cdns3/host.c +3 -1
@@ -62,7 +62,9 @@ static const struct xhci_plat_priv xhci_ .resume_quirk = xhci_cdns3_resume_quirk, }; -static const struct xhci_plat_priv xhci_plat_cdnsp_xhci; +static const struct xhci_plat_priv xhci_plat_cdnsp_xhci = { + .quirks =XHCI_CDNS_SCTX_QUIRK , +};static int __cdns_host_init (struct cdns *cdns) {
drivers/usb/host/xhci-pci.c +7 -0
@@ -78,6 +78,9 @@#define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142#define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 +#define PCI_DEVICE_ID_CADENCE 0x17CD +#define PCI_DEVICE_ID_CADENCE_SSP 0x0200 +static const char hcd_name[] ="xhci_hcd" ;static struct hc_driver __read_mostly xhci_pci_hc_driver;
@@ -473,6 +476,10 @@ static void xhci_pci_quirks(struct devic xhci->quirks |=XHCI_ZHAOXIN_TRB_FETCH ; } +if (pdev->vendor ==PCI_DEVICE_ID_CADENCE && + pdev->device ==PCI_DEVICE_ID_CADENCE_SSP ) + xhci->quirks |=XHCI_CDNS_SCTX_QUIRK ; +/* xHC spec requires PCI devices to support D3hot and D3cold */ if (xhci->hci_version >=0x120 ) xhci->quirks |=XHCI_DEFAULT_PM_RUNTIME_ALLOW ;
drivers/usb/host/xhci-ring.c +14 -0
@@ -1399,6 +1399,20 @@ static void xhci_handle_cmd_set_deq(strustruct xhci_stream_ctx *ctx = &ep->stream_info->stream_ctx_array[stream_id]; deq =le64_to_cpu (ctx->stream_ring) &SCTX_DEQ_MASK ; + +/* +* Cadence xHCI controllers store some endpoint state +* information within Rsvd0 fields of Stream Endpoint +* context. This field is not cleared during Set TR +* Dequeue Pointer command which causes XDMA to skip +* over transfer ring and leads to data loss on stream +* pipe. +* To fix this issue driver must clear Rsvd0 field. +*/ +if (xhci->quirks &XHCI_CDNS_SCTX_QUIRK ) { + ctx->reserved[0 ] =0 ; + ctx->reserved[1 ] =0 ; + } }else { deq =le64_to_cpu (ep_ctx->deq) & ~EP_CTX_CYCLE_MASK ; }
drivers/usb/host/xhci.h +1 -0
@@ -1628,6 +1628,7 @@ struct xhci_hcd {#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)#define XHCI_ZHAOXIN_HOST BIT_ULL(46)#define XHCI_WRITE_64_HI_LO BIT_ULL(47) +#define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48)unsigned int num_active_eps;unsigned int limit_active_eps;
Greg Kroah-Hartman
maintainerPATCH 586/695 usb: cdnsp: Fix incorrect usb_request status
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Laszczak <[email protected]>
commit 1702bec4477cc7d31adb4a760d14d33fac928b7a upstream.
Fix changes incorrect usb_request->status returned during disabling endpoints. Before fix the status returned during dequeuing requests while disabling endpoint was ECONNRESET.
Patch change it to ESHUTDOWN.
Patch fixes issue detected during testing UVC gadget.
During stopping streaming the class starts dequeuing usb requests and controller driver returns the -ECONNRESET status. After completion requests the class or application "uvc-gadget" try to queue this request again. Changing this status to ESHUTDOWN cause that UVC assumes that endpoint is disabled, or device is disconnected and stops re-queuing usb requests.
--- drivers/usb/cdns3/cdnsp-ring.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/cdns3/cdnsp-ring.c +4 -2
@@ -718,7 +718,8 @@ int cdnsp_remove_request(struct cdnsp_de seg =cdnsp_trb_in_td (pdev, cur_td->start_seg, cur_td->first_trb, cur_td->last_trb, hw_deq); -if (seg && (pep->ep_state &EP_ENABLED )) +if (seg && (pep->ep_state &EP_ENABLED ) && + !(pep->ep_state &EP_DIS_IN_RROGRESS ))cdnsp_find_new_dequeue_state (pdev, pep, preq->request.stream_id, cur_td, &deq_state);else
@@ -736,7 +737,8 @@ int cdnsp_remove_request(struct cdnsp_de* During disconnecting all endpoint will be disabled so we don't * have to worry about updating dequeue pointer. */ -if (pdev->cdnsp_state &CDNSP_STATE_DISCONNECT_PENDING ) { +if (pdev->cdnsp_state &CDNSP_STATE_DISCONNECT_PENDING || + pep->ep_state &EP_DIS_IN_RROGRESS ) { status = -ESHUTDOWN ; ret =cdnsp_cmd_set_deq (pdev, pep, &deq_state); }
Greg Kroah-Hartman
maintainerPATCH 587/695 usb: xHCI: add XHCI_RESET_ON_RESUME quirk for Phytium xHCI host
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: WangYuli <[email protected]>
commit 118ecef16cc221a23f96617016f7a205b070109f upstream.
The resume operation of Phytium Px210 xHCI host would failed to restore state. Use the XHCI_RESET_ON_RESUME quirk to skip it and reset the controller after resume.
--- drivers/usb/host/xhci-pci.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/host/xhci-pci.c +7 -0
@@ -55,6 +55,9 @@#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed +#define PCI_VENDOR_ID_PHYTIUM 0x1db7 +#define PCI_DEVICE_ID_PHYTIUM_XHCI 0xdc27 +/* Thunderbolt */ #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI 0x15b5
@@ -419,6 +422,10 @@ static void xhci_pci_quirks(struct devicif (pdev->vendor ==PCI_VENDOR_ID_VIA ) xhci->quirks |=XHCI_RESET_ON_RESUME ; +if (pdev->vendor ==PCI_VENDOR_ID_PHYTIUM && + pdev->device ==PCI_DEVICE_ID_PHYTIUM_XHCI ) + xhci->quirks |=XHCI_RESET_ON_RESUME ; +/* See https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ if (pdev->vendor ==PCI_VENDOR_ID_VIA && pdev->device ==0x3432 )
Greg Kroah-Hartman
maintainerPATCH 588/695 usb: gadget: dummy_hcd: execute hrtimer callback in softirq context
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Konovalov <[email protected]>
commit 9313d139aa25e572d860f6f673b73a20f32d7f93 upstream.
Commit a7f3813e589f ("usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler") switched dummy_hcd to use hrtimer and made the timer's callback be executed in the hardirq context.
With that change, __usb_hcd_giveback_urb now gets executed in the hardirq context, which causes problems for KCOV and KMSAN.
One problem is that KCOV now is unable to collect coverage from the USB code that gets executed from the dummy_hcd's timer callback, as KCOV cannot collect coverage in the hardirq context.
Another problem is that the dummy_hcd hrtimer might get triggered in the middle of a softirq with KCOV remote coverage collection enabled, and that causes a WARNING in KCOV, as reported by syzbot. (I sent a separate patch to shut down this WARNING, but that doesn't fix the other two issues.)
Finally, KMSAN appears to ignore tracking memory copying operations that happen in the hardirq context, which causes false positive kernel-infoleaks, as reported by syzbot.
Change the hrtimer in dummy_hcd to execute the callback in the softirq context.
--- drivers/usb/gadget/udc/dummy_hcd.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/usb/gadget/udc/dummy_hcd.c +8 -6
@@ -1304,7 +1304,8 @@ static int dummy_urb_enqueue(/* kick the scheduler, it'll do the rest */ if (!hrtimer_active (&dum_hcd->timer)) -hrtimer_start (&dum_hcd->timer,ns_to_ktime (DUMMY_TIMER_INT_NSECS ),HRTIMER_MODE_REL ); +hrtimer_start (&dum_hcd->timer,ns_to_ktime (DUMMY_TIMER_INT_NSECS ), +HRTIMER_MODE_REL_SOFT ); done:spin_unlock_irqrestore (&dum_hcd->dum->lock, flags);
@@ -1325,7 +1326,7 @@ static int dummy_urb_dequeue(struct usb_ rc =usb_hcd_check_unlink_urb (hcd, urb, status);if (!rc && dum_hcd->rh_state !=DUMMY_RH_RUNNING && !list_empty (&dum_hcd->urbp_list)) -hrtimer_start (&dum_hcd->timer,ns_to_ktime (0 ),HRTIMER_MODE_REL ); +hrtimer_start (&dum_hcd->timer,ns_to_ktime (0 ),HRTIMER_MODE_REL_SOFT );spin_unlock_irqrestore (&dum_hcd->dum->lock, flags);return rc;
@@ -1995,7 +1996,8 @@ return_urb: dum_hcd->udev =NULL ; }else if (dum_hcd->rh_state ==DUMMY_RH_RUNNING ) {/* want a 1 msec delay here */ -hrtimer_start (&dum_hcd->timer,ns_to_ktime (DUMMY_TIMER_INT_NSECS ),HRTIMER_MODE_REL ); +hrtimer_start (&dum_hcd->timer,ns_to_ktime (DUMMY_TIMER_INT_NSECS ), +HRTIMER_MODE_REL_SOFT ); }spin_unlock_irqrestore (&dum->lock, flags);
@@ -2389,7 +2391,7 @@ static int dummy_bus_resume(struct usb_h dum_hcd->rh_state =DUMMY_RH_RUNNING ;set_link_state (dum_hcd);if (!list_empty (&dum_hcd->urbp_list)) -hrtimer_start (&dum_hcd->timer,ns_to_ktime (0 ),HRTIMER_MODE_REL ); +hrtimer_start (&dum_hcd->timer,ns_to_ktime (0 ),HRTIMER_MODE_REL_SOFT ); hcd->state =HC_STATE_RUNNING ; }spin_unlock_irq (&dum_hcd->dum->lock);
@@ -2467,7 +2469,7 @@ static DEVICE_ATTR_RO(urbs);static int dummy_start_ss (struct dummy_hcd *dum_hcd) { -hrtimer_init (&dum_hcd->timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL ); +hrtimer_init (&dum_hcd->timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL_SOFT ); dum_hcd->timer.function = dummy_timer; dum_hcd->rh_state =DUMMY_RH_RUNNING ; dum_hcd->stream_en_ep =0 ;
@@ -2497,7 +2499,7 @@ static int dummy_start(struct usb_hcd *hreturn dummy_start_ss (dum_hcd);spin_lock_init (&dum_hcd->dum->lock); -hrtimer_init (&dum_hcd->timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL ); +hrtimer_init (&dum_hcd->timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL_SOFT ); dum_hcd->timer.function = dummy_timer; dum_hcd->rh_state =DUMMY_RH_RUNNING ;
Greg Kroah-Hartman
maintainerPATCH 589/695 usb: dwc2: drd: fix clock gating on USB role switch
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Marek <[email protected]>
commit 2c6b6afa59e78bebcb65bbc8a76b3459f139547c upstream.
The dwc2_handle_usb_suspend_intr() function disables gadget clocks in USB peripheral mode when no other power-down mode is available (introduced by commit 0112b7ce68ea ("usb: dwc2: Update dwc2_handle_usb_suspend_intr function.")). However, the dwc2_drd_role_sw_set() USB role update handler attempts to read DWC2 registers if the USB role has changed while the USB is in suspend mode (when the clocks are gated). This causes the system to hang.
Release the gadget clocks before handling the USB role update.
--- drivers/usb/dwc2/drd.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/dwc2/drd.c +9 -0
@@ -127,6 +127,15 @@ static int dwc2_drd_role_sw_set(struct u role =USB_ROLE_DEVICE ; } +if ((IS_ENABLED (CONFIG_USB_DWC2_PERIPHERAL ) || +IS_ENABLED (CONFIG_USB_DWC2_DUAL_ROLE )) && +dwc2_is_device_mode (hsotg) && + hsotg->lx_state ==DWC2_L2 && + hsotg->params.power_down ==DWC2_POWER_DOWN_PARAM_NONE && + hsotg->bus_suspended && + !hsotg->params.no_clock_gating) +dwc2_gadget_exit_clock_gating (hsotg,0 ); +if (role ==USB_ROLE_HOST ) { already =dwc2_ovr_avalid (hsotg, true); }else if (role ==USB_ROLE_DEVICE ) {
Greg Kroah-Hartman
maintainerPATCH 590/695 bus: integrator-lm: fix OF node leak in probe()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 15a62b81175885b5adfcaf49870466e3603f06c7 upstream.
Driver code is leaking OF node reference from of_find_matching_node() in probe().
--- drivers/bus/arm-integrator-lm.c | 1 + 1 file changed, 1 insertion(+)
drivers/bus/arm-integrator-lm.c +1 -0
@@ -85,6 +85,7 @@ static int integrator_ap_lm_probe(structreturn -ENODEV ; } map =syscon_node_to_regmap (syscon); +of_node_put (syscon);if (IS_ERR (map)) {dev_err (dev,"could not find Integrator/AP system controller\n" );
Greg Kroah-Hartman
maintainerPATCH 591/695 bus: mhi: host: pci_generic: Update EDL firmware path for Foxconn modems
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slark Xiao <[email protected]>
commit a7bc66fe8093b48e86386cf73dd601feaaa7949c upstream.
Foxconn uses a unique firmware for their MHI based modems. So the generic firmware from Qcom won't work. Hence, update the EDL firmware path to include the 'foxconn' subdirectory based on the modem SoC so that the Foxconn specific firmware could be used.
Respective firmware will be upstreamed to linux-firmware repo.
--- drivers/bus/mhi/host/pci_generic.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
drivers/bus/mhi/host/pci_generic.c +5 -8
@@ -433,8 +433,7 @@ static const struct mhi_controller_confistatic const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = { .name ="foxconn-sdx55" , - .fw ="qcom/sdx55m/sbl1.mbn" , - .edl ="qcom/sdx55m/edl.mbn" , + .edl ="qcom/sdx55m/foxconn/prog_firehose_sdx55.mbn" , .config = &modem_foxconn_sdx55_config, .bar_num =MHI_PCI_DEFAULT_BAR_NUM , .dma_data_width =32 ,
@@ -444,8 +443,7 @@ static const struct mhi_pci_dev_info mhistatic const struct mhi_pci_dev_info mhi_foxconn_t99w175_info = { .name ="foxconn-t99w175" , - .fw ="qcom/sdx55m/sbl1.mbn" , - .edl ="qcom/sdx55m/edl.mbn" , + .edl ="qcom/sdx55m/foxconn/prog_firehose_sdx55.mbn" , .config = &modem_foxconn_sdx55_config, .bar_num =MHI_PCI_DEFAULT_BAR_NUM , .dma_data_width =32 ,
@@ -455,8 +453,7 @@ static const struct mhi_pci_dev_info mhistatic const struct mhi_pci_dev_info mhi_foxconn_dw5930e_info = { .name ="foxconn-dw5930e" , - .fw ="qcom/sdx55m/sbl1.mbn" , - .edl ="qcom/sdx55m/edl.mbn" , + .edl ="qcom/sdx55m/foxconn/prog_firehose_sdx55.mbn" , .config = &modem_foxconn_sdx55_config, .bar_num =MHI_PCI_DEFAULT_BAR_NUM , .dma_data_width =32 ,
@@ -502,7 +499,7 @@ static const struct mhi_pci_dev_info mhistatic const struct mhi_pci_dev_info mhi_foxconn_t99w515_info = { .name ="foxconn-t99w515" , - .edl ="fox/sdx72m/edl.mbn" , + .edl ="qcom/sdx72m/foxconn/edl.mbn" , .edl_trigger = true, .config = &modem_foxconn_sdx72_config, .bar_num =MHI_PCI_DEFAULT_BAR_NUM ,
@@ -513,7 +510,7 @@ static const struct mhi_pci_dev_info mhistatic const struct mhi_pci_dev_info mhi_foxconn_dw5934e_info = { .name ="foxconn-dw5934e" , - .edl ="fox/sdx72m/edl.mbn" , + .edl ="qcom/sdx72m/foxconn/edl.mbn" , .edl_trigger = true, .config = &modem_foxconn_sdx72_config, .bar_num =MHI_PCI_DEFAULT_BAR_NUM ,
Greg Kroah-Hartman
maintainerPATCH 592/695 bus: mhi: host: pci_generic: Fix the name for the Telit FE990A
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Porcedda <[email protected]>
commit bfc5ca0fd1ea7aceae0b682fa4bd8079c52f96c8 upstream.
Add a mhi_pci_dev_info struct specific for the Telit FE990A modem in order to use the correct product name.
--- drivers/bus/mhi/host/pci_generic.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/bus/mhi/host/pci_generic.c +11 -2
@@ -677,6 +677,15 @@ static const struct mhi_pci_dev_info mhi .mru_default = 32768, }; +static const struct mhi_pci_dev_info mhi_telit_fe990a_info = { + .name ="telit-fe990a" , + .config = &modem_telit_fn990_config, + .bar_num =MHI_PCI_DEFAULT_BAR_NUM , + .dma_data_width =32 , + .sideband_wake = false, + .mru_default =32768 , +}; +/* Keep the list sorted based on the PID. New VID should be added as the last entry */ static const struct pci_device_id mhi_pci_id_table[] = { {PCI_DEVICE (PCI_VENDOR_ID_QCOM ,0x0304 ),
@@ -694,9 +703,9 @@ static const struct pci_device_id mhi_pc/* Telit FN990 */ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010), .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info }, -/* Telit FE990 */ +/* Telit FE990A */ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015), - .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info }, + .driver_data = (kernel_ulong_t) &mhi_telit_fe990a_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309),
Greg Kroah-Hartman
maintainerPATCH 593/695 firmware_loader: Block path traversal
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit f0e5311aa8022107d63c54e2f03684ec097d1394 upstream.
Most firmware names are hardcoded strings, or are constructed from fairly constrained format strings where the dynamic parts are just some hex numbers or such.
However, there are a couple codepaths in the kernel where firmware file names contain string components that are passed through from a device or semi-privileged userspace; the ones I could find (not counting interfaces that require root privileges) are:
- lpfc_sli4_request_firmware_update() seems to construct the firmware filename from "ModelName", a string that was previously parsed out of some descriptor ("Vital Product Data") in lpfc_fill_vpd()
- nfp_net_fw_find() seems to construct a firmware filename from a model name coming from nfp_hwinfo_lookup(pf->hwinfo, "nffw.partno"), which I think parses some descriptor that was read from the device. (But this case likely isn't exploitable because the format string looks like "netronome/nic_%s", and there shouldn't be any *folders* starting with "netronome/nic_". The previous case was different because there, the "%s" is *at the start* of the format string.)
- module_flash_fw_schedule() is reachable from the ETHTOOL_MSG_MODULE_FW_FLASH_ACT netlink command, which is marked as GENL_UNS_ADMIN_PERM (meaning CAP_NET_ADMIN inside a user namespace is enough to pass the privilege check), and takes a userspace-provided firmware name.
(But I think to reach this case, you need to have CAP_NET_ADMIN over a network namespace that a special kind of ethernet device is mapped into, so I think this is not a viable attack path in practice.)
Fix it by rejecting any firmware names containing ".." path components.
For what it's worth, I went looking and haven't found any USB device drivers that use the firmware loader dangerously.
--- drivers/base/firmware_loader/main.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
drivers/base/firmware_loader/main.c +30 -0
@@ -849,6 +849,26 @@ static void fw_log_firmware_info(const s {}#endif +/* +* Reject firmware file names with ".." path components. +* There are drivers that construct firmware file names from device-supplied +* strings, and we don't want some device to be able to tell us "I would like to +* be sent my firmware from ../../../etc/shadow, please". +* +* Search for ".." surrounded by either '/' or start/end of string. +* +* This intentionally only looks at the firmware name, not at the firmware base +* directory or at symlink contents. +*/ +static bool name_contains_dotdot (const char *name) +{ +size_t name_len =strlen (name); + +return strcmp (name,".." ) ==0 ||strncmp (name,"../" ,3 ) ==0 || +strstr (name,"/../" ) !=NULL || + (name_len >=3 &&strcmp (name+name_len-3 ,"/.." ) ==0 ); +} +/* called from request_firmware() and request_firmware_work_func() */ static int _request_firmware(const struct firmware **firmware_p, const char *name,
@@ -869,6 +889,14 @@ _request_firmware(const struct firmware goto out; } +if (name_contains_dotdot (name)) { +dev_warn (device, +"Firmware load for '%s' refused, path contains '..' component\n" , + name); + ret = -EINVAL ; + goto out; + } + ret =_request_firmware_prepare (&fw, name, device, buf, size, offset, opt_flags);if (ret <=0 )/* error or already assigned */
@@ -946,6 +974,8 @@ out:* @name will be used as $FIRMWARE in the uevent environment and * should be distinctive enough not to be confused with any other * firmware image for this or any other device. +* It must not contain any ".." path components - "foo/bar..bin" is +* allowed, but "foo/../bar.bin" is not. * * Caller must hold the reference count of @device. *
Greg Kroah-Hartman
maintainerPATCH 594/695 tty: rp2: Fix reset with non forgiving PCIe host bridges
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <[email protected]>
commit f16dd10ba342c429b1e36ada545fb36d4d1f0e63 upstream.
The write to RP2_GLOBAL_CMD followed by an immediate read of RP2_GLOBAL_CMD in rp2_reset_asic() is intented to flush out the write, however by then the device is already in reset and cannot respond to a memory cycle access.
On platforms such as the Raspberry Pi 4 and others using the pcie-brcmstb.c driver, any memory access to a device that cannot respond is met with a fatal system error, rather than being substituted with all 1s as is usually the case on PC platforms.
Swapping the delay and the read ensures that the device has finished resetting before we attempt to read from it.
--- drivers/tty/serial/rp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/rp2.c +1 -1
@@ -577,8 +577,8 @@ static void rp2_reset_asic(struct rp2_cau32 clk_cfg;writew (1 , base +RP2_GLOBAL_CMD ); -readw (base +RP2_GLOBAL_CMD );msleep (100 ); +readw (base +RP2_GLOBAL_CMD );writel (0 , base +RP2_CLK_PRESCALER );/* TDM clock configuration */
Greg Kroah-Hartman
maintainerPATCH 595/695 pps: add an error check in parport_attach
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 62c5a01a5711c8e4be8ae7b6f0db663094615d48 upstream.
In parport_attach, the return value of ida_alloc is unchecked, witch leads to the use of an invalid index value.
To address this issue, index should be checked. When the index value is abnormal, the device should be freed.
Found by code review, compile tested only.
--- drivers/pps/clients/pps_parport.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/pps/clients/pps_parport.c +6 -2
@@ -149,6 +149,9 @@ static void parport_attach(struct parpor } index =ida_alloc (&pps_client_index,GFP_KERNEL ); +if (index <0 ) + goto err_free_device; +memset (&pps_client_cb,0 ,sizeof (pps_client_cb)); pps_client_cb.private = device; pps_client_cb.irq_func = parport_irq;
@@ -159,7 +162,7 @@ static void parport_attach(struct parpor index);if (!device->pardev) {pr_err ("couldn't register with %s\n" , port->name); - goto err_free; + goto err_free_ida; }if (parport_claim_or_block (device->pardev) <0 ) {
@@ -187,8 +190,9 @@ err_release_dev:parport_release (device->pardev); err_unregister_dev:parport_unregister_device (device->pardev); -err_free: +err_free_ida:ida_free (&pps_client_index, index); +err_free_device:kfree (device); }
Greg Kroah-Hartman
maintainerPATCH 596/695 serial: dont use uninitialized value in uart_poll_init()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby (SUSE) <[email protected]>
commit d0009a32c9e4e083358092f3c97e3c6e803a8930 upstream.
Coverity reports (as CID 1536978) that uart_poll_init() passes uninitialized pm_state to uart_change_pm(). It is in case the first 'if' takes the true branch (does "goto out;").
Fix this and simplify the function by simple guard(mutex). The code needs no labels after this at all. And it is pretty clear that the code has not fiddled with pm_state at that point.
--- drivers/tty/serial/serial_core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/tty/serial/serial_core.c +6 -7
@@ -2696,14 +2696,13 @@ static int uart_poll_init(struct tty_driint ret =0 ; tport = &state->port; -mutex_lock (&tport->mutex); + +guard (mutex)(&tport->mutex); port =uart_port_check (state);if (!port || port->type ==PORT_UNKNOWN || - !(port->ops->poll_get_char && port->ops->poll_put_char)) { - ret =-1 ; - goto out; - } + !(port->ops->poll_get_char && port->ops->poll_put_char)) +return -1 ; pm_state = state->pm_state;uart_change_pm (state,UART_PM_STATE_ON );
@@ -2723,10 +2722,10 @@ static int uart_poll_init(struct tty_dri ret =uart_set_options (port,NULL , baud, parity, bits, flow);console_list_unlock (); } -out: +if (ret)uart_change_pm (state, pm_state); -mutex_unlock (&tport->mutex); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 597/695 xhci: Set quirky xHC PCI hosts to D3 _after_ stopping and freeing them.
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
commit f81dfa3b57c624c56f2bff171c431bc7f5b558f2 upstream.
PCI xHC host should be stopped and xhci driver memory freed before putting host to PCI D3 state during PCI remove callback.
Hosts with XHCI_SPURIOUS_WAKEUP quirk did this the wrong way around and set the host to D3 before calling usb_hcd_pci_remove(dev), which will access the host to stop it, and then free xhci.
--- drivers/usb/host/xhci-pci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-pci.c +5 -3
@@ -669,8 +669,10 @@ put_runtime_pm:static void xhci_pci_remove (struct pci_dev *dev) {struct xhci_hcd *xhci; +bool set_power_d3; xhci =hcd_to_xhci (pci_get_drvdata (dev)); + set_power_d3 = xhci->quirks &XHCI_SPURIOUS_WAKEUP ; xhci->xhc_state |=XHCI_STATE_REMOVING ;
@@ -683,11 +685,11 @@ static void xhci_pci_remove(struct pci_d xhci->shared_hcd =NULL ; } +usb_hcd_pci_remove (dev); +/* Workaround for spurious wakeups at shutdown with HSW */ -if (xhci->quirks &XHCI_SPURIOUS_WAKEUP ) +if (set_power_d3)pci_set_power_state (dev, PCI_D3hot); - -usb_hcd_pci_remove (dev); }/*
Greg Kroah-Hartman
maintainerPATCH 598/695 serial: qcom-geni: fix fifo polling timeout
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit c80ee36ac8f9e9c27d8e097a2eaaf198e7534c83 upstream.
The qcom_geni_serial_poll_bit() can be used to wait for events like command completion and is supposed to wait for the time it takes to clear a full fifo before timing out.
As noted by Doug, the current implementation does not account for start, stop and parity bits when determining the timeout. The helper also does not currently account for the shift register and the two-word intermediate transfer register.
A too short timeout can specifically lead to lost characters when waiting for a transfer to complete as the transfer is cancelled on timeout.
Instead of determining the poll timeout on every call, store the fifo timeout when updating it in set_termios() and make sure to take the shift and intermediate registers into account. Note that serial core has already added a 20 ms margin to the fifo timeout.
Also note that the current uart_fifo_timeout() interface does unnecessary calculations on every call and did not exist in earlier kernels so only store its result once. This facilitates backports too as earlier kernels can derive the timeout from uport->timeout, which has since been removed.
--- drivers/tty/serial/qcom_geni_serial.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +17 -14
@@ -124,7 +124,7 @@ struct qcom_geni_serial_port {dma_addr_t tx_dma_addr;dma_addr_t rx_dma_addr;bool setup; -unsigned int baud; +unsigned long poll_timeout_us;unsigned long clk_rate;void *rx_buf;u32 loopback;
@@ -270,22 +270,13 @@ static bool qcom_geni_serial_poll_bit(st {u32 reg;struct qcom_geni_serial_port *port; -unsigned int baud; -unsigned int fifo_bits;unsigned long timeout_us =20000 ;struct qcom_geni_private_data *private_data = uport->private_data;if (private_data->drv) { port =to_dev_port (uport); - baud = port->baud; -if (!baud) - baud =115200 ; - fifo_bits = port->tx_fifo_depth * port->tx_fifo_width; -/* -* Total polling iterations based on FIFO worth of bytes to be -* sent at current baud. Add a little fluff to the wait. -*/ - timeout_us = ((fifo_bits *USEC_PER_SEC ) / baud) +500 ; +if (port->poll_timeout_us) + timeout_us = port->poll_timeout_us; }/*
@@ -1244,11 +1235,11 @@ static void qcom_geni_serial_set_termiosunsigned long clk_rate;u32 ver, sampling_rate;unsigned int avg_bw_core; +unsigned long timeout;qcom_geni_serial_stop_rx (uport);/* baud rate */ baud =uart_get_baud_rate (uport, termios, old,300 ,4000000 ); - port->baud = baud; sampling_rate =UART_OVERSAMPLING ;/* Sampling rate is halved for IP versions >= 2.5 */
@@ -1326,9 +1317,21 @@ static void qcom_geni_serial_set_termioselse tx_trans_cfg |=UART_CTS_MASK ; -if (baud) +if (baud) {uart_update_timeout (uport, termios->c_cflag, baud); +/* +* Make sure that qcom_geni_serial_poll_bitfield() waits for +* the FIFO, two-word intermediate transfer register and shift +* register to clear. +* +* Note that uart_fifo_timeout() also adds a 20 ms margin. +*/ + timeout =jiffies_to_usecs (uart_fifo_timeout (uport)); + timeout +=3 * timeout / port->tx_fifo_depth; +WRITE_ONCE (port->poll_timeout_us, timeout); + } +if (!uart_console (uport))writel (port->loopback, uport->membase +SE_UART_LOOPBACK_CFG );
Greg Kroah-Hartman
maintainerPATCH 599/695 serial: qcom-geni: fix false console tx restart
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit f97cdbbf187fefcf1fe19689cd9fdca11fe9c3eb upstream.
Commit 663abb1a7a7f ("tty: serial: qcom_geni_serial: Fix UART hang") addressed an issue with stalled tx after the console code interrupted the last bytes of a tx command by reenabling the watermark interrupt if there is data in write buffer. This can however break software flow control by re-enabling tx after the user has stopped it.
Address the original issue by not clearing the CMD_DONE flag after polling for command completion. This allows the interrupt handler to start another transfer when the CMD_DONE interrupt has not been disabled due to flow control.
--- drivers/tty/serial/qcom_geni_serial.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +3 -10
@@ -306,18 +306,16 @@ static void qcom_geni_serial_setup_tx(ststatic void qcom_geni_serial_poll_tx_done (struct uart_port *uport) {int done; -u32 irq_clear =M_CMD_DONE_EN ; done =qcom_geni_serial_poll_bit (uport,SE_GENI_M_IRQ_STATUS ,M_CMD_DONE_EN , true);if (!done) {writel (M_GENI_CMD_ABORT , uport->membase +SE_GENI_M_CMD_CTRL_REG ); - irq_clear |=M_CMD_ABORT_EN ;qcom_geni_serial_poll_bit (uport,SE_GENI_M_IRQ_STATUS ,M_CMD_ABORT_EN , true); +writel (M_CMD_ABORT_EN , uport->membase +SE_GENI_M_IRQ_CLEAR ); } -writel (irq_clear, uport->membase +SE_GENI_M_IRQ_CLEAR ); }static void qcom_geni_serial_abort_rx (struct uart_port *uport)
@@ -378,6 +376,7 @@ static void qcom_geni_serial_poll_put_ch unsigned char c) {writel (DEF_TX_WM , uport->membase +SE_GENI_TX_WATERMARK_REG ); +writel (M_CMD_DONE_EN , uport->membase +SE_GENI_M_IRQ_CLEAR );qcom_geni_serial_setup_tx (uport,1 );WARN_ON (!qcom_geni_serial_poll_bit (uport,SE_GENI_M_IRQ_STATUS ,M_TX_FIFO_WATERMARK_EN , true));
@@ -422,6 +421,7 @@ __qcom_geni_serial_console_write(struct }writel (DEF_TX_WM , uport->membase +SE_GENI_TX_WATERMARK_REG ); +writel (M_CMD_DONE_EN , uport->membase +SE_GENI_M_IRQ_CLEAR );qcom_geni_serial_setup_tx (uport, bytes_to_send);for (i =0 ; i < count; ) {size_t chars_to_write =0 ;
@@ -463,7 +463,6 @@ static void qcom_geni_serial_console_wribool locked = true;unsigned long flags;u32 geni_status; -u32 irq_en;WARN_ON (co->index <0 || co->index >=GENI_UART_CONS_PORTS );
@@ -495,12 +494,6 @@ static void qcom_geni_serial_console_wri* has been sent, in which case we need to look for done first. */ qcom_geni_serial_poll_tx_done (uport); - -if (!kfifo_is_empty (&uport->state->port.xmit_fifo)) { - irq_en =readl (uport->membase +SE_GENI_M_IRQ_EN ); -writel (irq_en |M_TX_FIFO_WATERMARK_EN , - uport->membase +SE_GENI_M_IRQ_EN ); - } }__qcom_geni_serial_console_write (uport, s, count);
Greg Kroah-Hartman
maintainerPATCH 600/695 crypto: qcom-rng - fix support for ACPI-based systems
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Masney <[email protected]>
commit 3e87031a6ce68f13722155497cd511a00b56a2ae upstream.
The qcom-rng driver supports both ACPI and device tree-based systems. ACPI support was broken when the hw_random interface support was added. Let's go ahead and fix this by adding the appropriate driver data to the ACPI match table, and change the of_device_get_match_data() call to device_get_match_data() so that it will also work on ACPI-based systems.
This fix was boot tested on a Qualcomm Amberwing server (ACPI based) and on a Qualcomm SA8775p Automotive Development Board (DT based). I also verified that qcom-rng shows up in /proc/crypto on both systems.
--- drivers/crypto/qcom-rng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/crypto/qcom-rng.c +2 -2
@@ -196,7 +196,7 @@ static int qcom_rng_probe(struct platforif (IS_ERR (rng->clk))return PTR_ERR (rng->clk); - rng->of_data = (struct qcom_rng_of_data *)of_device_get_match_data (&pdev->dev); + rng->of_data = (struct qcom_rng_of_data *)device_get_match_data (&pdev->dev); qcom_rng_dev = rng; ret =crypto_register_rng (&qcom_rng_alg);
@@ -247,7 +247,7 @@ static struct qcom_rng_of_data qcom_trng };static const struct acpi_device_id __maybe_unused qcom_rng_acpi_match[] = { - { .id ="QCOM8160" , .driver_data =1 }, + { .id ="QCOM8160" , .driver_data = (kernel_ulong_t)&qcom_prng_ee_of_data }, {} };MODULE_DEVICE_TABLE (acpi, qcom_rng_acpi_match);
Greg Kroah-Hartman
maintainerPATCH 601/695 crypto: ccp - Properly unregister /dev/sev on sev PLATFORM_STATUS failure
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavan Kumar Paluri <[email protected]>
commit ce3d2d6b150ba8528f3218ebf0cee2c2c572662d upstream.
In case of sev PLATFORM_STATUS failure, sev_get_api_version() fails resulting in sev_data field of psp_master nulled out. This later becomes a problem when unloading the ccp module because the device has not been unregistered (via misc_deregister()) before clearing the sev_data field of psp_master. As a result, on reloading the ccp module, a duplicate device issue is encountered as can be seen from the dmesg log below.
on reloading ccp module via modprobe ccp
Call Trace: <TASK> dump_stack_lvl+0xd7/0xf0 dump_stack+0x10/0x20 sysfs_warn_dup+0x5c/0x70 sysfs_create_dir_ns+0xbc/0xd kobject_add_internal+0xb1/0x2f0 kobject_add+0x7a/0xe0 ? srso_alias_return_thunk+0x5/0xfbef5 ? get_device_parent+0xd4/0x1e0 ? __pfx_klist_children_get+0x10/0x10 device_add+0x121/0x870 ? srso_alias_return_thunk+0x5/0xfbef5 device_create_groups_vargs+0xdc/0x100 device_create_with_groups+0x3f/0x60 misc_register+0x13b/0x1c0 sev_dev_init+0x1d4/0x290 [ccp] psp_dev_init+0x136/0x300 [ccp] sp_init+0x6f/0x80 [ccp] sp_pci_probe+0x2a6/0x310 [ccp] ? srso_alias_return_thunk+0x5/0xfbef5 local_pci_probe+0x4b/0xb0 work_for_cpu_fn+0x1a/0x30 process_one_work+0x203/0x600 worker_thread+0x19e/0x350 ? __pfx_worker_thread+0x10/0x10 kthread+0xeb/0x120 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x3c/0x60 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> kobject: kobject_add_internal failed for sev with -EEXIST, don't try to register things with the same name in the same directory. ccp 0000:22:00.1: sev initialization failed ccp 0000:22:00.1: psp initialization failed ccp 0000:a2:00.1: no command queues available ccp 0000:a2:00.1: psp enabled
Address this issue by unregistering the /dev/sev before clearing out sev_data in case of PLATFORM_STATUS failure.
--- drivers/crypto/ccp/sev-dev.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/crypto/ccp/sev-dev.c +2 -0
@@ -2421,6 +2421,8 @@ void sev_pci_init(void)return ; err: +sev_dev_destroy (psp_master); + psp_master->sev_data =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 602/695 drbd: Fix atomicity violation in drbd_uuid_set_bm()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu-ji Chen <[email protected]>
commit 2f02b5af3a4482b216e6a466edecf6ba8450fa45 upstream.
The violation of atomicity occurs when the drbd_uuid_set_bm function is executed simultaneously with modifying the value of device->ldev->md.uuid[UI_BITMAP]. Consider a scenario where, while device->ldev->md.uuid[UI_BITMAP] passes the validity check when its value is not zero, the value of device->ldev->md.uuid[UI_BITMAP] is written to zero. In this case, the check in drbd_uuid_set_bm might refer to the old value of device->ldev->md.uuid[UI_BITMAP] (before locking), which allows an invalid value to pass the validity check, resulting in inconsistency.
To address this issue, it is recommended to include the data validity check within the locked section of the function. This modification ensures that the value of device->ldev->md.uuid[UI_BITMAP] does not change during the validation process, thereby maintaining its integrity.
This possible bug is found by an experimental static analysis tool developed by our team. This tool analyzes the locking APIs to extract function pairs that can be concurrently executed, and then analyzes the instructions in the paired functions to identify possible concurrency bugs including data races and atomicity violations.
--- drivers/block/drbd/drbd_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/block/drbd/drbd_main.c +4 -2
@@ -3399,10 +3399,12 @@ void drbd_uuid_new_current(struct drbd_dvoid drbd_uuid_set_bm (struct drbd_device *device,u64 val)__must_hold (local) {unsigned long flags; -if (device->ldev->md.uuid[UI_BITMAP ] ==0 && val ==0 ) +spin_lock_irqsave (&device->ldev->md.uuid_lock, flags); +if (device->ldev->md.uuid[UI_BITMAP ] ==0 && val ==0 ) { +spin_unlock_irqrestore (&device->ldev->md.uuid_lock, flags);return ; + } -spin_lock_irqsave (&device->ldev->md.uuid_lock, flags);if (val ==0 ) {drbd_uuid_move_history (device); device->ldev->md.uuid[UI_HISTORY_START ] = device->ldev->md.uuid[UI_BITMAP ];
Greg Kroah-Hartman
maintainerPATCH 603/695 drbd: Add NULL check for net_conf to prevent dereference in state validation
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Lobanov <[email protected]>
commit a5e61b50c9f44c5edb6e134ede6fee8806ffafa9 upstream.
If the net_conf pointer is NULL and the code attempts to access its fields without a check, it will lead to a null pointer dereference. Add a NULL check before dereferencing the pointer.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/block/drbd/drbd_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_state.c +1 -1
@@ -876,7 +876,7 @@ is_valid_state(struct drbd_device *devic ns.disk == D_OUTDATED) rv =SS_CONNECTED_OUTDATES ; - else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && + else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && (nc->verify_alg[0] == 0)) rv =SS_NO_VERIFY_ALG ;
Greg Kroah-Hartman
maintainerPATCH 604/695 ACPI: sysfs: validate return type of _STR method
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit 4bb1e7d027413835b086aed35bc3f0713bc0f72b upstream.
Only buffer objects are valid return values of _STR.
If something else is returned description_show() will access invalid memory.
--- drivers/acpi/device_sysfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/acpi/device_sysfs.c +3 -2
@@ -540,8 +540,9 @@ int acpi_device_setup_files(struct acpi_* If device has _STR, 'description' file is created */ if (acpi_has_method (dev->handle,"_STR" )) { - status =acpi_evaluate_object (dev->handle,"_STR" , -NULL , &buffer); + status =acpi_evaluate_object_typed (dev->handle,"_STR" , +NULL , &buffer, +ACPI_TYPE_BUFFER );if (ACPI_FAILURE (status)) buffer.pointer =NULL ; dev->pnp.str_obj = buffer.pointer;
Greg Kroah-Hartman
maintainerPATCH 605/695 ACPI: resource: Do IRQ override on MECHREV GM7XG0M
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Chen <[email protected]>
commit b53f09ecd602d7b8b7da83b0890cbac500b6a9b9 upstream.
Listed device need the override for the keyboard to work.
--- drivers/acpi/resource.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/acpi/resource.c +6 -0
@@ -555,6 +555,12 @@ static const struct dmi_system_id irq1_l*/ static const struct dmi_system_id irq1_edge_low_force_override[] = { { +/* MECHREV Jiaolong17KS Series GM7XG0M */ + .matches = { +DMI_MATCH (DMI_BOARD_NAME ,"GM7XG0M" ), + }, + }, + {/* XMG APEX 17 (M23) */ .matches = {DMI_MATCH (DMI_BOARD_NAME ,"GMxBGxx" ),
Greg Kroah-Hartman
maintainerPATCH 606/695 ACPI: resource: Add another DMI match for the TongFang GMxXGxx
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Sembach <[email protected]>
commit a98cfe6ff15b62f94a44d565607a16771c847bc6 upstream.
Internal documentation suggest that the TUXEDO Polaris 15 Gen5 AMD might have GMxXGxX as the board name instead of GMxXGxx.
Adding both to be on the safe side.
--- drivers/acpi/resource.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/acpi/resource.c +6 -0
@@ -579,6 +579,12 @@ static const struct dmi_system_id irq1_e }, }, { +/* TongFang GMxXGxX/TUXEDO Polaris 15 Gen5 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"), + }, + }, + {/* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Eluktronics Inc."),
Greg Kroah-Hartman
maintainerPATCH 607/695 efistub/tpm: Use ACPI reclaim memory for event log to avoid corruption
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ard Biesheuvel <[email protected]>
commit 77d48d39e99170b528e4f2e9fc5d1d64cdedd386 upstream.
The TPM event log table is a Linux specific construct, where the data produced by the GetEventLog() boot service is cached in memory, and passed on to the OS using an EFI configuration table.
The use of EFI_LOADER_DATA here results in the region being left unreserved in the E820 memory map constructed by the EFI stub, and this is the memory description that is passed on to the incoming kernel by kexec, which is therefore unaware that the region should be reserved.
Even though the utility of the TPM2 event log after a kexec is questionable, any corruption might send the parsing code off into the weeds and crash the kernel. So let's use EFI_ACPI_RECLAIM_MEMORY instead, which is always treated as reserved by the E820 conversion logic.
--- drivers/firmware/efi/libstub/tpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/efi/libstub/tpm.c +1 -1
@@ -96,7 +96,7 @@ static void efi_retrieve_tcg2_eventlog(i }/* Allocate space for the logs and copy them. */ - status =efi_bs_call (allocate_pool,EFI_LOADER_DATA , + status =efi_bs_call (allocate_pool,EFI_ACPI_RECLAIM_MEMORY ,sizeof (*log_tbl) + log_size, (void **)&log_tbl);if (status !=EFI_SUCCESS ) {
Greg Kroah-Hartman
maintainerPATCH 608/695 intel_idle: add Granite Rapids Xeon support
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Bityutskiy <[email protected]>
commit 370406bf5738dade8ac95a2ee95c29299d4ac902 upstream.
Add Granite Rapids Xeon C-states, which are C1, C1E, C6, and C6P.
Comparing to previous Xeon Generations (e.g., Emerald Rapids), C6 requests end up only in core C6 state, and no package C-state promotion takes place even if all cores in the package are in core C6.
C6P requests also end up in core C6, but if all cores have requested C6P, the SoC will enter the package C6 state.
--- drivers/idle/intel_idle.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
drivers/idle/intel_idle.c +46 -0
@@ -1022,6 +1022,45 @@ static struct cpuidle_state spr_cstates[ .enter = NULL } }; +static struct cpuidle_state gnr_cstates[]__initdata = { + { + .name ="C1" , + .desc ="MWAIT 0x00" , + .flags =MWAIT2flg (0x00 ), + .exit_latency =1 , + .target_residency =1 , + .enter = &intel_idle, + .enter_s2idle = intel_idle_s2idle, }, + { + .name ="C1E" , + .desc ="MWAIT 0x01" , + .flags =MWAIT2flg (0x01 ) |CPUIDLE_FLAG_ALWAYS_ENABLE , + .exit_latency =4 , + .target_residency =4 , + .enter = &intel_idle, + .enter_s2idle = intel_idle_s2idle, }, + { + .name ="C6" , + .desc ="MWAIT 0x20" , + .flags =MWAIT2flg (0x20 ) |CPUIDLE_FLAG_TLB_FLUSHED | +CPUIDLE_FLAG_INIT_XSTATE , + .exit_latency =170 , + .target_residency =650 , + .enter = &intel_idle, + .enter_s2idle = intel_idle_s2idle, }, + { + .name ="C6P" , + .desc ="MWAIT 0x21" , + .flags =MWAIT2flg (0x21 ) |CPUIDLE_FLAG_TLB_FLUSHED | +CPUIDLE_FLAG_INIT_XSTATE , + .exit_latency =210 , + .target_residency =1000 , + .enter = &intel_idle, + .enter_s2idle = intel_idle_s2idle, }, + { + .enter =NULL } +}; +static struct cpuidle_state atom_cstates[]__initdata = { { .name ="C1E" ,
@@ -1453,6 +1492,12 @@ static const struct idle_cpu idle_cpu_sp .use_acpi = true, }; +static const struct idle_cpu idle_cpu_gnr__initconst = { + .state_table = gnr_cstates, + .disable_promotion_to_c1e = true, + .use_acpi = true, +}; +static const struct idle_cpu idle_cpu_avn__initconst = { .state_table = avn_cstates, .disable_promotion_to_c1e = true,
@@ -1533,6 +1578,7 @@ static const struct x86_cpu_id intel_idlX86_MATCH_VFM (INTEL_ATOM_GRACEMONT , &idle_cpu_gmt),X86_MATCH_VFM (INTEL_SAPPHIRERAPIDS_X , &idle_cpu_spr),X86_MATCH_VFM (INTEL_EMERALDRAPIDS_X , &idle_cpu_spr), +X86_MATCH_VFM (INTEL_GRANITERAPIDS_X , &idle_cpu_gnr),X86_MATCH_VFM (INTEL_XEON_PHI_KNL , &idle_cpu_knl),X86_MATCH_VFM (INTEL_XEON_PHI_KNM , &idle_cpu_knl), X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &idle_cpu_bxt),
Re: [PATCH 6.11 608/695] intel_idle: add Granite Rapids Xeon support
Quoted 10 lines · Greg Kroah-Hartman
6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Bityutskiy <[email protected]>
commit
370406bf5738dade8ac95a2ee95c29299d4ac902upstream.Add Granite Rapids Xeon C-states, which are C1, C1E, C6, and C6P.
... snip ...
Hi Greg, I was on vacation. Looks good, but I'll test 6.11-stable with these patches (#608 and #609) to double check, and let you know if there are issues.
Thanks!
Re: [PATCH 6.11 608/695] intel_idle: add Granite Rapids Xeon support
Quoted 7 lines · Artem Bityutskiy
Quoted 6 lines · Greg Kroah-Hartman
6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Bityutskiy <[email protected]>
Quoted 8 lines
Quoted 4 lines
commit
370406bf5738dade8ac95a2ee95c29299d4ac902upstream.Add Granite Rapids Xeon C-states, which are C1, C1E, C6, and C6P.
... snip ...
Hi Greg, I was on vacation. Looks good, but I'll test 6.11-stable with these patches (#608 and #609) to double check, and let you know if there are issues.
Applied the 2 patches (#608 and #609) on top of v6.11.1, built, booted on Granite Rapids Xeon, all C-states are available and enabled by default, as expected.
Thanks.
Greg Kroah-Hartman
maintainerPATCH 609/695 intel_idle: fix ACPI _CST matching for newer Xeon platforms
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Artem Bityutskiy <[email protected]>
commit 4c411cca33cf1c21946b710b2eb59aca9f646703 upstream.
Background
~~~~~~~~~~
The driver uses 'use_acpi = true' in C-state custom table for all Xeon platforms. The meaning of this flag is as follows.
1. If a C-state from the custom table is defined in ACPI _CST (matched by the mwait hint), then enable this C-state.
2. Otherwise, disable this C-state, unless the C-sate definition in the custom table has the 'CPUIDLE_FLAG_ALWAYS_ENABLE' flag set, in which case enabled it.
The goal is to honor BIOS C6 settings - If BIOS disables C6, disable it by default in the OS too (but it can be enabled via sysfs).
This works well on Xeons that expose only one flavor of C6. This are all Xeons except for the newest Granite Rapids (GNR) and Sierra Forest (SRF).
The problem
~~~~~~~~~~~
GNR and SRF have 2 flavors of C6: C6/C6P on GNR, C6S/C6SP on SRF. The the "P" flavor allows for the package C6, while the "non-P" flavor allows only for core/module C6.
As far as this patch is concerned, both GNR and SRF platforms are handled the same way. Therefore, further discussion is focused on GNR, but it applies to SRF as well.
On Intel Xeon platforms, BIOS exposes only 2 ACPI C-states: C1 and C2. Well, depending on BIOS settings, C2 may be named as C3. But there still will be only 2 states - C1 and C3. But this is a non-essential detail, so further discussion is focused on the ACPI C1 and C2 case.
On pre-GNR/SRF Xeon platforms, ACPI C1 is mapped to C1 or C1E, and ACPI C2 is mapped to C6. The 'use_acpi' flag works just fine:
* If ACPI C2 enabled, enable C6.
* Otherwise, disable C6.
However, on GNR there are 2 flavors of C6, so BIOS maps ACPI C2 to either C6 or C6P, depending on the user settings. As a result, due to the 'use_acpi' flag, 'intel_idle' disables least one of the C6 flavors.
BIOS | OS | Verdict ----------------------------------------------------|--------- ACPI C2 disabled | C6 disabled, C6P disabled | OK ACPI C2 mapped to C6 | C6 enabled, C6P disabled | Not OK ACPI C2 mapped to C6P | C6 disabled, C6P enabled | Not OK
The goal of 'use_acpi' is to honor BIOS ACPI C2 disabled case, which works fine. But if ACPI C2 is enabled, the goal is to enable all flavors of C6, not just one of the flavors. This was overlooked when enabling GNR/SRF platforms.
In other words, before GNR/SRF, the ACPI C2 status was binary - enabled or disabled. But it is not binary on GNR/SRF, however the goal is to continue treat it as binary.
The fix
~~~~~~~
Notice, that current algorithm matches ACPI and custom table C-states by the mwait hint. However, mwait hint consists of the 'state' and 'sub-state' parts, and all C6 flavors have the same state value of 0x20, but different sub-state values.
Introduce new C-state table flag - CPUIDLE_FLAG_PARTIAL_HINT_MATCH and add it to both C6 flavors of the GNR/SRF platforms.
When matching ACPI _CST and custom table C-states, match only the start part if the C-state has CPUIDLE_FLAG_PARTIAL_HINT_MATCH, other wise match both state and sub-state parts (as before).
With this fix, GNR C-states enabled/disabled status looks like this.
BIOS | OS
----------------------------------------------------
ACPI C2 disabled | C6 disabled, C6P disabled ACPI C2 mapped to C6 | C6 enabled, C6P enabled ACPI C2 mapped to C6P | C6 enabled, C6P enabled
Possible alternative
~~~~~~~~~~~~~~~~~~~~
The alternative would be to remove 'use_acpi' flag for GNR and SRF. This would be a simpler solution, but it would violate the principle of least surprise - users of Xeon platforms are used to the fact that intel_idle honors C6 enabled/disabled flag. It is more consistent user experience if GNR/SRF continue doing so.
How tested
~~~~~~~~~~
Tested on GNR and SRF platform with all the 3 BIOS configurations: ACPI C2 disabled, mapped to C6/C6S, mapped to C6P/C6SP.
Tested on Ice lake Xeon and Sapphire Rapids Xeon platforms with ACPI C2 enabled and disabled, just to verify that the patch does not break older Xeons.
--- drivers/idle/intel_idle.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/idle/intel_idle.c +29 -8
@@ -121,6 +121,12 @@ static unsigned int mwait_substates __in#define CPUIDLE_FLAG_INIT_XSTATE BIT(17)/* +* Ignore the sub-state when matching mwait hints between the ACPI _CST and +* custom tables. +*/ +#define CPUIDLE_FLAG_PARTIAL_HINT_MATCH BIT(18) + +/* * MWAIT takes an 8-bit "hint" in EAX "suggesting" * the C-state (top nibble) and sub-state (bottom nibble) * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc.
@@ -1043,7 +1049,8 @@ static struct cpuidle_state gnr_cstates[ .name = "C6", .desc = "MWAIT 0x20", .flags =MWAIT2flg (0x20 ) |CPUIDLE_FLAG_TLB_FLUSHED | - CPUIDLE_FLAG_INIT_XSTATE, +CPUIDLE_FLAG_INIT_XSTATE | + CPUIDLE_FLAG_PARTIAL_HINT_MATCH, .exit_latency = 170, .target_residency = 650, .enter = &intel_idle,
@@ -1052,7 +1059,8 @@ static struct cpuidle_state gnr_cstates[ .name = "C6P", .desc = "MWAIT 0x21", .flags =MWAIT2flg (0x21 ) |CPUIDLE_FLAG_TLB_FLUSHED | - CPUIDLE_FLAG_INIT_XSTATE, +CPUIDLE_FLAG_INIT_XSTATE | + CPUIDLE_FLAG_PARTIAL_HINT_MATCH, .exit_latency = 210, .target_residency = 1000, .enter = &intel_idle,
@@ -1354,7 +1362,8 @@ static struct cpuidle_state srf_cstates[ { .name = "C6S", .desc = "MWAIT 0x22", - .flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags =MWAIT2flg (0x22 ) |CPUIDLE_FLAG_TLB_FLUSHED | + CPUIDLE_FLAG_PARTIAL_HINT_MATCH, .exit_latency = 270, .target_residency = 700, .enter = &intel_idle,
@@ -1362,7 +1371,8 @@ static struct cpuidle_state srf_cstates[ { .name = "C6SP", .desc = "MWAIT 0x23", - .flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags =MWAIT2flg (0x23 ) |CPUIDLE_FLAG_TLB_FLUSHED | + CPUIDLE_FLAG_PARTIAL_HINT_MATCH, .exit_latency = 310, .target_residency = 900, .enter = &intel_idle,
@@ -1738,7 +1748,7 @@ static void __init intel_idle_init_cstat } } -static bool __init intel_idle_off_by_default (u32 mwait_hint) +static bool __init intel_idle_off_by_default (unsigned int flags,u32 mwait_hint) {int cstate, limit;
@@ -1755,7 +1765,15 @@ static bool __init intel_idle_off_by_def* the interesting states are ACPI_CSTATE_FFH. */ for (cstate =1 ; cstate < limit; cstate++) { -if (acpi_state_table.states[cstate].address == mwait_hint) +u32 acpi_hint = acpi_state_table.states[cstate].address; +u32 table_hint = mwait_hint; + +if (flags &CPUIDLE_FLAG_PARTIAL_HINT_MATCH ) { + acpi_hint &= ~MWAIT_SUBSTATE_MASK ; + table_hint &= ~MWAIT_SUBSTATE_MASK ; + } + +if (acpi_hint == table_hint)return false; }return true;
@@ -1765,7 +1783,10 @@ static bool __init intel_idle_off_by_defstatic inline bool intel_idle_acpi_cst_extract (void ) {return false; }static inline void intel_idle_init_cstates_acpi (struct cpuidle_driver *drv) { } -static inline bool intel_idle_off_by_default (u32 mwait_hint) {return false; } +static inline bool intel_idle_off_by_default (unsigned int flags,u32 mwait_hint) +{ +return false; +}#endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */ /**
@@ -2092,7 +2113,7 @@ static void __init intel_idle_init_cstatif ((disabled_states_mask &BIT (drv->state_count)) || ((icpu->use_acpi || force_use_acpi) && -intel_idle_off_by_default (mwait_hint) && +intel_idle_off_by_default (state->flags, mwait_hint) && !(state->flags &CPUIDLE_FLAG_ALWAYS_ENABLE ))) state->flags |=CPUIDLE_FLAG_OFF ;
Greg Kroah-Hartman
maintainerPATCH 610/695 x86/entry: Remove unwanted instrumentation in common_interrupt()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Vyukov <[email protected]>
commit 477d81a1c47a1b79b9c08fc92b5dea3c5143800b upstream.
common_interrupt() and related variants call kvm_set_cpu_l1tf_flush_l1d(), which is neither marked noinstr nor __always_inline.
So compiler puts it out of line and adds instrumentation to it. Since the call is inside of instrumentation_begin/end(), objtool does not warn about it.
The manifestation is that KCOV produces spurious coverage in kvm_set_cpu_l1tf_flush_l1d() in random places because the call happens when preempt count is not yet updated to say that the kernel is in an interrupt.
Mark kvm_set_cpu_l1tf_flush_l1d() as __always_inline and move it out of the instrumentation_begin/end() section. It only calls __this_cpu_write() which is already safe to call in noinstr contexts.
--- arch/x86/include/asm/hardirq.h | 8 ++++++-- arch/x86/include/asm/idtentry.h | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/include/asm/hardirq.h +6 -2
@@ -69,7 +69,11 @@ extern u64 arch_irq_stat(void);#define local_softirq_pending_ref pcpu_hot.softirq_pending#if IS_ENABLED (CONFIG_KVM_INTEL ) -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) +/* +* This function is called from noinstr interrupt contexts +* and must be inlined to not get instrumentation. +*/ +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) {__this_cpu_write (irq_stat.kvm_cpu_l1tf_flush_l1d,1 ); }
@@ -84,7 +88,7 @@ static __always_inline bool kvm_get_cpu_return __this_cpu_read (irq_stat.kvm_cpu_l1tf_flush_l1d); }#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */ -static inline void kvm_set_cpu_l1tf_flush_l1d (void ) { } +static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */ #endif /* _ASM_X86_HARDIRQ_H */
arch/x86/include/asm/idtentry.h +3 -3
@@ -212,8 +212,8 @@ __visible noinstr void func(struct pt_reirqentry_state_t state =irqentry_enter (regs); \u32 vector = (u32 )(u8 )error_code; \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ -kvm_set_cpu_l1tf_flush_l1d (); \ run_irq_on_irqstack_cond(__##func, regs, vector); \ instrumentation_end(); \ irqentry_exit(regs, state); \
@@ -250,7 +250,6 @@ static void __##func(struct pt_regs *reg \ static __always_inline void instr_##func(struct pt_regs *regs) \ { \ - kvm_set_cpu_l1tf_flush_l1d(); \ run_sysvec_on_irqstack_cond(__##func, regs); \ } \ \
@@ -258,6 +257,7 @@ __visible noinstr void func(struct pt_re { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
@@ -288,7 +288,6 @@ static __always_inline void __##func(str static __always_inline void instr_##func(struct pt_regs *regs) \ { \ __irq_enter_raw(); \ - kvm_set_cpu_l1tf_flush_l1d(); \ __##func (regs); \ __irq_exit_raw(); \ } \
@@ -297,6 +296,7 @@ __visible noinstr void func(struct pt_re { \irqentry_state_t state =irqentry_enter (regs); \ \ +kvm_set_cpu_l1tf_flush_l1d (); \instrumentation_begin (); \ instr_##func (regs); \instrumentation_end (); \
Greg Kroah-Hartman
maintainerPATCH 611/695 perf/x86/intel: Allow to setup LBR for counting event for BPF
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
commit ef493f4b122d6b14a6de111d1acac1eab1d673b0 upstream.
The BPF subsystem may capture LBR data on a counting event. However, the current implementation assumes that LBR can/should only be used with sampling events.
For instance, retsnoop tool ([0]) makes an extensive use of this functionality and sets up perf event as follows:
struct perf_event_attr attr; memset(&attr, 0, sizeof(attr)); attr.size = sizeof(attr); attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.sample_type = PERF_SAMPLE_BRANCH_STACK; attr.branch_sample_type = PERF_SAMPLE_BRANCH_KERNEL;
To limit the LBR for a sampling event is to avoid unnecessary branch stack setup for a counting event in the sample read. Because LBR is only read in the sampling event's overflow.
Although in most cases LBR is used in sampling, there is no HW limit to bind LBR to the sampling mode. Allow an LBR setup for a counting event unless in the sample read mode.
--- arch/x86/events/intel/core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/x86/events/intel/core.c +6 -2
@@ -3972,8 +3972,12 @@ static int intel_pmu_hw_config(struct pe x86_pmu.pebs_aliases (event); } -if (needs_branch_stack (event) &&is_sampling_event (event)) - event->hw.flags |=PERF_X86_EVENT_NEEDS_BRANCH_STACK ; +if (needs_branch_stack (event)) { +/* Avoid branch stack setup for counting events in SAMPLE READ */ +if (is_sampling_event (event) || + !(event->attr.sample_type &PERF_SAMPLE_READ )) + event->hw.flags |=PERF_X86_EVENT_NEEDS_BRANCH_STACK ; + }if (branch_sample_counters (event)) {struct perf_event *leader, *sibling;
Greg Kroah-Hartman
maintainerPATCH 612/695 perf/x86/intel/pt: Fix sampling synchronization
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <[email protected]>
commit d92792a4b26e50b96ab734cbe203d8a4c932a7a9 upstream.
pt_event_snapshot_aux() uses pt->handle_nmi to determine if tracing needs to be stopped, however tracing can still be going because pt->handle_nmi is set to zero before tracing is stopped in pt_event_stop, whereas pt_event_snapshot_aux() requires that tracing must be stopped in order to copy a sample of trace from the buffer.
Instead call pt_config_stop() always, which anyway checks config for RTIT_CTL_TRACEEN and does nothing if it is already clear.
Note pt_event_snapshot_aux() can continue to use pt->handle_nmi to determine if the trace needs to be restarted afterwards.
--- arch/x86/events/intel/pt.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
arch/x86/events/intel/pt.c +7 -8
@@ -1606,6 +1606,7 @@ static void pt_event_stop(struct perf_ev* see comment in intel_pt_interrupt(). */ WRITE_ONCE (pt->handle_nmi,0 ); +barrier ();pt_config_stop (event);
@@ -1657,11 +1658,10 @@ static long pt_event_snapshot_aux(structreturn 0 ;/* -* Here, handle_nmi tells us if the tracing is on +* There is no PT interrupt in this mode, so stop the trace and it will +* remain stopped while the buffer is copied. */ -if (READ_ONCE (pt->handle_nmi)) -pt_config_stop (event); - +pt_config_stop (event);pt_read_offset (buf);pt_update_head (pt);
@@ -1673,11 +1673,10 @@ static long pt_event_snapshot_aux(struct ret =perf_output_copy_aux (&pt->handle, handle, from, to);/* -* If the tracing was on when we turned up, restart it. -* Compiler barrier not needed as we couldn't have been -* preempted by anything that touches pt->handle_nmi. +* Here, handle_nmi tells us if the tracing was on. +* If the tracing was on, restart it. */ -if (pt->handle_nmi) +if (READ_ONCE (pt->handle_nmi))pt_config_start (event);return ret;
Greg Kroah-Hartman
maintainerPATCH 613/695 btrfs: subpage: fix the bitmap dump which can cause bitmap corruption
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 77b0b98bb743f5d04d8f995ba1936e1143689d4a upstream.
In commit 75258f20fb70 ("btrfs: subpage: dump extra subpage bitmaps for debug") an internal macro GET_SUBPAGE_BITMAP() is introduced to grab the bitmap of each attribute.
But that commit is using bitmap_cut() which will do the left shift of the larger bitmap, causing incorrect values.
Thankfully this bitmap_cut() is only called for debug usage, and so far it's not yet causing problem.
Fix it to use bitmap_read() to only grab the desired sub-bitmap.
--- fs/btrfs/subpage.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
fs/btrfs/subpage.c +8 -2
@@ -900,8 +900,14 @@ void btrfs_folio_end_all_writers(const s }#define GET_SUBPAGE_BITMAP (subpage, subpage_info, name, dst) \ - bitmap_cut(dst, subpage->bitmaps, 0, \ - subpage_info->name##_offset, subpage_info->bitmap_nr_bits) +{ \ + const int bitmap_nr_bits = subpage_info->bitmap_nr_bits; \ + \ + ASSERT(bitmap_nr_bits < BITS_PER_LONG); \ + *dst = bitmap_read(subpage->bitmaps, \ + subpage_info->name##_offset, \ + bitmap_nr_bits); \ +}void __cold btrfs_subpage_dump_bitmap (const struct btrfs_fs_info *fs_info,struct folio *folio,u64 start,u32 len)
Greg Kroah-Hartman
maintainerPATCH 614/695 wifi: mt76: mt7921: Check devm_kasprintf() returned value
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 1ccc9e476ce76e8577ba4fdbd1f63cb3e3499d38 upstream.
devm_kasprintf() can return a NULL pointer on failure but this returned value is not checked. Fix this lack and check the returned value.
Found by code review.
--- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7921/init.c +2 -0
@@ -52,6 +52,8 @@ static int mt7921_thermal_init(struct mt name =devm_kasprintf (&wiphy->dev,GFP_KERNEL ,"mt7921_%s" ,wiphy_name (wiphy)); +if (!name) +return -ENOMEM ; hwmon =devm_hwmon_device_register_with_groups (&wiphy->dev, name, phy, mt7921_hwmon_groups);
Greg Kroah-Hartman
maintainerPATCH 615/695 wifi: mt76: mt7915: check devm_kasprintf() returned value
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 267efeda8c55f30e0e7c5b7fd03dea4efec6916c upstream.
devm_kasprintf() can return a NULL pointer on failure but this returned value is not checked. Fix this lack and check the returned value.
Found by code review.
--- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7915/init.c +2 -0
@@ -194,6 +194,8 @@ static int mt7915_thermal_init(struct mt name =devm_kasprintf (&wiphy->dev,GFP_KERNEL ,"mt7915_%s" ,wiphy_name (wiphy)); +if (!name) +return -ENOMEM ; cdev =thermal_cooling_device_register (name, phy, &mt7915_thermal_ops);if (!IS_ERR (cdev)) {
Greg Kroah-Hartman
maintainerPATCH 616/695 wifi: mt76: mt7996: fix NULL pointer dereference in mt7996_mcu_sta_bfer_he
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit f503ae90c7355e8506e68498fe84c1357894cd5b upstream.
Fix the NULL pointer dereference in mt7996_mcu_sta_bfer_he routine adding an sta interface to the mt7996 driver.
Found by code review.
--- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +3 -0
@@ -1544,6 +1544,9 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_u8 nss_mcs =mt7996_mcu_get_sta_nss (mcs_map);u8 snd_dim, sts; +if (!vc) +return ; + bf->tx_mode =MT_PHY_TYPE_HE_SU ;mt7996_mcu_sta_sounding_rate (bf);
Greg Kroah-Hartman
maintainerPATCH 617/695 idpf: fix netdev Tx queue stop/wake
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Kubiak <[email protected]>
commit e4b398dd82f5d5867bc5f442c43abc8fba30ed2c upstream.
netif_txq_maybe_stop() returns -1, 0, or 1, while idpf_tx_maybe_stop_common() says it returns 0 or -EBUSY. As a result, there sometimes are Tx queue timeout warnings despite that the queue is empty or there is at least enough space to restart it. Make idpf_tx_maybe_stop_common() inline and returning true or false, handling the return of netif_txq_maybe_stop() properly. Use a correct goto in idpf_tx_maybe_stop_splitq() to avoid stopping the queue or incrementing the stops counter twice.
--- drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c | 4 ++ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 35 +++++--------------- drivers/net/ethernet/intel/idpf/idpf_txrx.h | 9 ++++- 3 files changed, 21 insertions(+), 27 deletions(-)
drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c +4 -0
@@ -371,6 +371,10 @@ netdev_tx_t idpf_tx_singleq_frame(struct IDPF_TX_DESCS_FOR_CTX)) {idpf_tx_buf_hw_update (tx_q, tx_q->next_to_use, false); +u64_stats_update_begin (&tx_q->stats_sync); +u64_stats_inc (&tx_q->q_stats.q_busy); +u64_stats_update_end (&tx_q->stats_sync); +return NETDEV_TX_BUSY ; }
drivers/net/ethernet/intel/idpf/idpf_txrx.c +9 -26
@@ -2158,29 +2158,6 @@ void idpf_tx_splitq_build_flow_desc(unio }/** -* idpf_tx_maybe_stop_common - 1st level check for common Tx stop conditions -* @tx_q: the queue to be checked -* @size: number of descriptors we want to assure is available -* -* Returns 0 if stop is not needed -*/ -int idpf_tx_maybe_stop_common (struct idpf_tx_queue *tx_q,unsigned int size) -{ -struct netdev_queue *nq; - -if (likely (IDPF_DESC_UNUSED (tx_q) >= size)) -return 0 ; - -u64_stats_update_begin (&tx_q->stats_sync); -u64_stats_inc (&tx_q->q_stats.q_busy); -u64_stats_update_end (&tx_q->stats_sync); - - nq =netdev_get_tx_queue (tx_q->netdev, tx_q->idx); - -return netif_txq_maybe_stop (nq,IDPF_DESC_UNUSED (tx_q), size, size); -} - -/** * idpf_tx_maybe_stop_splitq - 1st level check for Tx splitq stop conditions * @tx_q: the queue to be checked * @descs_needed: number of descriptors required for this packet
@@ -2191,7 +2168,7 @@ static int idpf_tx_maybe_stop_splitq(str unsigned int descs_needed) {if (idpf_tx_maybe_stop_common (tx_q, descs_needed)) - goto splitq_stop; + goto out;/* If there are too many outstanding completions expected on the * completion queue, stop the TX queue to give the device some time to
@@ -2210,10 +2187,12 @@ static int idpf_tx_maybe_stop_splitq(strreturn 0 ; splitq_stop: +netif_stop_subqueue (tx_q->netdev, tx_q->idx); + +out:u64_stats_update_begin (&tx_q->stats_sync);u64_stats_inc (&tx_q->q_stats.q_busy);u64_stats_update_end (&tx_q->stats_sync); -netif_stop_subqueue (tx_q->netdev, tx_q->idx);return -EBUSY ; }
@@ -2236,7 +2215,11 @@ void idpf_tx_buf_hw_update(struct idpf_t nq =netdev_get_tx_queue (tx_q->netdev, tx_q->idx); tx_q->next_to_use = val; -idpf_tx_maybe_stop_common (tx_q,IDPF_TX_DESC_NEEDED ); +if (idpf_tx_maybe_stop_common (tx_q,IDPF_TX_DESC_NEEDED )) { +u64_stats_update_begin (&tx_q->stats_sync); +u64_stats_inc (&tx_q->q_stats.q_busy); +u64_stats_update_end (&tx_q->stats_sync); + }/* Force memory writes to complete before letting h/w * know there are new descriptors to fetch. (Only
drivers/net/ethernet/intel/idpf/idpf_txrx.h +8 -1
@@ -1064,7 +1064,6 @@ void idpf_tx_dma_map_error(struct idpf_t struct idpf_tx_buf *first, u16 ring_idx);unsigned int idpf_tx_desc_count_required (struct idpf_tx_queue *txq,struct sk_buff *skb); -int idpf_tx_maybe_stop_common (struct idpf_tx_queue *tx_q,unsigned int size);void idpf_tx_timeout (struct net_device *netdev,unsigned int txqueue);netdev_tx_t idpf_tx_singleq_frame (struct sk_buff *skb,struct idpf_tx_queue *tx_q);
@@ -1073,4 +1072,12 @@ bool idpf_rx_singleq_buf_hw_alloc_all(st u16 cleaned_count);int idpf_tso (struct sk_buff *skb,struct idpf_tx_offload_params *off); +static inline bool idpf_tx_maybe_stop_common (struct idpf_tx_queue *tx_q, +u32 needed) +{ +return !netif_subqueue_maybe_stop (tx_q->netdev, tx_q->idx, +IDPF_DESC_UNUSED (tx_q), + needed, needed); +} +#endif /* !_IDPF_TXRX_H_ */
Greg Kroah-Hartman
maintainerPATCH 618/695 wifi: mt76: mt7925: fix a potential array-index-out-of-bounds issue for clc
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Yen Hsieh <[email protected]>
commit 9679ca7326e52282cc923c4d71d81c999cb6cd55 upstream.
Due to the lack of checks on the clc array, if the firmware supports more clc configuration, it will cause illegal memory access.
--- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +3 -0
@@ -638,6 +638,9 @@ static int mt7925_load_clc(struct mt792xfor (offset =0 ; offset < len; offset +=le32_to_cpu (clc->len)) { clc = (const struct mt7925_clc *)(clc_base + offset); +if (clc->idx >ARRAY_SIZE (phy->clc)) +break ; +/* do not init buf again if chip reset triggered */ if (phy->clc[clc->idx])continue ;
Greg Kroah-Hartman
maintainerPATCH 619/695 wifi: rtw88: 8821cu: Remove VID/PID 0bda:c82c
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Morrow <[email protected]>
commit 0af8cd2822f31ed8363223329e5cff2a7ed01961 upstream.
Remove VID/PID 0bda:c82c as it was inadvertently added to the device list in driver rtw8821cu. This VID/PID is for the rtw8822cu device and it is already in the appropriate place for that device.
--- drivers/net/wireless/realtek/rtw88/rtw8821cu.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/wireless/realtek/rtw88/rtw8821cu.c +0 -2
@@ -31,8 +31,6 @@ static const struct usb_device_id rtw_88 .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, - { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331d, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* D-Link */ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc811, 0xff, 0xff, 0xff),
Greg Kroah-Hartman
maintainerPATCH 620/695 wifi: rtw88: 8822c: Fix reported RX band width
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <[email protected]>
commit a71ed5898dfae68262f79277915d1dfe34586bc6 upstream.
"iw dev wlp2s0 station dump" shows incorrect rx bitrate:
tx bitrate: 866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2 rx bitrate: 86.7 MBit/s VHT-MCS 9 VHT-NSS 1
This is because the RX band width is calculated incorrectly. Fix the calculation according to the phydm_rxsc_2_bw() function from the official drivers.
After:
tx bitrate: 866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2 rx bitrate: 390.0 MBit/s VHT-MCS 9 80MHz VHT-NSS 1
It also works correctly with the AP configured for 20 MHz and 40 MHz.
Tested with RTL8822CE.
--- drivers/net/wireless/realtek/rtw88/rtw8822c.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/wireless/realtek/rtw88/rtw8822c.c +6 -4
@@ -2611,12 +2611,14 @@ static void query_phy_status_page1(strucelse rxsc =GET_PHY_STAT_P1_HT_RXSC (phy_status); -if (rxsc >=9 && rxsc <=12 ) +if (rxsc ==0 ) + bw = rtwdev->hal.current_band_width; +else if (rxsc >=1 && rxsc <=8 ) + bw =RTW_CHANNEL_WIDTH_20 ; +else if (rxsc >=9 && rxsc <=12 ) bw =RTW_CHANNEL_WIDTH_40 ; -else if (rxsc >=13 ) - bw =RTW_CHANNEL_WIDTH_80 ;else - bw =RTW_CHANNEL_WIDTH_20 ; + bw =RTW_CHANNEL_WIDTH_80 ; channel =GET_PHY_STAT_P1_CHANNEL (phy_status);rtw_set_rx_freq_band (pkt_stat, channel);
Greg Kroah-Hartman
maintainerPATCH 621/695 wifi: rtw88: 8703b: Fix reported RX band width
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <[email protected]>
commit 0129e5ff2842450f1426e312b5e580c0814e0de3 upstream.
The definition of GET_RX_DESC_BW is incorrect. Fix it according to the GET_RX_STATUS_DESC_BW_8703B macro from the official driver.
Tested only with RTL8812AU, which uses the same bits.
--- drivers/net/wireless/realtek/rtw88/rx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw88/rx.h +1 -1
@@ -41,7 +41,7 @@ enum rtw_rx_desc_enc {#define GET_RX_DESC_TSFL (rxdesc) \ le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0))#define GET_RX_DESC_BW (rxdesc) \ - (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(31, 24))) + (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4)))void rtw_rx_stats (struct rtw_dev *rtwdev,struct ieee80211_vif *vif,struct sk_buff *skb);
Greg Kroah-Hartman
maintainerPATCH 622/695 wifi: mt76: mt7615: check devm_kasprintf() returned value
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit 5acdc432f832d810e0d638164c393b877291d9b4 upstream.
devm_kasprintf() can return a NULL pointer on failure but this returned value is not checked. Fix this lack and check the returned value.
Found by code review.
--- drivers/net/wireless/mediatek/mt76/mt7615/init.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7615/init.c +3 -0
@@ -56,6 +56,9 @@ int mt7615_thermal_init(struct mt7615_de name =devm_kasprintf (&wiphy->dev,GFP_KERNEL ,"mt7615_%s" ,wiphy_name (wiphy)); +if (!name) +return -ENOMEM ; + hwmon =devm_hwmon_device_register_with_groups (&wiphy->dev, name, dev, mt7615_hwmon_groups);return PTR_ERR_OR_ZERO (hwmon);
Greg Kroah-Hartman
maintainerPATCH 623/695 wifi: mt76: mt7925: fix a potential association failure upon resuming
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Lo <[email protected]>
commit 45064d19fd3af6aeb0887b35b5564927980cf150 upstream.
In multi-channel scenarios, the granted channel must be aborted before suspending. Otherwise, the firmware will be put into a wrong state, resulting in an association failure after resuming.
With this patch, the granted channel will be aborted before suspending if necessary.
--- drivers/net/wireless/mediatek/mt76/mt7925/main.c | 15 +++++++++++++++ drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h | 1 + drivers/net/wireless/mediatek/mt76/mt7925/pci.c | 2 ++ 3 files changed, 18 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/main.c +15 -0
@@ -439,6 +439,19 @@ static void mt7925_roc_iter(void *priv,mt7925_mcu_abort_roc (phy, &mvif->bss_conf, phy->roc_token_id); } +void mt7925_roc_abort_sync (struct mt792x_dev *dev) +{ +struct mt792x_phy *phy = &dev->phy; + +del_timer_sync (&phy->roc_timer); +cancel_work_sync (&phy->roc_work); +if (test_and_clear_bit (MT76_STATE_ROC , &phy->mt76->state)) +ieee80211_iterate_interfaces (mt76_hw (dev), +IEEE80211_IFACE_ITER_RESUME_ALL , + mt7925_roc_iter, (void *)phy); +} +EXPORT_SYMBOL_GPL (mt7925_roc_abort_sync); +void mt7925_roc_work (struct work_struct *work) {struct mt792x_phy *phy;
@@ -1109,6 +1122,8 @@ static void mt7925_mac_link_sta_remove(s msta = (struct mt792x_sta *)link_sta->sta->drv_priv; mlink =mt792x_sta_to_link (msta, link_id); +mt7925_roc_abort_sync (dev); +mt76_connac_free_pending_tx_skbs (&dev->pm, &mlink->wcid);mt76_connac_pm_wake (&dev->mphy, &dev->pm);
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +1 -0
@@ -307,6 +307,7 @@ int mt7925_mcu_set_roc(struct mt792x_phy enum mt7925_roc_req type, u8 token_id);int mt7925_mcu_abort_roc (struct mt792x_phy *phy,struct mt792x_bss_conf *mconf,u8 token_id); +void mt7925_roc_abort_sync (struct mt792x_dev *dev);int mt7925_mcu_fill_message (struct mt76_dev *mdev,struct sk_buff *skb,int cmd,int *wait_seq); int mt7925_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
drivers/net/wireless/mediatek/mt76/mt7925/pci.c +2 -0
@@ -449,6 +449,8 @@ static int mt7925_pci_suspend(struct devcancel_delayed_work_sync (&pm->ps_work);cancel_work_sync (&pm->wake_work); +mt7925_roc_abort_sync (dev); + err =mt792x_mcu_drv_pmctrl (dev);if (err <0 ) goto restore_suspend;
Greg Kroah-Hartman
maintainerPATCH 624/695 debugfs show actual source in /proc/mounts
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Aurèle La France <[email protected]>
commit 3a987b88a42593875f6345188ca33731c7df728c upstream.
After its conversion to the new mount API, debugfs displays "none" in /proc/mounts instead of the actual source. Fix this by recognising its "source" mount option.
--- fs/debugfs/inode.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/debugfs/inode.c +8 -0
@@ -89,12 +89,14 @@ enum { Opt_uid, Opt_gid, Opt_mode, + Opt_source, };static const struct fs_parameter_spec debugfs_param_specs[] = {fsparam_gid ("gid" , Opt_gid),fsparam_u32oct ("mode" , Opt_mode),fsparam_uid ("uid" , Opt_uid), +fsparam_string ("source" , Opt_source), {} };
@@ -126,6 +128,12 @@ static int debugfs_parse_param(struct fscase Opt_mode: opts->mode = result.uint_32 &S_IALLUGO ;break ; +case Opt_source: +if (fc->source) +return invalfc (fc,"Multiple sources specified" ); + fc->source = param->string; + param->string =NULL ; +break ;/* * We might like to report bad mount options here; * but traditionally debugfs has ignored all mount options
Greg Kroah-Hartman
maintainerPATCH 625/695 debugobjects: Fix conditions in fill_pool()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
commit 684d28feb8546d1e9597aa363c3bfcf52fe250b7 upstream.
fill_pool() uses 'obj_pool_min_free' to decide whether objects should be handed back to the kmem cache. But 'obj_pool_min_free' records the lowest historical value of the number of objects in the object pool and not the minimum number of objects which should be kept in the pool.
Use 'debug_objects_pool_min_level' instead, which holds the minimum number which was scaled to the number of CPUs at boot time.
[ tglx: Massage change log ]
--- lib/debugobjects.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
lib/debugobjects.c +3 -2
@@ -142,13 +142,14 @@ static void fill_pool(void)* READ_ONCE()s pair with the WRITE_ONCE()s in pool_lock critical * sections. */ -while (READ_ONCE (obj_nr_tofree) && (READ_ONCE (obj_pool_free) < obj_pool_min_free)) { +while (READ_ONCE (obj_nr_tofree) && +READ_ONCE (obj_pool_free) < debug_objects_pool_min_level) {raw_spin_lock_irqsave (&pool_lock, flags);/* * Recheck with the lock held as the worker thread might have * won the race and freed the global free list already. */ -while (obj_nr_tofree && (obj_pool_free < obj_pool_min_free)) { +while (obj_nr_tofree && (obj_pool_free < debug_objects_pool_min_level)) { obj =hlist_entry (obj_to_free.first,typeof (*obj), node);hlist_del (&obj->node);WRITE_ONCE (obj_nr_tofree, obj_nr_tofree -1 );
Greg Kroah-Hartman
maintainerPATCH 626/695 btrfs: fix race setting file private on concurrent lseek using same fd
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 7ee85f5515e86a4e2a2f51969795920733912bad upstream.
When doing concurrent lseek(2) system calls against the same file descriptor, using multiple threads belonging to the same process, we have a short time window where a race happens and can result in a memory leak.
The race happens like this:
1) A program opens a file descriptor for a file and then spawns two threads (with the pthreads library for example), lets call them task A and task B;
2) Task A calls lseek with SEEK_DATA or SEEK_HOLE and ends up at file.c:find_desired_extent() while holding a read lock on the inode;
3) At the start of find_desired_extent(), it extracts the file's private_data pointer into a local variable named 'private', which has a value of NULL;
4) Task B also calls lseek with SEEK_DATA or SEEK_HOLE, locks the inode in shared mode and enters file.c:find_desired_extent(), where it also extracts file->private_data into its local variable 'private', which has a NULL value;
5) Because it saw a NULL file private, task A allocates a private structure and assigns to the file structure;
6) Task B also saw a NULL file private so it also allocates its own file private and then assigns it to the same file structure, since both tasks are using the same file descriptor.
At this point we leak the private structure allocated by task A.
Besides the memory leak, there's also the detail that both tasks end up using the same cached state record in the private structure (struct btrfs_file_private::llseek_cached_state), which can result in a use-after-free problem since one task can free it while the other is still using it (only one task took a reference count on it). Also, sharing the cached state is not a good idea since it could result in incorrect results in the future - right now it should not be a problem because it end ups being used only in extent-io-tree.c:count_range_bits() where we do range validation before using the cached state.
Fix this by protecting the private assignment and check of a file while holding the inode's spinlock and keep track of the task that allocated the private, so that it's used only by that task in order to prevent user-after-free issues with the cached state record as well as potentially using it incorrectly in the future.
--- fs/btrfs/btrfs_inode.h | 1 + fs/btrfs/ctree.h | 2 ++ fs/btrfs/file.c | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-)
fs/btrfs/btrfs_inode.h +1 -0
@@ -152,6 +152,7 @@ struct btrfs_inode {* logged_trans), to access/update delalloc_bytes, new_delalloc_bytes, * defrag_bytes, disk_i_size, outstanding_extents, csum_bytes and to * update the VFS' inode number of bytes used. +* Also protects setting struct file::private_data. */ spinlock_t lock;
fs/btrfs/ctree.h +2 -0
@@ -459,6 +459,8 @@ struct btrfs_file_private {void *filldir_buf;u64 last_index;struct extent_state *llseek_cached_state; +/* Task that allocated this structure. */ +struct task_struct *owner_task; };static inline u32 BTRFS_LEAF_DATA_SIZE (const struct btrfs_fs_info *info)
fs/btrfs/file.c +31 -3
@@ -3485,7 +3485,7 @@ static bool find_desired_extent_in_hole(static loff_t find_desired_extent (struct file *file,loff_t offset,int whence) {struct btrfs_inode *inode =BTRFS_I (file->f_mapping->host); -struct btrfs_file_private *private = file->private_data; +struct btrfs_file_private *private;struct btrfs_fs_info *fs_info = inode->root->fs_info;struct extent_state *cached_state =NULL ;struct extent_state **delalloc_cached_state;
@@ -3513,7 +3513,19 @@ static loff_t find_desired_extent(struct inode_get_bytes(&inode->vfs_inode) == i_size)return i_size; -if (!private) { +spin_lock (&inode->lock); + private = file->private_data; +spin_unlock (&inode->lock); + +if (private && private->owner_task != current) { +/* +* Not allocated by us, don't use it as its cached state is used +* by the task that allocated it and we don't want neither to +* mess with it nor get incorrect results because it reflects an +* invalid state for the current task. +*/ + private =NULL ; + }else if (!private) { private =kzalloc (sizeof (*private),GFP_KERNEL );/* * No worries if memory allocation failed.
@@ -3521,7 +3533,23 @@ static loff_t find_desired_extent(struct* lseek SEEK_HOLE/DATA calls to a file when there's delalloc, * so everything will still be correct. */ - file->private_data = private; +if (private) { +bool free = false; + + private->owner_task = current; + +spin_lock (&inode->lock); +if (file->private_data) + free = true; +else + file->private_data = private; +spin_unlock (&inode->lock); + +if (free) { +kfree (private); + private =NULL ; + } + } }if (private)
Greg Kroah-Hartman
maintainerPATCH 627/695 btrfs: tree-checker: fix the wrong output of data backref objectid
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit b0b595e61d97de61c15b379b754b2caa90e83e5c upstream.
[BUG]
There are some reports about invalid data backref objectids, the report looks like this:
BTRFS critical (device sda): corrupt leaf: block=333654787489792 slot=110 extent bytenr=333413935558656 len=65536 invalid data ref objectid value 2543
The data ref objectid is the inode number inside the subvolume.
But in above case, the value is completely sane, not really showing the problem.
[CAUSE]
The root cause of the problem is the deprecated feature, inode cache.
This feature results a special inode number, -12ULL, and it's no longer recognized by tree-checker, triggering the error.
The direct problem here is the output of data ref objectid. The value shown is in fact the dref_root (subvolume id), not the dref_objectid (inode number).
[FIX]
Fix the output to use dref_objectid instead.
--- fs/btrfs/tree-checker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/tree-checker.c +1 -1
@@ -1517,7 +1517,7 @@ static int check_extent_item(struct exte dref_objectid > BTRFS_LAST_FREE_OBJECTID)) {extent_err (leaf, slot,"invalid data ref objectid value %llu" , - dref_root); + dref_objectid);return -EUCLEAN ; } if (unlikely(!IS_ALIGNED(dref_offset,
Greg Kroah-Hartman
maintainerPATCH 628/695 btrfs: always update fstrim_range on failure in FITRIM ioctl
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Stefani <[email protected]>
commit 3368597206dc3c6c3c2247ee146beada14c67380 upstream.
Even in case of failure we could've discarded some data and userspace should be made aware of it, so copy fstrim_range to userspace regardless.
Also make sure to update the trimmed bytes amount even if btrfs_trim_free_extents fails.
--- fs/btrfs/extent-tree.c | 4 ++-- fs/btrfs/ioctl.c | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-)
fs/btrfs/extent-tree.c +2 -2
@@ -6551,13 +6551,13 @@ int btrfs_trim_fs(struct btrfs_fs_info *continue ; ret =btrfs_trim_free_extents (device, &group_trimmed); + + trimmed += group_trimmed;if (ret) { dev_failed++; dev_ret = ret;break ; } - - trimmed += group_trimmed; }mutex_unlock (&fs_devices->device_list_mutex);
fs/btrfs/ioctl.c +1 -3
@@ -543,13 +543,11 @@ static noinline int btrfs_ioctl_fitrim(s range.minlen =max (range.minlen, minlen); ret =btrfs_trim_fs (fs_info, &range); -if (ret <0 ) -return ret;if (copy_to_user (arg, &range,sizeof (range)))return -EFAULT ; -return 0 ; +return ret; }int __pure btrfs_is_empty_uuid (const u8 *uuid)
Greg Kroah-Hartman
maintainerPATCH 629/695 f2fs: fix to wait dio completion
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit 96cfeb0389530ae32ade8a48ae3ae1ac3b6c009d upstream.
It should wait all existing dio write IOs before block removal, otherwise, previous direct write IO may overwrite data in the block which may be reused by other inode.
--- fs/f2fs/file.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
fs/f2fs/file.c +13 -0
@@ -1055,6 +1055,13 @@ int f2fs_setattr(struct mnt_idmap *idmapreturn err; } +/* +* wait for inflight dio, blocks should be removed after +* IO completion. +*/ +if (attr->ia_size < old_size) +inode_dio_wait (inode); +f2fs_down_write (&fi->i_gc_rwsem[WRITE ]);filemap_invalidate_lock (inode->i_mapping);
@@ -1891,6 +1898,12 @@ static long f2fs_fallocate(struct file *if (ret) goto out; +/* +* wait for inflight dio, blocks should be removed after IO +* completion. +*/ +inode_dio_wait (inode); +if (mode &FALLOC_FL_PUNCH_HOLE ) {if (offset >= inode->i_size) goto out;
Greg Kroah-Hartman
maintainerPATCH 630/695 f2fs: fix several potential integer overflows in file offsets
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit 1cade98cf6415897bf9342ee451cc5b40b58c638 upstream.
When dealing with large extents and calculating file offsets by summing up according extent offsets and lengths of unsigned int type, one may encounter possible integer overflow if the values are big enough.
Prevent this from happening by expanding one of the addends to (pgoff_t) type.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
--- fs/f2fs/extent_cache.c | 4 ++-- fs/f2fs/file.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
fs/f2fs/extent_cache.c +2 -2
@@ -366,7 +366,7 @@ static unsigned int __free_extent_tree(sstatic void __drop_largest_extent (struct extent_tree *et,pgoff_t fofs,unsigned int len) { -if (fofs < et->largest.fofs + et->largest.len && +if (fofs < (pgoff_t )et->largest.fofs + et->largest.len && fofs + len > et->largest.fofs) { et->largest.len =0 ; et->largest_updated = true;
@@ -456,7 +456,7 @@ static bool __lookup_extent_tree(structif (type ==EX_READ && et->largest.fofs <= pgofs && - et->largest.fofs + et->largest.len > pgofs) { + (pgoff_t )et->largest.fofs + et->largest.len > pgofs) { *ei = et->largest; ret = true;stat_inc_largest_node_hit (sbi);
fs/f2fs/file.c +1 -1
@@ -2731,7 +2731,7 @@ static int f2fs_defragment_range(struct* block addresses are continuous. */ if (f2fs_lookup_read_extent_cache (inode, pg_start, &ei)) { -if (ei.fofs + ei.len >= pg_end) +if ((pgoff_t )ei.fofs + ei.len >= pg_end) goto out; }
Greg Kroah-Hartman
maintainerPATCH 631/695 f2fs: prevent possible int overflow in dir_block_index()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit 47f268f33dff4a5e31541a990dc09f116f80e61c upstream.
The result of multiplication between values derived from functions dir_buckets() and bucket_blocks() *could* technically reach 2^30 * 2^2 = 2^32.
While unlikely to happen, it is prudent to ensure that it will not lead to integer overflow. Thus, use mul_u32_u32() as it's more appropriate to mitigate the issue.
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
--- fs/f2fs/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/f2fs/dir.c +2 -1
@@ -166,7 +166,8 @@ static unsigned long dir_block_index(unsunsigned long bidx =0 ;for (i =0 ; i < level; i++) - bidx +=dir_buckets (i, dir_level) *bucket_blocks (i); + bidx +=mul_u32_u32 (dir_buckets (i, dir_level), +bucket_blocks (i)); bidx += idx *bucket_blocks (level);return bidx; }
Greg Kroah-Hartman
maintainerPATCH 632/695 f2fs: avoid potential int overflow in sanity_check_area_boundary()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Zhandarovich <[email protected]>
commit 50438dbc483ca6a133d2bce9d5d6747bcee38371 upstream.
While calculating the end addresses of main area and segment 0, u32 may be not enough to hold the result without the danger of int overflow.
Just in case, play it safe and cast one of the operands to a wider type (u64).
Found by Linux Verification Center (linuxtesting.org) with static analysis tool SVACE.
--- fs/f2fs/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/super.c +2 -2
@@ -3356,9 +3356,9 @@ static inline bool sanity_check_area_bouu32 segment_count =le32_to_cpu (raw_super->segment_count);u32 log_blocks_per_seg =le32_to_cpu (raw_super->log_blocks_per_seg);u64 main_end_blkaddr = main_blkaddr + - (segment_count_main << log_blocks_per_seg); + ((u64 )segment_count_main << log_blocks_per_seg);u64 seg_end_blkaddr = segment0_blkaddr + - (segment_count << log_blocks_per_seg); + ((u64 )segment_count << log_blocks_per_seg);if (segment0_blkaddr != cp_blkaddr) { f2fs_info(sbi, "Mismatch start address, segment0(%u) cp_blkaddr(%u)",
Greg Kroah-Hartman
maintainerPATCH 633/695 f2fs: Require FMODE_WRITE for atomic write ioctls
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 4f5a100f87f32cb65d4bb1ad282a08c92f6f591e upstream.
The F2FS ioctls for starting and committing atomic writes check for inode_owner_or_capable(), but this does not give LSMs like SELinux or Landlock an opportunity to deny the write access - if the caller's FSUID matches the inode's UID, inode_owner_or_capable() immediately returns true.
There are scenarios where LSMs want to deny a process the ability to write particular files, even files that the FSUID of the process owns; but this can currently partially be bypassed using atomic write ioctls in two ways:
- F2FS_IOC_START_ATOMIC_REPLACE + F2FS_IOC_COMMIT_ATOMIC_WRITE can truncate an inode to size 0
- F2FS_IOC_START_ATOMIC_WRITE + F2FS_IOC_ABORT_ATOMIC_WRITE can revert changes another process concurrently made to a file
Fix it by requiring FMODE_WRITE for these operations, just like for F2FS_IOC_MOVE_RANGE. Since any legitimate caller should only be using these ioctls when intending to write into the file, that seems unlikely to break anything.
--- fs/f2fs/file.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/f2fs/file.c +9 -0
@@ -2135,6 +2135,9 @@ static int f2fs_ioc_start_atomic_write(sloff_t isize;int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (idmap, inode))return -EACCES ;
@@ -2242,6 +2245,9 @@ static int f2fs_ioc_commit_atomic_write(struct mnt_idmap *idmap =file_mnt_idmap (filp);int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (idmap, inode))return -EACCES ;
@@ -2274,6 +2280,9 @@ static int f2fs_ioc_abort_atomic_write(sstruct mnt_idmap *idmap =file_mnt_idmap (filp);int ret; +if (!(filp->f_mode &FMODE_WRITE )) +return -EBADF ; +if (!inode_owner_or_capable (idmap, inode))return -EACCES ;
Greg Kroah-Hartman
maintainerPATCH 634/695 f2fs: check discard support for conventional zones
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shin'ichiro Kawasaki <[email protected]>
commit 43aec4d01bd2ce961817a777b3846f8318f398e4 upstream.
As the helper function f2fs_bdev_support_discard() shows, f2fs checks if the target block devices support discard by calling bdev_max_discard_sectors() and bdev_is_zoned(). This check works well for most cases, but it does not work for conventional zones on zoned block devices. F2fs assumes that zoned block devices support discard, and calls __submit_discard_cmd(). When __submit_discard_cmd() is called for sequential write required zones, it works fine since __submit_discard_cmd() issues zone reset commands instead of discard commands. However, when __submit_discard_cmd() is called for conventional zones, __blkdev_issue_discard() is called even when the devices do not support discard.
The inappropriate __blkdev_issue_discard() call was not a problem before the commit 30f1e7241422 ("block: move discard checks into the ioctl handler") because __blkdev_issue_discard() checked if the target devices support discard or not. If not, it returned EOPNOTSUPP. After the commit, __blkdev_issue_discard() no longer checks it. It always returns zero and sets NULL to the given bio pointer. This NULL pointer triggers f2fs_bug_on() in __submit_discard_cmd(). The BUG is recreated with the commands below at the umount step, where /dev/nullb0 is a zoned null_blk with 5GB total size, 128MB zone size and 10 conventional zones.
$ mkfs.f2fs -f -m /dev/nullb0 $ mount /dev/nullb0 /mnt $ for ((i=0;i<5;i++)); do dd if=/dev/zero of=/mnt/test bs=65536 count=1600 conv=fsync; done $ umount /mnt
To fix the BUG, avoid the inappropriate __blkdev_issue_discard() call. When discard is requested for conventional zones, check if the device supports discard or not. If not, return EOPNOTSUPP.
--- fs/f2fs/segment.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/f2fs/segment.c +7 -0
@@ -1290,6 +1290,13 @@ static int __submit_discard_cmd(struct f wait_list, issued); return 0; } + +/* +* Issue discard for conventional zones only if the device +* supports discard. +*/ +if (!bdev_max_discard_sectors (bdev)) +return -EOPNOTSUPP ; }#endif
Greg Kroah-Hartman
maintainerPATCH 635/695 f2fs: fix to check atomic_file in f2fs ioctl interfaces
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit bfe5c02654261bfb8bd9cb174a67f3279ea99e58 upstream.
Some f2fs ioctl interfaces like f2fs_ioc_set_pin_file(), f2fs_move_file_range(), and f2fs_defragment_range() missed to check atomic_write status, which may cause potential race issue, fix it.
--- fs/f2fs/file.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
fs/f2fs/file.c +12 -1
@@ -2716,7 +2716,8 @@ static int f2fs_defragment_range(struct (range->start + range->len) >>PAGE_SHIFT , DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE)); -if (is_inode_flag_set (inode,FI_COMPRESS_RELEASED )) { +if (is_inode_flag_set (inode,FI_COMPRESS_RELEASED ) || +f2fs_is_atomic_file (inode)) { err = -EINVAL ; goto unlock_out; }
@@ -2949,6 +2950,11 @@ static int f2fs_move_file_range(struct f goto out_unlock; } +if (f2fs_is_atomic_file (src) ||f2fs_is_atomic_file (dst)) { + ret = -EINVAL ; + goto out_unlock; + } + ret = -EINVAL ;if (pos_in + len > src->i_size || pos_in + len < pos_in) goto out_unlock;
@@ -3332,6 +3338,11 @@ static int f2fs_ioc_set_pin_file(structinode_lock (inode); +if (f2fs_is_atomic_file (inode)) { + ret = -EINVAL ; + goto out; + } +if (!pin) {clear_inode_flag (inode,FI_PIN_FILE );f2fs_i_gc_failures_write (inode,0 );
Greg Kroah-Hartman
maintainerPATCH 636/695 hwrng: mtk - Use devm_pm_runtime_enable
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guoqing Jiang <[email protected]>
commit 78cb66caa6ab5385ac2090f1aae5f3c19e08f522 upstream.
Replace pm_runtime_enable with the devres-enabled version which can trigger pm_runtime_disable.
Otherwise, the below appears during reload driver.
mtk_rng 1020f000.rng: Unbalanced pm_runtime_enable!
--- drivers/char/hw_random/mtk-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/hw_random/mtk-rng.c +1 -1
@@ -142,7 +142,7 @@ static int mtk_rng_probe(struct platformdev_set_drvdata (&pdev->dev, priv);pm_runtime_set_autosuspend_delay (&pdev->dev,RNG_AUTOSUSPEND_TIMEOUT );pm_runtime_use_autosuspend (&pdev->dev); -pm_runtime_enable (&pdev->dev); +devm_pm_runtime_enable (&pdev->dev);dev_info (&pdev->dev,"registered RNG driver\n" );
Greg Kroah-Hartman
maintainerPATCH 637/695 hwrng: bcm2835 - Add missing clk_disable_unprepare in bcm2835_rng_init
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
commit d57e2f7cffd57fe2800332dec768ec1b67a4159f upstream.
Add the missing clk_disable_unprepare() before return in bcm2835_rng_init().
--- drivers/char/hw_random/bcm2835-rng.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/char/hw_random/bcm2835-rng.c +3 -1
@@ -94,8 +94,10 @@ static int bcm2835_rng_init(struct hwrngreturn ret; ret =reset_control_reset (priv->reset); -if (ret) +if (ret) { +clk_disable_unprepare (priv->clk);return ret; + }if (priv->mask_interrupts) {/* mask the interrupt */
Greg Kroah-Hartman
maintainerPATCH 638/695 hwrng: cctrng - Add missing clk_disable_unprepare in cctrng_resume
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaosheng Cui <[email protected]>
commit 4b7acc85de14ee8a2236f54445dc635d47eceac0 upstream.
Add the missing clk_disable_unprepare() before return in cctrng_resume().
--- drivers/char/hw_random/cctrng.c | 1 + 1 file changed, 1 insertion(+)
drivers/char/hw_random/cctrng.c +1 -0
@@ -622,6 +622,7 @@ static int __maybe_unused cctrng_resume(/* wait for Cryptocell reset completion */ if (!cctrng_wait_for_reset_completion (drvdata)) {dev_err (dev,"Cryptocell reset not completed" ); +clk_disable_unprepare (drvdata->clk);return -EBUSY ; }
Greg Kroah-Hartman
maintainerPATCH 639/695 arm64: esr: Define ESR_ELx_EC_* constants as UL
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anastasia Belova <[email protected]>
commit b6db3eb6c373b97d9e433530d748590421bbeea7 upstream.
Add explicit casting to prevent expantion of 32th bit of u32 into highest half of u64 in several places.
For example, in inject_abt64:ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT = 0x24 << 26. This operation's result is int with 1 in 32th bit. While casting this value into u64 (esr is u64) 1 fills 32 highest bits.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- arch/arm64/include/asm/esr.h | 88 +++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 44 deletions(-)
arch/arm64/include/asm/esr.h +44 -44
@@ -10,63 +10,63 @@#include <asm/memory.h> #include <asm/sysreg.h> -#define ESR_ELx_EC_UNKNOWN (0x00) -#define ESR_ELx_EC_WFx (0x01) +#define ESR_ELx_EC_UNKNOWN UL(0x00) +#define ESR_ELx_EC_WFx UL(0x01)/* Unallocated EC: 0x02 */ -#define ESR_ELx_EC_CP15_32 (0x03) -#define ESR_ELx_EC_CP15_64 (0x04) -#define ESR_ELx_EC_CP14_MR (0x05) -#define ESR_ELx_EC_CP14_LS (0x06) -#define ESR_ELx_EC_FP_ASIMD (0x07) -#define ESR_ELx_EC_CP10_ID (0x08)/* EL2 only */ -#define ESR_ELx_EC_PAC (0x09)/* EL2 and above */ +#define ESR_ELx_EC_CP15_32 UL(0x03) +#define ESR_ELx_EC_CP15_64 UL(0x04) +#define ESR_ELx_EC_CP14_MR UL(0x05) +#define ESR_ELx_EC_CP14_LS UL(0x06) +#define ESR_ELx_EC_FP_ASIMD UL(0x07) +#define ESR_ELx_EC_CP10_ID UL(0x08)/* EL2 only */ +#define ESR_ELx_EC_PAC UL(0x09)/* EL2 and above */ /* Unallocated EC: 0x0A - 0x0B */ -#define ESR_ELx_EC_CP14_64 (0x0C) -#define ESR_ELx_EC_BTI (0x0D) -#define ESR_ELx_EC_ILL (0x0E) +#define ESR_ELx_EC_CP14_64 UL(0x0C) +#define ESR_ELx_EC_BTI UL(0x0D) +#define ESR_ELx_EC_ILL UL(0x0E)/* Unallocated EC: 0x0F - 0x10 */ -#define ESR_ELx_EC_SVC32 (0x11) -#define ESR_ELx_EC_HVC32 (0x12)/* EL2 only */ -#define ESR_ELx_EC_SMC32 (0x13)/* EL2 and above */ +#define ESR_ELx_EC_SVC32 UL(0x11) +#define ESR_ELx_EC_HVC32 UL(0x12)/* EL2 only */ +#define ESR_ELx_EC_SMC32 UL(0x13)/* EL2 and above */ /* Unallocated EC: 0x14 */ -#define ESR_ELx_EC_SVC64 (0x15) -#define ESR_ELx_EC_HVC64 (0x16)/* EL2 and above */ -#define ESR_ELx_EC_SMC64 (0x17)/* EL2 and above */ -#define ESR_ELx_EC_SYS64 (0x18) -#define ESR_ELx_EC_SVE (0x19) -#define ESR_ELx_EC_ERET (0x1a)/* EL2 only */ +#define ESR_ELx_EC_SVC64 UL(0x15) +#define ESR_ELx_EC_HVC64 UL(0x16)/* EL2 and above */ +#define ESR_ELx_EC_SMC64 UL(0x17)/* EL2 and above */ +#define ESR_ELx_EC_SYS64 UL(0x18) +#define ESR_ELx_EC_SVE UL(0x19) +#define ESR_ELx_EC_ERET UL(0x1a)/* EL2 only */ /* Unallocated EC: 0x1B */ -#define ESR_ELx_EC_FPAC (0x1C)/* EL1 and above */ -#define ESR_ELx_EC_SME (0x1D) +#define ESR_ELx_EC_FPAC UL(0x1C)/* EL1 and above */ +#define ESR_ELx_EC_SME UL(0x1D)/* Unallocated EC: 0x1E */ -#define ESR_ELx_EC_IMP_DEF (0x1f)/* EL3 only */ -#define ESR_ELx_EC_IABT_LOW (0x20) -#define ESR_ELx_EC_IABT_CUR (0x21) -#define ESR_ELx_EC_PC_ALIGN (0x22) +#define ESR_ELx_EC_IMP_DEF UL(0x1f)/* EL3 only */ +#define ESR_ELx_EC_IABT_LOW UL(0x20) +#define ESR_ELx_EC_IABT_CUR UL(0x21) +#define ESR_ELx_EC_PC_ALIGN UL(0x22)/* Unallocated EC: 0x23 */ -#define ESR_ELx_EC_DABT_LOW (0x24) -#define ESR_ELx_EC_DABT_CUR (0x25) -#define ESR_ELx_EC_SP_ALIGN (0x26) -#define ESR_ELx_EC_MOPS (0x27) -#define ESR_ELx_EC_FP_EXC32 (0x28) +#define ESR_ELx_EC_DABT_LOW UL(0x24) +#define ESR_ELx_EC_DABT_CUR UL(0x25) +#define ESR_ELx_EC_SP_ALIGN UL(0x26) +#define ESR_ELx_EC_MOPS UL(0x27) +#define ESR_ELx_EC_FP_EXC32 UL(0x28)/* Unallocated EC: 0x29 - 0x2B */ -#define ESR_ELx_EC_FP_EXC64 (0x2C) +#define ESR_ELx_EC_FP_EXC64 UL(0x2C)/* Unallocated EC: 0x2D - 0x2E */ -#define ESR_ELx_EC_SERROR (0x2F) -#define ESR_ELx_EC_BREAKPT_LOW (0x30) -#define ESR_ELx_EC_BREAKPT_CUR (0x31) -#define ESR_ELx_EC_SOFTSTP_LOW (0x32) -#define ESR_ELx_EC_SOFTSTP_CUR (0x33) -#define ESR_ELx_EC_WATCHPT_LOW (0x34) -#define ESR_ELx_EC_WATCHPT_CUR (0x35) +#define ESR_ELx_EC_SERROR UL(0x2F) +#define ESR_ELx_EC_BREAKPT_LOW UL(0x30) +#define ESR_ELx_EC_BREAKPT_CUR UL(0x31) +#define ESR_ELx_EC_SOFTSTP_LOW UL(0x32) +#define ESR_ELx_EC_SOFTSTP_CUR UL(0x33) +#define ESR_ELx_EC_WATCHPT_LOW UL(0x34) +#define ESR_ELx_EC_WATCHPT_CUR UL(0x35)/* Unallocated EC: 0x36 - 0x37 */ -#define ESR_ELx_EC_BKPT32 (0x38) +#define ESR_ELx_EC_BKPT32 UL(0x38)/* Unallocated EC: 0x39 */ -#define ESR_ELx_EC_VECTOR32 (0x3A)/* EL2 only */ +#define ESR_ELx_EC_VECTOR32 UL(0x3A)/* EL2 only */ /* Unallocated EC: 0x3B */ -#define ESR_ELx_EC_BRK64 (0x3C) +#define ESR_ELx_EC_BRK64 UL(0x3C)/* Unallocated EC: 0x3D - 0x3F */ -#define ESR_ELx_EC_MAX (0x3F) +#define ESR_ELx_EC_MAX UL(0x3F)#define ESR_ELx_EC_SHIFT (26)#define ESR_ELx_EC_WIDTH (6)
Greg Kroah-Hartman
maintainerPATCH 640/695 arm64: errata: Enable the AC03_CPU_38 workaround for ampere1a
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: D Scott Phillips <[email protected]>
commit db0d8a84348b876df7c4276f0cbce5df3b769f5f upstream.
The ampere1a cpu is affected by erratum AC04_CPU_10 which is the same bug as AC03_CPU_38. Add ampere1a to the AC03_CPU_38 workaround midr list.
--- Documentation/arch/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 2 +- arch/arm64/include/asm/cputype.h | 2 ++ arch/arm64/kernel/cpu_errata.c | 10 +++++++++- 4 files changed, 14 insertions(+), 2 deletions(-)
Documentation/arch/arm64/silicon-errata.rst +2 -0
@@ -55,6 +55,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Ampere | AmpereOne | AC03_CPU_38 | AMPERE_ERRATUM_AC03_CPU_38 | +----------------+-----------------+-----------------+-----------------------------+ +| Ampere | AmpereOne AC04 | AC04_CPU_10 | AMPERE_ERRATUM_AC03_CPU_38 | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A510 | #2457168 | ARM64_ERRATUM_2457168 | +----------------+-----------------+-----------------+-----------------------------+
arch/arm64/Kconfig +1 -1
@@ -423,7 +423,7 @@ config AMPERE_ERRATUM_AC03_CPU_38 default y help This option adds an alternative code sequence to work around Ampere - erratum AC03_CPU_38 on AmpereOne. + errata AC03_CPU_38 and AC04_CPU_10 on AmpereOne. The affected design reports FEAT_HAFDBS as not implemented in ID_AA64MMFR1_EL1.HAFDBS, but (V)TCR_ELx.{HA,HD} are not RES0
arch/arm64/include/asm/cputype.h +2 -0
@@ -143,6 +143,7 @@#define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039#define AMPERE_CPU_PART_AMPERE1 0xAC3 +#define AMPERE_CPU_PART_AMPERE1A 0xAC4#define MICROSOFT_CPU_PART_AZURE_COBALT_100 0xD49/* Based on r0p0 of ARM Neoverse N2 */
@@ -212,6 +213,7 @@#define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)#define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) +#define MIDR_AMPERE1A MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1A)#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)/* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
arch/arm64/kernel/cpu_errata.c +9 -1
@@ -456,6 +456,14 @@ static const struct midr_range erratum_s };#endif +#ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38 +static const struct midr_range erratum_ac03_cpu_38_list[] = { +MIDR_ALL_VERSIONS (MIDR_AMPERE1 ), +MIDR_ALL_VERSIONS (MIDR_AMPERE1A ), + {}, +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = {#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE {
@@ -772,7 +780,7 @@ const struct arm64_cpu_capabilities arm6 { .desc = "AmpereOne erratum AC03_CPU_38", .capability = ARM64_WORKAROUND_AMPERE_AC03_CPU_38, - ERRATA_MIDR_ALL_VERSIONS(MIDR_AMPERE1), + ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list), }, #endif {
Greg Kroah-Hartman
maintainerPATCH 641/695 arm64: dts: mediatek: mt8186-corsola: Disable DPI display interface
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
commit 3079fb09ddac159bd8bb87f6f15b924e265f8d4d upstream.
The DPI display interface feeds the external display pipeline. However the pipeline representation is currently incomplete. Efforts are still under way to come up with a way to represent the "creative" repurposing of the DP bridge chip's internal output mux, which is meant to support USB type-C orientation changes, to output to one of two type-C ports.
Until that is finalized, the external display can't be fully described, and thus won't work. Even worse, the half complete graph potentially confuses the OS, breaking the internal display as well.
Disable the external display interface across the whole Corsola family until the DP / USB Type-C muxing graph binding is ready.
--- arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi +2 -1
@@ -353,7 +353,8 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&dpi_pins_default>; pinctrl-1 = <&dpi_pins_sleep>; - status = "okay"; + /* TODO Re-enable after DP to Type-C port muxing can be described */ + status = "disabled"; }; &dpi_out {
Greg Kroah-Hartman
maintainerPATCH 642/695 arm64: dts: rockchip: Raise Pinebook Pros panel backlight PWM frequency
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragan Simic <[email protected]>
commit 8c51521de18755d4112a77a598a348b38d0af370 upstream.
Increase the frequency of the PWM signal that drives the LED backlight of the Pinebook Pro's panel, from about 1.35 KHz (which equals to the PWM period of 740,740 ns), to exactly 8 kHz (which equals to the PWM period of 125,000 ns). Using a higher PWM frequency for the panel backlight, which reduces the flicker, can only be beneficial to the end users' eyes.
On top of that, increasing the backlight PWM signal frequency reportedly eliminates the buzzing emitted from the Pinebook Pro's built-in speakers when certain backlight levels are set, which cause some weird interference with some of the components of the Pinebook Pro's audio chain.
The old value for the backlight PWM period, i.e. 740,740 ns, is pretty much an arbitrary value that was selected during the very early bring-up of the Pinebook Pro, only because that value seemed to minimize horizontal line distortion on the display, which resulted from the old X.org drivers causing screen tearing when dragging windows around. That's no longer an issue, so there are no reasons to stick with the old PWM period value.
The lower and the upper backlight PWM frequency limits for the Pinebook Pro's panel, according to its datasheet, are 200 Hz and 10 kHz, respectively. [1] These changes still leave some headroom, which may have some positive effects on the lifetime expectancy of the panel's backlight LEDs.
[1] https://files.pine64.org/doc/datasheet/PinebookPro/NV140FHM-N49_Rev.P0_20160804_201710235838.pdf
--- arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +1 -1
@@ -32,7 +32,7 @@ backlight: edp-backlight { compatible = "pwm-backlight"; power-supply = <&vcc_12v>; - pwms = <&pwm0 0 740740 0>; + pwms = <&pwm0 0 125000 0>; }; bat: battery {
Greg Kroah-Hartman
maintainerPATCH 643/695 arm64: dts: qcom: sa8775p: Mark APPS and PCIe SMMUs as DMA coherent
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingqing Zhou <[email protected]>
commit 421688265d7f5d3ff4211982e7231765378bb64f upstream.
The SMMUs on sa8775p are cache-coherent. GPU SMMU is marked as such, mark the APPS and PCIe ones as well.
Rule: add
--- arch/arm64/boot/dts/qcom/sa8775p.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/qcom/sa8775p.dtsi +2 -0
@@ -3070,6 +3070,7 @@ reg = <0x0 0x15000000 0x0 0x100000>; #iommu-cells = <2>; #global-interrupts = <2>; + dma-coherent; interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
@@ -3208,6 +3209,7 @@ reg = <0x0 0x15200000 0x0 0x80000>; #iommu-cells = <2>; #global-interrupts = <2>; + dma-coherent; interrupts = <GIC_SPI 920 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 921 IRQ_TYPE_LEVEL_HIGH>,
Greg Kroah-Hartman
maintainerPATCH 644/695 arm64: dts: rockchip: Correct the Pinebook Pro battery design capacity
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragan Simic <[email protected]>
commit def33fb1191207f5afa6dcb681d71fef2a6c1293 upstream.
All batches of the Pine64 Pinebook Pro, except the latest batch (as of 2024) whose hardware design was revised due to the component shortage, use a 1S lithium battery whose nominal/design capacity is 10,000 mAh, according to the battery datasheet. [1][2] Let's correct the design full-charge value in the Pinebook Pro board dts, to improve the accuracy of the hardware description, and to hopefully improve the accuracy of the fuel gauge a bit on all units that don't belong to the latest batch.
The above-mentioned latest batch uses a different 1S lithium battery with a slightly lower capacity, more precisely 9,600 mAh. To make the fuel gauge work reliably on the latest batch, a sample battery would need to be sent to CellWise, to obtain its proprietary battery profile, whose data goes into "cellwise,battery-profile" in the Pinebook Pro board dts. Without that data, the fuel gauge reportedly works unreliably, so changing the design capacity won't have any negative effects on the already unreliable operation of the fuel gauge in the Pinebook Pros that belong to the latest batch.
According to the battery datasheet, its voltage can go as low as 2.75 V while discharging, but it's better to leave the current 3.0 V value in the dts file, because of the associated Pinebook Pro's voltage regulation issues.
[1] https://wiki.pine64.org/index.php/Pinebook_Pro#Battery
[2] https://files.pine64.org/doc/datasheet/pinebook/40110175P%203.8V%2010000mAh%E8%A7%84%E6%A0%BC%E4%B9%A6-14.pdf
--- arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +1 -1
@@ -37,7 +37,7 @@ bat: battery { compatible = "simple-battery"; - charge-full-design-microamp-hours = <9800000>; + charge-full-design-microamp-hours = <10000000>; voltage-max-design-microvolt = <4350000>; voltage-min-design-microvolt = <3000000>; };
Greg Kroah-Hartman
maintainerPATCH 645/695 vfs: fix race between evice_inodes() and find_inode()&iput()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Sun <[email protected]>
commit 88b1afbf0f6b221f6c5bb66cc80cd3b38d696687 upstream.
Hi, all
Recently I noticed a bug[1] in btrfs, after digged it into and I believe it'a race in vfs.
Let's assume there's a inode (ie ino 261) with i_count 1 is called by iput(), and there's a concurrent thread calling generic_shutdown_super().
cpu0: cpu1:iput() // i_count is 1
->spin_lock(inode)
->dec i_count to 0
->iput_final() generic_shutdown_super()
->__inode_add_lru() ->evict_inodes()
// cause some reason[2] ->if (atomic_read(inode->i_count)) continue;
// return before // inode 261 passed the above check
// list_lru_add_obj() // and then schedule out ->spin_unlock()
// note here: the inode 261
// was still at sb list and hash list,
// and I_FREEING|I_WILL_FREE was not been set
btrfs_iget()
// after some function calls
->find_inode()
// found the above inode 261
->spin_lock(inode)
// check I_FREEING|I_WILL_FREE
// and passed
->__iget()
->spin_unlock(inode) // schedule back
->spin_lock(inode)
// check (I_NEW|I_FREEING|I_WILL_FREE) flags,
// passed and set I_FREEINGiput() ->spin_unlock(inode)
->spin_lock(inode) ->evict()
// dec i_count to 0
->iput_final()
->spin_unlock()
->evict()Now, we have two threads simultaneously evicting
the same inode, which may trigger the BUG(inode->i_state & I_CLEAR) statement both within clear_inode() and iput().
To fix the bug, recheck the inode->i_count after holding i_lock. Because in the most scenarios, the first check is valid, and the overhead of spin_lock() can be reduced.
If there is any misunderstanding, please let me know, thanks.
[1]: https://lore.kernel.org/linux-btrfs/[email protected]/
[2]: The reason might be 1. SB_ACTIVE was removed or 2. mapping_shrinkable() return false when I reproduced the bug.
--- fs/inode.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/inode.c +4 -0
@@ -770,6 +770,10 @@ again:continue ;spin_lock (&inode->i_lock); +if (atomic_read (&inode->i_count)) { +spin_unlock (&inode->i_lock); +continue ; + }if (inode->i_state & (I_NEW |I_FREEING |I_WILL_FREE )) {spin_unlock (&inode->i_lock);continue ;
Greg Kroah-Hartman
maintainerPATCH 646/695 netfs: Delete subtree of fs/netfs when netfs module exits
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 3c58a9575e02c2b90a3180007d57105ceaa7c246 upstream.
In netfs_init() or fscache_proc_init(), we create dentry under 'fs/netfs', but in netfs_exit(), we only delete the proc entry of 'fs/netfs' without deleting its subtree. This triggers the following WARNING:
==================================================================remove_proc_entry: removing non-empty directory 'fs/netfs', leaking at least 'requests'
WARNING: CPU: 4 PID: 566 at fs/proc/generic.c:717 remove_proc_entry+0x160/0x1c0 Modules linked in: netfs(-) CPU: 4 UID: 0 PID: 566 Comm: rmmod Not tainted 6.11.0-rc3 #860 RIP: 0010:remove_proc_entry+0x160/0x1c0 Call Trace: <TASK> netfs_exit+0x12/0x620 [netfs] __do_sys_delete_module.isra.0+0x14c/0x2e0 do_syscall_64+0x4b/0x110 entry_SYSCALL_64_after_hwframe+0x76/0x7e ==================================================================
Therefore use remove_proc_subtree() instead of remove_proc_entry() to fix the above problem.
--- fs/netfs/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/netfs/main.c +2 -2
@@ -142,7 +142,7 @@ static int __init netfs_init(void) error_fscache: error_procfile: -remove_proc_entry ("fs/netfs" ,NULL ); +remove_proc_subtree ("fs/netfs" ,NULL ); error_proc:mempool_exit (&netfs_subrequest_pool); error_subreqpool:
@@ -159,7 +159,7 @@ fs_initcall(netfs_init); static void __exit netfs_exit(void) {fscache_exit (); -remove_proc_entry ("fs/netfs" ,NULL ); +remove_proc_subtree ("fs/netfs" ,NULL );mempool_exit (&netfs_subrequest_pool);kmem_cache_destroy (netfs_subrequest_slab);mempool_exit (&netfs_request_pool);
Greg Kroah-Hartman
maintainerPATCH 647/695 fs: Fix file_set_fowner LSM hook inconsistencies
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mickaël Salaün <[email protected]>
commit 26f204380a3c182e5adf1a798db0724d6111b597 upstream.
The fcntl's F_SETOWN command sets the process that handle SIGIO/SIGURG for the related file descriptor. Before this change, the file_set_fowner LSM hook was always called, ignoring the VFS logic which may not actually change the process that handles SIGIO (e.g. TUN, TTY, dnotify), nor update the related UID/EUID.
Moreover, because security_file_set_fowner() was called without lock (e.g. f_owner.lock), concurrent F_SETOWN commands could result to a race condition and inconsistent LSM states (e.g. SELinux's fown_sid) compared to struct fown_struct's UID/EUID.
This change makes sure the LSM states are always in sync with the VFS state by moving the security_file_set_fowner() call close to the UID/EUID updates and using the same f_owner.lock .
Rename f_modown() to __f_setown() to simplify code.
--- fs/fcntl.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
fs/fcntl.c +4 -10
@@ -87,8 +87,8 @@ static int setfl(int fd, struct file * freturn error; } -static void f_modown (struct file *filp,struct pid *pid,enum pid_type type, -int force) +void __f_setown (struct file *filp,struct pid *pid,enum pid_type type, +int force) {write_lock_irq (&filp->f_owner.lock);if (force || !filp->f_owner.pid) {
@@ -98,19 +98,13 @@ static void f_modown(struct file *filp,if (pid) {const struct cred *cred =current_cred (); +security_file_set_fowner (filp); filp->f_owner.uid = cred->uid; filp->f_owner.euid = cred->euid; } }write_unlock_irq (&filp->f_owner.lock); } - -void __f_setown (struct file *filp,struct pid *pid,enum pid_type type, -int force) -{ -security_file_set_fowner (filp); -f_modown (filp, pid, type, force); -}EXPORT_SYMBOL (__f_setown);int f_setown (struct file *filp,int who,int force)
@@ -146,7 +140,7 @@ EXPORT_SYMBOL(f_setown);void f_delown (struct file *filp) { -f_modown (filp,NULL ,PIDTYPE_TGID ,1 ); +__f_setown (filp,NULL ,PIDTYPE_TGID ,1 ); }pid_t f_getown (struct file *filp)
Greg Kroah-Hartman
maintainerPATCH 648/695 nfs: fix memory leak in error path of nfs4_do_reclaim
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
commit 8f6a7c9467eaf39da4c14e5474e46190ab3fb529 upstream.
Commit c77e22834ae9 ("NFSv4: Fix a potential sleep while atomic in nfs4_do_reclaim()") separate out the freeing of the state owners from nfs4_purge_state_owners() and finish it outside the rcu lock. However, the error path is omitted. As a result, the state owners in "freeme" will not be released.
Fix it by adding freeing in the error path.
--- fs/nfs/nfs4state.c | 1 + 1 file changed, 1 insertion(+)
fs/nfs/nfs4state.c +1 -0
@@ -1957,6 +1957,7 @@ restart:set_bit (ops->owner_flag_bit, &sp->so_flags);nfs4_put_state_owner (sp); status =nfs4_recovery_handle_error (clp, status); +nfs4_free_state_owners (&freeme);return (status !=0 ) ? status : -EAGAIN ; }
Greg Kroah-Hartman
maintainerPATCH 649/695 EDAC/igen6: Fix conversion of system address to physical memory address
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <[email protected]>
commit 0ad875f442e95d69a1145a38aabac2fd29984fe3 upstream.
The conversion of system address to physical memory address (as viewed by the memory controller) by igen6_edac is incorrect when the system address is above the TOM (Total amount Of populated physical Memory) for Elkhart Lake and Ice Lake (Neural Network Processor). Fix this conversion.
--- drivers/edac/igen6_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/edac/igen6_edac.c +1 -1
@@ -316,7 +316,7 @@ static u64 ehl_err_addr_to_imc_addr(u64if (igen6_tom <= _4GB)return eaddr + igen6_tolud - _4GB; -if (eaddr < _4GB) +if (eaddr >= igen6_tom)return eaddr + igen6_tolud - igen6_tom;return eaddr;
Greg Kroah-Hartman
maintainerPATCH 650/695 icmp: change the order of rate limits
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
commit 8c2bd38b95f75f3d2a08c93e35303e26d480d24e upstream.
ICMP messages are ratelimited :
After the blamed commits, the two rate limiters are applied in this order:
1) host wide ratelimit (icmp_global_allow())
2) Per destination ratelimit (inetpeer based)
In order to avoid side-channels attacks, we need to apply the per destination check first.
This patch makes the following change :
1) icmp_global_allow() checks if the host wide limit is reached. But credits are not yet consumed. This is deferred to 3)
2) The per destination limit is checked/updated.
This might add a new node in inetpeer tree.
3) icmp_global_consume() consumes tokens if prior operations succeeded.
This means that host wide ratelimit is still effective in keeping inetpeer tree small even under DDOS.
As a bonus, I removed icmp_global.lock as the fast path can use a lock-free operation.
--- include/net/ip.h | 2 + net/ipv4/icmp.c | 103 +++++++++++++++++++++++++++++-------------------------- net/ipv6/icmp.c | 28 +++++++++----- 3 files changed, 76 insertions(+), 57 deletions(-)
include/net/ip.h +2 -0
@@ -795,6 +795,8 @@ static inline void ip_cmsg_recv(struct m }bool icmp_global_allow (void ); +void icmp_global_consume (void ); +extern int sysctl_icmp_msgs_per_sec;extern int sysctl_icmp_msgs_burst;
net/ipv4/icmp.c +56 -47
199 lines not on this page · raw message
net/ipv6/icmp.c +18 -10
@@ -175,14 +175,16 @@ static bool icmpv6_mask_allow(struct netreturn false; } -static bool icmpv6_global_allow (struct net *net,int type) +static bool icmpv6_global_allow (struct net *net,int type, +bool *apply_ratelimit) {if (icmpv6_mask_allow (net, type))return true; -if (icmp_global_allow ()) +if (icmp_global_allow ()) { + *apply_ratelimit = true;return true; - + }__ICMP_INC_STATS (net,ICMP_MIB_RATELIMITGLOBAL );return false; }
@@ -191,13 +193,13 @@ static bool icmpv6_global_allow(struct n* Check the ICMP output rate limit */ static bool icmpv6_xrlim_allow (struct sock *sk,u8 type, -struct flowi6 *fl6) +struct flowi6 *fl6,bool apply_ratelimit) {struct net *net =sock_net (sk);struct dst_entry *dst;bool res = false; -if (icmpv6_mask_allow (net, type)) +if (!apply_ratelimit)return true;/*
@@ -228,6 +230,8 @@ static bool icmpv6_xrlim_allow(struct soif (!res)__ICMP6_INC_STATS (net,ip6_dst_idev (dst),ICMP6_MIB_RATELIMITHOST ); +else +icmp_global_consume ();dst_release (dst);return res; }
@@ -452,6 +456,7 @@ void icmp6_send(struct sk_buff *skb, u8struct net *net;struct ipv6_pinfo *np;const struct in6_addr *saddr =NULL ; +bool apply_ratelimit = false;struct dst_entry *dst;struct icmp6hdr tmp_hdr;struct flowi6 fl6;
@@ -533,11 +538,12 @@ void icmp6_send(struct sk_buff *skb, u8return ; } -/* Needed by both icmp_global_allow and icmpv6_xmit_lock */ +/* Needed by both icmpv6_global_allow and icmpv6_xmit_lock */ local_bh_disable ();/* Check global sysctl_icmp_msgs_per_sec ratelimit */ -if (!(skb->dev->flags &IFF_LOOPBACK ) && !icmpv6_global_allow (net, type)) +if (!(skb->dev->flags &IFF_LOOPBACK ) && + !icmpv6_global_allow (net, type, &apply_ratelimit)) goto out_bh_enable;mip6_addr_swap (skb, parm);
@@ -575,7 +581,7 @@ void icmp6_send(struct sk_buff *skb, u8 np =inet6_sk (sk); -if (!icmpv6_xrlim_allow (sk, type, &fl6)) +if (!icmpv6_xrlim_allow (sk, type, &fl6, apply_ratelimit)) goto out; tmp_hdr.icmp6_type = type;
@@ -717,6 +723,7 @@ static enum skb_drop_reason icmpv6_echo_struct ipv6_pinfo *np;const struct in6_addr *saddr =NULL ;struct icmp6hdr *icmph =icmp6_hdr (skb); +bool apply_ratelimit = false;struct icmp6hdr tmp_hdr;struct flowi6 fl6;struct icmpv6_msg msg;
@@ -781,8 +788,9 @@ static enum skb_drop_reason icmpv6_echo_ goto out;/* Check the ratelimit */ -if ((!(skb->dev->flags &IFF_LOOPBACK ) && !icmpv6_global_allow (net,ICMPV6_ECHO_REPLY )) || - !icmpv6_xrlim_allow (sk,ICMPV6_ECHO_REPLY , &fl6)) +if ((!(skb->dev->flags &IFF_LOOPBACK ) && + !icmpv6_global_allow (net,ICMPV6_ECHO_REPLY , &apply_ratelimit)) || + !icmpv6_xrlim_allow (sk,ICMPV6_ECHO_REPLY , &fl6, apply_ratelimit)) goto out_dst_release; idev =__in6_dev_get (skb->dev);
Greg Kroah-Hartman
maintainerPATCH 651/695 eventpoll: Annotate data-race of busy_poll_usecs
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Karsten <[email protected]>
commit b9ca079dd6b09e08863aa998edf5c47597806c05 upstream.
A struct eventpoll's busy_poll_usecs field can be modified via a user ioctl at any time. All reads of this field should be annotated with READ_ONCE.
--- fs/eventpoll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/eventpoll.c +1 -1
@@ -420,7 +420,7 @@ static bool busy_loop_ep_timeout(unsignestatic bool ep_busy_loop_on (struct eventpoll *ep) { -return !!ep->busy_poll_usecs ||net_busy_loop_on (); +return !!READ_ONCE (ep->busy_poll_usecs) ||net_busy_loop_on (); }static bool ep_busy_loop_end (void *p,unsigned long start_time)
Greg Kroah-Hartman
maintainerPATCH 652/695 md: Dont flush sync_work in md_write_start()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai <[email protected]>
commit 86ad4cda79e0dade87d4bb0d32e1fe541d4a63e8 upstream.
Because flush sync_work may trigger mddev_suspend() if there are spares, and this should never be done in IO path because mddev_suspend() is used to wait for IO.
This problem is found by code review.
--- drivers/md/md.c | 1 - 1 file changed, 1 deletion(-)
drivers/md/md.c +0 -1
@@ -8668,7 +8668,6 @@ void md_write_start(struct mddev *mddev,BUG_ON (mddev->ro ==MD_RDONLY );if (mddev->ro ==MD_AUTO_READ ) {/* need to switch to read/write */ -flush_work (&mddev->sync_work); mddev->ro =MD_RDWR ;set_bit (MD_RECOVERY_NEEDED , &mddev->recovery);md_wakeup_thread (mddev->thread);
Greg Kroah-Hartman
maintainerPATCH 653/695 cpuidle: riscv-sbi: Use scoped device node handling to fix missing of_node_put
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit a309320ddbac6b1583224fcb6bacd424bcf8637f upstream.
Two return statements in sbi_cpuidle_dt_init_states() did not drop the OF node reference count. Solve the issue and simplify entire error handling with scoped/cleanup.h.
--- drivers/cpuidle/cpuidle-riscv-sbi.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-)
drivers/cpuidle/cpuidle-riscv-sbi.c +7 -14
@@ -8,6 +8,7 @@#define pr_fmt (fmt) "cpuidle-riscv-sbi: " fmt +#include <linux/cleanup.h> #include <linux/cpuhotplug.h> #include <linux/cpuidle.h> #include <linux/cpumask.h>
@@ -236,19 +237,16 @@ static int sbi_cpuidle_dt_init_states(st {struct sbi_cpuidle_data *data =per_cpu_ptr (&sbi_cpuidle_data, cpu);struct device_node *state_node; -struct device_node *cpu_node;u32 *states;int i, ret; - cpu_node =of_cpu_device_node_get (cpu); + struct device_node *cpu_node __free(device_node) = of_cpu_device_node_get(cpu);if (!cpu_node)return -ENODEV ; states =devm_kcalloc (dev, state_count,sizeof (*states),GFP_KERNEL ); -if (!states) { - ret = -ENOMEM ; - goto fail; - } +if (!states) +return -ENOMEM ;/* Parse SBI specific details from state DT nodes */ for (i =1 ; i < state_count; i++) {
@@ -264,10 +262,8 @@ static int sbi_cpuidle_dt_init_states(stpr_debug ("sbi-state %#x index %d\n" , states[i], i); } -if (i != state_count) { - ret = -ENODEV ; - goto fail; - } +if (i != state_count) +return -ENODEV ;/* Initialize optional data, used for the hierarchical topology. */ ret =sbi_dt_cpu_init_topology (drv, data, state_count, cpu);
@@ -277,10 +273,7 @@ static int sbi_cpuidle_dt_init_states(st/* Store states in the per-cpu struct. */ data->states = states; -fail: -of_node_put (cpu_node); - -return ret; +return 0 ; }static void sbi_cpuidle_deinit_cpu (int cpu)
Greg Kroah-Hartman
maintainerPATCH 654/695 padata: use integer wrap around to prevent deadlock on seq_nr overflow
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: VanGiang Nguyen <[email protected]>
commit 9a22b2812393d93d84358a760c347c21939029a6 upstream.
When submitting more than 2^32 padata objects to padata_do_serial, the current sorting implementation incorrectly sorts padata objects with overflowed seq_nr, causing them to be placed before existing objects in the reorder list. This leads to a deadlock in the serialization process as padata_find_next cannot match padata->seq_nr and pd->processed because the padata instance with overflowed seq_nr will be selected next.
To fix this, we use an unsigned integer wrap around to correctly sort padata objects in scenarios with integer overflow.
--- kernel/padata.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/padata.c +2 -1
@@ -404,7 +404,8 @@ void padata_do_serial(struct padata_priv/* Sort in ascending order of sequence number. */ list_for_each_prev (pos, &reorder->list) { cur = list_entry(pos, struct padata_priv, list); -if (cur->seq_nr < padata->seq_nr) +/* Compare by difference to consider integer wrap around */ +if ((signed int )(cur->seq_nr - padata->seq_nr) <0 )break ; }list_add (&padata->list, pos);
Greg Kroah-Hartman
maintainerPATCH 655/695 lsm: add the inode_free_security_rcu() LSM implementation hook
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Moore <[email protected]>
commit 63dff3e48871b0583be5032ff8fb7260c349a18c upstream.
The LSM framework has an existing inode_free_security() hook which is used by LSMs that manage state associated with an inode, but due to the use of RCU to protect the inode, special care must be taken to ensure that the LSMs do not fully release the inode state until it is safe from a RCU perspective.
This patch implements a new inode_free_security_rcu() implementation hook which is called when it is safe to free the LSM's internal inode state. Unfortunately, this new hook does not have access to the inode itself as it may already be released, so the existing inode_free_security() hook is retained for those LSMs which require access to the inode.
--- include/linux/lsm_hook_defs.h | 1 + security/integrity/ima/ima.h | 2 +- security/integrity/ima/ima_iint.c | 20 ++++++++------------ security/integrity/ima/ima_main.c | 2 +- security/landlock/fs.c | 9 ++++++--- security/security.c | 32 ++++++++++++++++---------------- 6 files changed, 33 insertions(+), 33 deletions(-)
include/linux/lsm_hook_defs.h +1 -0
@@ -114,6 +114,7 @@ LSM_HOOK(int, 0, path_notify, const stru unsigned int obj_type) LSM_HOOK(int, 0, inode_alloc_security, struct inode *inode) LSM_HOOK(void, LSM_RET_VOID, inode_free_security, struct inode *inode) +LSM_HOOK(void, LSM_RET_VOID, inode_free_security_rcu, void *inode_security) LSM_HOOK(int, -EOPNOTSUPP, inode_init_security, struct inode *inode, struct inode *dir, const struct qstr *qstr, struct xattr *xattrs, int *xattr_count)
security/integrity/ima/ima.h +1 -1
@@ -223,7 +223,7 @@ static inline void ima_inode_set_iint(costruct ima_iint_cache *ima_iint_find (struct inode *inode);struct ima_iint_cache *ima_inode_get (struct inode *inode); -void ima_inode_free (struct inode *inode); +void ima_inode_free_rcu (void *inode_security);void __init ima_iintcache_init (void );extern const int read_idmap[];
security/integrity/ima/ima_iint.c +8 -12
@@ -109,22 +109,18 @@ struct ima_iint_cache *ima_inode_get(str }/** -* ima_inode_free - Called on inode free -* @inode: Pointer to the inode +* ima_inode_free_rcu - Called to free an inode via a RCU callback +* @inode_security: The inode->i_security pointer * -* Free the iint associated with an inode. +* Free the IMA data associated with an inode. */ -void ima_inode_free (struct inode *inode) +void ima_inode_free_rcu (void *inode_security) { -struct ima_iint_cache *iint; +struct ima_iint_cache **iint_p = inode_security + ima_blob_sizes.lbs_inode; -if (!IS_IMA (inode)) -return ; - - iint =ima_iint_find (inode); -ima_inode_set_iint (inode,NULL ); - -ima_iint_free (iint); +/* *iint_p should be NULL if !IS_IMA(inode) */ +if (*iint_p) +ima_iint_free (*iint_p); }static void ima_iint_init_once (void *foo)
security/integrity/ima/ima_main.c +1 -1
@@ -1193,7 +1193,7 @@ static struct security_hook_list ima_hoo #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS LSM_HOOK_INIT(kernel_module_request, ima_kernel_module_request), #endif - LSM_HOOK_INIT(inode_free_security, ima_inode_free), + LSM_HOOK_INIT(inode_free_security_rcu, ima_inode_free_rcu), }; static const struct lsm_id ima_lsmid = {
security/landlock/fs.c +6 -3
@@ -1207,13 +1207,16 @@ static int current_check_refer_path(stru/* Inode hooks */ -static void hook_inode_free_security (struct inode *const inode) +static void hook_inode_free_security_rcu (void *inode_security) { +struct landlock_inode_security *inode_sec; +/* * All inodes must already have been untied from their object by * release_inode() or hook_sb_delete(). */ -WARN_ON_ONCE (landlock_inode (inode)->object); + inode_sec = inode_security + landlock_blob_sizes.lbs_inode; +WARN_ON_ONCE (inode_sec->object); }/* Super-block hooks */
@@ -1637,7 +1640,7 @@ static int hook_file_ioctl_compat(struct }static struct security_hook_list landlock_hooks[]__ro_after_init = { -LSM_HOOK_INIT (inode_free_security, hook_inode_free_security), +LSM_HOOK_INIT (inode_free_security_rcu, hook_inode_free_security_rcu),LSM_HOOK_INIT (sb_delete, hook_sb_delete),LSM_HOOK_INIT (sb_mount, hook_sb_mount),
security/security.c +16 -16
@@ -1596,9 +1596,8 @@ int security_inode_alloc(struct inode *istatic void inode_free_by_rcu (struct rcu_head *head) { -/* -* The rcu head is at the start of the inode blob -*/ +/* The rcu head is at the start of the inode blob */ +call_void_hook (inode_free_security_rcu, head);kmem_cache_free (lsm_inode_cache, head); }
@@ -1606,23 +1605,24 @@ static void inode_free_by_rcu(struct rcu* security_inode_free() - Free an inode's LSM blob * @inode: the inode * -* Deallocate the inode security structure and set @inode->i_security to NULL. +* Release any LSM resources associated with @inode, although due to the +* inode's RCU protections it is possible that the resources will not be +* fully released until after the current RCU grace period has elapsed. +* +* It is important for LSMs to note that despite being present in a call to +* security_inode_free(), @inode may still be referenced in a VFS path walk +* and calls to security_inode_permission() may be made during, or after, +* a call to security_inode_free(). For this reason the inode->i_security +* field is released via a call_rcu() callback and any LSMs which need to +* retain inode state for use in security_inode_permission() should only +* release that state in the inode_free_security_rcu() LSM hook callback. */ void security_inode_free (struct inode *inode) {call_void_hook (inode_free_security, inode); -/* -* The inode may still be referenced in a path walk and -* a call to security_inode_permission() can be made -* after inode_free_security() is called. Ideally, the VFS -* wouldn't do this, but fixing that is a much harder -* job. For now, simply free the i_security via RCU, and -* leave the current inode->i_security pointer intact. -* The inode will be freed after the RCU grace period too. -*/ -if (inode->i_security) -call_rcu ((struct rcu_head *)inode->i_security, - inode_free_by_rcu); +if (!inode->i_security) +return ; +call_rcu ((struct rcu_head *)inode->i_security, inode_free_by_rcu); }/**
Greg Kroah-Hartman
maintainerPATCH 656/695 spi: fspi: involve lut_num for struct nxp_fspi_devtype_data
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haibo Chen <[email protected]>
commit 190b7e2efb1ed8435fc7431d9c7a2447d05d5066 upstream.
The flexspi on different SoCs may have different number of LUTs. So involve lut_num in nxp_fspi_devtype_data to make distinguish. This patch prepare for the adding of imx8ulp.
--- drivers/spi/spi-nxp-fspi.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-)
drivers/spi/spi-nxp-fspi.c +25 -19
@@ -57,13 +57,6 @@#include <linux/spi/spi.h> #include <linux/spi/spi-mem.h> -/* -* The driver only uses one single LUT entry, that is updated on -* each call of exec_op(). Index 0 is preset at boot with a basic -* read operation, so let's use the last entry (31). -*/ -#define SEQID_LUT 31 -/* Registers used by the driver */ #define FSPI_MCR0 0x00#define FSPI_MCR0_AHB_TIMEOUT (x) ((x) << 24)
@@ -263,9 +256,6 @@#define FSPI_TFDR 0x180#define FSPI_LUT_BASE 0x200 -#define FSPI_LUT_OFFSET (SEQID_LUT * 4 * 4) -#define FSPI_LUT_REG (idx) \ - (FSPI_LUT_BASE + FSPI_LUT_OFFSET + (idx) * 4)/* register map end */
@@ -341,6 +331,7 @@ struct nxp_fspi_devtype_data {unsigned int txfifo;unsigned int ahb_buf_size;unsigned int quirks; +unsigned int lut_num;bool little_endian; };
@@ -349,6 +340,7 @@ static struct nxp_fspi_devtype_data lx21 .txfifo = SZ_1K, /* (128 * 64 bits) */ .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ .quirks = 0, + .lut_num = 32, .little_endian = true, /* little-endian */ };
@@ -357,6 +349,7 @@ static struct nxp_fspi_devtype_data imx8 .txfifo = SZ_1K, /* (128 * 64 bits) */ .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ .quirks = 0, + .lut_num = 32, .little_endian = true, /* little-endian */ };
@@ -365,6 +358,7 @@ static struct nxp_fspi_devtype_data imx8 .txfifo = SZ_1K, /* (128 * 64 bits) */ .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ .quirks = 0, + .lut_num = 32, .little_endian = true, /* little-endian */ };
@@ -373,6 +367,7 @@ static struct nxp_fspi_devtype_data imx8 .txfifo = SZ_1K, /* (128 * 64 bits) */ .ahb_buf_size = SZ_2K, /* (256 * 64 bits) */ .quirks = FSPI_QUIRK_USE_IP_ONLY, + .lut_num = 32, .little_endian = true, /* little-endian */ };
@@ -544,6 +539,8 @@ static void nxp_fspi_prepare_lut(structvoid __iomem *base = f->iobase;u32 lutval[4 ] = {};int lutidx =1 , i; +u32 lut_offset = (f->devtype_data->lut_num -1 ) *4 *4 ; +u32 target_lut_reg;/* cmd */ lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth),
@@ -588,8 +585,10 @@ static void nxp_fspi_prepare_lut(structfspi_writel (f,FSPI_LCKER_UNLOCK , f->iobase +FSPI_LCKCR );/* fill LUT */ -for (i =0 ; i <ARRAY_SIZE (lutval); i++) -fspi_writel (f, lutval[i], base +FSPI_LUT_REG (i)); +for (i =0 ; i <ARRAY_SIZE (lutval); i++) { + target_lut_reg =FSPI_LUT_BASE + lut_offset + i *4 ; +fspi_writel (f, lutval[i], base + target_lut_reg); + }dev_dbg (f->dev,"CMD[%02x] lutval[0:%08x 1:%08x 2:%08x 3:%08x], size: 0x%08x\n" , op->cmd.opcode, lutval[0 ], lutval[1 ], lutval[2 ], lutval[3 ], op->data.nbytes);
@@ -876,7 +875,7 @@ static int nxp_fspi_do_op(struct nxp_fspvoid __iomem *base = f->iobase;int seqnum =0 ;int err =0 ; -u32 reg; +u32 reg, seqid_lut; reg =fspi_readl (f, base +FSPI_IPRXFCR );/* invalid RXFIFO first */
@@ -892,8 +891,9 @@ static int nxp_fspi_do_op(struct nxp_fsp* the LUT at each exec_op() call. And also specify the DATA * length, since it's has not been specified in the LUT. */ + seqid_lut = f->devtype_data->lut_num -1 ;fspi_writel (f, op->data.nbytes | - (SEQID_LUT <<FSPI_IPCR1_SEQID_SHIFT ) | + (seqid_lut <<FSPI_IPCR1_SEQID_SHIFT ) | (seqnum <<FSPI_IPCR1_SEQNUM_SHIFT ), base +FSPI_IPCR1 );
@@ -1017,7 +1017,7 @@ static int nxp_fspi_default_setup(struct {void __iomem *base = f->iobase;int ret, i; -u32 reg; +u32 reg, seqid_lut;/* disable and unprepare clock to avoid glitch pass to controller */ nxp_fspi_clk_disable_unprep (f);
@@ -1092,11 +1092,17 @@ static int nxp_fspi_default_setup(structfspi_writel (f, reg, base +FSPI_FLSHB1CR1 );fspi_writel (f, reg, base +FSPI_FLSHB2CR1 ); +/* +* The driver only uses one single LUT entry, that is updated on +* each call of exec_op(). Index 0 is preset at boot with a basic +* read operation, so let's use the last entry. +*/ + seqid_lut = f->devtype_data->lut_num -1 ;/* AHB Read - Set lut sequence ID for all CS. */ -fspi_writel (f,SEQID_LUT , base +FSPI_FLSHA1CR2 ); -fspi_writel (f,SEQID_LUT , base +FSPI_FLSHA2CR2 ); -fspi_writel (f,SEQID_LUT , base +FSPI_FLSHB1CR2 ); -fspi_writel (f,SEQID_LUT , base +FSPI_FLSHB2CR2 ); +fspi_writel (f, seqid_lut, base +FSPI_FLSHA1CR2 ); +fspi_writel (f, seqid_lut, base +FSPI_FLSHA2CR2 ); +fspi_writel (f, seqid_lut, base +FSPI_FLSHB1CR2 ); +fspi_writel (f, seqid_lut, base +FSPI_FLSHB2CR2 ); f->selected =-1 ;
Greg Kroah-Hartman
maintainerPATCH 657/695 dt-bindings: spi: nxp-fspi: add imx8ulp support
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haibo Chen <[email protected]>
commit 12736adc43b7cd5cb83f274f8f37b0f89d107c97 upstream.
The flexspi on imx8ulp only has 16 number of LUTs, it is different with flexspi on other imx SoC which has 32 number of LUTs.
--- Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml +1 -0
@@ -21,6 +21,7 @@ properties: - nxp,imx8mm-fspi - nxp,imx8mp-fspi - nxp,imx8qxp-fspi + - nxp,imx8ulp-fspi - nxp,lx2160a-fspi - items: - enum:
Greg Kroah-Hartman
maintainerPATCH 658/695 ARM: dts: imx6ul-geam: fix fsl,pins property in tscgrp pinctrl
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 1b0e32753d8550908dff8982410357b5114be78c upstream.
The property is "fsl,pins", not "fsl,pin". Wrong property means the pin configuration was not applied. Fixes dtbs_check warnings:
imx6ul-geam.dtb: pinctrl@20e0000: tscgrp: 'fsl,pins' is a required property imx6ul-geam.dtb: pinctrl@20e0000: tscgrp: 'fsl,pin' does not match any of the regexes: 'pinctrl-[0-9]+'
--- arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts +1 -1
@@ -365,7 +365,7 @@ }; pinctrl_tsc: tscgrp { - fsl,pin = < + fsl,pins = < MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0 MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0 MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
Greg Kroah-Hartman
maintainerPATCH 659/695 ARM: dts: imx6ull-seeed-npi: fix fsl,pins property in tscgrp pinctrl
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 3dedd4889cfc2851444a1f7626b293c0bfd1e42c upstream.
The property is "fsl,pins", not "fsl,pin". Wrong property means the pin configuration was not applied. Fixes dtbs_check warnings:
imx6ull-seeed-npi-dev-board-emmc.dtb: pinctrl@20e0000: uart1grp: 'fsl,pins' is a required property imx6ull-seeed-npi-dev-board-emmc.dtb: pinctrl@20e0000: uart1grp: 'fsl,pin' does not match any of the regexes: 'pinctrl-[0-9]+'
--- arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi +6 -6
@@ -339,14 +339,14 @@ }; pinctrl_uart1: uart1grp { - fsl,pin = < + fsl,pins = < MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1 MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1 >; }; pinctrl_uart2: uart2grp { - fsl,pin = < + fsl,pins = < MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1 MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1 MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS 0x1b0b1
@@ -355,7 +355,7 @@ }; pinctrl_uart3: uart3grp { - fsl,pin = < + fsl,pins = < MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0x1b0b1 MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0x1b0b1 MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS 0x1b0b1
@@ -364,21 +364,21 @@ }; pinctrl_uart4: uart4grp { - fsl,pin = < + fsl,pins = < MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX 0x1b0b1 MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX 0x1b0b1 >; }; pinctrl_uart5: uart5grp { - fsl,pin = < + fsl,pins = < MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX 0x1b0b1 MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX 0x1b0b1 >; }; pinctrl_usb_otg1_id: usbotg1idgrp { - fsl,pin = < + fsl,pins = < MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059 >; };
Greg Kroah-Hartman
maintainerPATCH 660/695 tools/nolibc: include arch.h from string.h
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit 6ea2987c9a7b6c5f37d08a3eaa664c9ff7467670 upstream.
string.h tests for the macros NOLIBC_ARCH_HAS_$FUNC to use the architecture-optimized function variants.
However if string.h is included before arch.h header then that check does not work, leading to duplicate function definitions.
--- tools/include/nolibc/string.h | 1 + 1 file changed, 1 insertion(+)
tools/include/nolibc/string.h +1 -0
@@ -7,6 +7,7 @@#ifndef _NOLIBC_STRING_H#define _NOLIBC_STRING_H +#include "arch.h" #include "std.h" static void *malloc (size_t len);
Greg Kroah-Hartman
maintainerPATCH 661/695 soc: versatile: realview: fix memory leak during device remove
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 1c4f26a41f9d052f334f6ae629e01f598ed93508 ]
If device is unbound, the memory allocated for soc_dev_attr should be freed to prevent leaks.
Stable-dep-of: c774f2564c00 ("soc: versatile: realview: fix soc_dev leak during device remove")
--- drivers/soc/versatile/soc-realview.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/soc/versatile/soc-realview.c +3 -4
@@ -93,7 +93,7 @@ static int realview_soc_probe(struct platform_device *pdev)if (IS_ERR (syscon_regmap))return PTR_ERR (syscon_regmap); - soc_dev_attr =kzalloc (sizeof (*soc_dev_attr),GFP_KERNEL ); + soc_dev_attr =devm_kzalloc (&pdev->dev,sizeof (*soc_dev_attr),GFP_KERNEL );if (!soc_dev_attr)return -ENOMEM ;
@@ -106,10 +106,9 @@ static int realview_soc_probe(struct platform_device *pdev) soc_dev_attr->family ="Versatile" ; soc_dev_attr->custom_attr_group = realview_groups[0 ]; soc_dev =soc_device_register (soc_dev_attr); -if (IS_ERR (soc_dev)) { -kfree (soc_dev_attr); +if (IS_ERR (soc_dev))return -ENODEV ; - } + ret =regmap_read (syscon_regmap,REALVIEW_SYS_ID_OFFSET , &realview_coreid);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 662/695 soc: versatile: realview: fix soc_dev leak during device remove
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit c774f2564c0086c23f5269fd4691f233756bf075 ]
If device is unbound, the soc_dev should be unregistered to prevent memory leak.
--- drivers/soc/versatile/soc-realview.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/soc/versatile/soc-realview.c +13 -0
@@ -4,6 +4,7 @@* * Author: Linus Walleij <[email protected]> */ +#include <linux/device.h> #include <linux/init.h> #include <linux/io.h> #include <linux/slab.h>
@@ -81,6 +82,13 @@ static struct attribute *realview_attrs[] = {ATTRIBUTE_GROUPS (realview); +static void realview_soc_socdev_release (void *data) +{ +struct soc_device *soc_dev = data; + +soc_device_unregister (soc_dev); +} +static int realview_soc_probe (struct platform_device *pdev) {struct regmap *syscon_regmap;
@@ -109,6 +117,11 @@ static int realview_soc_probe(struct platform_device *pdev)if (IS_ERR (soc_dev))return -ENODEV ; + ret =devm_add_action_or_reset (&pdev->dev, realview_soc_socdev_release, + soc_dev); +if (ret) +return ret; + ret =regmap_read (syscon_regmap,REALVIEW_SYS_ID_OFFSET , &realview_coreid);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 663/695 usb: typec: ucsi: Call CANCEL from single location
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <[email protected]>
[ Upstream commit 4f322657ade1b784bb2b1ba8761469ae87520681 ]
The command cancellation can be done right after detecting that the PPM is busy. There is no need to do it separately in ucsi_read_error() and ucsi_send_command_common().
Stable-dep-of: 7fa6b25dfb43 ("usb: typec: ucsi: Fix busy loop on ASUS VivoBooks")
--- drivers/usb/typec/ucsi/ucsi.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
drivers/usb/typec/ucsi/ucsi.c +4 -13
@@ -115,7 +115,7 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,return ret;if (*cci &UCSI_CCI_BUSY ) -return -EBUSY ; +return ucsi_run_command (ucsi,UCSI_CANCEL , cci,NULL ,0 , false) ?: -EBUSY ;if (!(*cci &UCSI_CCI_COMMAND_COMPLETE ))return -EIO ;
@@ -148,15 +148,7 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)int ret; command =UCSI_GET_ERROR_STATUS |UCSI_CONNECTOR_NUMBER (connector_num); - ret =ucsi_run_command (ucsi, command, &cci, - &error,sizeof (error), false); - -if (cci &UCSI_CCI_BUSY ) { - ret =ucsi_run_command (ucsi,UCSI_CANCEL , &cci,NULL ,0 , false); - -return ret ? ret : -EBUSY ; - } - + ret =ucsi_run_command (ucsi, command, &cci, &error,sizeof (error), false);if (ret <0 )return ret;
@@ -238,9 +230,8 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd,mutex_lock (&ucsi->ppm_lock); ret =ucsi_run_command (ucsi, cmd, &cci, data, size, conn_ack); -if (cci &UCSI_CCI_BUSY ) - ret =ucsi_run_command (ucsi,UCSI_CANCEL , &cci,NULL ,0 , false) ?: -EBUSY ; -else if (cci &UCSI_CCI_ERROR ) + +if (cci &UCSI_CCI_ERROR ) ret =ucsi_read_error (ucsi, connector_num);mutex_unlock (&ucsi->ppm_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 664/695 usb: typec: ucsi: Fix busy loop on ASUS VivoBooks
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian A. Ehrhardt <[email protected]>
[ Upstream commit 7fa6b25dfb43dafc0e16510e2fcfd63634fc95c2 ]
If the busy indicator is set, all other fields in CCI should be clear according to the spec. However, some UCSI implementations do not follow this rule and report bogus data in CCI along with the busy indicator. Ignore the contents of CCI if the busy indicator is set.
If a command timeout is hit it is possible that the EVENT_PENDING bit is cleared while connector work is still scheduled which can cause the EVENT_PENDING bit to go out of sync with scheduled connector work. Check and set the EVENT_PENDING bit on entry to ucsi_handle_connector_change() to fix this.
Finally, check UCSI_CCI_BUSY before the return code of ->sync_control. This ensures that the command is cancelled even if ->sync_control returns an error (most likely -ETIMEDOUT).
--- drivers/usb/typec/ucsi/ucsi.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/usb/typec/ucsi/ucsi.c +12 -6
@@ -38,6 +38,10 @@void ucsi_notify_common (struct ucsi *ucsi,u32 cci) { +/* Ignore bogus data in CCI if busy indicator is set. */ +if (cci &UCSI_CCI_BUSY ) +return ; +if (UCSI_CCI_CONNECTOR (cci))ucsi_connector_change (ucsi,UCSI_CCI_CONNECTOR (cci));
@@ -107,15 +111,13 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, size =clamp (size,0 ,16 ); ret = ucsi->ops->sync_control (ucsi, command); -if (ret) -return ret; - - ret = ucsi->ops->read_cci (ucsi, cci); -if (ret) -return ret; +if (ucsi->ops->read_cci (ucsi, cci)) +return -EIO ;if (*cci &UCSI_CCI_BUSY )return ucsi_run_command (ucsi,UCSI_CANCEL , cci,NULL ,0 , false) ?: -EBUSY ; +if (ret) +return ret;if (!(*cci &UCSI_CCI_COMMAND_COMPLETE ))return -EIO ;
@@ -1240,6 +1242,10 @@ static void ucsi_handle_connector_change(struct work_struct *work)mutex_lock (&con->lock); +if (!test_and_set_bit (EVENT_PENDING , &ucsi->flags)) +dev_err_once (ucsi->dev,"%s entered without EVENT_PENDING\n" , + __func__); + command =UCSI_GET_CONNECTOR_STATUS |UCSI_CONNECTOR_NUMBER (con->num); ret = ucsi_send_command_common(ucsi, command, &con->status,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 665/695 soc: qcom: geni-se: add GP_LENGTH/IRQ_EN_SET/IRQ_EN_CLEAR registers
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
[ Upstream commit b03ffc76b83c1a7d058454efbcf1bf0e345ef1c2 ]
For UART devices the M_GP_LENGTH is the TX word count. For other devices this is the transaction word count.
For UART devices the S_GP_LENGTH is the RX word count.
The IRQ_EN set/clear registers allow you to set or clear bits in the IRQ_EN register without needing a read-modify-write.
Stable-dep-of: cc4a0e5754a1 ("serial: qcom-geni: fix console corruption")
--- include/linux/soc/qcom/geni-se.h | 9 +++++++++ 1 file changed, 9 insertions(+)
include/linux/soc/qcom/geni-se.h +9 -0
@@ -88,11 +88,15 @@ struct geni_se {#define SE_GENI_M_IRQ_STATUS 0x610#define SE_GENI_M_IRQ_EN 0x614#define SE_GENI_M_IRQ_CLEAR 0x618 +#define SE_GENI_M_IRQ_EN_SET 0x61c +#define SE_GENI_M_IRQ_EN_CLEAR 0x620#define SE_GENI_S_CMD0 0x630#define SE_GENI_S_CMD_CTRL_REG 0x634#define SE_GENI_S_IRQ_STATUS 0x640#define SE_GENI_S_IRQ_EN 0x644#define SE_GENI_S_IRQ_CLEAR 0x648 +#define SE_GENI_S_IRQ_EN_SET 0x64c +#define SE_GENI_S_IRQ_EN_CLEAR 0x650#define SE_GENI_TX_FIFOn 0x700#define SE_GENI_RX_FIFOn 0x780#define SE_GENI_TX_FIFO_STATUS 0x800
@@ -101,6 +105,8 @@ struct geni_se {#define SE_GENI_RX_WATERMARK_REG 0x810#define SE_GENI_RX_RFR_WATERMARK_REG 0x814#define SE_GENI_IOS 0x908 +#define SE_GENI_M_GP_LENGTH 0x910 +#define SE_GENI_S_GP_LENGTH 0x914#define SE_DMA_TX_IRQ_STAT 0xc40#define SE_DMA_TX_IRQ_CLR 0xc44#define SE_DMA_TX_FSM_RST 0xc58
@@ -234,6 +240,9 @@ struct geni_se {#define IO2_DATA_IN BIT(1)#define RX_DATA_IN BIT(0) +/* SE_GENI_M_GP_LENGTH and SE_GENI_S_GP_LENGTH fields */ +#define GP_LENGTH GENMASK(31, 0) +/* SE_DMA_TX_IRQ_STAT Register fields */ #define TX_DMA_DONE BIT(0)#define TX_EOT BIT(1)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 666/695 serial: qcom-geni: fix arg types for qcom_geni_serial_poll_bit()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
[ Upstream commit c2eaf5e01275ae13f1ec5b1434f6c49cfff57430 ]
The "offset" passed in should be unsigned since it's always a positive offset from our memory mapped IO.
The "field" should be u32 since we're anding it with a 32-bit value read from the device.
Stable-dep-of: cc4a0e5754a1 ("serial: qcom-geni: fix console corruption")
--- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/qcom_geni_serial.c +1 -1
@@ -266,7 +266,7 @@ static bool qcom_geni_serial_secondary_active(struct uart_port *uport) }static bool qcom_geni_serial_poll_bit (struct uart_port *uport, -int offset,int field,bool set) +unsigned int offset,u32 field,bool set) {u32 reg;struct qcom_geni_serial_port *port;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 667/695 serial: qcom-geni: introduce qcom_geni_serial_poll_bitfield()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
[ Upstream commit b26d1ad1221273c88c2c4f5b4080338b8ca23859 ]
With a small modification the qcom_geni_serial_poll_bit() function could be used to poll more than just a single bit. Let's generalize it. We'll make the qcom_geni_serial_poll_bit() into just a wrapper of the general function.
Stable-dep-of: cc4a0e5754a1 ("serial: qcom-geni: fix console corruption")
--- drivers/tty/serial/qcom_geni_serial.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +9 -3
@@ -265,8 +265,8 @@ static bool qcom_geni_serial_secondary_active(struct uart_port *uport)return readl (uport->membase +SE_GENI_STATUS ) &S_GENI_CMD_ACTIVE ; } -static bool qcom_geni_serial_poll_bit (struct uart_port *uport, -unsigned int offset,u32 field,bool set) +static bool qcom_geni_serial_poll_bitfield (struct uart_port *uport, +unsigned int offset,u32 field,u32 val) {u32 reg;struct qcom_geni_serial_port *port;
@@ -286,7 +286,7 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport, timeout_us =DIV_ROUND_UP (timeout_us,10 ) *10 ;while (timeout_us) { reg =readl (uport->membase + offset); -if ((bool )(reg & field) == set) +if ((reg & field) == val)return true;udelay (10 ); timeout_us -=10 ;
@@ -294,6 +294,12 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,return false; } +static bool qcom_geni_serial_poll_bit (struct uart_port *uport, +unsigned int offset,u32 field,bool set) +{ +return qcom_geni_serial_poll_bitfield (uport, offset, field, set ? field :0 ); +} +static void qcom_geni_serial_setup_tx (struct uart_port *uport,u32 xmit_size) {u32 m_cmd;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 668/695 serial: qcom-geni: fix console corruption
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit cc4a0e5754a16bbc1e215c091349a7c83a2c5e14 ]
The Qualcomm serial console implementation is broken and can lose characters when the serial port is also used for tty output.
Specifically, the console code only waits for the current tx command to complete when all data has already been written to the fifo. When there are on-going longer transfers this often means that console output is lost when the console code inadvertently "hijacks" the current tx command instead of starting a new one.
This can, for example, be observed during boot when console output that should have been interspersed with init output is truncated:
[ 9.462317] qcom-snps-eusb2-hsphy fde000.phy: Registered Qcom-eUSB2 phy [ OK ] Found device KBG50ZNS256G KIOXIA Wi[ 9.471743ndows. [ 9.539915] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
Add a new state variable to track how much data has been written to the fifo and use it to determine when the fifo and shift register are both empty. This is needed since there is currently no other known way to determine when the shift register is empty.
This in turn allows the console code to interrupt long transfers without losing data.
Note that the oops-in-progress case is similarly broken as it does not cancel any active command and also waits for the wrong status flag when attempting to drain the fifo (TX_FIFO_NOT_EMPTY_EN is only set when cancelling a command leaves data in the fifo).
--- drivers/tty/serial/qcom_geni_serial.c | 45 +++++++++++++-------------- 1 file changed, 22 insertions(+), 23 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +22 -23
@@ -131,6 +131,7 @@ struct qcom_geni_serial_port {bool brk;unsigned int tx_remaining; +unsigned int tx_queued;int wakeup_irq;bool rx_tx_swap;bool cts_rts_swap;
@@ -144,6 +145,8 @@ static const struct uart_ops qcom_geni_uart_pops;static struct uart_driver qcom_geni_console_driver;static struct uart_driver qcom_geni_uart_driver; +static void qcom_geni_serial_cancel_tx_cmd (struct uart_port *uport); +static inline struct qcom_geni_serial_port *to_dev_port (struct uart_port *uport) { return container_of(uport, struct qcom_geni_serial_port, uport);
@@ -393,6 +396,14 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,#endif #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE +static void qcom_geni_serial_drain_fifo (struct uart_port *uport) +{ +struct qcom_geni_serial_port *port =to_dev_port (uport); + +qcom_geni_serial_poll_bitfield (uport,SE_GENI_M_GP_LENGTH ,GP_LENGTH , + port->tx_queued); +} +static void qcom_geni_serial_wr_char (struct uart_port *uport,unsigned char ch) {struct qcom_geni_private_data *private_data = uport->private_data;
@@ -468,7 +479,6 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,struct qcom_geni_serial_port *port;bool locked = true;unsigned long flags; -u32 geni_status;WARN_ON (co->index <0 || co->index >=GENI_UART_CONS_PORTS );
@@ -482,34 +492,20 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,else uart_port_lock_irqsave (uport, &flags); - geni_status =readl (uport->membase +SE_GENI_STATUS ); +if (qcom_geni_serial_main_active (uport)) { +/* Wait for completion or drain FIFO */ +if (!locked || port->tx_remaining ==0 ) +qcom_geni_serial_poll_tx_done (uport); +else +qcom_geni_serial_drain_fifo (uport); -if (!locked) { -/* -* We can only get here if an oops is in progress then we were -* unable to get the lock. This means we can't safely access -* our state variables like tx_remaining. About the best we -* can do is wait for the FIFO to be empty before we start our -* transfer, so we'll do that. -*/ -qcom_geni_serial_poll_bit (uport,SE_GENI_M_IRQ_STATUS , -M_TX_FIFO_NOT_EMPTY_EN , false); - }else if ((geni_status &M_GENI_CMD_ACTIVE ) && !port->tx_remaining) { -/* -* It seems we can't interrupt existing transfers if all data -* has been sent, in which case we need to look for done first. -*/ -qcom_geni_serial_poll_tx_done (uport); +qcom_geni_serial_cancel_tx_cmd (uport); }__qcom_geni_serial_console_write (uport, s, count); - -if (locked) { -if (port->tx_remaining) -qcom_geni_serial_setup_tx (uport, port->tx_remaining); +if (locked)uart_port_unlock_irqrestore (uport, flags); - } }static void handle_rx_console (struct uart_port *uport,u32 bytes,bool drop)
@@ -690,6 +686,7 @@ static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport)writel (M_CMD_CANCEL_EN , uport->membase +SE_GENI_M_IRQ_CLEAR ); port->tx_remaining =0 ; + port->tx_queued =0 ; }static void qcom_geni_serial_handle_rx_fifo (struct uart_port *uport,bool drop)
@@ -916,6 +913,7 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport,if (!port->tx_remaining) {qcom_geni_serial_setup_tx (uport, pending); port->tx_remaining = pending; + port->tx_queued =0 ; irq_en =readl (uport->membase +SE_GENI_M_IRQ_EN );if (!(irq_en &M_TX_FIFO_WATERMARK_EN ))
@@ -924,6 +922,7 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport, }qcom_geni_serial_send_chunk_fifo (uport, chunk); + port->tx_queued += chunk;/* * The tx fifo watermark is level triggered and latched. Though we had
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 669/695 thermal: core: Store trip sysfs attributes in thermal_trip_desc
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit 66b263306a86c0f2d3cdb44e3722db6cff3a32b3 ]
Instead of allocating memory for trip point sysfs attributes separately, store them in struct thermal_trip_desc for each trip individually which allows a few extra memory allocations to be avoided.
No intentional functional impact.
Stable-dep-of: 874b6476fa88 ("thermal: sysfs: Add sanity checks for trip temperature and hysteresis")
--- drivers/thermal/thermal_core.h | 23 +++---- drivers/thermal/thermal_sysfs.c | 105 +++++++++++--------------------- 2 files changed, 46 insertions(+), 82 deletions(-)
drivers/thermal/thermal_core.h +12 -11
@@ -15,8 +15,20 @@#include "thermal_netlink.h" #include "thermal_debugfs.h" +struct thermal_attr { +struct device_attribute attr; +char name[THERMAL_NAME_LENGTH ]; +}; + +struct thermal_trip_attrs { +struct thermal_attr type; +struct thermal_attr temp; +struct thermal_attr hyst; +}; +struct thermal_trip_desc {struct thermal_trip trip; +struct thermal_trip_attrs trip_attrs;struct list_head notify_list_node;int notify_temp;int threshold;
@@ -56,9 +68,6 @@ struct thermal_governor {* @device: &struct device for this thermal zone * @removal: removal completion * @resume: resume completion -* @trip_temp_attrs: attributes for trip points for sysfs: trip temperature -* @trip_type_attrs: attributes for trip points for sysfs: trip type -* @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis * @mode: current mode of this thermal zone * @devdata: private pointer for device private data * @num_trips: number of trip points the thermal zone supports
@@ -102,9 +111,6 @@ struct thermal_zone_device {struct completion removal;struct completion resume;struct attribute_group trips_attribute_group; -struct thermal_attr *trip_temp_attrs; -struct thermal_attr *trip_type_attrs; -struct thermal_attr *trip_hyst_attrs;enum thermal_device_mode mode;void *devdata;int num_trips;
@@ -188,11 +194,6 @@ int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),struct thermal_zone_device *thermal_zone_get_by_id (int id); -struct thermal_attr { -struct device_attribute attr; -char name[THERMAL_NAME_LENGTH ]; -}; -static inline bool cdev_is_power_actor (struct thermal_cooling_device *cdev) { return cdev->ops->get_requested_power && cdev->ops->state2power &&
drivers/thermal/thermal_sysfs.c +34 -71
134 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 670/695 thermal: sysfs: Get to trips via attribute pointers
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit afd84fb10ced3caf53769ba734ea237bde0f69e3 ]
The _store() and _show() functions for sysfs attributes corresponding to trip point parameters (type, temperature and hysteresis) read the trip ID from the attribute name and then use the trip ID as the index in the given thermal zone's trips table to get to the trip object they want.
Instead of doing this, make them use the attribute pointer they get as the second argument to get to the trip object embedded in the same struct thermal_trip_desc as the struct device_attribute pointed to by it, which is much more straightforward and less overhead.
Stable-dep-of: 874b6476fa88 ("thermal: sysfs: Add sanity checks for trip temperature and hysteresis")
--- drivers/thermal/thermal_sysfs.c | 54 ++++++++++++--------------------- 1 file changed, 20 insertions(+), 34 deletions(-)
drivers/thermal/thermal_sysfs.c +20 -34
@@ -12,6 +12,7 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <linux/container_of.h> #include <linux/sysfs.h> #include <linux/device.h> #include <linux/err.h>
@@ -78,39 +79,38 @@ mode_store(struct device *dev, struct device_attribute *attr,return count; } +#define thermal_trip_of_attr (_ptr_, _attr_) \ + ({ \ + struct thermal_trip_desc *td; \ + \ + td = container_of(_ptr_, struct thermal_trip_desc, \ + trip_attrs._attr_.attr); \ + &td->trip; \ + }) +static ssize_t trip_point_type_show (struct device *dev,struct device_attribute *attr,char *buf) { -struct thermal_zone_device *tz =to_thermal_zone (dev); -int trip_id; - -if (sscanf (attr->attr.name,"trip_point_%d_type" , &trip_id) !=1 ) -return -EINVAL ; +struct thermal_trip *trip =thermal_trip_of_attr (attr, type); -return sprintf (buf,"%s\n" ,thermal_trip_type_name (tz->trips[trip_id].trip.type)); +return sprintf (buf,"%s\n" ,thermal_trip_type_name (trip->type)); }static ssize_t trip_point_temp_store (struct device *dev,struct device_attribute *attr,const char *buf,size_t count) { +struct thermal_trip *trip =thermal_trip_of_attr (attr, temp);struct thermal_zone_device *tz =to_thermal_zone (dev); -struct thermal_trip *trip; -int trip_id, ret; -int temp; +int ret, temp; ret =kstrtoint (buf,10 , &temp);if (ret)return -EINVAL ; -if (sscanf (attr->attr.name,"trip_point_%d_temp" , &trip_id) !=1 ) -return -EINVAL ; -mutex_lock (&tz->lock); - trip = &tz->trips[trip_id].trip; -if (temp != trip->temperature) {if (tz->ops.set_trip_temp) { ret = tz->ops.set_trip_temp (tz, trip, temp);
@@ -133,35 +133,25 @@ static ssize_t trip_point_temp_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct thermal_zone_device *tz = to_thermal_zone(dev); -int trip_id; + struct thermal_trip *trip = thermal_trip_of_attr(attr, temp); -if (sscanf (attr->attr.name,"trip_point_%d_temp" , &trip_id) !=1 ) -return -EINVAL ; - -return sprintf (buf,"%d\n" ,READ_ONCE (tz->trips[trip_id].trip.temperature)); +return sprintf (buf,"%d\n" ,READ_ONCE (trip->temperature)); }static ssize_t trip_point_hyst_store (struct device *dev,struct device_attribute *attr,const char *buf,size_t count) { +struct thermal_trip *trip =thermal_trip_of_attr (attr, hyst);struct thermal_zone_device *tz =to_thermal_zone (dev); -struct thermal_trip *trip; -int trip_id, ret; -int hyst; +int ret, hyst; ret =kstrtoint (buf,10 , &hyst);if (ret || hyst <0 )return -EINVAL ; -if (sscanf (attr->attr.name,"trip_point_%d_hyst" , &trip_id) !=1 ) -return -EINVAL ; -mutex_lock (&tz->lock); - trip = &tz->trips[trip_id].trip; -if (hyst != trip->hysteresis) {WRITE_ONCE (trip->hysteresis, hyst);
@@ -177,13 +167,9 @@ static ssize_t trip_point_hyst_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct thermal_zone_device *tz = to_thermal_zone(dev); -int trip_id; - -if (sscanf (attr->attr.name,"trip_point_%d_hyst" , &trip_id) !=1 ) -return -EINVAL ; + struct thermal_trip *trip = thermal_trip_of_attr(attr, hyst); -return sprintf (buf,"%d\n" ,READ_ONCE (tz->trips[trip_id].trip.hysteresis)); +return sprintf (buf,"%d\n" ,READ_ONCE (trip->hysteresis)); } static ssize_t
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 671/695 thermal: sysfs: Refine the handling of trip hysteresis changes
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit 107280e1371f1ba183be1ac88e91ec60cad33c18 ]
Change trip_point_hyst_store() and replace thermal_zone_trip_updated() with thermal_zone_set_trip_hyst() to follow the trip_point_temp_store() code pattern for more consistency.
No intentional functional impact.
Stable-dep-of: 874b6476fa88 ("thermal: sysfs: Add sanity checks for trip temperature and hysteresis")
--- drivers/thermal/thermal_core.h | 4 ++-- drivers/thermal/thermal_sysfs.c | 4 ++-- drivers/thermal/thermal_trip.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-)
drivers/thermal/thermal_core.h +2 -2
@@ -263,11 +263,11 @@ const char *thermal_trip_type_name(enum thermal_trip_type trip_type);void thermal_zone_set_trips (struct thermal_zone_device *tz);int thermal_zone_trip_id (const struct thermal_zone_device *tz,const struct thermal_trip *trip); -void thermal_zone_trip_updated (struct thermal_zone_device *tz, -const struct thermal_trip *trip);int __thermal_zone_get_temp (struct thermal_zone_device *tz,int *temp);void thermal_zone_trip_down (struct thermal_zone_device *tz,const struct thermal_trip *trip); +void thermal_zone_set_trip_hyst (struct thermal_zone_device *tz, +struct thermal_trip *trip,int hyst);/* sysfs I/F */ int thermal_zone_create_device_groups (struct thermal_zone_device *tz);
drivers/thermal/thermal_sysfs.c +2 -2
@@ -153,9 +153,9 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,mutex_lock (&tz->lock);if (hyst != trip->hysteresis) { -WRITE_ONCE (trip->hysteresis, hyst); +thermal_zone_set_trip_hyst (tz, trip, hyst); -thermal_zone_trip_updated (tz, trip); +__thermal_zone_device_update (tz,THERMAL_TRIP_CHANGED ); }mutex_unlock (&tz->lock);
drivers/thermal/thermal_trip.c +3 -3
@@ -138,11 +138,11 @@ int thermal_zone_trip_id(const struct thermal_zone_device *tz,return trip_to_trip_desc (trip) - tz->trips; } -void thermal_zone_trip_updated (struct thermal_zone_device *tz, -const struct thermal_trip *trip) +void thermal_zone_set_trip_hyst (struct thermal_zone_device *tz, +struct thermal_trip *trip,int hyst) { +WRITE_ONCE (trip->hysteresis, hyst);thermal_notify_tz_trip_change (tz, trip); -__thermal_zone_device_update (tz,THERMAL_TRIP_CHANGED ); } void thermal_zone_set_trip_temp(struct thermal_zone_device *tz,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 672/695 thermal: sysfs: Add sanity checks for trip temperature and hysteresis
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
[ Upstream commit 874b6476fa888e79e41daf7653384c8d70927b90 ]
Add sanity checks for new trip temperature and hysteresis values to trip_point_temp_store() and trip_point_hyst_store() to prevent trip point threshold from falling below THERMAL_TEMP_INVALID.
However, still allow user space to pass THERMAL_TEMP_INVALID as the new trip temperature value to invalidate the trip if necessary.
Also allow the hysteresis to be updated when the temperature is invalid to allow user space to avoid having to adjust hysteresis after a valid temperature has been set, but in that case just change the value and do nothing else.
--- drivers/thermal/thermal_sysfs.c | 50 +++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 12 deletions(-)
drivers/thermal/thermal_sysfs.c +38 -12
@@ -111,18 +111,26 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,mutex_lock (&tz->lock); -if (temp != trip->temperature) { -if (tz->ops.set_trip_temp) { - ret = tz->ops.set_trip_temp (tz, trip, temp); -if (ret) - goto unlock; - } +if (temp == trip->temperature) + goto unlock; -thermal_zone_set_trip_temp (tz, trip, temp); +/* Arrange the condition to avoid integer overflows. */ +if (temp !=THERMAL_TEMP_INVALID && + temp <= trip->hysteresis +THERMAL_TEMP_INVALID ) { + ret = -EINVAL ; + goto unlock; + } -__thermal_zone_device_update (tz,THERMAL_TRIP_CHANGED ); +if (tz->ops.set_trip_temp) { + ret = tz->ops.set_trip_temp (tz, trip, temp); +if (ret) + goto unlock; } +thermal_zone_set_trip_temp (tz, trip, temp); + +__thermal_zone_device_update (tz,THERMAL_TRIP_CHANGED ); + unlock:mutex_unlock (&tz->lock);
@@ -152,15 +160,33 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,mutex_lock (&tz->lock); -if (hyst != trip->hysteresis) { -thermal_zone_set_trip_hyst (tz, trip, hyst); +if (hyst == trip->hysteresis) + goto unlock; + +/* +* Allow the hysteresis to be updated when the temperature is invalid +* to allow user space to avoid having to adjust hysteresis after a +* valid temperature has been set, but in that case just change the +* value and do nothing else. +*/ +if (trip->temperature ==THERMAL_TEMP_INVALID ) { +WRITE_ONCE (trip->hysteresis, hyst); + goto unlock; + } -__thermal_zone_device_update (tz,THERMAL_TRIP_CHANGED ); +if (trip->temperature - hyst <=THERMAL_TEMP_INVALID ) { + ret = -EINVAL ; + goto unlock; } +thermal_zone_set_trip_hyst (tz, trip, hyst); + +__thermal_zone_device_update (tz,THERMAL_TRIP_CHANGED ); + +unlock:mutex_unlock (&tz->lock); -return count; +return ret ? ret : count; } static ssize_t
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 673/695 lsm: infrastructure management of the sock security
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Casey Schaufler <[email protected]>
[ Upstream commit 2aff9d20d50ac45dd13a013ef5231f4fb8912356 ]
Move management of the sock->sk_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there.
Stable-dep-of: 63dff3e48871 ("lsm: add the inode_free_security_rcu() LSM implementation hook")
--- include/linux/lsm_hooks.h | 1 security/apparmor/include/net.h | 3 - security/apparmor/lsm.c | 17 -------- security/apparmor/net.c | 2 security/security.c | 36 ++++++++++++++++- security/selinux/hooks.c | 80 +++++++++++++++++--------------------- security/selinux/include/objsec.h | 5 ++ security/selinux/netlabel.c | 23 +++++----- security/smack/smack.h | 5 ++ security/smack/smack_lsm.c | 70 +++++++++++++++------------------ security/smack/smack_netfilter.c | 4 - 11 files changed, 133 insertions(+), 113 deletions(-)
include/linux/lsm_hooks.h +1 -0
@@ -73,6 +73,7 @@ struct lsm_blob_sizes {int lbs_cred;int lbs_file;int lbs_inode; +int lbs_sock;int lbs_superblock;int lbs_ipc;int lbs_msg_msg;
security/apparmor/include/net.h +1 -2
@@ -51,10 +51,9 @@ struct aa_sk_ctx {struct aa_label *peer; }; -#define SK_CTX (X ) ((X)->sk_security)static inline struct aa_sk_ctx *aa_sock (const struct sock *sk) { -return sk->sk_security; +return sk->sk_security + apparmor_blob_sizes.lbs_sock; }#define DEFINE_AUDIT_NET (NAME ,OP ,SK ,F ,T ,P ) \
security/apparmor/lsm.c +1 -16
@@ -1058,27 +1058,12 @@ static int apparmor_userns_create(constreturn error; } -static int apparmor_sk_alloc_security (struct sock *sk,int family,gfp_t flags) -{ -struct aa_sk_ctx *ctx; - - ctx =kzalloc (sizeof (*ctx), flags); -if (!ctx) -return -ENOMEM ; - - sk->sk_security = ctx; - -return 0 ; -} -static void apparmor_sk_free_security (struct sock *sk) {struct aa_sk_ctx *ctx =aa_sock (sk); - sk->sk_security =NULL ;aa_put_label (ctx->label);aa_put_label (ctx->peer); -kfree (ctx); }/**
@@ -1433,6 +1418,7 @@ struct lsm_blob_sizes apparmor_blob_size .lbs_cred = sizeof(struct aa_label *), .lbs_file = sizeof(struct aa_file_ctx), .lbs_task = sizeof(struct aa_task_ctx), + .lbs_sock = sizeof(struct aa_sk_ctx), };static const struct lsm_id apparmor_lsmid = {
@@ -1478,7 +1464,6 @@ static struct security_hook_list apparmoLSM_HOOK_INIT (getprocattr, apparmor_getprocattr),LSM_HOOK_INIT (setprocattr, apparmor_setprocattr), -LSM_HOOK_INIT (sk_alloc_security, apparmor_sk_alloc_security),LSM_HOOK_INIT (sk_free_security, apparmor_sk_free_security), LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
security/apparmor/net.c +1 -1
@@ -151,7 +151,7 @@ static int aa_label_sk_perm(const struct const char *op, u32 request, struct sock *sk) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk);int error =0 ;AA_BUG (!label);
security/security.c +35 -1
@@ -29,6 +29,7 @@#include <linux/msg.h> #include <linux/overflow.h> #include <net/flow.h> +#include <net/sock.h> /* How many LSMs were built into the kernel? */ #define LSM_COUNT (__end_lsm_info - __start_lsm_info)
@@ -227,6 +228,7 @@ static void __init lsm_set_blob_sizes(stlsm_set_blob_size (&needed->lbs_inode, &blob_sizes.lbs_inode);lsm_set_blob_size (&needed->lbs_ipc, &blob_sizes.lbs_ipc);lsm_set_blob_size (&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); +lsm_set_blob_size (&needed->lbs_sock, &blob_sizes.lbs_sock);lsm_set_blob_size (&needed->lbs_superblock, &blob_sizes.lbs_superblock);lsm_set_blob_size (&needed->lbs_task, &blob_sizes.lbs_task); lsm_set_blob_size(&needed->lbs_xattr_count,
@@ -401,6 +403,7 @@ static void __init ordered_lsm_init(voidinit_debug ("inode blob size = %d\n" , blob_sizes.lbs_inode);init_debug ("ipc blob size = %d\n" , blob_sizes.lbs_ipc);init_debug ("msg_msg blob size = %d\n" , blob_sizes.lbs_msg_msg); +init_debug ("sock blob size = %d\n" , blob_sizes.lbs_sock);init_debug ("superblock blob size = %d\n" , blob_sizes.lbs_superblock);init_debug ("task blob size = %d\n" , blob_sizes.lbs_task);init_debug ("xattr slots = %d\n" , blob_sizes.lbs_xattr_count);
@@ -4674,6 +4677,28 @@ int security_socket_getpeersec_dgram(strEXPORT_SYMBOL (security_socket_getpeersec_dgram);/** +* lsm_sock_alloc - allocate a composite sock blob +* @sock: the sock that needs a blob +* @priority: allocation mode +* +* Allocate the sock blob for all the modules +* +* Returns 0, or -ENOMEM if memory can't be allocated. +*/ +static int lsm_sock_alloc (struct sock *sock,gfp_t priority) +{ +if (blob_sizes.lbs_sock ==0 ) { + sock->sk_security =NULL ; +return 0 ; + } + + sock->sk_security =kzalloc (blob_sizes.lbs_sock, priority); +if (sock->sk_security ==NULL ) +return -ENOMEM ; +return 0 ; +} + +/** * security_sk_alloc() - Allocate and initialize a sock's LSM blob * @sk: sock * @family: protocol family
@@ -4686,7 +4711,14 @@ EXPORT_SYMBOL(security_socket_getpeersec*/ int security_sk_alloc (struct sock *sk,int family,gfp_t priority) { -return call_int_hook (sk_alloc_security, sk, family, priority); +int rc =lsm_sock_alloc (sk, priority); + +if (unlikely (rc)) +return rc; + rc =call_int_hook (sk_alloc_security, sk, family, priority); +if (unlikely (rc)) +security_sk_free (sk); +return rc; }/**
@@ -4698,6 +4730,8 @@ int security_sk_alloc(struct sock *sk, ivoid security_sk_free (struct sock *sk) {call_void_hook (sk_free_security, sk); +kfree (sk->sk_security); + sk->sk_security =NULL ; }/**
security/selinux/hooks.c +37 -43
265 lines not on this page · raw message
security/selinux/include/objsec.h +5 -0
@@ -195,4 +195,9 @@ selinux_superblock(const struct super_bl return superblock->s_security + selinux_blob_sizes.lbs_superblock; } +static inline struct sk_security_struct *selinux_sock (const struct sock *sock) +{ +return sock->sk_security + selinux_blob_sizes.lbs_sock; +} +#endif /* _SELINUX_OBJSEC_H_ */
security/selinux/netlabel.c +12 -11
@@ -17,6 +17,7 @@#include <linux/gfp.h> #include <linux/ip.h> #include <linux/ipv6.h> +#include <linux/lsm_hooks.h> #include <net/sock.h> #include <net/netlabel.h> #include <net/ip.h>
@@ -68,7 +69,7 @@ static int selinux_netlbl_sidlookup_cachstatic struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr (struct sock *sk) {int rc; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);struct netlbl_lsm_secattr *secattr;if (sksec->nlbl_secattr !=NULL )
@@ -100,7 +101,7 @@ static struct netlbl_lsm_secattr *selinu const struct sock *sk, u32 sid) { -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr;if (secattr ==NULL )
@@ -240,7 +241,7 @@ int selinux_netlbl_skbuff_setsid(struct* being labeled by it's parent socket, if it is just exit */ sk =skb_to_full_sk (skb);if (sk !=NULL ) { -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);if (sksec->nlbl_state !=NLBL_REQSKB )return 0 ;
@@ -277,7 +278,7 @@ int selinux_netlbl_sctp_assoc_request(st {int rc;struct netlbl_lsm_secattr secattr; -struct sk_security_struct *sksec = asoc->base.sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (asoc->base.sk);struct sockaddr_in addr4;struct sockaddr_in6 addr6;
@@ -356,7 +357,7 @@ inet_conn_request_return:*/ void selinux_netlbl_inet_csk_clone (struct sock *sk,u16 family) { -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);if (family ==PF_INET ) sksec->nlbl_state =NLBL_LABELED ;
@@ -374,8 +375,8 @@ void selinux_netlbl_inet_csk_clone(struc*/ void selinux_netlbl_sctp_sk_clone (struct sock *sk,struct sock *newsk) { -struct sk_security_struct *sksec = sk->sk_security; -struct sk_security_struct *newsksec = newsk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk); +struct sk_security_struct *newsksec =selinux_sock (newsk); newsksec->nlbl_state = sksec->nlbl_state; }
@@ -393,7 +394,7 @@ void selinux_netlbl_sctp_sk_clone(structint selinux_netlbl_socket_post_create (struct sock *sk,u16 family) {int rc; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);struct netlbl_lsm_secattr *secattr;if (family !=PF_INET && family !=PF_INET6 )
@@ -510,7 +511,7 @@ int selinux_netlbl_socket_setsockopt(str {int rc =0 ;struct sock *sk = sock->sk; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);struct netlbl_lsm_secattr secattr; if (selinux_netlbl_option(level, optname) &&
@@ -548,7 +549,7 @@ static int selinux_netlbl_socket_connect struct sockaddr *addr) {int rc; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);struct netlbl_lsm_secattr *secattr;/* connected sockets are allowed to disconnect when the address family
@@ -587,7 +588,7 @@ static int selinux_netlbl_socket_connectint selinux_netlbl_socket_connect_locked (struct sock *sk,struct sockaddr *addr) { -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =selinux_sock (sk);if (sksec->nlbl_state !=NLBL_REQSKB && sksec->nlbl_state !=NLBL_CONNLABELED )
security/smack/smack.h +5 -0
@@ -355,6 +355,11 @@ static inline struct superblock_smack *sreturn superblock->s_security + smack_blob_sizes.lbs_superblock; } +static inline struct socket_smack *smack_sock (const struct sock *sock) +{ +return sock->sk_security + smack_blob_sizes.lbs_sock; +} +/* * Is the directory transmuting? */
security/smack/smack_lsm.c +33 -37
243 lines not on this page · raw message
security/smack/smack_netfilter.c +2 -2
@@ -26,8 +26,8 @@ static unsigned int smack_ip_output(voidstruct socket_smack *ssp;struct smack_known *skp; -if (sk && sk->sk_security) { - ssp = sk->sk_security; +if (sk) { + ssp =smack_sock (sk); skp = ssp->smk_out; skb->secmark = skp->smk_secid; }
Greg Kroah-Hartman
maintainerPATCH 674/695 bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Liu <[email protected]>
commit 300a90b2cb5d442879e6398920c49aebbd5c8e40 upstream.
bpf task local storage is now using task_struct->bpf_storage, so bpf_lsm_blob_sizes.lbs_task is no longer needed. Remove it to save some memory.
--- security/bpf/hooks.c | 1 - 1 file changed, 1 deletion(-)
security/bpf/hooks.c +0 -1
@@ -31,7 +31,6 @@ static int __init bpf_lsm_init(void)struct lsm_blob_sizes bpf_lsm_blob_sizes__ro_after_init = { .lbs_inode =sizeof (struct bpf_storage_blob ), - .lbs_task =sizeof (struct bpf_storage_blob ), };DEFINE_LSM (bpf) = {
Greg Kroah-Hartman
maintainerPATCH 675/695 dm-verity: restart or panic on an I/O error
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit e6a3531dd542cb127c8de32ab1e54a48ae19962b upstream.
Maxim Suhanov reported that dm-verity doesn't crash if an I/O error happens. In theory, this could be used to subvert security, because an attacker can create sectors that return error with the Write Uncorrectable command. Some programs may misbehave if they have to deal with EIO.
This commit fixes dm-verity, so that if "panic_on_corruption" or "restart_on_corruption" was specified and an I/O error happens, the machine will panic or restart.
This commit also changes kernel_restart to emergency_restart - kernel_restart calls reboot notifiers and these reboot notifiers may wait for the bio that failed. emergency_restart doesn't call the notifiers.
--- drivers/md/dm-verity-target.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/md/dm-verity-target.c +21 -2
@@ -272,8 +272,10 @@ out:if (v->mode ==DM_VERITY_MODE_LOGGING )return 0 ; -if (v->mode ==DM_VERITY_MODE_RESTART ) -kernel_restart ("dm-verity device corrupted" ); +if (v->mode ==DM_VERITY_MODE_RESTART ) { +pr_emerg ("dm-verity device corrupted\n" ); +emergency_restart (); + }if (v->mode ==DM_VERITY_MODE_PANIC )panic ("dm-verity device corrupted" );
@@ -596,6 +598,23 @@ static void verity_finish_io(struct dm_vif (!static_branch_unlikely (&use_bh_wq_enabled) || !io->in_bh)verity_fec_finish_io (io); +if (unlikely (status !=BLK_STS_OK ) && +unlikely (!(bio->bi_opf &REQ_RAHEAD )) && + !verity_is_system_shutting_down ()) { +if (v->mode ==DM_VERITY_MODE_RESTART || + v->mode ==DM_VERITY_MODE_PANIC ) +DMERR_LIMIT ("%s has error: %s" , v->data_dev->name, +blk_status_to_str (status)); + +if (v->mode ==DM_VERITY_MODE_RESTART ) { +pr_emerg ("dm-verity device corrupted\n" ); +emergency_restart (); + } + +if (v->mode ==DM_VERITY_MODE_PANIC ) +panic ("dm-verity device corrupted" ); + } +bio_endio (bio); }
Greg Kroah-Hartman
maintainerPATCH 676/695 compiler.h: specify correct attribute for .rodata..c_jump_table
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
commit c5b1184decc819756ae549ba54c63b6790c4ddfd upstream.
Currently, there is an assembler message when generating kernel/bpf/core.o under CONFIG_OBJTOOL with LoongArch compiler toolchain:
Warning: setting incorrect section attributes for .rodata..c_jump_table
This is because the section ".rodata..c_jump_table" should be readonly, but there is a "W" (writable) part of the flags:
$ readelf -S kernel/bpf/core.o | grep -A 1 "rodata..c"
[34] .rodata..c_j[...] PROGBITS 0000000000000000 0000d2e0
0000000000000800 0000000000000000 WA 0 0 8There is no above issue on x86 due to the generated section flag is only "A" (allocatable). In order to silence the warning on LoongArch, specify the attribute like ".rodata..c_jump_table,\"a\",@progbits #" explicitly, then the section attribute of ".rodata..c_jump_table" must be readonly in the kernel/bpf/core.o file.
Before:
$ objdump -h kernel/bpf/core.o | grep -A 1 "rodata..c"
21 .rodata..c_jump_table 00000800 0000000000000000 0000000000000000 0000d2e0 2**3
CONTENTS, ALLOC, LOAD, RELOC, DATAAfter:
$ objdump -h kernel/bpf/core.o | grep -A 1 "rodata..c"
21 .rodata..c_jump_table 00000800 0000000000000000 0000000000000000 0000d2e0 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATABy the way, AFAICT, maybe the root cause is related with the different compiler behavior of various archs, so to some extent this change is a workaround for LoongArch, and also there is no effect for x86 which is the only port supported by objtool before LoongArch with this patch.
--- include/linux/compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/compiler.h +1 -1
@@ -133,7 +133,7 @@ void ftrace_likely_update(struct ftrace_#define annotate_unreachable () __annotate_unreachable(__COUNTER__)/* Annotate a C jump table to allow objtool to follow the code flow */ -#define __annotate_jump_table __section(".rodata..c_jump_table") +#define __annotate_jump_table __section(".rodata..c_jump_table,\"a\",@progbits #")#else /* !CONFIG_OBJTOOL */ #define annotate_reachable ()