Add Artemis stress test for detecting cache aliasing bugs. Include statistical hypothesis evaluations, fix validation data, and run reports for validation across architectures.

Signed-off-by: Robert Allan James <robert.allan.james@gmail.com>
This commit is contained in:
Robert Allan James
2026-08-02 14:49:52 -04:00
parent 148c4aa12c
commit 1cb68502fb
44 changed files with 5610173 additions and 2680 deletions
+31 -8
View File
@@ -177,12 +177,20 @@ static int blk_vm_evict(VM *vm) {
return s;
}
}
/* All slots dirty: evict round-robin, sync back to C buffer first. */
/* All slots dirty: evict round-robin, sync back to C buffer first.
* Re-resolve the buffer pointer by LBN rather than trusting the
* stored one -- the block-subsystem's own devblock cache may have
* shifted (struct-copy eviction) since this slot was populated,
* which silently invalidates any raw pointer captured earlier. */
int s = vm->blk_vm_next;
vm->blk_vm_next = (vm->blk_vm_next + 1) % BLK_VM_SLOTS;
vaddr_t base = BLK_VM_WINDOW_BASE + (vaddr_t)s * BLOCK_SIZE;
memcpy(vm->blk_vm_cbuf[s], vm->memory + base, BLOCK_SIZE);
blk_update(vm->blk_vm_lbn[s]);
uint8_t* fresh = blk_get_buffer(vm->blk_vm_lbn[s], 1);
if (fresh)
{
memcpy(fresh, vm->memory + base, BLOCK_SIZE);
blk_update(vm->blk_vm_lbn[s]);
}
vm->blk_vm_lbn[s] = 0;
vm->blk_vm_cbuf[s] = NULL;
vm->blk_vm_dirty[s] = 0;
@@ -230,13 +238,19 @@ static vaddr_t blk_vm_assign(VM *vm, uint32_t lbn) {
return BLK_VM_WINDOW_BASE + (vaddr_t)s * BLOCK_SIZE;
}
/* Sync all dirty slots to their C buffers and flush the subsystem. */
/* Sync all dirty slots to their C buffers and flush the subsystem.
* Re-resolve each buffer pointer by LBN rather than trusting the stored
* one -- see blk_vm_evict for why a stored pointer can go stale. */
static void blk_vm_flush_all(VM *vm) {
for (int i = 0; i < BLK_VM_SLOTS; i++) {
if (vm->blk_vm_cbuf[i] != NULL && vm->blk_vm_dirty[i]) {
vaddr_t base = BLK_VM_WINDOW_BASE + (vaddr_t)i * BLOCK_SIZE;
memcpy(vm->blk_vm_cbuf[i], vm->memory + base, BLOCK_SIZE);
blk_update(vm->blk_vm_lbn[i]);
uint8_t* fresh = blk_get_buffer(vm->blk_vm_lbn[i], 1);
if (fresh)
{
memcpy(fresh, vm->memory + base, BLOCK_SIZE);
blk_update(vm->blk_vm_lbn[i]);
}
vm->blk_vm_dirty[i] = 0;
}
}
@@ -267,14 +281,23 @@ void block_word_buffer(VM *vm) {
vm_push(vm, CELL(vaddr));
}
/* UPDATE ( -- ) : sync current SCR slot to C layer and mark dirty */
/* UPDATE ( -- ) : sync current SCR slot to C layer and mark dirty.
* Re-resolve the buffer pointer by LBN rather than trusting the stored
* one -- see blk_vm_evict for why a stored pointer can go stale. */
void block_word_update(VM *vm) {
cell_t blk = vm_load_cell(vm, vm->scr_addr);
if (blk == 0 || !blk_is_valid((uint32_t) blk)) { vm->error = 1; return; }
int s = blk_vm_find(vm, (uint32_t) blk);
if (s < 0) { vm->error = 1; return; }
vaddr_t base = BLK_VM_WINDOW_BASE + (vaddr_t)s * BLOCK_SIZE;
memcpy(vm->blk_vm_cbuf[s], vm->memory + base, BLOCK_SIZE);
uint8_t* fresh = blk_get_buffer((uint32_t)blk, 1);
if (!fresh)
{
vm->error = 1;
return;
}
memcpy(fresh, vm->memory + base, BLOCK_SIZE);
vm->blk_vm_cbuf[s] = fresh;
vm->blk_vm_dirty[s] = 1;
blk_update((uint32_t) blk);
}