[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH RFC V4 1/5] xen: Emulate with no writes


  • To: Jan Beulich <JBeulich@xxxxxxxx>
  • From: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx>
  • Date: Tue, 05 Aug 2014 18:16:26 +0300
  • Cc: kevin.tian@xxxxxxxxx, ian.campbell@xxxxxxxxxx, stefano.stabellini@xxxxxxxxxxxxx, andrew.cooper3@xxxxxxxxxx, eddie.dong@xxxxxxxxx, xen-devel@xxxxxxxxxxxxx, jun.nakajima@xxxxxxxxx, ian.jackson@xxxxxxxxxxxxx
  • Comment: DomainKeys? See http://domainkeys.sourceforge.net/
  • Delivery-date: Tue, 05 Aug 2014 15:16:48 +0000
  • Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=bitdefender.com; b=Jl8X00e+jeLk6KxlgScCvBXF0JkvusJpdMH3DN2JucVH7f85HldIubn9QDFJXEM/8dNy7gsCKI+vNw2HSbGmlPYFn1Nu9QHiVeaf/9aAAGs6BtbSQzqCe6hvGLddRd9QKwh/laxENZX3rJQwJPr8/s6cqnCn50xTVlrVsJZ6Y/J4iYTGKT6/8IetetcKrq8nWFr6OTaIaZIuefTlxlB9629MB40NKJ96UxLCB1RHgNSjE5sC7LpZsXB/MEBhWRBjAHu1IzEksYRNUSQW5iYEHtCC5qaLR42ZNfI+1fcoexDw87V51qNb0fegUEoWkga6rGhAq+v44A3E5+MQpd7IiQ==; h=Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding:X-BitDefender-Scanner:X-BitDefender-Spam:X-BitDefender-SpamStamp:X-BitDefender-CF-Stamp;
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

On 08/04/2014 05:09 PM, Jan Beulich wrote:
>>>> On 04.08.14 at 13:30, <rcojocaru@xxxxxxxxxxxxxxx> wrote:
>> +static int hvmemul_rep_ins_discard(
>> +    uint16_t src_port,
>> +    enum x86_segment dst_seg,
>> +    unsigned long dst_offset,
>> +    unsigned int bytes_per_rep,
>> +    unsigned long *reps,
>> +    struct x86_emulate_ctxt *ctxt)
>> +{
>> +    return X86EMUL_OKAY;
>> +}
>> +
>> +static int hvmemul_rep_movs_discard(
>> +   enum x86_segment src_seg,
>> +   unsigned long src_offset,
>> +   enum x86_segment dst_seg,
>> +   unsigned long dst_offset,
>> +   unsigned int bytes_per_rep,
>> +   unsigned long *reps,
>> +   struct x86_emulate_ctxt *ctxt)
>> +{
>> +    return X86EMUL_OKAY;
>> +}
> 
> ... these don't seem to be: I don't think you can just drop the other
> half of the operation (i.e. the port or MMIO read).

I've been looking at hvmemul_do_io() (in arch/x86/hvm/emulate.c, line
52), which is what the above functions are reduced to. At line 88 I've
come across the following code:

 /*
  * Weird-sized accesses have undefined behaviour: we discard writes
  * and read all-ones.
  */
 if ( unlikely((size > sizeof(long)) || (size & (size - 1))) )
 {
     gdprintk(XENLOG_WARNING, "bad mmio size %d\n", size);
     ASSERT(p_data != NULL); /* cannot happen with a REP prefix */
     if ( dir == IOREQ_READ )
         memset(p_data, ~0, size);
     if ( ram_page )
         put_page(ram_page);
     return X86EMUL_UNHANDLEABLE;
 }

which does drop the last half of the function (though it does so by
returning X86EMUL_UNHANDLEABLE). Hvmemul_rep_ins() looks like this:

 static int hvmemul_rep_ins(
     uint16_t src_port,
     enum x86_segment dst_seg,
     unsigned long dst_offset,
     unsigned int bytes_per_rep,
     unsigned long *reps,
     struct x86_emulate_ctxt *ctxt)
 {
     struct hvm_emulate_ctxt *hvmemul_ctxt =
         container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
     unsigned long addr;
     uint32_t pfec = PFEC_page_present | PFEC_write_access;
     paddr_t gpa;
     p2m_type_t p2mt;
     int rc;

     rc = hvmemul_virtual_to_linear(
         dst_seg, dst_offset, bytes_per_rep, reps, hvm_access_write,
         hvmemul_ctxt, &addr);
     if ( rc != X86EMUL_OKAY )
         return rc;

     if ( hvmemul_ctxt->seg_reg[x86_seg_ss].attr.fields.dpl == 3 )
         pfec |= PFEC_user_mode;

     rc = hvmemul_linear_to_phys(
         addr, &gpa, bytes_per_rep, reps, pfec, hvmemul_ctxt);
     if ( rc != X86EMUL_OKAY )
         return rc;

     (void) get_gfn_query_unlocked(current->domain, gpa >> PAGE_SHIFT,
&p2mt);
     if ( p2mt == p2m_mmio_direct || p2mt == p2m_mmio_dm )
         return X86EMUL_UNHANDLEABLE;

     return hvmemul_do_pio(src_port, reps, bytes_per_rep, gpa, IOREQ_READ,
                           !!(ctxt->regs->eflags & X86_EFLAGS_DF), NULL);
 }

So if I understand this code correctly, hvmemul_rep_ins() performs a few
checks, and then calls hvmemul_do_pio(), which ends up calling
hvmemul_do_io(), which seems to discard the write rather unceremoniously
for weird-sized accesses. This would seem to roughly correspond to just
returning X86EMUL_UNHANDLEABLE from hvmemul_rep_ins() for that special
case (with no MMIO code executed).

Did I misunderstand something?


Thanks,
Razvan Cojocaru

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.