goldfish patches
diff --git a/0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch b/0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch
new file mode 100644
index 0000000..248bf0a
--- /dev/null
+++ b/0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch
@@ -0,0 +1,1927 @@
+From c53b6059ba261505317a4d8de63832846c9c92fb Mon Sep 17 00:00:00 2001
+From: Jin Qian <jinqian@android.com>
+Date: Mon, 27 Feb 2017 12:06:21 -0800
+Subject: [PATCH 1/3] goldfish_pipe: An implementation of more parallel pipe
+
+This is a driver code for a redesigned android pipe.
+Currently it works for x86 and x64 emulators with the following
+performance results:
+ ADB push to /dev/null,
+ Ubuntu,
+ 400 MB file,
+ times are for (1 / 10 / 100) parallel adb commands
+x86 adb push: (4.4s / 11.5s / 2m10s) -> (2.8s / 6s / 51s)
+x64 adb push: (7s / 15s / (too long, 6m+) -> (2.7s / 6.2s / 52s)
+
+ADB pull and push to /data/ have the same %% of speedup
+More importantly, I don't see any signs of slowdowns when
+run in parallel with Antutu benchmark, so it is definitely
+making much better job at multithreading.
+
+Signed-off-by: Yurii Zubrytskyi <zyy@google.com>
+Signed-off-by: Jin Qian <jinqian@android.com>
+---
+ drivers/platform/goldfish/goldfish_pipe.c | 976 +++++++++++++++--------
+ drivers/platform/goldfish/goldfish_pipe_legacy.c | 671 +++++++++++++++
+ 2 files changed, 1315 insertions(+), 332 deletions(-)
+ create mode 100644 drivers/platform/goldfish/goldfish_pipe_legacy.c
+
+--- a/drivers/platform/goldfish/goldfish_pipe.c
++++ b/drivers/platform/goldfish/goldfish_pipe.c
+@@ -1,8 +1,8 @@
+ /*
+- * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2012 Intel, Inc.
+ * Copyright (C) 2013 Intel, Inc.
+ * Copyright (C) 2014 Linaro Limited
++ * Copyright (C) 2011-2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+@@ -46,6 +46,7 @@
+ * exchange is properly mapped during a transfer.
+ */
+
++
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+@@ -63,122 +64,232 @@
+ #include <linux/acpi.h>
+
+ /*
++ * Update this when something changes in the driver's behavior so the host
++ * can benefit from knowing it
++ */
++enum {
++ PIPE_DRIVER_VERSION = 2,
++ PIPE_CURRENT_DEVICE_VERSION = 2
++};
++
++/*
+ * 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 */
+-#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 */
++enum PipePollFlags {
++ PIPE_POLL_IN = 1 << 0,
++ PIPE_POLL_OUT = 1 << 1,
++ PIPE_POLL_HUP = 1 << 2
++};
+
+ /* 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
++enum PipeErrors {
++ PIPE_ERROR_INVAL = -1,
++ PIPE_ERROR_AGAIN = -2,
++ PIPE_ERROR_NOMEM = -3,
++ 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 */
++enum PipeWakeFlags {
++ PIPE_WAKE_CLOSED = 1 << 0, /* emulator closed pipe */
++ PIPE_WAKE_READ = 1 << 1, /* pipe can now be read from */
++ PIPE_WAKE_WRITE = 1 << 2 /* pipe can now be written to */
++};
++
++/* Bit flags for the 'flags' field */
++enum PipeFlagsBits {
++ 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 */
++};
++
++enum PipeRegs {
++ PIPE_REG_CMD = 0,
++
++ PIPE_REG_SIGNAL_BUFFER_HIGH = 4,
++ PIPE_REG_SIGNAL_BUFFER = 8,
++ PIPE_REG_SIGNAL_BUFFER_COUNT = 12,
++
++ PIPE_REG_OPEN_BUFFER_HIGH = 20,
++ PIPE_REG_OPEN_BUFFER = 24,
++
++ PIPE_REG_VERSION = 36,
++
++ PIPE_REG_GET_SIGNALLED = 48,
++};
++
++enum PipeCmdCode {
++ PIPE_CMD_OPEN = 1, /* to be used by the pipe device itself */
++ PIPE_CMD_CLOSE,
++ PIPE_CMD_POLL,
++ PIPE_CMD_WRITE,
++ PIPE_CMD_WAKE_ON_WRITE,
++ PIPE_CMD_READ,
++ PIPE_CMD_WAKE_ON_READ,
++
++ /*
++ * TODO(zyy): implement a deferred read/write execution to allow
++ * parallel processing of pipe operations on the host.
++ */
++ PIPE_CMD_WAKE_ON_DONE_IO,
++};
++
++enum {
++ MAX_BUFFERS_PER_COMMAND = 336,
++ MAX_SIGNALLED_PIPES = 64,
++ INITIAL_PIPES_CAPACITY = 64
++};
++
++struct goldfish_pipe_dev;
++struct goldfish_pipe;
++struct goldfish_pipe_command;
++
++/* A per-pipe command structure, shared with the host */
++struct goldfish_pipe_command {
++ s32 cmd; /* PipeCmdCode, guest -> host */
++ s32 id; /* pipe id, guest -> host */
++ s32 status; /* command execution status, host -> guest */
++ s32 reserved; /* to pad to 64-bit boundary */
++ union {
++ /* Parameters for PIPE_CMD_{READ,WRITE} */
++ struct {
++ /* number of buffers, guest -> host */
++ u32 buffers_count;
++ /* number of consumed bytes, host -> guest */
++ s32 consumed_size;
++ /* buffer pointers, guest -> host */
++ u64 ptrs[MAX_BUFFERS_PER_COMMAND];
++ /* buffer sizes, guest -> host */
++ u32 sizes[MAX_BUFFERS_PER_COMMAND];
++ } rw_params;
++ };
++};
++
++/* A single signalled pipe information */
++struct signalled_pipe_buffer {
++ u32 id;
+ 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;
+- u32 version;
++/* Parameters for the PIPE_CMD_OPEN command */
++struct open_command_param {
++ u64 command_buffer_ptr;
++ u32 rw_params_max_count;
+ };
+
+-static struct goldfish_pipe_dev pipe_dev[1];
++/* Device-level set of buffers shared with the host */
++struct goldfish_pipe_dev_buffers {
++ struct open_command_param open_command_params;
++ struct signalled_pipe_buffer signalled_pipe_buffers[
++ MAX_SIGNALLED_PIPES];
++};
+
+ /* This data type models a given pipe instance */
+ struct goldfish_pipe {
+- struct goldfish_pipe_dev *dev;
+- struct mutex lock;
++ /* pipe ID - index into goldfish_pipe_dev::pipes array */
++ u32 id;
++ /* The wake flags pipe is waiting for
++ * Note: not protected with any lock, uses atomic operations
++ * and barriers to make it thread-safe.
++ */
+ unsigned long flags;
++ /* wake flags host have signalled,
++ * - protected by goldfish_pipe_dev::lock
++ */
++ unsigned long signalled_flags;
++
++ /* A pointer to command buffer */
++ struct goldfish_pipe_command *command_buffer;
++
++ /* doubly linked list of signalled pipes, protected by
++ * goldfish_pipe_dev::lock
++ */
++ struct goldfish_pipe *prev_signalled;
++ struct goldfish_pipe *next_signalled;
++
++ /*
++ * A pipe's own lock. Protects the following:
++ * - *command_buffer - makes sure a command can safely write its
++ * parameters to the host and read the results back.
++ */
++ struct mutex lock;
++
++ /* A wake queue for sleeping until host signals an event */
+ wait_queue_head_t wake_queue;
++ /* Pointer to the parent goldfish_pipe_dev instance */
++ struct goldfish_pipe_dev *dev;
+ };
+
++/* 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 {
++ /*
++ * Global device spinlock. Protects the following members:
++ * - pipes, pipes_capacity
++ * - [*pipes, *pipes + pipes_capacity) - array data
++ * - first_signalled_pipe,
++ * goldfish_pipe::prev_signalled,
++ * goldfish_pipe::next_signalled,
++ * goldfish_pipe::signalled_flags - all singnalled-related fields,
++ * in all allocated pipes
++ * - open_command_params - PIPE_CMD_OPEN-related buffers
++ *
++ * It looks like a lot of different fields, but the trick is that
++ * the only operation that happens often is the signalled pipes array
++ * manipulation. That's why it's OK for now to keep the rest of the
++ * fields under the same lock. If we notice too much contention because
++ * of PIPE_CMD_OPEN, then we should add a separate lock there.
++ */
++ spinlock_t lock;
+
+-/* 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 */
++ /*
++ * Array of the pipes of |pipes_capacity| elements,
++ * indexed by goldfish_pipe::id
++ */
++ struct goldfish_pipe **pipes;
++ u32 pipes_capacity;
++
++ /* Pointers to the buffers host uses for interaction with this driver */
++ struct goldfish_pipe_dev_buffers *buffers;
++
++ /* Head of a doubly linked list of signalled pipes */
++ struct goldfish_pipe *first_signalled_pipe;
++
++ /* Some device-specific data */
++ int irq;
++ int version;
++ unsigned char __iomem *base;
+ };
+
++struct goldfish_pipe_dev pipe_dev[1] = {};
+
+-static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd)
++static int goldfish_cmd_locked(struct goldfish_pipe *pipe, enum PipeCmdCode 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;
++ pipe->command_buffer->cmd = cmd;
++ /* failure by default */
++ pipe->command_buffer->status = PIPE_ERROR_INVAL;
++ writel(pipe->id, pipe->dev->base + PIPE_REG_CMD);
++ return pipe->command_buffer->status;
+ }
+
+-static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd)
++static int goldfish_cmd(struct goldfish_pipe *pipe, enum PipeCmdCode cmd)
+ {
+- unsigned long flags;
+- struct goldfish_pipe_dev *dev = pipe->dev;
++ int status;
+
+- 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);
++ if (mutex_lock_interruptible(&pipe->lock))
++ return PIPE_ERROR_IO;
++ status = goldfish_cmd_locked(pipe, cmd);
++ mutex_unlock(&pipe->lock);
++ return status;
+ }
+
+-/* This function converts an error code returned by the emulator through
++/*
++ * 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)
+@@ -195,184 +306,202 @@ static int goldfish_pipe_error_convert(i
+ }
+ }
+
+-/*
+- * 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)
++static int pin_user_pages(unsigned long first_page, unsigned long last_page,
++ unsigned int last_page_size, int is_write,
++ struct page *pages[MAX_BUFFERS_PER_COMMAND],
++ unsigned int *iter_last_page_size)
++{
++ int ret;
++ int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1;
++
++ if (requested_pages > MAX_BUFFERS_PER_COMMAND) {
++ requested_pages = MAX_BUFFERS_PER_COMMAND;
++ *iter_last_page_size = PAGE_SIZE;
++ } else {
++ *iter_last_page_size = last_page_size;
++ }
++
++ ret = get_user_pages_fast(
++ first_page, requested_pages, !is_write, pages);
++ if (ret <= 0)
++ return -EFAULT;
++ if (ret < requested_pages)
++ *iter_last_page_size = PAGE_SIZE;
++ return ret;
++
++}
++
++static void release_user_pages(struct page **pages, int pages_count,
++ int is_write, s32 consumed_size)
+ {
+- u32 aph, apl;
+- u64 paddr;
+- aph = readl(dev->base + PIPE_REG_PARAMS_ADDR_HIGH);
+- apl = readl(dev->base + PIPE_REG_PARAMS_ADDR_LOW);
++ int i;
+
+- paddr = ((u64)aph << 32) | apl;
+- if (paddr != (__pa(aps)))
+- return 0;
+- return 1;
++ for (i = 0; i < pages_count; i++) {
++ if (!is_write && consumed_size > 0)
++ set_page_dirty(pages[i]);
++ put_page(pages[i]);
++ }
++}
++
++/* Populate the call parameters, merging adjacent pages together */
++static void populate_rw_params(
++ struct page **pages, int pages_count,
++ unsigned long address, unsigned long address_end,
++ unsigned long first_page, unsigned long last_page,
++ unsigned int iter_last_page_size, int is_write,
++ struct goldfish_pipe_command *command)
++{
++ /*
++ * Process the first page separately - it's the only page that
++ * needs special handling for its start address.
++ */
++ unsigned long xaddr = page_to_phys(pages[0]);
++ unsigned long xaddr_prev = xaddr;
++ int buffer_idx = 0;
++ int i = 1;
++ int size_on_page = first_page == last_page
++ ? (int)(address_end - address)
++ : (PAGE_SIZE - (address & ~PAGE_MASK));
++ command->rw_params.ptrs[0] = (u64)(xaddr | (address & ~PAGE_MASK));
++ command->rw_params.sizes[0] = size_on_page;
++ for (; i < pages_count; ++i) {
++ xaddr = page_to_phys(pages[i]);
++ size_on_page = (i == pages_count - 1) ?
++ iter_last_page_size : PAGE_SIZE;
++ if (xaddr == xaddr_prev + PAGE_SIZE) {
++ command->rw_params.sizes[buffer_idx] += size_on_page;
++ } else {
++ ++buffer_idx;
++ command->rw_params.ptrs[buffer_idx] = (u64)xaddr;
++ command->rw_params.sizes[buffer_idx] = size_on_page;
++ }
++ xaddr_prev = xaddr;
++ }
++ command->rw_params.buffers_count = buffer_idx + 1;
+ }
+
+-/* 0 on success */
+-static int setup_access_params_addr(struct platform_device *pdev,
+- struct goldfish_pipe_dev *dev)
++static int transfer_max_buffers(struct goldfish_pipe *pipe,
++ unsigned long address, unsigned long address_end, int is_write,
++ unsigned long last_page, unsigned int last_page_size,
++ s32 *consumed_size, int *status)
+ {
+- dma_addr_t dma_handle;
+- struct access_params *aps;
++ struct page *pages[MAX_BUFFERS_PER_COMMAND];
++ unsigned long first_page = address & PAGE_MASK;
++ unsigned int iter_last_page_size;
++ int pages_count = pin_user_pages(first_page, last_page,
++ last_page_size, is_write,
++ pages, &iter_last_page_size);
+
+- aps = dmam_alloc_coherent(&pdev->dev, sizeof(struct access_params),
+- &dma_handle, GFP_KERNEL);
+- if (!aps)
+- return -ENOMEM;
++ if (pages_count < 0)
++ return pages_count;
+
+- 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);
++ /* Serialize access to the pipe command buffers */
++ if (mutex_lock_interruptible(&pipe->lock))
++ return -ERESTARTSYS;
+
+- if (valid_batchbuffer_addr(dev, aps)) {
+- dev->aps = aps;
+- return 0;
+- } else
+- return -1;
++ populate_rw_params(pages, pages_count, address, address_end,
++ first_page, last_page, iter_last_page_size, is_write,
++ pipe->command_buffer);
++
++ /* Transfer the data */
++ *status = goldfish_cmd_locked(pipe,
++ is_write ? PIPE_CMD_WRITE : PIPE_CMD_READ);
++
++ *consumed_size = pipe->command_buffer->rw_params.consumed_size;
++
++ mutex_unlock(&pipe->lock);
++
++ release_user_pages(pages, pages_count, is_write, *consumed_size);
++
++ return 0;
+ }
+
+-/* 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;
++static int wait_for_host_signal(struct goldfish_pipe *pipe, int is_write)
++{
++ u32 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 */
++ (void)goldfish_cmd(pipe,
++ is_write ? PIPE_CMD_WAKE_ON_WRITE : PIPE_CMD_WAKE_ON_READ);
++
++ 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;
++ }
++
+ return 0;
+ }
+
+-static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
+- size_t bufflen, int is_write)
++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;
++ unsigned long address, address_end, last_page;
++ unsigned int last_page_size;
+
+ /* If the emulator already closed the pipe, no need to go further */
+- if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))
++ if (unlikely(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))
++ if (unlikely(!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 = (unsigned long)buffer;
+ address_end = address + bufflen;
++ last_page = (address_end - 1) & PAGE_MASK;
++ last_page_size = ((address_end - 1) & ~PAGE_MASK) + 1;
+
+ 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;
+-
+- /* Either vaddr or paddr depending on the device version */
+- unsigned long xaddr;
++ s32 consumed_size;
++ int status;
+
+- /*
+- * 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);
++ ret = transfer_max_buffers(pipe, address, address_end, is_write,
++ last_page, last_page_size, &consumed_size,
++ &status);
+ if (ret < 0)
+ break;
+
+- if (dev->version) {
+- /* Device version 1 or newer (qemu-android) expects the
+- * physical address.
++ if (consumed_size > 0) {
++ /* No matter what's the status, we've transferred
++ * something.
+ */
+- xaddr = page_to_phys(page) | (address & ~PAGE_MASK);
+- } else {
+- /* Device version 0 (classic emulator) expects the
+- * virtual address.
+- */
+- xaddr = address;
++ count += consumed_size;
++ address += consumed_size;
+ }
+-
+- /* 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,
+- 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 *)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;
++ if (status > 0)
+ continue;
+- } else if (status == 0) { /* EOF */
++ if (status == 0) {
++ /* EOF */
+ ret = 0;
+ break;
+- } else if (status < 0 && count > 0) {
++ }
++ if (count > 0) {
+ /*
+- * An error occurred and we already transferred
+- * something on one of the previous pages.
++ * An error occurred, but we already transferred
++ * something on one of the previous iterations.
+ * 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",
++ pr_info_ratelimited("goldfish_pipe: backend 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
++ * If the error is not PIPE_ERROR_AGAIN, or if we are in
+ * non-blocking mode, just return the error code.
+ */
+ if (status != PIPE_ERROR_AGAIN ||
+@@ -381,139 +510,214 @@ static ssize_t goldfish_pipe_read_write(
+ 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;
++ status = wait_for_host_signal(pipe, is_write);
++ if (status < 0)
++ return status;
+ }
+- mutex_unlock(&pipe->lock);
+
+- if (ret < 0)
+- return ret;
+- else
++ if (count > 0)
+ return count;
++ return ret;
+ }
+
+ static ssize_t goldfish_pipe_read(struct file *filp, char __user *buffer,
+- size_t bufflen, loff_t *ppos)
++ size_t bufflen, loff_t *ppos)
+ {
+- return goldfish_pipe_read_write(filp, buffer, bufflen, 0);
++ return goldfish_pipe_read_write(filp, buffer, bufflen,
++ /* is_write */ 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);
++ return goldfish_pipe_read_write(filp,
++ /* cast away the const */(char __user *)buffer, bufflen,
++ /* is_write */ 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);
++ status = goldfish_cmd(pipe, PIPE_CMD_POLL);
++ if (status < 0)
++ return -ERESTARTSYS;
+
+ 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)
++static void signalled_pipes_add_locked(struct goldfish_pipe_dev *dev,
++ u32 id, u32 flags)
+ {
+- struct goldfish_pipe_dev *dev = dev_id;
+- unsigned long irq_flags;
+- int count = 0;
++ struct goldfish_pipe *pipe;
+
+- /*
+- * 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;
++ if (WARN_ON(id >= dev->pipes_capacity))
++ return;
+
+-#ifdef CONFIG_64BIT
+- channel = (u64)readl(dev->base + PIPE_REG_CHANNEL_HIGH) << 32;
++ pipe = dev->pipes[id];
++ if (!pipe)
++ return;
++ pipe->signalled_flags |= flags;
++
++ if (pipe->prev_signalled || pipe->next_signalled
++ || dev->first_signalled_pipe == pipe)
++ return; /* already in the list */
++ pipe->next_signalled = dev->first_signalled_pipe;
++ if (dev->first_signalled_pipe)
++ dev->first_signalled_pipe->prev_signalled = pipe;
++ dev->first_signalled_pipe = pipe;
++}
++
++static void signalled_pipes_remove_locked(struct goldfish_pipe_dev *dev,
++ struct goldfish_pipe *pipe) {
++ if (pipe->prev_signalled)
++ pipe->prev_signalled->next_signalled = pipe->next_signalled;
++ if (pipe->next_signalled)
++ pipe->next_signalled->prev_signalled = pipe->prev_signalled;
++ if (pipe == dev->first_signalled_pipe)
++ dev->first_signalled_pipe = pipe->next_signalled;
++ pipe->prev_signalled = NULL;
++ pipe->next_signalled = NULL;
++}
+
+- if (channel == 0)
+- break;
+-#endif
+- channel |= readl(dev->base + PIPE_REG_CHANNEL);
++static struct goldfish_pipe *signalled_pipes_pop_front(
++ struct goldfish_pipe_dev *dev, int *wakes)
++{
++ struct goldfish_pipe *pipe;
++ unsigned long flags;
+
+- if (channel == 0)
+- break;
++ spin_lock_irqsave(&dev->lock, flags);
+
+- /* Convert channel to struct pipe pointer + read wake flags */
+- wakes = readl(dev->base + PIPE_REG_WAKES);
+- pipe = (struct goldfish_pipe *)(ptrdiff_t)channel;
++ pipe = dev->first_signalled_pipe;
++ if (pipe) {
++ *wakes = pipe->signalled_flags;
++ pipe->signalled_flags = 0;
++ /*
++ * This is an optimized version of
++ * signalled_pipes_remove_locked()
++ * - We want to make it as fast as possible to
++ * wake the sleeping pipe operations faster.
++ */
++ dev->first_signalled_pipe = pipe->next_signalled;
++ if (dev->first_signalled_pipe)
++ dev->first_signalled_pipe->prev_signalled = NULL;
++ pipe->next_signalled = NULL;
++ }
+
+- /* Did the emulator just closed a pipe? */
++ spin_unlock_irqrestore(&dev->lock, flags);
++ return pipe;
++}
++
++static void goldfish_interrupt_task(unsigned long unused)
++{
++ struct goldfish_pipe_dev *dev = pipe_dev;
++ /* Iterate over the signalled pipes and wake them one by one */
++ struct goldfish_pipe *pipe;
++ int wakes;
++
++ while ((pipe = signalled_pipes_pop_front(dev, &wakes)) != NULL) {
+ if (wakes & PIPE_WAKE_CLOSED) {
+- set_bit(BIT_CLOSED_ON_HOST, &pipe->flags);
+- wakes |= PIPE_WAKE_READ | PIPE_WAKE_WRITE;
++ pipe->flags = 1 << BIT_CLOSED_ON_HOST;
++ } else {
++ 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);
+ }
+- 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() implies a write barrier, so don't
++ * explicitly add another one here.
++ */
+ wake_up_interruptible(&pipe->wake_queue);
+- count++;
+ }
+- spin_unlock_irqrestore(&dev->lock, irq_flags);
++}
++DECLARE_TASKLET(goldfish_interrupt_tasklet, goldfish_interrupt_task, 0);
++
++/*
++ * The general idea of the interrupt handling:
++ *
++ * 1. device raises an interrupt if there's at least one signalled pipe
++ * 2. IRQ handler reads the signalled pipes and their count from the device
++ * 3. device writes them into a shared buffer and returns the count
++ * it only resets the IRQ if it has returned all signalled pipes,
++ * otherwise it leaves it raised, so IRQ handler will be called
++ * again for the next chunk
++ * 4. IRQ handler adds all returned pipes to the device's signalled pipes list
++ * 5. IRQ handler launches a tasklet to process the signalled pipes from the
++ * list in a separate context
++ */
++static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id)
++{
++ u32 count;
++ u32 i;
++ unsigned long flags;
++ struct goldfish_pipe_dev *dev = dev_id;
++
++ if (dev != pipe_dev)
++ return IRQ_NONE;
++
++ /* Request the signalled pipes from the device */
++ spin_lock_irqsave(&dev->lock, flags);
++
++ count = readl(dev->base + PIPE_REG_GET_SIGNALLED);
++ if (count == 0) {
++ spin_unlock_irqrestore(&dev->lock, flags);
++ return IRQ_NONE;
++ }
++ if (count > MAX_SIGNALLED_PIPES)
++ count = MAX_SIGNALLED_PIPES;
+
+- return (count == 0) ? IRQ_NONE : IRQ_HANDLED;
++ for (i = 0; i < count; ++i)
++ signalled_pipes_add_locked(dev,
++ dev->buffers->signalled_pipe_buffers[i].id,
++ dev->buffers->signalled_pipe_buffers[i].flags);
++
++ spin_unlock_irqrestore(&dev->lock, flags);
++
++ tasklet_schedule(&goldfish_interrupt_tasklet);
++ return IRQ_HANDLED;
++}
++
++static int get_free_pipe_id_locked(struct goldfish_pipe_dev *dev)
++{
++ int id;
++
++ for (id = 0; id < dev->pipes_capacity; ++id)
++ if (!dev->pipes[id])
++ return id;
++
++ {
++ /* Reallocate the array */
++ u32 new_capacity = 2 * dev->pipes_capacity;
++ struct goldfish_pipe **pipes =
++ kcalloc(new_capacity, sizeof(*pipes), GFP_KERNEL);
++ if (!pipes)
++ return -ENOMEM;
++ memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity);
++ kfree(dev->pipes);
++ dev->pipes = pipes;
++ id = dev->pipes_capacity;
++ dev->pipes_capacity = new_capacity;
++ }
++ return id;
+ }
+
+ /**
+- * goldfish_pipe_open - open a channel to the AVD
++ * goldfish_pipe_open - open a channel to the AVD
+ * @inode: inode of device
+ * @file: file struct of opener
+ *
+@@ -525,12 +729,13 @@ static irqreturn_t goldfish_pipe_interru
+ */
+ 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;
++ unsigned long flags;
++ int id;
++ int status;
+
+ /* Allocate new pipe kernel object */
+- pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
++ struct goldfish_pipe *pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
+ if (pipe == NULL)
+ return -ENOMEM;
+
+@@ -539,29 +744,69 @@ static int goldfish_pipe_open(struct ino
+ 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.
++ * Command buffer needs to be allocated on its own page to make sure
++ * it is physically contiguous in host's address space.
+ */
++ pipe->command_buffer =
++ (struct goldfish_pipe_command *)__get_free_page(GFP_KERNEL);
++ if (!pipe->command_buffer) {
++ status = -ENOMEM;
++ goto err_pipe;
++ }
+
+- status = goldfish_cmd_status(pipe, CMD_OPEN);
+- if (status < 0) {
+- kfree(pipe);
+- return status;
++ spin_lock_irqsave(&dev->lock, flags);
++
++ id = get_free_pipe_id_locked(dev);
++ if (id < 0) {
++ status = id;
++ goto err_id_locked;
+ }
+
++ dev->pipes[id] = pipe;
++ pipe->id = id;
++ pipe->command_buffer->id = id;
++
++ /* Now tell the emulator we're opening a new pipe. */
++ dev->buffers->open_command_params.rw_params_max_count =
++ MAX_BUFFERS_PER_COMMAND;
++ dev->buffers->open_command_params.command_buffer_ptr =
++ (u64)(unsigned long)__pa(pipe->command_buffer);
++ status = goldfish_cmd_locked(pipe, PIPE_CMD_OPEN);
++ spin_unlock_irqrestore(&dev->lock, flags);
++ if (status < 0)
++ goto err_cmd;
+ /* All is done, save the pipe into the file's private data field */
+ file->private_data = pipe;
+ return 0;
++
++err_cmd:
++ spin_lock_irqsave(&dev->lock, flags);
++ dev->pipes[id] = NULL;
++err_id_locked:
++ spin_unlock_irqrestore(&dev->lock, flags);
++ free_page((unsigned long)pipe->command_buffer);
++err_pipe:
++ kfree(pipe);
++ return status;
+ }
+
+ static int goldfish_pipe_release(struct inode *inode, struct file *filp)
+ {
++ unsigned long flags;
+ struct goldfish_pipe *pipe = filp->private_data;
++ struct goldfish_pipe_dev *dev = pipe->dev;
+
+ /* The guest is closing the channel, so tell the emulator right now */
+- goldfish_cmd(pipe, CMD_CLOSE);
+- kfree(pipe);
++ (void)goldfish_cmd(pipe, PIPE_CMD_CLOSE);
++
++ spin_lock_irqsave(&dev->lock, flags);
++ dev->pipes[pipe->id] = NULL;
++ signalled_pipes_remove_locked(dev, pipe);
++ spin_unlock_irqrestore(&dev->lock, flags);
++
+ filp->private_data = NULL;
++ free_page((unsigned long)pipe->command_buffer);
++ kfree(pipe);
+ return 0;
+ }
+
+@@ -574,18 +819,91 @@ static const struct file_operations gold
+ .release = goldfish_pipe_release,
+ };
+
+-static struct miscdevice goldfish_pipe_device = {
++static struct miscdevice goldfish_pipe_dev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "goldfish_pipe",
+ .fops = &goldfish_pipe_fops,
+ };
+
++static int goldfish_pipe_device_init(struct platform_device *pdev)
++{
++ char *page;
++ struct goldfish_pipe_dev *dev = pipe_dev;
++ int 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 for v2\n");
++ return err;
++ }
++
++ err = misc_register(&goldfish_pipe_dev);
++ if (err) {
++ dev_err(&pdev->dev, "unable to register v2 device\n");
++ return err;
++ }
++
++ dev->first_signalled_pipe = NULL;
++ dev->pipes_capacity = INITIAL_PIPES_CAPACITY;
++ dev->pipes = kcalloc(dev->pipes_capacity, sizeof(*dev->pipes),
++ GFP_KERNEL);
++ if (!dev->pipes)
++ return -ENOMEM;
++
++ /*
++ * We're going to pass two buffers, open_command_params and
++ * signalled_pipe_buffers, to the host. This means each of those buffers
++ * needs to be contained in a single physical page. The easiest choice
++ * is to just allocate a page and place the buffers in it.
++ */
++ if (WARN_ON(sizeof(*dev->buffers) > PAGE_SIZE))
++ return -ENOMEM;
++
++ page = (char *)__get_free_page(GFP_KERNEL);
++ if (!page) {
++ kfree(dev->pipes);
++ return -ENOMEM;
++ }
++ dev->buffers = (struct goldfish_pipe_dev_buffers *)page;
++
++ /* Send the buffer addresses to the host */
++ {
++ u64 paddr = __pa(&dev->buffers->signalled_pipe_buffers);
++
++ writel((u32)(unsigned long)(paddr >> 32),
++ dev->base + PIPE_REG_SIGNAL_BUFFER_HIGH);
++ writel((u32)(unsigned long)paddr,
++ dev->base + PIPE_REG_SIGNAL_BUFFER);
++ writel((u32)MAX_SIGNALLED_PIPES,
++ dev->base + PIPE_REG_SIGNAL_BUFFER_COUNT);
++
++ paddr = __pa(&dev->buffers->open_command_params);
++ writel((u32)(unsigned long)(paddr >> 32),
++ dev->base + PIPE_REG_OPEN_BUFFER_HIGH);
++ writel((u32)(unsigned long)paddr,
++ dev->base + PIPE_REG_OPEN_BUFFER);
++ }
++ return 0;
++}
++
++static void goldfish_pipe_device_deinit(struct platform_device *pdev)
++{
++ struct goldfish_pipe_dev *dev = pipe_dev;
++
++ misc_deregister(&goldfish_pipe_dev);
++ kfree(dev->pipes);
++ free_page((unsigned long)dev->buffers);
++}
++
+ static int goldfish_pipe_probe(struct platform_device *pdev)
+ {
+ int err;
+ struct resource *r;
+ struct goldfish_pipe_dev *dev = pipe_dev;
+
++ if (WARN_ON(sizeof(struct goldfish_pipe_command) > PAGE_SIZE))
++ return -ENOMEM;
++
+ /* not thread safe, but this should not happen */
+ WARN_ON(dev->base != NULL);
+
+@@ -609,26 +927,21 @@ static int goldfish_pipe_probe(struct pl
+ }
+ 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);
+-
+- /* 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.
++ /*
++ * Exchange the versions with the host device
++ *
++ * Note: v1 driver used to not report its version, so we write it before
++ * reading device version back: this allows the host implementation to
++ * detect the old driver (if there was no version write before read).
+ */
++ writel((u32)PIPE_DRIVER_VERSION, dev->base + PIPE_REG_VERSION);
+ dev->version = readl(dev->base + PIPE_REG_VERSION);
+- return 0;
++ if (WARN_ON(dev->version < PIPE_CURRENT_DEVICE_VERSION))
++ return -EINVAL;
++
++ err = goldfish_pipe_device_init(pdev);
++ if (!err)
++ return 0;
+
+ error:
+ dev->base = NULL;
+@@ -638,7 +951,7 @@ error:
+ static int goldfish_pipe_remove(struct platform_device *pdev)
+ {
+ struct goldfish_pipe_dev *dev = pipe_dev;
+- misc_deregister(&goldfish_pipe_device);
++ goldfish_pipe_device_deinit(pdev);
+ dev->base = NULL;
+ return 0;
+ }
+@@ -655,17 +968,16 @@ static const struct of_device_id goldfis
+ };
+ MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match);
+
+-static struct platform_driver goldfish_pipe = {
++static struct platform_driver goldfish_pipe_driver = {
+ .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_platform_driver(goldfish_pipe_driver);
+ MODULE_AUTHOR("David Turner <digit@google.com>");
+ MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/platform/goldfish/goldfish_pipe_legacy.c
+@@ -0,0 +1,671 @@
++/*
++ * 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 */
++#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;
++ 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;
++
++ /* 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;
++
++ 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,
++ 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 *)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);
++
++ /* 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");
diff --git a/0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch b/0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch
new file mode 100644
index 0000000..01b6e8d
--- /dev/null
+++ b/0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch
@@ -0,0 +1,76 @@
+From 384a2aaec210cc69d53cf9eec2cc7f15b10d7312 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dtor@chromium.org>
+Date: Tue, 8 Sep 2015 17:30:52 -0700
+Subject: [PATCH 2/3] CHROMIUM: android: fix warning when releasing active sync
+ point
+
+Userspace can close the sync device while there are still active fence
+points, in which case kernel produces the following warning:
+
+[ 43.853176] ------------[ cut here ]------------
+[ 43.857834] WARNING: CPU: 0 PID: 892 at /mnt/host/source/src/third_party/kernel/v3.18/drivers/staging/android/sync.c:439 android_fence_release+0x88/0x104()
+[ 43.871741] CPU: 0 PID: 892 Comm: Binder_5 Tainted: G U 3.18.0-07661-g0550ce9 #1
+[ 43.880176] Hardware name: Google Tegra210 Smaug Rev 1+ (DT)
+[ 43.885834] Call trace:
+[ 43.888294] [<ffffffc000207464>] dump_backtrace+0x0/0x10c
+[ 43.893697] [<ffffffc000207580>] show_stack+0x10/0x1c
+[ 43.898756] [<ffffffc000ab1258>] dump_stack+0x74/0xb8
+[ 43.903814] [<ffffffc00021d414>] warn_slowpath_common+0x84/0xb0
+[ 43.909736] [<ffffffc00021d530>] warn_slowpath_null+0x14/0x20
+[ 43.915482] [<ffffffc00088aefc>] android_fence_release+0x84/0x104
+[ 43.921582] [<ffffffc000671cc4>] fence_release+0x104/0x134
+[ 43.927066] [<ffffffc00088b0cc>] sync_fence_free+0x74/0x9c
+[ 43.932552] [<ffffffc00088b128>] sync_fence_release+0x34/0x48
+[ 43.938304] [<ffffffc000317bbc>] __fput+0x100/0x1b8
+[ 43.943185] [<ffffffc000317cc8>] ____fput+0x8/0x14
+[ 43.947982] [<ffffffc000237f38>] task_work_run+0xb0/0xe4
+[ 43.953297] [<ffffffc000207074>] do_notify_resume+0x44/0x5c
+[ 43.958867] ---[ end trace 5a2aa4027cc5d171 ]---
+
+Let's fix it by introducing a new optional callback (disable_signaling)
+to fence operations so that drivers can do proper clean ups when we
+remove last callback for given fence.
+
+Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
+Reviewed-on: https://chromium-review.googlesource.com/303409
+Reviewed-by: Andrew Bresticker <abrestic@chromium.org>
+Signed-off-by: Jin Qian <jinqian@android.com>
+---
+ drivers/dma-buf/dma-fence.c | 6 +++++-
+ include/linux/dma-fence.h | 2 ++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma-buf/dma-fence.c
++++ b/drivers/dma-buf/dma-fence.c
+@@ -332,8 +332,12 @@ dma_fence_remove_callback(struct dma_fen
+ spin_lock_irqsave(fence->lock, flags);
+
+ ret = !list_empty(&cb->node);
+- if (ret)
++ if (ret) {
+ list_del_init(&cb->node);
++ if (list_empty(&fence->cb_list))
++ if (fence->ops->disable_signaling)
++ fence->ops->disable_signaling(fence);
++ }
+
+ spin_unlock_irqrestore(fence->lock, flags);
+
+--- a/include/linux/dma-fence.h
++++ b/include/linux/dma-fence.h
+@@ -109,6 +109,7 @@ struct dma_fence_cb {
+ * @get_driver_name: returns the driver name.
+ * @get_timeline_name: return the name of the context this fence belongs to.
+ * @enable_signaling: enable software signaling of fence.
++ * @disable_signaling: disable software signaling of fence (optional).
+ * @signaled: [optional] peek whether the fence is signaled, can be null.
+ * @wait: custom wait implementation, or dma_fence_default_wait.
+ * @release: [optional] called on destruction of fence, can be null
+@@ -168,6 +169,7 @@ struct dma_fence_ops {
+ const char * (*get_driver_name)(struct dma_fence *fence);
+ const char * (*get_timeline_name)(struct dma_fence *fence);
+ bool (*enable_signaling)(struct dma_fence *fence);
++ void (*disable_signaling)(struct dma_fence *fence);
+ bool (*signaled)(struct dma_fence *fence);
+ signed long (*wait)(struct dma_fence *fence,
+ bool intr, signed long timeout);
diff --git a/0003-goldfish-Add-goldfish-sync-driver.patch b/0003-goldfish-Add-goldfish-sync-driver.patch
new file mode 100644
index 0000000..2bf7249
--- /dev/null
+++ b/0003-goldfish-Add-goldfish-sync-driver.patch
@@ -0,0 +1,1429 @@
+From c7f0d1bafcc183f23995c4757cf9ecc9e0bd1cc8 Mon Sep 17 00:00:00 2001
+From: Lingfeng Yang <lfy@google.com>
+Date: Mon, 13 Jun 2016 09:24:07 -0700
+Subject: [PATCH 3/3] goldfish: Add goldfish sync driver
+
+This is kernel driver for controlling the Goldfish sync
+device on the host. It is used to maintain ordering
+in critical OpenGL state changes while using
+GPU emulation.
+
+The guest open()'s the Goldfish sync device to create
+a context for possibly maintaining sync timeline and fences.
+There is a 1:1 correspondence between such sync contexts
+and OpenGL contexts in the guest that need synchronization
+(which in turn, is anything involving swapping buffers,
+SurfaceFlinger, or Hardware Composer).
+
+The ioctl QUEUE_WORK takes a handle to a sync object
+and attempts to tell the host GPU to wait on the sync object
+and deal with signaling it. It possibly outputs
+a fence FD on which the Android systems that use them
+(GLConsumer, SurfaceFlinger, anything employing
+EGL_ANDROID_native_fence_sync) can use to wait.
+
+Design decisions and work log:
+
+- New approach is to have the guest issue ioctls that
+ trigger host wait, and then host increments timeline.
+- We need the host's sync object handle and sync thread handle
+ as the necessary information for that.
+- ioctl() from guest can work simultaneously with the
+ interrupt handling for commands from host.
+- optimization: don't write back on timeline inc
+- Change spin lock design to be much more lightweight;
+ do not call sw_sync functions or loop too long
+ anywhere.
+- Send read/write commands in batches to minimize guest/host
+ transitions.
+- robustness: BUG if we will overrun the cmd buffer.
+- robustness: return fd -1 if we cannot get an unused fd.
+- correctness: remove global mutex
+- cleanup pass done, incl. but not limited to:
+ - removal of clear_upto and
+ - switching to devm_***
+
+Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
+Signed-off-by: Lingfeng Yang <lfy@google.com>
+Signed-off-by: Jin Qian <jinqian@android.com>
+---
+ Documentation/devicetree/bindings/goldfish/sync.txt | 17
+ drivers/staging/goldfish/Kconfig | 8
+ drivers/staging/goldfish/Makefile | 6
+ drivers/staging/goldfish/goldfish_sync_timeline.c | 980 ++++++++++++++++
+ drivers/staging/goldfish/goldfish_sync_timeline_fence.c | 258 ++++
+ drivers/staging/goldfish/goldfish_sync_timeline_fence.h | 72 +
+ 6 files changed, 1341 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/goldfish/sync.txt
+ create mode 100644 drivers/staging/goldfish/goldfish_sync_timeline.c
+ create mode 100644 drivers/staging/goldfish/goldfish_sync_timeline_fence.c
+ create mode 100644 drivers/staging/goldfish/goldfish_sync_timeline_fence.h
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/goldfish/sync.txt
+@@ -0,0 +1,17 @@
++Android Goldfish QEMU Sync Device
++
++goldfish sync virtual device generated by android emulator.
++
++Required properties:
++
++- compatible : should contain "google,goldfish-sync" to match emulator
++- reg : <registers mapping>
++- interrupts : <interrupt mapping>
++
++Example:
++
++ android_pipe@a010000 {
++ compatible = "google,goldfish-sync";
++ reg = <ff01D000 0x0100>;
++ interrupts = <0xb>;
++ };
+--- a/drivers/staging/goldfish/Kconfig
++++ b/drivers/staging/goldfish/Kconfig
+@@ -4,6 +4,14 @@ config GOLDFISH_AUDIO
+ ---help---
+ Emulated audio channel for the Goldfish Android Virtual Device
+
++config GOLDFISH_SYNC
++ tristate "Goldfish AVD Sync Driver"
++ depends on GOLDFISH
++ depends on SW_SYNC
++ depends on SYNC_FILE
++ ---help---
++ Emulated sync fences for the Goldfish Android Virtual Device
++
+ config MTD_GOLDFISH_NAND
+ tristate "Goldfish NAND device"
+ depends on GOLDFISH
+--- a/drivers/staging/goldfish/Makefile
++++ b/drivers/staging/goldfish/Makefile
+@@ -4,3 +4,9 @@
+
+ obj-$(CONFIG_GOLDFISH_AUDIO) += goldfish_audio.o
+ obj-$(CONFIG_MTD_GOLDFISH_NAND) += goldfish_nand.o
++
++# and sync
++
++ccflags-y := -Idrivers/staging/android
++goldfish_sync-objs := goldfish_sync_timeline_fence.o goldfish_sync_timeline.o
++obj-$(CONFIG_GOLDFISH_SYNC) += goldfish_sync.o
+--- /dev/null
++++ b/drivers/staging/goldfish/goldfish_sync_timeline.c
+@@ -0,0 +1,980 @@
++/*
++ * Copyright (C) 2016 Google, Inc.
++ *
++ * 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.
++ *
++ */
++
++#include <linux/fdtable.h>
++#include <linux/file.h>
++#include <linux/init.h>
++#include <linux/miscdevice.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#include <linux/interrupt.h>
++#include <linux/kref.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++#include <linux/io.h>
++#include <linux/mm.h>
++#include <linux/acpi.h>
++
++#include <linux/string.h>
++
++#include <linux/fs.h>
++#include <linux/syscalls.h>
++#include <linux/sync_file.h>
++#include <linux/dma-fence.h>
++
++#include "goldfish_sync_timeline_fence.h"
++
++#define DTRACE() pr_debug("%s: enter", __func__)
++
++/* The Goldfish sync driver is designed to provide a interface
++ * between the underlying host's sync device and the kernel's
++ * fence sync framework..
++ * The purpose of the device/driver is to enable lightweight
++ * creation and signaling of timelines and fences
++ * in order to synchronize the guest with host-side graphics events.
++ *
++ * Each time the interrupt trips, the driver
++ * may perform a sync operation.
++ */
++
++/* The operations are: */
++
++/* Ready signal - used to mark when irq should lower */
++#define CMD_SYNC_READY 0
++
++/* Create a new timeline. writes timeline handle */
++#define CMD_CREATE_SYNC_TIMELINE 1
++
++/* Create a fence object. reads timeline handle and time argument.
++ * Writes fence fd to the SYNC_REG_HANDLE register.
++ */
++#define CMD_CREATE_SYNC_FENCE 2
++
++/* Increments timeline. reads timeline handle and time argument */
++#define CMD_SYNC_TIMELINE_INC 3
++
++/* Destroys a timeline. reads timeline handle */
++#define CMD_DESTROY_SYNC_TIMELINE 4
++
++/* Starts a wait on the host with
++ * the given glsync object and sync thread handle.
++ */
++#define CMD_TRIGGER_HOST_WAIT 5
++
++/* The register layout is: */
++
++/* host->guest batch commands */
++#define SYNC_REG_BATCH_COMMAND 0x00
++/* guest->host batch commands */
++#define SYNC_REG_BATCH_GUESTCOMMAND 0x04
++/* communicate physical address of host->guest batch commands */
++#define SYNC_REG_BATCH_COMMAND_ADDR 0x08
++/* 64-bit part */
++#define SYNC_REG_BATCH_COMMAND_ADDR_HIGH 0x0c
++/* communicate physical address of guest->host commands */
++#define SYNC_REG_BATCH_GUESTCOMMAND_ADDR 0x10
++/* 64-bit part */
++#define SYNC_REG_BATCH_GUESTCOMMAND_ADDR_HIGH 0x14
++/* signals that the device has been probed */
++#define SYNC_REG_INIT 0x18
++
++/* There is an ioctl associated with goldfish sync driver.
++ * Make it conflict with ioctls that are not likely to be used
++ * in the emulator.
++ *
++ * '@' 00-0F linux/radeonfb.h conflict!
++ * '@' 00-0F drivers/video/aty/aty128fb.c conflict!
++ */
++#define GOLDFISH_SYNC_IOC_MAGIC '@'
++
++#define GOLDFISH_SYNC_IOC_QUEUE_WORK \
++ _IOWR(GOLDFISH_SYNC_IOC_MAGIC, 0, struct goldfish_sync_ioctl_info)
++
++/* The above definitions (command codes, register layout, ioctl definitions)
++ * need to be in sync with the following files:
++ *
++ * Host-side (emulator):
++ * external/qemu/android/emulation/goldfish_sync.h
++ * external/qemu-android/hw/misc/goldfish_sync.c
++ *
++ * Guest-side (system image):
++ * device/generic/goldfish-opengl/system/egl/goldfish_sync.h
++ * device/generic/goldfish/ueventd.ranchu.rc
++ * platform/build/target/board/generic/sepolicy/file_contexts
++ */
++struct goldfish_sync_hostcmd {
++ /* sorted for alignment */
++ u64 handle;
++ u64 hostcmd_handle;
++ u32 cmd;
++ u32 time_arg;
++};
++
++struct goldfish_sync_guestcmd {
++ u64 host_command; /* u64 for alignment */
++ u64 glsync_handle;
++ u64 thread_handle;
++ u64 guest_timeline_handle;
++};
++
++#define GOLDFISH_SYNC_MAX_CMDS 32
++
++struct goldfish_sync_state {
++ char __iomem *reg_base;
++ int irq;
++
++ /* Spinlock protects |to_do| / |to_do_end|. */
++ spinlock_t lock;
++ /* |mutex_lock| protects all concurrent access
++ * to timelines for both kernel and user space.
++ */
++ struct mutex mutex_lock;
++
++ /* Buffer holding commands issued from host. */
++ struct goldfish_sync_hostcmd to_do[GOLDFISH_SYNC_MAX_CMDS];
++ u32 to_do_end;
++
++ /* Addresses for the reading or writing
++ * of individual commands. The host can directly write
++ * to |batch_hostcmd| (and then this driver immediately
++ * copies contents to |to_do|). This driver either replies
++ * through |batch_hostcmd| or simply issues a
++ * guest->host command through |batch_guestcmd|.
++ */
++ struct goldfish_sync_hostcmd *batch_hostcmd;
++ struct goldfish_sync_guestcmd *batch_guestcmd;
++
++ /* Used to give this struct itself to a work queue
++ * function for executing actual sync commands.
++ */
++ struct work_struct work_item;
++};
++
++static struct goldfish_sync_state global_sync_state[1];
++
++struct goldfish_sync_timeline_obj {
++ struct goldfish_sync_timeline *sync_tl;
++ u32 current_time;
++ /* We need to be careful about when we deallocate
++ * this |goldfish_sync_timeline_obj| struct.
++ * In order to ensure proper cleanup, we need to
++ * consider the triggered host-side wait that may
++ * still be in flight when the guest close()'s a
++ * goldfish_sync device's sync context fd (and
++ * destroys the |sync_tl| field above).
++ * The host-side wait may raise IRQ
++ * and tell the kernel to increment the timeline _after_
++ * the |sync_tl| has already been set to null.
++ *
++ * From observations on OpenGL apps and CTS tests, this
++ * happens at some very low probability upon context
++ * destruction or process close, but it does happen
++ * and it needs to be handled properly. Otherwise,
++ * if we clean up the surrounding |goldfish_sync_timeline_obj|
++ * too early, any |handle| field of any host->guest command
++ * might not even point to a null |sync_tl| field,
++ * but to garbage memory or even a reclaimed |sync_tl|.
++ * If we do not count such "pending waits" and kfree the object
++ * immediately upon |goldfish_sync_timeline_destroy|,
++ * we might get mysterous RCU stalls after running a long
++ * time because the garbage memory that is being read
++ * happens to be interpretable as a |spinlock_t| struct
++ * that is currently in the locked state.
++ *
++ * To track when to free the |goldfish_sync_timeline_obj|
++ * itself, we maintain a kref.
++ * The kref essentially counts the timeline itself plus
++ * the number of waits in flight. kref_init/kref_put
++ * are issued on
++ * |goldfish_sync_timeline_create|/|goldfish_sync_timeline_destroy|
++ * and kref_get/kref_put are issued on
++ * |goldfish_sync_fence_create|/|goldfish_sync_timeline_inc|.
++ *
++ * The timeline is destroyed after reference count
++ * reaches zero, which would happen after
++ * |goldfish_sync_timeline_destroy| and all pending
++ * |goldfish_sync_timeline_inc|'s are fulfilled.
++ *
++ * NOTE (1): We assume that |fence_create| and
++ * |timeline_inc| calls are 1:1, otherwise the kref scheme
++ * will not work. This is a valid assumption as long
++ * as the host-side virtual device implementation
++ * does not insert any timeline increments
++ * that we did not trigger from here.
++ *
++ * NOTE (2): The use of kref by itself requires no locks,
++ * but this does not mean everything works without locks.
++ * Related timeline operations do require a lock of some sort,
++ * or at least are not proven to work without it.
++ * In particualr, we assume that all the operations
++ * done on the |kref| field above are done in contexts where
++ * |global_sync_state->mutex_lock| is held. Do not
++ * remove that lock until everything is proven to work
++ * without it!!!
++ */
++ struct kref kref;
++};
++
++/* We will call |delete_timeline_obj| when the last reference count
++ * of the kref is decremented. This deletes the sync
++ * timeline object along with the wrapper itself.
++ */
++static void delete_timeline_obj(struct kref *kref)
++{
++ struct goldfish_sync_timeline_obj *obj =
++ container_of(kref, struct goldfish_sync_timeline_obj, kref);
++
++ goldfish_sync_timeline_put_internal(obj->sync_tl);
++ obj->sync_tl = NULL;
++ kfree(obj);
++}
++
++static u64 gensym_ctr;
++static void gensym(char *dst)
++{
++ sprintf(dst, "goldfish_sync:gensym:%llu", gensym_ctr);
++ gensym_ctr++;
++}
++
++/* |goldfish_sync_timeline_create| assumes that |global_sync_state->mutex_lock|
++ * is held.
++ */
++static struct goldfish_sync_timeline_obj *
++goldfish_sync_timeline_create(void)
++{
++ char timeline_name[256];
++ struct goldfish_sync_timeline *res_sync_tl = NULL;
++ struct goldfish_sync_timeline_obj *res;
++
++ DTRACE();
++
++ gensym(timeline_name);
++
++ res_sync_tl = goldfish_sync_timeline_create_internal(timeline_name);
++ if (!res_sync_tl) {
++ pr_err("Failed to create goldfish_sw_sync timeline.");
++ return NULL;
++ }
++
++ res = kzalloc(sizeof(*res), GFP_KERNEL);
++ res->sync_tl = res_sync_tl;
++ res->current_time = 0;
++ kref_init(&res->kref);
++
++ pr_debug("new timeline_obj=0x%p", res);
++ return res;
++}
++
++/* |goldfish_sync_fence_create| assumes that |global_sync_state->mutex_lock|
++ * is held.
++ */
++static int
++goldfish_sync_fence_create(struct goldfish_sync_timeline_obj *obj, u32 val)
++{
++ int fd;
++ char fence_name[256];
++ struct sync_pt *syncpt = NULL;
++ struct sync_file *sync_file_obj = NULL;
++ struct goldfish_sync_timeline *tl;
++
++ DTRACE();
++
++ if (!obj)
++ return -1;
++
++ tl = obj->sync_tl;
++
++ syncpt = goldfish_sync_pt_create_internal(
++ tl, sizeof(struct sync_pt) + 4, val);
++ if (!syncpt) {
++ pr_err(
++ "could not create sync point! goldfish_sync_timeline=0x%p val=%d",
++ tl, val);
++ return -1;
++ }
++
++ fd = get_unused_fd_flags(O_CLOEXEC);
++ if (fd < 0) {
++ pr_err("could not get unused fd for sync fence. errno=%d", fd);
++ goto err_cleanup_pt;
++ }
++
++ gensym(fence_name);
++
++ sync_file_obj = sync_file_create(&syncpt->base);
++ if (!sync_file_obj) {
++ pr_err("could not create sync fence! goldfish_sync_timeline=0x%p val=%d sync_pt=0x%p",
++ tl, val, syncpt);
++ goto err_cleanup_fd_pt;
++ }
++
++ pr_debug("installing sync fence into fd %d sync_file_obj=0x%p",
++ fd, sync_file_obj);
++ fd_install(fd, sync_file_obj->file);
++ kref_get(&obj->kref);
++
++ return fd;
++
++err_cleanup_fd_pt:
++ put_unused_fd(fd);
++err_cleanup_pt:
++ dma_fence_put(&syncpt->base);
++ return -1;
++}
++
++/* |goldfish_sync_timeline_inc| assumes that |global_sync_state->mutex_lock|
++ * is held.
++ */
++static void
++goldfish_sync_timeline_inc(struct goldfish_sync_timeline_obj *obj, u32 inc)
++{
++ DTRACE();
++ /* Just give up if someone else nuked the timeline.
++ * Whoever it was won't care that it doesn't get signaled.
++ */
++ if (!obj)
++ return;
++
++ pr_debug("timeline_obj=0x%p", obj);
++ goldfish_sync_timeline_signal_internal(obj->sync_tl, inc);
++ pr_debug("incremented timeline. increment max_time");
++ obj->current_time += inc;
++
++ /* Here, we will end up deleting the timeline object if it
++ * turns out that this call was a pending increment after
++ * |goldfish_sync_timeline_destroy| was called.
++ */
++ kref_put(&obj->kref, delete_timeline_obj);
++ pr_debug("done");
++}
++
++/* |goldfish_sync_timeline_destroy| assumes
++ * that |global_sync_state->mutex_lock| is held.
++ */
++static void
++goldfish_sync_timeline_destroy(struct goldfish_sync_timeline_obj *obj)
++{
++ DTRACE();
++ /* See description of |goldfish_sync_timeline_obj| for why we
++ * should not immediately destroy |obj|
++ */
++ kref_put(&obj->kref, delete_timeline_obj);
++}
++
++static inline void
++goldfish_sync_cmd_queue(struct goldfish_sync_state *sync_state,
++ u32 cmd,
++ u64 handle,
++ u32 time_arg,
++ u64 hostcmd_handle)
++{
++ struct goldfish_sync_hostcmd *to_add;
++
++ DTRACE();
++
++ if (WARN_ON(sync_state->to_do_end == GOLDFISH_SYNC_MAX_CMDS))
++ return;
++
++ to_add = &sync_state->to_do[sync_state->to_do_end];
++
++ to_add->cmd = cmd;
++ to_add->handle = handle;
++ to_add->time_arg = time_arg;
++ to_add->hostcmd_handle = hostcmd_handle;
++
++ sync_state->to_do_end += 1;
++}
++
++static inline void
++goldfish_sync_hostcmd_reply(struct goldfish_sync_state *sync_state,
++ u32 cmd,
++ u64 handle,
++ u32 time_arg,
++ u64 hostcmd_handle)
++{
++ unsigned long irq_flags;
++ struct goldfish_sync_hostcmd *batch_hostcmd =
++ sync_state->batch_hostcmd;
++
++ DTRACE();
++
++ spin_lock_irqsave(&sync_state->lock, irq_flags);
++
++ batch_hostcmd->cmd = cmd;
++ batch_hostcmd->handle = handle;
++ batch_hostcmd->time_arg = time_arg;
++ batch_hostcmd->hostcmd_handle = hostcmd_handle;
++ writel(0, sync_state->reg_base + SYNC_REG_BATCH_COMMAND);
++
++ spin_unlock_irqrestore(&sync_state->lock, irq_flags);
++}
++
++static inline void
++goldfish_sync_send_guestcmd(struct goldfish_sync_state *sync_state,
++ u32 cmd,
++ u64 glsync_handle,
++ u64 thread_handle,
++ u64 timeline_handle)
++{
++ unsigned long irq_flags;
++ struct goldfish_sync_guestcmd *batch_guestcmd =
++ sync_state->batch_guestcmd;
++
++ DTRACE();
++
++ spin_lock_irqsave(&sync_state->lock, irq_flags);
++
++ batch_guestcmd->host_command = (u64)cmd;
++ batch_guestcmd->glsync_handle = (u64)glsync_handle;
++ batch_guestcmd->thread_handle = (u64)thread_handle;
++ batch_guestcmd->guest_timeline_handle = (u64)timeline_handle;
++ writel(0, sync_state->reg_base + SYNC_REG_BATCH_GUESTCOMMAND);
++
++ spin_unlock_irqrestore(&sync_state->lock, irq_flags);
++}
++
++/* |goldfish_sync_interrupt| handles IRQ raises from the virtual device.
++ * In the context of OpenGL, this interrupt will fire whenever we need
++ * to signal a fence fd in the guest, with the command
++ * |CMD_SYNC_TIMELINE_INC|.
++ * However, because this function will be called in an interrupt context,
++ * it is necessary to do the actual work of signaling off of interrupt context.
++ * The shared work queue is used for this purpose. At the end when
++ * all pending commands are intercepted by the interrupt handler,
++ * we call |schedule_work|, which will later run the actual
++ * desired sync command in |goldfish_sync_work_item_fn|.
++ */
++static irqreturn_t goldfish_sync_interrupt(int irq, void *dev_id)
++{
++ struct goldfish_sync_state *sync_state = dev_id;
++
++ u32 nextcmd;
++ u32 command_r;
++ u64 handle_rw;
++ u32 time_r;
++ u64 hostcmd_handle_rw;
++
++ int count = 0;
++
++ DTRACE();
++
++ sync_state = dev_id;
++
++ spin_lock(&sync_state->lock);
++
++ for (;;) {
++ readl(sync_state->reg_base + SYNC_REG_BATCH_COMMAND);
++ nextcmd = sync_state->batch_hostcmd->cmd;
++
++ if (nextcmd == 0)
++ break;
++
++ command_r = nextcmd;
++ handle_rw = sync_state->batch_hostcmd->handle;
++ time_r = sync_state->batch_hostcmd->time_arg;
++ hostcmd_handle_rw = sync_state->batch_hostcmd->hostcmd_handle;
++
++ goldfish_sync_cmd_queue(
++ sync_state,
++ command_r,
++ handle_rw,
++ time_r,
++ hostcmd_handle_rw);
++
++ count++;
++ }
++
++ spin_unlock(&sync_state->lock);
++
++ schedule_work(&sync_state->work_item);
++
++ return (count == 0) ? IRQ_NONE : IRQ_HANDLED;
++}
++
++/* |goldfish_sync_work_item_fn| does the actual work of servicing
++ * host->guest sync commands. This function is triggered whenever
++ * the IRQ for the goldfish sync device is raised. Once it starts
++ * running, it grabs the contents of the buffer containing the
++ * commands it needs to execute (there may be multiple, because
++ * our IRQ is active high and not edge triggered), and then
++ * runs all of them one after the other.
++ */
++static void goldfish_sync_work_item_fn(struct work_struct *input)
++{
++ struct goldfish_sync_state *sync_state;
++ int sync_fence_fd;
++
++ struct goldfish_sync_timeline_obj *timeline;
++ u64 timeline_ptr;
++
++ u64 hostcmd_handle;
++
++ u32 cmd;
++ u64 handle;
++ u32 time_arg;
++
++ struct goldfish_sync_hostcmd *todo;
++ u32 todo_end;
++
++ unsigned long irq_flags;
++
++ struct goldfish_sync_hostcmd to_run[GOLDFISH_SYNC_MAX_CMDS];
++ u32 i = 0;
++
++ sync_state = container_of(input, struct goldfish_sync_state, work_item);
++
++ mutex_lock(&sync_state->mutex_lock);
++
++ spin_lock_irqsave(&sync_state->lock, irq_flags); {
++ todo_end = sync_state->to_do_end;
++
++ pr_debug("num sync todos: %u", sync_state->to_do_end);
++
++ for (i = 0; i < todo_end; i++)
++ to_run[i] = sync_state->to_do[i];
++
++ /* We expect that commands will come in at a slow enough rate
++ * so that incoming items will not be more than
++ * GOLDFISH_SYNC_MAX_CMDS.
++ *
++ * This is because the way the sync device is used,
++ * it's only for managing buffer data transfers per frame,
++ * with a sequential dependency between putting things in
++ * to_do and taking them out. Once a set of commands is
++ * queued up in to_do, the user of the device waits for
++ * them to be processed before queuing additional commands,
++ * which limits the rate at which commands come in
++ * to the rate at which we take them out here.
++ *
++ * We also don't expect more than MAX_CMDS to be issued
++ * at once; there is a correspondence between
++ * which buffers need swapping to the (display / buffer queue)
++ * to particular commands, and we don't expect there to be
++ * enough display or buffer queues in operation at once
++ * to overrun GOLDFISH_SYNC_MAX_CMDS.
++ */
++ sync_state->to_do_end = 0;
++
++ } spin_unlock_irqrestore(&sync_state->lock, irq_flags);
++
++ for (i = 0; i < todo_end; i++) {
++ pr_debug("todo index: %u", i);
++
++ todo = &to_run[i];
++
++ cmd = todo->cmd;
++
++ handle = (u64)todo->handle;
++ time_arg = todo->time_arg;
++ hostcmd_handle = (u64)todo->hostcmd_handle;
++
++ DTRACE();
++
++ timeline =
++ (struct goldfish_sync_timeline_obj *)(uintptr_t)handle;
++
++ switch (cmd) {
++ case CMD_SYNC_READY:
++ break;
++ case CMD_CREATE_SYNC_TIMELINE:
++ pr_debug("exec CMD_CREATE_SYNC_TIMELINE: handle=0x%llx time_arg=%d",
++ handle, time_arg);
++ timeline = goldfish_sync_timeline_create();
++ timeline_ptr = (uintptr_t)timeline;
++ goldfish_sync_hostcmd_reply(sync_state,
++ CMD_CREATE_SYNC_TIMELINE,
++ timeline_ptr,
++ 0,
++ hostcmd_handle);
++ pr_debug("sync timeline created: %p", timeline);
++ break;
++ case CMD_CREATE_SYNC_FENCE:
++ pr_debug("exec CMD_CREATE_SYNC_FENCE: handle=0x%llx time_arg=%d",
++ handle, time_arg);
++ sync_fence_fd = goldfish_sync_fence_create(
++ timeline, time_arg);
++ goldfish_sync_hostcmd_reply(sync_state,
++ CMD_CREATE_SYNC_FENCE,
++ sync_fence_fd,
++ 0,
++ hostcmd_handle);
++ break;
++ case CMD_SYNC_TIMELINE_INC:
++ pr_debug("exec CMD_SYNC_TIMELINE_INC: handle=0x%llx time_arg=%d",
++ handle, time_arg);
++ goldfish_sync_timeline_inc(timeline, time_arg);
++ break;
++ case CMD_DESTROY_SYNC_TIMELINE:
++ pr_debug("exec CMD_DESTROY_SYNC_TIMELINE: handle=0x%llx time_arg=%d",
++ handle, time_arg);
++ goldfish_sync_timeline_destroy(timeline);
++ break;
++ }
++ pr_debug("Done executing sync command");
++ }
++ mutex_unlock(&sync_state->mutex_lock);
++}
++
++/* Guest-side interface: file operations */
++
++/* Goldfish sync context and ioctl info.
++ *
++ * When a sync context is created by open()-ing the goldfish sync device, we
++ * create a sync context (|goldfish_sync_context|).
++ *
++ * Currently, the only data required to track is the sync timeline itself
++ * along with the current time, which are all packed up in the
++ * |goldfish_sync_timeline_obj| field. We use a |goldfish_sync_context|
++ * as the filp->private_data.
++ *
++ * Next, when a sync context user requests that work be queued and a fence
++ * fd provided, we use the |goldfish_sync_ioctl_info| struct, which holds
++ * information about which host handles to touch for this particular
++ * queue-work operation. We need to know about the host-side sync thread
++ * and the particular host-side GLsync object. We also possibly write out
++ * a file descriptor.
++ */
++struct goldfish_sync_context {
++ struct goldfish_sync_timeline_obj *timeline;
++};
++
++struct goldfish_sync_ioctl_info {
++ u64 host_glsync_handle_in;
++ u64 host_syncthread_handle_in;
++ int fence_fd_out;
++};
++
++static int goldfish_sync_open(struct inode *inode, struct file *file)
++{
++ struct goldfish_sync_context *sync_context;
++
++ DTRACE();
++
++ mutex_lock(&global_sync_state->mutex_lock);
++
++ sync_context = kzalloc(sizeof(*sync_context),
++ GFP_KERNEL);
++
++ if (!sync_context) {
++ pr_err("Creation of goldfish sync context failed!");
++ mutex_unlock(&global_sync_state->mutex_lock);
++ return -ENOMEM;
++ }
++
++ sync_context->timeline = NULL;
++
++ file->private_data = sync_context;
++
++ pr_debug("successfully create a sync context @0x%p", sync_context);
++
++ mutex_unlock(&global_sync_state->mutex_lock);
++
++ return 0;
++}
++
++static int goldfish_sync_release(struct inode *inode, struct file *file)
++{
++ struct goldfish_sync_context *sync_context;
++
++ DTRACE();
++
++ mutex_lock(&global_sync_state->mutex_lock);
++
++ sync_context = file->private_data;
++
++ if (sync_context->timeline)
++ goldfish_sync_timeline_destroy(sync_context->timeline);
++
++ sync_context->timeline = NULL;
++
++ kfree(sync_context);
++
++ mutex_unlock(&global_sync_state->mutex_lock);
++
++ return 0;
++}
++
++/* |goldfish_sync_ioctl| is the guest-facing interface of goldfish sync
++ * and is used in conjunction with eglCreateSyncKHR to queue up the
++ * actual work of waiting for the EGL sync command to complete,
++ * possibly returning a fence fd to the guest.
++ */
++static long goldfish_sync_ioctl(struct file *file,
++ unsigned int cmd,
++ unsigned long arg)
++{
++ struct goldfish_sync_context *sync_context_data;
++ struct goldfish_sync_timeline_obj *timeline;
++ int fd_out;
++ struct goldfish_sync_ioctl_info ioctl_data;
++
++ DTRACE();
++
++ sync_context_data = file->private_data;
++ fd_out = -1;
++
++ switch (cmd) {
++ case GOLDFISH_SYNC_IOC_QUEUE_WORK:
++
++ pr_debug("exec GOLDFISH_SYNC_IOC_QUEUE_WORK");
++
++ mutex_lock(&global_sync_state->mutex_lock);
++
++ if (copy_from_user(&ioctl_data,
++ (void __user *)arg,
++ sizeof(ioctl_data))) {
++ pr_err("Failed to copy memory for ioctl_data from user.");
++ mutex_unlock(&global_sync_state->mutex_lock);
++ return -EFAULT;
++ }
++
++ if (ioctl_data.host_syncthread_handle_in == 0) {
++ pr_debug("Error: zero host syncthread handle!!!");
++ mutex_unlock(&global_sync_state->mutex_lock);
++ return -EFAULT;
++ }
++
++ if (!sync_context_data->timeline) {
++ pr_debug("no timeline yet, create one.");
++ sync_context_data->timeline =
++ goldfish_sync_timeline_create();
++ pr_debug("timeline: 0x%p",
++ &sync_context_data->timeline);
++ }
++
++ timeline = sync_context_data->timeline;
++ fd_out = goldfish_sync_fence_create(timeline,
++ timeline->current_time + 1);
++ pr_debug("Created fence with fd %d and current time %u (timeline: 0x%p)",
++ fd_out,
++ sync_context_data->timeline->current_time + 1,
++ sync_context_data->timeline);
++
++ ioctl_data.fence_fd_out = fd_out;
++
++ if (copy_to_user((void __user *)arg,
++ &ioctl_data,
++ sizeof(ioctl_data))) {
++ pr_debug("Error, could not copy to user!!!");
++
++ sys_close(fd_out);
++ /* We won't be doing an increment, kref_put
++ * immediately.
++ */
++ kref_put(&timeline->kref, delete_timeline_obj);
++ mutex_unlock(&global_sync_state->mutex_lock);
++ return -EFAULT;
++ }
++
++ /* We are now about to trigger a host-side wait;
++ * accumulate on |pending_waits|.
++ */
++ goldfish_sync_send_guestcmd(
++ global_sync_state,
++ CMD_TRIGGER_HOST_WAIT,
++ ioctl_data.host_glsync_handle_in,
++ ioctl_data.host_syncthread_handle_in,
++ (u64)(uintptr_t)(sync_context_data->timeline));
++
++ mutex_unlock(&global_sync_state->mutex_lock);
++ return 0;
++ default:
++ return -ENOTTY;
++ }
++}
++
++static const struct file_operations goldfish_sync_fops = {
++ .owner = THIS_MODULE,
++ .open = goldfish_sync_open,
++ .release = goldfish_sync_release,
++ .unlocked_ioctl = goldfish_sync_ioctl,
++ .compat_ioctl = goldfish_sync_ioctl,
++};
++
++static struct miscdevice goldfish_sync_device = {
++ .name = "goldfish_sync",
++ .fops = &goldfish_sync_fops,
++};
++
++static bool setup_verify_batch_cmd_addr(struct goldfish_sync_state *sync_state,
++ void *batch_addr,
++ u32 addr_offset,
++ u32 addr_offset_high)
++{
++ u64 batch_addr_phys;
++ u32 batch_addr_phys_test_lo;
++ u32 batch_addr_phys_test_hi;
++
++ if (!batch_addr) {
++ pr_err("Could not use batch command address!");
++ return false;
++ }
++
++ batch_addr_phys = virt_to_phys(batch_addr);
++ writel((u32)(batch_addr_phys),
++ sync_state->reg_base + addr_offset);
++ writel((u32)(batch_addr_phys >> 32),
++ sync_state->reg_base + addr_offset_high);
++
++ batch_addr_phys_test_lo =
++ readl(sync_state->reg_base + addr_offset);
++ batch_addr_phys_test_hi =
++ readl(sync_state->reg_base + addr_offset_high);
++
++ if (virt_to_phys(batch_addr) !=
++ (((u64)batch_addr_phys_test_hi << 32) |
++ batch_addr_phys_test_lo)) {
++ pr_err("Invalid batch command address!");
++ return false;
++ }
++
++ return true;
++}
++
++int goldfish_sync_probe(struct platform_device *pdev)
++{
++ struct resource *ioresource;
++ struct goldfish_sync_state *sync_state = global_sync_state;
++ int status;
++
++ DTRACE();
++
++ sync_state->to_do_end = 0;
++
++ spin_lock_init(&sync_state->lock);
++ mutex_init(&sync_state->mutex_lock);
++
++ platform_set_drvdata(pdev, sync_state);
++
++ ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!ioresource) {
++ pr_err("platform_get_resource failed");
++ return -ENODEV;
++ }
++
++ sync_state->reg_base =
++ devm_ioremap(&pdev->dev, ioresource->start, PAGE_SIZE);
++ if (!sync_state->reg_base) {
++ pr_err("Could not ioremap");
++ return -ENOMEM;
++ }
++
++ sync_state->irq = platform_get_irq(pdev, 0);
++ if (sync_state->irq < 0) {
++ pr_err("Could not platform_get_irq");
++ return -ENODEV;
++ }
++
++ status = devm_request_irq(&pdev->dev,
++ sync_state->irq,
++ goldfish_sync_interrupt,
++ IRQF_SHARED,
++ pdev->name,
++ sync_state);
++ if (status) {
++ pr_err("request_irq failed");
++ return -ENODEV;
++ }
++
++ INIT_WORK(&sync_state->work_item,
++ goldfish_sync_work_item_fn);
++
++ misc_register(&goldfish_sync_device);
++
++ /* Obtain addresses for batch send/recv of commands. */
++ {
++ struct goldfish_sync_hostcmd *batch_addr_hostcmd;
++ struct goldfish_sync_guestcmd *batch_addr_guestcmd;
++
++ batch_addr_hostcmd =
++ devm_kzalloc(&pdev->dev,
++ sizeof(struct goldfish_sync_hostcmd),
++ GFP_KERNEL);
++ batch_addr_guestcmd =
++ devm_kzalloc(&pdev->dev,
++ sizeof(struct goldfish_sync_guestcmd),
++ GFP_KERNEL);
++
++ if (!setup_verify_batch_cmd_addr(
++ sync_state,
++ batch_addr_hostcmd,
++ SYNC_REG_BATCH_COMMAND_ADDR,
++ SYNC_REG_BATCH_COMMAND_ADDR_HIGH)) {
++ pr_err("goldfish_sync: Could not setup batch command address");
++ return -ENODEV;
++ }
++
++ if (!setup_verify_batch_cmd_addr(
++ sync_state,
++ batch_addr_guestcmd,
++ SYNC_REG_BATCH_GUESTCOMMAND_ADDR,
++ SYNC_REG_BATCH_GUESTCOMMAND_ADDR_HIGH)) {
++ pr_err("goldfish_sync: Could not setup batch guest command address");
++ return -ENODEV;
++ }
++
++ sync_state->batch_hostcmd = batch_addr_hostcmd;
++ sync_state->batch_guestcmd = batch_addr_guestcmd;
++ }
++
++ pr_info("goldfish_sync: Initialized goldfish sync device");
++
++ writel(0, sync_state->reg_base + SYNC_REG_INIT);
++
++ return 0;
++}
++
++static int goldfish_sync_remove(struct platform_device *pdev)
++{
++ struct goldfish_sync_state *sync_state = global_sync_state;
++
++ DTRACE();
++
++ misc_deregister(&goldfish_sync_device);
++ memset(sync_state, 0, sizeof(struct goldfish_sync_state));
++ return 0;
++}
++
++static const struct of_device_id goldfish_sync_of_match[] = {
++ { .compatible = "google,goldfish-sync", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, goldfish_sync_of_match);
++
++static const struct acpi_device_id goldfish_sync_acpi_match[] = {
++ { "GFSH0006", 0 },
++ { },
++};
++
++MODULE_DEVICE_TABLE(acpi, goldfish_sync_acpi_match);
++
++static struct platform_driver goldfish_sync = {
++ .probe = goldfish_sync_probe,
++ .remove = goldfish_sync_remove,
++ .driver = {
++ .name = "goldfish_sync",
++ .of_match_table = goldfish_sync_of_match,
++ .acpi_match_table = ACPI_PTR(goldfish_sync_acpi_match),
++ }
++};
++
++module_platform_driver(goldfish_sync);
++
++MODULE_AUTHOR("Google, Inc.");
++MODULE_DESCRIPTION("Android QEMU Sync Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("1.0");
+--- /dev/null
++++ b/drivers/staging/goldfish/goldfish_sync_timeline_fence.c
+@@ -0,0 +1,258 @@
++/*
++ * Timeline-based sync for Goldfish Sync
++ * Based on "Sync File validation framework"
++ * (drivers/dma-buf/sw_sync.c)
++ *
++ * Copyright (C) 2017 Google, Inc.
++ *
++ * 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.
++ *
++ */
++
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/syscalls.h>
++#include <linux/sync_file.h>
++#include <linux/dma-fence.h>
++
++#include "goldfish_sync_timeline_fence.h"
++
++/**
++ * struct goldfish_sync_timeline - sync object
++ * @kref: reference count on fence.
++ * @name: name of the goldfish_sync_timeline. Useful for debugging
++ * @child_list_head: list of children sync_pts for goldfish_sync_timeline
++ * @child_list_lock: lock protecting @child_list_head and fence.status
++ * @active_list_head: list of active (unsignaled/errored) sync_pts
++ */
++struct goldfish_sync_timeline {
++ struct kref kref;
++ char name[32];
++
++ /* protected by child_list_lock */
++ u64 context;
++ int value;
++
++ struct list_head child_list_head;
++ /* protecting @child_list_head and fence.status */
++ spinlock_t child_list_lock;
++
++ struct list_head active_list_head;
++};
++
++static inline struct goldfish_sync_timeline *fence_parent(
++ struct dma_fence *fence)
++{
++ return container_of(fence->lock, struct goldfish_sync_timeline,
++ child_list_lock);
++}
++
++static const struct dma_fence_ops goldfish_sync_timeline_fence_ops;
++
++static inline struct sync_pt *goldfish_sync_fence_to_sync_pt(
++ struct dma_fence *fence)
++{
++ if (fence->ops != &goldfish_sync_timeline_fence_ops)
++ return NULL;
++ return container_of(fence, struct sync_pt, base);
++}
++
++/**
++ * goldfish_sync_timeline_create_internal() - creates a sync object
++ * @name: sync_timeline name
++ *
++ * Creates a new sync_timeline. Returns the sync_timeline object or NULL in
++ * case of error.
++ */
++struct goldfish_sync_timeline
++*goldfish_sync_timeline_create_internal(const char *name)
++{
++ struct goldfish_sync_timeline *obj;
++
++ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
++ if (!obj)
++ return NULL;
++
++ kref_init(&obj->kref);
++ obj->context = dma_fence_context_alloc(1);
++ strlcpy(obj->name, name, sizeof(obj->name));
++
++ INIT_LIST_HEAD(&obj->child_list_head);
++ INIT_LIST_HEAD(&obj->active_list_head);
++ spin_lock_init(&obj->child_list_lock);
++
++ return obj;
++}
++
++static void goldfish_sync_timeline_free_internal(struct kref *kref)
++{
++ struct goldfish_sync_timeline *obj =
++ container_of(kref, struct goldfish_sync_timeline, kref);
++
++ kfree(obj);
++}
++
++static void goldfish_sync_timeline_get_internal(
++ struct goldfish_sync_timeline *obj)
++{
++ kref_get(&obj->kref);
++}
++
++void goldfish_sync_timeline_put_internal(struct goldfish_sync_timeline *obj)
++{
++ kref_put(&obj->kref, goldfish_sync_timeline_free_internal);
++}
++
++/**
++ * goldfish_sync_timeline_signal() -
++ * signal a status change on a goldfish_sync_timeline
++ * @obj: sync_timeline to signal
++ * @inc: num to increment on timeline->value
++ *
++ * A sync implementation should call this any time one of it's fences
++ * has signaled or has an error condition.
++ */
++void goldfish_sync_timeline_signal_internal(
++ struct goldfish_sync_timeline *obj, unsigned int inc)
++{
++ unsigned long flags;
++ struct sync_pt *pt, *next;
++
++ spin_lock_irqsave(&obj->child_list_lock, flags);
++
++ obj->value += inc;
++
++ list_for_each_entry_safe(pt, next, &obj->active_list_head,
++ active_list) {
++ if (dma_fence_is_signaled_locked(&pt->base))
++ list_del_init(&pt->active_list);
++ }
++
++ spin_unlock_irqrestore(&obj->child_list_lock, flags);
++}
++
++/**
++ * goldfish_sync_pt_create_internal() - creates a sync pt
++ * @parent: fence's parent sync_timeline
++ * @size: size to allocate for this pt
++ * @inc: value of the fence
++ *
++ * Creates a new sync_pt as a child of @parent. @size bytes will be
++ * allocated allowing for implementation specific data to be kept after
++ * the generic sync_timeline struct. Returns the sync_pt object or
++ * NULL in case of error.
++ */
++struct sync_pt *goldfish_sync_pt_create_internal(
++ struct goldfish_sync_timeline *obj, int size, unsigned int value)
++{
++ unsigned long flags;
++ struct sync_pt *pt;
++
++ if (size < sizeof(*pt))
++ return NULL;
++
++ pt = kzalloc(size, GFP_KERNEL);
++ if (!pt)
++ return NULL;
++
++ spin_lock_irqsave(&obj->child_list_lock, flags);
++ goldfish_sync_timeline_get_internal(obj);
++ dma_fence_init(&pt->base, &goldfish_sync_timeline_fence_ops,
++ &obj->child_list_lock, obj->context, value);
++ list_add_tail(&pt->child_list, &obj->child_list_head);
++ INIT_LIST_HEAD(&pt->active_list);
++ spin_unlock_irqrestore(&obj->child_list_lock, flags);
++ return pt;
++}
++
++static const char *goldfish_sync_timeline_fence_get_driver_name(
++ struct dma_fence *fence)
++{
++ return "sw_sync";
++}
++
++static const char *goldfish_sync_timeline_fence_get_timeline_name(
++ struct dma_fence *fence)
++{
++ struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++ return parent->name;
++}
++
++static void goldfish_sync_timeline_fence_release(struct dma_fence *fence)
++{
++ struct sync_pt *pt = goldfish_sync_fence_to_sync_pt(fence);
++ struct goldfish_sync_timeline *parent = fence_parent(fence);
++ unsigned long flags;
++
++ spin_lock_irqsave(fence->lock, flags);
++ list_del(&pt->child_list);
++ if (!list_empty(&pt->active_list))
++ list_del(&pt->active_list);
++ spin_unlock_irqrestore(fence->lock, flags);
++
++ goldfish_sync_timeline_put_internal(parent);
++ dma_fence_free(fence);
++}
++
++static bool goldfish_sync_timeline_fence_signaled(struct dma_fence *fence)
++{
++ struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++ return (fence->seqno > parent->value) ? false : true;
++}
++
++static bool goldfish_sync_timeline_fence_enable_signaling(
++ struct dma_fence *fence)
++{
++ struct sync_pt *pt = goldfish_sync_fence_to_sync_pt(fence);
++ struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++ if (goldfish_sync_timeline_fence_signaled(fence))
++ return false;
++
++ list_add_tail(&pt->active_list, &parent->active_list_head);
++ return true;
++}
++
++static void goldfish_sync_timeline_fence_disable_signaling(
++ struct dma_fence *fence)
++{
++ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
++
++ list_del_init(&pt->active_list);
++}
++
++static void goldfish_sync_timeline_fence_value_str(
++ struct dma_fence *fence, char *str, int size)
++{
++ snprintf(str, size, "%d", fence->seqno);
++}
++
++static void goldfish_sync_timeline_fence_timeline_value_str(
++ struct dma_fence *fence,
++ char *str, int size)
++{
++ struct goldfish_sync_timeline *parent = fence_parent(fence);
++
++ snprintf(str, size, "%d", parent->value);
++}
++
++static const struct dma_fence_ops goldfish_sync_timeline_fence_ops = {
++ .get_driver_name = goldfish_sync_timeline_fence_get_driver_name,
++ .get_timeline_name = goldfish_sync_timeline_fence_get_timeline_name,
++ .enable_signaling = goldfish_sync_timeline_fence_enable_signaling,
++ .disable_signaling = goldfish_sync_timeline_fence_disable_signaling,
++ .signaled = goldfish_sync_timeline_fence_signaled,
++ .wait = dma_fence_default_wait,
++ .release = goldfish_sync_timeline_fence_release,
++ .fence_value_str = goldfish_sync_timeline_fence_value_str,
++ .timeline_value_str = goldfish_sync_timeline_fence_timeline_value_str,
++};
+--- /dev/null
++++ b/drivers/staging/goldfish/goldfish_sync_timeline_fence.h
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (C) 2016 Google, Inc.
++ *
++ * 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.
++ *
++ */
++
++#include <linux/sync_file.h>
++#include <linux/dma-fence.h>
++
++/**
++ * struct sync_pt - sync_pt object
++ * @base: base fence object
++ * @child_list: sync timeline child's list
++ * @active_list: sync timeline active child's list
++ */
++struct sync_pt {
++ struct dma_fence base;
++ struct list_head child_list;
++ struct list_head active_list;
++};
++
++/**
++ * goldfish_sync_timeline_create_internal() - creates a sync object
++ * @name: goldfish_sync_timeline name
++ *
++ * Creates a new goldfish_sync_timeline.
++ * Returns the goldfish_sync_timeline object or NULL in case of error.
++ */
++struct goldfish_sync_timeline
++*goldfish_sync_timeline_create_internal(const char *name);
++
++/**
++ * goldfish_sync_pt_create_internal() - creates a sync pt
++ * @parent: fence's parent goldfish_sync_timeline
++ * @size: size to allocate for this pt
++ * @inc: value of the fence
++ *
++ * Creates a new sync_pt as a child of @parent. @size bytes will be
++ * allocated allowing for implementation specific data to be kept after
++ * the generic sync_timeline struct. Returns the sync_pt object or
++ * NULL in case of error.
++ */
++struct sync_pt
++*goldfish_sync_pt_create_internal(
++ struct goldfish_sync_timeline *obj, int size, unsigned int value);
++
++/**
++ * goldfish_sync_timeline_signal_internal() -
++ * signal a status change on a sync_timeline
++ * @obj: goldfish_sync_timeline to signal
++ * @inc: num to increment on timeline->value
++ *
++ * A sync implementation should call this any time one of it's fences
++ * has signaled or has an error condition.
++ */
++void goldfish_sync_timeline_signal_internal(
++ struct goldfish_sync_timeline *obj, unsigned int inc);
++
++/**
++ * goldfish_sync_timeline_put_internal() - dec refcount of a sync_timeline
++ * and clean up memory if it was the last ref.
++ * @obj: goldfish_sync_timeline to decref
++ */
++void goldfish_sync_timeline_put_internal(struct goldfish_sync_timeline *obj);
diff --git a/series b/series
index 10ecdfd..41096ea 100644
--- a/series
+++ b/series
@@ -1,3 +1,6 @@
+0001-goldfish_pipe-An-implementation-of-more-parallel-pip.patch
+0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch
+0003-goldfish-Add-goldfish-sync-driver.patch
eventpoll.h-fix-epoll-event-masks.patch
eventpoll.h-add-missing-epoll-event-masks.patch
0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch