Skip to content

Commit

Permalink
Fix LR/SC implementation inconsistent with specs
Browse files Browse the repository at this point in the history
According to the unprivileged ISA specs. at section 8.2
> An SC may succeed only if no store from another hart to the
> reservation set can be observed to have occurred between the LR and
> the SC, and if there is no other SC between the LR and itself in
> program order. An SC may succeed only if no write from a device other
> than a hart to the bytes accessed by the LR instruction can be
> observed to have occurred between the LR and SC.

By this mechanism, the LR/SC instructions can resolve the ABA problem by
reserving the address of loaded bytes.

In this commit, it prevents the LR/SC in semu from suffering ABA problem by
strictly obeying the rules mentioned above
  • Loading branch information
ranvd committed Jul 3, 2024
1 parent 932709b commit 97bb66e
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 11 deletions.
19 changes: 9 additions & 10 deletions riscv.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdint.h>
#include <stdio.h>

#include "common.h"
Expand Down Expand Up @@ -315,7 +316,6 @@ static void mmu_load(hart_t *vm,

if (unlikely(reserved)) {
vm->lr_reservation = addr | 1;
vm->lr_val = *value;
}
}

Expand All @@ -331,18 +331,17 @@ static bool mmu_store(hart_t *vm,
if (vm->error)
return false;

if (unlikely(cond)) {
uint32_t cas_value;
vm->mem_load(vm, addr, width, &cas_value);
if ((vm->lr_reservation != (addr | 1)) || vm->lr_val != cas_value)
if (unlikely(cond)){
if ((vm->lr_reservation != (addr | 1)))
return false;
}

vm->lr_reservation = 0;
} else {
if (unlikely(vm->lr_reservation & 1) &&
(vm->lr_reservation & ~3) == (addr & ~3))
vm->lr_reservation = 0;
for (uint32_t i = 0; i < vm->vm->hart_number; i++) {
if (unlikely(vm->vm->hart[i]->lr_reservation & 1) &&
(vm->vm->hart[i]->lr_reservation & ~3) == (addr & ~3))
vm->vm->hart[i]->lr_reservation = 0;
}

vm->mem_store(vm, addr, width, value);
return true;
}
Expand Down
1 change: 0 additions & 1 deletion riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ struct __hart_internal {

/* LR reservation virtual address. last bit is 1 if valid */
uint32_t lr_reservation;
uint32_t lr_val;

/* Assumed to contain an aligned address at all times */
uint32_t pc;
Expand Down

0 comments on commit 97bb66e

Please sign in to comment.