Skip to content

Commit c370e33

Browse files
committed
Correct LR/SC implementation
LR/SC needs to ensure the address is valid and the value does not change. In the original implementation, it only checks if the address is valid.
1 parent cfdb547 commit c370e33

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

riscv.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,10 @@ static void mmu_load(vm_t *vm,
311311
if (vm->error)
312312
return;
313313

314-
if (unlikely(reserved))
314+
if (unlikely(reserved)) {
315315
vm->lr_reservation = addr | 1;
316+
vm->lr_val = *value;
317+
}
316318
}
317319

318320
static bool mmu_store(vm_t *vm,
@@ -328,8 +330,11 @@ static bool mmu_store(vm_t *vm,
328330
return false;
329331

330332
if (unlikely(cond)) {
331-
if (vm->lr_reservation != (addr | 1))
333+
uint32_t cas_value;
334+
vm->mem_load(vm, addr, width, &cas_value);
335+
if ((vm->lr_reservation != (addr | 1)) || vm->lr_val != cas_value)
332336
return false;
337+
333338
vm->lr_reservation = 0;
334339
} else {
335340
if (unlikely(vm->lr_reservation & 1) &&

riscv.h

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct __vm_internal {
5656

5757
/* LR reservation virtual address. last bit is 1 if valid */
5858
uint32_t lr_reservation;
59+
uint32_t lr_val;
5960

6061
/* Assumed to contain an aligned address at all times */
6162
uint32_t pc;

0 commit comments

Comments
 (0)