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

Reply via email to