Enable adb with android-pipe in IA image
authorLizhe Liu <lizhe.liu@intel.com>
Tue, 13 Oct 2015 05:27:20 +0000 (13:27 +0800)
committerJohn Stultz <john.stultz@linaro.org>
Tue, 16 Feb 2016 21:54:21 +0000 (13:54 -0800)
To enable adb for x86/x86_64 Brillo emulator, we bring
drivers/platform/goldfish/ in kernel/common (branch android-3.18)
up to date with that in kernel/goldfish
(branch android-goldfish-3.10), by porting the following patches:

044d26f goldfish: Enable ACPI-based enumeration for android pipe
acf92a5 goldfish_pipe: Pass physical addresses to the device if supported
77559b0 [MIPS] Enable platform support for Goldfish virtual devices
1bebc76 platform: goldfish: pipe: don't log when dropping PIPE_ERROR_AGAIN
3c56d07 platform: goldfish: pipe: add devicetree bindings
ca8dafc android_pipe: Pin pages to memory while copying and other cleanups
b765d47 android_pipe: don't be clever with #define offsets
7119108 goldfish: refactor goldfish platform configs
dc02035 goldfish: fix kernel panic when using multiple adb connection

Change-Id: Ic4f2f5e43ba2a70831d6a12a370417984f784dbc
Signed-off-by: Lizhe Liu <lizhe.liu@intel.com>
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
Signed-off-by: Jason Hu <jia-cheng.hu@intel.com>
Signed-off-by: Yu Ning <yu.ning@intel.com>
drivers/platform/Kconfig
drivers/platform/goldfish/Kconfig
drivers/platform/goldfish/Makefile
drivers/platform/goldfish/goldfish_pipe.c

index 0adccbf5c83f116bd698c392c47b75a9197f892f..5bd93a25d2ce75d118e565f230963784bb409a06 100644 (file)
@@ -4,8 +4,6 @@ endif
 if MIPS
 source "drivers/platform/mips/Kconfig"
 endif
-if GOLDFISH
 source "drivers/platform/goldfish/Kconfig"
-endif
 
 source "drivers/platform/chrome/Kconfig"
index 635ef25cc722a0c01ee13fd95ddfe78b6bbd6f39..f4f00f75d267c016b1e1482aa4a7a39f06b29d7d 100644 (file)
@@ -1,5 +1,23 @@
+menuconfig GOLDFISH
+       bool "Platform support for Goldfish virtual devices"
+       depends on X86_32 || X86_64 || ARM || ARM64 || MIPS
+       ---help---
+         Say Y here to get to see options for the Goldfish virtual platform.
+         This option alone does not add any kernel code.
+
+         Unless you are building for the Android Goldfish emulator say N here.
+
+if GOLDFISH
+
+config GOLDFISH_BUS
+       tristate "Goldfish platform bus"
+       ---help---
+         This is a virtual bus to host Goldfish Android Virtual Devices.
+
 config GOLDFISH_PIPE
        tristate "Goldfish virtual device for QEMU pipes"
        ---help---
          This is a virtual device to drive the QEMU pipe interface used by
          the Goldfish Android Virtual Device.
+
+endif # GOLDFISH
index a0022395eee93f38c6a981cc9145cbe5ae8774f4..d3487125838cdce457c2f7acefdd9052b92cbde1 100644 (file)
@@ -1,5 +1,5 @@
 #
 # Makefile for Goldfish platform specific drivers
 #
-obj-$(CONFIG_GOLDFISH) +=      pdev_bus.o
+obj-$(CONFIG_GOLDFISH_BUS)     += pdev_bus.o
 obj-$(CONFIG_GOLDFISH_PIPE)    += goldfish_pipe.o
index e7a29e2750c6aeb274047b37a9d32eb3fe70961d..34e447975ece0898ced4fa330094ea365d6acb13 100644 (file)
@@ -2,6 +2,7 @@
  * 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
@@ -57,6 +58,8 @@
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/goldfish.h>
+#include <linux/mm.h>
+#include <linux/acpi.h>
 
 /*
  * IMPORTANT: The following constants must match the ones used and defined
@@ -75,6 +78,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 */
 #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 */
-
-/* The following commands are related to read operations, they must be
- * listed in the same order than the corresponding write ones, since we
- * will use (CMD_READ_BUFFER - CMD_WRITE_BUFFER) as a special offset
- * in goldfish_pipe_read_write() below.
- */
 #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 */
@@ -130,6 +128,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];
@@ -263,19 +262,14 @@ static int access_with_param(struct goldfish_pipe_dev *dev, const int cmd,
        return 0;
 }
 
-/* This function is used for both reading from and writing to a given
- * pipe.
- */
 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;
-       const int cmd_offset = is_write ? 0
-                                       : (CMD_READ_BUFFER - CMD_WRITE_BUFFER);
        unsigned long address, address_end;
-       int ret = 0;
+       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))
@@ -304,73 +298,100 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
                unsigned long  avail    = next - address;
                int status, wakeBit;
 
-               /* Ensure that the corresponding page is properly mapped */
-               /* FIXME: this isn't safe or sufficient - use get_user_pages */
-               if (is_write) {
-                       char c;
-                       /* Ensure that the page is mapped and readable */
-                       if (__get_user(c, (char __user *)address)) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               break;
-                       }
+               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(&current->mm->mmap_sem);
+               ret = get_user_pages(current, current->mm, address, 1,
+                                    !is_write, 0, &page, NULL);
+               up_read(&current->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 {
-                       /* Ensure that the page is mapped and writable */
-                       if (__put_user(0, (char __user *)address)) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               break;
-                       }
+                       /* 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, CMD_WRITE_BUFFER + cmd_offset,
-                               address, avail, pipe, &status)) {
+               if (access_with_param(dev,
+                                     is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER,
+                                     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(CMD_WRITE_BUFFER + cmd_offset,
-                                       dev->base + PIPE_REG_COMMAND);
+                       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 */
-                       ret += status;
+                       count += status;
                        address += status;
                        continue;
-               }
-
-               if (status == 0)  /* EOF */
+               } else if (status == 0) { /* EOF */
+                       ret = 0;
                        break;
-
-               /* An error occured. If we already transfered stuff, just
-               * return with its count. We expect the next call to return
-               * an error code */
-               if (ret > 0)
+               } else if (status < 0 && count > 0) {
+                       /*
+                        * An error occured and we already transfered
+                        * 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 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;
                }
 
-               /* We will have to wait until more data/space is available.
-               * First, mark the pipe as waiting for a specific wake signal.
-               */
+               /*
+                * 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, CMD_WAKE_ON_WRITE + cmd_offset);
+               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);
@@ -378,22 +399,29 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
                while (test_bit(wakeBit, &pipe->flags)) {
                        if (wait_event_interruptible(
                                        pipe->wake_queue,
-                                       !test_bit(wakeBit, &pipe->flags)))
-                               return -ERESTARTSYS;
+                                       !test_bit(wakeBit, &pipe->flags))) {
+                               ret = -ERESTARTSYS;
+                               break;
+                       }
 
-                       if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
-                               return -EIO;
+                       if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) {
+                               ret = -EIO;
+                               break;
+                       }
                }
 
                /* Try to re-acquire the lock */
-               if (mutex_lock_interruptible(&pipe->lock))
-                       return -ERESTARTSYS;
-
-               /* Try the transfer again */
-               continue;
+               if (mutex_lock_interruptible(&pipe->lock)) {
+                       ret = -ERESTARTSYS;
+                       break;
+               }
        }
        mutex_unlock(&pipe->lock);
-       return ret;
+
+       if (ret < 0)
+               return ret;
+       else
+               return count;
 }
 
 static ssize_t goldfish_pipe_read(struct file *filp, char __user *buffer,
@@ -446,10 +474,11 @@ static irqreturn_t goldfish_pipe_interrupt(int irq, void *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 occured on each
-       * blocked pipe (i.e. channel).
-       */
+       /*
+        * We're going to read from the emulator a list of (channel,flags)
+        * pairs corresponding to the wake events that occured 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 */
@@ -600,6 +629,11 @@ 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:
@@ -615,11 +649,26 @@ static int goldfish_pipe_remove(struct platform_device *pdev)
        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 = "generic,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"
+               .name = "goldfish_pipe",
+               .owner = THIS_MODULE,
+               .of_match_table = goldfish_pipe_of_match,
+               .acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match),
        }
 };