Browse Source

Fix pointer masking for misaligned accesses

Pointer masking needs to be reapplied after computing the address of the
tail of a misaligned access in case there's a carry-out into the MSBs.

Resolves #1895
pull/1905/head
Andrew Waterman 2 years ago
parent
commit
aa9918bd54
  1. 12
      riscv/mmu.cc
  2. 4
      riscv/mmu.h

12
riscv/mmu.cc

@ -241,8 +241,10 @@ void mmu_t::load_slow_path(reg_t original_addr, reg_t len, uint8_t* bytes, xlate
reg_t len_page0 = std::min(len, PGSIZE - transformed_addr % PGSIZE);
load_slow_path_intrapage(len_page0, bytes, access_info);
if (len_page0 != len)
load_slow_path_intrapage(len - len_page0, bytes + len_page0, access_info.split_misaligned_access(len_page0));
if (len_page0 != len) {
auto tail_access_info = generate_access_info(original_addr + len_page0, LOAD, xlate_flags);
load_slow_path_intrapage(len - len_page0, bytes + len_page0, tail_access_info);
}
}
while (len > sizeof(reg_t)) {
@ -306,8 +308,10 @@ void mmu_t::store_slow_path(reg_t original_addr, reg_t len, const uint8_t* bytes
reg_t len_page0 = std::min(len, PGSIZE - transformed_addr % PGSIZE);
store_slow_path_intrapage(len_page0, bytes, access_info, actually_store);
if (len_page0 != len)
store_slow_path_intrapage(len - len_page0, bytes + len_page0, access_info.split_misaligned_access(len_page0), actually_store);
if (len_page0 != len) {
auto tail_access_info = generate_access_info(original_addr + len_page0, STORE, xlate_flags);
store_slow_path_intrapage(len - len_page0, bytes + len_page0, tail_access_info, actually_store);
}
} else {
store_slow_path_intrapage(len, bytes, access_info, actually_store);
}

4
riscv/mmu.h

@ -57,10 +57,6 @@ struct mem_access_info_t {
const bool effective_virt;
const xlate_flags_t flags;
const access_type type;
mem_access_info_t split_misaligned_access(reg_t offset) const {
return {vaddr + offset, transformed_vaddr + offset, effective_priv, effective_virt, flags, type};
}
};
void throw_access_exception(bool virt, reg_t addr, access_type type);

Loading…
Cancel
Save