зеркало из https://github.com/microsoft/Komodo.git
87 строки
3.2 KiB
Plaintext
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);
|
|
}
|
|
}
|
|
}
|