|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 02/16] x86/hvm: remove multiple open coded 'chunking' loops
On 30/06/15 14:05, Paul Durrant wrote:
> ...in hvmemul_read/write()
>
> Add hvmemul_phys_mmio_access() and hvmemul_linear_mmio_access() functions
> to reduce code duplication.
>
> NOTE: This patch also introduces a change in 'chunking' around a page
> boundary. Previously (for example) an 8 byte access at the last
> byte of a page would get carried out as 8 single-byte accesses.
> It will now be carried out as a single-byte access, followed by
> a 4-byte access, a 2-byte access and then another single-byte
> access.
>
> Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
> Cc: Keir Fraser <keir@xxxxxxx>
> Cc: Jan Beulich <jbeulich@xxxxxxxx>
> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> ---
> xen/arch/x86/hvm/emulate.c | 223
> +++++++++++++++++++++++---------------------
> 1 file changed, 116 insertions(+), 107 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
> index 8b60843..b67f5db 100644
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -539,6 +539,117 @@ static int hvmemul_virtual_to_linear(
> return X86EMUL_EXCEPTION;
> }
>
> +static int hvmemul_phys_mmio_access(
> + paddr_t gpa, unsigned int size, uint8_t dir, uint8_t *buffer)
> +{
> + unsigned long one_rep = 1;
> + unsigned int chunk;
> + int rc;
> +
> + /* Accesses must fall within a page */
Full stop.
> + BUG_ON((gpa & (PAGE_SIZE - 1)) + size > PAGE_SIZE);
~PAGE_MASK as opposed to (PAGE_SIZE - 1)
> +
> + /*
> + * hvmemul_do_io() cannot handle non-power-of-2 accesses or
> + * accesses larger than sizeof(long), so choose the highest power
> + * of 2 not exceeding sizeof(long) as the 'chunk' size.
> + */
> + chunk = 1 << (fls(size) - 1);
Depending on size, chunk can become undefined (shifting by 31 or -1) or
zero (shifting by 32).
How about
if ( size > sizeof(long) )
chunk = sizeof(long);
else
chunk = 1U << (fls(size) - 1);
?
> + if ( chunk > sizeof (long) )
> + chunk = sizeof (long);
> +
> + for ( ;; )
> + {
> + rc = hvmemul_do_mmio_buffer(gpa, &one_rep, chunk, dir, 0,
> + buffer);
> + if ( rc != X86EMUL_OKAY )
> + break;
> +
> + /* Advance to the next chunk */
Full stop.
> + gpa += chunk;
> + buffer += chunk;
> + size -= chunk;
> +
> + if ( size == 0 )
> + break;
> +
> + /*
> + * If the chunk now exceeds the remaining size, choose the next
> + * lowest power of 2 that will fit.
> + */
> + while ( chunk > size )
> + chunk >>= 1;
> + }
> +
> + return rc;
> +}
> +
> +static int hvmemul_linear_mmio_access(
> + unsigned long gla, unsigned int size, uint8_t dir, uint8_t *buffer,
> + uint32_t pfec, struct hvm_emulate_ctxt *hvmemul_ctxt, bool_t known_gpfn)
> +{
> + struct hvm_vcpu_io *vio = ¤t->arch.hvm_vcpu.hvm_io;
> + unsigned long page_off = gla & (PAGE_SIZE - 1);
Can be int as opposed to long, and "offset" appears to be the prevailing
name. Also, ~PAGE_MASK.
> + unsigned int chunk;
> + paddr_t gpa;
> + unsigned long one_rep = 1;
> + int rc;
> +
> + chunk = min_t(unsigned int, size, PAGE_SIZE - page_off);
> +
> + if ( known_gpfn )
> + gpa = pfn_to_paddr(vio->mmio_gpfn) | page_off;
> + else
> + {
> + rc = hvmemul_linear_to_phys(gla, &gpa, chunk, &one_rep, pfec,
> + hvmemul_ctxt);
> + if ( rc != X86EMUL_OKAY )
> + return rc;
> + }
> +
> + for ( ;; )
> + {
> + rc = hvmemul_phys_mmio_access(gpa, chunk, dir, buffer);
> + if ( rc != X86EMUL_OKAY )
> + break;
> +
> + gla += chunk;
> + buffer += chunk;
> + size -= chunk;
> +
> + if ( size == 0 )
> + break;
> +
> + ASSERT((gla & (PAGE_SIZE - 1)) == 0);
~PAGE_MASK.
> + ASSERT(size < PAGE_SIZE);
Nothing I can see here prevents size being greater than PAGE_SIZE.
chunk strictly will be, but size -= chunk can still leave size greater
than a page.
~Andrew
> + chunk = size;
> + rc = hvmemul_linear_to_phys(gla, &gpa, chunk, &one_rep, pfec,
> + hvmemul_ctxt);
> + if ( rc != X86EMUL_OKAY )
> + return rc;
> + }
> +
> + return rc;
> +}
> +
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |