kernel_optimize_test/drivers/platform/goldfish/goldfish_pipe.c

672 lines
18 KiB
C
Raw Normal View History

/*
* Copyright (C) 2011 Google, Inc.
* Copyright (C) 2012 Intel, Inc.
* Copyright (C) 2013 Intel, Inc.
* Copyright (C) 2014 Linaro Limited
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/* This source file contains the implementation of a special device driver
* that intends to provide a *very* fast communication channel between the
* guest system and the QEMU emulator.
*
* Usage from the guest is simply the following (error handling simplified):
*
* int fd = open("/dev/qemu_pipe",O_RDWR);
* .... write() or read() through the pipe.
*
* This driver doesn't deal with the exact protocol used during the session.
* It is intended to be as simple as something like:
*
* // do this _just_ after opening the fd to connect to a specific
* // emulator service.
* const char* msg = "<pipename>";
* if (write(fd, msg, strlen(msg)+1) < 0) {
* ... could not connect to <pipename> service
* close(fd);
* }
*
* // after this, simply read() and write() to communicate with the
* // service. Exact protocol details left as an exercise to the reader.
*
* This driver is very fast because it doesn't copy any data through
* intermediate buffers, since the emulator is capable of translating
* guest user addresses into host ones.
*
* Note that we must however ensure that each user page involved in the
* exchange is properly mapped during a transfer.
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/goldfish.h>
#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/acpi.h>
/*
* IMPORTANT: The following constants must match the ones used and defined
* in external/qemu/hw/goldfish_pipe.c in the Android source tree.
*/
/* pipe device registers */
#define PIPE_REG_COMMAND 0x00 /* write: value = command */
#define PIPE_REG_STATUS 0x04 /* read */
#define PIPE_REG_CHANNEL 0x08 /* read/write: channel id */
#define PIPE_REG_CHANNEL_HIGH 0x30 /* read/write: channel id */
#define PIPE_REG_SIZE 0x0c /* read/write: buffer size */
#define PIPE_REG_ADDRESS 0x10 /* write: physical address */
#define PIPE_REG_ADDRESS_HIGH 0x34 /* write: physical address */
#define PIPE_REG_WAKES 0x14 /* read: wake flags */
#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 */
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
#define PIPE_REG_VERSION 0x24 /* read: device version */
/* list of commands for PIPE_REG_COMMAND */
#define CMD_OPEN 1 /* open new channel */
#define CMD_CLOSE 2 /* close channel (from guest) */
#define CMD_POLL 3 /* poll read/write status */
/* List of bitflags returned in status of CMD_POLL command */
#define PIPE_POLL_IN (1 << 0)
#define PIPE_POLL_OUT (1 << 1)
#define PIPE_POLL_HUP (1 << 2)
/* The following commands are related to write operations */
#define CMD_WRITE_BUFFER 4 /* send a user buffer to the emulator */
#define CMD_WAKE_ON_WRITE 5 /* tell the emulator to wake us when writing
is possible */
#define CMD_READ_BUFFER 6 /* receive a user buffer from the emulator */
#define CMD_WAKE_ON_READ 7 /* tell the emulator to wake us when reading
* is possible */
/* Possible status values used to signal errors - see goldfish_pipe_error_convert */
#define PIPE_ERROR_INVAL -1
#define PIPE_ERROR_AGAIN -2
#define PIPE_ERROR_NOMEM -3
#define PIPE_ERROR_IO -4
/* Bit-flags used to signal events from the emulator */
#define PIPE_WAKE_CLOSED (1 << 0) /* emulator closed pipe */
#define PIPE_WAKE_READ (1 << 1) /* pipe can now be read from */
#define PIPE_WAKE_WRITE (1 << 2) /* pipe can now be written to */
struct access_params {
unsigned long channel;
u32 size;
unsigned long address;
u32 cmd;
u32 result;
/* reserved for future extension */
u32 flags;
};
/* The global driver data. Holds a reference to the i/o page used to
* communicate with the emulator, and a wake queue for blocked tasks
* waiting to be awoken.
*/
struct goldfish_pipe_dev {
spinlock_t lock;
unsigned char __iomem *base;
struct access_params *aps;
int irq;
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
u32 version;
};
static struct goldfish_pipe_dev pipe_dev[1];
/* This data type models a given pipe instance */
struct goldfish_pipe {
struct goldfish_pipe_dev *dev;
struct mutex lock;
unsigned long flags;
wait_queue_head_t wake_queue;
};
/* Bit flags for the 'flags' field */
enum {
BIT_CLOSED_ON_HOST = 0, /* pipe closed by host */
BIT_WAKE_ON_WRITE = 1, /* want to be woken on writes */
BIT_WAKE_ON_READ = 2, /* want to be woken on reads */
};
static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd)
{
unsigned long flags;
u32 status;
struct goldfish_pipe_dev *dev = pipe->dev;
spin_lock_irqsave(&dev->lock, flags);
gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
dev->base + PIPE_REG_CHANNEL_HIGH);
writel(cmd, dev->base + PIPE_REG_COMMAND);
status = readl(dev->base + PIPE_REG_STATUS);
spin_unlock_irqrestore(&dev->lock, flags);
return status;
}
static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd)
{
unsigned long flags;
struct goldfish_pipe_dev *dev = pipe->dev;
spin_lock_irqsave(&dev->lock, flags);
gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL,
dev->base + PIPE_REG_CHANNEL_HIGH);
writel(cmd, dev->base + PIPE_REG_COMMAND);
spin_unlock_irqrestore(&dev->lock, flags);
}
/* This function converts an error code returned by the emulator through
* the PIPE_REG_STATUS i/o register into a valid negative errno value.
*/
static int goldfish_pipe_error_convert(int status)
{
switch (status) {
case PIPE_ERROR_AGAIN:
return -EAGAIN;
case PIPE_ERROR_NOMEM:
return -ENOMEM;
case PIPE_ERROR_IO:
return -EIO;
default:
return -EINVAL;
}
}
/*
* Notice: QEMU will return 0 for un-known register access, indicating
* param_acess is supported or not
*/
static int valid_batchbuffer_addr(struct goldfish_pipe_dev *dev,
struct access_params *aps)
{
u32 aph, apl;
u64 paddr;
aph = readl(dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
apl = readl(dev->base + PIPE_REG_PARAMS_ADDR_LOW);
paddr = ((u64)aph << 32) | apl;
if (paddr != (__pa(aps)))
return 0;
return 1;
}
/* 0 on success */
static int setup_access_params_addr(struct platform_device *pdev,
struct goldfish_pipe_dev *dev)
{
dma_addr_t dma_handle;
struct access_params *aps;
aps = dmam_alloc_coherent(&pdev->dev, sizeof(struct access_params),
&dma_handle, GFP_KERNEL);
if (!aps)
return -ENOMEM;
writel(upper_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
writel(lower_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_LOW);
if (valid_batchbuffer_addr(dev, aps)) {
dev->aps = aps;
return 0;
} else
return -1;
}
/* A value that will not be set by qemu emulator */
#define INITIAL_BATCH_RESULT (0xdeadbeaf)
static int access_with_param(struct goldfish_pipe_dev *dev, const int cmd,
unsigned long address, unsigned long avail,
struct goldfish_pipe *pipe, int *status)
{
struct access_params *aps = dev->aps;
if (aps == NULL)
return -1;
aps->result = INITIAL_BATCH_RESULT;
aps->channel = (unsigned long)pipe;
aps->size = avail;
aps->address = address;
aps->cmd = cmd;
writel(cmd, dev->base + PIPE_REG_ACCESS_PARAMS);
/*
* If the aps->result has not changed, that means
* that the batch command failed
*/
if (aps->result == INITIAL_BATCH_RESULT)
return -1;
*status = aps->result;
return 0;
}
static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
size_t bufflen, int is_write)
{
unsigned long irq_flags;
struct goldfish_pipe *pipe = filp->private_data;
struct goldfish_pipe_dev *dev = pipe->dev;
unsigned long address, address_end;
int count = 0, ret = -EINVAL;
/* If the emulator already closed the pipe, no need to go further */
if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
return -EIO;
/* Null reads or writes succeeds */
if (unlikely(bufflen == 0))
return 0;
/* Check the buffer range for access */
if (!access_ok(is_write ? VERIFY_WRITE : VERIFY_READ,
buffer, bufflen))
return -EFAULT;
/* Serialize access to the pipe */
if (mutex_lock_interruptible(&pipe->lock))
return -ERESTARTSYS;
address = (unsigned long)(void *)buffer;
address_end = address + bufflen;
while (address < address_end) {
unsigned long page_end = (address & PAGE_MASK) + PAGE_SIZE;
unsigned long next = page_end < address_end ? page_end
: address_end;
unsigned long avail = next - address;
int status, wakeBit;
struct page *page;
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
/* 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.
*/
ret = get_user_pages_unlocked(address, 1, &page,
is_write ? 0 : FOLL_WRITE);
if (ret < 0)
break;
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
if (dev->version) {
/* Device version 1 or newer (qemu-android) expects the
* physical address.
*/
xaddr = page_to_phys(page) | (address & ~PAGE_MASK);
} else {
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
/* 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,
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
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);
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
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,
dev->base + PIPE_REG_COMMAND);
status = readl(dev->base + PIPE_REG_STATUS);
}
spin_unlock_irqrestore(&dev->lock, irq_flags);
if (status > 0 && !is_write)
set_page_dirty(page);
put_page(page);
if (status > 0) { /* Correct transfer */
count += status;
address += status;
continue;
} else if (status == 0) { /* EOF */
ret = 0;
break;
} else if (status < 0 && count > 0) {
/*
* An error occurred and we already transferred
* something on one of the previous pages.
* Just return what we already copied and log this
* err.
*
* Note: This seems like an incorrect approach but
* cannot change it until we check if any user space
* ABI relies on this behavior.
*/
if (status != PIPE_ERROR_AGAIN)
pr_info_ratelimited("goldfish_pipe: backend returned error %d on %s\n",
status, is_write ? "write" : "read");
ret = 0;
break;
}
/*
* If the error is not PIPE_ERROR_AGAIN, or if we are not in
* non-blocking mode, just return the error code.
*/
if (status != PIPE_ERROR_AGAIN ||
(filp->f_flags & O_NONBLOCK) != 0) {
ret = goldfish_pipe_error_convert(status);
break;
}
/*
* The backend blocked the read/write, wait until the backend
* tells us it's ready to process more data.
*/
wakeBit = is_write ? BIT_WAKE_ON_WRITE : BIT_WAKE_ON_READ;
set_bit(wakeBit, &pipe->flags);
/* Tell the emulator we're going to wait for a wake event */
goldfish_cmd(pipe,
is_write ? CMD_WAKE_ON_WRITE : CMD_WAKE_ON_READ);
/* Unlock the pipe, then wait for the wake signal */
mutex_unlock(&pipe->lock);
while (test_bit(wakeBit, &pipe->flags)) {
if (wait_event_interruptible(
pipe->wake_queue,
!test_bit(wakeBit, &pipe->flags)))
return -ERESTARTSYS;
if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
return -EIO;
}
/* Try to re-acquire the lock */
if (mutex_lock_interruptible(&pipe->lock))
return -ERESTARTSYS;
}
mutex_unlock(&pipe->lock);
if (ret < 0)
return ret;
else
return count;
}
static ssize_t goldfish_pipe_read(struct file *filp, char __user *buffer,
size_t bufflen, loff_t *ppos)
{
return goldfish_pipe_read_write(filp, buffer, bufflen, 0);
}
static ssize_t goldfish_pipe_write(struct file *filp,
const char __user *buffer, size_t bufflen,
loff_t *ppos)
{
return goldfish_pipe_read_write(filp, (char __user *)buffer,
bufflen, 1);
}
static unsigned int goldfish_pipe_poll(struct file *filp, poll_table *wait)
{
struct goldfish_pipe *pipe = filp->private_data;
unsigned int mask = 0;
int status;
mutex_lock(&pipe->lock);
poll_wait(filp, &pipe->wake_queue, wait);
status = goldfish_cmd_status(pipe, CMD_POLL);
mutex_unlock(&pipe->lock);
if (status & PIPE_POLL_IN)
mask |= POLLIN | POLLRDNORM;
if (status & PIPE_POLL_OUT)
mask |= POLLOUT | POLLWRNORM;
if (status & PIPE_POLL_HUP)
mask |= POLLHUP;
if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
mask |= POLLERR;
return mask;
}
static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id)
{
struct goldfish_pipe_dev *dev = dev_id;
unsigned long irq_flags;
int count = 0;
/*
* We're going to read from the emulator a list of (channel,flags)
* pairs corresponding to the wake events that occurred on each
* blocked pipe (i.e. channel).
*/
spin_lock_irqsave(&dev->lock, irq_flags);
for (;;) {
/* First read the channel, 0 means the end of the list */
struct goldfish_pipe *pipe;
unsigned long wakes;
unsigned long channel = 0;
#ifdef CONFIG_64BIT
channel = (u64)readl(dev->base + PIPE_REG_CHANNEL_HIGH) << 32;
if (channel == 0)
break;
#endif
channel |= readl(dev->base + PIPE_REG_CHANNEL);
if (channel == 0)
break;
/* Convert channel to struct pipe pointer + read wake flags */
wakes = readl(dev->base + PIPE_REG_WAKES);
pipe = (struct goldfish_pipe *)(ptrdiff_t)channel;
/* Did the emulator just closed a pipe? */
if (wakes & PIPE_WAKE_CLOSED) {
set_bit(BIT_CLOSED_ON_HOST, &pipe->flags);
wakes |= PIPE_WAKE_READ | PIPE_WAKE_WRITE;
}
if (wakes & PIPE_WAKE_READ)
clear_bit(BIT_WAKE_ON_READ, &pipe->flags);
if (wakes & PIPE_WAKE_WRITE)
clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags);
wake_up_interruptible(&pipe->wake_queue);
count++;
}
spin_unlock_irqrestore(&dev->lock, irq_flags);
return (count == 0) ? IRQ_NONE : IRQ_HANDLED;
}
/**
* goldfish_pipe_open - open a channel to the AVD
* @inode: inode of device
* @file: file struct of opener
*
* Create a new pipe link between the emulator and the use application.
* Each new request produces a new pipe.
*
* Note: we use the pipe ID as a mux. All goldfish emulations are 32bit
* right now so this is fine. A move to 64bit will need this addressing
*/
static int goldfish_pipe_open(struct inode *inode, struct file *file)
{
struct goldfish_pipe *pipe;
struct goldfish_pipe_dev *dev = pipe_dev;
int32_t status;
/* Allocate new pipe kernel object */
pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
if (pipe == NULL)
return -ENOMEM;
pipe->dev = dev;
mutex_init(&pipe->lock);
init_waitqueue_head(&pipe->wake_queue);
/*
* Now, tell the emulator we're opening a new pipe. We use the
* pipe object's address as the channel identifier for simplicity.
*/
status = goldfish_cmd_status(pipe, CMD_OPEN);
if (status < 0) {
kfree(pipe);
return status;
}
/* All is done, save the pipe into the file's private data field */
file->private_data = pipe;
return 0;
}
static int goldfish_pipe_release(struct inode *inode, struct file *filp)
{
struct goldfish_pipe *pipe = filp->private_data;
/* The guest is closing the channel, so tell the emulator right now */
goldfish_cmd(pipe, CMD_CLOSE);
kfree(pipe);
filp->private_data = NULL;
return 0;
}
static const struct file_operations goldfish_pipe_fops = {
.owner = THIS_MODULE,
.read = goldfish_pipe_read,
.write = goldfish_pipe_write,
.poll = goldfish_pipe_poll,
.open = goldfish_pipe_open,
.release = goldfish_pipe_release,
};
static struct miscdevice goldfish_pipe_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "goldfish_pipe",
.fops = &goldfish_pipe_fops,
};
static int goldfish_pipe_probe(struct platform_device *pdev)
{
int err;
struct resource *r;
struct goldfish_pipe_dev *dev = pipe_dev;
/* not thread safe, but this should not happen */
WARN_ON(dev->base != NULL);
spin_lock_init(&dev->lock);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL || resource_size(r) < PAGE_SIZE) {
dev_err(&pdev->dev, "can't allocate i/o page\n");
return -EINVAL;
}
dev->base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE);
if (dev->base == NULL) {
dev_err(&pdev->dev, "ioremap failed\n");
return -EINVAL;
}
r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (r == NULL) {
err = -EINVAL;
goto error;
}
dev->irq = r->start;
err = devm_request_irq(&pdev->dev, dev->irq, goldfish_pipe_interrupt,
IRQF_SHARED, "goldfish_pipe", dev);
if (err) {
dev_err(&pdev->dev, "unable to allocate IRQ\n");
goto error;
}
err = misc_register(&goldfish_pipe_device);
if (err) {
dev_err(&pdev->dev, "unable to register device\n");
goto error;
}
setup_access_params_addr(pdev, dev);
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 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> Signed-off-by: Jin Qian <jinqian@android.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-01-06 22:06:40 +08:00
/* 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:
dev->base = NULL;
return err;
}
static int goldfish_pipe_remove(struct platform_device *pdev)
{
struct goldfish_pipe_dev *dev = pipe_dev;
misc_deregister(&goldfish_pipe_device);
dev->base = NULL;
return 0;
}
static const struct acpi_device_id goldfish_pipe_acpi_match[] = {
{ "GFSH0003", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, goldfish_pipe_acpi_match);
static const struct of_device_id goldfish_pipe_of_match[] = {
{ .compatible = "google,android-pipe", },
{},
};
MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match);
static struct platform_driver goldfish_pipe = {
.probe = goldfish_pipe_probe,
.remove = goldfish_pipe_remove,
.driver = {
.name = "goldfish_pipe",
.owner = THIS_MODULE,
.of_match_table = goldfish_pipe_of_match,
.acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match),
}
};
module_platform_driver(goldfish_pipe);
MODULE_AUTHOR("David Turner <digit@google.com>");
MODULE_LICENSE("GPL");