pub struct Caches;
Expand description
Cache maintenance functions.
Role of Cache Maintenance in the Fuzzer
The fuzzer does a lot of modifications on the virtual address space of fuzzed programs at runtime (e.g. adding breakpoints for hooks) and for these changes to be taken into account, we need to flush caches.
Fuzzer Cache Maintenance
The hypervisor doesn’t allow cache maintenance outside of the applevisor::Vcpu
, which
forces us to create handlers for this purpose in the Vcpu’s address space.
These handlers are found at address HANDLERS_ADDR
.
+---------------+ <--- HANDLERS_ADDR + 0x000
| |
| IC IVAU |
| handler |
| |
+---------------+ <--- HANDLERS_ADDR + 0x080
| |
| TLBI VAAE1 |
| handler |
| |
+---------------+ <--- HANDLERS_ADDR + 0x100
| |
• •
• •
• •
In order to keep the number of context-switches between the fuzzer and the hypervisor to a minimum, the handlers are written in such a way that they jump back to where we originally stopped the exectution.
+-----------------+
| NORMAL |
| EXECUTION |<-----------------+
+--------+--------+ |
EL0 | |
-------------------|---------------------------|-----------------------
EL1 | |
v |
+--------+--------+ +--------+--------+
| EXCEPTION FROM | | CACHE |
| THE GUEST | | MAINTENANCE |
+--------+--------+ +--------+--------+
| ^
FUZZER | |
-------------------|---------------------------|-----------------------
HYPERVISOR | |
v |
+--------+--------+ +--------+--------+
| EXCEPTION |-------->| SETUP CACHE |
| HANDLING | | MAINTENANCE |
+-----------------+ +-----------------+
Before resuming the execution of the Vcpu and entering the cache maintenance handler, we
store the address we want to return to, as well as other state registers, on a dedicated stack
mapped at address STACK_ADDR
. The handler is entered at EL1, the cache maintenance
operation is performed, the original state is loaded and we perform an eret
instruction to
resume the execution at the original exception level.
Implementations
sourceimpl Caches
impl Caches
sourcepub fn init(vcpu: &mut Vcpu, vma: &mut VirtMemAllocator) -> Result<()>
pub fn init(vcpu: &mut Vcpu, vma: &mut VirtMemAllocator) -> Result<()>
Maps and writes the cache maintenance handlers at address HANDLERS_ADDR
.
sourcepub fn ic_ivau(vcpu: &mut Vcpu, vma: &mut VirtMemAllocator) -> Result<()>
pub fn ic_ivau(vcpu: &mut Vcpu, vma: &mut VirtMemAllocator) -> Result<()>
Instruction cache invalidation handler.
Executes a IC IVAU
instruction, which invalidates the instruction cache by virtual
address to point of unification.
sourcepub fn tlbi_vmalle1_ic_ialluis(
vcpu: &mut Vcpu,
vma: &mut VirtMemAllocator
) -> Result<()>
pub fn tlbi_vmalle1_ic_ialluis(
vcpu: &mut Vcpu,
vma: &mut VirtMemAllocator
) -> Result<()>
Translation Lookaside Buffer invalidation and instruction cache invalidation handler.
Executes a TLBI VMALLE1
instruction to invalidate the whole TLB followed by a IC ALLUIS
instruction to flush the entire instruction cache.
sourcepub fn tlbi_vaae1_on_fault(
vcpu: &mut Vcpu,
vma: &mut VirtMemAllocator
) -> Result<()>
pub fn tlbi_vaae1_on_fault(
vcpu: &mut Vcpu,
vma: &mut VirtMemAllocator
) -> Result<()>
Translation Lookaside Buffer entry invalidation handler used during a data abort.
Executes a TLBI VAAE1
instruction, which invalidates cached copies of translation table
entries from TLBs.
sourcepub fn tlbi_vaae1(
vcpu: &mut Vcpu,
vma: &mut VirtMemAllocator,
addr: u64
) -> Result<()>
pub fn tlbi_vaae1(
vcpu: &mut Vcpu,
vma: &mut VirtMemAllocator,
addr: u64
) -> Result<()>
Translation Lookaside Buffer entry invalidation handler.
Executes a TLBI VAAE1
instruction, which invalidates cached copies of translation table
entries from TLBs.