diff --git a/kernel/bin/riscv32i-unknown-none-elf.a b/kernel/bin/riscv32i-unknown-none-elf.a index bc88a1f90..7342c6ca3 100644 Binary files a/kernel/bin/riscv32i-unknown-none-elf.a and b/kernel/bin/riscv32i-unknown-none-elf.a differ diff --git a/kernel/bin/riscv32imac-unknown-none-elf.a b/kernel/bin/riscv32imac-unknown-none-elf.a index c2cb641f5..8e65db07f 100644 Binary files a/kernel/bin/riscv32imac-unknown-none-elf.a and b/kernel/bin/riscv32imac-unknown-none-elf.a differ diff --git a/kernel/bin/riscv32imac-unknown-xous-elf.a b/kernel/bin/riscv32imac-unknown-xous-elf.a index c2cb641f5..8e65db07f 100644 Binary files a/kernel/bin/riscv32imac-unknown-xous-elf.a and b/kernel/bin/riscv32imac-unknown-xous-elf.a differ diff --git a/kernel/bin/riscv32imc-unknown-none-elf.a b/kernel/bin/riscv32imc-unknown-none-elf.a index c2cb641f5..8e65db07f 100644 Binary files a/kernel/bin/riscv32imc-unknown-none-elf.a and b/kernel/bin/riscv32imc-unknown-none-elf.a differ diff --git a/kernel/bin/riscv64gc-unknown-none-elf.a b/kernel/bin/riscv64gc-unknown-none-elf.a index 3e38f0124..9c0144400 100644 Binary files a/kernel/bin/riscv64gc-unknown-none-elf.a and b/kernel/bin/riscv64gc-unknown-none-elf.a differ diff --git a/kernel/bin/riscv64imac-unknown-none-elf.a b/kernel/bin/riscv64imac-unknown-none-elf.a index 3e38f0124..9c0144400 100644 Binary files a/kernel/bin/riscv64imac-unknown-none-elf.a and b/kernel/bin/riscv64imac-unknown-none-elf.a differ diff --git a/kernel/src/asm.S b/kernel/src/asm.S index 813d2cfef..755a2f9d5 100644 --- a/kernel/src/asm.S +++ b/kernel/src/asm.S @@ -154,6 +154,11 @@ _xous_resume_context: move sp, a0 LOAD x1, 0*REGBYTES(sp) + // Clear any reservations, invalidating any atomic operations +#ifndef SKIP_MULTICORE + sc.w zero, x1, 0*REGBYTES(sp) +#endif + // Skip SP for now LOAD x3, 2*REGBYTES(sp) LOAD x4, 3*REGBYTES(sp) @@ -206,6 +211,21 @@ _xous_syscall_return_result: csrw sepc, t0 LOAD x1, 0*REGBYTES(sp) + // An atomic operation is broken up into multiple instructions. + // A program first issues a `lr` instruction, which basically + // raises a flag saying that an atomic operation is now live. It + // then issues an `sc` instruction, and if the flag is still held + // it succeeds and clears the flag. + // + // This flag is a bit of state within the processor, and the + // RISC-V spec doesn't say how to access it. However, it is only + // one bit, and we can clear the bit by performing a dummy `sc` + // here. This will cause a failure in any atomic operation in the + // program we're switching to. +#ifndef SKIP_MULTICORE + sc.w zero, x1, 0*REGBYTES(sp) +#endif + // Skip SP for now LOAD x3, 2*REGBYTES(sp) LOAD x4, 3*REGBYTES(sp)