fix(cpu): PPCBUG-151 add reservation_width discriminator to stwcx./stdcx.
Track lwarx vs ldarx reservation width in PpcContext as a u8 (4 = word,
8 = doubleword, 0 = none). stwcx. requires width==4; stdcx. requires
width==8. Cross-width pairs (lwarx + stdcx., ldarx + stwcx.) now fail
deterministically with CR0.EQ=0 instead of spuriously succeeding.
The width is held per-thread; the cross-thread reservation table keeps
its existing slot encoding because each host thread consults its own
ctx.reservation_width before committing.
Affected:
PPCBUG-151 stwcx./stdcx. shared the same reservation slot without
width discriminator; cross-width commits silently succeeded
Tests: lwarx_then_stdcx_cross_width_fails,
ldarx_then_stwcx_cross_width_fails
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -101,6 +101,12 @@ pub struct PpcContext {
|
||||
pub reserved_line: u32,
|
||||
pub reserved_val: u64,
|
||||
pub has_reservation: bool,
|
||||
/// PPCBUG-151 — width of the active reservation: 4 = `lwarx` (word),
|
||||
/// 8 = `ldarx` (doubleword), 0 = no reservation. `stwcx.` requires
|
||||
/// width==4; `stdcx.` requires width==8. Cross-width pairs fail
|
||||
/// deterministically with CR0.EQ=0. Cleared alongside `has_reservation`
|
||||
/// on every `stwcx.`/`stdcx.` exit (success or failure).
|
||||
pub reservation_width: u8,
|
||||
/// M3.7 — generation stamp returned by [`crate::ReservationTable::reserve`]
|
||||
/// at the most recent `lwarx`/`ldarx`. Paired with `reserved_line`;
|
||||
/// `stwcx.`/`stdcx.` pass this back to `try_commit`. Meaningful only
|
||||
@@ -159,6 +165,7 @@ impl PpcContext {
|
||||
reserved_line: 0,
|
||||
reserved_val: 0,
|
||||
has_reservation: false,
|
||||
reservation_width: 0,
|
||||
reserved_generation: 0,
|
||||
reservation_table: None,
|
||||
hw_id: 0,
|
||||
|
||||
Reference in New Issue
Block a user