From: Jin Qian <jinqian@android.com>
To: "Greg Hackmann" <ghackmann@google.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Jason Hu" <jia-cheng.hu@intel.com>,
"Christoffer Dall" <christoffer.dall@linaro.org>,
"Joe Perches" <joe@perches.com>,
"Peter Senna Tschudin" <peter.senna@gmail.com>,
"Yu Ning" <yu.ning@intel.com>,
linux-kernel@vger.kernel.org
Cc: Jin Qian <jinqian@android.com>
Subject: [PATCH 7/8] goldfish_pipe: Pass physical addresses to the device if supported
Date: Tue, 24 Nov 2015 17:10:11 -0800 [thread overview]
Message-ID: <1448413812-24289-8-git-send-email-jinqian@android.com> (raw)
In-Reply-To: <1448413812-24289-1-git-send-email-jinqian@android.com>
From: Yu Ning <yu.ning@intel.com>
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 08c7228c50f8 ("x86-kvm: only sync
SREGS when doing address translation") 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.
See https://android-review.googlesource.com/128280 for the QEMU-side
patch.
In addition, use the mmap semaphore (in read mode) to safeguard the
call to get_user_pages().
Signed-off-by: Yu Ning <yu.ning@intel.com>
(cherry picked from commit acf92a5c274dfbdfff877ed86bebc4b2b92fe1d9)
Signed-off-by: Jin Qian <jinqian@android.com>
---
drivers/platform/goldfish/goldfish_pipe.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c
index afc6f8d..a473aca 100644
--- a/drivers/platform/goldfish/goldfish_pipe.c
+++ b/drivers/platform/goldfish/goldfish_pipe.c
@@ -77,6 +77,7 @@
#define PIPE_REG_PARAMS_ADDR_LOW 0x18 /* read/write: batch data address */
#define PIPE_REG_PARAMS_ADDR_HIGH 0x1c /* read/write: batch data address */
#define PIPE_REG_ACCESS_PARAMS 0x20 /* write: batch access */
+#define PIPE_REG_VERSION 0x24 /* read: device version */
/* list of commands for PIPE_REG_COMMAND */
#define CMD_OPEN 1 /* open new channel */
@@ -126,6 +127,7 @@ struct goldfish_pipe_dev {
unsigned char __iomem *base;
struct access_params *aps;
int irq;
+ u32 version;
};
static struct goldfish_pipe_dev pipe_dev[1];
@@ -296,26 +298,43 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
int status, wakeBit;
struct page *page;
+ /* Either vaddr or paddr depending on the device version */
+ unsigned long xaddr;
+
/*
* We grab the pages on a page-by-page basis in case user
* space gives us a potentially huge buffer but the read only
* returns a small amount, then there's no need to pin that
* much memory to the process.
*/
+ down_read(¤t->mm->mmap_sem);
ret = get_user_pages(current, current->mm, address, 1,
!is_write, 0, &page, NULL);
+ up_read(¤t->mm->mmap_sem);
if (ret < 0)
return ret;
+ if (dev->version) {
+ /* Device version 1 or newer (qemu-android) expects the
+ * physical address.
+ */
+ xaddr = page_to_phys(page) | (address & ~PAGE_MASK);
+ } else {
+ /* Device version 0 (classic emulator) expects the
+ * virtual address.
+ */
+ xaddr = address;
+ }
+
/* Now, try to transfer the bytes in the current page */
spin_lock_irqsave(&dev->lock, irq_flags);
if (access_with_param(dev,
is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER,
- address, avail, pipe, &status)) {
+ xaddr, avail, pipe, &status)) {
gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
dev->base + PIPE_REG_CHANNEL_HIGH);
writel(avail, dev->base + PIPE_REG_SIZE);
- gf_write_ptr((void *)address,
+ gf_write_ptr((void *)xaddr,
dev->base + PIPE_REG_ADDRESS,
dev->base + PIPE_REG_ADDRESS_HIGH);
writel(is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER,
@@ -610,6 +629,12 @@ static int goldfish_pipe_probe(struct platform_device *pdev)
goto error;
}
setup_access_params_addr(pdev, dev);
+
+ /* Although the pipe device in the classic Android emulator does not
+ * recognize the 'version' register, it won't treat this as an error
+ * either and will simply return 0, which is fine.
+ */
+ dev->version = readl(dev->base + PIPE_REG_VERSION);
return 0;
error:
--
2.6.0.rc2.230.g3dd15c0
next prev parent reply other threads:[~2015-11-25 1:12 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1448413812-24289-1-git-send-email-jinqian@android.com>
2015-11-25 1:10 ` [PATCH 1/8] goldfish: refactor goldfish platform configs Jin Qian
2015-11-25 12:32 ` Alex Bennée
2015-11-25 1:10 ` [PATCH 2/8] android_pipe: don't be clever with #define offsets Jin Qian
2015-11-25 1:10 ` [PATCH 3/8] android_pipe: Pin pages to memory while copying and other cleanups Jin Qian
2015-11-25 1:10 ` [PATCH 4/8] platform: goldfish: pipe: add devicetree bindings Jin Qian
2015-11-25 11:22 ` Christoffer Dall
2015-11-25 1:10 ` [PATCH 5/8] platform: goldfish: pipe: don't log when dropping PIPE_ERROR_AGAIN Jin Qian
2015-11-25 1:10 ` [PATCH 6/8] [MIPS] Enable platform support for Goldfish virtual devices Jin Qian
2015-11-25 1:10 ` Jin Qian [this message]
2015-11-25 1:10 ` [PATCH 8/8] goldfish: Enable ACPI-based enumeration for android pipe Jin Qian
2016-01-06 14:03 [PATCH 0/8] Goldfish: partial resync with Google tree Alan
2016-01-06 14:06 ` [PATCH 7/8] goldfish_pipe: Pass physical addresses to the device if supported Alan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1448413812-24289-8-git-send-email-jinqian@android.com \
--to=jinqian@android.com \
--cc=alex.bennee@linaro.org \
--cc=christoffer.dall@linaro.org \
--cc=ghackmann@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=jia-cheng.hu@intel.com \
--cc=joe@perches.com \
--cc=linux-kernel@vger.kernel.org \
--cc=peter.senna@gmail.com \
--cc=yu.ning@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®