Classic emulator : Goldfish Pipe - Use guest physical address for buffer read/write

311 views
Skip to first unread message

Miodrag Dinic

unread,
Sep 18, 2015, 2:09:51 PM9/18/15
to Android emulator development
Hello everyone,

I've uploaded a backported solution for using physical addresses with Goldfish Pipe device for the classic emulator :


Solution was originally written for qemu2 (qemu-android) and kernel android-goldfish-3.10 branch but it is completely applicable for the classic emulator.
It's a much cleaner and optimized solution since it does not require cpu_phys_page_debug() function anymore, because it uses PA addresses from the kernel directly.

Copy from original commits :

Goldfish Kernel - android-goldfish-3.10 branch 

commit ca8dafc623c6956fad77df80540a1e31f5f8fe2b
Author: Christoffer Dall <christof...@linaro.org>
Date:   Mon Jun 23 12:53:39 2014 +0200

    android_pipe: Pin pages to memory while copying and other cleanups
    
    The existing code had a troubling TODO statement concerning the fact
    that it just did a check if the page that the QEMU backend was going to
    read from / write to was there before the call to the QEMU backend and
    then relying on the fact that the page stayed around, even in a
    preemptible SMP kernel.  Obviously the page could go away or be
    reassigned, and strange things may happen.
    
    Further, writes were not tracked, so any use of COW or KSM-like features
    would break completely.  Probably that was never used by adbd (the only
    current active user of the pipe), but could prove much more dangerous
    for the GPU passthrough mechanism.
    
    Instead, use get_user_pages() as the comment suggested and cleanup the
    error path and add the set_page_dirt() call on a successful read
    operation.
    
    Also clarify the count used to return from successful read/write calls
    and use Linux style commentary in various places of the file.
    
    Note: The "just ignore error and return whatever we read so far" error
    handling is really quite horrific.  I cannot change it without a more
    careful study of all user space ABIs reliance on this 'feature'.
    
    Signed-off-by: Christoffer Dall <christof...@linaro.org>
    
    Conflicts:
        drivers/platform/goldfish/goldfish_pipe.c
    
    Change-Id: Ib4e5dd6612781072d617f69f67f3991b946dae36

------------------------------------------------------------------------------------------------------------------------------

commit acf92a5c274dfbdfff877ed86bebc4b2b92fe1d9
Author: Yu Ning <yu....@intel.com>
Date:   Mon Feb 2 23:26:18 2015 +0800

    goldfish_pipe: Pass physical addresses to the device if supported
    
    For reading and writing guest user space buffers, currently the kernel
    sends the guest virtual address of the buffer to the pipe device. This
    virtual address has to be first converted to a guest physical address.
    Doing this translation on the QEMU side is inefficient and requires
    additional handling when KVM is enabled, whose implementation would
    either incur intrusive changes to QEMU's KVM support code or suffer
    from poor performance (see commit 08c7228 of $AOSP/external/qemu for
    details), and thus should be avoided if possible.
    
    There is a TODO comment in hw/misc/android_pipe.c in the new Android
    emulator source tree ($AOSP/external/qemu-android) which requests that
    the translation be done on the kernel side and that physical addresses
    be passed to the device instead of virtual ones. Once the QEMU-side
    implementation is done, the kernel will need to support both the new
    paddr-based pipe device and the old vaddr-based one (which will
    continue to be used by the classic emulator). This patch achieves that
    by leveraging the device version register available in the new device.
    
    patch.
    
    In addition, use the mmap semaphore (in read mode) to safeguard the
    call to get_user_pages().
    
    Change-Id: I29a53ee7b07a01c98cc0ad26b3705dce077dde33
    Signed-off-by: Yu Ning <yu....@intel.com>

==================================================================================

external/qemu-android/

commit 10c79ce0959875f1f72b69c34f8df2e09f11adcc
Author: Yu Ning <yu....@intel.com>
Date:   Mon Feb 2 22:36:50 2015 +0800

    android_pipe: Use guest physical address for buffer read/write
    
    For reading and writing guest user space buffers, currently the kernel
    sends the guest virtual address of the buffer to the pipe device. This
    virtual address has to be first converted to a guest physical address.
    Doing this translation on the QEMU side is inefficient and requires
    additional handling when KVM is enabled, whose implementation would
    either incur intrusive changes to QEMU's KVM support code or suffer
    from poor performance (see commit 08c7228 of $AOSP/external/qemu for
    details), and thus should be avoided if possible.
    
    There is a TODO comment on map_guest_buffer() (hw/misc/android_pipe.c)
    which requests that the translation be done on the kernel side and that
    physical addresses be passed to the device instead of virtual ones.
    This patch implements the QEMU-side changes.
    
    In order to allow the kernel to work with both the new (paddr-based)
    and the old (vaddr-based) pipe devices, a read-only register is added
    to the new device, which is read by the pipe driver to obtain the
    version of the device. The new pipe device is assigned a non-zero
    version number (currently 1), while the old device automatically gets
    version 0 because it simply returns 0 on read of any unknown register.
    This way, the driver can tell which version of the emulator is running
    on the host, and then sends either the virtual or the physical address
    for buffer read/write.
    
    patch.
    
    Change-Id: Icbc0bdc58b13219e380baea2097011225380e72c
    Signed-off-by: Yu Ning <yu....@intel.com>

=================================================================================

Pretty much everything said in the original commits is in place for the classic emulator Goldfish Pipe device/driver as well.
Once we have this solution submitted and put in use, we would not have any discrepancy between classic emulator and qemu2 in regards to Goldfish Pipe,
both of them will use the same approach.

I'll be happy to address any comments, here or in gerrit if you have any questions.

Regards,
Miodrag

Reply all
Reply to author
Forward
0 new messages