From: Bhupinder Thakur <bhupinder.thakur@linaro.org>
To: Julien Grall <julien.grall@arm.com>
Cc: xen-devel@lists.xenproject.org,
Stefano Stabellini <sstabellini@kernel.org>,
Ian Jackson <ian.jackson@eu.citrix.com>,
Wei Liu <wei.liu2@citrix.com>
Subject: Re: [PATCH 03/14 v4] xen/arm: vpl011: Add pl011 uart emulation in Xen
Date: Tue, 13 Jun 2017 16:27:40 +0530 [thread overview]
Message-ID: <CACtJ1JRAUh23iB=YBxO9uU_edfrfFjZ_rtAaJ+grLnLe8dGMaQ@mail.gmail.com> (raw)
In-Reply-To: <1fe7dea9-9120-63c7-5efd-b98fed3a70ba@arm.com>
Hi Julien,
>>
>> tools/console/daemon/io.c | 2 +-
>> xen/arch/arm/Kconfig | 5 +
>> xen/arch/arm/Makefile | 1 +
>> xen/arch/arm/vpl011.c | 418
>> +++++++++++++++++++++++++++++++++++++++
>> xen/include/asm-arm/domain.h | 6 +
>> xen/include/asm-arm/pl011-uart.h | 2 +
>> xen/include/asm-arm/vpl011.h | 74 +++++++
>> xen/include/public/arch-arm.h | 6 +
>> xen/include/public/io/console.h | 4 +
>
>
> This would require an ACK from Konrad. The addition would also need to be
> justified in the commit message. Although, you probably want to split this
> change in a separate patch.
I will send this change in a separate patch.
>
>> 9 files changed, 517 insertions(+), 1 deletion(-)
>> create mode 100644 xen/arch/arm/vpl011.c
>> create mode 100644 xen/include/asm-arm/vpl011.h
>>
>> diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
>> index 7e6a886..947f13a 100644
>> --- a/tools/console/daemon/io.c
>> +++ b/tools/console/daemon/io.c
>
>
> Can you explain why you change the position of the include in io.c?
Since I am including ring.h in console.h, it needs string.h to be
included first.
>
>> @@ -21,6 +21,7 @@
>>
>> #include "utils.h"
>> #include "io.h"
>> +#include <string.h>
>> #include <xenevtchn.h>
>> #include <xengnttab.h>
>> #include <xenstore.h>
>> @@ -29,7 +30,6 @@
>>
>> #include <stdlib.h>
>> #include <errno.h>
>> -#include <string.h>
>> #include <poll.h>
>> #include <fcntl.h>
>> #include <unistd.h>
>
>
>
> [...]
>
>> menu "ARM errata workaround via the alternative framework"
>> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
>> index 49e1fb2..15efc13 100644
>> --- a/xen/arch/arm/Makefile
>> +++ b/xen/arch/arm/Makefile
>> @@ -52,6 +52,7 @@ obj-y += vm_event.o
>> obj-y += vtimer.o
>> obj-y += vpsci.o
>> obj-y += vuart.o
>> +obj-$(CONFIG_VPL011_CONSOLE) += vpl011.o
>
>
> Please the alphabetical order. Just noticed vtimer is not correctly
> positioned. I will send a patch for that.
>
ok.
>
>> +#include <xen/errno.h>
>> +#include <xen/event.h>
>> +#include <xen/guest_access.h>
>> +#include <xen/init.h>
>> +#include <xen/lib.h>
>> +#include <xen/mm.h>
>> +#include <xen/sched.h>
>> +#include <public/domctl.h>
>> +#include <public/io/console.h>
>> +#include <asm-arm/pl011-uart.h>
>> +#include <asm-arm/vgic-emul.h>
>> +#include <asm-arm/vpl011.h>
>> +
>> +static bool vpl011_reg32_check_access(struct hsr_dabt dabt)
>> +{
>> + return (dabt.size != DABT_DOUBLE_WORD);
>
>
> Again, please add a comment explaining why we allow all the sizes but
> 64-bit.
>
>> +}
>> +
>> +static void vpl011_update(struct domain *d)
>> +{
>> + struct vpl011 *vpl011 = &d->arch.vpl011;
>> +
>> + /*
>> + * TODO: PL011 interrupts are level triggered which means
>> + * that interrupt needs to be set/clear instead of being
>> + * injected. However, currently vGIC does not handle level
>> + * triggered interrupts properly. This function needs to be
>> + * revisited once vGIC starts handling level triggered
>> + * interrupts.
>> + */
>> + if ( vpl011->uartris & vpl011->uartimsc )
>
>
> The write in uartirs and uartimsc are protected by a lock. Shouldn't it be
> the case here too? More that they are not updated atomically.
>
> You probably want to call vpl011_update with vpl011 lock taken to make sure
> you don't have any synchronization issue.
Since we are just reading the values here, I think it is fine to not
take a lock. The
condition will either be true or false.
>
>> + vgic_vcpu_inject_spi(d, GUEST_VPL011_SPI);
>> +}
>> +
>> +static uint8_t vpl011_read_data(struct domain *d)
>> +{
>> + unsigned long flags;
>> + uint8_t data = 0;
>> + struct vpl011 *vpl011 = &d->arch.vpl011;
>> + struct xencons_interface *intf = vpl011->ring_buf;
>> + XENCONS_RING_IDX in_cons = intf->in_cons;
>> + XENCONS_RING_IDX in_prod = intf->in_prod;
>
>
> See my answer on Stefano's e-mail regarding the barrier here.
> (<fa3e5003-5c7f-0886-d437-6b643347b4c5@arm.com>)
>
>> +
>> + VPL011_LOCK(d, flags);
>> +
>> + /*
>> + * It is expected that there will be data in the ring buffer when
>> this
>> + * function is called since the guest is expected to read the data
>> register
>> + * only if the TXFE flag is not set.
>> + * If the guest still does read when TXFE bit is set then 0 will be
>> returned.
>> + */
>> + if ( xencons_queued(in_prod, in_cons, sizeof(intf->in)) > 0 )
>> + {
>> + data = intf->in[xencons_mask(in_cons, sizeof(intf->in))];
>> + in_cons += 1;
>> + intf->in_cons = in_cons;
>> + smp_mb();
>
>
> I don't understand why you moved the barrier from between reading the data
> and intf->in_cons. You have to ensure the character is read before updating
> in_cons.
I thought that since these 3 statements are dependent on in_cons, they
would be executed in order due to data dependency. The memory barrier
after the 3 statements ensures that intf->in_cons is updated before
proceeding ahead.
>
>> + }
>> + else
>> + {
>> + gprintk(XENLOG_ERR, "vpl011: Unexpected IN ring buffer empty\n");
>> + }
>
>
> The {} are not necessary.
ok.
>
>> +
>> + if ( xencons_queued(in_prod, in_cons, sizeof(intf->in)) == 0 )
>
>
> What if the other end of the ring has put more data whilst reading one
> character?
It will raise an event when the other end puts more data and in the
event handling function data_available(), it will clear the RXFE bit.
>
>> + {
>> + vpl011->uartfr |= RXFE;
>> + vpl011->uartris &= ~RXI;
>> + }
>> + vpl011->uartfr &= ~RXFF;
>> + VPL011_UNLOCK(d, flags);
>> +
>> + return data;
>> +}
>> +
>> +static void vpl011_write_data(struct domain *d, uint8_t data)
>> +{
>> + unsigned long flags;
>> + struct vpl011 *vpl011 = &d->arch.vpl011;
>> + struct xencons_interface *intf = vpl011->ring_buf;
>> + XENCONS_RING_IDX out_cons = intf->out_cons;
>> + XENCONS_RING_IDX out_prod = intf->out_prod;
>
>
> See my remark above.
I will move index reading under lock.
>
>> +
>> + VPL011_LOCK(d, flags);
>> +
>> + /*
>> + * It is expected that the ring is not full when this function is
>> called
>> + * as the guest is expected to write to the data register only when
>> the
>> + * TXFF flag is not set.
>> + * In case the guest does write even when the TXFF flag is set then
>> the
>> + * data will be silently dropped.
>> + */
>> + if ( xencons_queued(out_prod, out_cons, sizeof(intf->out)) !=
>> + sizeof (intf->out) )
>> + {
>> + intf->out[xencons_mask(out_prod, sizeof(intf->out))] = data;
>> + smp_wmb();
>> + out_prod += 1;
>> + intf->out_prod = out_prod;
>> + }
>> + else
>> + {
>> + gprintk(XENLOG_ERR, "vpl011: Unexpected OUT ring buffer full\n");
>> + }
>
>
> The {} are not necessary.
ok.
>
>> +
>> + if ( xencons_queued(out_prod, out_cons, sizeof(intf->out)) ==
>> + sizeof (intf->out) )
>
>
> Ditto here.
>
>
>> + {
>> + vpl011->uartfr |= TXFF;
>> + vpl011->uartris &= ~TXI;
>> + }
>> +
>> + vpl011->uartfr |= BUSY;
>> +
>> + vpl011->uartfr &= ~TXFE;
>> +
>> + VPL011_UNLOCK(d, flags);
>> +
>> + /*
>> + * Send an event to console backend to indicate that there is
>> + * data in the OUT ring buffer.
>> + */
>> + notify_via_xen_event_channel(d, vpl011->evtchn);
>> +}
>> +
>> +static int vpl011_mmio_read(struct vcpu *v,
>> + mmio_info_t *info,
>> + register_t *r,
>> + void *priv)
>> +{
>> + struct hsr_dabt dabt = info->dabt;
>> + uint32_t vpl011_reg = (uint32_t)(info->gpa - GUEST_PL011_BASE);
>> + struct vpl011 *vpl011 = &v->domain->arch.vpl011;
>> +
>> + switch ( vpl011_reg )
>> + {
>> + case DR:
>> + /*
>> + * Since pl011 registers are 32-bit registers, all registers
>> + * are handled similarly allowing 8-bit, 16-bit and 32-bit
>> + * accesses.
>> + */
>
>
> This comment should be on top of the declaration of
> vpl011_reg32_check_access.
ok.
>
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + *r = vreg_reg32_extract(vpl011_read_data(v->domain), info);
>> + return 1;
>> +
>> + case RSR:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + /* It always returns 0 as there are no physical errors. */
>> + *r = 0;
>> + return 1;
>> +
>> + case FR:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + *r = vreg_reg32_extract(vpl011->uartfr, info);
>
>
> You need to ensure that uartfr is read only once because vreg_reg32_extract
> does not currently ensure that.
>
>> + return 1;
>> +
>> + case RIS:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + *r = vreg_reg32_extract(vpl011->uartris, info);
>
>
> Ditto.
>
>> + return 1;
>> +
>> + case MIS:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + *r = vreg_reg32_extract(vpl011->uartris &
>> + vpl011->uartimsc, info);
>
>
> Ditto.
>
>> + return 1;
>> +
>> + case IMSC:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + *r = vreg_reg32_extract(vpl011->uartimsc, info);
>
>
> Ditto.
I will read these registers into a local variable and use it.
>
>
>> + return 1;
>> +
>> + case ICR:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + /* Only write is valid. */
>> + return 0;
>> +
>> + default:
>> + gprintk(XENLOG_ERR, "vpl011: unhandled read r%d offset %#08x\n",
>> + dabt.reg, vpl011_reg);
>> + return 0;
>> + }
>> +
>> + return 1;
>> +
>> +bad_width:
>> + gprintk(XENLOG_ERR, "vpl011: bad read width %d r%d offset %#08x\n",
>> + dabt.size, dabt.reg, vpl011_reg);
>> + domain_crash_synchronous();
>> + return 0;
>> +
>> +}
>> +
>> +static int vpl011_mmio_write(struct vcpu *v,
>> + mmio_info_t *info,
>> + register_t r,
>> + void *priv)
>> +{
>> + struct hsr_dabt dabt = info->dabt;
>> + uint32_t vpl011_reg = (uint32_t)(info->gpa - GUEST_PL011_BASE);
>> + struct vpl011 *vpl011 = &v->domain->arch.vpl011;
>> + struct domain *d = v->domain;
>> + unsigned long flags;
>> +
>> + switch ( vpl011_reg )
>> + {
>> + case DR:
>> + {
>> + uint32_t data = 0;
>> +
>> + /*
>> + * Since pl011 registers are 32-bit registers, all registers
>> + * are handled similarly allowing 8-bit, 16-bit and 32-bit
>> + * accesses.
>> + */
>
>
> See above.
>
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + vreg_reg32_update(&data, r, info);
>> + data &= 0xFF;
>> + vpl011_write_data(v->domain, data);
>> + return 1;
>> + }
>> + case RSR: /* Nothing to clear. */
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + return 1;
>> +
>> + case FR:
>> + case RIS:
>> + case MIS:
>> + goto write_ignore;
>> +
>> + case IMSC:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + VPL011_LOCK(d, flags);
>> + vreg_reg32_update(&vpl011->uartimsc, r, info);
>> + VPL011_UNLOCK(d, flags);
>> + vpl011_update(v->domain);
>
>
> I think this should be call with under the lock.
>
>> + return 1;
>> +
>> + case ICR:
>> + if ( !vpl011_reg32_check_access(dabt) ) goto bad_width;
>> +
>> + VPL011_LOCK(d, flags);
>> + vreg_reg32_clearbits(&vpl011->uartris, r, info);
>> + VPL011_UNLOCK(d, flags);
>> + vpl011_update(d);
>
>
> Ditto.
>
>
>> + return 1;
>> +
>> + default:
>> + gprintk(XENLOG_ERR, "vpl011: unhandled write r%d offset %#08x\n",
>> + dabt.reg, vpl011_reg);
>> + return 0;
>> + }
>> +
>> +write_ignore:
>> + return 1;
>> +
>> +bad_width:
>> + gprintk(XENLOG_ERR, "vpl011: bad write width %d r%d offset %#08x\n",
>> + dabt.size, dabt.reg, vpl011_reg);
>> + domain_crash_synchronous();
>> + return 0;
>> +
>> +}
>> +
>> +static const struct mmio_handler_ops vpl011_mmio_handler = {
>> + .read = vpl011_mmio_read,
>> + .write = vpl011_mmio_write,
>> +};
>> +
>> +static void vpl011_data_avail(struct domain *d)
>> +{
>> + unsigned long flags;
>> + struct vpl011 *vpl011 = &d->arch.vpl011;
>> + struct xencons_interface *intf = vpl011->ring_buf;
>> + XENCONS_RING_IDX in_cons = intf->in_cons;
>> + XENCONS_RING_IDX in_prod = intf->in_prod;
>> + XENCONS_RING_IDX out_cons = intf->out_cons;
>> + XENCONS_RING_IDX out_prod = intf->out_prod;
>
>
> Same as above for the barrier.
>
>
>> + XENCONS_RING_IDX in_ring_qsize, out_ring_qsize;
>> +
>> + VPL011_LOCK(d, flags);
>> +
>> + in_ring_qsize = xencons_queued(in_prod,
>> + in_cons,
>> + sizeof(intf->in));
>> +
>> + out_ring_qsize = xencons_queued(out_prod,
>> + out_cons,
>> + sizeof(intf->out));
>> +
>> + /* Update the uart rx state if the buffer is not empty. */
>> + if ( in_ring_qsize != 0 )
>> + {
>> + vpl011->uartfr &= ~RXFE;
>> + if ( in_ring_qsize == sizeof(intf->in) )
>> + vpl011->uartfr |= RXFF;
>> + vpl011->uartris |= RXI;
>> + }
>> +
>> + /* Update the uart tx state if the buffer is not full. */
>> + if ( out_ring_qsize != sizeof(intf->out) )
>> + {
>> + vpl011->uartfr &= ~TXFF;
>> + vpl011->uartris |= TXI;
>> + if ( out_ring_qsize == 0 )
>> + {
>> + vpl011->uartfr &= ~BUSY;
>> + vpl011->uartfr |= TXFE;
>> + }
>> + }
>> +
>> + VPL011_UNLOCK(d, flags);
>> +
>> + vpl011_update(d);
>
>
> See my comment above for the calling vpl011_update
>
>> +}
>> +
>> +
>> +static void vpl011_notification(struct vcpu *v, unsigned int port)
>> +{
>> + vpl011_data_avail(v->domain);
>> +}
>> +
>> +int domain_vpl011_init(struct domain *d, struct vpl011_init_info *info)
>> +{
>> + int rc;
>> + struct vpl011 *vpl011 = &d->arch.vpl011;
>> +
>> + if ( vpl011->ring_buf )
>> + return 0;
>
>
> IHMO, you should return an error if the PL011 is already initialized. This
> should never happen.
ok.
>
>> +
>> + /* Map the guest PFN to Xen address space. */
>> + rc = prepare_ring_for_helper(d,
>> + gfn_x(info->gfn),
>> + &vpl011->ring_page,
>> + &vpl011->ring_buf);
>> + if ( rc < 0 )
>> + goto out;
>> +
>> + rc = vgic_reserve_virq(d, GUEST_VPL011_SPI);
>> + if ( !rc )
>> + {
>> + rc = -EINVAL;
>> + goto out1;
>> + }
>> +
>> + register_mmio_handler(d, &vpl011_mmio_handler,
>> + GUEST_PL011_BASE, GUEST_PL011_SIZE, NULL);
>
>
> Again, you register MMIO handler but never remove them. So if this call
> fail, you will end up with the handlers existing but the rest
> half-initialized which likely lead to a segfault, or worst leaking data.
This function does not return a status. So there is no way to find out
if the mmio handlers were
registered successfully. I am removing the mmio handlers in the error
legs in domain_vpl011_init().
>
>> +
>> + spin_lock_init(&vpl011->lock);
>> +
>> + rc = alloc_unbound_xen_event_channel(d, 0, info->console_domid,
>> + vpl011_notification);
>> + if ( rc < 0 )
>
> You
I think this is a type.
>>
>> + goto out2;
>> +
>> + vpl011->evtchn = info->evtchn = rc;
>> +
>> + return 0;
>> +
>> +out2:
>> + xfree(d->arch.vmmio.handlers);
>> + vgic_free_virq(d, GUEST_VPL011_SPI);
>> +
>> +out1:
>> + destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page);
>> +
>> +out:
>> + return rc;
>> +}
>> +
>> +void domain_vpl011_deinit(struct domain *d)
>> +{
>> + struct vpl011 *vpl011 = &d->arch.vpl011;
>> +
>> + if ( !vpl011->ring_buf )
>
>
> You will bail out if ring_buf is NULL. However, if you called
> domain_vpl011_init first and it failed, you may have ring_buf set but the
> rest not fully updated. This means that you will free garbagge.
>
> I think this could be solved by reinitialize ring_buf if an error occur in
> domain_vpl011_init.
destroy_ring_for_helper() sets the first parameter to NULL incase it fails.
>
>> + return;
>> +
>> + free_xen_event_channel(d, vpl011->evtchn);
>> + destroy_ring_for_helper(&vpl011->ring_buf, vpl011->ring_page);
>> + xfree(d->arch.vmmio.handlers);
>> +}
>
>
> [...]
>
>
>> diff --git a/xen/include/asm-arm/vpl011.h b/xen/include/asm-arm/vpl011.h
>> new file mode 100644
>> index 0000000..b3e332d
>> --- /dev/null
>> +++ b/xen/include/asm-arm/vpl011.h
>> @@ -0,0 +1,74 @@
>> +/*
>> + * 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_
>> +
>
>
> We tend to keep #ifndef and #define together. So please drop the newline
> here.
>
ok.
>> +#ifdef CONFIG_VPL011_CONSOLE
>> +int domain_vpl011_init(struct domain *d,
>> + struct vpl011_init_info *info);
>> +void domain_vpl011_deinit(struct domain *d);
>> +#else
>> +static inline int domain_vpl011_init(struct domain *d,
>> + struct vpl011_init_info *info)
>> +{
>> + return -ENOSYS;
>> +}
>> +
>> +static inline void domain_vpl011_deinit(struct domain *d) { }
>> +#endif
>> +
>> +#endif
>> +
>
>
> Please drop this newline.
You mean the newline between the #endifs or after the last #endif?
>
Regards,
Bhupinder
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-06-13 10:57 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-06 17:25 [PATCH 00/14 v4] PL011 emulation support in Xen Bhupinder Thakur
2017-06-06 17:25 ` [PATCH 01/14 v4] xen/arm: vpl011: Move vgic register access functions to vreg.h Bhupinder Thakur
2017-06-09 12:49 ` Julien Grall
2017-06-06 17:25 ` [PATCH 02/14 v4] xen/arm: vpl011: Define generic vreg_reg* access functions in vreg.h Bhupinder Thakur
2017-06-09 12:54 ` Julien Grall
2017-06-19 9:33 ` Andre Przywara
2017-06-19 16:53 ` Bhupinder Thakur
2017-06-19 16:59 ` Andre Przywara
2017-06-06 17:25 ` [PATCH 03/14 v4] xen/arm: vpl011: Add pl011 uart emulation in Xen Bhupinder Thakur
2017-06-06 23:02 ` Stefano Stabellini
2017-06-09 13:15 ` Julien Grall
2017-06-09 18:02 ` Stefano Stabellini
2017-06-13 8:58 ` Bhupinder Thakur
2017-06-13 9:25 ` Julien Grall
2017-06-09 13:54 ` Julien Grall
2017-06-13 10:57 ` Bhupinder Thakur [this message]
2017-06-13 12:44 ` Julien Grall
2017-06-13 17:50 ` Stefano Stabellini
2017-06-14 5:47 ` Bhupinder Thakur
2017-06-14 9:33 ` Julien Grall
2017-06-19 10:14 ` Andre Przywara
2017-06-22 5:16 ` Bhupinder Thakur
2017-06-23 12:45 ` Julien Grall
2017-06-06 17:25 ` [PATCH 04/14 v4] xen/arm: vpl011: Add support for vuart in libxl Bhupinder Thakur
2017-06-06 23:07 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 05/14 v4] xen/arm: vpl011: Allocate a new GFN in the toolstack for vuart Bhupinder Thakur
2017-06-06 23:17 ` Stefano Stabellini
2017-06-07 16:43 ` Wei Liu
2017-06-06 17:25 ` [PATCH 06/14 v4] xen/arm: vpl011: Add a new domctl API to initialize vpl011 Bhupinder Thakur
2017-06-06 23:26 ` Stefano Stabellini
2017-06-09 14:06 ` Julien Grall
2017-06-09 18:32 ` Stefano Stabellini
2017-06-14 7:35 ` Bhupinder Thakur
2017-06-14 8:34 ` Bhupinder Thakur
2017-06-09 14:13 ` Julien Grall
2017-06-14 9:16 ` Bhupinder Thakur
2017-06-14 10:15 ` Julien Grall
2017-06-15 6:33 ` Bhupinder Thakur
2017-06-19 10:59 ` Bhupinder Thakur
2017-06-19 11:01 ` Julien Grall
2017-06-19 11:47 ` Wei Liu
2017-06-19 13:11 ` Bhupinder Thakur
2017-06-20 11:16 ` Julien Grall
2017-06-20 11:42 ` Wei Liu
2017-06-21 10:18 ` Bhupinder Thakur
2017-06-06 17:25 ` [PATCH 07/14 v4] xen/arm: vpl011: Add a new vuart node in the xenstore Bhupinder Thakur
2017-06-06 23:38 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 08/14 v4] xen/arm: vpl011: Modify xenconsole to define and use a new console structure Bhupinder Thakur
2017-06-07 1:13 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 09/14 v4] xen/arm: vpl011: Modify xenconsole functions to take console structure as input Bhupinder Thakur
2017-06-07 0:43 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 10/14 v4] xen/arm: vpl011: Modify xenconsole to support multiple consoles Bhupinder Thakur
2017-06-07 1:03 ` Stefano Stabellini
2017-06-07 3:51 ` Bhupinder Thakur
2017-06-07 16:46 ` Wei Liu
2017-06-07 17:54 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 11/14 v4] xen/arm: vpl011: Add support for vuart console in xenconsole Bhupinder Thakur
2017-06-07 1:08 ` Stefano Stabellini
2017-06-07 16:44 ` Wei Liu
2017-06-06 17:25 ` [PATCH 12/14 v4] xen/arm: vpl011: Add a new vuart console type to xenconsole client Bhupinder Thakur
2017-06-06 23:41 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 13/14 v4] xen/arm: vpl011: Add a pl011 uart DT node in the guest device tree Bhupinder Thakur
2017-06-06 17:25 ` [PATCH 14/14 v4] xen/arm: vpl011: Update documentation for vuart console support Bhupinder Thakur
2017-06-09 13:58 ` [PATCH 00/14 v4] PL011 emulation support in Xen Julien Grall
-- strict thread matches above, loose matches on Subject: below --
2017-06-06 10:02 [PATCH 03/14 v4] xen/arm: vpl011: Add pl011 uart emulation " Bhupinder Thakur
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CACtJ1JRAUh23iB=YBxO9uU_edfrfFjZ_rtAaJ+grLnLe8dGMaQ@mail.gmail.com' \
--to=bhupinder.thakur@linaro.org \
--cc=ian.jackson@eu.citrix.com \
--cc=julien.grall@arm.com \
--cc=sstabellini@kernel.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).