mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 18:51:21 +02:00
firewire fixes for 6.19-rc8
Fix a race condition introduced in v6.18. Andreas Persson discovered this issue while working with Focusrite Saffire Pro 40 (TCD33070). The fw_card instance maintains a linked list of pending transactions, which must be protected against concurrent access. However, a commitb5725cfa41("firewire: core: use spin lock specific to timer for split transaction") unintentionally allowed concurrent accesses to this list. Fix this by adjusting the relevant critical sections to properly serialize access. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQE66IEYNDXNBPeGKSsLtaWM8LwEwUCaX00QAAKCRCsLtaWM8Lw E0G/AP9PAE2Una4WBWNMw24zgyMYJyODekEQEZLr72ksPHMDGQD9GZNKylKogQdi OquDPN4J93mw4/9DGtCbF8ZEQLAxdwA= =7hNC -----END PGP SIGNATURE----- Merge tag 'firewire-fixes-6.19-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394 Pull firewire fix from Takashi Sakamoto: "Fix a race condition introduced in v6.18. Andreas Persson discovered this issue while working with Focusrite Saffire Pro 40 (TCD33070). The fw_card instance maintains a linked list of pending transactions, which must be protected against concurrent access. However, a commitb5725cfa41("firewire: core: use spin lock specific to timer for split transaction") unintentionally allowed concurrent accesses to this list. Fix this by adjusting the relevant critical sections to properly serialize access" * tag 'firewire-fixes-6.19-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394: firewire: core: fix race condition against transaction list
This commit is contained in:
commit
2912d799e5
|
|
@ -173,20 +173,14 @@ static void split_transaction_timeout_callback(struct timer_list *timer)
|
|||
}
|
||||
}
|
||||
|
||||
static void start_split_transaction_timeout(struct fw_transaction *t,
|
||||
struct fw_card *card)
|
||||
// card->transactions.lock should be acquired in advance for the linked list.
|
||||
static void start_split_transaction_timeout(struct fw_transaction *t, unsigned int delta)
|
||||
{
|
||||
unsigned long delta;
|
||||
|
||||
if (list_empty(&t->link) || WARN_ON(t->is_split_transaction))
|
||||
return;
|
||||
|
||||
t->is_split_transaction = true;
|
||||
|
||||
// NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
|
||||
// local destination never runs in any type of IRQ context.
|
||||
scoped_guard(spinlock_irqsave, &card->split_timeout.lock)
|
||||
delta = card->split_timeout.jiffies;
|
||||
mod_timer(&t->split_timeout_timer, jiffies + delta);
|
||||
}
|
||||
|
||||
|
|
@ -207,13 +201,20 @@ static void transmit_complete_callback(struct fw_packet *packet,
|
|||
break;
|
||||
case ACK_PENDING:
|
||||
{
|
||||
unsigned int delta;
|
||||
|
||||
// NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
|
||||
// local destination never runs in any type of IRQ context.
|
||||
scoped_guard(spinlock_irqsave, &card->split_timeout.lock) {
|
||||
t->split_timeout_cycle =
|
||||
compute_split_timeout_timestamp(card, packet->timestamp) & 0xffff;
|
||||
delta = card->split_timeout.jiffies;
|
||||
}
|
||||
start_split_transaction_timeout(t, card);
|
||||
|
||||
// NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for
|
||||
// local destination never runs in any type of IRQ context.
|
||||
scoped_guard(spinlock_irqsave, &card->transactions.lock)
|
||||
start_split_transaction_timeout(t, delta);
|
||||
break;
|
||||
}
|
||||
case ACK_BUSY_X:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user