[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 1/5] xen/arm: vgic-v2: Handle correctly byte write in ITARGETSR
On 23/10/15 10:33, Ian Campbell wrote: > On Thu, 2015-10-22 at 17:36 +0100, Julien Grall wrote: >> On 22/10/15 16:53, Ian Campbell wrote: >>> On Mon, 2015-10-12 at 15:22 +0100, Julien Grall wrote: [...] >>>> >>>> Furthermore, the body of the loop is retrieving the old target list >>>> using the index of the byte. >>>> >>>> To avoid modifying too much the loop, shift the byte stored to the >>>> correct >>>> offset. >>> >>> That might have meant a smaller patch, but it's a lot harder to >>> understand >>> either the result or the diff. >> >> The size of the patch would have been the same. Although, it requires to >> modify the call to vgic_byte_read in the loop to access the correct >> interrupt. >> >> I didn't try to spend to much time to modify the loop because the >> follow-up patch (#2) will rewrite the loop. > > Since this patch is marked for backport then if we decided to take #2 then > that's probably ok, otherwise the state of the tree after just this patch > is more relevant. > That's in itself probably a stronger argument for taking #2 than the actual > functionality of #2 is. This code is already complex and I don't think the loop modification would have make the code easier to read. Although, my plan was to ask to backport the whole series once we exercise the code a bit in unstable. This is in order to fix 32-bit access on 64-bit register. >> >> [...] >> >>>> xen/arch/arm/vgic-v2.c | 12 ++++++------ >>>> 1 file changed, 6 insertions(+), 6 deletions(-) >>>> >>>> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c >>>> index 2d63e12..665afeb 100644 >>>> --- a/xen/arch/arm/vgic-v2.c >>>> +++ b/xen/arch/arm/vgic-v2.c >>>> @@ -346,11 +346,11 @@ static int vgic_v2_distr_mmio_write(struct vcpu >>>> *v, mmio_info_t *info, >>>> /* 8-bit vcpu mask for this domain */ >>>> BUG_ON(v->domain->max_vcpus > 8); >>>> target = (1 << v->domain->max_vcpus) - 1; >>>> - if ( dabt.size == 2 ) >>>> - target = target | (target << 8) | (target << 16) | >>>> (target << 24); >>>> + target = target | (target << 8) | (target << 16) | (target >>>> << 24); >>>> + if ( dabt.size == DABT_WORD ) >>>> + target &= r; >>>> else >>>> - target = (target << (8 * (gicd_reg & 0x3))); >>>> - target &= r; >>>> + target &= (r << (8 * (gicd_reg & 0x3))); >>> >>> At this point do you not now have 3 bytes of >>> (1 << v->domain->max_vcpus) - 1; >>> and 1 byte of that masked with the write? >>> >>> IOW isn't this modifying the 3 bytes which aren't written? >> >> No, the current loop search for bit set to 1. As the target variable >> will only contain one byte with some bit set to 1, only the IRQ >> associated to this byte will be updated. > > Um, OK, I'll take your word for that. FWIW, I wrote a Linux patch to exercise the code changed and I didn't see any possible issue: diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 982c09c..b6de74f 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -446,6 +446,7 @@ static void gic_cpu_if_up(struct gic_chip_data *gic) writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL); } +#include <xen/hvc-console.h> static void __init gic_dist_init(struct gic_chip_data *gic) { @@ -453,6 +454,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) u32 cpumask; unsigned int gic_irqs = gic->gic_irqs; void __iomem *base = gic_data_dist_base(gic); + void __iomem *target = base + GIC_DIST_TARGET; writel_relaxed(GICD_DISABLE, base + GIC_DIST_CTRL); @@ -465,6 +467,45 @@ static void __init gic_dist_init(struct gic_chip_data *gic) for (i = 32; i < gic_irqs; i += 4) writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); + for (i = 32; i < 34; i++) { + unsigned int n = i / 4; + unsigned int nb = i % 4; + int j; + void __iomem *regaddr = target + (i & ~0x3); + void __iomem *byte = target + i; + + xen_raw_printk("Exerce ITARGETSR for irq %u\n", i); + xen_raw_printk("\t 32-bit ITARGETSR%u = 0x%x\n", + n, readl_relaxed(regaddr)); + xen_raw_printk("\t 8-bit ITARGETSR%u[%u] = 0x%x\n", + n, nb, readb_relaxed(byte)); + for (j = 0; j < 5; j++) { + xen_raw_printk("switch to CPU%u\n", j); + writeb(1 << j, byte); + xen_raw_printk("\t 32-bit ITARGETSR%u = 0x%x\n", + n, readl_relaxed(regaddr)); + xen_raw_printk("\t 8-bit ITARGETSR%u[%u] = 0x%x\n", + n, nb, readb_relaxed(byte)); + } + } + + cpumask = 0x2; + cpumask |= cpumask << 8; + cpumask |= cpumask << 16; + xen_raw_printk("Excerce 32-bit access\n"); + for (i = 32; i < 38; i += 4) + { + unsigned int n = i / 4; + void __iomem *regaddr = target + i * 4 / 4; + + xen_raw_printk("Exerce 32-bit access on ITARGETSR%u\n", n); + xen_raw_printk("\t before = 0x%x\n", readl_relaxed(regaddr)); + writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); + xen_raw_printk("\t after = 0x%x\n", readl_relaxed(regaddr)); + } + + while (1); + gic_dist_config(base, gic_irqs, NULL); writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); Regards, -- Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |