def intremaps_equiv(conj, ctx, kernelstate): index = util.FreshBitVec('index', dt.size_t) # intremap index conj.append( z3.ForAll([index], z3.Implies( is_intremap_valid(index), util.global_field_element( ctx, '@intremap_table', 'state', index) == kernelstate.intremaps[index].state))) conj.append( z3.ForAll([index], z3.Implies( is_intremap_valid(index), util.global_field_element( ctx, '@intremap_table', 'devid', index) == kernelstate.intremaps[index].devid))) conj.append( z3.ForAll([index], z3.Implies( is_intremap_valid(index), util.global_field_element( ctx, '@intremap_table', 'vector', index) == kernelstate.intremaps[index].vector)))
def spec_lemma_nr_intremaps(kernelstate): conj = [] index = util.FreshBitVec('index', dt.size_t) # active intremaps have valid pid owners #valid(intremap_id) & intremap.state == IR_ACTIVE ==>valid(intemap.device's pci's pid) conj.append( z3.ForAll([index], z3.Implies( z3.And( is_intremap_valid(index), kernelstate.intremaps[index].state == dt.intremap_state.IR_ACTIVE), is_pid_valid(kernelstate.pci[ kernelstate.intremaps[index].devid].owner)))) # intremaps's vector and devid match conj.append( z3.ForAll([index], z3.Implies( z3.And( is_intremap_valid(index), kernelstate.intremaps[index].state == dt.intremap_state.IR_ACTIVE), kernelstate.pci[kernelstate.intremaps[index].devid].owner == kernelstate.vectors[ kernelstate.intremaps[index].vector].owner))) kernelstate.procs.nr_intremaps.check(conj, is_owner_valid=is_pid_valid, is_owned_valid=is_intremap_valid, max_refs=dt.NINTREMAP, ownerfn=lambda index0: \ util.If(kernelstate.intremaps[index0].state == dt.intremap_state.IR_ACTIVE, kernelstate.pci[kernelstate.intremaps[index0].devid].owner, 0)) return z3.And(*conj)
def sys_reclaim_intremap(old, index): pid = old.pci[old.intremaps[index].devid].owner cond = z3.And( # active index is_intremap_valid(index), old.intremaps[index].state == dt.intremap_state.IR_ACTIVE, is_pid_valid(pid), old.procs[pid].state == dt.proc_state.PROC_ZOMBIE ) new = old.copy() new.intremaps[index].state = dt.intremap_state.IR_FREE new.intremaps[index].devid = z3.BitVecVal(0, dt.devid_t) new.intremaps[index].vector = z3.BitVecVal(0, dt.uint8_t) new.procs[pid].nr_intremaps[index] -= 1 return cond, util.If(cond, new, old)
def sys_alloc_intremap(old, index, devid, vector): cond = z3.And( # valid and free index is_intremap_valid(index), old.intremaps[index].state == dt.intremap_state.IR_FREE, # current owns this devid old.pci[devid].owner == old.current, # current owns this vector old.vectors[vector].owner == old.current, ) new = old.copy() new.intremaps[index].state = dt.intremap_state.IR_ACTIVE new.intremaps[index].devid = devid new.intremaps[index].vector = vector new.procs[new.current].nr_intremaps[index] += 1 return cond, util.If(cond, new, old)