On Mon, Apr 10, 2017 at 3:44 AM, Razvan Cojocaru <rcojoc...@bitdefender.com> wrote:
> This patch adds support for testing instruction emulation when > required by the vm_event reply sent for MEM_ACCESS events. To this > end, it adds the "emulate_write" and "emulate_exec" parameters > that behave like the old "write" and "exec" parameters, except > instead of allowing writes / executes for a hit page, they emulate > the trigger instruction. The new parameters don't mark all of the > guest's pages, instead they stop at the arbitrary low limit of > the first 1000 pages - otherwise the guest would slow to a crawl. > Since the emulator is still incomplete and has trouble with > emulating competing writes in SMP scenarios, the new tests are > only meant for debugging issues. > > Signed-off-by: Razvan Cojocaru <rcojoc...@bitdefender.com> > --- > tools/tests/xen-access/xen-access.c | 38 ++++++++++++++++++++++++++++-- > ------- > 1 file changed, 29 insertions(+), 9 deletions(-) > > diff --git a/tools/tests/xen-access/xen-access.c > b/tools/tests/xen-access/xen-access.c > index ff4d289..0ba2e45 100644 > --- a/tools/tests/xen-access/xen-access.c > +++ b/tools/tests/xen-access/xen-access.c > @@ -335,7 +335,7 @@ static void put_response(vm_event_t *vm_event, > vm_event_response_t *rsp) > > void usage(char* progname) > { > - fprintf(stderr, "Usage: %s [-m] <domain_id> write|exec", progname); > + fprintf(stderr, "Usage: %s [-m] <domain_id> > write|exec|emulate_write|emulate_exec", > progname); > These options are only for x86, so they need to be moved into the #if block below. > #if defined(__i386__) || defined(__x86_64__) > fprintf(stderr, "|breakpoint|altp2m_write| > altp2m_exec|debug|cpuid|desc_access"); > #elif defined(__arm__) || defined(__aarch64__) > @@ -369,6 +369,7 @@ int main(int argc, char *argv[]) > int debug = 0; > int cpuid = 0; > int desc_access = 0; > + int emulate = 0; > uint16_t altp2m_view_id = 0; > > char* progname = argv[0]; > @@ -404,12 +405,26 @@ int main(int argc, char *argv[]) > after_first_access = XENMEM_access_rwx; > memaccess = 1; > } > + else if ( !strcmp(argv[0], "emulate_write") ) > + { > + default_access = XENMEM_access_rx; > + after_first_access = XENMEM_access_rwx; > Setting after_first_access not needed. + emulate = 1; > + memaccess = 1; > + } > else if ( !strcmp(argv[0], "exec") ) > { > default_access = XENMEM_access_rw; > after_first_access = XENMEM_access_rwx; > memaccess = 1; > } > + else if ( !strcmp(argv[0], "emulate_exec") ) > + { > + default_access = XENMEM_access_rw; > + after_first_access = XENMEM_access_rwx; > Setting after_first_access not needed. > > + emulate = 1; > + memaccess = 1; > + } > #if defined(__i386__) || defined(__x86_64__) > else if ( !strcmp(argv[0], "breakpoint") ) > { > @@ -536,7 +551,7 @@ int main(int argc, char *argv[]) > } > > rc = xc_set_mem_access(xch, domain_id, default_access, START_PFN, > - (xenaccess->max_gpfn - START_PFN) ); > + emulate ? 1000 : (xenaccess->max_gpfn - > START_PFN)); > Why only 1000? What if the domain has less then 1000? > > if ( rc < 0 ) > { > @@ -702,15 +717,20 @@ int main(int argc, char *argv[]) > } > else if ( default_access != after_first_access ) > { > - rc = xc_set_mem_access(xch, domain_id, > after_first_access, > - req.u.mem_access.gfn, 1); > - if (rc < 0) > + if ( !emulate ) > { > - ERROR("Error %d setting gfn to access_type %d\n", > rc, > - after_first_access); > - interrupted = -1; > - continue; > + rc = xc_set_mem_access(xch, domain_id, > after_first_access, > + req.u.mem_access.gfn, 1); > + if (rc < 0) > + { > + ERROR("Error %d setting gfn to access_type > %d\n", rc, > + after_first_access); > + interrupted = -1; > + continue; > + } > } > + else > + rsp.flags |= VM_EVENT_FLAG_EMULATE; > } > > rsp.u.mem_access = req.u.mem_access; > -- > 1.9.1 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > https://lists.xen.org/xen-devel >
_______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel