Komodo/verified/stop.sdfy

87 строки
3.2 KiB
Plaintext

include {:verbatim} "kom_common.i.dfy"
include {:verbatim} "pagedb.i.dfy"
include {:verbatim} "smcapi.i.dfy"
include "ARMdecls.sdfy"
include "kom_utils.sdfy"
procedure kom_smc_stop(
operand as_page:reg,
operand pagedb_base:reg,
out operand err:reg,
ghost pagedb_in:PageDb)
returns (ghost pagedb:PageDb)
requires/ensures
SaneState(this);
requires
@as_page == OReg(R1) && @err == OReg(R0) && @pagedb_base == OReg(R12);
pagedb_base == AddressOfGlobal(PageDb());
validPageDb(pagedb_in);
pageDbCorresponds(this.m, pagedb_in);
reads
globals;
modifies
mem; r2; r3;
ensures
SmcProcedureInvariant(old(this), this);
tuple(pagedb, err) == smc_stop_premium(pagedb_in, old(as_page));
pageDbCorresponds(this.m, pagedb);
{
reveal smc_stop_premium;
pagedb := pagedb_in;
ghost var specResult := smc_stop_premium(pagedb, as_page);
if (as_page >= const(KOM_SECURE_NPAGES)) {
err := const(KOM_ERR_INVALID_ADDRSPACE);
} else {
assert validPageNr(as_page);
load_page_type(as_page, pagedb_base, r3, r3, pagedb);
if (r3 != const(KOM_PAGE_ADDRSPACE)) {
assert !isAddrspace(pagedb, as_page);
err := const(KOM_ERR_INVALID_ADDRSPACE);
assert err == specErr(specResult);
} else {
page_monvaddr_impl(r2, as_page, r3);
assert r2 == page_monvaddr(as_page);
r3 := const(KOM_ADDRSPACE_STOPPED);
assert r3 == pageDbAddrspaceStateVal(StoppedState);
STR(r3, r2, const(ADDRSPACE_STATE));
assert MemContents(this.m, page_monvaddr(as_page) +
ADDRSPACE_STATE) == pageDbAddrspaceStateVal(StoppedState);
assert pageDbCorrespondsOnly(this.m, specPageDb(specResult),
as_page)
by {
ghost var d' := specPageDb(specResult);
reveal_validPageDb();
reveal_pageContentsCorresponds();
reveal_pageDbAddrspaceCorresponds();
assert pageContentsCorresponds(as_page, d'[as_page],
extractPage(this.m, as_page));
reveal_pageDbEntryCorresponds();
assert pageDbEntryCorresponds(d'[as_page],
extractPageDbEntry(this.m, as_page));
}
assert pageDbCorrespondsExcluding(this.m,
specPageDb(specResult), as_page)
by {
reveal_validPageDb();
reveal_pageContentsCorresponds();
reveal_pageDbAddrspaceCorresponds();
ghost var d' := specPageDb(specResult);
assert pageDbCorrespondsExcluding(old(this).m, pagedb, as_page);
assert pageDbCorrespondsExcluding(this.m, pagedb, as_page)
by {
forall p :| validPageNr(p) && p != as_page ::
extractPage(this.m, p) == extractPage(old(this).m, p) {}
}
forall p :| validPageNr(p) && p != as_page :: pagedb[p] == d'[p] {}
}
err := const(KOM_ERR_SUCCESS);
assert err == specErr(specResult);
pagedb := specPageDb(specResult);
}
}
}