From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: Re: [PATCH v4 17/17] x86/hvm: track large memory mapped accesses by buffer offset Date: Thu, 25 Jun 2015 11:46:50 +0100 Message-ID: <558BF83A02000078000897E7@mail.emea.novell.com> References: <1435145089-21999-1-git-send-email-paul.durrant@citrix.com> <1435145089-21999-18-git-send-email-paul.durrant@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Z84gH-0005rG-Nx for xen-devel@lists.xenproject.org; Thu, 25 Jun 2015 10:46:53 +0000 In-Reply-To: <1435145089-21999-18-git-send-email-paul.durrant@citrix.com> Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Paul Durrant Cc: Andrew Cooper , Keir Fraser , xen-devel@lists.xenproject.org List-Id: xen-devel@lists.xenproject.org >>> On 24.06.15 at 13:24, wrote: > @@ -621,14 +574,41 @@ static int hvmemul_phys_mmio_access( > > for ( ;; ) > { > - rc = hvmemul_do_mmio_buffer(gpa, &one_rep, chunk, dir, 0, > - *buffer); > - if ( rc != X86EMUL_OKAY ) > - break; > + /* Have we already done this chunk? */ > + if ( (*off + chunk) <= vio->mmio_cache[dir].size ) I can see why you would like to get rid of the address check, but I'm afraid you can't: You have to avoid getting mixed up multiple same kind (reads or writes) memory accesses that a single instruction can do. While generally I would assume that secondary accesses (like the I/O bitmap read associated with an OUTS) wouldn't go to MMIO, CMPS with both operands being in MMIO would break even if neither crosses a page boundary (not to think of when the emulator starts supporting the scatter/gather instructions, albeit supporting them will require further changes, or we could choose to do them one element at a time). > + { > + ASSERT(*off + chunk <= vio->mmio_cache[dir].size); I don't see any difference to the if() expression just above. > + if ( dir == IOREQ_READ ) > + memcpy(&buffer[*off], > + &vio->mmio_cache[IOREQ_READ].buffer[*off], > + chunk); > + else > + { > + if ( memcmp(&buffer[*off], "else if" please. > + &vio->mmio_cache[IOREQ_WRITE].buffer[*off], > + chunk) != 0 ) > + domain_crash(curr->domain); > + } > + } > + else > + { > + ASSERT(*off == vio->mmio_cache[dir].size); > + > + rc = hvmemul_do_mmio_buffer(gpa, &one_rep, chunk, dir, 0, > + &buffer[*off]); > + if ( rc != X86EMUL_OKAY ) > + break; > + > + /* Note that we have now done this chunk */ Missing stop. Jan