All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] pl011 emulation support in Xen
@ 2017-02-21 11:25 Bhupinder Thakur
  2017-02-21 11:25 ` [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
                   ` (12 more replies)
  0 siblings, 13 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:25 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

PL011 emulation for guests in Xen
=====================================

This feature allows the Xen guests to map their console to a SBSA compliant
pl011 UART as specified in ARM Service Base System architecture, Appendix B. 
Currently, Xen supports paravirtualized (aka PV) and an emulated serial 
consoles. This feature will allow an emulated SBSA pl011 UART console, which 
a user can access using xenconsoled running on dom0.

The device tree passed to the guest VM will contain the pl011 MMIO address 
range and an irq for receiving rx/tx pl011 interrupts. The device tree format 
is specified in Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt.

The Xen hypervisor will expose two types of interfaces to dom0 and domU. 

The interface exposed to domU will be an emulated pl011 UART by emulating the 
access to the following pl011 registers by the guest.

- Data register (DR)            - RW
- Control register (CR)         - RW
- Raw interrupt status register (RIS)   - RO
- Masked interrupt status register (MIS)- RO
- Interrupt Mask (IMSC)         - RW
- Interrupt Clear (ICR)         - WO

It will also inject the pl011 interrupts to the guest in the following 
conditions:

- incoming data in the rx buffer for the guest
- there is space in the tx buffer for the guest to write more data

The interface exposed to dom0 will be the same PV console interface, which
minimizes the changes required in xenconsole to support a new pl011 console.

This interface has rx and tx ring buffers and an event channel for 
sending/receiving events from dom0. 

So essentially Xen handles the data on behalf of domU and dom0. Any data 
written by domU is captured by Xen and written to the TX (OUT) ring buffer 
and a pl011 event is raised to dom0 to read the TX ring buffer.
 
Similarly on reciving a pl011 event, Xen injects an interrupt to guest to
indicate there is data available in the RX (IN) ring buffer.

Note that the pl011 UART state is completely captured in the set of registers 
mentioned above and this state is updated everytime there is an event from 
dom0 or there is register read/write access from domU. For example, if domU 
has masked the rx interrupt in the IMSC register, then Xen will not inject an 
interrupt to guest and will just update the RIS register. Once the interrupt 
is unmasked by guest, the interrupt will be delivered to the guest.

The following changes were done:

Xen Hypervisor
===============

1. Add emulation code to emulate read/write access to pl011 registers and pl011 
   interrupts
    - It emulates DR read/write by reading and writing from/to the IN and 
      OUT ring buffers and raising an event to dom0 when there is data in 
      the OUT ring buffer and injecting an interrupt to the guest when there 
      is data in the IN ring buffer
    - Other registers are related to interrupt management and essentially 
      control when interrupts are delivered to the guest

2. Add three new HVM param handlers for 
    - allocating a new VIRQ and return to the toolstack
    - allocating a new event channel for sending/receiving events from Xen 
      and return to the toolstack
    - mapping the PFN allocted by the toolstack to be used as IN/OUT ring 
      buffers
3. Breakup evtchn_send() to allow sending events for a Xen bound channel 
   (Currently, there is a check which disallows generating events for a Xen 
    bound channel)

4. Enable vpl011 emulation for a domain when it is created

5. Ensuring that nr_spis is atleast 1 to allow allocation of vpl011 spi virq

Toolstack
==========

1. Reading a VIRQ from Xen using a hvm call and using it for adding new device 
   tree node in the guest DT for SBSA pl011 uart containing the IRQ and the 
   MMIO address range to be used by the guest

2. Allocating a new PFN and passing it on to Xen though a hvm call to be used 
   as the IN/OUT ring buffers

3. Add two new parameters to the xen store
    - newly allocated PFN to be used as IN/OUT ring buffer by xenconsoled 
    - a new event channel read from Xen using a hvm call to be used by 
      xenconsoled for eventing

Xenconsoled
============

1. Modfication in domain_create_ring() 
    - Bind to the vpl011 event channel obtained from the xen store as a new
      parameter
    - Map the PFN to its address space to be used as IN/OUT ring buffers. 
      It obtains the PFN from the xen store as a new parameter

2. Modificaton to handle_ring_read() and buffer_append () to allow reading data 
   from both PV or vpl011 OUT ring buffers and add to the output buffer

3. Modification in handle_tty_read to write the user data to the vpl011 IN ring
   buffer  

There are still some items which are pending:

1. Adding dynamic enable/disable of pl011 emulation for a guest
2. Add a new console type "pl011" in xenconsoled to allow the user to connect to
either PV/serial/pl011 console.
3. Add checks to ensure that the new hvm params read/written by the guest


Bhupinder Thakur (11):
  xen/arm: vpl011: Add pl011 uart emulation in Xen
  xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events
    from a xen bound channel
  xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen
  xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the
    toolstack
  xen/arm: vpl011: Add two new vpl011 parameters to xenstore
  xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen
    using a hvm call
  xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the
    ring buffer and event channel
  xen/arm: vpl011: Modify handle_ring_read and buffer_append to
    read/append vpl011 data
  xen/arm: vpl011: Modify handle_tty_read in xenconsole to redirect user
    data to vpl011 IN ring buffer

 tools/console/daemon/io.c       | 168 +++++++++++++++---
 tools/libxc/include/xc_dom.h    |   5 +
 tools/libxc/xc_dom_arm.c        |   7 +-
 tools/libxc/xc_dom_boot.c       |   5 +
 tools/libxc/xc_domain.c         |   3 +
 tools/libxl/libxl.c             |   6 +
 tools/libxl/libxl_arm.c         |  47 +++++-
 tools/libxl/libxl_dom.c         |  18 +-
 tools/libxl/libxl_internal.h    |   4 +
 xen/arch/arm/Makefile           |   1 +
 xen/arch/arm/domain.c           |   8 +
 xen/arch/arm/hvm.c              |  39 +++++
 xen/arch/arm/vgic.c             |   5 +
 xen/arch/arm/vpl011.c           | 366 ++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/vpl011.h           | 208 +++++++++++++++++++++++
 xen/common/Kconfig              |   6 +
 xen/common/domctl.c             |   2 +
 xen/common/event_channel.c      |  49 ++++--
 xen/include/asm-arm/domain.h    |  15 ++
 xen/include/public/arch-arm.h   |   5 +
 xen/include/public/hvm/params.h |  10 +-
 xen/include/xen/event.h         |   6 +
 xen/include/xen/sched.h         |   4 +
 23 files changed, 944 insertions(+), 43 deletions(-)
 create mode 100644 xen/arch/arm/vpl011.c
 create mode 100644 xen/arch/arm/vpl011.h

-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
@ 2017-02-21 11:25 ` Bhupinder Thakur
  2017-02-26 21:37   ` Julien Grall
                     ` (2 more replies)
  2017-02-21 11:25 ` [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup Bhupinder Thakur
                   ` (11 subsequent siblings)
  12 siblings, 3 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:25 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Add emulation code to emulate read/write access to pl011 registers
and pl011 interrupts:

    - It emulates DR read/write by reading and writing from/to the IN
      and OUT ring buffers and raising an event to dom0 when there is
      data in the OUT ring buffer and injecting an interrupt to the
      guest when there is data in the IN ring buffer

    - Other registers are related to interrupt management and
      essentially control when interrupts are delivered to the guest

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 xen/arch/arm/Makefile         |   1 +
 xen/arch/arm/vpl011.c         | 366 ++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/vpl011.h         | 208 ++++++++++++++++++++++++
 xen/common/Kconfig            |   6 +
 xen/include/asm-arm/domain.h  |  15 ++
 xen/include/public/arch-arm.h |   5 +
 6 files changed, 601 insertions(+)
 create mode 100644 xen/arch/arm/vpl011.c
 create mode 100644 xen/arch/arm/vpl011.h

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 7afb8a3..a94bdab 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -49,6 +49,7 @@ obj-y += vm_event.o
 obj-y += vtimer.o
 obj-y += vpsci.o
 obj-y += vuart.o
+obj-$(CONFIG_VPL011_CONSOLE) += vpl011.o
 
 #obj-bin-y += ....o
 
diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
new file mode 100644
index 0000000..88ba968
--- /dev/null
+++ b/xen/arch/arm/vpl011.c
@@ -0,0 +1,366 @@
+/*
+ * arch/arm/vpl011.c
+ *
+ * Virtual PL011 UART 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/guest_access.h>
+#include <xen/sched.h>
+#include <xen/monitor.h>
+#include <xen/event.h>
+#include <xen/vmap.h>
+
+#include <xsm/xsm.h>
+
+#include <public/xen.h>
+#include <public/hvm/params.h>
+#include <public/hvm/hvm_op.h>
+
+#include <asm/hypercall.h>
+#include "vpl011.h"
+
+static int vpl011_mmio_read(struct vcpu *v, mmio_info_t *info, register_t *r, void *priv)
+{
+    unsigned char ch;
+
+    switch (info->gpa - GUEST_PL011_BASE)
+    {
+        case VPL011_UARTCR_OFFSET:
+            *r = v->domain->arch.vpl011.control;
+            break;
+        case VPL011_UARTDR_OFFSET:
+            vpl011_read_data(v->domain, &ch);
+            *r = ch;
+            break;
+        case VPL011_UARTFR_OFFSET:
+            *r = v->domain->arch.vpl011.flag;
+            break;
+        case VPL011_UARTIMSC_OFFSET:
+            *r = v->domain->arch.vpl011.intr_mask;
+            break;
+        case VPL011_UARTICR_OFFSET: 
+            *r = 0;
+            break;
+        case VPL011_UARTRIS_OFFSET:
+            *r = v->domain->arch.vpl011.raw_intr_status;
+            break;
+        case VPL011_UARTMIS_OFFSET:
+            *r = v->domain->arch.vpl011.raw_intr_status &
+                                v->domain->arch.vpl011.intr_mask;
+            break;
+        case VPL011_UARTDMACR_OFFSET:
+            *r = 0; /* uart DMA is not supported. Here it always returns 0 */
+            break;
+        case VPL011_UARTRSR_OFFSET: 
+            *r = 0; /* it always returns 0 as there are no physical errors */
+            break;
+        default:
+            printk ("vpl011_mmio_read: invalid switch case %d\n", (int)(info->gpa - GUEST_PL011_BASE));
+            break;
+    }
+
+    return VPL011_EMUL_OK;
+}
+
+static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void *priv)
+{
+    unsigned char ch = r;
+
+    switch (info->gpa - GUEST_PL011_BASE)
+    {
+        case VPL011_UARTCR_OFFSET:
+            v->domain->arch.vpl011.control = r;
+            break;
+        case VPL011_UARTDR_OFFSET:
+            vpl011_write_data(v->domain, ch);
+            break;
+        case VPL011_UARTIMSC_OFFSET:
+            v->domain->arch.vpl011.intr_mask = r;
+            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )
+                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
+            break;
+        case VPL011_UARTICR_OFFSET: 
+            /*
+             * clear all bits which are set in the input
+             */
+            v->domain->arch.vpl011.raw_intr_status &= ~r;
+            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )
+            {
+                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
+            }
+            break;
+        case VPL011_UARTRSR_OFFSET: // nothing to clear
+            break;
+        case VPL011_UARTFR_OFFSET: // these are all RO registers
+        case VPL011_UARTRIS_OFFSET:
+        case VPL011_UARTMIS_OFFSET:
+        case VPL011_UARTDMACR_OFFSET:
+            break;
+        default:
+            printk ("vpl011_mmio_write: switch case not handled %d\n", (int)(info->gpa - GUEST_PL011_BASE));
+            break;
+    }
+
+    return VPL011_EMUL_OK;
+}
+
+static const struct mmio_handler_ops vpl011_mmio_handler = {
+    .read = vpl011_mmio_read,
+    .write = vpl011_mmio_write,
+};
+
+
+
+int vpl011_map_guest_page(struct domain *d)
+{
+    int rc=0;
+
+    /*
+     * map the guest PFN to Xen address space
+     */
+    rc = prepare_ring_for_helper(d, 
+                                 d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_PFN],
+                                 &d->arch.vpl011.ring_page, 
+                                 (void **)&d->arch.vpl011.ring_buf);
+    if ( rc < 0 )
+    {
+        printk("Failed to map vpl011 guest PFN\n");
+    }
+
+    return rc;
+}
+
+static int vpl011_data_avail(struct domain *d)
+{
+    int rc=0;
+    unsigned long flags;
+
+    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
+
+    VPL011_LOCK(d, flags);
+
+    /*`
+     * check IN ring buffer
+     */
+    if ( !VPL011_IN_RING_EMPTY(intf) )
+    {
+        /*
+         * clear the RX FIFO empty flag as the ring is not empty
+         */
+        d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFE);
+
+        /*
+         * if the buffer is full then set the RX FIFO FULL flag
+         */
+        if ( VPL011_IN_RING_FULL(intf) )
+            d->arch.vpl011.flag |= (VPL011_UARTFR_RXFF);
+
+        /*
+         * set the RX interrupt status
+         */
+        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_RXRIS);
+    }
+
+    /*
+     * check OUT ring buffer
+     */
+    if ( !VPL011_OUT_RING_FULL(intf) )
+    {
+        /*
+         * if the buffer is not full then clear the TX FIFO full flag
+         */
+        d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFF);
+
+        /*
+         * set the TX interrupt status
+         */
+        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_TXRIS);
+
+        if ( VPL011_OUT_RING_EMPTY(intf) )
+        {
+            /*
+             * clear the uart busy flag and set the TX FIFO empty flag
+             */
+            d->arch.vpl011.flag &= ~(VPL011_UARTFR_BUSY);
+            d->arch.vpl011.flag |= (VPL011_UARTFR_TXFE);
+        }
+    }
+
+    VPL011_UNLOCK(d, flags);
+
+    /*
+     * send an interrupt if it is not masked
+     */
+    if ( (d->arch.vpl011.raw_intr_status & d->arch.vpl011.intr_mask) )
+        vgic_vcpu_inject_spi(d, (int)d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
+
+    if ( !VPL011_OUT_RING_EMPTY(intf) )
+    {
+        /*
+         * raise an interrupt to dom0
+         */
+        rc = raw_evtchn_send(d, 
+                    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL); 
+
+        if ( rc < 0 )
+            printk("Failed to send vpl011 interrupt to dom0\n");
+    }
+
+    return rc;
+}
+
+int vpl011_read_data(struct domain *d, unsigned char *data)
+{
+    int rc=0;
+    unsigned long flags;
+    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
+
+    *data = 0;
+
+    VPL011_LOCK(d, flags);
+
+    /*
+     * if there is data in the ring buffer then copy it to the output buffer
+     */
+    if ( !VPL011_IN_RING_EMPTY(intf) )
+    {
+        *data = intf->in[MASK_VPL011CONS_IDX(intf->in_cons++, intf->in)];
+    }
+
+    /*
+     * if the ring buffer is empty then set the RX FIFO empty flag
+     */
+    if ( VPL011_IN_RING_EMPTY(intf) )
+    {
+        d->arch.vpl011.flag |= (VPL011_UARTFR_RXFE);
+        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_RXRIS);
+    }
+
+    /*
+     * clear the RX FIFO full flag
+     */
+    d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFF);
+
+    VPL011_UNLOCK(d, flags);
+
+    return rc;
+}
+
+int vpl011_write_data(struct domain *d, unsigned char data)
+{
+    int rc=0;
+    unsigned long flags;
+    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
+
+    VPL011_LOCK(d, flags);
+
+    /*
+     * if there is space in the ring buffer then write the data
+     */
+    if ( !VPL011_OUT_RING_FULL(intf) )
+    {
+        intf->out[MASK_VPL011CONS_IDX(intf->out_prod++, intf->out)] = data;
+        smp_wmb();
+    }
+
+    /*
+     * if there is no space in the ring buffer then set the 
+     * TX FIFO FULL flag
+     */
+    if ( VPL011_OUT_RING_FULL(intf) )
+    {
+        d->arch.vpl011.flag |= (VPL011_UARTFR_TXFF);
+        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_TXRIS);
+    }
+
+    /*
+     * set the uart busy status
+     */
+    d->arch.vpl011.flag |= (VPL011_UARTFR_BUSY);
+
+    /*
+     * clear the TX FIFO empty flag
+     */
+    d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFE);
+
+    VPL011_UNLOCK(d, flags);
+
+    /*
+     * raise an event to dom0 only if it is the first character in the buffer
+     */
+    if ( VPL011_RING_DEPTH(intf, out) == 1 )
+    {
+        rc = raw_evtchn_send(d, 
+                d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL); 
+
+        if ( rc < 0 )
+            printk("Failed to send vpl011 interrupt to dom0\n");
+    }
+
+    return rc;
+}
+
+static void vpl011_notification(struct vcpu *v, unsigned int port)
+{
+    vpl011_data_avail(v->domain);
+}
+
+int domain_vpl011_init(struct domain *d)
+{
+    int rc=0;
+
+    /*
+     * register xen event channel
+     */
+    rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id, 
+                                                        vpl011_notification);
+    if (rc < 0)
+    {
+        printk ("Failed to allocate vpl011 event channel\n");
+        return rc;
+    }
+    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN] = rc;
+    
+    /*
+     * allocate an SPI VIRQ for the guest
+     */
+    d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ] = vgic_allocate_spi(d);
+
+    /*
+     * register mmio handler 
+     */
+    register_mmio_handler (d, &vpl011_mmio_handler, GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL);
+
+    /* 
+     * initialize the lock
+     */
+    spin_lock_init(&d->arch.vpl011.lock);
+
+    /* 
+     * clear the flag, control and interrupt status registers
+     */
+    d->arch.vpl011.control = 0;
+    d->arch.vpl011.flag = 0;
+    d->arch.vpl011.intr_mask = 0;
+    d->arch.vpl011.intr_clear = 0;
+    d->arch.vpl011.raw_intr_status = 0;
+    d->arch.vpl011.masked_intr_status = 0;
+
+    return 0;
+}
diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h
new file mode 100644
index 0000000..f2c577f
--- /dev/null
+++ b/xen/arch/arm/vpl011.h
@@ -0,0 +1,208 @@
+/*
+ * include/xen/vpl011.h
+ *
+ * Virtual PL011 UART 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _VPL011_H_
+
+#define _VPL011_H_
+
+/*
+ * register offsets
+ */
+#define VPL011_UARTDR_OFFSET    0x0 // data register (RW)
+#define VPL011_UARTRSR_OFFSET   0x4 // receive status and error clear register (RW)
+#define VPL011_UARTFR_OFFSET    0x18 // flag register (RO)
+#define VPL011_UARTRIS_OFFSET   0x3c // raw interrupt status register (RO)
+#define VPL011_UARTMIS_OFFSET   0x40 // masked interrupt status register (RO)
+#define VPL011_UARTIMSC_OFFSET  0x38 // interrupt mask set/clear register (RW)
+#define VPL011_UARTICR_OFFSET   0x44 // interrupt clear register (WO)
+#define VPL011_UARTCR_OFFSET    0x30 // uart control register
+#define VPL011_UARTDMACR_OFFSET 0x48 // uart dma control register
+
+/*
+ * control register bits - RW
+ */
+#define VPL011_UARTCR_UARTEN_BIT 0
+#define VPL011_UARTCR_UARTEN    (1<<VPL011_UARTCR_UARTEN_BIT)
+#define VPL011_UARTCR_TXE_BIT    8
+#define VPL011_UARTCR_TXE       (1<<VPL011_UARTCR_TXE_BIT)
+#define VPL011_UARTCR_RXE_BIT    9
+#define VPL011_UARTCR_RXE       (1<<VPL011_UARTCR_RXE_BIT)
+
+/*
+ * Flag register bits - RO
+ */
+#define VPL011_UARTFR_CTS_BIT   0   // clear to send
+#define VPL011_UARTFR_CTS       (1<<VPL011_UARTFR_CTS_BIT)
+#define VPL011_UARTFR_DSR_BIT   1   // data set ready
+#define VPL011_UARTFR_DSR       (1<<VPL011_UARTFR_DSR_BIT)
+#define VPL011_UARTFR_DCD_BIT   2   // data carrier detect
+#define VPL011_UARTFR_DCD       (1<<VPL011_UARTFR_DCD_BIT)
+#define VPL011_UARTFR_BUSY_BIT  3   // uart busy
+#define VPL011_UARTFR_BUSY      (1<<VPL011_UARTFR_BUSY_BIT)
+#define VPL011_UARTFR_RXFE_BIT  4   // receive fifo empty
+#define VPL011_UARTFR_RXFE      (1<<VPL011_UARTFR_RXFE_BIT)
+#define VPL011_UARTFR_TXFF_BIT  5   // transmit fifo full
+#define VPL011_UARTFR_TXFF      (1<<VPL011_UARTFR_TXFF_BIT)
+#define VPL011_UARTFR_RXFF_BIT  6   // receive fifo full
+#define VPL011_UARTFR_RXFF      (1<<VPL011_UARTFR_RXFF_BIT)
+#define VPL011_UARTFR_TXFE_BIT  7   // transmit fifo empty
+#define VPL011_UARTFR_TXFE      (1<<VPL011_UARTFR_TXFE_BIT)
+#define VPL011_UARTFR_RI_BIT    8   // ring indicator
+#define VPL011_UARTFR_RI        (1<<VPL011_UARTFR_RI_BIT)
+
+/*
+ * UART raw interrupt status bits - RO
+ */
+#define VPL011_UARTRIS_RIRMIS_BIT  0
+#define VPL011_UARTRIS_RIRMIS      (1<<VPL011_UARTRIS_RIRMIS_BIT)
+#define VPL011_UARTRIS_CTSRMIS_BIT 1
+#define VPL011_UARTRIS_CTSRMIS     (1<<VPL011_UARTRIS_CTSRMIS_BIT)
+#define VPL011_UARTRIS_DCDRMIS_BIT 2
+#define VPL011_UARTRIS_DCDRMIS     (1<<VPL011_UARTRIS_DCDRMIS_BIT)
+#define VPL011_UARTRIS_DSRRMIS_BIT 3
+#define VPL011_UARTRIS_DSRRMIS     (1<<VPL011_UARTRIS_DSRRMIS_BIT)
+#define VPL011_UARTRIS_RXRIS_BIT   4
+#define VPL011_UARTRIS_RXRIS       (1<<VPL011_UARTRIS_RXRIS_BIT)
+#define VPL011_UARTRIS_TXRIS_BIT   5
+#define VPL011_UARTRIS_TXRIS       (1<<VPL011_UARTRIS_TXRIS_BIT)
+#define VPL011_UARTRIS_RTRIS_BIT   6
+#define VPL011_UARTRIS_RTRIS       (1<<VPL011_UARTRIS_RTRIS_BIT)
+#define VPL011_UARTRIS_FERIS_BIT   7
+#define VPL011_UARTRIS_FERIS       (1<<VPL011_UARTRIS_FERIS_BIT)
+#define VPL011_UARTRIS_PERIS_BIT   8
+#define VPL011_UARTRIS_PERIS       (1<<VPL011_UARTRIS_PERIS_BIT)
+#define VPL011_UARTRIS_BERIS_BIT   9
+#define VPL011_UARTRIS_BERIS       (1<<VPL011_UARTRIS_BERIS_BIT)
+#define VPL011_UARTRIS_OERIS_BIT   10
+#define VPL011_UARTRIS_OERIS       (1<<VPL011_UARTRIS_OERIS_BIT)
+
+/*
+ * UART masked interrupt status bits - RO
+ */
+#define VPL011_UARTMIS_RIMMIS_BIT  0
+#define VPL011_UARTMIS_RIMMIS      (1<<VPL011_UARTMIS_RIMMIS_BIT)
+#define VPL011_UARTMIS_CTSMMIS_BIT 1
+#define VPL011_UARTMIS_CTSMMIS     (1<<VPL011_UARTMIS_CTSMMIS_BIT)
+#define VPL011_UARTMIS_DCDMMIS_BIT 2
+#define VPL011_UARTMIS_DCDMMIS     (1<<VPL011_UARTMIS_DCDMMIS_BIT)
+#define VPL011_UARTMIS_DSRMMIS_BIT 3
+#define VPL011_UARTMIS_DSRMMIS     (1<<VPL011_UARTMIS_DSRMMIS_BIT)
+#define VPL011_UARTMIS_RXMIS_BIT   4
+#define VPL011_UARTMIS_RXMIS       (1<<VPL011_UARTMIS_RXMIS_BIT)
+#define VPL011_UARTMIS_TXMIS_BIT   5
+#define VPL011_UARTMIS_TXMIS       (1<<VPL011_UARTMIS_TXMIS_BIT)
+#define VPL011_UARTMIS_RTMIS_BIT   6
+#define VPL011_UARTMIS_RTMIS       (1<<VPL011_UARTMIS_RTMIS_BIT)
+#define VPL011_UARTMIS_FEMIS_BIT   7
+#define VPL011_UARTMIS_FEMIS       (1<<VPL011_UARTMIS_FEMIS_BIT)
+#define VPL011_UARTMIS_PEMIS_BIT   8
+#define VPL011_UARTMIS_PEMIS       (1<<VPL011_UARTMIS_PEMIS_BIT)
+#define VPL011_UARTMIS_BEMIS_BIT   9
+#define VPL011_UARTMIS_BEMIS       (1<<VPL011_UARTMIS_BEMIS_BIT)
+#define VPL011_UARTMIS_OEMIS_BIT   10
+#define VPL011_UARTMIS_OEMIS       (1<<VPL011_UARTMIS_OEMIS_BIT)
+
+/*
+ * UART  interrupt clear bits - WO
+ */
+#define VPL011_UARTICR_RIMIC_BIT    0
+#define VPL011_UARTICR_RIMIC        (1<<VPL011_UARTICR_RIMIC_BIT)
+#define VPL011_UARTICR_CTSMIC_BIT   1
+#define VPL011_UARTICR_CTSMIC       (1<<VPL011_UARTICR_CTSMIC_BIT)
+#define VPL011_UARTICR_DCDMIC_BIT   2
+#define VPL011_UARTICR_DCDMIC       (1<<VPL011_UARTICR_DCDMIC_BIT)
+#define VPL011_UARTICR_DSRMIC_BIT   3
+#define VPL011_UARTICR_DSRMIC       (1<<VPL011_UARTICR_DSRMIC_BIT)
+#define VPL011_UARTICR_RXIC_BIT     4
+#define VPL011_UARTICR_RXIC         (1<<VPL011_UARTICR_RXIC_BIT)
+#define VPL011_UARTICR_TXIC_BIT     5
+#define VPL011_UARTICR_TXIC         (1<<VPL011_UARTICR_TXIC_BIT)
+#define VPL011_UARTICR_RTIC_BIT     6
+#define VPL011_UARTICR_RTIC         (1<<VPL011_UARTICR_RTIC_BIT)
+#define VPL011_UARTICR_FEIC_BIT     7
+#define VPL011_UARTICR_FEIC         (1<<VPL011_UARTICR_FEIC_BIT)
+#define VPL011_UARTICR_PEIC_BIT     8
+#define VPL011_UARTICR_PEIC         (1<<VPL011_UARTICR_PEIC_BIT)
+#define VPL011_UARTICR_BEIC_BIT     9
+#define VPL011_UARTICR_BEIC         (1<<VPL011_UARTICR_BEIC_BIT)
+#define VPL011_UARTICR_OEIC_BIT     10
+#define VPL011_UARTICR_OEIC         (1<<VPL011_UARTICR_OEIC_BIT)
+
+/*
+ * UART interrupt mask set/clear bits - RW
+ */
+#define VPL011_UARTIMSC_RIMIM_BIT   0
+#define VPL011_UARTIMSC_RIMIM       (1<<VPL011_UARTIMSC_RIMIM_BIT)
+#define VPL011_UARTIMSC_CTSMIM_BIT  1
+#define VPL011_UARTIMSC_CTSMIM      (1<<VPL011_UARTIMSC_CTSMIM_BIT)
+#define VPL011_UARTIMSC_DCDMIM_BIT   2
+#define VPL011_UARTIMSC_DCDMIM      (1<<VPL011_UARTIMSC_DCDMIM_BIT)
+#define VPL011_UARTIMSC_DSRMIM_BIT  3
+#define VPL011_UARTIMSC_DSRMIM      (1<<VPL011_UARTIMSC_DSRMIM_BIT)
+#define VPL011_UARTIMSC_RXIM_BIT    4
+#define VPL011_UARTIMSC_RXIM        (1<<VPL011_UARTIMSC_RXIM_BIT)
+#define VPL011_UARTIMSC_TXIM_BIT    5
+#define VPL011_UARTIMSC_TXIM        (1<<VPL011_UARTIMSC_TXIM_BIT)
+#define VPL011_UARTIMSC_RTIM_BIT    6
+#define VPL011_UARTIMSC_RTIM        (1<<VPL011_UARTIMSC_RTIM_BIT)
+#define VPL011_UARTIMSC_FEIM_BIT    7
+#define VPL011_UARTIMSC_FEIM        (1<<VPL011_UARTIMSC_FEIM_BIT)
+#define VPL011_UARTIMSC_PEIM_BIT    8
+#define VPL011_UARTIMSC_PEIM        (1<<VPL011_UARTIMSC_PEIM_BIT)
+#define VPL011_UARTIMSC_BEIM_BIT    9
+#define VPL011_UARTIMSC_BEIM        (1<<VPL011_UARTIMSC_BEIM_BIT)
+#define VPL011_UARTIMSC_OEIM_BIT    10
+#define VPL011_UARTIMSC_OEIM        (1<<VPL011_UARTIMSC_OEIM_BIT)
+
+
+/*
+ * helper macros
+ */
+#define VPL011_RING_DEPTH(intf,dir) (((intf)->dir ## _prod - (intf)->dir ## _cons))
+#define VPL011_RING_MAX_DEPTH(intf,dir) (sizeof((intf)->dir)-1)
+
+#define VPL011_IN_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, in) == 0)
+
+#define VPL011_OUT_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, out) == 0)
+
+#define VPL011_IN_RING_FULL(intf) (VPL011_RING_DEPTH(intf, in) == VPL011_RING_MAX_DEPTH(intf, in))
+
+#define VPL011_OUT_RING_FULL(intf) (VPL011_RING_DEPTH(intf, out) == VPL011_RING_MAX_DEPTH(intf,out))
+
+#define VPL011_LOCK(d,flags) spin_lock_irqsave(&(d)->arch.vpl011.lock, flags)
+#define VPL011_UNLOCK(d,flags) spin_unlock_irqrestore(&(d)->arch.vpl011.lock, flags)
+
+/*
+ * MMIO return values
+ */
+#define     VPL011_EMUL_OK      1
+#define     VPL011_EMUL_FAIL    0
+
+int domain_vpl011_init(struct domain *d);
+int vpl011_map_guest_page(struct domain *d);
+int vpl011_read_data(struct domain *d, unsigned char *data);
+int vpl011_write_data(struct domain *d, unsigned char data);
+
+#define MASK_VPL011CONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) 
+struct console_interface {
+    char in[1024];
+    char out[2048];
+    uint32_t in_cons, in_prod;
+    uint32_t out_cons, out_prod;
+};
+#endif
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index f2ecbc4..7e2feac 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -237,4 +237,10 @@ config FAST_SYMBOL_LOOKUP
 	  The only user of this is Live patching.
 
 	  If unsure, say Y.
+
+config VPL011_CONSOLE
+	bool "Emulated pl011 console support"
+	default y
+	---help---
+	  Allows a guest to use pl011 UART as a console
 endmenu
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 2d6fbb1..ff2403a 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -40,6 +40,7 @@ struct vtimer {
         uint64_t cval;
 };
 
+
 struct arch_domain
 {
 #ifdef CONFIG_ARM_64
@@ -131,6 +132,20 @@ struct arch_domain
     struct {
         uint8_t privileged_call_enabled : 1;
     } monitor;
+
+#ifdef CONFIG_VPL011_CONSOLE
+    struct vpl011 {
+        void *ring_buf;
+        struct page_info *ring_page;
+        uint32_t    flag;               /* flag register */
+        uint32_t    control;            /* control register */
+        uint32_t    intr_mask;          /* interrupt mask register*/
+        uint32_t    intr_clear;         /* interrupt clear register */
+        uint32_t    raw_intr_status;    /* raw interrupt status register */
+        uint32_t    masked_intr_status; /* masked interrupt register */
+        spinlock_t  lock;
+    } vpl011;
+#endif
 }  __cacheline_aligned;
 
 struct arch_vcpu
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index bd974fb..1d4548f 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -410,6 +410,10 @@ typedef uint64_t xen_callback_t;
 #define GUEST_ACPI_BASE 0x20000000ULL
 #define GUEST_ACPI_SIZE 0x02000000ULL
 
+/* PL011 mappings */
+#define GUEST_PL011_BASE    0x22000000ULL
+#define GUEST_PL011_SIZE    0x00001000ULL
+
 /*
  * 16MB == 4096 pages reserved for guest to use as a region to map its
  * grant table in.
@@ -420,6 +424,7 @@ typedef uint64_t xen_callback_t;
 #define GUEST_MAGIC_BASE  xen_mk_ullong(0x39000000)
 #define GUEST_MAGIC_SIZE  xen_mk_ullong(0x01000000)
 
+
 #define GUEST_RAM_BANKS   2
 
 #define GUEST_RAM0_BASE   xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
  2017-02-21 11:25 ` [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
@ 2017-02-21 11:25 ` Bhupinder Thakur
  2017-03-03 20:02   ` Konrad Rzeszutek Wilk
  2017-03-05 12:35   ` Julien Grall
  2017-02-21 11:26 ` [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel Bhupinder Thakur
                   ` (10 subsequent siblings)
  12 siblings, 2 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:25 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Three new HVM param handlers added for:
    - allocating a new VIRQ and return to the toolstack
    - allocating a new event channel for sending/receiving events from Xen and return
      to the toolstack
    - mapping the PFN allocted by the toolstack to be used as IN/OUT ring buffers

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 xen/arch/arm/hvm.c              | 39 +++++++++++++++++++++++++++++++++++++++
 xen/include/public/hvm/params.h | 10 +++++++++-
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c
index d999bde..f3b9eb1 100644
--- a/xen/arch/arm/hvm.c
+++ b/xen/arch/arm/hvm.c
@@ -23,6 +23,8 @@
 #include <xen/guest_access.h>
 #include <xen/sched.h>
 #include <xen/monitor.h>
+#include <xen/event.h>
+#include <xen/vmap.h>
 
 #include <xsm/xsm.h>
 
@@ -31,6 +33,7 @@
 #include <public/hvm/hvm_op.h>
 
 #include <asm/hypercall.h>
+#include "vpl011.h"
 
 long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
@@ -61,9 +64,45 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( op == HVMOP_set_param )
         {
             d->arch.hvm_domain.params[a.index] = a.value;
+
+#ifdef CONFIG_VPL011_CONSOLE
+            /*
+             * if it is a vpl011 console pfn then map it to its
+             * own address space
+             */
+            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN )
+            {
+                vpl011_map_guest_page(d);
+            }
+#else
+            /* 
+             * if VPL011 is not compiled in then disallow setting of any 
+             * related HVM params
+             */
+            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
+                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
+                 a.index == HVM_PARAM_VPL011_VIRQ )
+            {
+                rc = -1;
+                goto param_fail;
+            }
+#endif
         }
         else
         {
+#ifndef CONFIG_VPL011_CONSOLE
+            /* 
+             * if VPL011 is not compiled in then disallow setting of any 
+             * related HVM params
+             */
+            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
+                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
+                 a.index == HVM_PARAM_VPL011_VIRQ )
+            {
+                rc = -1;
+                goto param_fail;
+            }
+#endif
             a.value = d->arch.hvm_domain.params[a.index];
             rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
         }
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 3f54a49..13bf719 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -203,10 +203,17 @@
  */
 #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
 
-/* Deprecated */
+#if defined(__arm__) || defined(__aarch64__)
+#define HVM_PARAM_VPL011_CONSOLE_PFN    20
+#define HVM_PARAM_VPL011_CONSOLE_EVTCHN 21
+#define HVM_PARAM_VPL011_VIRQ           22
+#else
 #define HVM_PARAM_MEMORY_EVENT_CR0          20
 #define HVM_PARAM_MEMORY_EVENT_CR3          21
 #define HVM_PARAM_MEMORY_EVENT_CR4          22
+#endif
+
+/* Deprecated */
 #define HVM_PARAM_MEMORY_EVENT_INT3         23
 #define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP  25
 #define HVM_PARAM_MEMORY_EVENT_MSR          30
@@ -253,6 +260,7 @@
  */
 #define HVM_PARAM_X87_FIP_WIDTH 36
 
+
 #define HVM_NR_PARAMS 37
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
  2017-02-21 11:25 ` [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
  2017-02-21 11:25 ` [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 21:13   ` Konrad Rzeszutek Wilk
  2017-03-05 12:39   ` Julien Grall
  2017-02-21 11:26 ` [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen Bhupinder Thakur
                   ` (9 subsequent siblings)
  12 siblings, 2 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
is bound to a xen consumer then event generation is not allowed for that channel.
This check is to disallow a guest from raising an event via this channel. However,
it should allow Xen to send a event via this channel as it is required for sending
vpl011 event to the dom0.

This change introduces a new function raw_evtchn_send() which sends the event
without this check. The current evtchn_send() calls this function after doing the
xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
bypassing the check.

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 xen/common/event_channel.c | 49 ++++++++++++++++++++++++++++++++++------------
 xen/include/xen/event.h    |  6 ++++++
 2 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 638dc5e..4b039f3 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -27,6 +27,7 @@
 #include <xen/keyhandler.h>
 #include <xen/event_fifo.h>
 #include <asm/current.h>
+#include <xen/domain_page.h>
 
 #include <public/xen.h>
 #include <public/event_channel.h>
@@ -650,25 +651,21 @@ static long evtchn_close(struct domain *d1, int port1, bool_t guest)
     return rc;
 }
 
-int evtchn_send(struct domain *ld, unsigned int lport)
+int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data)
 {
     struct evtchn *lchn, *rchn;
     struct domain *rd;
-    int            rport, ret = 0;
+    int rport, ret=0;
 
-    if ( !port_is_valid(ld, lport) )
-        return -EINVAL;
-
-    lchn = evtchn_from_port(ld, lport);
-
-    spin_lock(&lchn->lock);
-
-    /* Guest cannot send via a Xen-attached event channel. */
-    if ( unlikely(consumer_is_xen(lchn)) )
+    if ( !data )
     {
-        ret = -EINVAL;
-        goto out;
+        if ( !port_is_valid(ld, lport) )
+            return -EINVAL;
+        lchn = evtchn_from_port(ld, lport);
+        spin_lock(&lchn->lock);
     }
+    else
+        lchn = (struct evtchn *)data; 
 
     ret = xsm_evtchn_send(XSM_HOOK, ld, lchn);
     if ( ret )
@@ -696,6 +693,32 @@ int evtchn_send(struct domain *ld, unsigned int lport)
     }
 
 out:
+    if ( !data )
+        spin_unlock(&lchn->lock);
+
+    return ret;
+}
+
+int evtchn_send(struct domain *ld, unsigned int lport)
+{
+    struct evtchn *lchn;
+    int ret;
+
+    if ( !port_is_valid(ld, lport) )
+        return -EINVAL;
+
+    lchn = evtchn_from_port(ld, lport);
+
+    spin_lock(&lchn->lock);
+
+    if ( unlikely(consumer_is_xen(lchn)) )
+    {
+        printk("evtchn_send failed to send via xen event channel\n");
+        return -EINVAL;
+    }
+
+    ret = raw_evtchn_send(ld, lport, lchn);
+
     spin_unlock(&lchn->lock);
 
     return ret;
diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
index 5008c80..9bd17db 100644
--- a/xen/include/xen/event.h
+++ b/xen/include/xen/event.h
@@ -45,6 +45,12 @@ void send_guest_pirq(struct domain *, const struct pirq *);
 /* Send a notification from a given domain's event-channel port. */
 int evtchn_send(struct domain *d, unsigned int lport);
 
+/* 
+ * This function is same as evntchn_send() except it does not do xen consumer check
+ * to allow the events to be sent from xen bound channels.
+ */
+int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data);
+
 /* Bind a local event-channel port to the specified VCPU. */
 long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
 
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (2 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 21:47   ` Konrad Rzeszutek Wilk
  2017-03-05 12:46   ` Julien Grall
  2017-02-21 11:26 ` [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1 Bhupinder Thakur
                   ` (8 subsequent siblings)
  12 siblings, 2 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Based on one of the domain creation flags, the vpl011 emulation will be enabled for
the domain.

This flag is currently set always but finally it needs to be controlled by the user
through some configuration option.

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 xen/arch/arm/domain.c   | 8 ++++++++
 xen/common/domctl.c     | 2 ++
 xen/include/xen/sched.h | 4 ++++
 3 files changed, 14 insertions(+)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 7e43691..6fee541 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -36,6 +36,9 @@
 #include <asm/platform.h>
 #include "vtimer.h"
 #include "vuart.h"
+#ifdef CONFIG_VPL011_CONSOLE
+#include "vpl011.h"
+#endif
 
 DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
 
@@ -626,6 +629,11 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
     if ( (rc = domain_vtimer_init(d, config)) != 0 )
         goto fail;
 
+#ifdef CONFIG_VPL011_CONSOLE
+    if ( domcr_flags & DOMCRF_vpl011_console )
+        if ( (rc = domain_vpl011_init(d)) != 0 )
+            goto fail;
+#endif
     update_domain_wallclock_time(d);
 
     /*
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 12cf4a9..fafc506 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -551,6 +551,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
         if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_xs_domain )
             domcr_flags |= DOMCRF_xs_domain;
 
+        domcr_flags |= DOMCRF_vpl011_console;
+
         d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref,
                           &op->u.createdomain.config);
         if ( IS_ERR(d) )
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 063efe6..9e03a60 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -555,6 +555,10 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
 #define _DOMCRF_xs_domain       6
 #define DOMCRF_xs_domain        (1U<<_DOMCRF_xs_domain)
 
+ /* DOMCRF_vpl011_console: create domain with pl011 emulation enabled */
+#define _DOMCRF_vpl011_console  7
+#define DOMCRF_vpl011_console   (1U<<_DOMCRF_vpl011_console)
+
 /*
  * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
  * This is the preferred function if the returned domain reference
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (3 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 20:49   ` Konrad Rzeszutek Wilk
  2017-03-05 12:51   ` Julien Grall
  2017-02-21 11:26 ` [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack Bhupinder Thakur
                   ` (7 subsequent siblings)
  12 siblings, 2 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Ensure that nr_spis intialized in in vgic_init is atleast 1 to allow allocation of
pl011 spi virq.

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 xen/arch/arm/vgic.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 364d5f0..614b3ec 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -121,6 +121,11 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
     /* Limit the number of virtual SPIs supported to (1020 - 32) = 988  */
     if ( nr_spis > (1020 - NR_LOCAL_IRQS) )
         return -EINVAL;
+#ifdef CONFIG_VPL011_CONSOLE
+    /* Atleast 1 spi should be available for assigning to vpl011 */
+    else if ( nr_spis < (1020 - NR_LOCAL_IRQS) )
+        nr_spis += 1;
+#endif
 
     d->arch.vgic.nr_spis = nr_spis;
 
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (4 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1 Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 20:15   ` Konrad Rzeszutek Wilk
                     ` (2 more replies)
  2017-02-21 11:26 ` [PATCH 07/11] xen/arm: vpl011: Add two new vpl011 parameters to xenstore Bhupinder Thakur
                   ` (6 subsequent siblings)
  12 siblings, 3 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Add a new pl011 uart node
    - Get the pl011 spi virq from Xen using a hvm call
    - Add a new device tree node in the guest DT for SBSA pl011 uart containing the IRQ
      (read above) and the MMIO address range to be used by the guest

The format for the node is specified in Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt.

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 tools/libxl/libxl_arm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index d842d88..34c7e39 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -130,9 +130,10 @@ static struct arch_info {
     const char *guest_type;
     const char *timer_compat;
     const char *cpu_compat;
+    const char *uart_compat;
 } arch_info[] = {
-    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15" },
-    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8" },
+    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15", "arm,sbsa-uart" },
+    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8", "arm,sbsa-uart" },
 };
 
 /*
@@ -590,6 +591,38 @@ static int make_hypervisor_node(libxl__gc *gc, void *fdt,
     return 0;
 }
 
+static int make_vpl011_uart_node(libxl__gc *gc, void *fdt,
+                           const struct arch_info *ainfo,
+                           struct xc_dom_image *dom, uint64_t irq)
+{
+    int res;
+    gic_interrupt intr;
+
+    res = fdt_begin_node(fdt, "sbsa-pl011");
+    if (res) return res;
+
+    res = fdt_property_compat(gc, fdt, 1, ainfo->uart_compat);
+    if (res) return res;
+
+    res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
+                            1,
+                            GUEST_PL011_BASE, GUEST_PL011_SIZE);
+    if (res) 
+        return res;
+
+    set_interrupt(intr, irq, 0xf, DT_IRQ_TYPE_LEVEL_HIGH);
+
+    res = fdt_property_interrupts(gc, fdt, &intr, 1);
+    if (res) return res;
+
+    fdt_property_u32(fdt, "current-speed", 115200);
+
+    res = fdt_end_node(fdt);
+    if (res) return res;
+
+    return 0;
+}
+
 static const struct arch_info *get_arch_info(libxl__gc *gc,
                                              const struct xc_dom_image *dom)
 {
@@ -790,6 +823,7 @@ static int libxl__prepare_dtb(libxl__gc *gc, libxl_domain_build_info *info,
     int rc, res;
     size_t fdt_size = 0;
     int pfdt_size = 0;
+    uint64_t vpl011_irq=0;
 
     const libxl_version_info *vers;
     const struct arch_info *ainfo;
@@ -889,6 +923,13 @@ next_resize:
         FDT( make_timer_node(gc, fdt, ainfo, xc_config->clock_frequency) );
         FDT( make_hypervisor_node(gc, fdt, vers) );
 
+        /* 
+         * get the vpl011 VIRQ and use it for creating a vpl011 node entry
+         */
+        if ( !xc_hvm_param_get(dom->xch, dom->guest_domid, HVM_PARAM_VPL011_VIRQ, 
+                                                               &vpl011_irq) )
+            FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom, vpl011_irq) );
+
         if (pfdt)
             FDT( copy_partial_fdt(gc, fdt, pfdt) );
 
@@ -933,9 +974,11 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
     val |= GUEST_EVTCHN_PPI;
     rc = xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CALLBACK_IRQ,
                           val);
+
     if (rc)
         return rc;
 
+
     rc = libxl__prepare_dtb(gc, info, state, dom);
     if (rc) goto out;
 
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 07/11] xen/arm: vpl011: Add two new vpl011 parameters to xenstore
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (5 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 20:58   ` Konrad Rzeszutek Wilk
  2017-02-21 11:26 ` [PATCH 08/11] xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen using a hvm call Bhupinder Thakur
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Add two new parameters to the xen store:
    - newly allocated PFN to be used as IN/OUT ring buffer by xenconsoled
    - a new event channel read from Xen using a hvm call to be used by xenconsoled
      for eventing

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 tools/libxl/libxl.c          |  6 ++++++
 tools/libxl/libxl_dom.c      | 18 +++++++++++++++++-
 tools/libxl/libxl_internal.h |  4 ++++
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index d400fa2..cc00235 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -3159,6 +3159,12 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
         flexarray_append(ro_front, GCSPRINTF("%"PRIu32, state->console_port));
         flexarray_append(ro_front, "ring-ref");
         flexarray_append(ro_front, GCSPRINTF("%lu", state->console_mfn));
+#if defined(__arm__) || defined(__aarch64__)
+        flexarray_append(ro_front, "vpl011-port");
+        flexarray_append(ro_front, GCSPRINTF("%"PRIu32, state->vpl011_console_port));
+        flexarray_append(ro_front, "vpl011-ring-ref");
+        flexarray_append(ro_front, GCSPRINTF("%lu", state->vpl011_console_mfn));
+#endif
     } else {
         flexarray_append(front, "state");
         flexarray_append(front, GCSPRINTF("%d", XenbusStateInitialising));
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index d519c8d..39eaff6 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -302,7 +302,7 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *xs_domid, *con_domid;
     int rc;
-    uint64_t size;
+    uint64_t size, val=-1;
 
     if (xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus) != 0) {
         LOG(ERROR, "Couldn't set max vcpu count");
@@ -432,6 +432,16 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
     state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid);
     state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid);
 
+#if defined(__arm__) || defined(__aarch64__)
+    /* get the vpl011 event channel from Xen */
+    rc = xc_hvm_param_get(ctx->xch, domid, HVM_PARAM_VPL011_CONSOLE_EVTCHN,
+            &val);
+    if ( rc )
+        state->vpl011_console_port = -1;
+    else
+        state->vpl011_console_port = (uint32_t)val;
+#endif
+
     if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm_set_conf_params(ctx->xch, domid, info);
 #if defined(__i386__) || defined(__x86_64__)
@@ -727,6 +737,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
 
     dom->flags = flags;
     dom->console_evtchn = state->console_port;
+#if defined(__arm__) || defined(__aarch64__)
+    dom->vpl011_console_evtchn = state->vpl011_console_port;
+#endif
     dom->console_domid = state->console_domid;
     dom->xenstore_evtchn = state->store_port;
     dom->xenstore_domid = state->store_domid;
@@ -771,6 +784,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
     if (xc_dom_feature_translated(dom)) {
         state->console_mfn = dom->console_pfn;
         state->store_mfn = dom->xenstore_pfn;
+#if defined(__arm__) || defined(__aarch64__)
+        state->vpl011_console_mfn = dom->vpl011_console_pfn;
+#endif
     } else {
         state->console_mfn = xc_dom_p2m(dom, dom->console_pfn);
         state->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 5f46578..10e262e 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1128,6 +1128,10 @@ typedef struct {
     uint32_t num_vmemranges;
 
     xc_domain_configuration_t config;
+#if defined(__arm__) || defined(__aarch64__)
+    unsigned long vpl011_console_mfn;
+    uint32_t    vpl011_console_port;
+#endif
 } libxl__domain_build_state;
 
 _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid,
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 08/11] xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen using a hvm call
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (6 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 07/11] xen/arm: vpl011: Add two new vpl011 parameters to xenstore Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 20:51   ` Konrad Rzeszutek Wilk
  2017-02-21 11:26 ` [PATCH 09/11] xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the ring buffer and event channel Bhupinder Thakur
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Allocates a new pfn, initializes it and passes on to Xen using a hvm call.

Another changes is in xc_hvm_param_deprecated_check () to allow new vpl011 HVM params,
which have been defined to some deprecated HVM params.

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 tools/libxc/include/xc_dom.h | 5 +++++
 tools/libxc/xc_dom_arm.c     | 7 ++++++-
 tools/libxc/xc_dom_boot.c    | 5 +++++
 tools/libxc/xc_domain.c      | 3 +++
 4 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index 608cbc2..c763cf1 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -218,6 +218,11 @@ struct xc_dom_image {
 
     /* Extra SMBIOS structures passed to HVMLOADER */
     struct xc_hvm_firmware_module smbios_module;
+
+#if defined(__arm__) || defined(__aarch64__)
+    xen_pfn_t vpl011_console_pfn;
+    unsigned int vpl011_console_evtchn;
+#endif
 };
 
 /* --- pluggable kernel loader ------------------------------------- */
diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index a7e839e..7060a22 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -26,10 +26,11 @@
 #include "xg_private.h"
 #include "xc_dom.h"
 
-#define NR_MAGIC_PAGES 3
+#define NR_MAGIC_PAGES 4
 #define CONSOLE_PFN_OFFSET 0
 #define XENSTORE_PFN_OFFSET 1
 #define MEMACCESS_PFN_OFFSET 2
+#define VPL011_CONSOLE_PFN_OFFSET 3
 
 #define LPAE_SHIFT 9
 
@@ -85,6 +86,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
 
     dom->console_pfn = base + CONSOLE_PFN_OFFSET;
     dom->xenstore_pfn = base + XENSTORE_PFN_OFFSET;
+    dom->vpl011_console_pfn = base + VPL011_CONSOLE_PFN_OFFSET;
 
     xc_clear_domain_page(dom->xch, dom->guest_domid, dom->console_pfn);
     xc_clear_domain_page(dom->xch, dom->guest_domid, dom->xenstore_pfn);
@@ -95,6 +97,9 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
             dom->xenstore_pfn);
     xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_MONITOR_RING_PFN,
             base + MEMACCESS_PFN_OFFSET);
+    xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_VPL011_CONSOLE_PFN,
+            base + VPL011_CONSOLE_PFN_OFFSET);
+
     /* allocated by toolstack */
     xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_EVTCHN,
             dom->console_evtchn);
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index 791041b..933e92f 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -227,6 +227,11 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     if ( (rc = clear_page(dom, dom->xenstore_pfn)) != 0 )
         return rc;
 
+#if defined (__arm__) || defined(__aarch64__)
+    if ( (rc = clear_page(dom, dom->vpl011_console_pfn)) != 0 )
+        return rc;
+#endif
+
     /* start info page */
     if ( dom->arch_hooks->start_info )
         dom->arch_hooks->start_info(dom);
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index fa1daeb..d881288 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1337,9 +1337,12 @@ static inline int xc_hvm_param_deprecated_check(uint32_t param)
 {
     switch ( param )
     {
+#if defined (__arm__) || defined(__aarch64__)
+#else
         case HVM_PARAM_MEMORY_EVENT_CR0:
         case HVM_PARAM_MEMORY_EVENT_CR3:
         case HVM_PARAM_MEMORY_EVENT_CR4:
+#endif
         case HVM_PARAM_MEMORY_EVENT_INT3:
         case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
         case HVM_PARAM_MEMORY_EVENT_MSR:
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 09/11] xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the ring buffer and event channel
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (7 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 08/11] xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen using a hvm call Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 21:46   ` Konrad Rzeszutek Wilk
  2017-02-21 11:26 ` [PATCH 10/11] xen/arm: vpl011: Modify handle_ring_read and buffer_append to read/append vpl011 data Bhupinder Thakur
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Modfication in domain_create_ring():
    - Bind to the vpl011 event channel obtained from the xen store as a new parameter
    - Map the PFN to its address space to be used as IN/OUT ring buffers. It obtains
      the PFN from the xen store as a new parameter

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 tools/console/daemon/io.c | 128 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 110 insertions(+), 18 deletions(-)

diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 7e6a886..b1aa615 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -101,13 +101,18 @@ struct domain {
 	struct domain *next;
 	char *conspath;
 	int ring_ref;
+	int vpl011_ring_ref;
 	xenevtchn_port_or_error_t local_port;
 	xenevtchn_port_or_error_t remote_port;
+	xenevtchn_port_or_error_t vpl011_local_port;
+	xenevtchn_port_or_error_t vpl011_remote_port;
 	xenevtchn_handle *xce_handle;
 	int xce_pollfd_idx;
 	struct xencons_interface *interface;
+	struct xencons_interface *vpl011_interface;
 	int event_count;
 	long long next_period;
+	bool vpl011_initialized;
 };
 
 static struct domain *dom_head;
@@ -529,9 +534,58 @@ static void domain_unmap_interface(struct domain *dom)
 	dom->ring_ref = -1;
 }
  
+static void domain_unmap_vpl011_interface(struct domain *dom)
+{
+	if ( dom->vpl011_interface == NULL )
+        return;
+
+	if ( xgt_handle && dom->vpl011_ring_ref == -1 )
+		xengnttab_unmap(xgt_handle, dom->vpl011_interface, 1);
+	else
+		munmap(dom->vpl011_interface, XC_PAGE_SIZE);
+	dom->vpl011_interface = NULL;
+	dom->vpl011_ring_ref = -1;
+}
+
+int bind_event_channel(struct domain *dom, int new_rport, int *lport, int *rport)
+{
+	int err = 0, rc;
+
+	/* Go no further if port has not changed and we are still bound. */
+	if ( new_rport == *rport ) {
+		xc_evtchn_status_t status = {
+		.dom = DOMID_SELF,
+		.port = *lport };
+	if ((xc_evtchn_status(xc, &status) == 0) &&
+		(status.status == EVTCHNSTAT_interdomain))
+		goto out;
+	}
+
+	/* initialize the ports */
+	*lport = -1;
+	*rport = -1;
+ 
+	/* bind to new remote port */
+	rc = xenevtchn_bind_interdomain(dom->xce_handle,
+	dom->domid, new_rport);
+
+	if ( rc == -1 ) {
+		err = errno;
+		xenevtchn_close(dom->xce_handle);
+		dom->xce_handle = NULL;
+		goto out;
+	}
+
+	/* store new local and remote event channel ports */
+	*lport = rc;
+	*rport = new_rport;
+out:
+	return err;
+}
+ 
 static int domain_create_ring(struct domain *dom)
 {
-	int err, remote_port, ring_ref, rc;
+	int err, remote_port, ring_ref, vpl011_remote_port, vpl011_ring_ref;
 	char *type, path[PATH_MAX];
 
 	err = xs_gather(xs, dom->conspath,
@@ -541,6 +595,20 @@ static int domain_create_ring(struct domain *dom)
 	if (err)
 		goto out;
 
+	/*
+	* if the vpl011 parameters are not available or are not initialized
+	* the vpl011 console is not available
+	*/
+	err = xs_gather(xs, dom->conspath,
+		"vpl011-ring-ref", "%u", &vpl011_ring_ref,
+		"vpl011-port", "%i", &vpl011_remote_port,
+		NULL);
+
+	if ( err || vpl011_ring_ref == -1 )
+		dom->vpl011_initialized = false;
+	else
+		dom->vpl011_initialized = true;
+
 	snprintf(path, sizeof(path), "%s/type", dom->conspath);
 	type = xs_read(xs, XBT_NULL, path, NULL);
 	if (type && strcmp(type, "xenconsoled") != 0) {
@@ -553,6 +621,12 @@ static int domain_create_ring(struct domain *dom)
 	if (ring_ref != dom->ring_ref && dom->ring_ref != -1)
 		domain_unmap_interface(dom);
 
+	/* If using vpl011 ring_ref and it has changed, remap */
+	if ( dom->vpl011_initialized && 
+		vpl011_ring_ref != dom->vpl011_ring_ref && 
+		dom->vpl011_ring_ref != -1 )
+		domain_unmap_vpl011_interface(dom);
+
 	if (!dom->interface && xgt_handle) {
 		/* Prefer using grant table */
 		dom->interface = xengnttab_map_grant_ref(xgt_handle,
@@ -560,6 +634,8 @@ static int domain_create_ring(struct domain *dom)
 			PROT_READ|PROT_WRITE);
 		dom->ring_ref = -1;
 	}
+
+	/* map PV console ring buffer */
 	if (!dom->interface) {
 		/* Fall back to xc_map_foreign_range */
 		dom->interface = xc_map_foreign_range(
@@ -573,18 +649,21 @@ static int domain_create_ring(struct domain *dom)
 		dom->ring_ref = ring_ref;
 	}
 
-	/* Go no further if port has not changed and we are still bound. */
-	if (remote_port == dom->remote_port) {
-		xc_evtchn_status_t status = {
-			.dom = DOMID_SELF,
-			.port = dom->local_port };
-		if ((xc_evtchn_status(xc, &status) == 0) &&
-		    (status.status == EVTCHNSTAT_interdomain))
+	/* map vpl011 console ring buffer */
+	if ( dom->vpl011_initialized && !dom->vpl011_interface ) {
+
+		/* Fall back to xc_map_foreign_range */
+		dom->vpl011_interface = xc_map_foreign_range(
+		xc, dom->domid, XC_PAGE_SIZE,
+		PROT_READ|PROT_WRITE,
+		(unsigned long)vpl011_ring_ref);
+		if ( dom->vpl011_interface == NULL ) {
+			err = EINVAL;
 			goto out;
+		}
+		dom->vpl011_ring_ref = vpl011_ring_ref;
 	}
 
-	dom->local_port = -1;
-	dom->remote_port = -1;
 	if (dom->xce_handle != NULL)
 		xenevtchn_close(dom->xce_handle);
 
@@ -596,17 +675,24 @@ static int domain_create_ring(struct domain *dom)
 		goto out;
 	}
  
-	rc = xenevtchn_bind_interdomain(dom->xce_handle,
-		dom->domid, remote_port);
-
-	if (rc == -1) {
-		err = errno;
+	/* bind PV console channel */
+	err = bind_event_channel(dom, remote_port, &dom->local_port, &dom->remote_port);
+	if (err)
+	{
 		xenevtchn_close(dom->xce_handle);
-		dom->xce_handle = NULL;
 		goto out;
 	}
-	dom->local_port = rc;
-	dom->remote_port = remote_port;
+
+	/* bind vpl011 console channel */
+	if ( dom->vpl011_initialized )
+	{
+		err = bind_event_channel(dom, vpl011_remote_port, &dom->vpl011_local_port, &dom->vpl011_remote_port);
+		if (err)
+		{
+			xenevtchn_close(dom->xce_handle);
+			goto out;
+		}
+	}
 
 	if (dom->master_fd == -1) {
 		if (!domain_create_tty(dom)) {
@@ -615,6 +701,9 @@ static int domain_create_ring(struct domain *dom)
 			dom->xce_handle = NULL;
 			dom->local_port = -1;
 			dom->remote_port = -1;
+			dom->vpl011_local_port = -1;
+			dom->vpl011_remote_port = -1;
+			dom->vpl011_initialized = false;
 			goto out;
 		}
 	}
@@ -684,8 +773,11 @@ static struct domain *create_domain(int domid)
 	dom->next_period = ((long long)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000) + RATE_LIMIT_PERIOD;
 
 	dom->ring_ref = -1;
+	dom->vpl011_ring_ref = -1;
 	dom->local_port = -1;
 	dom->remote_port = -1;
+	dom->vpl011_local_port = -1;
+	dom->vpl011_remote_port = -1;
 
 	if (!watch_domain(dom, true))
 		goto out;
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 10/11] xen/arm: vpl011: Modify handle_ring_read and buffer_append to read/append vpl011 data
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (8 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 09/11] xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the ring buffer and event channel Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 21:06   ` Konrad Rzeszutek Wilk
  2017-02-21 11:26 ` [PATCH 11/11] xen/arm: vpl011: Modify handle_tty_read in xenconsole to redirect user data to vpl011 IN ring buffer Bhupinder Thakur
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

MOdifications in the following functions:

    - handle_ring_read() - to allow reading data from both PV or vpl011 OUT ring buffers
      based on which port received the event
    - buffer_append() - append data received for either PV or vp011 OUT ring buffer

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 tools/console/daemon/io.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index b1aa615..4e531e7 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -163,12 +163,11 @@ static int write_with_timestamp(int fd, const char *data, size_t sz,
 	return 0;
 }
 
-static void buffer_append(struct domain *dom)
+static void buffer_append(struct domain *dom, struct xencons_interface *intf, int port)
 {
 	struct buffer *buffer = &dom->buffer;
 	XENCONS_RING_IDX cons, prod, size;
-	struct xencons_interface *intf = dom->interface;
-
+	
 	cons = intf->out_cons;
 	prod = intf->out_prod;
 	xen_mb();
@@ -192,7 +191,8 @@ static void buffer_append(struct domain *dom)
 
 	xen_mb();
 	intf->out_cons = cons;
-	xenevtchn_notify(dom->xce_handle, dom->local_port);
+
+	xenevtchn_notify(dom->xce_handle, port);
 
 	/* Get the data to the logfile as early as possible because if
 	 * no one is listening on the console pty then it will fill up
@@ -961,6 +961,7 @@ static void handle_tty_write(struct domain *dom)
 static void handle_ring_read(struct domain *dom)
 {
 	xenevtchn_port_or_error_t port;
+	struct xencons_interface *intf;
 
 	if (dom->is_dead)
 		return;
@@ -970,7 +971,15 @@ static void handle_ring_read(struct domain *dom)
 
 	dom->event_count++;
 
-	buffer_append(dom);
+	/*
+	* select the interface based on the port which the event received
+	*/
+	if ( port == dom->vpl011_local_port )
+		intf = dom->vpl011_interface;
+	else
+		intf = dom->interface;
+
+	buffer_append(dom, intf, port);
 
 	if (dom->event_count < RATE_LIMIT_ALLOWANCE)
 		(void)xenevtchn_unmask(dom->xce_handle, port);
@@ -1161,6 +1170,8 @@ void handle_io(void)
 				d->next_period = now + RATE_LIMIT_PERIOD;
 				if (d->event_count >= RATE_LIMIT_ALLOWANCE) {
 					(void)xenevtchn_unmask(d->xce_handle, d->local_port);
+					if ( d->vpl011_initialized )
+						(void)xenevtchn_unmask(d->xce_handle, d->vpl011_local_port);
 				}
 				d->event_count = 0;
 			}
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 11/11] xen/arm: vpl011: Modify handle_tty_read in xenconsole to redirect user data to vpl011 IN ring buffer
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (9 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 10/11] xen/arm: vpl011: Modify handle_ring_read and buffer_append to read/append vpl011 data Bhupinder Thakur
@ 2017-02-21 11:26 ` Bhupinder Thakur
  2017-03-03 21:17   ` Konrad Rzeszutek Wilk
  2017-03-03 20:23 ` [PATCH 00/11] pl011 emulation support in Xen Konrad Rzeszutek Wilk
  2017-03-05 11:46 ` Julien Grall
  12 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-02-21 11:26 UTC (permalink / raw)
  To: xen-devel; +Cc: Julien Grall, Stefano Stabellini

Modification in handle_tty_read to write the user data to the vpl011 IN ring buffer.

Finally this needs to be modified to allow user input for both PV and vpl011 consoles.

Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
 tools/console/daemon/io.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 4e531e7..a59b4c0 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -877,6 +877,9 @@ static int ring_free_bytes(struct domain *dom)
 	struct xencons_interface *intf = dom->interface;
 	XENCONS_RING_IDX cons, prod, space;
 
+	if ( dom->vpl011_initialized )
+		intf = dom->vpl011_interface;
+
 	cons = intf->in_cons;
 	prod = intf->in_prod;
 	xen_mb();
@@ -904,8 +907,9 @@ static void handle_tty_read(struct domain *dom)
 	ssize_t len = 0;
 	char msg[80];
 	int i;
-	struct xencons_interface *intf = dom->interface;
+	struct xencons_interface *intf=dom->interface;
 	XENCONS_RING_IDX prod;
+	xenevtchn_port_or_error_t port=dom->local_port;
 
 	if (dom->is_dead)
 		return;
@@ -918,6 +922,16 @@ static void handle_tty_read(struct domain *dom)
 		len = sizeof(msg);
 
 	len = read(dom->master_fd, msg, len);
+
+	/* select the interface based on whether vpl011 console is 
+	* enabled or not
+	*/
+	if ( dom->vpl011_initialized )
+	{
+		intf = dom->vpl011_interface;
+		port = dom->vpl011_local_port;
+	}
+
 	/*
 	 * Note: on Solaris, len == 0 means the slave closed, and this
 	 * is no problem, but Linux can't handle this usefully, so we
@@ -927,13 +941,14 @@ static void handle_tty_read(struct domain *dom)
 		domain_handle_broken_tty(dom, domain_is_valid(dom->domid));
 	} else if (domain_is_valid(dom->domid)) {
 		prod = intf->in_prod;
+
 		for (i = 0; i < len; i++) {
 			intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
 				msg[i];
 		}
 		xen_wmb();
 		intf->in_prod = prod;
-		xenevtchn_notify(dom->xce_handle, dom->local_port);
+		xenevtchn_notify(dom->xce_handle, port);
 	} else {
 		domain_close_tty(dom);
 		shutdown_domain(dom);
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-02-21 11:25 ` [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
@ 2017-02-26 21:37   ` Julien Grall
  2017-03-03 19:19     ` Julien Grall
  2017-03-21 13:27     ` Bhupinder Thakur
  2017-03-03 19:59   ` Konrad Rzeszutek Wilk
  2017-03-05 12:12   ` Julien Grall
  2 siblings, 2 replies; 82+ messages in thread
From: Julien Grall @ 2017-02-26 21:37 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel; +Cc: nd, Stefano Stabellini

Hi Bhupinder,

On 02/21/2017 11:25 AM, Bhupinder Thakur wrote:
> Add emulation code to emulate read/write access to pl011 registers
> and pl011 interrupts:
>
>     - It emulates DR read/write by reading and writing from/to the IN
>       and OUT ring buffers and raising an event to dom0 when there is
>       data in the OUT ring buffer and injecting an interrupt to the
>       guest when there is data in the IN ring buffer
>
>     - Other registers are related to interrupt management and
>       essentially control when interrupts are delivered to the guest

A link to the documentation would have been helpful.

> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/arch/arm/Makefile         |   1 +
>  xen/arch/arm/vpl011.c         | 366 ++++++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/vpl011.h         | 208 ++++++++++++++++++++++++
>  xen/common/Kconfig            |   6 +
>  xen/include/asm-arm/domain.h  |  15 ++
>  xen/include/public/arch-arm.h |   5 +
>  6 files changed, 601 insertions(+)
>  create mode 100644 xen/arch/arm/vpl011.c
>  create mode 100644 xen/arch/arm/vpl011.h
>
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index 7afb8a3..a94bdab 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -49,6 +49,7 @@ obj-y += vm_event.o
>  obj-y += vtimer.o
>  obj-y += vpsci.o
>  obj-y += vuart.o
> +obj-$(CONFIG_VPL011_CONSOLE) += vpl011.o
>
>  #obj-bin-y += ....o
>
> diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
> new file mode 100644
> index 0000000..88ba968
> --- /dev/null
> +++ b/xen/arch/arm/vpl011.c
> @@ -0,0 +1,366 @@
> +/*
> + * arch/arm/vpl011.c
> + *
> + * Virtual PL011 UART
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program; If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <xen/config.h>

xen/config.h is included by default. Please drop it.

> +#include <xen/init.h>
> +#include <xen/lib.h>
> +#include <xen/errno.h>
> +#include <xen/guest_access.h>
> +#include <xen/sched.h>
> +#include <xen/monitor.h>

Why do you need to include monitor.h?

> +#include <xen/event.h>
> +#include <xen/vmap.h>
> +
> +#include <xsm/xsm.h>

Ditto.

> +
> +#include <public/xen.h>
> +#include <public/hvm/params.h>
> +#include <public/hvm/hvm_op.h>
> +
> +#include <asm/hypercall.h>

Ditto.

> +#include "vpl011.h"
> +
> +static int vpl011_mmio_read(struct vcpu *v, mmio_info_t *info, register_t *r, void *priv)
> +{
> +    unsigned char ch;
> +
> +    switch (info->gpa - GUEST_PL011_BASE)

Coding style:

switch ( ... )

> +    {
> +        case VPL011_UARTCR_OFFSET:

Coding style: the case should be aligned to {. E.g

{
case ...

Also, I would prefer if you don't include _OFFSET in all the name.

Furthermore, can you please order the case by offset in the MMIO region. 
This would help to find if a register has been emulated or not.

Lastly, the user may have requested to read 8-bit, 16-bit, 32-bit. But 
you always return a 32-bit. Is a guest allowed to access using any size 
and in the middle of a register? Give a look on what is done for 
vgic-v{2,3}.c to check the size and read register. You may want to pull 
some code out to re-use here.

> +            *r = v->domain->arch.vpl011.control;

Similarly, I would prefer if the name of the field match the register name.

> +            break;
> +        case VPL011_UARTDR_OFFSET:
> +            vpl011_read_data(v->domain, &ch);

Should not you check the return value of vpl011_read_data? Also, what if 
there is no data?

> +            *r = ch;
> +            break;
> +        case VPL011_UARTFR_OFFSET:
> +            *r = v->domain->arch.vpl011.flag;

I am fairly surprised that none of this code is actually protected by 
lock. For instance the update of flag is not atomic. So is it safe?

> +            break;
> +        case VPL011_UARTIMSC_OFFSET:
> +            *r = v->domain->arch.vpl011.intr_mask;
> +            break;
> +        case VPL011_UARTICR_OFFSET:
> +            *r = 0;

Looking at the spec, this register is write-only. So why do you 
implement RAZ?

> +            break;
> +        case VPL011_UARTRIS_OFFSET:
> +            *r = v->domain->arch.vpl011.raw_intr_status;
> +            break;
> +        case VPL011_UARTMIS_OFFSET:
> +            *r = v->domain->arch.vpl011.raw_intr_status &
> +                                v->domain->arch.vpl011.intr_mask;
> +            break;
> +        case VPL011_UARTDMACR_OFFSET:
> +            *r = 0; /* uart DMA is not supported. Here it always returns 0 */

My understanding of the spec is DMA is not optional. So what would 
happen if the guest tries to enable it?

> +            break;
> +        case VPL011_UARTRSR_OFFSET:
> +            *r = 0; /* it always returns 0 as there are no physical errors */

This register contains contains the bit OE that tells whether the FIFO 
is full or not. The FIFO here is the PV ring, so maybe we should set 
this bit if the ring is full.

> +            break;
> +        default:
> +            printk ("vpl011_mmio_read: invalid switch case %d\n", (int)(info->gpa - GUEST_PL011_BASE));

Coding style: printk(...).

Also, printk is not ratelimited by default. Please use gprintk(...) 
which will be ratelimited and print the domain information. This is 
useful when you have multiple guest.

> +            break;
> +    }
> +
> +    return VPL011_EMUL_OK;

Please use plain value as the return is not pl011 specific. Also, I am a 
bit surprised that you return "ok" even when a register as not been 
emulated. IHMO, a data abort should be sent to the guest.

Furthermore, looking at the overall function, I think it should be 
better if you re-use the template used by the other emulation (see 
vgic-v2.c) for instance. They have labels that helps to know what's 
going on.

I will stop here in the review for today and will comment the rest tomorrow.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-02-26 21:37   ` Julien Grall
@ 2017-03-03 19:19     ` Julien Grall
  2017-03-21 13:27     ` Bhupinder Thakur
  1 sibling, 0 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-03 19:19 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel; +Cc: nd, Stefano Stabellini

Hi Bhupinder,

On 26/02/17 21:37, Julien Grall wrote:
> On 02/21/2017 11:25 AM, Bhupinder Thakur wrote:

[...]

>> +    {
>> +        case VPL011_UARTCR_OFFSET:
>
> Coding style: the case should be aligned to {. E.g
>
> {
> case ...
>
> Also, I would prefer if you don't include _OFFSET in all the name.
>
> Furthermore, can you please order the case by offset in the MMIO region.
> This would help to find if a register has been emulated or not.
>
> Lastly, the user may have requested to read 8-bit, 16-bit, 32-bit. But
> you always return a 32-bit. Is a guest allowed to access using any size
> and in the middle of a register? Give a look on what is done for
> vgic-v{2,3}.c to check the size and read register. You may want to pull
> some code out to re-use here.

Answering to myself here. Looking at the SBSA UART spec, register could 
be accessed with different size. SO please handle that in the next version.

[...]

>> +        case VPL011_UARTDMACR_OFFSET:
>> +            *r = 0; /* uart DMA is not supported. Here it always
>> returns 0 */
>
> My understanding of the spec is DMA is not optional. So what would
> happen if the guest tries to enable it?

Answering to myself here. As discussed on Wednesday, we will emulate a 
subset of PL011 registers to be compliant with SBSA UART as exposed in 
the guest DT (see patch #6). This would avoid for us to handle 
unnecessary register (such as DMA, line control register...).

But I would keep the file name vpl011.c so someone can extend to support 
a full PL011 if necessary. You would also need to explain in the commit 
message what we are emulating and give a link to the SBSA UART spec.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-02-21 11:25 ` [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
  2017-02-26 21:37   ` Julien Grall
@ 2017-03-03 19:59   ` Konrad Rzeszutek Wilk
  2017-03-05  1:04     ` Julien Grall
                       ` (3 more replies)
  2017-03-05 12:12   ` Julien Grall
  2 siblings, 4 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 19:59 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

.snip..
> +        case VPL011_UARTCR_OFFSET:
> +            *r = v->domain->arch.vpl011.control;
> +            break;

Pls add a new newline after each break.

> +        case VPL011_UARTDR_OFFSET:
> +            vpl011_read_data(v->domain, &ch);
> +            *r = ch;
> +            break;
> +        case VPL011_UARTFR_OFFSET:
> +            *r = v->domain->arch.vpl011.flag;
> +            break;
> +        case VPL011_UARTIMSC_OFFSET:
> +            *r = v->domain->arch.vpl011.intr_mask;
> +            break;
> +        case VPL011_UARTICR_OFFSET: 
> +            *r = 0;
> +            break;
> +        case VPL011_UARTRIS_OFFSET:
> +            *r = v->domain->arch.vpl011.raw_intr_status;
> +            break;
> +        case VPL011_UARTMIS_OFFSET:
> +            *r = v->domain->arch.vpl011.raw_intr_status &
> +                                v->domain->arch.vpl011.intr_mask;
> +            break;
> +        case VPL011_UARTDMACR_OFFSET:
> +            *r = 0; /* uart DMA is not supported. Here it always returns 0 */
> +            break;
> +        case VPL011_UARTRSR_OFFSET: 
> +            *r = 0; /* it always returns 0 as there are no physical errors */
> +            break;
> +        default:
> +            printk ("vpl011_mmio_read: invalid switch case %d\n", (int)(info->gpa - GUEST_PL011_BASE));

.. and you still return EMULOK?

Also is this printk really neccessary?

> +            break;
> +    }
> +
> +    return VPL011_EMUL_OK;
> +}
> +
> +static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void *priv)
> +{
> +    unsigned char ch = r;
> +
> +    switch (info->gpa - GUEST_PL011_BASE)
> +    {
> +        case VPL011_UARTCR_OFFSET:
> +            v->domain->arch.vpl011.control = r;
> +            break;
> +        case VPL011_UARTDR_OFFSET:
> +            vpl011_write_data(v->domain, ch);
> +            break;
> +        case VPL011_UARTIMSC_OFFSET:
> +            v->domain->arch.vpl011.intr_mask = r;
> +            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )
> +                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
> +            break;
> +        case VPL011_UARTICR_OFFSET: 
> +            /*
> +             * clear all bits which are set in the input
> +             */
> +            v->domain->arch.vpl011.raw_intr_status &= ~r;
> +            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )
> +            {
> +                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
> +            }
> +            break;
> +        case VPL011_UARTRSR_OFFSET: // nothing to clear
> +            break;
> +        case VPL011_UARTFR_OFFSET: // these are all RO registers
> +        case VPL011_UARTRIS_OFFSET:
> +        case VPL011_UARTMIS_OFFSET:
> +        case VPL011_UARTDMACR_OFFSET:
> +            break;
> +        default:
> +            printk ("vpl011_mmio_write: switch case not handled %d\n", (int)(info->gpa - GUEST_PL011_BASE));
> +            break;
> +    }
> +
> +    return VPL011_EMUL_OK;
> +}
> +
> +static const struct mmio_handler_ops vpl011_mmio_handler = {
> +    .read = vpl011_mmio_read,
> +    .write = vpl011_mmio_write,
> +};
> +
> +

why the extra newline.

> +
> +int vpl011_map_guest_page(struct domain *d)
> +{
> +    int rc=0;

No need for = 0;
> +
> +    /*
> +     * map the guest PFN to Xen address space
> +     */
> +    rc = prepare_ring_for_helper(d, 
> +                                 d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_PFN],
> +                                 &d->arch.vpl011.ring_page, 
> +                                 (void **)&d->arch.vpl011.ring_buf);
> +    if ( rc < 0 )
> +    {
> +        printk("Failed to map vpl011 guest PFN\n");
> +    }
> +
> +    return rc;

Could you just make this whole routine be:

 return prepare_ring_for_helper(..)

That printk is not needed I think? I would add it to the caller of this function.

> +}
> +
> +static int vpl011_data_avail(struct domain *d)
> +{
> +    int rc=0;
> +    unsigned long flags;
> +
> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;

Can you have an macro for this?
> +
> +    VPL011_LOCK(d, flags);

Please don't. Just use normal spin_lock invocation.

> +
> +    /*`
> +     * check IN ring buffer
> +     */

Please remove the comment. It does not add much context to the code.

> +    if ( !VPL011_IN_RING_EMPTY(intf) )
> +    {
> +        /*
> +         * clear the RX FIFO empty flag as the ring is not empty
> +         */

Please remove this comment.

> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFE);
> +
> +        /*
> +         * if the buffer is full then set the RX FIFO FULL flag

Also please remove this comment.

> +         */
> +        if ( VPL011_IN_RING_FULL(intf) )
> +            d->arch.vpl011.flag |= (VPL011_UARTFR_RXFF);
> +
> +        /*
> +         * set the RX interrupt status
> +         */

And this one too.

What I would recommend is that you write one nice comment at the start
of the 'if' saying:

"Have to set RX state regardless whether it is full or has some entries."

> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_RXRIS);
> +    }
> +
> +    /*
> +     * check OUT ring buffer

Please remove this comment.
> +     */
> +    if ( !VPL011_OUT_RING_FULL(intf) )
> +    {
> +        /*
> +         * if the buffer is not full then clear the TX FIFO full flag
> +         */


Please remove this comment.
> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFF);
> +
> +        /*
> +         * set the TX interrupt status
> +         */
> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_TXRIS);
> +
> +        if ( VPL011_OUT_RING_EMPTY(intf) )
> +        {
> +            /*
> +             * clear the uart busy flag and set the TX FIFO empty flag
> +             */
> +            d->arch.vpl011.flag &= ~(VPL011_UARTFR_BUSY);
> +            d->arch.vpl011.flag |= (VPL011_UARTFR_TXFE);
> +        }
> +    }

> +
> +    VPL011_UNLOCK(d, flags);
> +
> +    /*
> +     * send an interrupt if it is not masked

So does that mean we would send an interrupt even if the in/out rings
are full?

> +     */
> +    if ( (d->arch.vpl011.raw_intr_status & d->arch.vpl011.intr_mask) )
> +        vgic_vcpu_inject_spi(d, (int)d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
> +
> +    if ( !VPL011_OUT_RING_EMPTY(intf) )

This is asking for a race.

So it may have changed between the first time you read it and this
one.

Is that OK? Would it still be OK to send an interrupt even if say
the ring was emtpry at start of the function but became empty now?

Would it be better if you read all the values from
the ring at the start of the function in local variables
and made sure to use 'barrier()' so there are no compiler
"optimizations" done?

> +    {
> +        /*
> +         * raise an interrupt to dom0
> +         */

Please remove this.

> +        rc = raw_evtchn_send(d, 
> +                    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL); 

What if HVM_PARAM_VPL011_CONSOLE_EVTCHN is zero? Should you check
that first?

Or is it given (in which case please add an ASSERT) that the
HVM_PARAM_VPL011_CONSOLE_EVTCHN is _always_ set?

> +
> +        if ( rc < 0 )
> +            printk("Failed to send vpl011 interrupt to dom0\n");

gdprintk. But is this useful? How will this help in debugging the
problem?

> +    }
> +
> +    return rc;
> +}
> +
> +int vpl011_read_data(struct domain *d, unsigned char *data)
> +{
> +    int rc=0;

No point for this. Just do 'return 0'
> +    unsigned long flags;
> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
> +
> +    *data = 0;
> +
> +    VPL011_LOCK(d, flags);
> +
> +    /*
> +     * if there is data in the ring buffer then copy it to the output buffer
> +     */
> +    if ( !VPL011_IN_RING_EMPTY(intf) )
> +    {
> +        *data = intf->in[MASK_VPL011CONS_IDX(intf->in_cons++, intf->in)];
> +    }
> +
> +    /*
> +     * if the ring buffer is empty then set the RX FIFO empty flag
> +     */
> +    if ( VPL011_IN_RING_EMPTY(intf) )

So there is a nice race here. Why don't you just use an 'else' ?


> +    {
> +        d->arch.vpl011.flag |= (VPL011_UARTFR_RXFE);
> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_RXRIS);
> +    }
> +
> +    /*
> +     * clear the RX FIFO full flag
> +     */
> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFF);
> +
> +    VPL011_UNLOCK(d, flags);
> +
> +    return rc;
> +}
> +
> +int vpl011_write_data(struct domain *d, unsigned char data)
> +{
> +    int rc=0;

Pls remove the '=0'
> +    unsigned long flags;
> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
> +
> +    VPL011_LOCK(d, flags);
> +
> +    /*
> +     * if there is space in the ring buffer then write the data

Please moreve this comment.
> +     */
> +    if ( !VPL011_OUT_RING_FULL(intf) )
> +    {
> +        intf->out[MASK_VPL011CONS_IDX(intf->out_prod++, intf->out)] = data;
> +        smp_wmb();
> +    }
> 
> +    /*
> +     * if there is no space in the ring buffer then set the 
> +     * TX FIFO FULL flag

Again, why not just an 'else'?

> +     */
> +    if ( VPL011_OUT_RING_FULL(intf) )
> +    {
> +        d->arch.vpl011.flag |= (VPL011_UARTFR_TXFF);
> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_TXRIS);
> +    }
> +
> +    /*
> +     * set the uart busy status
> +     */
> +    d->arch.vpl011.flag |= (VPL011_UARTFR_BUSY);
> +
> +    /*
> +     * clear the TX FIFO empty flag
> +     */

Please remove these comments. They are distracting.

Also a single line comment should be:

/* <comment> */


> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFE);
> +
> +    VPL011_UNLOCK(d, flags);
> +
> +    /*
> +     * raise an event to dom0 only if it is the first character in the buffer

Why? Why only the first charcter?

> +     */
> +    if ( VPL011_RING_DEPTH(intf, out) == 1 )
> +    {
> +        rc = raw_evtchn_send(d, 
> +                d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL); 

And again, should we have an assert for HVM_PARAM_VPL011_CONSOLE_EVTCHN or a check
for it?

> +
> +        if ( rc < 0 )
> +            printk("Failed to send vpl011 interrupt to dom0\n");

gdprintk.

> +    }
> +
> +    return rc;
> +}
> +
> +static void vpl011_notification(struct vcpu *v, unsigned int port)
> +{
> +    vpl011_data_avail(v->domain);
> +}
> +
> +int domain_vpl011_init(struct domain *d)
> +{
> +    int rc=0;

You can remove the =0;
> +
> +    /*
> +     * register xen event channel
> +     */

Please remove this comment.

> +    rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id, 
> +                                                        vpl011_notification);
> +    if (rc < 0)

Spaces.
> +    {
> +        printk ("Failed to allocate vpl011 event channel\n");

gdprintk

And also not sure if this is needed. Won't the rc be propagated to the
caller who can print this?

> +        return rc;
> +    }
> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN] = rc;
> +    
> +    /*
> +     * allocate an SPI VIRQ for the guest
> +     */
> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ] = vgic_allocate_spi(d);

You are not checking vgic_allocate_spi for errors?

> +
> +    /*
> +     * register mmio handler 
> +     */

Please remove these comments. They are just saying what the code
is doing. Not adding anything extra.

> +    register_mmio_handler (d, &vpl011_mmio_handler, GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL);

Please kill that space before (.

And what if register_mmio_handler returns an error?

> +
> +    /* 
> +     * initialize the lock
> +     */

That is a comment that is really not needed.

> +    spin_lock_init(&d->arch.vpl011.lock);
> +
> +    /* 
> +     * clear the flag, control and interrupt status registers
> +     */

Why not just do memset on the structure?

> +    d->arch.vpl011.control = 0;
> +    d->arch.vpl011.flag = 0;
> +    d->arch.vpl011.intr_mask = 0;
> +    d->arch.vpl011.intr_clear = 0;
> +    d->arch.vpl011.raw_intr_status = 0;
> +    d->arch.vpl011.masked_intr_status = 0;
> +
> +    return 0;
> +}
> diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h
> new file mode 100644
> index 0000000..f2c577f
> --- /dev/null
> +++ b/xen/arch/arm/vpl011.h
> @@ -0,0 +1,208 @@
> +/*
> + * include/xen/vpl011.h
> + *
> + * Virtual PL011 UART 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program; If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef _VPL011_H_
> +
> +#define _VPL011_H_
> +
> +/*
> + * register offsets
> + */
> +#define VPL011_UARTDR_OFFSET    0x0 // data register (RW)

Wrong type of comments. Pls use /* */ variant

> +#define VPL011_UARTRSR_OFFSET   0x4 // receive status and error clear register (RW)
> +#define VPL011_UARTFR_OFFSET    0x18 // flag register (RO)
> +#define VPL011_UARTRIS_OFFSET   0x3c // raw interrupt status register (RO)
> +#define VPL011_UARTMIS_OFFSET   0x40 // masked interrupt status register (RO)
> +#define VPL011_UARTIMSC_OFFSET  0x38 // interrupt mask set/clear register (RW)
> +#define VPL011_UARTICR_OFFSET   0x44 // interrupt clear register (WO)
> +#define VPL011_UARTCR_OFFSET    0x30 // uart control register
> +#define VPL011_UARTDMACR_OFFSET 0x48 // uart dma control register
> +
> +/*
> + * control register bits - RW
> + */
> +#define VPL011_UARTCR_UARTEN_BIT 0
> +#define VPL011_UARTCR_UARTEN    (1<<VPL011_UARTCR_UARTEN_BIT)
> +#define VPL011_UARTCR_TXE_BIT    8
> +#define VPL011_UARTCR_TXE       (1<<VPL011_UARTCR_TXE_BIT)
> +#define VPL011_UARTCR_RXE_BIT    9
> +#define VPL011_UARTCR_RXE       (1<<VPL011_UARTCR_RXE_BIT)
> +
> +/*
> + * Flag register bits - RO
> + */
> +#define VPL011_UARTFR_CTS_BIT   0   // clear to send
> +#define VPL011_UARTFR_CTS       (1<<VPL011_UARTFR_CTS_BIT)
> +#define VPL011_UARTFR_DSR_BIT   1   // data set ready
> +#define VPL011_UARTFR_DSR       (1<<VPL011_UARTFR_DSR_BIT)
> +#define VPL011_UARTFR_DCD_BIT   2   // data carrier detect
> +#define VPL011_UARTFR_DCD       (1<<VPL011_UARTFR_DCD_BIT)
> +#define VPL011_UARTFR_BUSY_BIT  3   // uart busy
> +#define VPL011_UARTFR_BUSY      (1<<VPL011_UARTFR_BUSY_BIT)
> +#define VPL011_UARTFR_RXFE_BIT  4   // receive fifo empty
> +#define VPL011_UARTFR_RXFE      (1<<VPL011_UARTFR_RXFE_BIT)
> +#define VPL011_UARTFR_TXFF_BIT  5   // transmit fifo full
> +#define VPL011_UARTFR_TXFF      (1<<VPL011_UARTFR_TXFF_BIT)
> +#define VPL011_UARTFR_RXFF_BIT  6   // receive fifo full
> +#define VPL011_UARTFR_RXFF      (1<<VPL011_UARTFR_RXFF_BIT)
> +#define VPL011_UARTFR_TXFE_BIT  7   // transmit fifo empty
> +#define VPL011_UARTFR_TXFE      (1<<VPL011_UARTFR_TXFE_BIT)
> +#define VPL011_UARTFR_RI_BIT    8   // ring indicator
> +#define VPL011_UARTFR_RI        (1<<VPL011_UARTFR_RI_BIT)
> +
> +/*
> + * UART raw interrupt status bits - RO
> + */
> +#define VPL011_UARTRIS_RIRMIS_BIT  0
> +#define VPL011_UARTRIS_RIRMIS      (1<<VPL011_UARTRIS_RIRMIS_BIT)
> +#define VPL011_UARTRIS_CTSRMIS_BIT 1
> +#define VPL011_UARTRIS_CTSRMIS     (1<<VPL011_UARTRIS_CTSRMIS_BIT)
> +#define VPL011_UARTRIS_DCDRMIS_BIT 2
> +#define VPL011_UARTRIS_DCDRMIS     (1<<VPL011_UARTRIS_DCDRMIS_BIT)
> +#define VPL011_UARTRIS_DSRRMIS_BIT 3
> +#define VPL011_UARTRIS_DSRRMIS     (1<<VPL011_UARTRIS_DSRRMIS_BIT)
> +#define VPL011_UARTRIS_RXRIS_BIT   4
> +#define VPL011_UARTRIS_RXRIS       (1<<VPL011_UARTRIS_RXRIS_BIT)
> +#define VPL011_UARTRIS_TXRIS_BIT   5
> +#define VPL011_UARTRIS_TXRIS       (1<<VPL011_UARTRIS_TXRIS_BIT)
> +#define VPL011_UARTRIS_RTRIS_BIT   6
> +#define VPL011_UARTRIS_RTRIS       (1<<VPL011_UARTRIS_RTRIS_BIT)
> +#define VPL011_UARTRIS_FERIS_BIT   7
> +#define VPL011_UARTRIS_FERIS       (1<<VPL011_UARTRIS_FERIS_BIT)
> +#define VPL011_UARTRIS_PERIS_BIT   8
> +#define VPL011_UARTRIS_PERIS       (1<<VPL011_UARTRIS_PERIS_BIT)
> +#define VPL011_UARTRIS_BERIS_BIT   9
> +#define VPL011_UARTRIS_BERIS       (1<<VPL011_UARTRIS_BERIS_BIT)
> +#define VPL011_UARTRIS_OERIS_BIT   10
> +#define VPL011_UARTRIS_OERIS       (1<<VPL011_UARTRIS_OERIS_BIT)
> +
> +/*
> + * UART masked interrupt status bits - RO
> + */
> +#define VPL011_UARTMIS_RIMMIS_BIT  0
> +#define VPL011_UARTMIS_RIMMIS      (1<<VPL011_UARTMIS_RIMMIS_BIT)
> +#define VPL011_UARTMIS_CTSMMIS_BIT 1
> +#define VPL011_UARTMIS_CTSMMIS     (1<<VPL011_UARTMIS_CTSMMIS_BIT)
> +#define VPL011_UARTMIS_DCDMMIS_BIT 2
> +#define VPL011_UARTMIS_DCDMMIS     (1<<VPL011_UARTMIS_DCDMMIS_BIT)
> +#define VPL011_UARTMIS_DSRMMIS_BIT 3
> +#define VPL011_UARTMIS_DSRMMIS     (1<<VPL011_UARTMIS_DSRMMIS_BIT)
> +#define VPL011_UARTMIS_RXMIS_BIT   4
> +#define VPL011_UARTMIS_RXMIS       (1<<VPL011_UARTMIS_RXMIS_BIT)
> +#define VPL011_UARTMIS_TXMIS_BIT   5
> +#define VPL011_UARTMIS_TXMIS       (1<<VPL011_UARTMIS_TXMIS_BIT)
> +#define VPL011_UARTMIS_RTMIS_BIT   6
> +#define VPL011_UARTMIS_RTMIS       (1<<VPL011_UARTMIS_RTMIS_BIT)
> +#define VPL011_UARTMIS_FEMIS_BIT   7
> +#define VPL011_UARTMIS_FEMIS       (1<<VPL011_UARTMIS_FEMIS_BIT)
> +#define VPL011_UARTMIS_PEMIS_BIT   8
> +#define VPL011_UARTMIS_PEMIS       (1<<VPL011_UARTMIS_PEMIS_BIT)
> +#define VPL011_UARTMIS_BEMIS_BIT   9
> +#define VPL011_UARTMIS_BEMIS       (1<<VPL011_UARTMIS_BEMIS_BIT)
> +#define VPL011_UARTMIS_OEMIS_BIT   10
> +#define VPL011_UARTMIS_OEMIS       (1<<VPL011_UARTMIS_OEMIS_BIT)
> +
> +/*
> + * UART  interrupt clear bits - WO
> + */
> +#define VPL011_UARTICR_RIMIC_BIT    0
> +#define VPL011_UARTICR_RIMIC        (1<<VPL011_UARTICR_RIMIC_BIT)
> +#define VPL011_UARTICR_CTSMIC_BIT   1
> +#define VPL011_UARTICR_CTSMIC       (1<<VPL011_UARTICR_CTSMIC_BIT)
> +#define VPL011_UARTICR_DCDMIC_BIT   2
> +#define VPL011_UARTICR_DCDMIC       (1<<VPL011_UARTICR_DCDMIC_BIT)
> +#define VPL011_UARTICR_DSRMIC_BIT   3
> +#define VPL011_UARTICR_DSRMIC       (1<<VPL011_UARTICR_DSRMIC_BIT)
> +#define VPL011_UARTICR_RXIC_BIT     4
> +#define VPL011_UARTICR_RXIC         (1<<VPL011_UARTICR_RXIC_BIT)
> +#define VPL011_UARTICR_TXIC_BIT     5
> +#define VPL011_UARTICR_TXIC         (1<<VPL011_UARTICR_TXIC_BIT)
> +#define VPL011_UARTICR_RTIC_BIT     6
> +#define VPL011_UARTICR_RTIC         (1<<VPL011_UARTICR_RTIC_BIT)
> +#define VPL011_UARTICR_FEIC_BIT     7
> +#define VPL011_UARTICR_FEIC         (1<<VPL011_UARTICR_FEIC_BIT)
> +#define VPL011_UARTICR_PEIC_BIT     8
> +#define VPL011_UARTICR_PEIC         (1<<VPL011_UARTICR_PEIC_BIT)
> +#define VPL011_UARTICR_BEIC_BIT     9
> +#define VPL011_UARTICR_BEIC         (1<<VPL011_UARTICR_BEIC_BIT)
> +#define VPL011_UARTICR_OEIC_BIT     10
> +#define VPL011_UARTICR_OEIC         (1<<VPL011_UARTICR_OEIC_BIT)
> +
> +/*
> + * UART interrupt mask set/clear bits - RW
> + */
> +#define VPL011_UARTIMSC_RIMIM_BIT   0
> +#define VPL011_UARTIMSC_RIMIM       (1<<VPL011_UARTIMSC_RIMIM_BIT)
> +#define VPL011_UARTIMSC_CTSMIM_BIT  1
> +#define VPL011_UARTIMSC_CTSMIM      (1<<VPL011_UARTIMSC_CTSMIM_BIT)
> +#define VPL011_UARTIMSC_DCDMIM_BIT   2
> +#define VPL011_UARTIMSC_DCDMIM      (1<<VPL011_UARTIMSC_DCDMIM_BIT)
> +#define VPL011_UARTIMSC_DSRMIM_BIT  3
> +#define VPL011_UARTIMSC_DSRMIM      (1<<VPL011_UARTIMSC_DSRMIM_BIT)
> +#define VPL011_UARTIMSC_RXIM_BIT    4
> +#define VPL011_UARTIMSC_RXIM        (1<<VPL011_UARTIMSC_RXIM_BIT)
> +#define VPL011_UARTIMSC_TXIM_BIT    5
> +#define VPL011_UARTIMSC_TXIM        (1<<VPL011_UARTIMSC_TXIM_BIT)
> +#define VPL011_UARTIMSC_RTIM_BIT    6
> +#define VPL011_UARTIMSC_RTIM        (1<<VPL011_UARTIMSC_RTIM_BIT)
> +#define VPL011_UARTIMSC_FEIM_BIT    7
> +#define VPL011_UARTIMSC_FEIM        (1<<VPL011_UARTIMSC_FEIM_BIT)
> +#define VPL011_UARTIMSC_PEIM_BIT    8
> +#define VPL011_UARTIMSC_PEIM        (1<<VPL011_UARTIMSC_PEIM_BIT)
> +#define VPL011_UARTIMSC_BEIM_BIT    9
> +#define VPL011_UARTIMSC_BEIM        (1<<VPL011_UARTIMSC_BEIM_BIT)
> +#define VPL011_UARTIMSC_OEIM_BIT    10
> +#define VPL011_UARTIMSC_OEIM        (1<<VPL011_UARTIMSC_OEIM_BIT)
> +
> +
> +/*
> + * helper macros
> + */
> +#define VPL011_RING_DEPTH(intf,dir) (((intf)->dir ## _prod - (intf)->dir ## _cons))
> +#define VPL011_RING_MAX_DEPTH(intf,dir) (sizeof((intf)->dir)-1)
> +
> +#define VPL011_IN_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, in) == 0)
> +
> +#define VPL011_OUT_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, out) == 0)
> +
> +#define VPL011_IN_RING_FULL(intf) (VPL011_RING_DEPTH(intf, in) == VPL011_RING_MAX_DEPTH(intf, in))
> +
> +#define VPL011_OUT_RING_FULL(intf) (VPL011_RING_DEPTH(intf, out) == VPL011_RING_MAX_DEPTH(intf,out))
> +
> +#define VPL011_LOCK(d,flags) spin_lock_irqsave(&(d)->arch.vpl011.lock, flags)
> +#define VPL011_UNLOCK(d,flags) spin_unlock_irqrestore(&(d)->arch.vpl011.lock, flags)
> +
> +/*
> + * MMIO return values
> + */
> +#define     VPL011_EMUL_OK      1
> +#define     VPL011_EMUL_FAIL    0
> +
> +int domain_vpl011_init(struct domain *d);
> +int vpl011_map_guest_page(struct domain *d);
> +int vpl011_read_data(struct domain *d, unsigned char *data);
> +int vpl011_write_data(struct domain *d, unsigned char data);
> +
> +#define MASK_VPL011CONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) 
> +struct console_interface {
> +    char in[1024];
> +    char out[2048];
> +    uint32_t in_cons, in_prod;
> +    uint32_t out_cons, out_prod;
> +};
> +#endif
> diff --git a/xen/common/Kconfig b/xen/common/Kconfig
> index f2ecbc4..7e2feac 100644
> --- a/xen/common/Kconfig
> +++ b/xen/common/Kconfig
> @@ -237,4 +237,10 @@ config FAST_SYMBOL_LOOKUP
>  	  The only user of this is Live patching.
>  
>  	  If unsure, say Y.
> +
> +config VPL011_CONSOLE
> +	bool "Emulated pl011 console support"
> +	default y

I thought by default it would be 'n'?

Or perhaps defauly y if CONFIG_ARM or such?

> +	---help---
> +	  Allows a guest to use pl011 UART as a console
>  endmenu
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 2d6fbb1..ff2403a 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -40,6 +40,7 @@ struct vtimer {
>          uint64_t cval;
>  };
>  
> +

??
>  struct arch_domain
>  {
>  #ifdef CONFIG_ARM_64
> @@ -131,6 +132,20 @@ struct arch_domain
>      struct {
>          uint8_t privileged_call_enabled : 1;
>      } monitor;
> +
> +#ifdef CONFIG_VPL011_CONSOLE
> +    struct vpl011 {
> +        void *ring_buf;
> +        struct page_info *ring_page;
> +        uint32_t    flag;               /* flag register */
> +        uint32_t    control;            /* control register */
> +        uint32_t    intr_mask;          /* interrupt mask register*/
> +        uint32_t    intr_clear;         /* interrupt clear register */
> +        uint32_t    raw_intr_status;    /* raw interrupt status register */
> +        uint32_t    masked_intr_status; /* masked interrupt register */
> +        spinlock_t  lock;
> +    } vpl011;
> +#endif
>  }  __cacheline_aligned;
>  
>  struct arch_vcpu
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index bd974fb..1d4548f 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -410,6 +410,10 @@ typedef uint64_t xen_callback_t;
>  #define GUEST_ACPI_BASE 0x20000000ULL
>  #define GUEST_ACPI_SIZE 0x02000000ULL
>  
> +/* PL011 mappings */
> +#define GUEST_PL011_BASE    0x22000000ULL
> +#define GUEST_PL011_SIZE    0x00001000ULL
> +
>  /*
>   * 16MB == 4096 pages reserved for guest to use as a region to map its
>   * grant table in.
> @@ -420,6 +424,7 @@ typedef uint64_t xen_callback_t;
>  #define GUEST_MAGIC_BASE  xen_mk_ullong(0x39000000)
>  #define GUEST_MAGIC_SIZE  xen_mk_ullong(0x01000000)
>  
> +

???
>  #define GUEST_RAM_BANKS   2
>  
>  #define GUEST_RAM0_BASE   xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-02-21 11:25 ` [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup Bhupinder Thakur
@ 2017-03-03 20:02   ` Konrad Rzeszutek Wilk
  2017-03-24  6:58     ` Bhupinder Thakur
  2017-03-05 12:35   ` Julien Grall
  1 sibling, 1 reply; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 20:02 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:55:59PM +0530, Bhupinder Thakur wrote:
> Three new HVM param handlers added for:
>     - allocating a new VIRQ and return to the toolstack
>     - allocating a new event channel for sending/receiving events from Xen and return
>       to the toolstack
>     - mapping the PFN allocted by the toolstack to be used as IN/OUT ring buffers
> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/arch/arm/hvm.c              | 39 +++++++++++++++++++++++++++++++++++++++
>  xen/include/public/hvm/params.h | 10 +++++++++-
>  2 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c
> index d999bde..f3b9eb1 100644
> --- a/xen/arch/arm/hvm.c
> +++ b/xen/arch/arm/hvm.c
> @@ -23,6 +23,8 @@
>  #include <xen/guest_access.h>
>  #include <xen/sched.h>
>  #include <xen/monitor.h>
> +#include <xen/event.h>
> +#include <xen/vmap.h>
>  
>  #include <xsm/xsm.h>
>  
> @@ -31,6 +33,7 @@
>  #include <public/hvm/hvm_op.h>
>  
>  #include <asm/hypercall.h>
> +#include "vpl011.h"
>  
>  long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>  {
> @@ -61,9 +64,45 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>          if ( op == HVMOP_set_param )
>          {
>              d->arch.hvm_domain.params[a.index] = a.value;
> +
> +#ifdef CONFIG_VPL011_CONSOLE
> +            /*
> +             * if it is a vpl011 console pfn then map it to its

s/if/If/
> +             * own address space

And you can also add an . here.

> +             */
> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN )
> +            {
> +                vpl011_map_guest_page(d);
> +            }
> +#else
> +            /* 
> +             * if VPL011 is not compiled in then disallow setting of any 
> +             * related HVM params
> +             */
> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
> +                 a.index == HVM_PARAM_VPL011_VIRQ )
> +            {
> +                rc = -1;
> +                goto param_fail;
> +            }
> +#endif
>          }
>          else
>          {
> +#ifndef CONFIG_VPL011_CONSOLE
> +            /* 
> +             * if VPL011 is not compiled in then disallow setting of any 
> +             * related HVM params
> +             */
> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
> +                 a.index == HVM_PARAM_VPL011_VIRQ )
> +            {
> +                rc = -1;
> +                goto param_fail;

This and the above look like it could be nicely folded in a function?

Say:

static bool vpl011_built(unsigned int idx)
{
#ifdef CONFIG_VPL011_CONSOLE
	if ( idx == ..
		return true;
#else
	return false;
}

And here you can just do:
	if (vpl011_built())
	{
		rc = -1;
	.. and so on.
		
> +            }
> +#endif
>              a.value = d->arch.hvm_domain.params[a.index];
>              rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
>          }
> diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
> index 3f54a49..13bf719 100644
> --- a/xen/include/public/hvm/params.h
> +++ b/xen/include/public/hvm/params.h
> @@ -203,10 +203,17 @@
>   */
>  #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
>  
> -/* Deprecated */
> +#if defined(__arm__) || defined(__aarch64__)
> +#define HVM_PARAM_VPL011_CONSOLE_PFN    20
> +#define HVM_PARAM_VPL011_CONSOLE_EVTCHN 21
> +#define HVM_PARAM_VPL011_VIRQ           22
> +#else
>  #define HVM_PARAM_MEMORY_EVENT_CR0          20
>  #define HVM_PARAM_MEMORY_EVENT_CR3          21
>  #define HVM_PARAM_MEMORY_EVENT_CR4          22
> +#endif
> +
> +/* Deprecated */
>  #define HVM_PARAM_MEMORY_EVENT_INT3         23
>  #define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP  25
>  #define HVM_PARAM_MEMORY_EVENT_MSR          30
> @@ -253,6 +260,7 @@
>   */
>  #define HVM_PARAM_X87_FIP_WIDTH 36
>  
> +


???
>  #define HVM_NR_PARAMS 37
>  
>  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack
  2017-02-21 11:26 ` [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack Bhupinder Thakur
@ 2017-03-03 20:15   ` Konrad Rzeszutek Wilk
  2017-03-03 21:03   ` Konrad Rzeszutek Wilk
  2017-03-05 13:04   ` Julien Grall
  2 siblings, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 20:15 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

> @@ -933,9 +974,11 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>      val |= GUEST_EVTCHN_PPI;
>      rc = xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CALLBACK_IRQ,
>                            val);
> +
>      if (rc)
>          return rc;
>  
> +


Please do be careful. There is no need for these changes.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 00/11] pl011 emulation support in Xen
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (10 preceding siblings ...)
  2017-02-21 11:26 ` [PATCH 11/11] xen/arm: vpl011: Modify handle_tty_read in xenconsole to redirect user data to vpl011 IN ring buffer Bhupinder Thakur
@ 2017-03-03 20:23 ` Konrad Rzeszutek Wilk
  2017-03-03 21:15   ` Konrad Rzeszutek Wilk
  2017-03-14  7:44   ` Bhupinder Thakur
  2017-03-05 11:46 ` Julien Grall
  12 siblings, 2 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 20:23 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

> The following changes were done:

.. snip..

Thank you for this great writeup. I took a stab at it and stopped at patch
#2 b/c Julien said he would look in it deeper. But based on a brief
look I would say:
 - Please do remove most of the comments. They really do not add
   much context besides describing the code - and we all can
   read the code. The idea behind the comments is to describe some
   semantics of it, or something that is not obvious at first or
   such. Not the code.

 - Comments. One line comments are:
  /* Comment. */
   And please do use proper case and a period.

 - Be careful about compiler optimizations and jump tables.
   Specifically see https://xenbits.xen.org/xsa/advisory-155.html
   The way to make sure you don't introduce an security problem
   is to 1) use local variables 2) read once from the ring and
   make sure you use a compiler barrier.

 - There is also some unrelated changes. Like extra newlines. One
   way to avoid this is to send all your patches _just_ to yourself
   and review them - but review them in reverse order and from the
   bottom of the emails to the top. That way you can catch some of this.

 - Think in terms of how one would break this. For example the guest
   could change the HVM parameters (or maybe not?) - or find the
   console ring and muck with the ring indexes. You need to shield
   the code from such changes.

Thanks!

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-02-21 11:26 ` [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1 Bhupinder Thakur
@ 2017-03-03 20:49   ` Konrad Rzeszutek Wilk
  2017-03-05 12:51   ` Julien Grall
  1 sibling, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 20:49 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:02PM +0530, Bhupinder Thakur wrote:
> Ensure that nr_spis intialized in in vgic_init is atleast 1 to allow allocation of

s/atleast/at least/

> pl011 spi virq.
> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/arch/arm/vgic.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 364d5f0..614b3ec 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -121,6 +121,11 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
>      /* Limit the number of virtual SPIs supported to (1020 - 32) = 988  */
>      if ( nr_spis > (1020 - NR_LOCAL_IRQS) )
>          return -EINVAL;
> +#ifdef CONFIG_VPL011_CONSOLE
> +    /* Atleast 1 spi should be available for assigning to vpl011 */

Add period at the end please.

> +    else if ( nr_spis < (1020 - NR_LOCAL_IRQS) )
> +        nr_spis += 1;

So say the nr_spis is 988, you increase it to 989 but that means
the first check which checked against that is not being enforced.

Is that OK? Should it be reflected somewhere in a documentation?
Perhaps in the xen_arch_domainconfig structure to mention this?

> +#endif
>  
>      d->arch.vgic.nr_spis = nr_spis;
>  
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 08/11] xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen using a hvm call
  2017-02-21 11:26 ` [PATCH 08/11] xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen using a hvm call Bhupinder Thakur
@ 2017-03-03 20:51   ` Konrad Rzeszutek Wilk
  2017-03-05 13:07     ` Julien Grall
  0 siblings, 1 reply; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 20:51 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:05PM +0530, Bhupinder Thakur wrote:
> Allocates a new pfn, initializes it and passes on to Xen using a hvm call.

s/passes/pass/
> 
> Another changes is in xc_hvm_param_deprecated_check () to allow new vpl011 HVM params,
> which have been defined to some deprecated HVM params.

Do you need to do something special with migration?

Or does migration not work yet on ARM?

> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  tools/libxc/include/xc_dom.h | 5 +++++
>  tools/libxc/xc_dom_arm.c     | 7 ++++++-
>  tools/libxc/xc_dom_boot.c    | 5 +++++
>  tools/libxc/xc_domain.c      | 3 +++
>  4 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
> index 608cbc2..c763cf1 100644
> --- a/tools/libxc/include/xc_dom.h
> +++ b/tools/libxc/include/xc_dom.h
> @@ -218,6 +218,11 @@ struct xc_dom_image {
>  
>      /* Extra SMBIOS structures passed to HVMLOADER */
>      struct xc_hvm_firmware_module smbios_module;
> +
> +#if defined(__arm__) || defined(__aarch64__)
> +    xen_pfn_t vpl011_console_pfn;
> +    unsigned int vpl011_console_evtchn;
> +#endif
>  };
>  
>  /* --- pluggable kernel loader ------------------------------------- */
> diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
> index a7e839e..7060a22 100644
> --- a/tools/libxc/xc_dom_arm.c
> +++ b/tools/libxc/xc_dom_arm.c
> @@ -26,10 +26,11 @@
>  #include "xg_private.h"
>  #include "xc_dom.h"
>  
> -#define NR_MAGIC_PAGES 3
> +#define NR_MAGIC_PAGES 4
>  #define CONSOLE_PFN_OFFSET 0
>  #define XENSTORE_PFN_OFFSET 1
>  #define MEMACCESS_PFN_OFFSET 2
> +#define VPL011_CONSOLE_PFN_OFFSET 3
>  
>  #define LPAE_SHIFT 9
>  
> @@ -85,6 +86,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
>  
>      dom->console_pfn = base + CONSOLE_PFN_OFFSET;
>      dom->xenstore_pfn = base + XENSTORE_PFN_OFFSET;
> +    dom->vpl011_console_pfn = base + VPL011_CONSOLE_PFN_OFFSET;
>  
>      xc_clear_domain_page(dom->xch, dom->guest_domid, dom->console_pfn);
>      xc_clear_domain_page(dom->xch, dom->guest_domid, dom->xenstore_pfn);
> @@ -95,6 +97,9 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
>              dom->xenstore_pfn);
>      xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_MONITOR_RING_PFN,
>              base + MEMACCESS_PFN_OFFSET);
> +    xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_VPL011_CONSOLE_PFN,
> +            base + VPL011_CONSOLE_PFN_OFFSET);
> +
>      /* allocated by toolstack */
>      xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_EVTCHN,
>              dom->console_evtchn);
> diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
> index 791041b..933e92f 100644
> --- a/tools/libxc/xc_dom_boot.c
> +++ b/tools/libxc/xc_dom_boot.c
> @@ -227,6 +227,11 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
>      if ( (rc = clear_page(dom, dom->xenstore_pfn)) != 0 )
>          return rc;
>  
> +#if defined (__arm__) || defined(__aarch64__)
> +    if ( (rc = clear_page(dom, dom->vpl011_console_pfn)) != 0 )
> +        return rc;
> +#endif
> +
>      /* start info page */
>      if ( dom->arch_hooks->start_info )
>          dom->arch_hooks->start_info(dom);
> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> index fa1daeb..d881288 100644
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -1337,9 +1337,12 @@ static inline int xc_hvm_param_deprecated_check(uint32_t param)
>  {
>      switch ( param )
>      {
> +#if defined (__arm__) || defined(__aarch64__)

Can you add a comment here saying why it is empty please?

> +#else
>          case HVM_PARAM_MEMORY_EVENT_CR0:
>          case HVM_PARAM_MEMORY_EVENT_CR3:
>          case HVM_PARAM_MEMORY_EVENT_CR4:
> +#endif
>          case HVM_PARAM_MEMORY_EVENT_INT3:
>          case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
>          case HVM_PARAM_MEMORY_EVENT_MSR:
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 07/11] xen/arm: vpl011: Add two new vpl011 parameters to xenstore
  2017-02-21 11:26 ` [PATCH 07/11] xen/arm: vpl011: Add two new vpl011 parameters to xenstore Bhupinder Thakur
@ 2017-03-03 20:58   ` Konrad Rzeszutek Wilk
  2017-03-28  7:49     ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 20:58 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:04PM +0530, Bhupinder Thakur wrote:
> Add two new parameters to the xen store:
>     - newly allocated PFN to be used as IN/OUT ring buffer by xenconsoled
>     - a new event channel read from Xen using a hvm call to be used by xenconsoled
>       for eventing

This should have a correspoinding change in the include/public/io/console.h
describing this new 'vpl011-port' and 'vpl011-ring-ref' Xenbus entry.

Feel free to lift from kbdif.h.

Unless an earlier patch already does this? In which case you should
mention it:

"Patch titled XYZ introduces these XenBus entries in console.h"

> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  tools/libxl/libxl.c          |  6 ++++++
>  tools/libxl/libxl_dom.c      | 18 +++++++++++++++++-
>  tools/libxl/libxl_internal.h |  4 ++++
>  3 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index d400fa2..cc00235 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -3159,6 +3159,12 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
>          flexarray_append(ro_front, GCSPRINTF("%"PRIu32, state->console_port));
>          flexarray_append(ro_front, "ring-ref");
>          flexarray_append(ro_front, GCSPRINTF("%lu", state->console_mfn));
> +#if defined(__arm__) || defined(__aarch64__)
> +        flexarray_append(ro_front, "vpl011-port");
> +        flexarray_append(ro_front, GCSPRINTF("%"PRIu32, state->vpl011_console_port));
> +        flexarray_append(ro_front, "vpl011-ring-ref");
> +        flexarray_append(ro_front, GCSPRINTF("%lu", state->vpl011_console_mfn));
> +#endif

so... what if the VPL011 is not enabled in the guest? Should we still
create these XenBus entries?

>      } else {
>          flexarray_append(front, "state");
>          flexarray_append(front, GCSPRINTF("%d", XenbusStateInitialising));
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> index d519c8d..39eaff6 100644
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -302,7 +302,7 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
>      libxl_ctx *ctx = libxl__gc_owner(gc);
>      char *xs_domid, *con_domid;
>      int rc;
> -    uint64_t size;
> +    uint64_t size, val=-1;

So -1 for uint64_t is 0xffffffff... 

Is that what you meant? And why? Why not not uint32_t?


>  
>      if (xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus) != 0) {
>          LOG(ERROR, "Couldn't set max vcpu count");
> @@ -432,6 +432,16 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
>      state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid);
>      state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid);
>  
> +#if defined(__arm__) || defined(__aarch64__)
> +    /* get the vpl011 event channel from Xen */

Please remove this comment.

> +    rc = xc_hvm_param_get(ctx->xch, domid, HVM_PARAM_VPL011_CONSOLE_EVTCHN,
> +            &val);
> +    if ( rc )
> +        state->vpl011_console_port = -1;
> +    else
> +        state->vpl011_console_port = (uint32_t)val;
> +#endif
> +
>      if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
>          hvm_set_conf_params(ctx->xch, domid, info);
>  #if defined(__i386__) || defined(__x86_64__)
> @@ -727,6 +737,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
>  
>      dom->flags = flags;
>      dom->console_evtchn = state->console_port;
> +#if defined(__arm__) || defined(__aarch64__)
> +    dom->vpl011_console_evtchn = state->vpl011_console_port;
> +#endif
>      dom->console_domid = state->console_domid;
>      dom->xenstore_evtchn = state->store_port;
>      dom->xenstore_domid = state->store_domid;
> @@ -771,6 +784,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
>      if (xc_dom_feature_translated(dom)) {
>          state->console_mfn = dom->console_pfn;
>          state->store_mfn = dom->xenstore_pfn;
> +#if defined(__arm__) || defined(__aarch64__)
> +        state->vpl011_console_mfn = dom->vpl011_console_pfn;
> +#endif
>      } else {
>          state->console_mfn = xc_dom_p2m(dom, dom->console_pfn);
>          state->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 5f46578..10e262e 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -1128,6 +1128,10 @@ typedef struct {
>      uint32_t num_vmemranges;
>  
>      xc_domain_configuration_t config;
> +#if defined(__arm__) || defined(__aarch64__)
> +    unsigned long vpl011_console_mfn;
> +#endif

I am not a big fan of these #ifdef.

Could they go away and this could would be compiled on x86 too but
just never used? (The default value to use this owuld be disabled
for example)?

>  } libxl__domain_build_state;
>  
>  _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid,
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack
  2017-02-21 11:26 ` [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack Bhupinder Thakur
  2017-03-03 20:15   ` Konrad Rzeszutek Wilk
@ 2017-03-03 21:03   ` Konrad Rzeszutek Wilk
  2017-03-05 12:59     ` Julien Grall
  2017-03-05 13:04   ` Julien Grall
  2 siblings, 1 reply; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 21:03 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:03PM +0530, Bhupinder Thakur wrote:
> Add a new pl011 uart node
>     - Get the pl011 spi virq from Xen using a hvm call
>     - Add a new device tree node in the guest DT for SBSA pl011 uart containing the IRQ
>       (read above) and the MMIO address range to be used by the guest
> 
> The format for the node is specified in Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt.

Why don't you just copy-n-paste it in? It is only 10 linues.

> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  tools/libxl/libxl_arm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 45 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index d842d88..34c7e39 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -130,9 +130,10 @@ static struct arch_info {
>      const char *guest_type;
>      const char *timer_compat;
>      const char *cpu_compat;
> +    const char *uart_compat;
>  } arch_info[] = {
> -    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15" },
> -    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8" },
> +    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15", "arm,sbsa-uart" },
> +    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8", "arm,sbsa-uart" },
>  };
>  
>  /*
> @@ -590,6 +591,38 @@ static int make_hypervisor_node(libxl__gc *gc, void *fdt,
>      return 0;
>  }
>  
> +static int make_vpl011_uart_node(libxl__gc *gc, void *fdt,
> +                           const struct arch_info *ainfo,
> +                           struct xc_dom_image *dom, uint64_t irq)

Hm, mayube my editor is wrong but these arguments don't appear
to be right..

> +{
> +    int res;
> +    gic_interrupt intr;
> +
> +    res = fdt_begin_node(fdt, "sbsa-pl011");
> +    if (res) return res;
> +
> +    res = fdt_property_compat(gc, fdt, 1, ainfo->uart_compat);
> +    if (res) return res;
> +
> +    res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
> +                            1,
> +                            GUEST_PL011_BASE, GUEST_PL011_SIZE);
> +    if (res) 
> +        return res;

Shouldn't we free them?

> +
> +    set_interrupt(intr, irq, 0xf, DT_IRQ_TYPE_LEVEL_HIGH);

0xF looks like a good candidate for #define.
> +
> +    res = fdt_property_interrupts(gc, fdt, &intr, 1);
> +    if (res) return res;

Again, shouldn't we free it if we things go south?
> +
> +    fdt_property_u32(fdt, "current-speed", 115200);

So perhaps a #define?
> +
> +    res = fdt_end_node(fdt);
> +    if (res) return res;
> +
> +    return 0;
> +}
> +
>  static const struct arch_info *get_arch_info(libxl__gc *gc,
>                                               const struct xc_dom_image *dom)
>  {
> @@ -790,6 +823,7 @@ static int libxl__prepare_dtb(libxl__gc *gc, libxl_domain_build_info *info,
>      int rc, res;
>      size_t fdt_size = 0;
>      int pfdt_size = 0;
> +    uint64_t vpl011_irq=0;

Does it have to be =0 ?
>  
>      const libxl_version_info *vers;
>      const struct arch_info *ainfo;
> @@ -889,6 +923,13 @@ next_resize:
>          FDT( make_timer_node(gc, fdt, ainfo, xc_config->clock_frequency) );
>          FDT( make_hypervisor_node(gc, fdt, vers) );
>  
> +        /* 
> +         * get the vpl011 VIRQ and use it for creating a vpl011 node entry
> +         */
> +        if ( !xc_hvm_param_get(dom->xch, dom->guest_domid, HVM_PARAM_VPL011_VIRQ, 
> +                                                               &vpl011_irq) )

Why is the &vpl011 so far right? It should be right after the (

> +            FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom, vpl011_irq) );

Ah, so it will just fail with an goto out and leak.
> +
>          if (pfdt)
>              FDT( copy_partial_fdt(gc, fdt, pfdt) );
>  
> @@ -933,9 +974,11 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>      val |= GUEST_EVTCHN_PPI;
>      rc = xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CALLBACK_IRQ,
>                            val);
> +

Ahem?
>      if (rc)
>          return rc;
>  
> +

AHEM??
>      rc = libxl__prepare_dtb(gc, info, state, dom);
>      if (rc) goto out;
>  
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 10/11] xen/arm: vpl011: Modify handle_ring_read and buffer_append to read/append vpl011 data
  2017-02-21 11:26 ` [PATCH 10/11] xen/arm: vpl011: Modify handle_ring_read and buffer_append to read/append vpl011 data Bhupinder Thakur
@ 2017-03-03 21:06   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 21:06 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:07PM +0530, Bhupinder Thakur wrote:
> MOdifications in the following functions:

s/MO/Mo

> 
>     - handle_ring_read() - to allow reading data from both PV or vpl011 OUT ring buffers
>       based on which port received the event
>     - buffer_append() - append data received for either PV or vp011 OUT ring buffer
> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  tools/console/daemon/io.c | 21 ++++++++++++++++-----
>  1 file changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
> index b1aa615..4e531e7 100644
> --- a/tools/console/daemon/io.c
> +++ b/tools/console/daemon/io.c
> @@ -163,12 +163,11 @@ static int write_with_timestamp(int fd, const char *data, size_t sz,
>  	return 0;
>  }
>  
> -static void buffer_append(struct domain *dom)
> +static void buffer_append(struct domain *dom, struct xencons_interface *intf, int port)
>  {
>  	struct buffer *buffer = &dom->buffer;
>  	XENCONS_RING_IDX cons, prod, size;
> -	struct xencons_interface *intf = dom->interface;
> -
> +	

Any reason to add a tab here?
>  	cons = intf->out_cons;
>  	prod = intf->out_prod;
>  	xen_mb();
> @@ -192,7 +191,8 @@ static void buffer_append(struct domain *dom)
>  
>  	xen_mb();
>  	intf->out_cons = cons;
> -	xenevtchn_notify(dom->xce_handle, dom->local_port);
> +
> +	xenevtchn_notify(dom->xce_handle, port);
>  
>  	/* Get the data to the logfile as early as possible because if
>  	 * no one is listening on the console pty then it will fill up
> @@ -961,6 +961,7 @@ static void handle_tty_write(struct domain *dom)
>  static void handle_ring_read(struct domain *dom)
>  {
>  	xenevtchn_port_or_error_t port;
> +	struct xencons_interface *intf;
>  
>  	if (dom->is_dead)
>  		return;
> @@ -970,7 +971,15 @@ static void handle_ring_read(struct domain *dom)
>  
>  	dom->event_count++;
>  
> -	buffer_append(dom);
> +	/*
> +	* select the interface based on the port which the event received
> +	*/

Please remove this comment.

> +	if ( port == dom->vpl011_local_port )
> +		intf = dom->vpl011_interface;
> +	else
> +		intf = dom->interface;
> +
> +	buffer_append(dom, intf, port);
>  
>  	if (dom->event_count < RATE_LIMIT_ALLOWANCE)
>  		(void)xenevtchn_unmask(dom->xce_handle, port);
> @@ -1161,6 +1170,8 @@ void handle_io(void)
>  				d->next_period = now + RATE_LIMIT_PERIOD;
>  				if (d->event_count >= RATE_LIMIT_ALLOWANCE) {
>  					(void)xenevtchn_unmask(d->xce_handle, d->local_port);
> +					if ( d->vpl011_initialized )
> +						(void)xenevtchn_unmask(d->xce_handle, d->vpl011_local_port);
>  				}
>  				d->event_count = 0;
>  			}
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-02-21 11:26 ` [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel Bhupinder Thakur
@ 2017-03-03 21:13   ` Konrad Rzeszutek Wilk
  2017-03-06 10:16     ` Bhupinder Thakur
  2017-03-05 12:39   ` Julien Grall
  1 sibling, 1 reply; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 21:13 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:00PM +0530, Bhupinder Thakur wrote:
> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
> is bound to a xen consumer then event generation is not allowed for that channel.
> This check is to disallow a guest from raising an event via this channel. However,

Did any code archeology help in idenfitying why this was done this way?

You should explain why it was done - what was the use case , and why
your change will not change this semantic.
> it should allow Xen to send a event via this channel as it is required for sending
> vpl011 event to the dom0.
> 
> This change introduces a new function raw_evtchn_send() which sends the event
> without this check. The current evtchn_send() calls this function after doing the

.. and without taking a lock? Why?


> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
> bypassing the check.
> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/common/event_channel.c | 49 ++++++++++++++++++++++++++++++++++------------
>  xen/include/xen/event.h    |  6 ++++++
>  2 files changed, 42 insertions(+), 13 deletions(-)
> 
> diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
> index 638dc5e..4b039f3 100644
> --- a/xen/common/event_channel.c
> +++ b/xen/common/event_channel.c
> @@ -27,6 +27,7 @@
>  #include <xen/keyhandler.h>
>  #include <xen/event_fifo.h>
>  #include <asm/current.h>
> +#include <xen/domain_page.h>
>  
>  #include <public/xen.h>
>  #include <public/event_channel.h>
> @@ -650,25 +651,21 @@ static long evtchn_close(struct domain *d1, int port1, bool_t guest)
>      return rc;
>  }
>  
> -int evtchn_send(struct domain *ld, unsigned int lport)
> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data)
>  {
>      struct evtchn *lchn, *rchn;
>      struct domain *rd;
> -    int            rport, ret = 0;
> +    int rport, ret=0;

Please that code as is.

>  
> -    if ( !port_is_valid(ld, lport) )
> -        return -EINVAL;
> -
> -    lchn = evtchn_from_port(ld, lport);
> -
> -    spin_lock(&lchn->lock);
> -
> -    /* Guest cannot send via a Xen-attached event channel. */
> -    if ( unlikely(consumer_is_xen(lchn)) )
> +    if ( !data )
>      {
> -        ret = -EINVAL;
> -        goto out;
> +        if ( !port_is_valid(ld, lport) )
> +            return -EINVAL;
> +        lchn = evtchn_from_port(ld, lport);
> +        spin_lock(&lchn->lock);

That won't do. Please keep the format of the old code as much
as possible (hint: Those newlines).

>      }
> +    else
> +        lchn = (struct evtchn *)data; 
>  
>      ret = xsm_evtchn_send(XSM_HOOK, ld, lchn);
>      if ( ret )
> @@ -696,6 +693,32 @@ int evtchn_send(struct domain *ld, unsigned int lport)
>      }
>  
>  out:
> +    if ( !data )
> +        spin_unlock(&lchn->lock);
> +
> +    return ret;
> +}
> +
> +int evtchn_send(struct domain *ld, unsigned int lport)
> +{
> +    struct evtchn *lchn;
> +    int ret;
> +
> +    if ( !port_is_valid(ld, lport) )
> +        return -EINVAL;
> +
> +    lchn = evtchn_from_port(ld, lport);
> +
> +    spin_lock(&lchn->lock);
> +
> +    if ( unlikely(consumer_is_xen(lchn)) )
> +    {
> +        printk("evtchn_send failed to send via xen event channel\n");

No. Please do not.
> +        return -EINVAL;
> +    }
> +
> +    ret = raw_evtchn_send(ld, lport, lchn);
> +
>      spin_unlock(&lchn->lock);
>  
>      return ret;
> diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
> index 5008c80..9bd17db 100644
> --- a/xen/include/xen/event.h
> +++ b/xen/include/xen/event.h
> @@ -45,6 +45,12 @@ void send_guest_pirq(struct domain *, const struct pirq *);
>  /* Send a notification from a given domain's event-channel port. */
>  int evtchn_send(struct domain *d, unsigned int lport);
>  
> +/* 
> + * This function is same as evntchn_send() except it does not do xen consumer check
> + * to allow the events to be sent from xen bound channels.

And it also looks to ignore the locking? Could you explain why?

> + */
> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data);
> +
>  /* Bind a local event-channel port to the specified VCPU. */
>  long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
>  
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 00/11] pl011 emulation support in Xen
  2017-03-03 20:23 ` [PATCH 00/11] pl011 emulation support in Xen Konrad Rzeszutek Wilk
@ 2017-03-03 21:15   ` Konrad Rzeszutek Wilk
  2017-03-14  7:44   ` Bhupinder Thakur
  1 sibling, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 21:15 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Fri, Mar 03, 2017 at 03:23:31PM -0500, Konrad Rzeszutek Wilk wrote:
> > The following changes were done:
> 
> .. snip..
> 
> Thank you for this great writeup. I took a stab at it and stopped at patch
> #2 b/c Julien said he would look in it deeper. But based on a brief
> look I would say:

Run this on each patch:

$more bin/add_c 
#!/bin/bash

git diff HEAD^.. > /tmp/a

echo "---"
cat /tmp/a | scripts/get_maintainer.pl --no-l  | while read file; do echo "Cc: $file";done
rm -f /tmp/a

So that you have the right maintainers on the CC line 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 11/11] xen/arm: vpl011: Modify handle_tty_read in xenconsole to redirect user data to vpl011 IN ring buffer
  2017-02-21 11:26 ` [PATCH 11/11] xen/arm: vpl011: Modify handle_tty_read in xenconsole to redirect user data to vpl011 IN ring buffer Bhupinder Thakur
@ 2017-03-03 21:17   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 21:17 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:08PM +0530, Bhupinder Thakur wrote:
> Modification in handle_tty_read to write the user data to the vpl011 IN ring buffer.
> 
> Finally this needs to be modified to allow user input for both PV and vpl011 consoles.
> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  tools/console/daemon/io.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
> index 4e531e7..a59b4c0 100644
> --- a/tools/console/daemon/io.c
> +++ b/tools/console/daemon/io.c
> @@ -877,6 +877,9 @@ static int ring_free_bytes(struct domain *dom)
>  	struct xencons_interface *intf = dom->interface;
>  	XENCONS_RING_IDX cons, prod, space;
>  
> +	if ( dom->vpl011_initialized )
> +		intf = dom->vpl011_interface;
> +
>  	cons = intf->in_cons;
>  	prod = intf->in_prod;
>  	xen_mb();
> @@ -904,8 +907,9 @@ static void handle_tty_read(struct domain *dom)
>  	ssize_t len = 0;
>  	char msg[80];
>  	int i;
> -	struct xencons_interface *intf = dom->interface;
> +	struct xencons_interface *intf=dom->interface;

Please don't.

>  	XENCONS_RING_IDX prod;
> +	xenevtchn_port_or_error_t port=dom->local_port;

Please add spaces.

>  
>  	if (dom->is_dead)
>  		return;
> @@ -918,6 +922,16 @@ static void handle_tty_read(struct domain *dom)
>  		len = sizeof(msg);
>  
>  	len = read(dom->master_fd, msg, len);
> +
> +	/* select the interface based on whether vpl011 console is 
> +	* enabled or not

Please remove this comment. It is quite obvious from the code what
it does.

> +	*/
> +	if ( dom->vpl011_initialized )
> +	{
> +		intf = dom->vpl011_interface;
> +		port = dom->vpl011_local_port;
> +	}
> +
>  	/*
>  	 * Note: on Solaris, len == 0 means the slave closed, and this
>  	 * is no problem, but Linux can't handle this usefully, so we
> @@ -927,13 +941,14 @@ static void handle_tty_read(struct domain *dom)
>  		domain_handle_broken_tty(dom, domain_is_valid(dom->domid));
>  	} else if (domain_is_valid(dom->domid)) {
>  		prod = intf->in_prod;
> +

<cough> Please remove this.


>  		for (i = 0; i < len; i++) {
>  			intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
>  				msg[i];
>  		}
>  		xen_wmb();
>  		intf->in_prod = prod;
> -		xenevtchn_notify(dom->xce_handle, dom->local_port);
> +		xenevtchn_notify(dom->xce_handle, port);
>  	} else {
>  		domain_close_tty(dom);
>  		shutdown_domain(dom);
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 09/11] xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the ring buffer and event channel
  2017-02-21 11:26 ` [PATCH 09/11] xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the ring buffer and event channel Bhupinder Thakur
@ 2017-03-03 21:46   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 21:46 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:06PM +0530, Bhupinder Thakur wrote:
> Modfication in domain_create_ring():
>     - Bind to the vpl011 event channel obtained from the xen store as a new parameter
>     - Map the PFN to its address space to be used as IN/OUT ring buffers. It obtains
>       the PFN from the xen store as a new parameter
> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  tools/console/daemon/io.c | 128 +++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 110 insertions(+), 18 deletions(-)
> 
> diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
> index 7e6a886..b1aa615 100644
> --- a/tools/console/daemon/io.c
> +++ b/tools/console/daemon/io.c
> @@ -101,13 +101,18 @@ struct domain {
>  	struct domain *next;
>  	char *conspath;
>  	int ring_ref;
> +	int vpl011_ring_ref;
>  	xenevtchn_port_or_error_t local_port;
>  	xenevtchn_port_or_error_t remote_port;
> +	xenevtchn_port_or_error_t vpl011_local_port;
> +	xenevtchn_port_or_error_t vpl011_remote_port;
>  	xenevtchn_handle *xce_handle;
>  	int xce_pollfd_idx;
>  	struct xencons_interface *interface;
> +	struct xencons_interface *vpl011_interface;
>  	int event_count;
>  	long long next_period;
> +	bool vpl011_initialized;
>  };
>  
>  static struct domain *dom_head;
> @@ -529,9 +534,58 @@ static void domain_unmap_interface(struct domain *dom)
>  	dom->ring_ref = -1;
>  }
>   
> +static void domain_unmap_vpl011_interface(struct domain *dom)
> +{
> +	if ( dom->vpl011_interface == NULL )
> +        return;
> +
> +	if ( xgt_handle && dom->vpl011_ring_ref == -1 )
> +		xengnttab_unmap(xgt_handle, dom->vpl011_interface, 1);

This code uses its own styleguide, which means:
 - Use tabs instead of spaces. And only one here (and in the above return)
 - No spaces between ( ).


> +	else
> +		munmap(dom->vpl011_interface, XC_PAGE_SIZE);
> +	dom->vpl011_interface = NULL;
> +	dom->vpl011_ring_ref = -1;
> +}


Hm on second thought, this looks like domain_unmap_interface. Can you just
replicate it to be like it?

Or better yet. Could you change the domain_unmap_interface to
accept two parameters: a void pointer to the interface and
 a pointer to the ring_ref?

That way you could do:
 domain_unmap_interface(&dom->interface, &dom->ring_ref);
 domain_unmap_interface(&dom->vpl011_interface, &dom->vpl011_ring_ref);

And you would reuse the function?


> +
> +int bind_event_channel(struct domain *dom, int new_rport, int *lport, int *rport)
> +{
> +	int err = 0, rc;
> +
> +	/* Go no further if port has not changed and we are still bound. */
> +	if ( new_rport == *rport ) {

Again, no spaces here.

> +		xc_evtchn_status_t status = {
> +		.dom = DOMID_SELF,
> +		.port = *lport };

> +	if ((xc_evtchn_status(xc, &status) == 0) &&

Shouldn't this have an tab in front it? It is part of the 'if (new_rport == *rport)' conditional
after all.

> +		(status.status == EVTCHNSTAT_interdomain))
> +		goto out;
> +	}
> +
> +	/* initialize the ports */

Please remove this comment
> +	*lport = -1;
> +	*rport = -1;
> + 
> +	/* bind to new remote port */

And this one..
> +	rc = xenevtchn_bind_interdomain(dom->xce_handle,
> +	dom->domid, new_rport);

Huh? that should have been moved to be under (.

> +
> +	if ( rc == -1 ) {

Wrong style guide. No spaces.

> +		err = errno;
> +		xenevtchn_close(dom->xce_handle);
> +		dom->xce_handle = NULL;
> +		goto out;
> +	}
> +
> +	/* store new local and remote event channel ports */

Please remove this comment.

> +	*lport = rc;
> +	*rport = new_rport;
> +out:
> +	return err;
> +}
> + 
>  static int domain_create_ring(struct domain *dom)
>  {
> -	int err, remote_port, ring_ref, rc;
> +	int err, remote_port, ring_ref, vpl011_remote_port, vpl011_ring_ref;
>  	char *type, path[PATH_MAX];
>  
>  	err = xs_gather(xs, dom->conspath,
> @@ -541,6 +595,20 @@ static int domain_create_ring(struct domain *dom)
>  	if (err)
>  		goto out;
>  
> +	/*
> +	* if the vpl011 parameters are not available or are not initialized
> +	* the vpl011 console is not available

I would just change this to:

/* vpl011 is optional. */

> +	*/
> +	err = xs_gather(xs, dom->conspath,
> +		"vpl011-ring-ref", "%u", &vpl011_ring_ref,
> +		"vpl011-port", "%i", &vpl011_remote_port,

How come you don't use %u for both?

> +		NULL);
> +
> +	if ( err || vpl011_ring_ref == -1 )
> +		dom->vpl011_initialized = false;
> +	else
> +		dom->vpl011_initialized = true;
> +
>  	snprintf(path, sizeof(path), "%s/type", dom->conspath);
>  	type = xs_read(xs, XBT_NULL, path, NULL);
>  	if (type && strcmp(type, "xenconsoled") != 0) {
> @@ -553,6 +621,12 @@ static int domain_create_ring(struct domain *dom)
>  	if (ring_ref != dom->ring_ref && dom->ring_ref != -1)
>  		domain_unmap_interface(dom);
>  
> +	/* If using vpl011 ring_ref and it has changed, remap */
> +	if ( dom->vpl011_initialized && 
> +		vpl011_ring_ref != dom->vpl011_ring_ref && 
> +		dom->vpl011_ring_ref != -1 )

Something is off here. Or maybe it is my editor. But I would think that the condtionals
 should be on the same line. Also, no spaces here.

> +		domain_unmap_vpl011_interface(dom);
> +
>  	if (!dom->interface && xgt_handle) {
>  		/* Prefer using grant table */
>  		dom->interface = xengnttab_map_grant_ref(xgt_handle,
> @@ -560,6 +634,8 @@ static int domain_create_ring(struct domain *dom)
>  			PROT_READ|PROT_WRITE);
>  		dom->ring_ref = -1;
>  	}
> +
> +	/* map PV console ring buffer */

?? Please remove that.
>  	if (!dom->interface) {
>  		/* Fall back to xc_map_foreign_range */
>  		dom->interface = xc_map_foreign_range(
> @@ -573,18 +649,21 @@ static int domain_create_ring(struct domain *dom)
>  		dom->ring_ref = ring_ref;
>  	}
>  
> -	/* Go no further if port has not changed and we are still bound. */
> -	if (remote_port == dom->remote_port) {
> -		xc_evtchn_status_t status = {
> -			.dom = DOMID_SELF,
> -			.port = dom->local_port };
> -		if ((xc_evtchn_status(xc, &status) == 0) &&
> -		    (status.status == EVTCHNSTAT_interdomain))
> +	/* map vpl011 console ring buffer */

s/map/Map/ and also add period at the end please.

> +	if ( dom->vpl011_initialized && !dom->vpl011_interface ) {
> +
> +		/* Fall back to xc_map_foreign_range */
> +		dom->vpl011_interface = xc_map_foreign_range(
> +		xc, dom->domid, XC_PAGE_SIZE,
> +		PROT_READ|PROT_WRITE,
> +		(unsigned long)vpl011_ring_ref);

What happend here? Is my editor mixed up? I would think that those
would a bit shifted over?

> +		if ( dom->vpl011_interface == NULL ) {

No spaces ..
> +			err = EINVAL;
>  			goto out;
> +		}
> +		dom->vpl011_ring_ref = vpl011_ring_ref;
>  	}
>  
> -	dom->local_port = -1;
> -	dom->remote_port = -1;
>  	if (dom->xce_handle != NULL)
>  		xenevtchn_close(dom->xce_handle);
>  
> @@ -596,17 +675,24 @@ static int domain_create_ring(struct domain *dom)
>  		goto out;
>  	}
>   
> -	rc = xenevtchn_bind_interdomain(dom->xce_handle,
> -		dom->domid, remote_port);
> -
> -	if (rc == -1) {
> -		err = errno;
> +	/* bind PV console channel */
> +	err = bind_event_channel(dom, remote_port, &dom->local_port, &dom->remote_port);
> +	if (err)
> +	{

{ is on the same line as if (err) 

>  		xenevtchn_close(dom->xce_handle);
> -		dom->xce_handle = NULL;

Why? We are still closing it..

>  		goto out;
>  	}
> -	dom->local_port = rc;
> -	dom->remote_port = remote_port;
> +
> +	/* bind vpl011 console channel */

Uppercase please and period.

> +	if ( dom->vpl011_initialized )
> +	{

{ is on the same line as if in this code.

> +		err = bind_event_channel(dom, vpl011_remote_port, &dom->vpl011_local_port, &dom->vpl011_remote_port);
> +		if (err)
> +		{

Ditto.
> +			xenevtchn_close(dom->xce_handle);

No xce_handle = NULL?

> +			goto out;
> +		}
> +	}
>  
>  	if (dom->master_fd == -1) {
>  		if (!domain_create_tty(dom)) {
> @@ -615,6 +701,9 @@ static int domain_create_ring(struct domain *dom)
>  			dom->xce_handle = NULL;
>  			dom->local_port = -1;
>  			dom->remote_port = -1;
> +			dom->vpl011_local_port = -1;
> +			dom->vpl011_remote_port = -1;
> +			dom->vpl011_initialized = false;
>  			goto out;
>  		}
>  	}
> @@ -684,8 +773,11 @@ static struct domain *create_domain(int domid)
>  	dom->next_period = ((long long)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000) + RATE_LIMIT_PERIOD;
>  
>  	dom->ring_ref = -1;
> +	dom->vpl011_ring_ref = -1;
>  	dom->local_port = -1;
>  	dom->remote_port = -1;
> +	dom->vpl011_local_port = -1;
> +	dom->vpl011_remote_port = -1;
>  
>  	if (!watch_domain(dom, true))
>  		goto out;
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen
  2017-02-21 11:26 ` [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen Bhupinder Thakur
@ 2017-03-03 21:47   ` Konrad Rzeszutek Wilk
  2017-03-05 12:46   ` Julien Grall
  1 sibling, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-03 21:47 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

On Tue, Feb 21, 2017 at 04:56:01PM +0530, Bhupinder Thakur wrote:
> Based on one of the domain creation flags, the vpl011 emulation will be enabled for
> the domain.
> 
> This flag is currently set always but finally it needs to be controlled by the user
> through some configuration option.

"some"? Could you be more specific please.

Perhaps mention the title of the patch that adds this configuration
knob.

> 
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/arch/arm/domain.c   | 8 ++++++++
>  xen/common/domctl.c     | 2 ++
>  xen/include/xen/sched.h | 4 ++++
>  3 files changed, 14 insertions(+)
> 
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 7e43691..6fee541 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -36,6 +36,9 @@
>  #include <asm/platform.h>
>  #include "vtimer.h"
>  #include "vuart.h"
> +#ifdef CONFIG_VPL011_CONSOLE
> +#include "vpl011.h"
> +#endif
>  
>  DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
>  
> @@ -626,6 +629,11 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>      if ( (rc = domain_vtimer_init(d, config)) != 0 )
>          goto fail;
>  
> +#ifdef CONFIG_VPL011_CONSOLE
> +    if ( domcr_flags & DOMCRF_vpl011_console )
> +        if ( (rc = domain_vpl011_init(d)) != 0 )
> +            goto fail;
> +#endif
>      update_domain_wallclock_time(d);
>  
>      /*
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index 12cf4a9..fafc506 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -551,6 +551,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>          if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_xs_domain )
>              domcr_flags |= DOMCRF_xs_domain;
>  
> +        domcr_flags |= DOMCRF_vpl011_console;
> +
>          d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref,
>                            &op->u.createdomain.config);
>          if ( IS_ERR(d) )
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index 063efe6..9e03a60 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -555,6 +555,10 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
>  #define _DOMCRF_xs_domain       6
>  #define DOMCRF_xs_domain        (1U<<_DOMCRF_xs_domain)
>  
> + /* DOMCRF_vpl011_console: create domain with pl011 emulation enabled */

Perhaps:

/* Enable pl011 emulation. Preferred on ARM but not so much on x86. */ ?
> +#define _DOMCRF_vpl011_console  7
> +#define DOMCRF_vpl011_console   (1U<<_DOMCRF_vpl011_console)
> +
>  /*
>   * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
>   * This is the preferred function if the returned domain reference
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-03 19:59   ` Konrad Rzeszutek Wilk
@ 2017-03-05  1:04     ` Julien Grall
  2017-03-06 14:22       ` Konrad Rzeszutek Wilk
  2017-03-05  1:15     ` Julien Grall
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-05  1:04 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk, Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

Hi Konrad,

On 03/03/2017 07:59 PM, Konrad Rzeszutek Wilk wrote:
>> +}
>> +
>> +static int vpl011_data_avail(struct domain *d)
>> +{
>> +    int rc=0;
>> +    unsigned long flags;
>> +
>> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
>
> Can you have an macro for this?
>> +
>> +    VPL011_LOCK(d, flags);
>
> Please don't. Just use normal spin_lock invocation.

This is really a matter of taste. We've been using macro on the vgic 
emulation for the lock and I find it clearer and less error-prone. At 
least you are sure that all critical paths protected by the local will 
have IRQ disable.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-03 19:59   ` Konrad Rzeszutek Wilk
  2017-03-05  1:04     ` Julien Grall
@ 2017-03-05  1:15     ` Julien Grall
  2017-03-05 11:59     ` Julien Grall
  2017-03-22  5:50     ` Bhupinder Thakur
  3 siblings, 0 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-05  1:15 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk, Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

Hi,

On 03/03/2017 07:59 PM, Konrad Rzeszutek Wilk wrote:
>> diff --git a/xen/common/Kconfig b/xen/common/Kconfig
>> index f2ecbc4..7e2feac 100644
>> --- a/xen/common/Kconfig
>> +++ b/xen/common/Kconfig
>> @@ -237,4 +237,10 @@ config FAST_SYMBOL_LOOKUP
>>  	  The only user of this is Live patching.
>>
>>  	  If unsure, say Y.
>> +
>> +config VPL011_CONSOLE
>> +	bool "Emulated pl011 console support"
>> +	default y
>
> I thought by default it would be 'n'?
>
> Or perhaps defauly y if CONFIG_ARM or such?

I forgot to answer to this. The new config should go in arch/arm/Kconfig 
because the emulation is living there.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 00/11] pl011 emulation support in Xen
  2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
                   ` (11 preceding siblings ...)
  2017-03-03 20:23 ` [PATCH 00/11] pl011 emulation support in Xen Konrad Rzeszutek Wilk
@ 2017-03-05 11:46 ` Julien Grall
  2017-03-14  7:47   ` Bhupinder Thakur
  12 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-05 11:46 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel; +Cc: nd, Stefano Stabellini

Hi Bhupinder,

On 02/21/2017 11:25 AM, Bhupinder Thakur wrote:
> There are still some items which are pending:
>
> 1. Adding dynamic enable/disable of pl011 emulation for a guest
> 2. Add a new console type "pl011" in xenconsoled to allow the user to connect to
> either PV/serial/pl011 console.
> 3. Add checks to ensure that the new hvm params read/written by the guest

A couple of recommendations regarding the series:
	- All maintainers of the code you touch in a patch should be CCed. You 
can use scripts/get_maintainters.pl for that.
	- Providing a git branch with your code will allow people to test your 
code without handling potential rebasing.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-03 19:59   ` Konrad Rzeszutek Wilk
  2017-03-05  1:04     ` Julien Grall
  2017-03-05  1:15     ` Julien Grall
@ 2017-03-05 11:59     ` Julien Grall
  2017-03-22  5:50     ` Bhupinder Thakur
  3 siblings, 0 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-05 11:59 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk, Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

Hi Konrad,

On 03/03/2017 07:59 PM, Konrad Rzeszutek Wilk wrote:
>> +    rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id,
>> +                                                        vpl011_notification);
>> +    if (rc < 0)
>
> Spaces.
>> +    {
>> +        printk ("Failed to allocate vpl011 event channel\n");
>
> gdprintk

gdprintk will print the wrong domain as we are allocating a new domain. 
In general g*printk should be limited to the code we are sure the domain 
in parameter is the current one.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-02-21 11:25 ` [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
  2017-02-26 21:37   ` Julien Grall
  2017-03-03 19:59   ` Konrad Rzeszutek Wilk
@ 2017-03-05 12:12   ` Julien Grall
  2017-03-23  9:14     ` Bhupinder Thakur
  2 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-05 12:12 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel; +Cc: nd, Stefano Stabellini

Hi Bhupinder,

On 21/02/17 11:25, Bhupinder Thakur wrote:
> diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
> new file mode 100644
> index 0000000..88ba968
> --- /dev/null
> +++ b/xen/arch/arm/vpl011.c

[...]

> +static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void *priv)

See my comment on the vpl011_mmio_read about the structure of the function.

> +{
> +    unsigned char ch = r;
> +
> +    switch (info->gpa - GUEST_PL011_BASE)
> +    {
> +        case VPL011_UARTCR_OFFSET:

This register is not required in the SBSA UART.

> +            v->domain->arch.vpl011.control = r;
> +            break;
> +        case VPL011_UARTDR_OFFSET:
> +            vpl011_write_data(v->domain, ch);

The implicit casting of register_t to ch is a bit confusing. Also I 
would prefer to use uint8_t as it reflects the size of the field.

Lastly, what if vpl011_write_data is returning an error?

> +            break;
> +        case VPL011_UARTIMSC_OFFSET:
> +            v->domain->arch.vpl011.intr_mask = r;

You need to sanitize the value written and make sure reserved field and 
Write As Ones register and handle correctly (see the spec).

> +            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )

This line and the line below are over 80 columns. Also the code in 
general would benefits if you define a local variable to point to 
v->domain->arch.vpl011.

> +                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);

I don't think we need an HVM_PARAM for the pl011 SPI. We cannot hardcode 
this in the guest layout (see include/public/arch-arm.h).

> +            break;
> +        case VPL011_UARTICR_OFFSET:
> +            /*
> +             * clear all bits which are set in the input
> +             */
> +            v->domain->arch.vpl011.raw_intr_status &= ~r;
> +            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )
> +            {

{ } are not necessary.

> +                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
> +            }

The if is exactly the same as the on in IMSC. This is the call of an 
helper to check the interrupt state and inject one if necessary.

> +            break;
> +        case VPL011_UARTRSR_OFFSET: // nothing to clear

The coding style for single line comment in Xen is /* ... */

Also, I think we may want to handle Overrun error as the ring may be full.

> +            break;
> +        case VPL011_UARTFR_OFFSET: // these are all RO registers
> +        case VPL011_UARTRIS_OFFSET:
> +        case VPL011_UARTMIS_OFFSET:
> +        case VPL011_UARTDMACR_OFFSET:

Please have a look at the vGICv2/vGICv3 emulation see how we implemented 
write ignore register.

> +            break;
> +        default:
> +            printk ("vpl011_mmio_write: switch case not handled %d\n", (int)(info->gpa - GUEST_PL011_BASE));

See my comment about the prinkt in the read emulation.

> +            break;
> +    }
> +
> +    return VPL011_EMUL_OK;
> +}
> +
> +static const struct mmio_handler_ops vpl011_mmio_handler = {
> +    .read = vpl011_mmio_read,
> +    .write = vpl011_mmio_write,
> +};
> +
> +
> +

Only newline is sufficient. This was mention by Konrad and I will try to 
avoid repeating his comments.

> +int vpl011_map_guest_page(struct domain *d)
> +{
> +    int rc=0;
> +
> +    /*
> +     * map the guest PFN to Xen address space
> +     */
> +    rc = prepare_ring_for_helper(d,
> +                                 d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_PFN],
> +                                 &d->arch.vpl011.ring_page,
> +                                 (void **)&d->arch.vpl011.ring_buf);

Why do you need the cast?

Also I cannot find any code in this series which destroy the ring. 
Please have a helper called vpl011_unmap_guest_page to do this job and 
call when the domain is destroyed.

> +    if ( rc < 0 )
> +    {
> +        printk("Failed to map vpl011 guest PFN\n");
> +    }
> +
> +    return rc;
> +}
> +
> +static int vpl011_data_avail(struct domain *d)
> +{
> +    int rc=0;
> +    unsigned long flags;
> +
> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
> +
> +    VPL011_LOCK(d, flags);
> +
> +    /*`
> +     * check IN ring buffer
> +     */
> +    if ( !VPL011_IN_RING_EMPTY(intf) )
> +    {
> +        /*
> +         * clear the RX FIFO empty flag as the ring is not empty
> +         */
> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFE);
> +
> +        /*
> +         * if the buffer is full then set the RX FIFO FULL flag
> +         */
> +        if ( VPL011_IN_RING_FULL(intf) )
> +            d->arch.vpl011.flag |= (VPL011_UARTFR_RXFF);
> +
> +        /*
> +         * set the RX interrupt status
> +         */
> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_RXRIS);
> +    }
> +
> +    /*
> +     * check OUT ring buffer
> +     */
> +    if ( !VPL011_OUT_RING_FULL(intf) )
> +    {
> +        /*
> +         * if the buffer is not full then clear the TX FIFO full flag
> +         */
> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFF);
> +
> +        /*
> +         * set the TX interrupt status
> +         */
> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_TXRIS);
> +
> +        if ( VPL011_OUT_RING_EMPTY(intf) )
> +        {
> +            /*
> +             * clear the uart busy flag and set the TX FIFO empty flag
> +             */
> +            d->arch.vpl011.flag &= ~(VPL011_UARTFR_BUSY);
> +            d->arch.vpl011.flag |= (VPL011_UARTFR_TXFE);
> +        }
> +    }
> +
> +    VPL011_UNLOCK(d, flags);
> +
> +    /*
> +     * send an interrupt if it is not masked
> +     */
> +    if ( (d->arch.vpl011.raw_intr_status & d->arch.vpl011.intr_mask) )
> +        vgic_vcpu_inject_spi(d, (int)d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);

See my comment above about having an helper for this code.

> +
> +    if ( !VPL011_OUT_RING_EMPTY(intf) )
> +    {
> +        /*
> +         * raise an interrupt to dom0

The backend console does not necessarily live in DOM0. Anyway, Konrad 
requested to drop the comment and I am happy with that.

> +         */
> +        rc = raw_evtchn_send(d,
> +                    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL);

You are using a function that is been defined in a later patch (i.w #3). 
All the patch should be able to compile without applying upcoming patch 
to allow bisection.

Ideally, Xen should still be functional for every patch. But it is a 
best effort.

> +
> +        if ( rc < 0 )
> +            printk("Failed to send vpl011 interrupt to dom0\n");
> +    }
> +
> +    return rc;
> +}
> +
> +int vpl011_read_data(struct domain *d, unsigned char *data)

This function does not seem to be used outside of this file. So why do 
you export it?

> +{
> +    int rc=0;
> +    unsigned long flags;
> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
> +
> +    *data = 0;
> +
> +    VPL011_LOCK(d, flags);
> +
> +    /*
> +     * if there is data in the ring buffer then copy it to the output buffer
> +     */
> +    if ( !VPL011_IN_RING_EMPTY(intf) )
> +    {
> +        *data = intf->in[MASK_VPL011CONS_IDX(intf->in_cons++, intf->in)];
> +    }
> +
> +    /*
> +     * if the ring buffer is empty then set the RX FIFO empty flag
> +     */
> +    if ( VPL011_IN_RING_EMPTY(intf) )
> +    {
> +        d->arch.vpl011.flag |= (VPL011_UARTFR_RXFE);
> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_RXRIS);
> +    }
> +
> +    /*
> +     * clear the RX FIFO full flag
> +     */
> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFF);
> +
> +    VPL011_UNLOCK(d, flags);
> +
> +    return rc;
> +}
> +
> +int vpl011_write_data(struct domain *d, unsigned char data)

Same has for vpl011_read_data.

> +{
> +    int rc=0;
> +    unsigned long flags;
> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
> +
> +    VPL011_LOCK(d, flags);
> +
> +    /*
> +     * if there is space in the ring buffer then write the data
> +     */
> +    if ( !VPL011_OUT_RING_FULL(intf) )
> +    {
> +        intf->out[MASK_VPL011CONS_IDX(intf->out_prod++, intf->out)] = data;
> +        smp_wmb();
> +    }
> +
> +    /*
> +     * if there is no space in the ring buffer then set the
> +     * TX FIFO FULL flag
> +     */
> +    if ( VPL011_OUT_RING_FULL(intf) )
> +    {
> +        d->arch.vpl011.flag |= (VPL011_UARTFR_TXFF);
> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_TXRIS);
> +    }
> +
> +    /*
> +     * set the uart busy status
> +     */
> +    d->arch.vpl011.flag |= (VPL011_UARTFR_BUSY);
> +
> +    /*
> +     * clear the TX FIFO empty flag
> +     */
> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFE);
> +
> +    VPL011_UNLOCK(d, flags);
> +
> +    /*
> +     * raise an event to dom0 only if it is the first character in the buffer
> +     */
> +    if ( VPL011_RING_DEPTH(intf, out) == 1 )
> +    {
> +        rc = raw_evtchn_send(d,
> +                d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL);
> +
> +        if ( rc < 0 )
> +            printk("Failed to send vpl011 interrupt to dom0\n");
> +    }
> +
> +    return rc;
> +}
> +
> +static void vpl011_notification(struct vcpu *v, unsigned int port)
> +{
> +    vpl011_data_avail(v->domain);

vpl011_data_avail is returning an error but you don't check. What is the 
point of it then?

> +}
> +
> +int domain_vpl011_init(struct domain *d)

I was expected a destroy function to clean-up the vpl011 emulation.

> +{
> +    int rc=0;
> +
> +    /*
> +     * register xen event channel
> +     */
> +    rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id,
> +                                                        vpl011_notification);

This line looks wrong to me. The console backend may not live in the 
same domain as the toolstack.

> +    if (rc < 0)
> +    {
> +        printk ("Failed to allocate vpl011 event channel\n");
> +        return rc;
> +    }
> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN] = rc;
> +
> +    /*
> +     * allocate an SPI VIRQ for the guest
> +     */
> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ] = vgic_allocate_spi(d);

It makes little sense to hardcode the MMIO region and not the SPI. Also, 
I would rather avoid to introduce new HVM_PARAM when not necessary. So 
hardcoding the value looks more sensible to me.

> +
> +    /*
> +     * register mmio handler
> +     */
> +    register_mmio_handler (d, &vpl011_mmio_handler, GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL);

Coding style. No space between the function name and (.

> +
> +    /*
> +     * initialize the lock
> +     */
> +    spin_lock_init(&d->arch.vpl011.lock);
> +
> +    /*
> +     * clear the flag, control and interrupt status registers
> +     */
> +    d->arch.vpl011.control = 0;
> +    d->arch.vpl011.flag = 0;
> +    d->arch.vpl011.intr_mask = 0;
> +    d->arch.vpl011.intr_clear = 0;
> +    d->arch.vpl011.raw_intr_status = 0;
> +    d->arch.vpl011.masked_intr_status = 0;


The domain structure is already zeroed. So no need to 0 it again.

> +
> +    return 0;
> +}

Missing e-macs magic here.

> diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h
> new file mode 100644
> index 0000000..f2c577f
> --- /dev/null
> +++ b/xen/arch/arm/vpl011.h

Header should live in include.

[...]

> +#ifndef _VPL011_H_
> +
> +#define _VPL011_H_
> +
> +/*
> + * register offsets
> + */

We already define the PL011 register in include/asm-arm/pl011-uart.h. 
Please re-use them rather than re-inventing the wheel.

> +#define VPL011_UARTDR_OFFSET    0x0 // data register (RW)
> +#define VPL011_UARTRSR_OFFSET   0x4 // receive status and error clear register (RW)
> +#define VPL011_UARTFR_OFFSET    0x18 // flag register (RO)
> +#define VPL011_UARTRIS_OFFSET   0x3c // raw interrupt status register (RO)
> +#define VPL011_UARTMIS_OFFSET   0x40 // masked interrupt status register (RO)
> +#define VPL011_UARTIMSC_OFFSET  0x38 // interrupt mask set/clear register (RW)
> +#define VPL011_UARTICR_OFFSET   0x44 // interrupt clear register (WO)
> +#define VPL011_UARTCR_OFFSET    0x30 // uart control register
> +#define VPL011_UARTDMACR_OFFSET 0x48 // uart dma control register


[...]

> +#define MASK_VPL011CONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
> +struct console_interface {
> +    char in[1024];
> +    char out[2048];
> +    uint32_t in_cons, in_prod;
> +    uint32_t out_cons, out_prod;
> +};
> +#endif

The communication between Xen and the console backend is based on the PV 
console ring. It would be easier to re-use it rather than recreating one.

> diff --git a/xen/common/Kconfig b/xen/common/Kconfig
> index f2ecbc4..7e2feac 100644
> --- a/xen/common/Kconfig
> +++ b/xen/common/Kconfig
> @@ -237,4 +237,10 @@ config FAST_SYMBOL_LOOKUP
>  	  The only user of this is Live patching.
>
>  	  If unsure, say Y.
> +
> +config VPL011_CONSOLE
> +	bool "Emulated pl011 console support"
> +	default y
> +	---help---
> +	  Allows a guest to use pl011 UART as a console
>  endmenu

This should go in arch/arm/Kconfig

> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 2d6fbb1..ff2403a 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -40,6 +40,7 @@ struct vtimer {
>          uint64_t cval;
>  };
>
> +

Spurious line.

>  struct arch_domain
>  {
>  #ifdef CONFIG_ARM_64
> @@ -131,6 +132,20 @@ struct arch_domain
>      struct {
>          uint8_t privileged_call_enabled : 1;
>      } monitor;
> +
> +#ifdef CONFIG_VPL011_CONSOLE
> +    struct vpl011 {
> +        void *ring_buf;
> +        struct page_info *ring_page;
> +        uint32_t    flag;               /* flag register */
> +        uint32_t    control;            /* control register */
> +        uint32_t    intr_mask;          /* interrupt mask register*/
> +        uint32_t    intr_clear;         /* interrupt clear register */
> +        uint32_t    raw_intr_status;    /* raw interrupt status register */
> +        uint32_t    masked_intr_status; /* masked interrupt register */
> +        spinlock_t  lock;
> +    } vpl011;
> +#endif

I think the structure should be defined in vpl011.h.

>  }  __cacheline_aligned;
>
>  struct arch_vcpu
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index bd974fb..1d4548f 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -410,6 +410,10 @@ typedef uint64_t xen_callback_t;
>  #define GUEST_ACPI_BASE 0x20000000ULL
>  #define GUEST_ACPI_SIZE 0x02000000ULL
>
> +/* PL011 mappings */
> +#define GUEST_PL011_BASE    0x22000000ULL
> +#define GUEST_PL011_SIZE    0x00001000ULL
> +
>  /*
>   * 16MB == 4096 pages reserved for guest to use as a region to map its
>   * grant table in.
> @@ -420,6 +424,7 @@ typedef uint64_t xen_callback_t;
>  #define GUEST_MAGIC_BASE  xen_mk_ullong(0x39000000)
>  #define GUEST_MAGIC_SIZE  xen_mk_ullong(0x01000000)
>
> +

Spurious line.

>  #define GUEST_RAM_BANKS   2
>
>  #define GUEST_RAM0_BASE   xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */
>

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-02-21 11:25 ` [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup Bhupinder Thakur
  2017-03-03 20:02   ` Konrad Rzeszutek Wilk
@ 2017-03-05 12:35   ` Julien Grall
  2017-03-06  8:06     ` Jan Beulich
  2017-03-24  7:31     ` Bhupinder Thakur
  1 sibling, 2 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-05 12:35 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Jan Beulich, nd

(CC "The REST" maintainers)

Hi Bhupinder,

On 02/21/2017 11:25 AM, Bhupinder Thakur wrote:
> Three new HVM param handlers added for:
>     - allocating a new VIRQ and return to the toolstack

This is not necessary. We could hardcode it.

>     - allocating a new event channel for sending/receiving events from Xen and return
>       to the toolstack
>     - mapping the PFN allocted by the toolstack to be used as IN/OUT ring buffers

s/allocted/allocated/

>
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/arch/arm/hvm.c              | 39 +++++++++++++++++++++++++++++++++++++++
>  xen/include/public/hvm/params.h | 10 +++++++++-
>  2 files changed, 48 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c
> index d999bde..f3b9eb1 100644
> --- a/xen/arch/arm/hvm.c
> +++ b/xen/arch/arm/hvm.c
> @@ -23,6 +23,8 @@
>  #include <xen/guest_access.h>
>  #include <xen/sched.h>
>  #include <xen/monitor.h>
> +#include <xen/event.h>
> +#include <xen/vmap.h>
>
>  #include <xsm/xsm.h>
>
> @@ -31,6 +33,7 @@
>  #include <public/hvm/hvm_op.h>
>
>  #include <asm/hypercall.h>
> +#include "vpl011.h"
>
>  long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>  {
> @@ -61,9 +64,45 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>          if ( op == HVMOP_set_param )
>          {
>              d->arch.hvm_domain.params[a.index] = a.value;
> +
> +#ifdef CONFIG_VPL011_CONSOLE
> +            /*
> +             * if it is a vpl011 console pfn then map it to its
> +             * own address space
> +             */
> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN )
> +            {
> +                vpl011_map_guest_page(d);

vpl011_map_guest_page(...) is will return an error if it fails to map 
the page. Shouldn't you propagate the value.

Also, this code does not prevent the new HVM param to be set twice or 
even set by the guest. We probably want to introduce an helper to check 
if the domain is allowed to set it. See hvm_allow_set_param on x86.

> +            }
> +#else
> +            /*
> +             * if VPL011 is not compiled in then disallow setting of any
> +             * related HVM params
> +             */

We really don't care if the toolstack set unused HVM param as they 
should not be used.

> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
> +                 a.index == HVM_PARAM_VPL011_VIRQ )
> +            {
> +                rc = -1;
> +                goto param_fail;
> +            }
> +#endif
>          }
>          else
>          {
> +#ifndef CONFIG_VPL011_CONSOLE
> +            /*
> +             * if VPL011 is not compiled in then disallow setting of any
> +             * related HVM params
> +             */
> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
> +                 a.index == HVM_PARAM_VPL011_VIRQ )
> +            {
> +                rc = -1;
> +                goto param_fail;
> +            }
> +#endif

Ditto.

>              a.value = d->arch.hvm_domain.params[a.index];

We probably don't want the guest to be able to read the console pfn 
page. See hvm_allow_get_param.

>              rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
>          }
> diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
> index 3f54a49..13bf719 100644
> --- a/xen/include/public/hvm/params.h
> +++ b/xen/include/public/hvm/params.h
> @@ -203,10 +203,17 @@
>   */
>  #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
>
> -/* Deprecated */
> +#if defined(__arm__) || defined(__aarch64__)
> +#define HVM_PARAM_VPL011_CONSOLE_PFN    20
> +#define HVM_PARAM_VPL011_CONSOLE_EVTCHN 21
> +#define HVM_PARAM_VPL011_VIRQ           22
> +#else
>  #define HVM_PARAM_MEMORY_EVENT_CR0          20
>  #define HVM_PARAM_MEMORY_EVENT_CR3          21
>  #define HVM_PARAM_MEMORY_EVENT_CR4          22

Those parameters are still deprecated but you drop the comment stating that.

> +#endif
> +

Those params are x86 specific so should have never been set on ARM. But 
I am not sure if it is fine to re-purpose deprecated number.

I have CCed "The REST" maintainers to have their input here.

> +/* Deprecated */
>  #define HVM_PARAM_MEMORY_EVENT_INT3         23
>  #define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP  25
>  #define HVM_PARAM_MEMORY_EVENT_MSR          30
> @@ -253,6 +260,7 @@
>   */
>  #define HVM_PARAM_X87_FIP_WIDTH 36
>
> +

Spurious change.

>  #define HVM_NR_PARAMS 37
>
>  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
>

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-02-21 11:26 ` [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel Bhupinder Thakur
  2017-03-03 21:13   ` Konrad Rzeszutek Wilk
@ 2017-03-05 12:39   ` Julien Grall
  2017-03-06  8:15     ` Jan Beulich
  1 sibling, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-05 12:39 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Tim Deegan, Jan Beulich, nd, Ian Jackson

Hi Bhupinder,

My knowledge is limited for this code. So I've just CCed "The REST" 
maintainers. Please do CC them in the future.

On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
> is bound to a xen consumer then event generation is not allowed for that channel.
> This check is to disallow a guest from raising an event via this channel. However,
> it should allow Xen to send a event via this channel as it is required for sending
> vpl011 event to the dom0.
>
> This change introduces a new function raw_evtchn_send() which sends the event
> without this check. The current evtchn_send() calls this function after doing the
> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
> bypassing the check.
>
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/common/event_channel.c | 49 ++++++++++++++++++++++++++++++++++------------
>  xen/include/xen/event.h    |  6 ++++++
>  2 files changed, 42 insertions(+), 13 deletions(-)
>
> diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
> index 638dc5e..4b039f3 100644
> --- a/xen/common/event_channel.c
> +++ b/xen/common/event_channel.c
> @@ -27,6 +27,7 @@
>  #include <xen/keyhandler.h>
>  #include <xen/event_fifo.h>
>  #include <asm/current.h>
> +#include <xen/domain_page.h>

Why did you include xen/domain_page.h?

>
>  #include <public/xen.h>
>  #include <public/event_channel.h>
> @@ -650,25 +651,21 @@ static long evtchn_close(struct domain *d1, int port1, bool_t guest)
>      return rc;
>  }
>
> -int evtchn_send(struct domain *ld, unsigned int lport)
> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data)
>  {
>      struct evtchn *lchn, *rchn;
>      struct domain *rd;
> -    int            rport, ret = 0;
> +    int rport, ret=0;
>
> -    if ( !port_is_valid(ld, lport) )
> -        return -EINVAL;
> -
> -    lchn = evtchn_from_port(ld, lport);
> -
> -    spin_lock(&lchn->lock);
> -
> -    /* Guest cannot send via a Xen-attached event channel. */
> -    if ( unlikely(consumer_is_xen(lchn)) )
> +    if ( !data )
>      {
> -        ret = -EINVAL;
> -        goto out;
> +        if ( !port_is_valid(ld, lport) )
> +            return -EINVAL;
> +        lchn = evtchn_from_port(ld, lport);
> +        spin_lock(&lchn->lock);
>      }
> +    else
> +        lchn = (struct evtchn *)data;
>
>      ret = xsm_evtchn_send(XSM_HOOK, ld, lchn);
>      if ( ret )
> @@ -696,6 +693,32 @@ int evtchn_send(struct domain *ld, unsigned int lport)
>      }
>
>  out:
> +    if ( !data )
> +        spin_unlock(&lchn->lock);
> +
> +    return ret;
> +}
> +
> +int evtchn_send(struct domain *ld, unsigned int lport)
> +{
> +    struct evtchn *lchn;
> +    int ret;
> +
> +    if ( !port_is_valid(ld, lport) )
> +        return -EINVAL;
> +
> +    lchn = evtchn_from_port(ld, lport);
> +
> +    spin_lock(&lchn->lock);
> +
> +    if ( unlikely(consumer_is_xen(lchn)) )
> +    {
> +        printk("evtchn_send failed to send via xen event channel\n");
> +        return -EINVAL;
> +    }
> +
> +    ret = raw_evtchn_send(ld, lport, lchn);
> +
>      spin_unlock(&lchn->lock);
>
>      return ret;
> diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
> index 5008c80..9bd17db 100644
> --- a/xen/include/xen/event.h
> +++ b/xen/include/xen/event.h
> @@ -45,6 +45,12 @@ void send_guest_pirq(struct domain *, const struct pirq *);
>  /* Send a notification from a given domain's event-channel port. */
>  int evtchn_send(struct domain *d, unsigned int lport);
>
> +/*
> + * This function is same as evntchn_send() except it does not do xen consumer check
> + * to allow the events to be sent from xen bound channels.
> + */
> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data);
> +
>  /* Bind a local event-channel port to the specified VCPU. */
>  long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
>
>

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen
  2017-02-21 11:26 ` [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen Bhupinder Thakur
  2017-03-03 21:47   ` Konrad Rzeszutek Wilk
@ 2017-03-05 12:46   ` Julien Grall
  2017-03-06  8:27     ` Jan Beulich
  1 sibling, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-05 12:46 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Tim Deegan, Jan Beulich, nd, Ian Jackson

(CC the REST maintainer)

Hi Bhupinder,

On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
> Based on one of the domain creation flags, the vpl011 emulation will be enabled for
> the domain.
>
> This flag is currently set always but finally it needs to be controlled by the user
> through some configuration option.

We really don't want the pl011 emulation by default. You should provide 
a libxl option to enable pl011 emulation. Also without the next patch, 
this will break guest boot as SPIs are not correctly initialized.

You likely want to re-order the two.

>
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/arch/arm/domain.c   | 8 ++++++++
>  xen/common/domctl.c     | 2 ++
>  xen/include/xen/sched.h | 4 ++++
>  3 files changed, 14 insertions(+)
>
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 7e43691..6fee541 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -36,6 +36,9 @@
>  #include <asm/platform.h>
>  #include "vtimer.h"
>  #include "vuart.h"
> +#ifdef CONFIG_VPL011_CONSOLE
> +#include "vpl011.h"
> +#endif
>
>  DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
>
> @@ -626,6 +629,11 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>      if ( (rc = domain_vtimer_init(d, config)) != 0 )
>          goto fail;
>
> +#ifdef CONFIG_VPL011_CONSOLE
> +    if ( domcr_flags & DOMCRF_vpl011_console )
> +        if ( (rc = domain_vpl011_init(d)) != 0 )
> +            goto fail;
> +#endif

You likely want to return an error if the toolstack request the pl011 
emulation and it is not present in Xen.

So I would add a stub for domain_vpl011_init to return -ENOSYS when the 
pl011 emulation does not exist in Xen.

>      update_domain_wallclock_time(d);
>
>      /*
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index 12cf4a9..fafc506 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -551,6 +551,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>          if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_xs_domain )
>              domcr_flags |= DOMCRF_xs_domain;
>
> +        domcr_flags |= DOMCRF_vpl011_console;
> +

Please don't do that. See my suggestion above.


>          d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref,
>                            &op->u.createdomain.config);
>          if ( IS_ERR(d) )
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index 063efe6..9e03a60 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -555,6 +555,10 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags,
>  #define _DOMCRF_xs_domain       6
>  #define DOMCRF_xs_domain        (1U<<_DOMCRF_xs_domain)
>
> + /* DOMCRF_vpl011_console: create domain with pl011 emulation enabled */
> +#define _DOMCRF_vpl011_console  7
> +#define DOMCRF_vpl011_console   (1U<<_DOMCRF_vpl011_console)
> +
>  /*
>   * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
>   * This is the preferred function if the returned domain reference
>

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-02-21 11:26 ` [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1 Bhupinder Thakur
  2017-03-03 20:49   ` Konrad Rzeszutek Wilk
@ 2017-03-05 12:51   ` Julien Grall
  2017-03-16  6:50     ` Bhupinder Thakur
  1 sibling, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-05 12:51 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel; +Cc: nd, Stefano Stabellini

Hi Bhupinder,

Commit title: s/atleat/at least/

On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
> Ensure that nr_spis intialized in in vgic_init is atleast 1 to allow allocation of

s/intialized/initialized/ and again s/atleast/at least/

> pl011 spi virq.
>
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  xen/arch/arm/vgic.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 364d5f0..614b3ec 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -121,6 +121,11 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
>      /* Limit the number of virtual SPIs supported to (1020 - 32) = 988  */
>      if ( nr_spis > (1020 - NR_LOCAL_IRQS) )
>          return -EINVAL;
> +#ifdef CONFIG_VPL011_CONSOLE
> +    /* Atleast 1 spi should be available for assigning to vpl011 */
> +    else if ( nr_spis < (1020 - NR_LOCAL_IRQS) )
> +        nr_spis += 1;
> +#endif

Please don't do that. The toolstack should allocated the correct number 
of SPIs depending on the configuration of the guest.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack
  2017-03-03 21:03   ` Konrad Rzeszutek Wilk
@ 2017-03-05 12:59     ` Julien Grall
  0 siblings, 0 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-05 12:59 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk, Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

Hi Konrad,

On 03/03/2017 09:03 PM, Konrad Rzeszutek Wilk wrote:
> On Tue, Feb 21, 2017 at 04:56:03PM +0530, Bhupinder Thakur wrote:
>> Add a new pl011 uart node
>>     - Get the pl011 spi virq from Xen using a hvm call
>>     - Add a new device tree node in the guest DT for SBSA pl011 uart containing the IRQ
>>       (read above) and the MMIO address range to be used by the guest
>>
>> The format for the node is specified in Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt.
>
> Why don't you just copy-n-paste it in? It is only 10 linues.
>
>>
>> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
>> ---
>>  tools/libxl/libxl_arm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
>>  1 file changed, 45 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
>> index d842d88..34c7e39 100644
>> --- a/tools/libxl/libxl_arm.c
>> +++ b/tools/libxl/libxl_arm.c
>> @@ -130,9 +130,10 @@ static struct arch_info {
>>      const char *guest_type;
>>      const char *timer_compat;
>>      const char *cpu_compat;
>> +    const char *uart_compat;
>>  } arch_info[] = {
>> -    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15" },
>> -    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8" },
>> +    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15", "arm,sbsa-uart" },
>> +    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8", "arm,sbsa-uart" },
>>  };
>>
>>  /*
>> @@ -590,6 +591,38 @@ static int make_hypervisor_node(libxl__gc *gc, void *fdt,
>>      return 0;
>>  }
>>
>> +static int make_vpl011_uart_node(libxl__gc *gc, void *fdt,
>> +                           const struct arch_info *ainfo,
>> +                           struct xc_dom_image *dom, uint64_t irq)
>
> Hm, mayube my editor is wrong but these arguments don't appear
> to be right..
>
>> +{
>> +    int res;
>> +    gic_interrupt intr;
>> +
>> +    res = fdt_begin_node(fdt, "sbsa-pl011");
>> +    if (res) return res;
>> +
>> +    res = fdt_property_compat(gc, fdt, 1, ainfo->uart_compat);
>> +    if (res) return res;
>> +
>> +    res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
>> +                            1,
>> +                            GUEST_PL011_BASE, GUEST_PL011_SIZE);
>> +    if (res)
>> +        return res;
>
> Shouldn't we free them?

libxl is allocating a big chunk of memory for the FDT blob (see 
libxl__prepare_dtb) and those helpers will only fill the buffer. If they 
fail is means the buffer is not big enough and the process will be 
restarted from the beginning.

So there is not need to worry to free anything here.

>
>> +
>> +    set_interrupt(intr, irq, 0xf, DT_IRQ_TYPE_LEVEL_HIGH);
>
> 0xF looks like a good candidate for #define.
>> +
>> +    res = fdt_property_interrupts(gc, fdt, &intr, 1);
>> +    if (res) return res;
>
> Again, shouldn't we free it if we things go south?
>> +
>> +    fdt_property_u32(fdt, "current-speed", 115200);
>
> So perhaps a #define?

+1 and explaining why 115200. If it is a random value it should be 
explained.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack
  2017-02-21 11:26 ` [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack Bhupinder Thakur
  2017-03-03 20:15   ` Konrad Rzeszutek Wilk
  2017-03-03 21:03   ` Konrad Rzeszutek Wilk
@ 2017-03-05 13:04   ` Julien Grall
  2017-03-14 13:00     ` Wei Liu
  2 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-05 13:04 UTC (permalink / raw)
  To: Bhupinder Thakur, xen-devel; +Cc: Wei Liu, nd, Ian Jackson, Stefano Stabellini

Hi Bhupinder,

CC toolstack maintainers.

On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
> Add a new pl011 uart node
>     - Get the pl011 spi virq from Xen using a hvm call

See my comment on previous patches.

>     - Add a new device tree node in the guest DT for SBSA pl011 uart containing the IRQ
>       (read above) and the MMIO address range to be used by the guest
>
> The format for the node is specified in Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt.

The ordering of the patches in this series is a bit weird. You are 
exposing the pl011 to the guest before all the code to handle it is 
there. This patch should likely be at the end of this series.

Also, you want a libxl option to allow the user enabling/disable pl011 
emulation. We likely want this emulation disable by default.

>
> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> ---
>  tools/libxl/libxl_arm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> index d842d88..34c7e39 100644
> --- a/tools/libxl/libxl_arm.c
> +++ b/tools/libxl/libxl_arm.c
> @@ -130,9 +130,10 @@ static struct arch_info {
>      const char *guest_type;
>      const char *timer_compat;
>      const char *cpu_compat;
> +    const char *uart_compat;
>  } arch_info[] = {
> -    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15" },
> -    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8" },
> +    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15", "arm,sbsa-uart" },
> +    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8", "arm,sbsa-uart" },
>  };
>
>  /*
> @@ -590,6 +591,38 @@ static int make_hypervisor_node(libxl__gc *gc, void *fdt,
>      return 0;
>  }
>
> +static int make_vpl011_uart_node(libxl__gc *gc, void *fdt,
> +                           const struct arch_info *ainfo,
> +                           struct xc_dom_image *dom, uint64_t irq)

Why uint64_t for irq?

> +{
> +    int res;
> +    gic_interrupt intr;
> +
> +    res = fdt_begin_node(fdt, "sbsa-pl011");
> +    if (res) return res;
> +
> +    res = fdt_property_compat(gc, fdt, 1, ainfo->uart_compat);
> +    if (res) return res;
> +
> +    res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
> +                            1,
> +                            GUEST_PL011_BASE, GUEST_PL011_SIZE);
> +    if (res)
> +        return res;
> +
> +    set_interrupt(intr, irq, 0xf, DT_IRQ_TYPE_LEVEL_HIGH);
> +
> +    res = fdt_property_interrupts(gc, fdt, &intr, 1);
> +    if (res) return res;
> +
> +    fdt_property_u32(fdt, "current-speed", 115200);
> +
> +    res = fdt_end_node(fdt);
> +    if (res) return res;
> +
> +    return 0;
> +}
> +
>  static const struct arch_info *get_arch_info(libxl__gc *gc,
>                                               const struct xc_dom_image *dom)
>  {
> @@ -790,6 +823,7 @@ static int libxl__prepare_dtb(libxl__gc *gc, libxl_domain_build_info *info,
>      int rc, res;
>      size_t fdt_size = 0;
>      int pfdt_size = 0;
> +    uint64_t vpl011_irq=0;
>
>      const libxl_version_info *vers;
>      const struct arch_info *ainfo;
> @@ -889,6 +923,13 @@ next_resize:
>          FDT( make_timer_node(gc, fdt, ainfo, xc_config->clock_frequency) );
>          FDT( make_hypervisor_node(gc, fdt, vers) );
>
> +        /*
> +         * get the vpl011 VIRQ and use it for creating a vpl011 node entry
> +         */
> +        if ( !xc_hvm_param_get(dom->xch, dom->guest_domid, HVM_PARAM_VPL011_VIRQ,
> +                                                               &vpl011_irq) )
> +            FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom, vpl011_irq) );
> +
>          if (pfdt)
>              FDT( copy_partial_fdt(gc, fdt, pfdt) );
>
> @@ -933,9 +974,11 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
>      val |= GUEST_EVTCHN_PPI;
>      rc = xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CALLBACK_IRQ,
>                            val);
> +
>      if (rc)
>          return rc;
>
> +
>      rc = libxl__prepare_dtb(gc, info, state, dom);
>      if (rc) goto out;
>
>

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 08/11] xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen using a hvm call
  2017-03-03 20:51   ` Konrad Rzeszutek Wilk
@ 2017-03-05 13:07     ` Julien Grall
  0 siblings, 0 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-05 13:07 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk, Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

Hi Konrad,

On 03/03/2017 08:51 PM, Konrad Rzeszutek Wilk wrote:
> On Tue, Feb 21, 2017 at 04:56:05PM +0530, Bhupinder Thakur wrote:
>> Allocates a new pfn, initializes it and passes on to Xen using a hvm call.
>
> s/passes/pass/
>>
>> Another changes is in xc_hvm_param_deprecated_check () to allow new vpl011 HVM params,
>> which have been defined to some deprecated HVM params.
>
> Do you need to do something special with migration?
>
> Or does migration not work yet on ARM?

I will answer to this question and leave Bhupinder answering the rest. 
Sadly, the migration support does not yet exist on ARM.

Regardless that, I am sure whether re-purposing deprecating HVM params 
is fine. Although they should have never been used on ARM.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-05 12:35   ` Julien Grall
@ 2017-03-06  8:06     ` Jan Beulich
  2017-03-06 11:42       ` Julien Grall
  2017-03-24  7:31     ` Bhupinder Thakur
  1 sibling, 1 reply; 82+ messages in thread
From: Jan Beulich @ 2017-03-06  8:06 UTC (permalink / raw)
  To: Julien Grall, Bhupinder Thakur
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, xen-devel, nd

>>> On 05.03.17 at 13:35, <julien.grall@arm.com> wrote:
> On 02/21/2017 11:25 AM, Bhupinder Thakur wrote:
>> --- a/xen/include/public/hvm/params.h
>> +++ b/xen/include/public/hvm/params.h
>> @@ -203,10 +203,17 @@
>>   */
>>  #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
>>
>> -/* Deprecated */
>> +#if defined(__arm__) || defined(__aarch64__)
>> +#define HVM_PARAM_VPL011_CONSOLE_PFN    20
>> +#define HVM_PARAM_VPL011_CONSOLE_EVTCHN 21
>> +#define HVM_PARAM_VPL011_VIRQ           22
>> +#else
>>  #define HVM_PARAM_MEMORY_EVENT_CR0          20
>>  #define HVM_PARAM_MEMORY_EVENT_CR3          21
>>  #define HVM_PARAM_MEMORY_EVENT_CR4          22
> 
> Those parameters are still deprecated but you drop the comment stating that.
> 
>> +#endif
>> +
> 
> Those params are x86 specific so should have never been set on ARM. But 
> I am not sure if it is fine to re-purpose deprecated number.
> 
> I have CCed "The REST" maintainers to have their input here.

I think re-purposing something that was never (meant to be) used is
fine in a case like this. However, the question is moot with your
suggestion to not use params here in the first place.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-03-05 12:39   ` Julien Grall
@ 2017-03-06  8:15     ` Jan Beulich
  2017-03-06 10:44       ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Jan Beulich @ 2017-03-06  8:15 UTC (permalink / raw)
  To: Bhupinder Thakur
  Cc: Stefano Stabellini, Wei Liu, GeorgeDunlap, AndrewCooper,
	Ian Jackson, Tim Deegan, Julien Grall, xen-devel, nd

>>> On 05.03.17 at 13:39, <julien.grall@arm.com> wrote:
> My knowledge is limited for this code. So I've just CCed "The REST" 
> maintainers. Please do CC them in the future.

Indeed.

> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
>> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
>> is bound to a xen consumer then event generation is not allowed for that channel.
>> This check is to disallow a guest from raising an event via this channel. However,
>> it should allow Xen to send a event via this channel as it is required for sending
>> vpl011 event to the dom0.
>>
>> This change introduces a new function raw_evtchn_send() which sends the event
>> without this check. The current evtchn_send() calls this function after doing the
>> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
>> bypassing the check.

Why would Xen want to send an event it is itself the consumer of?
Surely there are better ways to communicate state internally? The
more that you say you want the event sent to Dom0...

>> @@ -650,25 +651,21 @@ static long evtchn_close(struct domain *d1, int port1, bool_t guest)
>>      return rc;
>>  }
>>
>> -int evtchn_send(struct domain *ld, unsigned int lport)
>> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data)
>>  {
>>      struct evtchn *lchn, *rchn;
>>      struct domain *rd;
>> -    int            rport, ret = 0;
>> +    int rport, ret=0;

There's only whitespace change here, and just the break existing
formatting. Please avoid stray changes like this.

>> @@ -696,6 +693,32 @@ int evtchn_send(struct domain *ld, unsigned int lport)
>>      }
>>
>>  out:
>> +    if ( !data )
>> +        spin_unlock(&lchn->lock);
>> +
>> +    return ret;
>> +}
>> +
>> +int evtchn_send(struct domain *ld, unsigned int lport)
>> +{
>> +    struct evtchn *lchn;
>> +    int ret;
>> +
>> +    if ( !port_is_valid(ld, lport) )
>> +        return -EINVAL;
>> +
>> +    lchn = evtchn_from_port(ld, lport);
>> +
>> +    spin_lock(&lchn->lock);
>> +
>> +    if ( unlikely(consumer_is_xen(lchn)) )
>> +    {
>> +        printk("evtchn_send failed to send via xen event channel\n");
>> +        return -EINVAL;

As a general remark: Splitting out functionality into a new function
should _never_ be accompanied by silent behavioral changes for
pre-existing code paths. In the case here there was no printk()
before, and I see no justification for one to be added.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen
  2017-03-05 12:46   ` Julien Grall
@ 2017-03-06  8:27     ` Jan Beulich
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Beulich @ 2017-03-06  8:27 UTC (permalink / raw)
  To: Julien Grall, Bhupinder Thakur
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	IanJackson, Tim Deegan, xen-devel, nd

>>> On 05.03.17 at 13:46, <julien.grall@arm.com> wrote:
> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>> Based on one of the domain creation flags, the vpl011 emulation will be enabled for
>> the domain.
>>
>> This flag is currently set always but finally it needs to be controlled by the user
>> through some configuration option.
> 
> We really don't want the pl011 emulation by default. You should provide 
> a libxl option to enable pl011 emulation.

Furthermore I don't think emulation of individual devices should be
set up via DOMCRF_*, these should be used only for more general
aspects of domain creation.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-03-03 21:13   ` Konrad Rzeszutek Wilk
@ 2017-03-06 10:16     ` Bhupinder Thakur
  2017-03-06 10:35       ` Jan Beulich
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-06 10:16 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk; +Cc: xen-devel, Julien Grall, Stefano Stabellini

Hi Konrad,

On 4 March 2017 at 02:43, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> wrote:
> On Tue, Feb 21, 2017 at 04:56:00PM +0530, Bhupinder Thakur wrote:
>> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
>> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
>> is bound to a xen consumer then event generation is not allowed for that channel.
>> This check is to disallow a guest from raising an event via this channel. However,
>
> Did any code archeology help in idenfitying why this was done this way?
>
> You should explain why it was done - what was the use case , and why
> your change will not change this semantic.

I think there was never a use case earlier to generate events from the
Xen itself to the guest. The event generation always happened on
behalf of a guest via evtchn_send(), which was invoked through a
hypercall by the guest. To disallow a guest from sending an event via
an event channel which is bound to Xen, there is a check in
evtchn_send() to check if it is a xen bound channel and if it is then
disallow sending an event via that channel because that channel is
meant only for Xen.

For pl011 emulation, there is a requirement for Xen to generate the
event to dom0 when there is data for dom0 to read in the ring buffer.
Since I am using a Xen bound channel so that Xen can receive events
from dom0 when there is data for Xen to read, the above mentioned
check would not allow the event to be sent to dom0.

Since this event is required to be generated from Xen only, it is safe
to allow to send the event from a xen bound channel. That is why I
introduced a new function raw_evtchn_send() to allow Xen to do that
while still keeping that restriction for the guests who use
evtchn_send() as it is today.

>> it should allow Xen to send a event via this channel as it is required for sending
>> vpl011 event to the dom0.
>>
>> This change introduces a new function raw_evtchn_send() which sends the event
>> without this check. The current evtchn_send() calls this function after doing the
>
> .. and without taking a lock? Why?
>
The third parameter to raw_evtchn_send() is the event channel
structure pointer. When raw_evtchn_send() is called from inside
evtchn_send(), it would be passed a pointer to the local event channel
structure and lock already taken (which would be case most of the
times). But when it is called directly by Xen to send an event to dom0
(as in case of pl011), the third parameter will be passed as NULL. In
this case, the lock and a reference to local channel structure would
be taken inside raw_evtchn_send().

>
>> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
>> bypassing the check.
>>
>> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
>> ---
>>  xen/common/event_channel.c | 49 ++++++++++++++++++++++++++++++++++------------
>>  xen/include/xen/event.h    |  6 ++++++
>>  2 files changed, 42 insertions(+), 13 deletions(-)
>>
>> diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
>> index 638dc5e..4b039f3 100644
>> --- a/xen/common/event_channel.c
>> +++ b/xen/common/event_channel.c
>> @@ -27,6 +27,7 @@
>>  #include <xen/keyhandler.h>
>>  #include <xen/event_fifo.h>
>>  #include <asm/current.h>
>> +#include <xen/domain_page.h>
>>
>>  #include <public/xen.h>
>>  #include <public/event_channel.h>
>> @@ -650,25 +651,21 @@ static long evtchn_close(struct domain *d1, int port1, bool_t guest)
>>      return rc;
>>  }
>>
>> -int evtchn_send(struct domain *ld, unsigned int lport)
>> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data)
>>  {
>>      struct evtchn *lchn, *rchn;
>>      struct domain *rd;
>> -    int            rport, ret = 0;
>> +    int rport, ret=0;
>
> Please that code as is.
>
I will remove these cosmetic changes in the next patch.

>>
>> -    if ( !port_is_valid(ld, lport) )
>> -        return -EINVAL;
>> -
>> -    lchn = evtchn_from_port(ld, lport);
>> -
>> -    spin_lock(&lchn->lock);
>> -
>> -    /* Guest cannot send via a Xen-attached event channel. */
>> -    if ( unlikely(consumer_is_xen(lchn)) )
>> +    if ( !data )
>>      {
>> -        ret = -EINVAL;
>> -        goto out;
>> +        if ( !port_is_valid(ld, lport) )
>> +            return -EINVAL;
>> +        lchn = evtchn_from_port(ld, lport);
>> +        spin_lock(&lchn->lock);
>
> That won't do. Please keep the format of the old code as much
> as possible (hint: Those newlines).
>
I will remove these cosmetic changes in the next patch.

>>      }
>> +    else
>> +        lchn = (struct evtchn *)data;
>>
>>      ret = xsm_evtchn_send(XSM_HOOK, ld, lchn);
>>      if ( ret )
>> @@ -696,6 +693,32 @@ int evtchn_send(struct domain *ld, unsigned int lport)
>>      }
>>
>>  out:
>> +    if ( !data )
>> +        spin_unlock(&lchn->lock);
>> +
>> +    return ret;
>> +}
>> +
>> +int evtchn_send(struct domain *ld, unsigned int lport)
>> +{
>> +    struct evtchn *lchn;
>> +    int ret;
>> +
>> +    if ( !port_is_valid(ld, lport) )
>> +        return -EINVAL;
>> +
>> +    lchn = evtchn_from_port(ld, lport);
>> +
>> +    spin_lock(&lchn->lock);
>> +
>> +    if ( unlikely(consumer_is_xen(lchn)) )
>> +    {
>> +        printk("evtchn_send failed to send via xen event channel\n");
>
> No. Please do not.
I will remove the failure print.

>> +        return -EINVAL;
>> +    }
>> +
>> +    ret = raw_evtchn_send(ld, lport, lchn);
>> +
>>      spin_unlock(&lchn->lock);
>>
>>      return ret;
>> diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h
>> index 5008c80..9bd17db 100644
>> --- a/xen/include/xen/event.h
>> +++ b/xen/include/xen/event.h
>> @@ -45,6 +45,12 @@ void send_guest_pirq(struct domain *, const struct pirq *);
>>  /* Send a notification from a given domain's event-channel port. */
>>  int evtchn_send(struct domain *d, unsigned int lport);
>>
>> +/*
>> + * This function is same as evntchn_send() except it does not do xen consumer check
>> + * to allow the events to be sent from xen bound channels.
>
> And it also looks to ignore the locking? Could you explain why?
>
It will take the lock when invoked directly (explained above).

>> + */
>> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data);
>> +
>>  /* Bind a local event-channel port to the specified VCPU. */
>>  long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
>>
>> --
>> 2.7.4
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-03-06 10:16     ` Bhupinder Thakur
@ 2017-03-06 10:35       ` Jan Beulich
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Beulich @ 2017-03-06 10:35 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Julien Grall, Stefano Stabellini

>>> On 06.03.17 at 11:16, <bhupinder.thakur@linaro.org> wrote:
> On 4 March 2017 at 02:43, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> wrote:
>> On Tue, Feb 21, 2017 at 04:56:00PM +0530, Bhupinder Thakur wrote:
>>> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
>>> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
>>> is bound to a xen consumer then event generation is not allowed for that channel.
>>> This check is to disallow a guest from raising an event via this channel. However,
>>
>> Did any code archeology help in idenfitying why this was done this way?
>>
>> You should explain why it was done - what was the use case , and why
>> your change will not change this semantic.
> 
> I think there was never a use case earlier to generate events from the
> Xen itself to the guest. The event generation always happened on
> behalf of a guest via evtchn_send(), which was invoked through a
> hypercall by the guest.

This is not true: All interrupts being converted to events go this
route, without any hypercall involved. Same for signaling qemu
to do emulation of an emulated device (memory of port) access.

> To disallow a guest from sending an event via
> an event channel which is bound to Xen, there is a check in
> evtchn_send() to check if it is a xen bound channel and if it is then
> disallow sending an event via that channel because that channel is
> meant only for Xen.

As said in reply to your patch - I think you got directions mixed up
here: You talk about Xen sending an event to a guest, but at the
same time you fiddle with code preventing guests from sending
events to Xen.

> For pl011 emulation, there is a requirement for Xen to generate the
> event to dom0 when there is data for dom0 to read in the ring buffer.

This is not different from hardware signaling the need for service
via an interrupt, which - always for PV guests, sometimes for HVM
ones - is being converted to an event.

> Since I am using a Xen bound channel so that Xen can receive events
> from dom0 when there is data for Xen to read, the above mentioned
> check would not allow the event to be sent to dom0.

Now here you come to talk about the direction which indeed is not
allowed. But breaking out part of the function won't help you, as
the new (raw) function then mustn't be called as a result of some
guest's request (hypercall or whatever), which includes Dom0.

> Since this event is required to be generated from Xen only, it is safe
> to allow to send the event from a xen bound channel. That is why I
> introduced a new function raw_evtchn_send() to allow Xen to do that
> while still keeping that restriction for the guests who use
> evtchn_send() as it is today.

And now it becomes confusing again: Yet another time you talk about
Xen sending the event. Please can you cleanly separate both directions
of event flow, and talk only about the relevant one in the respective
contexts?

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-03-06  8:15     ` Jan Beulich
@ 2017-03-06 10:44       ` Bhupinder Thakur
  2017-03-06 10:54         ` Jan Beulich
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-06 10:44 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, GeorgeDunlap, AndrewCooper,
	Ian Jackson, Tim Deegan, Julien Grall, xen-devel, nd

Hi Jan,

On 6 March 2017 at 13:45, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 05.03.17 at 13:39, <julien.grall@arm.com> wrote:
>> My knowledge is limited for this code. So I've just CCed "The REST"
>> maintainers. Please do CC them in the future.
>
> Indeed.
>
I will take care of this in the future.

>> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>>> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
>>> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
>>> is bound to a xen consumer then event generation is not allowed for that channel.
>>> This check is to disallow a guest from raising an event via this channel. However,
>>> it should allow Xen to send a event via this channel as it is required for sending
>>> vpl011 event to the dom0.
>>>
>>> This change introduces a new function raw_evtchn_send() which sends the event
>>> without this check. The current evtchn_send() calls this function after doing the
>>> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
>>> bypassing the check.
>
> Why would Xen want to send an event it is itself the consumer of?
> Surely there are better ways to communicate state internally? The
> more that you say you want the event sent to Dom0...
>
As a consumer, Xen receives event from dom0. It also needs to send
events to dom0 to indicate that there is data in the ring buffer for
dom0 to read. I am using a xen bound event channel for
sending/receiving events to/from dom0. I added a new function
raw_evtchn_send() to allow Xen to send events to dom0 without doing
the is_xen_consumer check. Note that this check is still there in
evtchn_send() to disallow guests to raise events on the xen bound
channel.

>>> @@ -650,25 +651,21 @@ static long evtchn_close(struct domain *d1, int port1, bool_t guest)
>>>      return rc;
>>>  }
>>>
>>> -int evtchn_send(struct domain *ld, unsigned int lport)
>>> +int raw_evtchn_send(struct domain *ld, unsigned int lport, void *data)
>>>  {
>>>      struct evtchn *lchn, *rchn;
>>>      struct domain *rd;
>>> -    int            rport, ret = 0;
>>> +    int rport, ret=0;
>
> There's only whitespace change here, and just the break existing
> formatting. Please avoid stray changes like this.
>
I will fix this in the next version.

>>> @@ -696,6 +693,32 @@ int evtchn_send(struct domain *ld, unsigned int lport)
>>>      }
>>>
>>>  out:
>>> +    if ( !data )
>>> +        spin_unlock(&lchn->lock);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +int evtchn_send(struct domain *ld, unsigned int lport)
>>> +{
>>> +    struct evtchn *lchn;
>>> +    int ret;
>>> +
>>> +    if ( !port_is_valid(ld, lport) )
>>> +        return -EINVAL;
>>> +
>>> +    lchn = evtchn_from_port(ld, lport);
>>> +
>>> +    spin_lock(&lchn->lock);
>>> +
>>> +    if ( unlikely(consumer_is_xen(lchn)) )
>>> +    {
>>> +        printk("evtchn_send failed to send via xen event channel\n");
>>> +        return -EINVAL;
>
> As a general remark: Splitting out functionality into a new function
> should _never_ be accompanied by silent behavioral changes for
> pre-existing code paths. In the case here there was no printk()
> before, and I see no justification for one to be added.
>
Ok. I will remove the printk.

> Jan
>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-03-06 10:44       ` Bhupinder Thakur
@ 2017-03-06 10:54         ` Jan Beulich
  2017-03-06 11:12           ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Jan Beulich @ 2017-03-06 10:54 UTC (permalink / raw)
  To: Bhupinder Thakur
  Cc: Stefano Stabellini, Wei Liu, GeorgeDunlap, AndrewCooper,
	Ian Jackson, Tim Deegan, Julien Grall, xen-devel, nd

>>> On 06.03.17 at 11:44, <bhupinder.thakur@linaro.org> wrote:
> On 6 March 2017 at 13:45, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 05.03.17 at 13:39, <julien.grall@arm.com> wrote:
>>> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>>>> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
>>>> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
>>>> is bound to a xen consumer then event generation is not allowed for that channel.
>>>> This check is to disallow a guest from raising an event via this channel. However,
>>>> it should allow Xen to send a event via this channel as it is required for sending
>>>> vpl011 event to the dom0.
>>>>
>>>> This change introduces a new function raw_evtchn_send() which sends the event
>>>> without this check. The current evtchn_send() calls this function after doing the
>>>> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
>>>> bypassing the check.
>>
>> Why would Xen want to send an event it is itself the consumer of?
>> Surely there are better ways to communicate state internally? The
>> more that you say you want the event sent to Dom0...
>>
> As a consumer, Xen receives event from dom0. It also needs to send
> events to dom0 to indicate that there is data in the ring buffer for
> dom0 to read. I am using a xen bound event channel for
> sending/receiving events to/from dom0. I added a new function
> raw_evtchn_send() to allow Xen to send events to dom0 without doing
> the is_xen_consumer check. Note that this check is still there in
> evtchn_send() to disallow guests to raise events on the xen bound
> channel.

I can see why Xen needs to send events; I can't see why Dom0 couldn't
simply make a hypercall instead of sending an event if it needs to signal
something.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-03-06 10:54         ` Jan Beulich
@ 2017-03-06 11:12           ` Bhupinder Thakur
  2017-03-28  9:43             ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-06 11:12 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, GeorgeDunlap, AndrewCooper,
	Ian Jackson, Tim Deegan, Julien Grall, xen-devel, nd

Hi,

On 6 March 2017 at 16:24, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 06.03.17 at 11:44, <bhupinder.thakur@linaro.org> wrote:
>> On 6 March 2017 at 13:45, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>> On 05.03.17 at 13:39, <julien.grall@arm.com> wrote:
>>>> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>>>>> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
>>>>> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
>>>>> is bound to a xen consumer then event generation is not allowed for that channel.
>>>>> This check is to disallow a guest from raising an event via this channel. However,
>>>>> it should allow Xen to send a event via this channel as it is required for sending
>>>>> vpl011 event to the dom0.
>>>>>
>>>>> This change introduces a new function raw_evtchn_send() which sends the event
>>>>> without this check. The current evtchn_send() calls this function after doing the
>>>>> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
>>>>> bypassing the check.
>>>
>>> Why would Xen want to send an event it is itself the consumer of?
>>> Surely there are better ways to communicate state internally? The
>>> more that you say you want the event sent to Dom0...
>>>
>> As a consumer, Xen receives event from dom0. It also needs to send
>> events to dom0 to indicate that there is data in the ring buffer for
>> dom0 to read. I am using a xen bound event channel for
>> sending/receiving events to/from dom0. I added a new function
>> raw_evtchn_send() to allow Xen to send events to dom0 without doing
>> the is_xen_consumer check. Note that this check is still there in
>> evtchn_send() to disallow guests to raise events on the xen bound
>> channel.
>
> I can see why Xen needs to send events; I can't see why Dom0 couldn't
> simply make a hypercall instead of sending an event if it needs to signal
> something.
>
We decided to reuse the same PV console interface for pl011 as used
for PV console in xenconsole running on dom0, which is events/ring
buffer based. From xenconsole point of view, there is no difference in
terms of handling a pl011 console and a PV console.

> Jan
>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-06  8:06     ` Jan Beulich
@ 2017-03-06 11:42       ` Julien Grall
  2017-03-06 12:41         ` Jan Beulich
  0 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-06 11:42 UTC (permalink / raw)
  To: Jan Beulich, Bhupinder Thakur
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, xen-devel, nd

Hi Jan,

On 06/03/17 08:06, Jan Beulich wrote:
>>>> On 05.03.17 at 13:35, <julien.grall@arm.com> wrote:
>> On 02/21/2017 11:25 AM, Bhupinder Thakur wrote:
>>> --- a/xen/include/public/hvm/params.h
>>> +++ b/xen/include/public/hvm/params.h
>>> @@ -203,10 +203,17 @@
>>>   */
>>>  #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
>>>
>>> -/* Deprecated */
>>> +#if defined(__arm__) || defined(__aarch64__)
>>> +#define HVM_PARAM_VPL011_CONSOLE_PFN    20
>>> +#define HVM_PARAM_VPL011_CONSOLE_EVTCHN 21
>>> +#define HVM_PARAM_VPL011_VIRQ           22
>>> +#else
>>>  #define HVM_PARAM_MEMORY_EVENT_CR0          20
>>>  #define HVM_PARAM_MEMORY_EVENT_CR3          21
>>>  #define HVM_PARAM_MEMORY_EVENT_CR4          22
>>
>> Those parameters are still deprecated but you drop the comment stating that.
>>
>>> +#endif
>>> +
>>
>> Those params are x86 specific so should have never been set on ARM. But
>> I am not sure if it is fine to re-purpose deprecated number.
>>
>> I have CCed "The REST" maintainers to have their input here.
>
> I think re-purposing something that was never (meant to be) used is
> fine in a case like this. However, the question is moot with your
> suggestion to not use params here in the first place.

I suggested to drop HVM_PARAM_VPL011_VIRQ because we can hardcode the 
guest interrupt number for the UART as we already do for the MMIO 
region. The 2 other HVM_PARAM looks sensible to me.

I thought a bit more about those params. I think the name should be 
generic and not tie to pl011 because we may want to emulate different 
UART for the guest in the future.

Also, by re-using deprecated encoding it means that it will not be 
possible to use those parameters on x86 if you ever decide to emulate 
UART in Xen. I am not sure whether if you are happy with that?

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-06 11:42       ` Julien Grall
@ 2017-03-06 12:41         ` Jan Beulich
  2017-03-06 13:21           ` Julien Grall
  0 siblings, 1 reply; 82+ messages in thread
From: Jan Beulich @ 2017-03-06 12:41 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Bhupinder Thakur, xen-devel, nd

>>> On 06.03.17 at 12:42, <julien.grall@arm.com> wrote:
> I thought a bit more about those params. I think the name should be 
> generic and not tie to pl011 because we may want to emulate different 
> UART for the guest in the future.

That's reasonable, but I continue to have reservations against the
underlying approach here, namely ...

> Also, by re-using deprecated encoding it means that it will not be 
> possible to use those parameters on x86 if you ever decide to emulate 
> UART in Xen. I am not sure whether if you are happy with that?

... with this in mind: If we wanted to do this for HVM guests, we'd
indeed want the parameters. If we wanted this for PV guests, the
model wouldn't fit at all.

Plus what I'm not understanding (perhaps because most of the
discussion around this seemed to be ARM-specific, and hence I've
skipped reading through it) is - why is this UART emulation needed
in the first place? We've never had a need for such on x86, afaia.

Furthermore - how does this scale? I.e. what if other devices pop
up wanting to be emulated? Or multiple UARTs?

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-06 12:41         ` Jan Beulich
@ 2017-03-06 13:21           ` Julien Grall
  2017-03-06 13:48             ` Jan Beulich
  2017-03-06 14:48             ` George Dunlap
  0 siblings, 2 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-06 13:21 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Bhupinder Thakur, xen-devel, nd

Hi Jan,

On 06/03/17 12:41, Jan Beulich wrote:
>>>> On 06.03.17 at 12:42, <julien.grall@arm.com> wrote:
>> I thought a bit more about those params. I think the name should be
>> generic and not tie to pl011 because we may want to emulate different
>> UART for the guest in the future.
>
> That's reasonable, but I continue to have reservations against the
> underlying approach here, namely ...
>
>> Also, by re-using deprecated encoding it means that it will not be
>> possible to use those parameters on x86 if you ever decide to emulate
>> UART in Xen. I am not sure whether if you are happy with that?
>
> ... with this in mind: If we wanted to do this for HVM guests, we'd
> indeed want the parameters. If we wanted this for PV guests, the
> model wouldn't fit at all.
>
> Plus what I'm not understanding (perhaps because most of the
> discussion around this seemed to be ARM-specific, and hence I've
> skipped reading through it) is - why is this UART emulation needed
> in the first place? We've never had a need for such on x86, afaia.

Linaro has published a set of guidelines to guarantee a same guest image 
can run on multiple hypervisors (see [1]). This specification mandates 
the presence of a SBSA-compliant UART.

I just realized the cover letter does not explain why we need to emulate 
a PL011 on ARM. Bhupinder can you detail it on the next version?

>
> Furthermore - how does this scale? I.e. what if other devices pop
> up wanting to be emulated? Or multiple UARTs?

I think you can appreciate that using QEMU for emulating an UART is 
quite overkill.

Also, we are expecting more people to look at providing mediation (such 
as Firmware access) within Xen as they are concerned about performance 
and certification.

An idea to ensure the integrity of Xen would be to run this code at a 
lower level.

Cheers,

[1] 
https://www.linaro.org/app/resources/WhitePaper/VMSystemSpecificationForARM-v2.0.pdf

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-06 13:21           ` Julien Grall
@ 2017-03-06 13:48             ` Jan Beulich
  2017-03-08 14:45               ` Julien Grall
  2017-03-06 14:48             ` George Dunlap
  1 sibling, 1 reply; 82+ messages in thread
From: Jan Beulich @ 2017-03-06 13:48 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Bhupinder Thakur, xen-devel, nd

>>> On 06.03.17 at 14:21, <julien.grall@arm.com> wrote:
> On 06/03/17 12:41, Jan Beulich wrote:
>> Furthermore - how does this scale? I.e. what if other devices pop
>> up wanting to be emulated? Or multiple UARTs?
> 
> I think you can appreciate that using QEMU for emulating an UART is 
> quite overkill.

Sure, but this doesn't answer my questions.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-05  1:04     ` Julien Grall
@ 2017-03-06 14:22       ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 82+ messages in thread
From: Konrad Rzeszutek Wilk @ 2017-03-06 14:22 UTC (permalink / raw)
  To: Julien Grall; +Cc: Bhupinder Thakur, xen-devel, nd, Stefano Stabellini

On Sun, Mar 05, 2017 at 01:04:54AM +0000, Julien Grall wrote:
> Hi Konrad,
> 
> On 03/03/2017 07:59 PM, Konrad Rzeszutek Wilk wrote:
> > > +}
> > > +
> > > +static int vpl011_data_avail(struct domain *d)
> > > +{
> > > +    int rc=0;
> > > +    unsigned long flags;
> > > +
> > > +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
> > 
> > Can you have an macro for this?
> > > +
> > > +    VPL011_LOCK(d, flags);
> > 
> > Please don't. Just use normal spin_lock invocation.
> 
> This is really a matter of taste. We've been using macro on the vgic
> emulation for the lock and I find it clearer and less error-prone. At least
> you are sure that all critical paths protected by the local will have IRQ
> disable.

OK. I am more of the other way, but then I can see the beaty of having
an macro that requires two parameters so there is no way to mess this
up.

Bhupinder, please ignore my request.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-06 13:21           ` Julien Grall
  2017-03-06 13:48             ` Jan Beulich
@ 2017-03-06 14:48             ` George Dunlap
  2017-03-08 13:52               ` Julien Grall
  1 sibling, 1 reply; 82+ messages in thread
From: George Dunlap @ 2017-03-06 14:48 UTC (permalink / raw)
  To: Julien Grall, Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Bhupinder Thakur, xen-devel, nd

On 06/03/17 13:21, Julien Grall wrote:
> Hi Jan,
> 
> On 06/03/17 12:41, Jan Beulich wrote:
>>>>> On 06.03.17 at 12:42, <julien.grall@arm.com> wrote:
>>> I thought a bit more about those params. I think the name should be
>>> generic and not tie to pl011 because we may want to emulate different
>>> UART for the guest in the future.
>>
>> That's reasonable, but I continue to have reservations against the
>> underlying approach here, namely ...
>>
>>> Also, by re-using deprecated encoding it means that it will not be
>>> possible to use those parameters on x86 if you ever decide to emulate
>>> UART in Xen. I am not sure whether if you are happy with that?
>>
>> ... with this in mind: If we wanted to do this for HVM guests, we'd
>> indeed want the parameters. If we wanted this for PV guests, the
>> model wouldn't fit at all.
>>
>> Plus what I'm not understanding (perhaps because most of the
>> discussion around this seemed to be ARM-specific, and hence I've
>> skipped reading through it) is - why is this UART emulation needed
>> in the first place? We've never had a need for such on x86, afaia.
> 
> Linaro has published a set of guidelines to guarantee a same guest image
> can run on multiple hypervisors (see [1]). This specification mandates
> the presence of a SBSA-compliant UART.
> 
> I just realized the cover letter does not explain why we need to emulate
> a PL011 on ARM. Bhupinder can you detail it on the next version?

Right, but in order to evaluate your question about whether we're
"happy" with not being able to use these parameters if we ever decide to
emulate UART on x86, we need to know a reason that one might decide to
add a UART *on x86*, not on ARM.

I mean, I don't think we're running out of bits, so I don't think it's a
problem allocating new HVM_PARAM numbers so that we can re-use them if
we ever decide to implement UARTs on x86.  On the other hand, given that
nobody has ever suggested doing so or knows why it might be useful,
maybe it makes more sense to just re-use some x86 params and allocate
extra numbers if / when we decide we want to implement UART on x86.

 -George


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-06 14:48             ` George Dunlap
@ 2017-03-08 13:52               ` Julien Grall
  0 siblings, 0 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-08 13:52 UTC (permalink / raw)
  To: George Dunlap, Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Bhupinder Thakur, xen-devel

Hi George,

On 06/03/17 14:48, George Dunlap wrote:
> On 06/03/17 13:21, Julien Grall wrote:
>> Hi Jan,
>>
>> On 06/03/17 12:41, Jan Beulich wrote:
>>>>>> On 06.03.17 at 12:42, <julien.grall@arm.com> wrote:
>>>> I thought a bit more about those params. I think the name should be
>>>> generic and not tie to pl011 because we may want to emulate different
>>>> UART for the guest in the future.
>>>
>>> That's reasonable, but I continue to have reservations against the
>>> underlying approach here, namely ...
>>>
>>>> Also, by re-using deprecated encoding it means that it will not be
>>>> possible to use those parameters on x86 if you ever decide to emulate
>>>> UART in Xen. I am not sure whether if you are happy with that?
>>>
>>> ... with this in mind: If we wanted to do this for HVM guests, we'd
>>> indeed want the parameters. If we wanted this for PV guests, the
>>> model wouldn't fit at all.
>>>
>>> Plus what I'm not understanding (perhaps because most of the
>>> discussion around this seemed to be ARM-specific, and hence I've
>>> skipped reading through it) is - why is this UART emulation needed
>>> in the first place? We've never had a need for such on x86, afaia.
>>
>> Linaro has published a set of guidelines to guarantee a same guest image
>> can run on multiple hypervisors (see [1]). This specification mandates
>> the presence of a SBSA-compliant UART.
>>
>> I just realized the cover letter does not explain why we need to emulate
>> a PL011 on ARM. Bhupinder can you detail it on the next version?
>
> Right, but in order to evaluate your question about whether we're
> "happy" with not being able to use these parameters if we ever decide to
> emulate UART on x86, we need to know a reason that one might decide to
> add a UART *on x86*, not on ARM.
>
> I mean, I don't think we're running out of bits, so I don't think it's a
> problem allocating new HVM_PARAM numbers so that we can re-use them if
> we ever decide to implement UARTs on x86.  On the other hand, given that
> nobody has ever suggested doing so or knows why it might be useful,
> maybe it makes more sense to just re-use some x86 params and allocate
> extra numbers if / when we decide we want to implement UART on x86.

I agree that the reason I gave is very ARM focused. I don't know what is 
the future on Xen for x86, but on ARM we have another potential use case 
for the UART emulation which I think could also apply for x86.

On ARM, the guest is booting through the same path as on native. All the 
devices are discovered through the firmware tables. So it would be 
possible to run a guest OS without any knowledge of Xen if you assign 
all the necessary physical devices (e.g disk, network, serial...). Often 
you want to log the console of all your guests and keep them safely in 
the controller domain. This is where an emulated UART can be useful, you 
don't need to add Xen drivers in the guest and still can use the guest 
seamlessly via xl.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-06 13:48             ` Jan Beulich
@ 2017-03-08 14:45               ` Julien Grall
  2017-03-08 15:21                 ` Jan Beulich
  0 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-08 14:45 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Bhupinder Thakur, xen-devel

Hi Jan,

On 06/03/17 13:48, Jan Beulich wrote:
>>>> On 06.03.17 at 14:21, <julien.grall@arm.com> wrote:
>> On 06/03/17 12:41, Jan Beulich wrote:
>>> Furthermore - how does this scale? I.e. what if other devices pop
>>> up wanting to be emulated? Or multiple UARTs?
>>
>> I think you can appreciate that using QEMU for emulating an UART is
>> quite overkill.
>
> Sure, but this doesn't answer my questions.

Devices we are planning to emulate are in order to be compliant with the 
SBSA. Looking at the spec, it requires:
	* SBSA UART
	* RTC: It is expected to drive through EFI API but we may want to also 
support in non-UEFI case.
	* Persistent environment storage: This is only required for the UEFI.

Another device we are expecting to emulate in Xen is the PCI root 
complex in order to avoid as much as PV drivers for the guest.

So I think we would need to emulate 3 devices: SBSA UART, RTC and root 
complex.

I cannot predict what will happen in the future, but I would expect the 
number of devices we require to emulate very limited.

Regarding the multiple UARTs, you have a point here. The code in itself 
could handle any number of UARTs easily, but we thought that guest will 
usually use only one console.

I was looking at the backend code and see it is using DOMCTL command. I 
guess it is considered that the console backend will be tied to a 
specific Xen version. Am I correct?

so maybe we can introduce new domctl command for handling vUART. This 
would avoid us to commit on an ABI and allow us to extend it if 
necessary in the future to support multiple UARTs.

Any opinions?

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-08 14:45               ` Julien Grall
@ 2017-03-08 15:21                 ` Jan Beulich
  2017-03-08 18:22                   ` Stefano Stabellini
  0 siblings, 1 reply; 82+ messages in thread
From: Jan Beulich @ 2017-03-08 15:21 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Bhupinder Thakur, xen-devel

>>> On 08.03.17 at 15:45, <julien.grall@arm.com> wrote:
> I was looking at the backend code and see it is using DOMCTL command. I 
> guess it is considered that the console backend will be tied to a 
> specific Xen version. Am I correct?

I don't think I'm qualified to talk about the console backend
implementation (and possible quirks it has). Generally I'd expect
backends not to use domctl-s, as that would tie them to the tool
stack domain.

> so maybe we can introduce new domctl command for handling vUART. This 
> would avoid us to commit on an ABI and allow us to extend it if 
> necessary in the future to support multiple UARTs.

Well, without having the context of who it would be to use such a
domctl (and for what purpose) I don#t think I can comment here.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-08 15:21                 ` Jan Beulich
@ 2017-03-08 18:22                   ` Stefano Stabellini
  2017-04-11 14:38                     ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Stefano Stabellini @ 2017-03-08 18:22 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Julien Grall, Bhupinder Thakur,
	xen-devel

On Wed, 8 Mar 2017, Jan Beulich wrote:
> >>> On 08.03.17 at 15:45, <julien.grall@arm.com> wrote:
> > I was looking at the backend code and see it is using DOMCTL command. I 
> > guess it is considered that the console backend will be tied to a 
> > specific Xen version. Am I correct?
> 
> I don't think I'm qualified to talk about the console backend
> implementation (and possible quirks it has). Generally I'd expect
> backends not to use domctl-s, as that would tie them to the tool
> stack domain.
> 
> > so maybe we can introduce new domctl command for handling vUART. This 
> > would avoid us to commit on an ABI and allow us to extend it if 
> > necessary in the future to support multiple UARTs.
> 
> Well, without having the context of who it would be to use such a
> domctl (and for what purpose) I don#t think I can comment here.

I guess the assumption was that xenconsoled was part of the Xen tools.
Indeed, it is part of the tools and is installed as such.

I don't have an opinion on this. If introducing a new DOMCTL makes the
code nicer in xen and xenconsoled, taking away some edges, like the
changes to evtchn_send, then we should probably just do it.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 00/11] pl011 emulation support in Xen
  2017-03-03 20:23 ` [PATCH 00/11] pl011 emulation support in Xen Konrad Rzeszutek Wilk
  2017-03-03 21:15   ` Konrad Rzeszutek Wilk
@ 2017-03-14  7:44   ` Bhupinder Thakur
  1 sibling, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-14  7:44 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk; +Cc: xen-devel, Julien Grall, Stefano Stabellini

Hi,

Thanks for your comments.

On 3 March 2017 at 21:23, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> wrote:
>> The following changes were done:
>
> .. snip..
>
> Thank you for this great writeup. I took a stab at it and stopped at patch
> #2 b/c Julien said he would look in it deeper. But based on a brief
> look I would say:
>  - Please do remove most of the comments. They really do not add
>    much context besides describing the code - and we all can
>    read the code. The idea behind the comments is to describe some
>    semantics of it, or something that is not obvious at first or
>    such. Not the code.
I will remove the comments where not required.

>
>  - Comments. One line comments are:
>   /* Comment. */
>    And please do use proper case and a period.
>
I will correct the comments.

>  - Be careful about compiler optimizations and jump tables.
>    Specifically see https://xenbits.xen.org/xsa/advisory-155.html
>    The way to make sure you don't introduce an security problem
>    is to 1) use local variables 2) read once from the ring and
>    make sure you use a compiler barrier.
>
will check the guidelines.

>  - There is also some unrelated changes. Like extra newlines. One
>    way to avoid this is to send all your patches _just_ to yourself
>    and review them - but review them in reverse order and from the
>    bottom of the emails to the top. That way you can catch some of this.
>
>  - Think in terms of how one would break this. For example the guest
>    could change the HVM parameters (or maybe not?) - or find the
>    console ring and muck with the ring indexes. You need to shield
>    the code from such changes.
>
I plan to add the checks that the HVM params can only be accessed from
a privileged guest.

> Thanks!

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 00/11] pl011 emulation support in Xen
  2017-03-05 11:46 ` Julien Grall
@ 2017-03-14  7:47   ` Bhupinder Thakur
  0 siblings, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-14  7:47 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, nd, Stefano Stabellini

Hi,


On 5 March 2017 at 12:46, Julien Grall <julien.grall@arm.com> wrote:
> Hi Bhupinder,
>
> On 02/21/2017 11:25 AM, Bhupinder Thakur wrote:
>>
>> There are still some items which are pending:
>>
>> 1. Adding dynamic enable/disable of pl011 emulation for a guest
>> 2. Add a new console type "pl011" in xenconsoled to allow the user to
>> connect to
>> either PV/serial/pl011 console.
>> 3. Add checks to ensure that the new hvm params read/written by the guest
>
>
> A couple of recommendations regarding the series:
>         - All maintainers of the code you touch in a patch should be CCed.
> You can use scripts/get_maintainters.pl for that.

I will run the script before sending the patches.

>         - Providing a git branch with your code will allow people to test
> your code without handling potential rebasing.
>
I plan to check-in the code in a linaro git repository and will share
the branch information in the next patch.

> Cheers,
>
> --
> Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack
  2017-03-05 13:04   ` Julien Grall
@ 2017-03-14 13:00     ` Wei Liu
  0 siblings, 0 replies; 82+ messages in thread
From: Wei Liu @ 2017-03-14 13:00 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, Wei Liu, Ian Jackson, Bhupinder Thakur,
	xen-devel, nd

On Sun, Mar 05, 2017 at 01:04:07PM +0000, Julien Grall wrote:
> Hi Bhupinder,
> 
> CC toolstack maintainers.
> 
> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
> > Add a new pl011 uart node
> >     - Get the pl011 spi virq from Xen using a hvm call
> 
> See my comment on previous patches.
> 
> >     - Add a new device tree node in the guest DT for SBSA pl011 uart containing the IRQ
> >       (read above) and the MMIO address range to be used by the guest
> > 
> > The format for the node is specified in Documentation/devicetree/bindings/serial/arm_sbsa_uart.txt.
> 
> The ordering of the patches in this series is a bit weird. You are exposing
> the pl011 to the guest before all the code to handle it is there. This patch
> should likely be at the end of this series.
> 
> Also, you want a libxl option to allow the user enabling/disable pl011
> emulation. We likely want this emulation disable by default.
> 

Yes, I concur.

> > 
> > Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
> > ---
> >  tools/libxl/libxl_arm.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 45 insertions(+), 2 deletions(-)
> > 
> > diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
> > index d842d88..34c7e39 100644
> > --- a/tools/libxl/libxl_arm.c
> > +++ b/tools/libxl/libxl_arm.c
> > @@ -130,9 +130,10 @@ static struct arch_info {
> >      const char *guest_type;
> >      const char *timer_compat;
> >      const char *cpu_compat;
> > +    const char *uart_compat;
> >  } arch_info[] = {
> > -    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15" },
> > -    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8" },
> > +    {"xen-3.0-armv7l",  "arm,armv7-timer", "arm,cortex-a15", "arm,sbsa-uart" },
> > +    {"xen-3.0-aarch64", "arm,armv8-timer", "arm,armv8", "arm,sbsa-uart" },
> >  };
> > 
> >  /*
> > @@ -590,6 +591,38 @@ static int make_hypervisor_node(libxl__gc *gc, void *fdt,
> >      return 0;
> >  }
> > 
> > +static int make_vpl011_uart_node(libxl__gc *gc, void *fdt,
> > +                           const struct arch_info *ainfo,
> > +                           struct xc_dom_image *dom, uint64_t irq)
> 
> Why uint64_t for irq?
> 
> > +{
> > +    int res;
> > +    gic_interrupt intr;
> > +
> > +    res = fdt_begin_node(fdt, "sbsa-pl011");
> > +    if (res) return res;
> > +
> > +    res = fdt_property_compat(gc, fdt, 1, ainfo->uart_compat);
> > +    if (res) return res;
> > +
> > +    res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
> > +                            1,
> > +                            GUEST_PL011_BASE, GUEST_PL011_SIZE);
> > +    if (res)
> > +        return res;
> > +
> > +    set_interrupt(intr, irq, 0xf, DT_IRQ_TYPE_LEVEL_HIGH);
> > +
> > +    res = fdt_property_interrupts(gc, fdt, &intr, 1);
> > +    if (res) return res;
> > +
> > +    fdt_property_u32(fdt, "current-speed", 115200);
> > +
> > +    res = fdt_end_node(fdt);
> > +    if (res) return res;
> > +
> > +    return 0;
> > +}
> > +
> >  static const struct arch_info *get_arch_info(libxl__gc *gc,
> >                                               const struct xc_dom_image *dom)
> >  {
> > @@ -790,6 +823,7 @@ static int libxl__prepare_dtb(libxl__gc *gc, libxl_domain_build_info *info,
> >      int rc, res;
> >      size_t fdt_size = 0;
> >      int pfdt_size = 0;
> > +    uint64_t vpl011_irq=0;

Spaces around "=" please.

> > 
> >      const libxl_version_info *vers;
> >      const struct arch_info *ainfo;
> > @@ -889,6 +923,13 @@ next_resize:
> >          FDT( make_timer_node(gc, fdt, ainfo, xc_config->clock_frequency) );
> >          FDT( make_hypervisor_node(gc, fdt, vers) );
> > 
> > +        /*
> > +         * get the vpl011 VIRQ and use it for creating a vpl011 node entry
> > +         */
> > +        if ( !xc_hvm_param_get(dom->xch, dom->guest_domid, HVM_PARAM_VPL011_VIRQ,
> > +                                                               &vpl011_irq) )
> > +            FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom, vpl011_irq) );
> > +

Coding style is wrong.

> >          if (pfdt)
> >              FDT( copy_partial_fdt(gc, fdt, pfdt) );
> > 
> > @@ -933,9 +974,11 @@ int libxl__arch_domain_init_hw_description(libxl__gc *gc,
> >      val |= GUEST_EVTCHN_PPI;
> >      rc = xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CALLBACK_IRQ,
> >                            val);
> > +

Stray blank line.

> >      if (rc)
> >          return rc;
> > 
> > +

Ditto.

Please check libxl/CODING_STYLE and avoid unrelated changes.

Wei.

> >      rc = libxl__prepare_dtb(gc, info, state, dom);
> >      if (rc) goto out;
> > 
> > 
> 
> Cheers,
> 
> -- 
> Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-03-05 12:51   ` Julien Grall
@ 2017-03-16  6:50     ` Bhupinder Thakur
  2017-03-16  8:24       ` Julien Grall
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-16  6:50 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, nd, Stefano Stabellini

Hi,

On 5 March 2017 at 13:51, Julien Grall <julien.grall@arm.com> wrote:
> Hi Bhupinder,
>
> Commit title: s/atleat/at least/
>
> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>>
>> Ensure that nr_spis intialized in in vgic_init is atleast 1 to allow
>> allocation of
>
>
> s/intialized/initialized/ and again s/atleast/at least/
>
>> pl011 spi virq.
>>
>> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
>> ---
>>  xen/arch/arm/vgic.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>> index 364d5f0..614b3ec 100644
>> --- a/xen/arch/arm/vgic.c
>> +++ b/xen/arch/arm/vgic.c
>> @@ -121,6 +121,11 @@ int domain_vgic_init(struct domain *d, unsigned int
>> nr_spis)
>>      /* Limit the number of virtual SPIs supported to (1020 - 32) = 988
>> */
>>      if ( nr_spis > (1020 - NR_LOCAL_IRQS) )
>>          return -EINVAL;
>> +#ifdef CONFIG_VPL011_CONSOLE
>> +    /* Atleast 1 spi should be available for assigning to vpl011 */
>> +    else if ( nr_spis < (1020 - NR_LOCAL_IRQS) )
>> +        nr_spis += 1;
>> +#endif
>
>
> Please don't do that. The toolstack should allocated the correct number of
> SPIs depending on the configuration of the guest.
>
Currently there is one parameter "irqs", which can be specified in the
guest configuration file to specify the list of physical irqs allowed
to a guest. The nr_spis is set to the maximum value of the irq
specified in the irqs list. Can I use this parameter to specify the
irq for pl011? I think not because this parameter is related to
physical irqs to be allowed to a guest.

The other option is to reserve a SPI for pl011 at compile time and use
that value. Let me know.

> Cheers,
>
> --
> Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-03-16  6:50     ` Bhupinder Thakur
@ 2017-03-16  8:24       ` Julien Grall
  2017-03-16 10:31         ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-16  8:24 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

On 03/16/2017 06:50 AM, Bhupinder Thakur wrote:
> Hi,

Hi Bhupinder,

> On 5 March 2017 at 13:51, Julien Grall <julien.grall@arm.com> wrote:
>> Hi Bhupinder,
>>
>> Commit title: s/atleat/at least/
>>
>> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>>>
>>> Ensure that nr_spis intialized in in vgic_init is atleast 1 to allow
>>> allocation of
>>
>>
>> s/intialized/initialized/ and again s/atleast/at least/
>>
>>> pl011 spi virq.
>>>
>>> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
>>> ---
>>>  xen/arch/arm/vgic.c | 5 +++++
>>>  1 file changed, 5 insertions(+)
>>>
>>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>>> index 364d5f0..614b3ec 100644
>>> --- a/xen/arch/arm/vgic.c
>>> +++ b/xen/arch/arm/vgic.c
>>> @@ -121,6 +121,11 @@ int domain_vgic_init(struct domain *d, unsigned int
>>> nr_spis)
>>>      /* Limit the number of virtual SPIs supported to (1020 - 32) = 988
>>> */
>>>      if ( nr_spis > (1020 - NR_LOCAL_IRQS) )
>>>          return -EINVAL;
>>> +#ifdef CONFIG_VPL011_CONSOLE
>>> +    /* Atleast 1 spi should be available for assigning to vpl011 */
>>> +    else if ( nr_spis < (1020 - NR_LOCAL_IRQS) )
>>> +        nr_spis += 1;
>>> +#endif
>>
>>
>> Please don't do that. The toolstack should allocated the correct number of
>> SPIs depending on the configuration of the guest.
>>
> Currently there is one parameter "irqs", which can be specified in the
> guest configuration file to specify the list of physical irqs allowed
> to a guest. The nr_spis is set to the maximum value of the irq
> specified in the irqs list. Can I use this parameter to specify the
> irq for pl011? I think not because this parameter is related to
> physical irqs to be allowed to a guest.

nr_spis in the DOMCTL create domain indicates the number of SPIs that 
will be available in the GIC emulation and exposed to the guest via 
GICD_TYPER. The virtual SPIs will be routed in a second step (see 
DOMCTL_bind_pt_irq.

>
> The other option is to reserve a SPI for pl011 at compile time and use
> that value. Let me know.

Whilst I am ok to have the pl011 SPI number hardcoded, I don't like the 
approach taken in this patch because the toolstack is in charge of the 
guest layout (interrupt, memory...) and not the hypervisor.

The values are hardcoded today because we decided to do a fix layout for 
simplicity. It is likely to be changed in the future.

The toolstack knows how much memory the user requested, the list of 
devices available... So it is the goal of the toolstack to bump the 
number of SPIs before creating the domain if a PL011 will be exposed.

Also, the interaction between the pl011 and the parameter "irqs" in the 
domain configuration file will need to be documented. By that I mean 
explaining from which number the SPIs will be allocated when choosing a 
pl011 enabling.

Note the probably want to allow the user to choose the pl011 IRQ and 
MMIO region. If he doesn't provide any, we would use the default value.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-03-16  8:24       ` Julien Grall
@ 2017-03-16 10:31         ` Bhupinder Thakur
  2017-03-16 13:24           ` Julien Grall
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-16 10:31 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, nd, Stefano Stabellini

On 16 March 2017 at 13:54, Julien Grall <julien.grall@arm.com> wrote:
>>
>> The other option is to reserve a SPI for pl011 at compile time and use
>> that value. Let me know.
>
>
> Whilst I am ok to have the pl011 SPI number hardcoded, I don't like the
> approach taken in this patch because the toolstack is in charge of the guest
> layout (interrupt, memory...) and not the hypervisor.
>
> The values are hardcoded today because we decided to do a fix layout for
> simplicity. It is likely to be changed in the future.
>
> The toolstack knows how much memory the user requested, the list of devices
> available... So it is the goal of the toolstack to bump the number of SPIs
> before creating the domain if a PL011 will be exposed.
>
> Also, the interaction between the pl011 and the parameter "irqs" in the
> domain configuration file will need to be documented. By that I mean
> explaining from which number the SPIs will be allocated when choosing a
> pl011 enabling.
>
> Note the probably want to allow the user to choose the pl011 IRQ and MMIO
> region. If he doesn't provide any, we would use the default value.
>
> Cheers,

We can follow the convention that when pl011 is enabled then the last
irq in the "irqs" list will be used as the pl011 irq. I believe that
the irqs mentioned in the "irqs" list will be reserved by the
hypervisor when the domain is created and we need not allocate a SPI
separately as we are doing currently.

One more parameter will be added "pl011" in the configuration to
indicate whether pl011 is enabled or not. By default it will disabled.

With this change, we can remove the pl011 virq HVM parameter.

Regards,
Bhupinder

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-03-16 10:31         ` Bhupinder Thakur
@ 2017-03-16 13:24           ` Julien Grall
  2017-03-20 16:29             ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-16 13:24 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, Stefano Stabellini

Hi Bhupinder,

On 03/16/2017 10:31 AM, Bhupinder Thakur wrote:
> On 16 March 2017 at 13:54, Julien Grall <julien.grall@arm.com> wrote:
>>>
>>> The other option is to reserve a SPI for pl011 at compile time and use
>>> that value. Let me know.
>>
>>
>> Whilst I am ok to have the pl011 SPI number hardcoded, I don't like the
>> approach taken in this patch because the toolstack is in charge of the guest
>> layout (interrupt, memory...) and not the hypervisor.
>>
>> The values are hardcoded today because we decided to do a fix layout for
>> simplicity. It is likely to be changed in the future.
>>
>> The toolstack knows how much memory the user requested, the list of devices
>> available... So it is the goal of the toolstack to bump the number of SPIs
>> before creating the domain if a PL011 will be exposed.
>>
>> Also, the interaction between the pl011 and the parameter "irqs" in the
>> domain configuration file will need to be documented. By that I mean
>> explaining from which number the SPIs will be allocated when choosing a
>> pl011 enabling.
>>
>> Note the probably want to allow the user to choose the pl011 IRQ and MMIO
>> region. If he doesn't provide any, we would use the default value.
>>
>> Cheers,
>
> We can follow the convention that when pl011 is enabled then the last
> irq in the "irqs" list will be used as the pl011 irq. I believe that
> the irqs mentioned in the "irqs" list will be reserved by the
> hypervisor when the domain is created and we need not allocate a SPI
> separately as we are doing currently.

I don't understand what you mean here. If you speak about the xl 
parameter "irqs", it is a list of physical IRQs and not virtual IRQs. 
Furthermore, we would like to keep to avoid a normal user to do more 
than specifying "pl011" or else on in the guest configuration file.

So could you clarify what you mean?

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1
  2017-03-16 13:24           ` Julien Grall
@ 2017-03-20 16:29             ` Bhupinder Thakur
  0 siblings, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-20 16:29 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, Stefano Stabellini

On 16 March 2017 at 18:54, Julien Grall <julien.grall@arm.com> wrote:
> Hi Bhupinder,
>
> On 03/16/2017 10:31 AM, Bhupinder Thakur wrote:
>>
>> On 16 March 2017 at 13:54, Julien Grall <julien.grall@arm.com> wrote:
>>>>
>>>>
>>>> The other option is to reserve a SPI for pl011 at compile time and use
>>>> that value. Let me know.
>>>
>>>
>>>
>>> Whilst I am ok to have the pl011 SPI number hardcoded, I don't like the
>>> approach taken in this patch because the toolstack is in charge of the
>>> guest
>>> layout (interrupt, memory...) and not the hypervisor.
>>>
>>> The values are hardcoded today because we decided to do a fix layout for
>>> simplicity. It is likely to be changed in the future.
>>>
>>> The toolstack knows how much memory the user requested, the list of
>>> devices
>>> available... So it is the goal of the toolstack to bump the number of
>>> SPIs
>>> before creating the domain if a PL011 will be exposed.
>>>
>>> Also, the interaction between the pl011 and the parameter "irqs" in the
>>> domain configuration file will need to be documented. By that I mean
>>> explaining from which number the SPIs will be allocated when choosing a
>>> pl011 enabling.
>>>
>>> Note the probably want to allow the user to choose the pl011 IRQ and MMIO
>>> region. If he doesn't provide any, we would use the default value.
>>>
>>> Cheers,
>>
>>
>> We can follow the convention that when pl011 is enabled then the last
>> irq in the "irqs" list will be used as the pl011 irq. I believe that
>> the irqs mentioned in the "irqs" list will be reserved by the
>> hypervisor when the domain is created and we need not allocate a SPI
>> separately as we are doing currently.
>
>
> I don't understand what you mean here. If you speak about the xl parameter
> "irqs", it is a list of physical IRQs and not virtual IRQs. Furthermore, we
> would like to keep to avoid a normal user to do more than specifying "pl011"
> or else on in the guest configuration file.
>
> So could you clarify what you mean?
>

Now, I am taking one option in the domU configuration file which tells
whether pl011 emulation is enabled or not. Based on this option, the
tool stack will increment the nr_spis (i have removed the nr_spis
increment logic from the hypervisor code). It will create the pl011 DT
node also based on whether this option is enabled.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-02-26 21:37   ` Julien Grall
  2017-03-03 19:19     ` Julien Grall
@ 2017-03-21 13:27     ` Bhupinder Thakur
  2017-03-21 19:38       ` Julien Grall
  1 sibling, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-21 13:27 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, nd, Stefano Stabellini

Hi Julien,

On 26 February 2017 at 22:37, Julien Grall <julien.grall@arm.com> wrote:
>> +
>> +#include <xen/config.h>
>
>
> xen/config.h is included by default. Please drop it.
Removed.

>
>> +#include <xen/init.h>
>> +#include <xen/lib.h>
>> +#include <xen/errno.h>
>> +#include <xen/guest_access.h>
>> +#include <xen/sched.h>
>> +#include <xen/monitor.h>
>
>
> Why do you need to include monitor.h?
>
>> +#include <xen/event.h>
>> +#include <xen/vmap.h>
>> +
>> +#include <xsm/xsm.h>
>
>
> Ditto.
>
>> +
>> +#include <public/xen.h>
>> +#include <public/hvm/params.h>
>> +#include <public/hvm/hvm_op.h>
>> +
>> +#include <asm/hypercall.h>
>
>
> Ditto.
>
I have removed the unncessary includes. I probably added them when I
initially created the file.

>> +#include "vpl011.h"
>> +
>> +static int vpl011_mmio_read(struct vcpu *v, mmio_info_t *info, register_t
>> *r, void *priv)
>> +{
>> +    unsigned char ch;
>> +
>> +    switch (info->gpa - GUEST_PL011_BASE)
>
>
> Coding style:
>
> switch ( ... )
>
>> +    {
>> +        case VPL011_UARTCR_OFFSET:
>
>
> Coding style: the case should be aligned to {. E.g
>
> {
> case ...
>
Switch/case style corrected.

> Also, I would prefer if you don't include _OFFSET in all the name.
>
Removed the _OFFSET.

> Furthermore, can you please order the case by offset in the MMIO region.
> This would help to find if a register has been emulated or not.
>
Ordered the offsets in increasing order.

> Lastly, the user may have requested to read 8-bit, 16-bit, 32-bit. But you
> always return a 32-bit. Is a guest allowed to access using any size and in
> the middle of a register? Give a look on what is done for vgic-v{2,3}.c to
> check the size and read register. You may want to pull some code out to
> re-use here.
>
>> +            *r = v->domain->arch.vpl011.control;
>
>
> Similarly, I would prefer if the name of the field match the register name.
>
Renamed the vpl011 fields match the corresponding register names.

>> +            break;
>> +        case VPL011_UARTDR_OFFSET:
>> +            vpl011_read_data(v->domain, &ch);
>
>
> Should not you check the return value of vpl011_read_data? Also, what if
> there is no data?
This condition should not happen because the RX FIFO empty bit would
be set in the UARTFR register when the last data is read from the ring
buffer and the the guest is not supposed to issue next read until the
RX FIFO empty bit is cleared indicating there is more data now.

>
>> +            *r = ch;
>> +            break;
>> +        case VPL011_UARTFR_OFFSET:
>> +            *r = v->domain->arch.vpl011.flag;
>
>
> I am fairly surprised that none of this code is actually protected by lock.
> For instance the update of flag is not atomic. So is it safe?
For reading, I thought no locking was required, as I believe a 32-bit
value read/write on ARM should be atomic. So if the value is modified
in some other context while it is being read in another context, the
reader should see either the old value or the new value.
For register writes, yes I need to take a lock where I am updating
certain bits in the register. I will add the locking there.

>
>> +            break;
>> +        case VPL011_UARTIMSC_OFFSET:
>> +            *r = v->domain->arch.vpl011.intr_mask;
>> +            break;
>> +        case VPL011_UARTICR_OFFSET:
>> +            *r = 0;
>
>
> Looking at the spec, this register is write-only. So why do you implement
> RAZ?
In such cases, where the guest tries to write to RO register or tries
to read a WO register, should I send a abort to the guest?

>
>> +            break;
>> +        case VPL011_UARTRIS_OFFSET:
>> +            *r = v->domain->arch.vpl011.raw_intr_status;
>> +            break;
>> +        case VPL011_UARTMIS_OFFSET:
>> +            *r = v->domain->arch.vpl011.raw_intr_status &
>> +                                v->domain->arch.vpl011.intr_mask;
>> +            break;
>> +        case VPL011_UARTDMACR_OFFSET:
>> +            *r = 0; /* uart DMA is not supported. Here it always returns
>> 0 */
>
>
> My understanding of the spec is DMA is not optional. So what would happen if
> the guest tries to enable it?
>
>> +            break;
>> +        case VPL011_UARTRSR_OFFSET:
>> +            *r = 0; /* it always returns 0 as there are no physical
>> errors */
>
>
> This register contains contains the bit OE that tells whether the FIFO is
> full or not. The FIFO here is the PV ring, so maybe we should set this bit
> if the ring is full.
The OE condition will not happen in this case since xenconsole will
not write more data to the guest if the ring buffer is full. There is
a separate UARTFR status bit which indicates whether the ring buffer
is full.

>
>> +            break;
>> +        default:
>> +            printk ("vpl011_mmio_read: invalid switch case %d\n",
>> (int)(info->gpa - GUEST_PL011_BASE));
>
>
> Coding style: printk(...).
>
> Also, printk is not ratelimited by default. Please use gprintk(...) which
> will be ratelimited and print the domain information. This is useful when
> you have multiple guest.
>
Replaced printk with gprintk.

>> +            break;
>> +    }
>> +
>> +    return VPL011_EMUL_OK;
>
>
> Please use plain value as the return is not pl011 specific. Also, I am a bit
> surprised that you return "ok" even when a register as not been emulated.
> IHMO, a data abort should be sent to the guest.

Corrected this. Now it returns an error incase the register is not
emulated . For the return values, I see that typically values 1/0 are
returned like in vgic-v2/3.c. Are there some common macros which I can
use?

>
> Furthermore, looking at the overall function, I think it should be better if
> you re-use the template used by the other emulation (see vgic-v2.c) for
> instance. They have labels that helps to know what's going on.
>
> I will stop here in the review for today and will comment the rest tomorrow.
>
> Cheers,

Regards,
Bhupinder

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-21 13:27     ` Bhupinder Thakur
@ 2017-03-21 19:38       ` Julien Grall
  2017-03-23  9:44         ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-21 19:38 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

On 03/21/2017 01:27 PM, Bhupinder Thakur wrote:
> Hi Julien,

Hi Bhupinder,

> On 26 February 2017 at 22:37, Julien Grall <julien.grall@arm.com> wrote:
>>> +            break;
>>> +        case VPL011_UARTDR_OFFSET:
>>> +            vpl011_read_data(v->domain, &ch);
>>
>>
>> Should not you check the return value of vpl011_read_data? Also, what if
>> there is no data?
> This condition should not happen because the RX FIFO empty bit would
> be set in the UARTFR register when the last data is read from the ring
> buffer and the the guest is not supposed to issue next read until the
> RX FIFO empty bit is cleared indicating there is more data now.

What you describe is how a well-behave guest will interact with the 
pl011 emulation. It does not describe what would happen if a misbehaved 
guest will read continuously the register.

I cannot find any things in the spec about what should be the state of 
the register if no data is available. So I guess we just need to ensure 
that we don't leak in information from the stack. This seems to be 
addressed by *data = 0 in "vpl011_read_data".

Please document it to avoid removing it by mistake in the future.

>
>>
>>> +            *r = ch;
>>> +            break;
>>> +        case VPL011_UARTFR_OFFSET:
>>> +            *r = v->domain->arch.vpl011.flag;
>>
>>
>> I am fairly surprised that none of this code is actually protected by lock.
>> For instance the update of flag is not atomic. So is it safe?
> For reading, I thought no locking was required, as I believe a 32-bit
> value read/write on ARM should be atomic. So if the value is modified
> in some other context while it is being read in another context, the
> reader should see either the old value or the new value.
> For register writes, yes I need to take a lock where I am updating
> certain bits in the register. I will add the locking there.

Fair point. I was more worry about ordering between read/write between 
multiple vCPU. But I guess we don't care if the read does not return an 
update to date value.

>
>>
>>> +            break;
>>> +        case VPL011_UARTIMSC_OFFSET:
>>> +            *r = v->domain->arch.vpl011.intr_mask;
>>> +            break;
>>> +        case VPL011_UARTICR_OFFSET:
>>> +            *r = 0;
>>
>>
>> Looking at the spec, this register is write-only. So why do you implement
>> RAZ?
> In such cases, where the guest tries to write to RO register or tries
> to read a WO register, should I send a abort to the guest?

I don't see any behavior requirement in the spec. So I would send an 
abort to the guest (e.g return 0 in the function).

>>
>>> +            break;
>>> +        case VPL011_UARTRIS_OFFSET:
>>> +            *r = v->domain->arch.vpl011.raw_intr_status;
>>> +            break;
>>> +        case VPL011_UARTMIS_OFFSET:
>>> +            *r = v->domain->arch.vpl011.raw_intr_status &
>>> +                                v->domain->arch.vpl011.intr_mask;
>>> +            break;
>>> +        case VPL011_UARTDMACR_OFFSET:
>>> +            *r = 0; /* uart DMA is not supported. Here it always returns
>>> 0 */
>>
>>
>> My understanding of the spec is DMA is not optional. So what would happen if
>> the guest tries to enable it?
>>
>>> +            break;
>>> +        case VPL011_UARTRSR_OFFSET:
>>> +            *r = 0; /* it always returns 0 as there are no physical
>>> errors */
>>
>>
>> This register contains contains the bit OE that tells whether the FIFO is
>> full or not. The FIFO here is the PV ring, so maybe we should set this bit
>> if the ring is full.
> The OE condition will not happen in this case since xenconsole will
> not write more data to the guest if the ring buffer is full. There is
> a separate UARTFR status bit which indicates whether the ring buffer
> is full.

Sorry I still don't get it. Xenconsole will likely have to hold 
characters that are not written in the PV console. I would have expected 
that this would be used to set the OE bit. Did I miss anything?

>>
>>> +            break;
>>> +        default:
>>> +            printk ("vpl011_mmio_read: invalid switch case %d\n",
>>> (int)(info->gpa - GUEST_PL011_BASE));
>>
>>
>> Coding style: printk(...).
>>
>> Also, printk is not ratelimited by default. Please use gprintk(...) which
>> will be ratelimited and print the domain information. This is useful when
>> you have multiple guest.
>>
> Replaced printk with gprintk.
>
>>> +            break;
>>> +    }
>>> +
>>> +    return VPL011_EMUL_OK;
>>
>>
>> Please use plain value as the return is not pl011 specific. Also, I am a bit
>> surprised that you return "ok" even when a register as not been emulated.
>> IHMO, a data abort should be sent to the guest.
>
> Corrected this. Now it returns an error incase the register is not
> emulated . For the return values, I see that typically values 1/0 are
> returned like in vgic-v2/3.c. Are there some common macros which I can
> use?

No. I want to replace 0/1 by false/true but I never had the time to do 
the work.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-03 19:59   ` Konrad Rzeszutek Wilk
                       ` (2 preceding siblings ...)
  2017-03-05 11:59     ` Julien Grall
@ 2017-03-22  5:50     ` Bhupinder Thakur
  3 siblings, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-22  5:50 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk; +Cc: xen-devel, Julien Grall, Stefano Stabellini

Hi Konrad,

On 4 March 2017 at 01:29, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> wrote:
> .snip..
>> +        case VPL011_UARTCR_OFFSET:
>> +            *r = v->domain->arch.vpl011.control;
>> +            break;
>
> Pls add a new newline after each break.
Ok.

>
>> +        case VPL011_UARTDR_OFFSET:
>> +            vpl011_read_data(v->domain, &ch);
>> +            *r = ch;
>> +            break;
>> +        case VPL011_UARTFR_OFFSET:
>> +            *r = v->domain->arch.vpl011.flag;
>> +            break;
>> +        case VPL011_UARTIMSC_OFFSET:
>> +            *r = v->domain->arch.vpl011.intr_mask;
>> +            break;
>> +        case VPL011_UARTICR_OFFSET:
>> +            *r = 0;
>> +            break;
>> +        case VPL011_UARTRIS_OFFSET:
>> +            *r = v->domain->arch.vpl011.raw_intr_status;
>> +            break;
>> +        case VPL011_UARTMIS_OFFSET:
>> +            *r = v->domain->arch.vpl011.raw_intr_status &
>> +                                v->domain->arch.vpl011.intr_mask;
>> +            break;
>> +        case VPL011_UARTDMACR_OFFSET:
>> +            *r = 0; /* uart DMA is not supported. Here it always returns 0 */
>> +            break;
>> +        case VPL011_UARTRSR_OFFSET:
>> +            *r = 0; /* it always returns 0 as there are no physical errors */
>> +            break;
>> +        default:
>> +            printk ("vpl011_mmio_read: invalid switch case %d\n", (int)(info->gpa - GUEST_PL011_BASE));
>
> .. and you still return EMULOK?
>
Now I am returning error for the default case.

> Also is this printk really neccessary?
>
>> +            break;
>> +    }
>> +
>> +    return VPL011_EMUL_OK;
>> +}
>> +
>> +static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r, void *priv)
>> +{
>> +    unsigned char ch = r;
>> +
>> +    switch (info->gpa - GUEST_PL011_BASE)
>> +    {
>> +        case VPL011_UARTCR_OFFSET:
>> +            v->domain->arch.vpl011.control = r;
>> +            break;
>> +        case VPL011_UARTDR_OFFSET:
>> +            vpl011_write_data(v->domain, ch);
>> +            break;
>> +        case VPL011_UARTIMSC_OFFSET:
>> +            v->domain->arch.vpl011.intr_mask = r;
>> +            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )
>> +                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
>> +            break;
>> +        case VPL011_UARTICR_OFFSET:
>> +            /*
>> +             * clear all bits which are set in the input
>> +             */
>> +            v->domain->arch.vpl011.raw_intr_status &= ~r;
>> +            if ( (v->domain->arch.vpl011.raw_intr_status & v->domain->arch.vpl011.intr_mask) )
>> +            {
>> +                vgic_vcpu_inject_spi(v->domain, (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
>> +            }
>> +            break;
>> +        case VPL011_UARTRSR_OFFSET: // nothing to clear
>> +            break;
>> +        case VPL011_UARTFR_OFFSET: // these are all RO registers
>> +        case VPL011_UARTRIS_OFFSET:
>> +        case VPL011_UARTMIS_OFFSET:
>> +        case VPL011_UARTDMACR_OFFSET:
>> +            break;
>> +        default:
>> +            printk ("vpl011_mmio_write: switch case not handled %d\n", (int)(info->gpa - GUEST_PL011_BASE));
>> +            break;
>> +    }
>> +
>> +    return VPL011_EMUL_OK;
>> +}
>> +
>> +static const struct mmio_handler_ops vpl011_mmio_handler = {
>> +    .read = vpl011_mmio_read,
>> +    .write = vpl011_mmio_write,
>> +};
>> +
>> +
>
> why the extra newline.
>
>> +
>> +int vpl011_map_guest_page(struct domain *d)
>> +{
>> +    int rc=0;
>
> No need for = 0;
Ok.

>> +
>> +    /*
>> +     * map the guest PFN to Xen address space
>> +     */
>> +    rc = prepare_ring_for_helper(d,
>> +                                 d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_PFN],
>> +                                 &d->arch.vpl011.ring_page,
>> +                                 (void **)&d->arch.vpl011.ring_buf);
>> +    if ( rc < 0 )
>> +    {
>> +        printk("Failed to map vpl011 guest PFN\n");
>> +    }
>> +
>> +    return rc;
>
> Could you just make this whole routine be:
>
>  return prepare_ring_for_helper(..)
>
> That printk is not needed I think? I would add it to the caller of this function.
>
Ok.

>> +}
>> +
>> +static int vpl011_data_avail(struct domain *d)
>> +{
>> +    int rc=0;
>> +    unsigned long flags;
>> +
>> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
>
> Can you have an macro for this?
>> +
>> +    VPL011_LOCK(d, flags);
>
> Please don't. Just use normal spin_lock invocation.
>
>> +
>> +    /*`
>> +     * check IN ring buffer
>> +     */
>
> Please remove the comment. It does not add much context to the code.
>
>> +    if ( !VPL011_IN_RING_EMPTY(intf) )
>> +    {
>> +        /*
>> +         * clear the RX FIFO empty flag as the ring is not empty
>> +         */
>
> Please remove this comment.
>
>> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFE);
>> +
>> +        /*
>> +         * if the buffer is full then set the RX FIFO FULL flag
>
> Also please remove this comment.
>
>> +         */
>> +        if ( VPL011_IN_RING_FULL(intf) )
>> +            d->arch.vpl011.flag |= (VPL011_UARTFR_RXFF);
>> +
>> +        /*
>> +         * set the RX interrupt status
>> +         */
>
> And this one too.
>
> What I would recommend is that you write one nice comment at the start
> of the 'if' saying:
>
> "Have to set RX state regardless whether it is full or has some entries."
>
>> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_RXRIS);
>> +    }
>> +
>> +    /*
>> +     * check OUT ring buffer
>
> Please remove this comment.
>> +     */
>> +    if ( !VPL011_OUT_RING_FULL(intf) )
>> +    {
>> +        /*
>> +         * if the buffer is not full then clear the TX FIFO full flag
>> +         */
>
>
> Please remove this comment.
>> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFF);
>> +
>> +        /*
>> +         * set the TX interrupt status
>> +         */
>> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_TXRIS);
>> +
>> +        if ( VPL011_OUT_RING_EMPTY(intf) )
>> +        {
>> +            /*
>> +             * clear the uart busy flag and set the TX FIFO empty flag
>> +             */
>> +            d->arch.vpl011.flag &= ~(VPL011_UARTFR_BUSY);
>> +            d->arch.vpl011.flag |= (VPL011_UARTFR_TXFE);
>> +        }
>> +    }
>
>> +
>> +    VPL011_UNLOCK(d, flags);
>> +
>> +    /*
>> +     * send an interrupt if it is not masked
>
> So does that mean we would send an interrupt even if the in/out rings
> are full?
If the out ring is full then the interrupt would not be raised because
the Tx interrupt status bit would be cleared in UARTRIS register in
vpl011_write_data().
For the in ring, the Rx interrupt would be raised if it is not masked.

>
>> +     */
>> +    if ( (d->arch.vpl011.raw_intr_status & d->arch.vpl011.intr_mask) )
>> +        vgic_vcpu_inject_spi(d, (int)d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
>> +
>> +    if ( !VPL011_OUT_RING_EMPTY(intf) )
>
> This is asking for a race.
>
> So it may have changed between the first time you read it and this
> one.
>
> Is that OK? Would it still be OK to send an interrupt even if say
> the ring was emtpry at start of the function but became empty now?
>
Yes the out ring state can change between the two times it is checked.
So finally it will be either be empty or non-empty irrespective of
what it was the first time.
If it is non-empty then an event is raised to dom0 to read the data
from the out ring.

> Would it be better if you read all the values from
> the ring at the start of the function in local variables
> and made sure to use 'barrier()' so there are no compiler
> "optimizations" done?
>
>> +    {
>> +        /*
>> +         * raise an interrupt to dom0
>> +         */
>
> Please remove this.
>
>> +        rc = raw_evtchn_send(d,
>> +                    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL);
>
> What if HVM_PARAM_VPL011_CONSOLE_EVTCHN is zero? Should you check
> that first?
>
> Or is it given (in which case please add an ASSERT) that the
> HVM_PARAM_VPL011_CONSOLE_EVTCHN is _always_ set?
>
Yes. During vpl011 initialization for this domain, this event channel
will be allocated. I will add an assert.
>> +
>> +        if ( rc < 0 )
>> +            printk("Failed to send vpl011 interrupt to dom0\n");
>
> gdprintk. But is this useful? How will this help in debugging the
> problem?
>
>> +    }
>> +
>> +    return rc;
>> +}
>> +
>> +int vpl011_read_data(struct domain *d, unsigned char *data)
>> +{
>> +    int rc=0;
>
> No point for this. Just do 'return 0'
>> +    unsigned long flags;
>> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
>> +
>> +    *data = 0;
>> +
>> +    VPL011_LOCK(d, flags);
>> +
>> +    /*
>> +     * if there is data in the ring buffer then copy it to the output buffer
>> +     */
>> +    if ( !VPL011_IN_RING_EMPTY(intf) )
>> +    {
>> +        *data = intf->in[MASK_VPL011CONS_IDX(intf->in_cons++, intf->in)];
>> +    }
>> +
>> +    /*
>> +     * if the ring buffer is empty then set the RX FIFO empty flag
>> +     */
>> +    if ( VPL011_IN_RING_EMPTY(intf) )
>
> So there is a nice race here. Why don't you just use an 'else' ?
>
Since we are reading the data from the ring buffer in the first step,
the ring buffer may go empty after the first step. If I use else then
I will not enter the 2nd if statement.

>
>> +    {
>> +        d->arch.vpl011.flag |= (VPL011_UARTFR_RXFE);
>> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_RXRIS);
>> +    }
>> +
>> +    /*
>> +     * clear the RX FIFO full flag
>> +     */
>> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFF);
>> +
>> +    VPL011_UNLOCK(d, flags);
>> +
>> +    return rc;
>> +}
>> +
>> +int vpl011_write_data(struct domain *d, unsigned char data)
>> +{
>> +    int rc=0;
>
> Pls remove the '=0'
>> +    unsigned long flags;
>> +    struct console_interface *intf=(struct console_interface *)d->arch.vpl011.ring_buf;
>> +
>> +    VPL011_LOCK(d, flags);
>> +
>> +    /*
>> +     * if there is space in the ring buffer then write the data
>
> Please moreve this comment.
>> +     */
>> +    if ( !VPL011_OUT_RING_FULL(intf) )
>> +    {
>> +        intf->out[MASK_VPL011CONS_IDX(intf->out_prod++, intf->out)] = data;
>> +        smp_wmb();
>> +    }
>>
>> +    /*
>> +     * if there is no space in the ring buffer then set the
>> +     * TX FIFO FULL flag
>
> Again, why not just an 'else'?
>
>> +     */
>> +    if ( VPL011_OUT_RING_FULL(intf) )
>> +    {
>> +        d->arch.vpl011.flag |= (VPL011_UARTFR_TXFF);
>> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_TXRIS);
>> +    }
>> +
>> +    /*
>> +     * set the uart busy status
>> +     */
>> +    d->arch.vpl011.flag |= (VPL011_UARTFR_BUSY);
>> +
>> +    /*
>> +     * clear the TX FIFO empty flag
>> +     */
>
> Please remove these comments. They are distracting.
>
> Also a single line comment should be:
>
> /* <comment> */
>
>
>> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFE);
>> +
>> +    VPL011_UNLOCK(d, flags);
>> +
>> +    /*
>> +     * raise an event to dom0 only if it is the first character in the buffer
>
> Why? Why only the first charcter?
>
I wanted to avoid raising too many events to dom0. Since dom0 is going
to process the data in the ring buffer until it goes empty, it should
be ok to raise an event initially only when the first data is written
to the ring buffer so that dom0 can start reading the data from the
ring buffer.

>> +     */
>> +    if ( VPL011_RING_DEPTH(intf, out) == 1 )
>> +    {
>> +        rc = raw_evtchn_send(d,
>> +                d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL);
>
> And again, should we have an assert for HVM_PARAM_VPL011_CONSOLE_EVTCHN or a check
> for it?
I will add an assert.

>
>> +
>> +        if ( rc < 0 )
>> +            printk("Failed to send vpl011 interrupt to dom0\n");
>
> gdprintk.
>
>> +    }
>> +
>> +    return rc;
>> +}
>> +
>> +static void vpl011_notification(struct vcpu *v, unsigned int port)
>> +{
>> +    vpl011_data_avail(v->domain);
>> +}
>> +
>> +int domain_vpl011_init(struct domain *d)
>> +{
>> +    int rc=0;
>
> You can remove the =0;
>> +
>> +    /*
>> +     * register xen event channel
>> +     */
>
> Please remove this comment.
>
>> +    rc = alloc_unbound_xen_event_channel(d, 0, current->domain->domain_id,
>> +                                                        vpl011_notification);
>> +    if (rc < 0)
>
> Spaces.
>> +    {
>> +        printk ("Failed to allocate vpl011 event channel\n");
>
> gdprintk
>
> And also not sure if this is needed. Won't the rc be propagated to the
> caller who can print this?
>
>> +        return rc;
>> +    }
>> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN] = rc;
>> +
>> +    /*
>> +     * allocate an SPI VIRQ for the guest
>> +     */
>> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ] = vgic_allocate_spi(d);
>
> You are not checking vgic_allocate_spi for errors?
>
I have added a check.

>> +
>> +    /*
>> +     * register mmio handler
>> +     */
>
> Please remove these comments. They are just saying what the code
> is doing. Not adding anything extra.
>
>> +    register_mmio_handler (d, &vpl011_mmio_handler, GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL);
>
> Please kill that space before (.
>
> And what if register_mmio_handler returns an error?
>
register_mmio_handler() does not return any value.

>> +
>> +    /*
>> +     * initialize the lock
>> +     */
>
> That is a comment that is really not needed.
>
>> +    spin_lock_init(&d->arch.vpl011.lock);
>> +
>> +    /*
>> +     * clear the flag, control and interrupt status registers
>> +     */
>
> Why not just do memset on the structure?
>
>> +    d->arch.vpl011.control = 0;
>> +    d->arch.vpl011.flag = 0;
>> +    d->arch.vpl011.intr_mask = 0;
>> +    d->arch.vpl011.intr_clear = 0;
>> +    d->arch.vpl011.raw_intr_status = 0;
>> +    d->arch.vpl011.masked_intr_status = 0;
>> +
>> +    return 0;
>> +}
I will use the memset.

>> diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h
>> new file mode 100644
>> index 0000000..f2c577f
>> --- /dev/null
>> +++ b/xen/arch/arm/vpl011.h
>> @@ -0,0 +1,208 @@
>> +/*
>> + * include/xen/vpl011.h
>> + *
>> + * Virtual PL011 UART
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope 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.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program; If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#ifndef _VPL011_H_
>> +
>> +#define _VPL011_H_
>> +
>> +/*
>> + * register offsets
>> + */
>> +#define VPL011_UARTDR_OFFSET    0x0 // data register (RW)
>
> Wrong type of comments. Pls use /* */ variant
Ok.
>
>> +#define VPL011_UARTRSR_OFFSET   0x4 // receive status and error clear register (RW)
>> +#define VPL011_UARTFR_OFFSET    0x18 // flag register (RO)
>> +#define VPL011_UARTRIS_OFFSET   0x3c // raw interrupt status register (RO)
>> +#define VPL011_UARTMIS_OFFSET   0x40 // masked interrupt status register (RO)
>> +#define VPL011_UARTIMSC_OFFSET  0x38 // interrupt mask set/clear register (RW)
>> +#define VPL011_UARTICR_OFFSET   0x44 // interrupt clear register (WO)
>> +#define VPL011_UARTCR_OFFSET    0x30 // uart control register
>> +#define VPL011_UARTDMACR_OFFSET 0x48 // uart dma control register
>> +
>> +/*
>> + * control register bits - RW
>> + */
>> +#define VPL011_UARTCR_UARTEN_BIT 0
>> +#define VPL011_UARTCR_UARTEN    (1<<VPL011_UARTCR_UARTEN_BIT)
>> +#define VPL011_UARTCR_TXE_BIT    8
>> +#define VPL011_UARTCR_TXE       (1<<VPL011_UARTCR_TXE_BIT)
>> +#define VPL011_UARTCR_RXE_BIT    9
>> +#define VPL011_UARTCR_RXE       (1<<VPL011_UARTCR_RXE_BIT)
>> +
>> +/*
>> + * Flag register bits - RO
>> + */
>> +#define VPL011_UARTFR_CTS_BIT   0   // clear to send
>> +#define VPL011_UARTFR_CTS       (1<<VPL011_UARTFR_CTS_BIT)
>> +#define VPL011_UARTFR_DSR_BIT   1   // data set ready
>> +#define VPL011_UARTFR_DSR       (1<<VPL011_UARTFR_DSR_BIT)
>> +#define VPL011_UARTFR_DCD_BIT   2   // data carrier detect
>> +#define VPL011_UARTFR_DCD       (1<<VPL011_UARTFR_DCD_BIT)
>> +#define VPL011_UARTFR_BUSY_BIT  3   // uart busy
>> +#define VPL011_UARTFR_BUSY      (1<<VPL011_UARTFR_BUSY_BIT)
>> +#define VPL011_UARTFR_RXFE_BIT  4   // receive fifo empty
>> +#define VPL011_UARTFR_RXFE      (1<<VPL011_UARTFR_RXFE_BIT)
>> +#define VPL011_UARTFR_TXFF_BIT  5   // transmit fifo full
>> +#define VPL011_UARTFR_TXFF      (1<<VPL011_UARTFR_TXFF_BIT)
>> +#define VPL011_UARTFR_RXFF_BIT  6   // receive fifo full
>> +#define VPL011_UARTFR_RXFF      (1<<VPL011_UARTFR_RXFF_BIT)
>> +#define VPL011_UARTFR_TXFE_BIT  7   // transmit fifo empty
>> +#define VPL011_UARTFR_TXFE      (1<<VPL011_UARTFR_TXFE_BIT)
>> +#define VPL011_UARTFR_RI_BIT    8   // ring indicator
>> +#define VPL011_UARTFR_RI        (1<<VPL011_UARTFR_RI_BIT)
>> +
>> +/*
>> + * UART raw interrupt status bits - RO
>> + */
>> +#define VPL011_UARTRIS_RIRMIS_BIT  0
>> +#define VPL011_UARTRIS_RIRMIS      (1<<VPL011_UARTRIS_RIRMIS_BIT)
>> +#define VPL011_UARTRIS_CTSRMIS_BIT 1
>> +#define VPL011_UARTRIS_CTSRMIS     (1<<VPL011_UARTRIS_CTSRMIS_BIT)
>> +#define VPL011_UARTRIS_DCDRMIS_BIT 2
>> +#define VPL011_UARTRIS_DCDRMIS     (1<<VPL011_UARTRIS_DCDRMIS_BIT)
>> +#define VPL011_UARTRIS_DSRRMIS_BIT 3
>> +#define VPL011_UARTRIS_DSRRMIS     (1<<VPL011_UARTRIS_DSRRMIS_BIT)
>> +#define VPL011_UARTRIS_RXRIS_BIT   4
>> +#define VPL011_UARTRIS_RXRIS       (1<<VPL011_UARTRIS_RXRIS_BIT)
>> +#define VPL011_UARTRIS_TXRIS_BIT   5
>> +#define VPL011_UARTRIS_TXRIS       (1<<VPL011_UARTRIS_TXRIS_BIT)
>> +#define VPL011_UARTRIS_RTRIS_BIT   6
>> +#define VPL011_UARTRIS_RTRIS       (1<<VPL011_UARTRIS_RTRIS_BIT)
>> +#define VPL011_UARTRIS_FERIS_BIT   7
>> +#define VPL011_UARTRIS_FERIS       (1<<VPL011_UARTRIS_FERIS_BIT)
>> +#define VPL011_UARTRIS_PERIS_BIT   8
>> +#define VPL011_UARTRIS_PERIS       (1<<VPL011_UARTRIS_PERIS_BIT)
>> +#define VPL011_UARTRIS_BERIS_BIT   9
>> +#define VPL011_UARTRIS_BERIS       (1<<VPL011_UARTRIS_BERIS_BIT)
>> +#define VPL011_UARTRIS_OERIS_BIT   10
>> +#define VPL011_UARTRIS_OERIS       (1<<VPL011_UARTRIS_OERIS_BIT)
>> +
>> +/*
>> + * UART masked interrupt status bits - RO
>> + */
>> +#define VPL011_UARTMIS_RIMMIS_BIT  0
>> +#define VPL011_UARTMIS_RIMMIS      (1<<VPL011_UARTMIS_RIMMIS_BIT)
>> +#define VPL011_UARTMIS_CTSMMIS_BIT 1
>> +#define VPL011_UARTMIS_CTSMMIS     (1<<VPL011_UARTMIS_CTSMMIS_BIT)
>> +#define VPL011_UARTMIS_DCDMMIS_BIT 2
>> +#define VPL011_UARTMIS_DCDMMIS     (1<<VPL011_UARTMIS_DCDMMIS_BIT)
>> +#define VPL011_UARTMIS_DSRMMIS_BIT 3
>> +#define VPL011_UARTMIS_DSRMMIS     (1<<VPL011_UARTMIS_DSRMMIS_BIT)
>> +#define VPL011_UARTMIS_RXMIS_BIT   4
>> +#define VPL011_UARTMIS_RXMIS       (1<<VPL011_UARTMIS_RXMIS_BIT)
>> +#define VPL011_UARTMIS_TXMIS_BIT   5
>> +#define VPL011_UARTMIS_TXMIS       (1<<VPL011_UARTMIS_TXMIS_BIT)
>> +#define VPL011_UARTMIS_RTMIS_BIT   6
>> +#define VPL011_UARTMIS_RTMIS       (1<<VPL011_UARTMIS_RTMIS_BIT)
>> +#define VPL011_UARTMIS_FEMIS_BIT   7
>> +#define VPL011_UARTMIS_FEMIS       (1<<VPL011_UARTMIS_FEMIS_BIT)
>> +#define VPL011_UARTMIS_PEMIS_BIT   8
>> +#define VPL011_UARTMIS_PEMIS       (1<<VPL011_UARTMIS_PEMIS_BIT)
>> +#define VPL011_UARTMIS_BEMIS_BIT   9
>> +#define VPL011_UARTMIS_BEMIS       (1<<VPL011_UARTMIS_BEMIS_BIT)
>> +#define VPL011_UARTMIS_OEMIS_BIT   10
>> +#define VPL011_UARTMIS_OEMIS       (1<<VPL011_UARTMIS_OEMIS_BIT)
>> +
>> +/*
>> + * UART  interrupt clear bits - WO
>> + */
>> +#define VPL011_UARTICR_RIMIC_BIT    0
>> +#define VPL011_UARTICR_RIMIC        (1<<VPL011_UARTICR_RIMIC_BIT)
>> +#define VPL011_UARTICR_CTSMIC_BIT   1
>> +#define VPL011_UARTICR_CTSMIC       (1<<VPL011_UARTICR_CTSMIC_BIT)
>> +#define VPL011_UARTICR_DCDMIC_BIT   2
>> +#define VPL011_UARTICR_DCDMIC       (1<<VPL011_UARTICR_DCDMIC_BIT)
>> +#define VPL011_UARTICR_DSRMIC_BIT   3
>> +#define VPL011_UARTICR_DSRMIC       (1<<VPL011_UARTICR_DSRMIC_BIT)
>> +#define VPL011_UARTICR_RXIC_BIT     4
>> +#define VPL011_UARTICR_RXIC         (1<<VPL011_UARTICR_RXIC_BIT)
>> +#define VPL011_UARTICR_TXIC_BIT     5
>> +#define VPL011_UARTICR_TXIC         (1<<VPL011_UARTICR_TXIC_BIT)
>> +#define VPL011_UARTICR_RTIC_BIT     6
>> +#define VPL011_UARTICR_RTIC         (1<<VPL011_UARTICR_RTIC_BIT)
>> +#define VPL011_UARTICR_FEIC_BIT     7
>> +#define VPL011_UARTICR_FEIC         (1<<VPL011_UARTICR_FEIC_BIT)
>> +#define VPL011_UARTICR_PEIC_BIT     8
>> +#define VPL011_UARTICR_PEIC         (1<<VPL011_UARTICR_PEIC_BIT)
>> +#define VPL011_UARTICR_BEIC_BIT     9
>> +#define VPL011_UARTICR_BEIC         (1<<VPL011_UARTICR_BEIC_BIT)
>> +#define VPL011_UARTICR_OEIC_BIT     10
>> +#define VPL011_UARTICR_OEIC         (1<<VPL011_UARTICR_OEIC_BIT)
>> +
>> +/*
>> + * UART interrupt mask set/clear bits - RW
>> + */
>> +#define VPL011_UARTIMSC_RIMIM_BIT   0
>> +#define VPL011_UARTIMSC_RIMIM       (1<<VPL011_UARTIMSC_RIMIM_BIT)
>> +#define VPL011_UARTIMSC_CTSMIM_BIT  1
>> +#define VPL011_UARTIMSC_CTSMIM      (1<<VPL011_UARTIMSC_CTSMIM_BIT)
>> +#define VPL011_UARTIMSC_DCDMIM_BIT   2
>> +#define VPL011_UARTIMSC_DCDMIM      (1<<VPL011_UARTIMSC_DCDMIM_BIT)
>> +#define VPL011_UARTIMSC_DSRMIM_BIT  3
>> +#define VPL011_UARTIMSC_DSRMIM      (1<<VPL011_UARTIMSC_DSRMIM_BIT)
>> +#define VPL011_UARTIMSC_RXIM_BIT    4
>> +#define VPL011_UARTIMSC_RXIM        (1<<VPL011_UARTIMSC_RXIM_BIT)
>> +#define VPL011_UARTIMSC_TXIM_BIT    5
>> +#define VPL011_UARTIMSC_TXIM        (1<<VPL011_UARTIMSC_TXIM_BIT)
>> +#define VPL011_UARTIMSC_RTIM_BIT    6
>> +#define VPL011_UARTIMSC_RTIM        (1<<VPL011_UARTIMSC_RTIM_BIT)
>> +#define VPL011_UARTIMSC_FEIM_BIT    7
>> +#define VPL011_UARTIMSC_FEIM        (1<<VPL011_UARTIMSC_FEIM_BIT)
>> +#define VPL011_UARTIMSC_PEIM_BIT    8
>> +#define VPL011_UARTIMSC_PEIM        (1<<VPL011_UARTIMSC_PEIM_BIT)
>> +#define VPL011_UARTIMSC_BEIM_BIT    9
>> +#define VPL011_UARTIMSC_BEIM        (1<<VPL011_UARTIMSC_BEIM_BIT)
>> +#define VPL011_UARTIMSC_OEIM_BIT    10
>> +#define VPL011_UARTIMSC_OEIM        (1<<VPL011_UARTIMSC_OEIM_BIT)
>> +
>> +
>> +/*
>> + * helper macros
>> + */
>> +#define VPL011_RING_DEPTH(intf,dir) (((intf)->dir ## _prod - (intf)->dir ## _cons))
>> +#define VPL011_RING_MAX_DEPTH(intf,dir) (sizeof((intf)->dir)-1)
>> +
>> +#define VPL011_IN_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, in) == 0)
>> +
>> +#define VPL011_OUT_RING_EMPTY(intf) (VPL011_RING_DEPTH(intf, out) == 0)
>> +
>> +#define VPL011_IN_RING_FULL(intf) (VPL011_RING_DEPTH(intf, in) == VPL011_RING_MAX_DEPTH(intf, in))
>> +
>> +#define VPL011_OUT_RING_FULL(intf) (VPL011_RING_DEPTH(intf, out) == VPL011_RING_MAX_DEPTH(intf,out))
>> +
>> +#define VPL011_LOCK(d,flags) spin_lock_irqsave(&(d)->arch.vpl011.lock, flags)
>> +#define VPL011_UNLOCK(d,flags) spin_unlock_irqrestore(&(d)->arch.vpl011.lock, flags)
>> +
>> +/*
>> + * MMIO return values
>> + */
>> +#define     VPL011_EMUL_OK      1
>> +#define     VPL011_EMUL_FAIL    0
>> +
>> +int domain_vpl011_init(struct domain *d);
>> +int vpl011_map_guest_page(struct domain *d);
>> +int vpl011_read_data(struct domain *d, unsigned char *data);
>> +int vpl011_write_data(struct domain *d, unsigned char data);
>> +
>> +#define MASK_VPL011CONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
>> +struct console_interface {
>> +    char in[1024];
>> +    char out[2048];
>> +    uint32_t in_cons, in_prod;
>> +    uint32_t out_cons, out_prod;
>> +};
>> +#endif
>> diff --git a/xen/common/Kconfig b/xen/common/Kconfig
>> index f2ecbc4..7e2feac 100644
>> --- a/xen/common/Kconfig
>> +++ b/xen/common/Kconfig
>> @@ -237,4 +237,10 @@ config FAST_SYMBOL_LOOKUP
>>         The only user of this is Live patching.
>>
>>         If unsure, say Y.
>> +
>> +config VPL011_CONSOLE
>> +     bool "Emulated pl011 console support"
>> +     default y
>
> I thought by default it would be 'n'?
>
> Or perhaps defauly y if CONFIG_ARM or such?
I moved this config option to xen/arch/arm/Kconfig.

>
>> +     ---help---
>> +       Allows a guest to use pl011 UART as a console
>>  endmenu
>> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
>> index 2d6fbb1..ff2403a 100644
>> --- a/xen/include/asm-arm/domain.h
>> +++ b/xen/include/asm-arm/domain.h
>> @@ -40,6 +40,7 @@ struct vtimer {
>>          uint64_t cval;
>>  };
>>
>> +
>
> ??
>>  struct arch_domain
>>  {
>>  #ifdef CONFIG_ARM_64
>> @@ -131,6 +132,20 @@ struct arch_domain
>>      struct {
>>          uint8_t privileged_call_enabled : 1;
>>      } monitor;
>> +
>> +#ifdef CONFIG_VPL011_CONSOLE
>> +    struct vpl011 {
>> +        void *ring_buf;
>> +        struct page_info *ring_page;
>> +        uint32_t    flag;               /* flag register */
>> +        uint32_t    control;            /* control register */
>> +        uint32_t    intr_mask;          /* interrupt mask register*/
>> +        uint32_t    intr_clear;         /* interrupt clear register */
>> +        uint32_t    raw_intr_status;    /* raw interrupt status register */
>> +        uint32_t    masked_intr_status; /* masked interrupt register */
>> +        spinlock_t  lock;
>> +    } vpl011;
>> +#endif
>>  }  __cacheline_aligned;
>>
>>  struct arch_vcpu
>> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
>> index bd974fb..1d4548f 100644
>> --- a/xen/include/public/arch-arm.h
>> +++ b/xen/include/public/arch-arm.h
>> @@ -410,6 +410,10 @@ typedef uint64_t xen_callback_t;
>>  #define GUEST_ACPI_BASE 0x20000000ULL
>>  #define GUEST_ACPI_SIZE 0x02000000ULL
>>
>> +/* PL011 mappings */
>> +#define GUEST_PL011_BASE    0x22000000ULL
>> +#define GUEST_PL011_SIZE    0x00001000ULL
>> +
>>  /*
>>   * 16MB == 4096 pages reserved for guest to use as a region to map its
>>   * grant table in.
>> @@ -420,6 +424,7 @@ typedef uint64_t xen_callback_t;
>>  #define GUEST_MAGIC_BASE  xen_mk_ullong(0x39000000)
>>  #define GUEST_MAGIC_SIZE  xen_mk_ullong(0x01000000)
>>
>> +
>
> ???
I will remove unnecessary newlines.

>>  #define GUEST_RAM_BANKS   2
>>
>>  #define GUEST_RAM0_BASE   xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */
>> --
>> 2.7.4
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> https://lists.xen.org/xen-devel

Regards,
Bhupinder

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-05 12:12   ` Julien Grall
@ 2017-03-23  9:14     ` Bhupinder Thakur
  2017-03-23 14:16       ` Julien Grall
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-23  9:14 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, nd, Stefano Stabellini

.Hi Julien,

On 5 March 2017 at 17:42, Julien Grall <julien.grall@arm.com> wrote:
> Hi Bhupinder,
>
> On 21/02/17 11:25, Bhupinder Thakur wrote:
>>
>> diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
>> new file mode 100644
>> index 0000000..88ba968
>> --- /dev/null
>> +++ b/xen/arch/arm/vpl011.c
>
>
> [...]
>
>> +static int vpl011_mmio_write(struct vcpu *v, mmio_info_t *info,
>> register_t r, void *priv)
>
>
> See my comment on the vpl011_mmio_read about the structure of the function.
>
>> +{
>> +    unsigned char ch = r;
>> +
>> +    switch (info->gpa - GUEST_PL011_BASE)
>> +    {
>> +        case VPL011_UARTCR_OFFSET:
>
>
> This register is not required in the SBSA UART.
Yes, I checked that. I will remove it.
>
>> +            v->domain->arch.vpl011.control = r;
>> +            break;
>> +        case VPL011_UARTDR_OFFSET:
>> +            vpl011_write_data(v->domain, ch);
>
>
> The implicit casting of register_t to ch is a bit confusing. Also I would
> prefer to use uint8_t as it reflects the size of the field.
I have removed implicit casing with explicit casting.
>
> Lastly, what if vpl011_write_data is returning an error?
>
Normally vpl011_write_data() should not fail since the guest should
stop writing more data once the ring buffer goes full and TXFF bit is
set in UARTFR.
So there should always be space in the ring buffer for the next data
when a mmio write happens.

If the guest still writes when ring buffer is already full then data
would be lost.

>> +            break;
>> +        case VPL011_UARTIMSC_OFFSET:
>> +            v->domain->arch.vpl011.intr_mask = r;
>
>
> You need to sanitize the value written and make sure reserved field and
> Write As Ones register and handle correctly (see the spec).
>
>> +            if ( (v->domain->arch.vpl011.raw_intr_status &
>> v->domain->arch.vpl011.intr_mask) )
>
>
> This line and the line below are over 80 columns. Also the code in general
> would benefits if you define a local variable to point to
> v->domain->arch.vpl011.
I will use a local variable for v->domain->arch.vpl011
>
>> +                vgic_vcpu_inject_spi(v->domain,
>> (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
>
>
> I don't think we need an HVM_PARAM for the pl011 SPI. We cannot hardcode
> this in the guest layout (see include/public/arch-arm.h).
Please see my comment below on how to reserve 1 SPI for vpl011.

>
>> +            break;
>> +        case VPL011_UARTICR_OFFSET:
>> +            /*
>> +             * clear all bits which are set in the input
>> +             */
>> +            v->domain->arch.vpl011.raw_intr_status &= ~r;
>> +            if ( (v->domain->arch.vpl011.raw_intr_status &
>> v->domain->arch.vpl011.intr_mask) )
>> +            {
>
>
> { } are not necessary.
>
>> +                vgic_vcpu_inject_spi(v->domain,
>> (int)v->domain->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
>> +            }
>
>
> The if is exactly the same as the on in IMSC. This is the call of an helper
> to check the interrupt state and inject one if necessary.
>
>> +            break;
>> +        case VPL011_UARTRSR_OFFSET: // nothing to clear
>
>
> The coding style for single line comment in Xen is /* ... */
>
> Also, I think we may want to handle Overrun error as the ring may be full.
>
>> +            break;
>> +        case VPL011_UARTFR_OFFSET: // these are all RO registers
>> +        case VPL011_UARTRIS_OFFSET:
>> +        case VPL011_UARTMIS_OFFSET:
>> +        case VPL011_UARTDMACR_OFFSET:
>
>
> Please have a look at the vGICv2/vGICv3 emulation see how we implemented
> write ignore register.
>
Ok.
>> +            break;
>> +        default:
>> +            printk ("vpl011_mmio_write: switch case not handled %d\n",
>> (int)(info->gpa - GUEST_PL011_BASE));
>
>
> See my comment about the prinkt in the read emulation.
>
>> +            break;
>> +    }
>> +
>> +    return VPL011_EMUL_OK;
>> +}
>> +
>> +static const struct mmio_handler_ops vpl011_mmio_handler = {
>> +    .read = vpl011_mmio_read,
>> +    .write = vpl011_mmio_write,
>> +};
>> +
>> +
>> +
>
>
> Only newline is sufficient. This was mention by Konrad and I will try to
> avoid repeating his comments.
>
>> +int vpl011_map_guest_page(struct domain *d)
>> +{
>> +    int rc=0;
>> +
>> +    /*
>> +     * map the guest PFN to Xen address space
>> +     */
>> +    rc = prepare_ring_for_helper(d,
>> +
>> d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_PFN],
>> +                                 &d->arch.vpl011.ring_page,
>> +                                 (void **)&d->arch.vpl011.ring_buf);
>
>
> Why do you need the cast?
>
I will remove the casting.

> Also I cannot find any code in this series which destroy the ring. Please
> have a helper called vpl011_unmap_guest_page to do this job and call when
> the domain is destroyed.
>
Ok.
>
>> +    if ( rc < 0 )
>> +    {
>> +        printk("Failed to map vpl011 guest PFN\n");
>> +    }
>> +
>> +    return rc;
>> +}
>> +
>> +static int vpl011_data_avail(struct domain *d)
>> +{
>> +    int rc=0;
>> +    unsigned long flags;
>> +
>> +    struct console_interface *intf=(struct console_interface
>> *)d->arch.vpl011.ring_buf;
>> +
>> +    VPL011_LOCK(d, flags);
>> +
>> +    /*`
>> +     * check IN ring buffer
>> +     */
>> +    if ( !VPL011_IN_RING_EMPTY(intf) )
>> +    {
>> +        /*
>> +         * clear the RX FIFO empty flag as the ring is not empty
>> +         */
>> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFE);
>> +
>> +        /*
>> +         * if the buffer is full then set the RX FIFO FULL flag
>> +         */
>> +        if ( VPL011_IN_RING_FULL(intf) )
>> +            d->arch.vpl011.flag |= (VPL011_UARTFR_RXFF);
>> +
>> +        /*
>> +         * set the RX interrupt status
>> +         */
>> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_RXRIS);
>> +    }
>> +
>> +    /*
>> +     * check OUT ring buffer
>> +     */
>> +    if ( !VPL011_OUT_RING_FULL(intf) )
>> +    {
>> +        /*
>> +         * if the buffer is not full then clear the TX FIFO full flag
>> +         */
>> +        d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFF);
>> +
>> +        /*
>> +         * set the TX interrupt status
>> +         */
>> +        d->arch.vpl011.raw_intr_status |= (VPL011_UARTRIS_TXRIS);
>> +
>> +        if ( VPL011_OUT_RING_EMPTY(intf) )
>> +        {
>> +            /*
>> +             * clear the uart busy flag and set the TX FIFO empty flag
>> +             */
>> +            d->arch.vpl011.flag &= ~(VPL011_UARTFR_BUSY);
>> +            d->arch.vpl011.flag |= (VPL011_UARTFR_TXFE);
>> +        }
>> +    }
>> +
>> +    VPL011_UNLOCK(d, flags);
>> +
>> +    /*
>> +     * send an interrupt if it is not masked
>> +     */
>> +    if ( (d->arch.vpl011.raw_intr_status & d->arch.vpl011.intr_mask) )
>> +        vgic_vcpu_inject_spi(d,
>> (int)d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ]);
>
>
> See my comment above about having an helper for this code.
Ok. I will add a helper function.

>
>> +
>> +    if ( !VPL011_OUT_RING_EMPTY(intf) )
>> +    {
>> +        /*
>> +         * raise an interrupt to dom0
>
>
> The backend console does not necessarily live in DOM0. Anyway, Konrad
> requested to drop the comment and I am happy with that.
>
>> +         */
>> +        rc = raw_evtchn_send(d,
>> +
>> d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL);
>
>
> You are using a function that is been defined in a later patch (i.w #3). All
> the patch should be able to compile without applying upcoming patch to allow
> bisection.
>
> Ideally, Xen should still be functional for every patch. But it is a best
> effort.
>
I will reorder the patches accordingly.

>> +
>> +        if ( rc < 0 )
>> +            printk("Failed to send vpl011 interrupt to dom0\n");
>> +    }
>> +
>> +    return rc;
>> +}
>> +
>> +int vpl011_read_data(struct domain *d, unsigned char *data)
>
>
> This function does not seem to be used outside of this file. So why do you
> export it?
>
Made it a static function.

>
>> +{
>> +    int rc=0;
>> +    unsigned long flags;
>> +    struct console_interface *intf=(struct console_interface
>> *)d->arch.vpl011.ring_buf;
>> +
>> +    *data = 0;
>> +
>> +    VPL011_LOCK(d, flags);
>> +
>> +    /*
>> +     * if there is data in the ring buffer then copy it to the output
>> buffer
>> +     */
>> +    if ( !VPL011_IN_RING_EMPTY(intf) )
>> +    {
>> +        *data = intf->in[MASK_VPL011CONS_IDX(intf->in_cons++, intf->in)];
>> +    }
>> +
>> +    /*
>> +     * if the ring buffer is empty then set the RX FIFO empty flag
>> +     */
>> +    if ( VPL011_IN_RING_EMPTY(intf) )
>> +    {
>> +        d->arch.vpl011.flag |= (VPL011_UARTFR_RXFE);
>> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_RXRIS);
>> +    }
>> +
>> +    /*
>> +     * clear the RX FIFO full flag
>> +     */
>> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_RXFF);
>> +
>> +    VPL011_UNLOCK(d, flags);
>> +
>> +    return rc;
>> +}
>> +
>> +int vpl011_write_data(struct domain *d, unsigned char data)
>
>
> Same has for vpl011_read_data.
>
>
>> +{
>> +    int rc=0;
>> +    unsigned long flags;
>> +    struct console_interface *intf=(struct console_interface
>> *)d->arch.vpl011.ring_buf;
>> +
>> +    VPL011_LOCK(d, flags);
>> +
>> +    /*
>> +     * if there is space in the ring buffer then write the data
>> +     */
>> +    if ( !VPL011_OUT_RING_FULL(intf) )
>> +    {
>> +        intf->out[MASK_VPL011CONS_IDX(intf->out_prod++, intf->out)] =
>> data;
>> +        smp_wmb();
>> +    }
>> +
>> +    /*
>> +     * if there is no space in the ring buffer then set the
>> +     * TX FIFO FULL flag
>> +     */
>> +    if ( VPL011_OUT_RING_FULL(intf) )
>> +    {
>> +        d->arch.vpl011.flag |= (VPL011_UARTFR_TXFF);
>> +        d->arch.vpl011.raw_intr_status &= ~(VPL011_UARTRIS_TXRIS);
>> +    }
>> +
>> +    /*
>> +     * set the uart busy status
>> +     */
>> +    d->arch.vpl011.flag |= (VPL011_UARTFR_BUSY);
>> +
>> +    /*
>> +     * clear the TX FIFO empty flag
>> +     */
>> +    d->arch.vpl011.flag &= ~(VPL011_UARTFR_TXFE);
>> +
>> +    VPL011_UNLOCK(d, flags);
>> +
>> +    /*
>> +     * raise an event to dom0 only if it is the first character in the
>> buffer
>> +     */
>> +    if ( VPL011_RING_DEPTH(intf, out) == 1 )
>> +    {
>> +        rc = raw_evtchn_send(d,
>> +
>> d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN], NULL);
>> +
>> +        if ( rc < 0 )
>> +            printk("Failed to send vpl011 interrupt to dom0\n");
>> +    }
>> +
>> +    return rc;
>> +}
>> +
>> +static void vpl011_notification(struct vcpu *v, unsigned int port)
>> +{
>> +    vpl011_data_avail(v->domain);
>
>
> vpl011_data_avail is returning an error but you don't check. What is the
> point of it then?
>
>> +}
>> +
>> +int domain_vpl011_init(struct domain *d)
>
>
> I was expected a destroy function to clean-up the vpl011 emulation.
>
I will add a deinit function.

>> +{
>> +    int rc=0;
>> +
>> +    /*
>> +     * register xen event channel
>> +     */
>> +    rc = alloc_unbound_xen_event_channel(d, 0,
>> current->domain->domain_id,
>> +
>> vpl011_notification);
>
>
> This line looks wrong to me. The console backend may not live in the same
> domain as the toolstack.

How should I figure out the correct domain where xenconsoled is
running?
>
>> +    if (rc < 0)
>> +    {
>> +        printk ("Failed to allocate vpl011 event channel\n");
>> +        return rc;
>> +    }
>> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN] = rc;
>> +
>> +    /*
>> +     * allocate an SPI VIRQ for the guest
>> +     */
>> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ] =
>> vgic_allocate_spi(d);
>
>
> It makes little sense to hardcode the MMIO region and not the SPI. Also, I
> would rather avoid to introduce new HVM_PARAM when not necessary. So
> hardcoding the value looks more sensible to me.
>
So for reserving a SPI for vpl011, should I reserve one bit in the
vgic.allocated_irqs bitmap in domain_vgic_init(), say 988, for vpl011?
I think if I am going to reserve 1 SPI for vpl011 then I need not bump
up nr_spis by 1.

>> +
>> +    /*
>> +     * register mmio handler
>> +     */
>> +    register_mmio_handler (d, &vpl011_mmio_handler, GUEST_PL011_BASE,
>> GUEST_PL011_SIZE, NULL);
>
>
> Coding style. No space between the function name and (.
>
Ok. I will remove the space.

>> +
>> +    /*
>> +     * initialize the lock
>> +     */
>> +    spin_lock_init(&d->arch.vpl011.lock);
>> +
>> +    /*
>> +     * clear the flag, control and interrupt status registers
>> +     */
>> +    d->arch.vpl011.control = 0;
>> +    d->arch.vpl011.flag = 0;
>> +    d->arch.vpl011.intr_mask = 0;
>> +    d->arch.vpl011.intr_clear = 0;
>> +    d->arch.vpl011.raw_intr_status = 0;
>> +    d->arch.vpl011.masked_intr_status = 0;
>
>
>
> The domain structure is already zeroed. So no need to 0 it again.
>
Ok.
>> +
>> +    return 0;
>> +}
>
>
> Missing e-macs magic here.
>
>> diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h
>> new file mode 100644
>> index 0000000..f2c577f
>> --- /dev/null
>> +++ b/xen/arch/arm/vpl011.h
>
>
> Header should live in include.
>
I will move vpl011.h to xen/include/xen.
> [...]
>
>> +#ifndef _VPL011_H_
>> +
>> +#define _VPL011_H_
>> +
>> +/*
>> + * register offsets
>> + */
>
>
> We already define the PL011 register in include/asm-arm/pl011-uart.h. Please
> re-use them rather than re-inventing the wheel.
>
>> +#define VPL011_UARTDR_OFFSET    0x0 // data register (RW)
>> +#define VPL011_UARTRSR_OFFSET   0x4 // receive status and error clear
>> register (RW)
>> +#define VPL011_UARTFR_OFFSET    0x18 // flag register (RO)
>> +#define VPL011_UARTRIS_OFFSET   0x3c // raw interrupt status register
>> (RO)
>> +#define VPL011_UARTMIS_OFFSET   0x40 // masked interrupt status register
>> (RO)
>> +#define VPL011_UARTIMSC_OFFSET  0x38 // interrupt mask set/clear register
>> (RW)
>> +#define VPL011_UARTICR_OFFSET   0x44 // interrupt clear register (WO)
>> +#define VPL011_UARTCR_OFFSET    0x30 // uart control register
>> +#define VPL011_UARTDMACR_OFFSET 0x48 // uart dma control register
>
>
I will reuse the pl011-uart definitions.

>
> [...]
>
>> +#define MASK_VPL011CONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
>> +struct console_interface {
>> +    char in[1024];
>> +    char out[2048];
>> +    uint32_t in_cons, in_prod;
>> +    uint32_t out_cons, out_prod;
>> +};
>> +#endif
>
>
> The communication between Xen and the console backend is based on the PV
> console ring. It would be easier to re-use it rather than recreating one.
>
I will reuse the ring definition.

>> diff --git a/xen/common/Kconfig b/xen/common/Kconfig
>> index f2ecbc4..7e2feac 100644
>> --- a/xen/common/Kconfig
>> +++ b/xen/common/Kconfig
>> @@ -237,4 +237,10 @@ config FAST_SYMBOL_LOOKUP
>>           The only user of this is Live patching.
>>
>>           If unsure, say Y.
>> +
>> +config VPL011_CONSOLE
>> +       bool "Emulated pl011 console support"
>> +       default y
>> +       ---help---
>> +         Allows a guest to use pl011 UART as a console
>>  endmenu
>
>
> This should go in arch/arm/Kconfig
>
Ok.

>> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
>> index 2d6fbb1..ff2403a 100644
>> --- a/xen/include/asm-arm/domain.h
>> +++ b/xen/include/asm-arm/domain.h
>> @@ -40,6 +40,7 @@ struct vtimer {
>>          uint64_t cval;
>>  };
>>
>> +
>
>
> Spurious line.
>
>>  struct arch_domain
>>  {
>>  #ifdef CONFIG_ARM_64
>> @@ -131,6 +132,20 @@ struct arch_domain
>>      struct {
>>          uint8_t privileged_call_enabled : 1;
>>      } monitor;
>> +
>> +#ifdef CONFIG_VPL011_CONSOLE
>> +    struct vpl011 {
>> +        void *ring_buf;
>> +        struct page_info *ring_page;
>> +        uint32_t    flag;               /* flag register */
>> +        uint32_t    control;            /* control register */
>> +        uint32_t    intr_mask;          /* interrupt mask register*/
>> +        uint32_t    intr_clear;         /* interrupt clear register */
>> +        uint32_t    raw_intr_status;    /* raw interrupt status register
>> */
>> +        uint32_t    masked_intr_status; /* masked interrupt register */
>> +        spinlock_t  lock;
>> +    } vpl011;
>> +#endif
>
>
> I think the structure should be defined in vpl011.h.
>
I will move the definition to vpl011.h.

>>  }  __cacheline_aligned;
>>
>>  struct arch_vcpu
>> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
>> index bd974fb..1d4548f 100644
>> --- a/xen/include/public/arch-arm.h
>> +++ b/xen/include/public/arch-arm.h
>> @@ -410,6 +410,10 @@ typedef uint64_t xen_callback_t;
>>  #define GUEST_ACPI_BASE 0x20000000ULL
>>  #define GUEST_ACPI_SIZE 0x02000000ULL
>>
>> +/* PL011 mappings */
>> +#define GUEST_PL011_BASE    0x22000000ULL
>> +#define GUEST_PL011_SIZE    0x00001000ULL
>> +
>>  /*
>>   * 16MB == 4096 pages reserved for guest to use as a region to map its
>>   * grant table in.
>> @@ -420,6 +424,7 @@ typedef uint64_t xen_callback_t;
>>  #define GUEST_MAGIC_BASE  xen_mk_ullong(0x39000000)
>>  #define GUEST_MAGIC_SIZE  xen_mk_ullong(0x01000000)
>>
>> +
>
>
> Spurious line.
>
>>  #define GUEST_RAM_BANKS   2
>>
>>  #define GUEST_RAM0_BASE   xen_mk_ullong(0x40000000) /* 3GB of low RAM @
>> 1GB */
>>
>
> Cheers,
>
> --
> Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-21 19:38       ` Julien Grall
@ 2017-03-23  9:44         ` Bhupinder Thakur
  2017-03-23 13:51           ` Julien Grall
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-23  9:44 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, nd, Stefano Stabellini

Hi Julien,


>>>> +            break;
>>>> +        case VPL011_UARTDR_OFFSET:
>>>> +            vpl011_read_data(v->domain, &ch);
>>>
>>>
>>>
>>> Should not you check the return value of vpl011_read_data? Also, what if
>>> there is no data?
>>
>> This condition should not happen because the RX FIFO empty bit would
>> be set in the UARTFR register when the last data is read from the ring
>> buffer and the the guest is not supposed to issue next read until the
>> RX FIFO empty bit is cleared indicating there is more data now.
>
>
> What you describe is how a well-behave guest will interact with the pl011
> emulation. It does not describe what would happen if a misbehaved guest will
> read continuously the register.
>
> I cannot find any things in the spec about what should be the state of the
> register if no data is available. So I guess we just need to ensure that we
> don't leak in information from the stack. This seems to be addressed by
> *data = 0 in "vpl011_read_data".
>
> Please document it to avoid removing it by mistake in the future.
>
Ok. I will add a comment.

>>
>>>
>>>> +            *r = ch;
>>>> +            break;
>>>> +        case VPL011_UARTFR_OFFSET:
>>>> +            *r = v->domain->arch.vpl011.flag;
>>>
>>>
>>>
>>> I am fairly surprised that none of this code is actually protected by
>>> lock.
>>> For instance the update of flag is not atomic. So is it safe?
>>
>> For reading, I thought no locking was required, as I believe a 32-bit
>> value read/write on ARM should be atomic. So if the value is modified
>> in some other context while it is being read in another context, the
>> reader should see either the old value or the new value.
>> For register writes, yes I need to take a lock where I am updating
>> certain bits in the register. I will add the locking there.
>
>
> Fair point. I was more worry about ordering between read/write between
> multiple vCPU. But I guess we don't care if the read does not return an
> update to date value.
>
>>
>>>
>>>> +            break;
>>>> +        case VPL011_UARTIMSC_OFFSET:
>>>> +            *r = v->domain->arch.vpl011.intr_mask;
>>>> +            break;
>>>> +        case VPL011_UARTICR_OFFSET:
>>>> +            *r = 0;
>>>
>>>
>>>
>>> Looking at the spec, this register is write-only. So why do you implement
>>> RAZ?
>>
>> In such cases, where the guest tries to write to RO register or tries
>> to read a WO register, should I send a abort to the guest?
>
>
> I don't see any behavior requirement in the spec. So I would send an abort
> to the guest (e.g return 0 in the function).
>
Ok.
>>>
>>>> +            break;
>>>> +        case VPL011_UARTRIS_OFFSET:
>>>> +            *r = v->domain->arch.vpl011.raw_intr_status;
>>>> +            break;
>>>> +        case VPL011_UARTMIS_OFFSET:
>>>> +            *r = v->domain->arch.vpl011.raw_intr_status &
>>>> +                                v->domain->arch.vpl011.intr_mask;
>>>> +            break;
>>>> +        case VPL011_UARTDMACR_OFFSET:
>>>> +            *r = 0; /* uart DMA is not supported. Here it always
>>>> returns
>>>> 0 */
>>>
>>>
>>>
>>> My understanding of the spec is DMA is not optional. So what would happen
>>> if
>>> the guest tries to enable it?
>>>
>>>> +            break;
>>>> +        case VPL011_UARTRSR_OFFSET:
>>>> +            *r = 0; /* it always returns 0 as there are no physical
>>>> errors */
>>>
>>>
>>>
>>> This register contains contains the bit OE that tells whether the FIFO is
>>> full or not. The FIFO here is the PV ring, so maybe we should set this
>>> bit
>>> if the ring is full.
>>
>> The OE condition will not happen in this case since xenconsole will
>> not write more data to the guest if the ring buffer is full. There is
>> a separate UARTFR status bit which indicates whether the ring buffer
>> is full.
>
>
> Sorry I still don't get it. Xenconsole will likely have to hold characters
> that are not written in the PV console. I would have expected that this
> would be used to set the OE bit. Did I miss anything?
I think OE bit is more applicable to physical UART, where data may
arrive while the hardware RX FIFO is already full. In that case, it
has to drop the incoming data but it also sets the OE bit to indicate
that overflow condition happened. In our case, since the ring buffer
acts as a flow control mechanism (i.e. if ring buffer is full then
xenconsole stops writing more data and hold the data) this condition
may not happen.

The pl011 emulation code does not know if xenconsole is holding the
data when the ring buffer is full. One thing we could do is to treat
the ring buffer full condition as an indication that overflow is
likely to happen and set this bit. Typically, the data rate from
xenconsole to the guest would be very low for this condition to ever
happen.
>
>>>
>>>> +            break;
>>>> +        default:
>>>> +            printk ("vpl011_mmio_read: invalid switch case %d\n",
>>>> (int)(info->gpa - GUEST_PL011_BASE));
>>>
>>>
>>>
>>> Coding style: printk(...).
>>>
>>> Also, printk is not ratelimited by default. Please use gprintk(...) which
>>> will be ratelimited and print the domain information. This is useful when
>>> you have multiple guest.
>>>
>> Replaced printk with gprintk.
>>
>>>> +            break;
>>>> +    }
>>>> +
>>>> +    return VPL011_EMUL_OK;
>>>
>>>
>>>
>>> Please use plain value as the return is not pl011 specific. Also, I am a
>>> bit
>>> surprised that you return "ok" even when a register as not been emulated.
>>> IHMO, a data abort should be sent to the guest.
>>
>>
>> Corrected this. Now it returns an error incase the register is not
>> emulated . For the return values, I see that typically values 1/0 are
>> returned like in vgic-v2/3.c. Are there some common macros which I can
>> use?
>
>
> No. I want to replace 0/1 by false/true but I never had the time to do the
> work.
>
I will use true/false.

Regards,
Bhupinder

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-23  9:44         ` Bhupinder Thakur
@ 2017-03-23 13:51           ` Julien Grall
  0 siblings, 0 replies; 82+ messages in thread
From: Julien Grall @ 2017-03-23 13:51 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

Hi Bhupinder,

On 23/03/17 09:44, Bhupinder Thakur wrote:
>>>>
>>>>> +            break;
>>>>> +        case VPL011_UARTRIS_OFFSET:
>>>>> +            *r = v->domain->arch.vpl011.raw_intr_status;
>>>>> +            break;
>>>>> +        case VPL011_UARTMIS_OFFSET:
>>>>> +            *r = v->domain->arch.vpl011.raw_intr_status &
>>>>> +                                v->domain->arch.vpl011.intr_mask;
>>>>> +            break;
>>>>> +        case VPL011_UARTDMACR_OFFSET:
>>>>> +            *r = 0; /* uart DMA is not supported. Here it always
>>>>> returns
>>>>> 0 */
>>>>
>>>>
>>>>
>>>> My understanding of the spec is DMA is not optional. So what would happen
>>>> if
>>>> the guest tries to enable it?
>>>>
>>>>> +            break;
>>>>> +        case VPL011_UARTRSR_OFFSET:
>>>>> +            *r = 0; /* it always returns 0 as there are no physical
>>>>> errors */
>>>>
>>>>
>>>>
>>>> This register contains contains the bit OE that tells whether the FIFO is
>>>> full or not. The FIFO here is the PV ring, so maybe we should set this
>>>> bit
>>>> if the ring is full.
>>>
>>> The OE condition will not happen in this case since xenconsole will
>>> not write more data to the guest if the ring buffer is full. There is
>>> a separate UARTFR status bit which indicates whether the ring buffer
>>> is full.
>>
>>
>> Sorry I still don't get it. Xenconsole will likely have to hold characters
>> that are not written in the PV console. I would have expected that this
>> would be used to set the OE bit. Did I miss anything?
> I think OE bit is more applicable to physical UART, where data may
> arrive while the hardware RX FIFO is already full.

 From my understanding, the ring is the RX FIFO and xenconsole will act 
of the "user" of the hardware. Hence why I though OE should be set if 
the ring is full.

Anyway, both point of views are valid, you should just document what has 
been chosen.

>>
>>>>
>>>>> +            break;
>>>>> +        default:
>>>>> +            printk ("vpl011_mmio_read: invalid switch case %d\n",
>>>>> (int)(info->gpa - GUEST_PL011_BASE));
>>>>
>>>>
>>>>
>>>> Coding style: printk(...).
>>>>
>>>> Also, printk is not ratelimited by default. Please use gprintk(...) which
>>>> will be ratelimited and print the domain information. This is useful when
>>>> you have multiple guest.
>>>>
>>> Replaced printk with gprintk.
>>>
>>>>> +            break;
>>>>> +    }
>>>>> +
>>>>> +    return VPL011_EMUL_OK;
>>>>
>>>>
>>>>
>>>> Please use plain value as the return is not pl011 specific. Also, I am a
>>>> bit
>>>> surprised that you return "ok" even when a register as not been emulated.
>>>> IHMO, a data abort should be sent to the guest.
>>>
>>>
>>> Corrected this. Now it returns an error incase the register is not
>>> emulated . For the return values, I see that typically values 1/0 are
>>> returned like in vgic-v2/3.c. Are there some common macros which I can
>>> use?
>>
>>
>> No. I want to replace 0/1 by false/true but I never had the time to do the
>> work.
>>
> I will use true/false.

It is not what I said. We should not mix true/false with int. My point 
was that I have an action to switch the return type for int to bool. For 
the time being we should use 0/1.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-23  9:14     ` Bhupinder Thakur
@ 2017-03-23 14:16       ` Julien Grall
  2017-03-24 10:39         ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Julien Grall @ 2017-03-23 14:16 UTC (permalink / raw)
  To: Bhupinder Thakur; +Cc: xen-devel, nd, Stefano Stabellini

On 23/03/17 09:14, Bhupinder Thakur wrote:
> .Hi Julien,

Hi Bhupinder,

> On 5 March 2017 at 17:42, Julien Grall <julien.grall@arm.com> wrote:
>> Hi Bhupinder,
>>
>> On 21/02/17 11:25, Bhupinder Thakur wrote:
>>>
>>> diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
>>
>> Lastly, what if vpl011_write_data is returning an error?
>>
> Normally vpl011_write_data() should not fail since the guest should
> stop writing more data once the ring buffer goes full and TXFF bit is
> set in UARTFR.
> So there should always be space in the ring buffer for the next data
> when a mmio write happens.
>
> If the guest still writes when ring buffer is already full then data
> would be lost.

If the return code is meaningless, then the function should be void. 
Also, the behavior should be documented.

[...]

>>> +{
>>> +    int rc=0;
>>> +
>>> +    /*
>>> +     * register xen event channel
>>> +     */
>>> +    rc = alloc_unbound_xen_event_channel(d, 0,
>>> current->domain->domain_id,
>>> +
>>> vpl011_notification);
>>
>>
>> This line looks wrong to me. The console backend may not live in the same
>> domain as the toolstack.
>
> How should I figure out the correct domain where xenconsoled is
> running?

I think you would to pass the console domain id from the toolstack (see 
console->backend_domid).

>>
>>> +    if (rc < 0)
>>> +    {
>>> +        printk ("Failed to allocate vpl011 event channel\n");
>>> +        return rc;
>>> +    }
>>> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_CONSOLE_EVTCHN] = rc;
>>> +
>>> +    /*
>>> +     * allocate an SPI VIRQ for the guest
>>> +     */
>>> +    d->arch.hvm_domain.params[HVM_PARAM_VPL011_VIRQ] =
>>> vgic_allocate_spi(d);
>>
>>
>> It makes little sense to hardcode the MMIO region and not the SPI. Also, I
>> would rather avoid to introduce new HVM_PARAM when not necessary. So
>> hardcoding the value looks more sensible to me.
>>
> So for reserving a SPI for vpl011, should I reserve one bit in the
> vgic.allocated_irqs bitmap in domain_vgic_init(), say 988, for vpl011?
> I think if I am going to reserve 1 SPI for vpl011 then I need not bump
> up nr_spis by 1.

Regardless the solution solution, nr_spis still need to be incremented. 
This field is used to know the number of SPIs exposed to the guest.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-03 20:02   ` Konrad Rzeszutek Wilk
@ 2017-03-24  6:58     ` Bhupinder Thakur
  0 siblings, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-24  6:58 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk; +Cc: xen-devel, Julien Grall, Stefano Stabellini

Hi Konrad,

On 4 March 2017 at 01:32, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> wrote:
> On Tue, Feb 21, 2017 at 04:55:59PM +0530, Bhupinder Thakur wrote:
>> Three new HVM param handlers added for:
>>     - allocating a new VIRQ and return to the toolstack
>>     - allocating a new event channel for sending/receiving events from Xen and return
>>       to the toolstack
>>     - mapping the PFN allocted by the toolstack to be used as IN/OUT ring buffers
>>
>> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
>> ---
>>  xen/arch/arm/hvm.c              | 39 +++++++++++++++++++++++++++++++++++++++
>>  xen/include/public/hvm/params.h | 10 +++++++++-
>>  2 files changed, 48 insertions(+), 1 deletion(-)
>>
>> diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c
>> index d999bde..f3b9eb1 100644
>> --- a/xen/arch/arm/hvm.c
>> +++ b/xen/arch/arm/hvm.c
>> @@ -23,6 +23,8 @@
>>  #include <xen/guest_access.h>
>>  #include <xen/sched.h>
>>  #include <xen/monitor.h>
>> +#include <xen/event.h>
>> +#include <xen/vmap.h>
>>
>>  #include <xsm/xsm.h>
>>
>> @@ -31,6 +33,7 @@
>>  #include <public/hvm/hvm_op.h>
>>
>>  #include <asm/hypercall.h>
>> +#include "vpl011.h"
>>
>>  long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>>  {
>> @@ -61,9 +64,45 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>>          if ( op == HVMOP_set_param )
>>          {
>>              d->arch.hvm_domain.params[a.index] = a.value;
>> +
>> +#ifdef CONFIG_VPL011_CONSOLE
>> +            /*
>> +             * if it is a vpl011 console pfn then map it to its
>
> s/if/If/
>> +             * own address space
>
> And you can also add an . here.
>
>> +             */
>> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN )
>> +            {
>> +                vpl011_map_guest_page(d);
>> +            }
>> +#else
>> +            /*
>> +             * if VPL011 is not compiled in then disallow setting of any
>> +             * related HVM params
>> +             */
>> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
>> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
>> +                 a.index == HVM_PARAM_VPL011_VIRQ )
>> +            {
>> +                rc = -1;
>> +                goto param_fail;
>> +            }
>> +#endif
>>          }
>>          else
>>          {
>> +#ifndef CONFIG_VPL011_CONSOLE
>> +            /*
>> +             * if VPL011 is not compiled in then disallow setting of any
>> +             * related HVM params
>> +             */
>> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
>> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
>> +                 a.index == HVM_PARAM_VPL011_VIRQ )
>> +            {
>> +                rc = -1;
>> +                goto param_fail;
>
> This and the above look like it could be nicely folded in a function?
>
> Say:
>
> static bool vpl011_built(unsigned int idx)
> {
> #ifdef CONFIG_VPL011_CONSOLE
>         if ( idx == ..
>                 return true;
> #else
>         return false;
> }
>
> And here you can just do:
>         if (vpl011_built())
>         {
>                 rc = -1;
>         .. and so on.
>
>> +            }
>> +#endif
Using vpl011_built() removes the #ifdef from the code. But I still
need to check that the param is a vpl011 param before calling
vpl011_built() to decide whether to handle it or
flag an error.
So I have modified the code like this:

static bool vpl011_built()
{
#ifdef CONFIG_VPL011_CONSOLE
         return true;
#else
         return false;
#endif
}

if ( a.index == vpl011_param1 || a.index == vpl011_param2 || ... )
{
      if ( vpl011_built() )
      {
            /* handle vpl011 params */
           ...
      }
      else
      {
             rc = -1;
             ...
      }
}
... continue as usual for other parameters

>>              a.value = d->arch.hvm_domain.params[a.index];
>>              rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
>>          }
>> diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
>> index 3f54a49..13bf719 100644
>> --- a/xen/include/public/hvm/params.h
>> +++ b/xen/include/public/hvm/params.h
>> @@ -203,10 +203,17 @@
>>   */
>>  #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
>>
>> -/* Deprecated */
>> +#if defined(__arm__) || defined(__aarch64__)
>> +#define HVM_PARAM_VPL011_CONSOLE_PFN    20
>> +#define HVM_PARAM_VPL011_CONSOLE_EVTCHN 21
>> +#define HVM_PARAM_VPL011_VIRQ           22
>> +#else
>>  #define HVM_PARAM_MEMORY_EVENT_CR0          20
>>  #define HVM_PARAM_MEMORY_EVENT_CR3          21
>>  #define HVM_PARAM_MEMORY_EVENT_CR4          22
>> +#endif
>> +
>> +/* Deprecated */
>>  #define HVM_PARAM_MEMORY_EVENT_INT3         23
>>  #define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP  25
>>  #define HVM_PARAM_MEMORY_EVENT_MSR          30
>> @@ -253,6 +260,7 @@
>>   */
>>  #define HVM_PARAM_X87_FIP_WIDTH 36
>>
>> +
Removed extra line.
>
>
> ???
>>  #define HVM_NR_PARAMS 37
>>
>>  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
>> --
>> 2.7.4
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-05 12:35   ` Julien Grall
  2017-03-06  8:06     ` Jan Beulich
@ 2017-03-24  7:31     ` Bhupinder Thakur
  1 sibling, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-24  7:31 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Jan Beulich, xen-devel, nd

Hi Julien,


>> Three new HVM param handlers added for:
>>     - allocating a new VIRQ and return to the toolstack
>
>
> This is not necessary. We could hardcode it.
I will modify the code to use a fixed SPI for vpl011.

>
>>     - allocating a new event channel for sending/receiving events from Xen
>> and return
>>       to the toolstack
>>     - mapping the PFN allocted by the toolstack to be used as IN/OUT ring
>> buffers
>
>
> s/allocted/allocated/
>
>
>>
>> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
>> ---
>>  xen/arch/arm/hvm.c              | 39
>> +++++++++++++++++++++++++++++++++++++++
>>  xen/include/public/hvm/params.h | 10 +++++++++-
>>  2 files changed, 48 insertions(+), 1 deletion(-)
>>
>> diff --git a/xen/arch/arm/hvm.c b/xen/arch/arm/hvm.c
>> index d999bde..f3b9eb1 100644
>> --- a/xen/arch/arm/hvm.c
>> +++ b/xen/arch/arm/hvm.c
>> @@ -23,6 +23,8 @@
>>  #include <xen/guest_access.h>
>>  #include <xen/sched.h>
>>  #include <xen/monitor.h>
>> +#include <xen/event.h>
>> +#include <xen/vmap.h>
>>
>>  #include <xsm/xsm.h>
>>
>> @@ -31,6 +33,7 @@
>>  #include <public/hvm/hvm_op.h>
>>
>>  #include <asm/hypercall.h>
>> +#include "vpl011.h"
>>
>>  long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg)
>>  {
>> @@ -61,9 +64,45 @@ long do_hvm_op(unsigned long op,
>> XEN_GUEST_HANDLE_PARAM(void) arg)
>>          if ( op == HVMOP_set_param )
>>          {
>>              d->arch.hvm_domain.params[a.index] = a.value;
>> +
>> +#ifdef CONFIG_VPL011_CONSOLE
>> +            /*
>> +             * if it is a vpl011 console pfn then map it to its
>> +             * own address space
>> +             */
>> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN )
>> +            {
>> +                vpl011_map_guest_page(d);
>
>
> vpl011_map_guest_page(...) is will return an error if it fails to map the
> page. Shouldn't you propagate the value.
I will propagate the value.

>
> Also, this code does not prevent the new HVM param to be set twice or even
> set by the guest. We probably want to introduce an helper to check if the
> domain is allowed to set it. See hvm_allow_set_param on x86.
How are these checks done on ARM currently?

>
>> +            }
>> +#else
>> +            /*
>> +             * if VPL011 is not compiled in then disallow setting of any
>> +             * related HVM params
>> +             */
>
>
> We really don't care if the toolstack set unused HVM param as they should
> not be used.
If the toolstack tries to set/get the vpl011 parameters (because user
has enabled pl011 emulation in libxl) while vpl011 support is compiled
out in Xen,
I wanted the toolstack to handle the failure case correctly.

>
>> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
>> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
>> +                 a.index == HVM_PARAM_VPL011_VIRQ )
>> +            {
>> +                rc = -1;
>> +                goto param_fail;
>> +            }
>> +#endif
>>          }
>>          else
>>          {
>> +#ifndef CONFIG_VPL011_CONSOLE
>> +            /*
>> +             * if VPL011 is not compiled in then disallow setting of any
>> +             * related HVM params
>> +             */
>> +            if ( a.index == HVM_PARAM_VPL011_CONSOLE_PFN ||
>> +                 a.index == HVM_PARAM_VPL011_CONSOLE_EVTCHN ||
>> +                 a.index == HVM_PARAM_VPL011_VIRQ )
>> +            {
>> +                rc = -1;
>> +                goto param_fail;
>> +            }
>> +#endif
>
>
> Ditto.
>
>>              a.value = d->arch.hvm_domain.params[a.index];
>
>
> We probably don't want the guest to be able to read the console pfn page.
> See hvm_allow_get_param.
>
>>              rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
>>          }
>> diff --git a/xen/include/public/hvm/params.h
>> b/xen/include/public/hvm/params.h
>> index 3f54a49..13bf719 100644
>> --- a/xen/include/public/hvm/params.h
>> +++ b/xen/include/public/hvm/params.h
>> @@ -203,10 +203,17 @@
>>   */
>>  #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
>>
>> -/* Deprecated */
>> +#if defined(__arm__) || defined(__aarch64__)
>> +#define HVM_PARAM_VPL011_CONSOLE_PFN    20
>> +#define HVM_PARAM_VPL011_CONSOLE_EVTCHN 21
>> +#define HVM_PARAM_VPL011_VIRQ           22
>> +#else
>>  #define HVM_PARAM_MEMORY_EVENT_CR0          20
>>  #define HVM_PARAM_MEMORY_EVENT_CR3          21
>>  #define HVM_PARAM_MEMORY_EVENT_CR4          22
>
>
> Those parameters are still deprecated but you drop the comment stating that.
Added the deprecated comment for x86.
>
>> +#endif
>> +
>
>
> Those params are x86 specific so should have never been set on ARM. But I am
> not sure if it is fine to re-purpose deprecated number.
>
> I have CCed "The REST" maintainers to have their input here.
>
>> +/* Deprecated */
>>  #define HVM_PARAM_MEMORY_EVENT_INT3         23
>>  #define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP  25
>>  #define HVM_PARAM_MEMORY_EVENT_MSR          30
>> @@ -253,6 +260,7 @@
>>   */
>>  #define HVM_PARAM_X87_FIP_WIDTH 36
>>
>> +
>
>
> Spurious change.
>
>>  #define HVM_NR_PARAMS 37
>>
>>  #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
>>
>
> Cheers,
>
> --
> Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation in Xen
  2017-03-23 14:16       ` Julien Grall
@ 2017-03-24 10:39         ` Bhupinder Thakur
  0 siblings, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-24 10:39 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel, nd, Stefano Stabellini

Hi Julien,

On 23 March 2017 at 19:46, Julien Grall <julien.grall@arm.com> wrote:
>>> It makes little sense to hardcode the MMIO region and not the SPI. Also,
>>> I
>>> would rather avoid to introduce new HVM_PARAM when not necessary. So
>>> hardcoding the value looks more sensible to me.
>>>
>> So for reserving a SPI for vpl011, should I reserve one bit in the
>> vgic.allocated_irqs bitmap in domain_vgic_init(), say 988, for vpl011?
>> I think if I am going to reserve 1 SPI for vpl011 then I need not bump
>> up nr_spis by 1.
>
>
> Regardless the solution solution, nr_spis still need to be incremented. This
> field is used to know the number of SPIs exposed to the guest.

The d->arch.vgic.allocated_irqs size is allocated based on the nr_spis
and the nr_spis is set to highest numbered irq requested by the user+1
by the toolstack (see libxl__arch_domain_prepare_config).

There are two possible values which we can reserve for vpl011 SPI:

1. Reserve one SPI for vpl011 at the end of the SPI range to 988
(1020-32), then nr_spis will have to be always set to 989.

2. Reserve one at the beginning of the range say 0 (i.e. virq number
32). In this case nr_spis will be set to 1.

I think 2nd option is better as it wastes less memory for maintaining
the irq bitmap data structures.

Let me know.

Regards,
Bhupinder

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 07/11] xen/arm: vpl011: Add two new vpl011 parameters to xenstore
  2017-03-03 20:58   ` Konrad Rzeszutek Wilk
@ 2017-03-28  7:49     ` Bhupinder Thakur
  0 siblings, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-28  7:49 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk; +Cc: xen-devel, Julien Grall, Stefano Stabellini

Hi Konrad,


>> Add two new parameters to the xen store:
>>     - newly allocated PFN to be used as IN/OUT ring buffer by xenconsoled
>>     - a new event channel read from Xen using a hvm call to be used by xenconsoled
>>       for eventing
>
> This should have a correspoinding change in the include/public/io/console.h
> describing this new 'vpl011-port' and 'vpl011-ring-ref' Xenbus entry.
>
> Feel free to lift from kbdif.h.
>
I tried looking at kbdif.h but could not find any xenbus entry
definitions. I looked at how "ring-ref" is defined which is used for
the PV console.
I tried to define "vpl011-ring-ref" in a similar way.

> Unless an earlier patch already does this? In which case you should
> mention it:
>

> "Patch titled XYZ introduces these XenBus entries in console.h"
>
>>
>> Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
>> ---
>>  tools/libxl/libxl.c          |  6 ++++++
>>  tools/libxl/libxl_dom.c      | 18 +++++++++++++++++-
>>  tools/libxl/libxl_internal.h |  4 ++++
>>  3 files changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
>> index d400fa2..cc00235 100644
>> --- a/tools/libxl/libxl.c
>> +++ b/tools/libxl/libxl.c
>> @@ -3159,6 +3159,12 @@ int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
>>          flexarray_append(ro_front, GCSPRINTF("%"PRIu32, state->console_port));
>>          flexarray_append(ro_front, "ring-ref");
>>          flexarray_append(ro_front, GCSPRINTF("%lu", state->console_mfn));
>> +#if defined(__arm__) || defined(__aarch64__)
>> +        flexarray_append(ro_front, "vpl011-port");
>> +        flexarray_append(ro_front, GCSPRINTF("%"PRIu32, state->vpl011_console_port));
>> +        flexarray_append(ro_front, "vpl011-ring-ref");
>> +        flexarray_append(ro_front, GCSPRINTF("%lu", state->vpl011_console_mfn));
>> +#endif
>
> so... what if the VPL011 is not enabled in the guest? Should we still
> create these XenBus entries?

I will add a libxl option for enabling/disabling pl011 emulation. Only
when this option is enabled,
vpl011-port and vpl011-ring-ref would be added to xenstore.

>
>>      } else {
>>          flexarray_append(front, "state");
>>          flexarray_append(front, GCSPRINTF("%d", XenbusStateInitialising));
>> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
>> index d519c8d..39eaff6 100644
>> --- a/tools/libxl/libxl_dom.c
>> +++ b/tools/libxl/libxl_dom.c
>> @@ -302,7 +302,7 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
>>      libxl_ctx *ctx = libxl__gc_owner(gc);
>>      char *xs_domid, *con_domid;
>>      int rc;
>> -    uint64_t size;
>> +    uint64_t size, val=-1;
>
> So -1 for uint64_t is 0xffffffff...
>
> Is that what you meant? And why? Why not not uint32_t?
I used -1 to indicate invalid event_channel since 0 might be a valid
event channel number.
Since xc_hvm_param_get() expects a uint64_t, I used a local variable
of type unit64_t.
>
>
>>
>>      if (xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus) != 0) {
>>          LOG(ERROR, "Couldn't set max vcpu count");
>> @@ -432,6 +432,16 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
>>      state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid);
>>      state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid);
>>
>> +#if defined(__arm__) || defined(__aarch64__)
>> +    /* get the vpl011 event channel from Xen */
>
> Please remove this comment.
Ok.
>
>> +    rc = xc_hvm_param_get(ctx->xch, domid, HVM_PARAM_VPL011_CONSOLE_EVTCHN,
>> +            &val);
>> +    if ( rc )
>> +        state->vpl011_console_port = -1;
>> +    else
>> +        state->vpl011_console_port = (uint32_t)val;
>> +#endif
>> +
>>      if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
>>          hvm_set_conf_params(ctx->xch, domid, info);
>>  #if defined(__i386__) || defined(__x86_64__)
>> @@ -727,6 +737,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
>>
>>      dom->flags = flags;
>>      dom->console_evtchn = state->console_port;
>> +#if defined(__arm__) || defined(__aarch64__)
>> +    dom->vpl011_console_evtchn = state->vpl011_console_port;
>> +#endif
>>      dom->console_domid = state->console_domid;
>>      dom->xenstore_evtchn = state->store_port;
>>      dom->xenstore_domid = state->store_domid;
>> @@ -771,6 +784,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
>>      if (xc_dom_feature_translated(dom)) {
>>          state->console_mfn = dom->console_pfn;
>>          state->store_mfn = dom->xenstore_pfn;
>> +#if defined(__arm__) || defined(__aarch64__)
>> +        state->vpl011_console_mfn = dom->vpl011_console_pfn;
>> +#endif
>>      } else {
>>          state->console_mfn = xc_dom_p2m(dom, dom->console_pfn);
>>          state->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn);
>> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
>> index 5f46578..10e262e 100644
>> --- a/tools/libxl/libxl_internal.h
>> +++ b/tools/libxl/libxl_internal.h
>> @@ -1128,6 +1128,10 @@ typedef struct {
>>      uint32_t num_vmemranges;
>>
>>      xc_domain_configuration_t config;
>> +#if defined(__arm__) || defined(__aarch64__)
>> +    unsigned long vpl011_console_mfn;
>> +#endif
>
> I am not a big fan of these #ifdef.
>
> Could they go away and this could would be compiled on x86 too but
> just never used? (The default value to use this owuld be disabled
> for example)?
>
>>  } libxl__domain_build_state;
>>
>>  _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid,
>> --
>> 2.7.4
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel
  2017-03-06 11:12           ` Bhupinder Thakur
@ 2017-03-28  9:43             ` Bhupinder Thakur
  0 siblings, 0 replies; 82+ messages in thread
From: Bhupinder Thakur @ 2017-03-28  9:43 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Wei Liu, GeorgeDunlap, AndrewCooper,
	Ian Jackson, Tim Deegan, Julien Grall, xen-devel, nd

Hi,

Now I am using notify_via_xen_event_channel() to send the vpl011
events to dom0. So no changes are required in evtchn_send() and this
patch can be dropped.

Regards,
Bhupinder

On 6 March 2017 at 16:42, Bhupinder Thakur <bhupinder.thakur@linaro.org> wrote:
> Hi,
>
> On 6 March 2017 at 16:24, Jan Beulich <JBeulich@suse.com> wrote:
>>>>> On 06.03.17 at 11:44, <bhupinder.thakur@linaro.org> wrote:
>>> On 6 March 2017 at 13:45, Jan Beulich <JBeulich@suse.com> wrote:
>>>>>>> On 05.03.17 at 13:39, <julien.grall@arm.com> wrote:
>>>>> On 02/21/2017 11:26 AM, Bhupinder Thakur wrote:
>>>>>> Breakup evtchn_send() to allow sending events for a Xen bound channel. Currently,
>>>>>> there is a check in evtchn_send() i.e. is_consumer_xen() that if the event channel
>>>>>> is bound to a xen consumer then event generation is not allowed for that channel.
>>>>>> This check is to disallow a guest from raising an event via this channel. However,
>>>>>> it should allow Xen to send a event via this channel as it is required for sending
>>>>>> vpl011 event to the dom0.
>>>>>>
>>>>>> This change introduces a new function raw_evtchn_send() which sends the event
>>>>>> without this check. The current evtchn_send() calls this function after doing the
>>>>>> xen consumer check. Xen uses the raw_evtchm_send() version to send the event thus
>>>>>> bypassing the check.
>>>>
>>>> Why would Xen want to send an event it is itself the consumer of?
>>>> Surely there are better ways to communicate state internally? The
>>>> more that you say you want the event sent to Dom0...
>>>>
>>> As a consumer, Xen receives event from dom0. It also needs to send
>>> events to dom0 to indicate that there is data in the ring buffer for
>>> dom0 to read. I am using a xen bound event channel for
>>> sending/receiving events to/from dom0. I added a new function
>>> raw_evtchn_send() to allow Xen to send events to dom0 without doing
>>> the is_xen_consumer check. Note that this check is still there in
>>> evtchn_send() to disallow guests to raise events on the xen bound
>>> channel.
>>
>> I can see why Xen needs to send events; I can't see why Dom0 couldn't
>> simply make a hypercall instead of sending an event if it needs to signal
>> something.
>>
> We decided to reuse the same PV console interface for pl011 as used
> for PV console in xenconsole running on dom0, which is events/ring
> buffer based. From xenconsole point of view, there is no difference in
> terms of handling a pl011 console and a PV console.
>
>> Jan
>>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-03-08 18:22                   ` Stefano Stabellini
@ 2017-04-11 14:38                     ` Bhupinder Thakur
  2017-04-11 22:07                       ` Stefano Stabellini
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-04-11 14:38 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, George Dunlap, AndrewCooper, IanJackson, Tim Deegan,
	Julien Grall, Jan Beulich, xen-devel

Hi,

Kindly let me know if my understanding is correct.

Using a domctl API will allow us to keep the vUART configuration
flexible. Currently, we can operate on one ring-buf PFN and an event
channel port only for a single vUART but if we use DOMCTL interface,
then we can effectively get/set multiple event channel ports/multiple
PFNs from/to Xen in a single domctl call.

I am not clear who will be the caller of this domctl API. Is it
xenconsoled or the toolstack? Currently, xenconsoled reads the
ring-buf PFN and event channel from the xenstore, which is populated
by the toolstack.

Regards,
Bhupinder

On 8 March 2017 at 23:52, Stefano Stabellini <sstabellini@kernel.org> wrote:
> On Wed, 8 Mar 2017, Jan Beulich wrote:
>> >>> On 08.03.17 at 15:45, <julien.grall@arm.com> wrote:
>> > I was looking at the backend code and see it is using DOMCTL command. I
>> > guess it is considered that the console backend will be tied to a
>> > specific Xen version. Am I correct?
>>
>> I don't think I'm qualified to talk about the console backend
>> implementation (and possible quirks it has). Generally I'd expect
>> backends not to use domctl-s, as that would tie them to the tool
>> stack domain.
>>
>> > so maybe we can introduce new domctl command for handling vUART. This
>> > would avoid us to commit on an ABI and allow us to extend it if
>> > necessary in the future to support multiple UARTs.
>>
>> Well, without having the context of who it would be to use such a
>> domctl (and for what purpose) I don#t think I can comment here.
>
> I guess the assumption was that xenconsoled was part of the Xen tools.
> Indeed, it is part of the tools and is installed as such.
>
> I don't have an opinion on this. If introducing a new DOMCTL makes the
> code nicer in xen and xenconsoled, taking away some edges, like the
> changes to evtchn_send, then we should probably just do it.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-04-11 14:38                     ` Bhupinder Thakur
@ 2017-04-11 22:07                       ` Stefano Stabellini
  2017-04-14  7:12                         ` Bhupinder Thakur
  0 siblings, 1 reply; 82+ messages in thread
From: Stefano Stabellini @ 2017-04-11 22:07 UTC (permalink / raw)
  To: Bhupinder Thakur
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Julien Grall, Jan Beulich, xen-devel

On Tue, 11 Apr 2017, Bhupinder Thakur wrote:
> Hi,
> 
> Kindly let me know if my understanding is correct.
> 
> Using a domctl API will allow us to keep the vUART configuration
> flexible. Currently, we can operate on one ring-buf PFN and an event
> channel port only for a single vUART but if we use DOMCTL interface,
> then we can effectively get/set multiple event channel ports/multiple
> PFNs from/to Xen in a single domctl call.
> 
> I am not clear who will be the caller of this domctl API. Is it
> xenconsoled or the toolstack? Currently, xenconsoled reads the
> ring-buf PFN and event channel from the xenstore, which is populated
> by the toolstack.

The caller could be either, but I think it would make sense for it to be
xenconsoled to cut the middle-man (xl).


> On 8 March 2017 at 23:52, Stefano Stabellini <sstabellini@kernel.org> wrote:
> > On Wed, 8 Mar 2017, Jan Beulich wrote:
> >> >>> On 08.03.17 at 15:45, <julien.grall@arm.com> wrote:
> >> > I was looking at the backend code and see it is using DOMCTL command. I
> >> > guess it is considered that the console backend will be tied to a
> >> > specific Xen version. Am I correct?
> >>
> >> I don't think I'm qualified to talk about the console backend
> >> implementation (and possible quirks it has). Generally I'd expect
> >> backends not to use domctl-s, as that would tie them to the tool
> >> stack domain.
> >>
> >> > so maybe we can introduce new domctl command for handling vUART. This
> >> > would avoid us to commit on an ABI and allow us to extend it if
> >> > necessary in the future to support multiple UARTs.
> >>
> >> Well, without having the context of who it would be to use such a
> >> domctl (and for what purpose) I don#t think I can comment here.
> >
> > I guess the assumption was that xenconsoled was part of the Xen tools.
> > Indeed, it is part of the tools and is installed as such.
> >
> > I don't have an opinion on this. If introducing a new DOMCTL makes the
> > code nicer in xen and xenconsoled, taking away some edges, like the
> > changes to evtchn_send, then we should probably just do it.
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-04-11 22:07                       ` Stefano Stabellini
@ 2017-04-14  7:12                         ` Bhupinder Thakur
  2017-04-19 18:43                           ` Stefano Stabellini
  0 siblings, 1 reply; 82+ messages in thread
From: Bhupinder Thakur @ 2017-04-14  7:12 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Wei Liu, George Dunlap, AndrewCooper, IanJackson, Tim Deegan,
	Julien Grall, Jan Beulich, xen-devel

Hi Stefano,

On 12 April 2017 at 03:37, Stefano Stabellini <sstabellini@kernel.org> wrote:
> On Tue, 11 Apr 2017, Bhupinder Thakur wrote:
>> Hi,
>>
>> Kindly let me know if my understanding is correct.
>>
>> Using a domctl API will allow us to keep the vUART configuration
>> flexible. Currently, we can operate on one ring-buf PFN and an event
>> channel port only for a single vUART but if we use DOMCTL interface,
>> then we can effectively get/set multiple event channel ports/multiple
>> PFNs from/to Xen in a single domctl call.
>>
>> I am not clear who will be the caller of this domctl API. Is it
>> xenconsoled or the toolstack? Currently, xenconsoled reads the
>> ring-buf PFN and event channel from the xenstore, which is populated
>> by the toolstack.
>
> The caller could be either, but I think it would make sense for it to be
> xenconsoled to cut the middle-man (xl).
>
I see the issue with Xenconsoled getting the PFN using a DOMCTL API.

PFN is allocated in alloc_magic_pages() which is part of
libxenguest.so and the DOMCTL API is part of libxenctrl.so. As per my
understanding, libxenguest.so has dependency on libxenctrl.so but not
the other way round.So I am not sure how libxenctrl can call into
libxenguest to get the PFN.

If the DOMCTL API is called from libxenguest then I can get the PFN easily.

Regards,
Bhupinder

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup
  2017-04-14  7:12                         ` Bhupinder Thakur
@ 2017-04-19 18:43                           ` Stefano Stabellini
  0 siblings, 0 replies; 82+ messages in thread
From: Stefano Stabellini @ 2017-04-19 18:43 UTC (permalink / raw)
  To: Bhupinder Thakur
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, AndrewCooper,
	IanJackson, Tim Deegan, Julien Grall, Jan Beulich, xen-devel

On Fri, 14 Apr 2017, Bhupinder Thakur wrote:
> Hi Stefano,
> 
> On 12 April 2017 at 03:37, Stefano Stabellini <sstabellini@kernel.org> wrote:
> > On Tue, 11 Apr 2017, Bhupinder Thakur wrote:
> >> Hi,
> >>
> >> Kindly let me know if my understanding is correct.
> >>
> >> Using a domctl API will allow us to keep the vUART configuration
> >> flexible. Currently, we can operate on one ring-buf PFN and an event
> >> channel port only for a single vUART but if we use DOMCTL interface,
> >> then we can effectively get/set multiple event channel ports/multiple
> >> PFNs from/to Xen in a single domctl call.
> >>
> >> I am not clear who will be the caller of this domctl API. Is it
> >> xenconsoled or the toolstack? Currently, xenconsoled reads the
> >> ring-buf PFN and event channel from the xenstore, which is populated
> >> by the toolstack.
> >
> > The caller could be either, but I think it would make sense for it to be
> > xenconsoled to cut the middle-man (xl).
> >
> I see the issue with Xenconsoled getting the PFN using a DOMCTL API.
> 
> PFN is allocated in alloc_magic_pages() which is part of
> libxenguest.so and the DOMCTL API is part of libxenctrl.so. As per my
> understanding, libxenguest.so has dependency on libxenctrl.so but not
> the other way round.So I am not sure how libxenctrl can call into
> libxenguest to get the PFN.
> 
> If the DOMCTL API is called from libxenguest then I can get the PFN easily.

Yes, that is the case. libxenguest would call libxenctrl to issue
domctls. You would simply replace hvm_param reads/writes with a new pair
of domctl, conceptually very similar.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

end of thread, other threads:[~2017-04-19 18:43 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-21 11:25 [PATCH 00/11] pl011 emulation support in Xen Bhupinder Thakur
2017-02-21 11:25 ` [PATCH 01/11] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
2017-02-26 21:37   ` Julien Grall
2017-03-03 19:19     ` Julien Grall
2017-03-21 13:27     ` Bhupinder Thakur
2017-03-21 19:38       ` Julien Grall
2017-03-23  9:44         ` Bhupinder Thakur
2017-03-23 13:51           ` Julien Grall
2017-03-03 19:59   ` Konrad Rzeszutek Wilk
2017-03-05  1:04     ` Julien Grall
2017-03-06 14:22       ` Konrad Rzeszutek Wilk
2017-03-05  1:15     ` Julien Grall
2017-03-05 11:59     ` Julien Grall
2017-03-22  5:50     ` Bhupinder Thakur
2017-03-05 12:12   ` Julien Grall
2017-03-23  9:14     ` Bhupinder Thakur
2017-03-23 14:16       ` Julien Grall
2017-03-24 10:39         ` Bhupinder Thakur
2017-02-21 11:25 ` [PATCH 02/11] xen/arm: vpl011: Add new hvm params in Xen for ring buffer/event setup Bhupinder Thakur
2017-03-03 20:02   ` Konrad Rzeszutek Wilk
2017-03-24  6:58     ` Bhupinder Thakur
2017-03-05 12:35   ` Julien Grall
2017-03-06  8:06     ` Jan Beulich
2017-03-06 11:42       ` Julien Grall
2017-03-06 12:41         ` Jan Beulich
2017-03-06 13:21           ` Julien Grall
2017-03-06 13:48             ` Jan Beulich
2017-03-08 14:45               ` Julien Grall
2017-03-08 15:21                 ` Jan Beulich
2017-03-08 18:22                   ` Stefano Stabellini
2017-04-11 14:38                     ` Bhupinder Thakur
2017-04-11 22:07                       ` Stefano Stabellini
2017-04-14  7:12                         ` Bhupinder Thakur
2017-04-19 18:43                           ` Stefano Stabellini
2017-03-06 14:48             ` George Dunlap
2017-03-08 13:52               ` Julien Grall
2017-03-24  7:31     ` Bhupinder Thakur
2017-02-21 11:26 ` [PATCH 03/11] xen/arm: vpl011: Refactor evtchn_send in Xen to allow sending events from a xen bound channel Bhupinder Thakur
2017-03-03 21:13   ` Konrad Rzeszutek Wilk
2017-03-06 10:16     ` Bhupinder Thakur
2017-03-06 10:35       ` Jan Beulich
2017-03-05 12:39   ` Julien Grall
2017-03-06  8:15     ` Jan Beulich
2017-03-06 10:44       ` Bhupinder Thakur
2017-03-06 10:54         ` Jan Beulich
2017-03-06 11:12           ` Bhupinder Thakur
2017-03-28  9:43             ` Bhupinder Thakur
2017-02-21 11:26 ` [PATCH 04/11] xen/arm: vpl011: Enable vpl011 emulation for a domain in Xen Bhupinder Thakur
2017-03-03 21:47   ` Konrad Rzeszutek Wilk
2017-03-05 12:46   ` Julien Grall
2017-03-06  8:27     ` Jan Beulich
2017-02-21 11:26 ` [PATCH 05/11] xen/arm: vpl011: Initialize nr_spis in vgic_init in Xen to atleast 1 Bhupinder Thakur
2017-03-03 20:49   ` Konrad Rzeszutek Wilk
2017-03-05 12:51   ` Julien Grall
2017-03-16  6:50     ` Bhupinder Thakur
2017-03-16  8:24       ` Julien Grall
2017-03-16 10:31         ` Bhupinder Thakur
2017-03-16 13:24           ` Julien Grall
2017-03-20 16:29             ` Bhupinder Thakur
2017-02-21 11:26 ` [PATCH 06/11] xen/arm: vpl011: Add a new pl011 uart node in the guest DT in the toolstack Bhupinder Thakur
2017-03-03 20:15   ` Konrad Rzeszutek Wilk
2017-03-03 21:03   ` Konrad Rzeszutek Wilk
2017-03-05 12:59     ` Julien Grall
2017-03-05 13:04   ` Julien Grall
2017-03-14 13:00     ` Wei Liu
2017-02-21 11:26 ` [PATCH 07/11] xen/arm: vpl011: Add two new vpl011 parameters to xenstore Bhupinder Thakur
2017-03-03 20:58   ` Konrad Rzeszutek Wilk
2017-03-28  7:49     ` Bhupinder Thakur
2017-02-21 11:26 ` [PATCH 08/11] xen/arm: vpl011: Allocate a new PFN in the toolstack and pass to Xen using a hvm call Bhupinder Thakur
2017-03-03 20:51   ` Konrad Rzeszutek Wilk
2017-03-05 13:07     ` Julien Grall
2017-02-21 11:26 ` [PATCH 09/11] xen/arm: vpl011: Modify domain_create_ring in xenconsole to map the ring buffer and event channel Bhupinder Thakur
2017-03-03 21:46   ` Konrad Rzeszutek Wilk
2017-02-21 11:26 ` [PATCH 10/11] xen/arm: vpl011: Modify handle_ring_read and buffer_append to read/append vpl011 data Bhupinder Thakur
2017-03-03 21:06   ` Konrad Rzeszutek Wilk
2017-02-21 11:26 ` [PATCH 11/11] xen/arm: vpl011: Modify handle_tty_read in xenconsole to redirect user data to vpl011 IN ring buffer Bhupinder Thakur
2017-03-03 21:17   ` Konrad Rzeszutek Wilk
2017-03-03 20:23 ` [PATCH 00/11] pl011 emulation support in Xen Konrad Rzeszutek Wilk
2017-03-03 21:15   ` Konrad Rzeszutek Wilk
2017-03-14  7:44   ` Bhupinder Thakur
2017-03-05 11:46 ` Julien Grall
2017-03-14  7:47   ` Bhupinder Thakur

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.