* [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support @ 2016-08-08 16:51 ` vijay.kilari 0 siblings, 0 replies; 12+ messages in thread From: vijay.kilari @ 2016-08-08 16:51 UTC (permalink / raw) To: qemu-arm, peter.maydell, pbonzini Cc: Prasun.Kapoor, p.fedin, qemu-devel, vijay.kilari, Vijaya Kumar K From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> This series introduces support for GICv3 live migration with new VGIC implementation in 4.7-rc3 kernel. In this series, patch 1 of the previous implementation are ported. https://lists.nongnu.org/archive/html/qemu-devel/2015-10/msg05284.html Patch 2, is based on below implementation. http://patchwork.ozlabs.org/patch/626746/ Kernel patches which implement this functionality are: http://www.spinics.net/lists/arm-kernel/msg519596.html This API definition is as per version of VGICv3 specification http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/445611.html Patch 1 of this series will be synced with KVM patches in next revision. Tested Live migration of Idle VM running with 4 VCPUs and 8GB RAM. Vijaya Kumar K (2): kernel: Add definitions for GICv3 attributes hw/intc/arm_gicv3_kvm: Implement get/put functions hw/intc/arm_gicv3_kvm.c | 474 +++++++++++++++++++++++++++++++++++++++++- linux-headers/asm-arm64/kvm.h | 17 +- 2 files changed, 478 insertions(+), 13 deletions(-) -- 1.9.1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support @ 2016-08-08 16:51 ` vijay.kilari 0 siblings, 0 replies; 12+ messages in thread From: vijay.kilari @ 2016-08-08 16:51 UTC (permalink / raw) To: qemu-arm, peter.maydell, pbonzini Cc: p.fedin, qemu-devel, Prasun.Kapoor, vijay.kilari, Vijaya Kumar K From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> This series introduces support for GICv3 live migration with new VGIC implementation in 4.7-rc3 kernel. In this series, patch 1 of the previous implementation are ported. https://lists.nongnu.org/archive/html/qemu-devel/2015-10/msg05284.html Patch 2, is based on below implementation. http://patchwork.ozlabs.org/patch/626746/ Kernel patches which implement this functionality are: http://www.spinics.net/lists/arm-kernel/msg519596.html This API definition is as per version of VGICv3 specification http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/445611.html Patch 1 of this series will be synced with KVM patches in next revision. Tested Live migration of Idle VM running with 4 VCPUs and 8GB RAM. Vijaya Kumar K (2): kernel: Add definitions for GICv3 attributes hw/intc/arm_gicv3_kvm: Implement get/put functions hw/intc/arm_gicv3_kvm.c | 474 +++++++++++++++++++++++++++++++++++++++++- linux-headers/asm-arm64/kvm.h | 17 +- 2 files changed, 478 insertions(+), 13 deletions(-) -- 1.9.1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-arm] [RFC PATCH v2 1/2] kernel: Add definitions for GICv3 attributes 2016-08-08 16:51 ` vijay.kilari @ 2016-08-08 16:51 ` vijay.kilari -1 siblings, 0 replies; 12+ messages in thread From: vijay.kilari @ 2016-08-08 16:51 UTC (permalink / raw) To: qemu-arm, peter.maydell, pbonzini Cc: Prasun.Kapoor, p.fedin, qemu-devel, vijay.kilari, Vijaya Kumar K From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> This temporary patch adds kernel API definitions. Use proper header update procedure after these features are released. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> --- linux-headers/asm-arm64/kvm.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h index 7d82d1f..396c6f3 100644 --- a/linux-headers/asm-arm64/kvm.h +++ b/linux-headers/asm-arm64/kvm.h @@ -180,14 +180,14 @@ struct kvm_arch_memory_slot { KVM_REG_ARM64_SYSREG_ ## n ## _MASK) #define __ARM64_SYS_REG(op0,op1,crn,crm,op2) \ - (KVM_REG_ARM64 | KVM_REG_ARM64_SYSREG | \ - ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \ + (ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \ ARM64_SYS_REG_SHIFT_MASK(op1, OP1) | \ ARM64_SYS_REG_SHIFT_MASK(crn, CRN) | \ ARM64_SYS_REG_SHIFT_MASK(crm, CRM) | \ ARM64_SYS_REG_SHIFT_MASK(op2, OP2)) -#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64) +#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_ARM64 | \ + KVM_REG_SIZE_U64 | KVM_REG_ARM64_SYSREG) #define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1) #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) @@ -199,10 +199,21 @@ struct kvm_arch_memory_slot { #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2 #define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32 #define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT) +#define KVM_DEV_ARM_VGIC_V3_CPUID_MASK \ + (0xffffffffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT) #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0 #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) +#define KVM_DEV_ARM_VGIC_SYSREG_MASK (KVM_REG_ARM64_SYSREG_OP0_MASK | \ + KVM_REG_ARM64_SYSREG_OP1_MASK | \ + KVM_REG_ARM64_SYSREG_CRN_MASK | \ + KVM_REG_ARM64_SYSREG_CRM_MASK | \ + KVM_REG_ARM64_SYSREG_OP2_MASK) +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ + __ARM64_SYS_REG(op0,op1,crn,crm,op2) #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3 #define KVM_DEV_ARM_VGIC_GRP_CTRL 4 +#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5 +#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6 #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 /* Device Control API on vcpu fd */ -- 1.9.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [RFC PATCH v2 1/2] kernel: Add definitions for GICv3 attributes @ 2016-08-08 16:51 ` vijay.kilari 0 siblings, 0 replies; 12+ messages in thread From: vijay.kilari @ 2016-08-08 16:51 UTC (permalink / raw) To: qemu-arm, peter.maydell, pbonzini Cc: p.fedin, qemu-devel, Prasun.Kapoor, vijay.kilari, Vijaya Kumar K From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> This temporary patch adds kernel API definitions. Use proper header update procedure after these features are released. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> --- linux-headers/asm-arm64/kvm.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h index 7d82d1f..396c6f3 100644 --- a/linux-headers/asm-arm64/kvm.h +++ b/linux-headers/asm-arm64/kvm.h @@ -180,14 +180,14 @@ struct kvm_arch_memory_slot { KVM_REG_ARM64_SYSREG_ ## n ## _MASK) #define __ARM64_SYS_REG(op0,op1,crn,crm,op2) \ - (KVM_REG_ARM64 | KVM_REG_ARM64_SYSREG | \ - ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \ + (ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \ ARM64_SYS_REG_SHIFT_MASK(op1, OP1) | \ ARM64_SYS_REG_SHIFT_MASK(crn, CRN) | \ ARM64_SYS_REG_SHIFT_MASK(crm, CRM) | \ ARM64_SYS_REG_SHIFT_MASK(op2, OP2)) -#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64) +#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_ARM64 | \ + KVM_REG_SIZE_U64 | KVM_REG_ARM64_SYSREG) #define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1) #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) @@ -199,10 +199,21 @@ struct kvm_arch_memory_slot { #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2 #define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32 #define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT) +#define KVM_DEV_ARM_VGIC_V3_CPUID_MASK \ + (0xffffffffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT) #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0 #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) +#define KVM_DEV_ARM_VGIC_SYSREG_MASK (KVM_REG_ARM64_SYSREG_OP0_MASK | \ + KVM_REG_ARM64_SYSREG_OP1_MASK | \ + KVM_REG_ARM64_SYSREG_CRN_MASK | \ + KVM_REG_ARM64_SYSREG_CRM_MASK | \ + KVM_REG_ARM64_SYSREG_OP2_MASK) +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ + __ARM64_SYS_REG(op0,op1,crn,crm,op2) #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3 #define KVM_DEV_ARM_VGIC_GRP_CTRL 4 +#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5 +#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6 #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 /* Device Control API on vcpu fd */ -- 1.9.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [RFC PATCH v2 2/2] hw/intc/arm_gicv3_kvm: Implement get/put functions 2016-08-08 16:51 ` vijay.kilari @ 2016-08-08 16:51 ` vijay.kilari -1 siblings, 0 replies; 12+ messages in thread From: vijay.kilari @ 2016-08-08 16:51 UTC (permalink / raw) To: qemu-arm, peter.maydell, pbonzini Cc: Prasun.Kapoor, p.fedin, qemu-devel, vijay.kilari, Vijaya Kumar K From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> This actually implements pre_save and post_load methods for in-kernel vGICv3. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> [PMM: * use decimal, not 0bnnn * fixed typo in names of ICC_APR0R_EL1 and ICC_AP1R_EL1 * completely rearranged the get and put functions to read and write the state in a natural order, rather than mixing distributor and redistributor state together] Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com> [Vijay: * Update macro KVM_VGIC_ATTR * Use 32 bit access for gicd and gicr * GICD_IROUTER, GICD_TYPER, GICR_PROPBASER and GICR_PENDBASER reg access are changed from 64-bit to 32-bit access] --- hw/intc/arm_gicv3_kvm.c | 474 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 464 insertions(+), 10 deletions(-) diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c index 711fde3..0f84c86 100644 --- a/hw/intc/arm_gicv3_kvm.c +++ b/hw/intc/arm_gicv3_kvm.c @@ -23,8 +23,11 @@ #include "qapi/error.h" #include "hw/intc/arm_gicv3_common.h" #include "hw/sysbus.h" +#include "migration/migration.h" +#include "qemu/error-report.h" #include "sysemu/kvm.h" #include "kvm_arm.h" +#include "gicv3_internal.h" #include "vgic_common.h" #include "migration/migration.h" @@ -44,6 +47,23 @@ #define KVM_ARM_GICV3_GET_CLASS(obj) \ OBJECT_GET_CLASS(KVMARMGICv3Class, (obj), TYPE_KVM_ARM_GICV3) +#define ICC_PMR_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 4, 6, 0) +#define ICC_BPR0_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 8, 3) +#define ICC_AP0R_EL1(n) \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 8, 4 | n) +#define ICC_AP1R_EL1(n) \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 9, n) +#define ICC_BPR1_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 3) +#define ICC_CTLR_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 4) +#define ICC_IGRPEN0_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 6) +#define ICC_IGRPEN1_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 7) + typedef struct KVMARMGICv3Class { ARMGICv3CommonClass parent_class; DeviceRealize parent_realize; @@ -57,16 +77,444 @@ static void kvm_arm_gicv3_set_irq(void *opaque, int irq, int level) kvm_arm_gic_set_irq(s->num_irq, irq, level); } +#define KVM_VGIC_ATTR(reg, typer) \ + ((typer & KVM_DEV_ARM_VGIC_V3_CPUID_MASK) | (reg)) + +static inline void kvm_gicd_access(GICv3State *s, int offset, + uint32_t *val, bool write) +{ + kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS, + KVM_VGIC_ATTR(offset, 0), + val, write); +} + +static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu, + uint32_t *val, bool write) +{ + kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, + KVM_VGIC_ATTR(offset, s->cpu[cpu].gicr_typer), + val, write); +} + +static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu, + uint64_t *val, bool write) +{ + kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, + KVM_VGIC_ATTR(reg, s->cpu[cpu].gicr_typer), + val, write); +} + +/* Translate from the in-kernel field for an IRQ value to/from the qemu + * representation. Note that these are only expected to be used for + * SPIs (that is, for interrupts whose state is in the distributor + * rather than the redistributor). + */ +typedef void (*vgic_translate_fn)(GICv3State *s, int irq, + uint32_t *field, bool to_kernel); + +static void translate_edge_trigger(GICv3State *s, int irq, + uint32_t *field, bool to_kernel) +{ + if (to_kernel) { \ + *field = gicv3_gicd_edge_trigger_test(s, irq); \ + } else { \ + gicv3_gicd_edge_trigger_replace(s, irq, *field); \ + } \ +} + +static void translate_priority(GICv3State *s, int irq, + uint32_t *field, bool to_kernel) +{ + if (to_kernel) { + *field = s->gicd_ipriority[irq]; + } else { + s->gicd_ipriority[irq] = *field; + } +} + +/* Loop through each distributor IRQ related register; since bits + * corresponding to SPIs and PPIs are RAZ/WI when affinity routing + * is enabled, we skip those. + */ +#define for_each_dist_irq_reg(_irq, _max, _field_width) \ + for (_irq = GIC_INTERNAL; _irq < _max; _irq += (32 / _field_width)) + +/* Read a register group from the kernel VGIC */ +static void kvm_dist_get(GICv3State *s, uint32_t offset, int width, + vgic_translate_fn translate_fn) +{ + uint32_t reg; + int j; + int irq; + uint32_t field; + int regsz = 32 / width; /* irqs per kernel register */ + + for_each_dist_irq_reg(irq, s->num_irq, width) { + kvm_gicd_access(s, offset, ®, false); + + for (j = 0; j < regsz; j++) { + field = extract32(reg, j * width, width); + translate_fn(s, irq + j, &field, false); + } + offset += 4; + } +} + +/* Write a register group to the kernel VGIC */ +static void kvm_dist_put(GICv3State *s, uint32_t offset, int width, + vgic_translate_fn translate_fn) +{ + uint32_t reg; + int j; + int irq; + uint32_t field; + int regsz = 32 / width; /* irqs per kernel register */ + + for_each_dist_irq_reg(irq, s->num_irq, width) { + reg = 0; + for (j = 0; j < regsz; j++) { + translate_fn(s, irq + j, &field, true); + reg = deposit32(reg, j * width, width, field); + } + kvm_gicd_access(s, offset, ®, true); + offset += 4; + } +} + +/* Read a bitmap register group from the kernel VGIC. */ +static void kvm_dist_getbmp(GICv3State *s, uint32_t offset, uint32_t *bmp) +{ + uint32_t reg; + int irq; + + for_each_dist_irq_reg(irq, s->num_irq, 1) { + kvm_gicd_access(s, offset, ®, false); + *gic_bmp_ptr32(bmp, irq) = reg; + offset += 4; + } +} + +static void kvm_dist_putbmp(GICv3State *s, uint32_t offset, + uint32_t clroffset, uint32_t *bmp) +{ + uint32_t reg; + int irq; + + for_each_dist_irq_reg(irq, s->num_irq, 1) { + /* If this bitmap is a set/clear register pair, first write to the + * clear-reg to clear all bits before using the set-reg to write + * the 1 bits. + */ + if (clroffset != 0) { + reg = 0; + kvm_gicd_access(s, clroffset, ®, true); + } + reg = *gic_bmp_ptr32(bmp, irq); + kvm_gicd_access(s, offset, ®, true); + offset += 4; + } +} + +static void kvm_arm_gicv3_check(GICv3State *s) +{ + uint32_t reg; + uint32_t num_irq; + + /* Sanity checking s->num_irq */ + kvm_gicd_access(s, GICD_TYPER, ®, false); + num_irq = ((reg & 0x1f) + 1) * 32; + + if (num_irq < s->num_irq) { + error_report("Model requests %u IRQs, but kernel supports max %u", + s->num_irq, num_irq); + abort(); + } +} + static void kvm_arm_gicv3_put(GICv3State *s) { - /* TODO */ - DPRINTF("Cannot put kernel gic state, no kernel interface\n"); + uint32_t regl, regh, reg; + uint64_t reg64, redist_typer; + int ncpu, i; + + kvm_arm_gicv3_check(s); + + kvm_gicr_access(s, GICR_TYPER, 0, ®l, false); + kvm_gicr_access(s, GICR_TYPER + 4, 0, ®h, false); + redist_typer = ((uint64_t)regh << 32) | regl; + + reg = s->gicd_ctlr; + kvm_gicd_access(s, GICD_CTLR, ®, true); + + if (redist_typer & GICR_TYPER_PLPIS) { + /* Set base addresses before LPIs are enabled by GICR_CTLR write */ + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + reg64 = c->gicr_propbaser; + regl = (uint32_t)reg64; + kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, true); + regh = (uint32_t)(reg64 >> 32); + kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, ®h, true); + + reg64 = c->gicr_pendbaser; + if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) { + /* Setting PTZ is advised if LPIs are disabled, to reduce + * GIC initialization time. + */ + reg64 |= GICR_PENDBASER_PTZ; + } + regl = (uint32_t)reg64; + kvm_gicr_access(s, GICR_PENDBASER, ncpu, ®l, true); + regh = (uint32_t)(reg64 >> 32); + kvm_gicr_access(s, GICR_PENDBASER + 4, ncpu, ®h, true); + } + } + + /* Redistributor state (one per CPU) */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + reg = c->gicr_ctlr; + kvm_gicr_access(s, GICR_CTLR, ncpu, ®, true); + + reg = c->gicr_statusr[GICV3_NS]; + kvm_gicr_access(s, GICR_STATUSR, ncpu, ®, true); + + reg = c->gicr_waker; + kvm_gicr_access(s, GICR_WAKER, ncpu, ®, true); + + reg = c->gicr_igroupr0; + kvm_gicr_access(s, GICR_IGROUPR0, ncpu, ®, true); + + reg = ~0; + kvm_gicr_access(s, GICR_ICENABLER0, ncpu, ®, true); + reg = c->gicr_ienabler0; + kvm_gicr_access(s, GICR_ISENABLER0, ncpu, ®, true); + + /* Restore config before pending so we treat level/edge correctly */ + reg = half_shuffle32(c->edge_trigger >> 16) << 1; + kvm_gicr_access(s, GICR_ICFGR1, ncpu, ®, true); + + // TODO: there is no kernel API for reading/writing c->level + + reg = ~0; + kvm_gicr_access(s, GICR_ICPENDR0, ncpu, ®, true); + reg = c->gicr_ipendr0; + kvm_gicr_access(s, GICR_ISPENDR0, ncpu, ®, true); + + reg = ~0; + kvm_gicr_access(s, GICR_ICACTIVER0, ncpu, ®, true); + reg = c->gicr_iactiver0; + kvm_gicr_access(s, GICR_ISACTIVER0, ncpu, ®, true); + + for (i = 0; i < GIC_INTERNAL; i += 4) { + reg = c->gicr_ipriorityr[i] | + (c->gicr_ipriorityr[i + 1] << 8) | + (c->gicr_ipriorityr[i + 2] << 16) | + (c->gicr_ipriorityr[i + 3] << 24); + kvm_gicr_access(s, GICR_IPRIORITYR + i, ncpu, ®, true); + } + } + + /* Distributor state (shared between all CPUs */ + reg = s->gicd_statusr[GICV3_NS]; + kvm_gicd_access(s, GICD_STATUSR, ®, true); + + /* s->enable bitmap -> GICD_ISENABLERn */ + kvm_dist_putbmp(s, GICD_ISENABLER, GICD_ICENABLER, s->enabled); + + /* s->group bitmap -> GICD_IGROUPRn */ + kvm_dist_putbmp(s, GICD_IGROUPR, 0, s->group); + + /* Restore targets before pending to ensure the pending state is set on + * the appropriate CPU interfaces in the kernel + */ + + /* s->gicd_irouter[irq] -> GICD_IROUTERn + * We can't use kvm_dist_put() here because the registers are 64-bit + */ + for (i = GIC_INTERNAL; i < s->num_irq; i++) { + uint32_t offset; + + offset = GICD_IROUTER + (sizeof(uint32_t) * i); + reg = (uint32_t)s->gicd_irouter[i]; + kvm_gicd_access(s, offset, ®, true); + + offset = GICD_IROUTER + (sizeof(uint32_t) * i) + 4; + reg = (uint32_t)(s->gicd_irouter[i] >> 32); + kvm_gicd_access(s, offset, ®, true); + } + + /* s->trigger bitmap -> GICD_ICFGRn + * (restore configuration registers before pending IRQs so we treat + * level/edge correctly) + */ + kvm_dist_put(s, GICD_ICFGR, 2, translate_edge_trigger); + + // TODO: there is no kernel API for reading/writing s->level + + /* s->pending bitmap -> GICD_ISPENDRn */ + kvm_dist_putbmp(s, GICD_ISPENDR, GICD_ICPENDR, s->pending); + + /* s->active bitmap -> GICD_ISACTIVERn */ + kvm_dist_putbmp(s, GICD_ISACTIVER, GICD_ICACTIVER, s->active); + + /* s->gicd_ipriority[] -> GICD_IPRIORITYRn */ + kvm_dist_put(s, GICD_IPRIORITYR, 8, translate_priority); + + /* CPU Interface state (one per CPU) */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicc_access(s, ICC_CTLR_EL1, ncpu, + &c->icc_ctlr_el1[GICV3_NS], true); + kvm_gicc_access(s, ICC_IGRPEN0_EL1, ncpu, + &c->icc_igrpen[GICV3_G0], true); + kvm_gicc_access(s, ICC_IGRPEN1_EL1, ncpu, + &c->icc_igrpen[GICV3_G1NS], true); + kvm_gicc_access(s, ICC_PMR_EL1, ncpu, &c->icc_pmr_el1, true); + kvm_gicc_access(s, ICC_BPR0_EL1, ncpu, &c->icc_bpr[GICV3_G0], true); + kvm_gicc_access(s, ICC_BPR1_EL1, ncpu, &c->icc_bpr[GICV3_G1NS], true); + + for (i = 0; i < 4; i++) { + reg64 = c->icc_apr[GICV3_G0][i]; + kvm_gicc_access(s, ICC_AP0R_EL1(i), ncpu, ®64, true); + } + + for (i = 0; i < 4; i++) { + reg64 = c->icc_apr[GICV3_G1NS][i]; + kvm_gicc_access(s, ICC_AP1R_EL1(i), ncpu, ®64, true); + } + } } static void kvm_arm_gicv3_get(GICv3State *s) { - /* TODO */ - DPRINTF("Cannot get kernel gic state, no kernel interface\n"); + uint32_t regl, regh, reg; + uint64_t reg64, redist_typer; + int ncpu, i; + + kvm_arm_gicv3_check(s); + + kvm_gicr_access(s, GICR_TYPER, 0, ®l, false); + kvm_gicr_access(s, GICR_TYPER + 4, 0, ®h, false); + redist_typer = ((uint64_t)regh << 32) | regl; + + kvm_gicd_access(s, GICD_CTLR, ®, false); + s->gicd_ctlr = reg; + + /* Redistributor state (one per CPU) */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicr_access(s, GICR_CTLR, ncpu, ®, false); + c->gicr_ctlr = reg; + + kvm_gicr_access(s, GICR_STATUSR, ncpu, ®, false); + c->gicr_statusr[GICV3_NS] = reg; + + kvm_gicr_access(s, GICR_WAKER, ncpu, ®, false); + c->gicr_waker = reg; + + kvm_gicr_access(s, GICR_IGROUPR0, ncpu, ®, false); + c->gicr_igroupr0 = reg; + kvm_gicr_access(s, GICR_ISENABLER0, ncpu, ®, false); + c->gicr_ienabler0 = reg; + kvm_gicr_access(s, GICR_ICFGR1, ncpu, ®, false); + c->edge_trigger = half_unshuffle32(reg >> 1) << 16; + kvm_gicr_access(s, GICR_ISPENDR0, ncpu, ®, false); + c->gicr_ipendr0 = reg; + kvm_gicr_access(s, GICR_ISACTIVER0, ncpu, ®, false); + c->gicr_iactiver0 = reg; + + for (i = 0; i < GIC_INTERNAL; i += 4) { + kvm_gicr_access(s, GICR_IPRIORITYR + i, ncpu, ®, false); + c->gicr_ipriorityr[i] = extract32(reg, 0, 8); + c->gicr_ipriorityr[i + 1] = extract32(reg, 8, 8); + c->gicr_ipriorityr[i + 2] = extract32(reg, 16, 8); + c->gicr_ipriorityr[i + 3] = extract32(reg, 24, 8); + } + } + + if (redist_typer & GICR_TYPER_PLPIS) { + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, false); + kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, ®h, false); + c->gicr_propbaser = ((uint64_t)regh << 32) | regl; + + kvm_gicr_access(s, GICR_PENDBASER, ncpu, ®l, false); + kvm_gicr_access(s, GICR_PENDBASER + 4, ncpu, ®h, false); + c->gicr_pendbaser = ((uint64_t)regh << 32) | regl; + } + } + + /* Distributor state (shared between all CPUs */ + + kvm_gicd_access(s, GICD_STATUSR, ®, false); + s->gicd_statusr[GICV3_NS] = reg; + + /* GICD_IGROUPRn -> s->group bitmap */ + kvm_dist_getbmp(s, GICD_IGROUPR, s->group); + + /* GICD_ISENABLERn -> s->enabled bitmap */ + kvm_dist_getbmp(s, GICD_ISENABLER, s->enabled); + + /* GICD_ISPENDRn -> s->pending bitmap */ + kvm_dist_getbmp(s, GICD_ISPENDR, s->pending); + + /* GICD_ISACTIVERn -> s->active bitmap */ + kvm_dist_getbmp(s, GICD_ISACTIVER, s->active); + + /* GICD_ICFGRn -> s->trigger bitmap */ + kvm_dist_get(s, GICD_ICFGR, 2, translate_edge_trigger); + + /* GICD_IPRIORITYRn -> s->gicd_ipriority[] */ + kvm_dist_get(s, GICD_IPRIORITYR, 8, translate_priority); + + /* GICD_IROUTERn -> s->gicd_irouter[irq] */ + for (i = GIC_INTERNAL; i < s->num_irq; i++) { + uint32_t offset; + + offset = GICD_IROUTER + (sizeof(uint32_t) * i); + kvm_gicd_access(s, offset, ®l, false); + offset = GICD_IROUTER + (sizeof(uint32_t) * i) + 4; + kvm_gicd_access(s, offset, ®h, false); + s->gicd_irouter[i] = ((uint64_t)regh << 32) | regl; + } + + /***************************************************************** + * CPU Interface(s) State + */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicc_access(s, ICC_CTLR_EL1, ncpu, + &c->icc_ctlr_el1[GICV3_NS], false); + kvm_gicc_access(s, ICC_IGRPEN0_EL1, ncpu, + &c->icc_igrpen[GICV3_G0], false); + kvm_gicc_access(s, ICC_IGRPEN1_EL1, ncpu, + &c->icc_igrpen[GICV3_G1NS], false); + kvm_gicc_access(s, ICC_PMR_EL1, ncpu, &c->icc_pmr_el1, false); + kvm_gicc_access(s, ICC_BPR0_EL1, ncpu, &c->icc_bpr[GICV3_G0], false); + kvm_gicc_access(s, ICC_BPR1_EL1, ncpu, &c->icc_bpr[GICV3_G1NS], false); + + for (i = 0; i < 4; i++) { + kvm_gicc_access(s, ICC_AP0R_EL1(i), ncpu, ®64, false); + c->icc_apr[0][i] = reg64; + } + + for (i = 0; i < 4; i++) { + kvm_gicc_access(s, ICC_AP1R_EL1(i), ncpu, ®64, false); + c->icc_apr[1][i] = reg64; + } + } } static void kvm_arm_gicv3_reset(DeviceState *dev) @@ -77,6 +525,12 @@ static void kvm_arm_gicv3_reset(DeviceState *dev) DPRINTF("Reset\n"); kgc->parent_reset(dev); + + if (s->migration_blocker) { + DPRINTF("Cannot put kernel gic state, no kernel interface\n"); + return; + } + kvm_arm_gicv3_put(s); } @@ -121,12 +575,12 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd); - /* Block migration of a KVM GICv3 device: the API for saving and restoring - * the state in the kernel is not yet finalised in the kernel or - * implemented in QEMU. - */ - error_setg(&s->migration_blocker, "vGICv3 migration is not implemented"); - migrate_add_blocker(s->migration_blocker); + if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS, + GICD_CTLR)) { + error_setg(&s->migration_blocker, "This operating system kernel does " + "not support vGICv3 migration"); + migrate_add_blocker(s->migration_blocker); + } } static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data) -- 1.9.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [RFC PATCH v2 2/2] hw/intc/arm_gicv3_kvm: Implement get/put functions @ 2016-08-08 16:51 ` vijay.kilari 0 siblings, 0 replies; 12+ messages in thread From: vijay.kilari @ 2016-08-08 16:51 UTC (permalink / raw) To: qemu-arm, peter.maydell, pbonzini Cc: p.fedin, qemu-devel, Prasun.Kapoor, vijay.kilari, Vijaya Kumar K From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> This actually implements pre_save and post_load methods for in-kernel vGICv3. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> [PMM: * use decimal, not 0bnnn * fixed typo in names of ICC_APR0R_EL1 and ICC_AP1R_EL1 * completely rearranged the get and put functions to read and write the state in a natural order, rather than mixing distributor and redistributor state together] Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com> [Vijay: * Update macro KVM_VGIC_ATTR * Use 32 bit access for gicd and gicr * GICD_IROUTER, GICD_TYPER, GICR_PROPBASER and GICR_PENDBASER reg access are changed from 64-bit to 32-bit access] --- hw/intc/arm_gicv3_kvm.c | 474 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 464 insertions(+), 10 deletions(-) diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c index 711fde3..0f84c86 100644 --- a/hw/intc/arm_gicv3_kvm.c +++ b/hw/intc/arm_gicv3_kvm.c @@ -23,8 +23,11 @@ #include "qapi/error.h" #include "hw/intc/arm_gicv3_common.h" #include "hw/sysbus.h" +#include "migration/migration.h" +#include "qemu/error-report.h" #include "sysemu/kvm.h" #include "kvm_arm.h" +#include "gicv3_internal.h" #include "vgic_common.h" #include "migration/migration.h" @@ -44,6 +47,23 @@ #define KVM_ARM_GICV3_GET_CLASS(obj) \ OBJECT_GET_CLASS(KVMARMGICv3Class, (obj), TYPE_KVM_ARM_GICV3) +#define ICC_PMR_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 4, 6, 0) +#define ICC_BPR0_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 8, 3) +#define ICC_AP0R_EL1(n) \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 8, 4 | n) +#define ICC_AP1R_EL1(n) \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 9, n) +#define ICC_BPR1_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 3) +#define ICC_CTLR_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 4) +#define ICC_IGRPEN0_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 6) +#define ICC_IGRPEN1_EL1 \ + KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 7) + typedef struct KVMARMGICv3Class { ARMGICv3CommonClass parent_class; DeviceRealize parent_realize; @@ -57,16 +77,444 @@ static void kvm_arm_gicv3_set_irq(void *opaque, int irq, int level) kvm_arm_gic_set_irq(s->num_irq, irq, level); } +#define KVM_VGIC_ATTR(reg, typer) \ + ((typer & KVM_DEV_ARM_VGIC_V3_CPUID_MASK) | (reg)) + +static inline void kvm_gicd_access(GICv3State *s, int offset, + uint32_t *val, bool write) +{ + kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS, + KVM_VGIC_ATTR(offset, 0), + val, write); +} + +static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu, + uint32_t *val, bool write) +{ + kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS, + KVM_VGIC_ATTR(offset, s->cpu[cpu].gicr_typer), + val, write); +} + +static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu, + uint64_t *val, bool write) +{ + kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS, + KVM_VGIC_ATTR(reg, s->cpu[cpu].gicr_typer), + val, write); +} + +/* Translate from the in-kernel field for an IRQ value to/from the qemu + * representation. Note that these are only expected to be used for + * SPIs (that is, for interrupts whose state is in the distributor + * rather than the redistributor). + */ +typedef void (*vgic_translate_fn)(GICv3State *s, int irq, + uint32_t *field, bool to_kernel); + +static void translate_edge_trigger(GICv3State *s, int irq, + uint32_t *field, bool to_kernel) +{ + if (to_kernel) { \ + *field = gicv3_gicd_edge_trigger_test(s, irq); \ + } else { \ + gicv3_gicd_edge_trigger_replace(s, irq, *field); \ + } \ +} + +static void translate_priority(GICv3State *s, int irq, + uint32_t *field, bool to_kernel) +{ + if (to_kernel) { + *field = s->gicd_ipriority[irq]; + } else { + s->gicd_ipriority[irq] = *field; + } +} + +/* Loop through each distributor IRQ related register; since bits + * corresponding to SPIs and PPIs are RAZ/WI when affinity routing + * is enabled, we skip those. + */ +#define for_each_dist_irq_reg(_irq, _max, _field_width) \ + for (_irq = GIC_INTERNAL; _irq < _max; _irq += (32 / _field_width)) + +/* Read a register group from the kernel VGIC */ +static void kvm_dist_get(GICv3State *s, uint32_t offset, int width, + vgic_translate_fn translate_fn) +{ + uint32_t reg; + int j; + int irq; + uint32_t field; + int regsz = 32 / width; /* irqs per kernel register */ + + for_each_dist_irq_reg(irq, s->num_irq, width) { + kvm_gicd_access(s, offset, ®, false); + + for (j = 0; j < regsz; j++) { + field = extract32(reg, j * width, width); + translate_fn(s, irq + j, &field, false); + } + offset += 4; + } +} + +/* Write a register group to the kernel VGIC */ +static void kvm_dist_put(GICv3State *s, uint32_t offset, int width, + vgic_translate_fn translate_fn) +{ + uint32_t reg; + int j; + int irq; + uint32_t field; + int regsz = 32 / width; /* irqs per kernel register */ + + for_each_dist_irq_reg(irq, s->num_irq, width) { + reg = 0; + for (j = 0; j < regsz; j++) { + translate_fn(s, irq + j, &field, true); + reg = deposit32(reg, j * width, width, field); + } + kvm_gicd_access(s, offset, ®, true); + offset += 4; + } +} + +/* Read a bitmap register group from the kernel VGIC. */ +static void kvm_dist_getbmp(GICv3State *s, uint32_t offset, uint32_t *bmp) +{ + uint32_t reg; + int irq; + + for_each_dist_irq_reg(irq, s->num_irq, 1) { + kvm_gicd_access(s, offset, ®, false); + *gic_bmp_ptr32(bmp, irq) = reg; + offset += 4; + } +} + +static void kvm_dist_putbmp(GICv3State *s, uint32_t offset, + uint32_t clroffset, uint32_t *bmp) +{ + uint32_t reg; + int irq; + + for_each_dist_irq_reg(irq, s->num_irq, 1) { + /* If this bitmap is a set/clear register pair, first write to the + * clear-reg to clear all bits before using the set-reg to write + * the 1 bits. + */ + if (clroffset != 0) { + reg = 0; + kvm_gicd_access(s, clroffset, ®, true); + } + reg = *gic_bmp_ptr32(bmp, irq); + kvm_gicd_access(s, offset, ®, true); + offset += 4; + } +} + +static void kvm_arm_gicv3_check(GICv3State *s) +{ + uint32_t reg; + uint32_t num_irq; + + /* Sanity checking s->num_irq */ + kvm_gicd_access(s, GICD_TYPER, ®, false); + num_irq = ((reg & 0x1f) + 1) * 32; + + if (num_irq < s->num_irq) { + error_report("Model requests %u IRQs, but kernel supports max %u", + s->num_irq, num_irq); + abort(); + } +} + static void kvm_arm_gicv3_put(GICv3State *s) { - /* TODO */ - DPRINTF("Cannot put kernel gic state, no kernel interface\n"); + uint32_t regl, regh, reg; + uint64_t reg64, redist_typer; + int ncpu, i; + + kvm_arm_gicv3_check(s); + + kvm_gicr_access(s, GICR_TYPER, 0, ®l, false); + kvm_gicr_access(s, GICR_TYPER + 4, 0, ®h, false); + redist_typer = ((uint64_t)regh << 32) | regl; + + reg = s->gicd_ctlr; + kvm_gicd_access(s, GICD_CTLR, ®, true); + + if (redist_typer & GICR_TYPER_PLPIS) { + /* Set base addresses before LPIs are enabled by GICR_CTLR write */ + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + reg64 = c->gicr_propbaser; + regl = (uint32_t)reg64; + kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, true); + regh = (uint32_t)(reg64 >> 32); + kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, ®h, true); + + reg64 = c->gicr_pendbaser; + if (!c->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) { + /* Setting PTZ is advised if LPIs are disabled, to reduce + * GIC initialization time. + */ + reg64 |= GICR_PENDBASER_PTZ; + } + regl = (uint32_t)reg64; + kvm_gicr_access(s, GICR_PENDBASER, ncpu, ®l, true); + regh = (uint32_t)(reg64 >> 32); + kvm_gicr_access(s, GICR_PENDBASER + 4, ncpu, ®h, true); + } + } + + /* Redistributor state (one per CPU) */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + reg = c->gicr_ctlr; + kvm_gicr_access(s, GICR_CTLR, ncpu, ®, true); + + reg = c->gicr_statusr[GICV3_NS]; + kvm_gicr_access(s, GICR_STATUSR, ncpu, ®, true); + + reg = c->gicr_waker; + kvm_gicr_access(s, GICR_WAKER, ncpu, ®, true); + + reg = c->gicr_igroupr0; + kvm_gicr_access(s, GICR_IGROUPR0, ncpu, ®, true); + + reg = ~0; + kvm_gicr_access(s, GICR_ICENABLER0, ncpu, ®, true); + reg = c->gicr_ienabler0; + kvm_gicr_access(s, GICR_ISENABLER0, ncpu, ®, true); + + /* Restore config before pending so we treat level/edge correctly */ + reg = half_shuffle32(c->edge_trigger >> 16) << 1; + kvm_gicr_access(s, GICR_ICFGR1, ncpu, ®, true); + + // TODO: there is no kernel API for reading/writing c->level + + reg = ~0; + kvm_gicr_access(s, GICR_ICPENDR0, ncpu, ®, true); + reg = c->gicr_ipendr0; + kvm_gicr_access(s, GICR_ISPENDR0, ncpu, ®, true); + + reg = ~0; + kvm_gicr_access(s, GICR_ICACTIVER0, ncpu, ®, true); + reg = c->gicr_iactiver0; + kvm_gicr_access(s, GICR_ISACTIVER0, ncpu, ®, true); + + for (i = 0; i < GIC_INTERNAL; i += 4) { + reg = c->gicr_ipriorityr[i] | + (c->gicr_ipriorityr[i + 1] << 8) | + (c->gicr_ipriorityr[i + 2] << 16) | + (c->gicr_ipriorityr[i + 3] << 24); + kvm_gicr_access(s, GICR_IPRIORITYR + i, ncpu, ®, true); + } + } + + /* Distributor state (shared between all CPUs */ + reg = s->gicd_statusr[GICV3_NS]; + kvm_gicd_access(s, GICD_STATUSR, ®, true); + + /* s->enable bitmap -> GICD_ISENABLERn */ + kvm_dist_putbmp(s, GICD_ISENABLER, GICD_ICENABLER, s->enabled); + + /* s->group bitmap -> GICD_IGROUPRn */ + kvm_dist_putbmp(s, GICD_IGROUPR, 0, s->group); + + /* Restore targets before pending to ensure the pending state is set on + * the appropriate CPU interfaces in the kernel + */ + + /* s->gicd_irouter[irq] -> GICD_IROUTERn + * We can't use kvm_dist_put() here because the registers are 64-bit + */ + for (i = GIC_INTERNAL; i < s->num_irq; i++) { + uint32_t offset; + + offset = GICD_IROUTER + (sizeof(uint32_t) * i); + reg = (uint32_t)s->gicd_irouter[i]; + kvm_gicd_access(s, offset, ®, true); + + offset = GICD_IROUTER + (sizeof(uint32_t) * i) + 4; + reg = (uint32_t)(s->gicd_irouter[i] >> 32); + kvm_gicd_access(s, offset, ®, true); + } + + /* s->trigger bitmap -> GICD_ICFGRn + * (restore configuration registers before pending IRQs so we treat + * level/edge correctly) + */ + kvm_dist_put(s, GICD_ICFGR, 2, translate_edge_trigger); + + // TODO: there is no kernel API for reading/writing s->level + + /* s->pending bitmap -> GICD_ISPENDRn */ + kvm_dist_putbmp(s, GICD_ISPENDR, GICD_ICPENDR, s->pending); + + /* s->active bitmap -> GICD_ISACTIVERn */ + kvm_dist_putbmp(s, GICD_ISACTIVER, GICD_ICACTIVER, s->active); + + /* s->gicd_ipriority[] -> GICD_IPRIORITYRn */ + kvm_dist_put(s, GICD_IPRIORITYR, 8, translate_priority); + + /* CPU Interface state (one per CPU) */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicc_access(s, ICC_CTLR_EL1, ncpu, + &c->icc_ctlr_el1[GICV3_NS], true); + kvm_gicc_access(s, ICC_IGRPEN0_EL1, ncpu, + &c->icc_igrpen[GICV3_G0], true); + kvm_gicc_access(s, ICC_IGRPEN1_EL1, ncpu, + &c->icc_igrpen[GICV3_G1NS], true); + kvm_gicc_access(s, ICC_PMR_EL1, ncpu, &c->icc_pmr_el1, true); + kvm_gicc_access(s, ICC_BPR0_EL1, ncpu, &c->icc_bpr[GICV3_G0], true); + kvm_gicc_access(s, ICC_BPR1_EL1, ncpu, &c->icc_bpr[GICV3_G1NS], true); + + for (i = 0; i < 4; i++) { + reg64 = c->icc_apr[GICV3_G0][i]; + kvm_gicc_access(s, ICC_AP0R_EL1(i), ncpu, ®64, true); + } + + for (i = 0; i < 4; i++) { + reg64 = c->icc_apr[GICV3_G1NS][i]; + kvm_gicc_access(s, ICC_AP1R_EL1(i), ncpu, ®64, true); + } + } } static void kvm_arm_gicv3_get(GICv3State *s) { - /* TODO */ - DPRINTF("Cannot get kernel gic state, no kernel interface\n"); + uint32_t regl, regh, reg; + uint64_t reg64, redist_typer; + int ncpu, i; + + kvm_arm_gicv3_check(s); + + kvm_gicr_access(s, GICR_TYPER, 0, ®l, false); + kvm_gicr_access(s, GICR_TYPER + 4, 0, ®h, false); + redist_typer = ((uint64_t)regh << 32) | regl; + + kvm_gicd_access(s, GICD_CTLR, ®, false); + s->gicd_ctlr = reg; + + /* Redistributor state (one per CPU) */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicr_access(s, GICR_CTLR, ncpu, ®, false); + c->gicr_ctlr = reg; + + kvm_gicr_access(s, GICR_STATUSR, ncpu, ®, false); + c->gicr_statusr[GICV3_NS] = reg; + + kvm_gicr_access(s, GICR_WAKER, ncpu, ®, false); + c->gicr_waker = reg; + + kvm_gicr_access(s, GICR_IGROUPR0, ncpu, ®, false); + c->gicr_igroupr0 = reg; + kvm_gicr_access(s, GICR_ISENABLER0, ncpu, ®, false); + c->gicr_ienabler0 = reg; + kvm_gicr_access(s, GICR_ICFGR1, ncpu, ®, false); + c->edge_trigger = half_unshuffle32(reg >> 1) << 16; + kvm_gicr_access(s, GICR_ISPENDR0, ncpu, ®, false); + c->gicr_ipendr0 = reg; + kvm_gicr_access(s, GICR_ISACTIVER0, ncpu, ®, false); + c->gicr_iactiver0 = reg; + + for (i = 0; i < GIC_INTERNAL; i += 4) { + kvm_gicr_access(s, GICR_IPRIORITYR + i, ncpu, ®, false); + c->gicr_ipriorityr[i] = extract32(reg, 0, 8); + c->gicr_ipriorityr[i + 1] = extract32(reg, 8, 8); + c->gicr_ipriorityr[i + 2] = extract32(reg, 16, 8); + c->gicr_ipriorityr[i + 3] = extract32(reg, 24, 8); + } + } + + if (redist_typer & GICR_TYPER_PLPIS) { + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, false); + kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, ®h, false); + c->gicr_propbaser = ((uint64_t)regh << 32) | regl; + + kvm_gicr_access(s, GICR_PENDBASER, ncpu, ®l, false); + kvm_gicr_access(s, GICR_PENDBASER + 4, ncpu, ®h, false); + c->gicr_pendbaser = ((uint64_t)regh << 32) | regl; + } + } + + /* Distributor state (shared between all CPUs */ + + kvm_gicd_access(s, GICD_STATUSR, ®, false); + s->gicd_statusr[GICV3_NS] = reg; + + /* GICD_IGROUPRn -> s->group bitmap */ + kvm_dist_getbmp(s, GICD_IGROUPR, s->group); + + /* GICD_ISENABLERn -> s->enabled bitmap */ + kvm_dist_getbmp(s, GICD_ISENABLER, s->enabled); + + /* GICD_ISPENDRn -> s->pending bitmap */ + kvm_dist_getbmp(s, GICD_ISPENDR, s->pending); + + /* GICD_ISACTIVERn -> s->active bitmap */ + kvm_dist_getbmp(s, GICD_ISACTIVER, s->active); + + /* GICD_ICFGRn -> s->trigger bitmap */ + kvm_dist_get(s, GICD_ICFGR, 2, translate_edge_trigger); + + /* GICD_IPRIORITYRn -> s->gicd_ipriority[] */ + kvm_dist_get(s, GICD_IPRIORITYR, 8, translate_priority); + + /* GICD_IROUTERn -> s->gicd_irouter[irq] */ + for (i = GIC_INTERNAL; i < s->num_irq; i++) { + uint32_t offset; + + offset = GICD_IROUTER + (sizeof(uint32_t) * i); + kvm_gicd_access(s, offset, ®l, false); + offset = GICD_IROUTER + (sizeof(uint32_t) * i) + 4; + kvm_gicd_access(s, offset, ®h, false); + s->gicd_irouter[i] = ((uint64_t)regh << 32) | regl; + } + + /***************************************************************** + * CPU Interface(s) State + */ + + for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { + GICv3CPUState *c = &s->cpu[ncpu]; + + kvm_gicc_access(s, ICC_CTLR_EL1, ncpu, + &c->icc_ctlr_el1[GICV3_NS], false); + kvm_gicc_access(s, ICC_IGRPEN0_EL1, ncpu, + &c->icc_igrpen[GICV3_G0], false); + kvm_gicc_access(s, ICC_IGRPEN1_EL1, ncpu, + &c->icc_igrpen[GICV3_G1NS], false); + kvm_gicc_access(s, ICC_PMR_EL1, ncpu, &c->icc_pmr_el1, false); + kvm_gicc_access(s, ICC_BPR0_EL1, ncpu, &c->icc_bpr[GICV3_G0], false); + kvm_gicc_access(s, ICC_BPR1_EL1, ncpu, &c->icc_bpr[GICV3_G1NS], false); + + for (i = 0; i < 4; i++) { + kvm_gicc_access(s, ICC_AP0R_EL1(i), ncpu, ®64, false); + c->icc_apr[0][i] = reg64; + } + + for (i = 0; i < 4; i++) { + kvm_gicc_access(s, ICC_AP1R_EL1(i), ncpu, ®64, false); + c->icc_apr[1][i] = reg64; + } + } } static void kvm_arm_gicv3_reset(DeviceState *dev) @@ -77,6 +525,12 @@ static void kvm_arm_gicv3_reset(DeviceState *dev) DPRINTF("Reset\n"); kgc->parent_reset(dev); + + if (s->migration_blocker) { + DPRINTF("Cannot put kernel gic state, no kernel interface\n"); + return; + } + kvm_arm_gicv3_put(s); } @@ -121,12 +575,12 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd); - /* Block migration of a KVM GICv3 device: the API for saving and restoring - * the state in the kernel is not yet finalised in the kernel or - * implemented in QEMU. - */ - error_setg(&s->migration_blocker, "vGICv3 migration is not implemented"); - migrate_add_blocker(s->migration_blocker); + if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS, + GICD_CTLR)) { + error_setg(&s->migration_blocker, "This operating system kernel does " + "not support vGICv3 migration"); + migrate_add_blocker(s->migration_blocker); + } } static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data) -- 1.9.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Qemu-arm] [RFC PATCH v2 2/2] hw/intc/arm_gicv3_kvm: Implement get/put functions 2016-08-08 16:51 ` vijay.kilari @ 2016-08-08 16:57 ` Peter Maydell -1 siblings, 0 replies; 12+ messages in thread From: Peter Maydell @ 2016-08-08 16:57 UTC (permalink / raw) To: Vijay Kilari Cc: prasun.kapoor, Pavel Fedin, QEMU Developers, Vijaya Kumar K, qemu-arm, Paolo Bonzini On 8 August 2016 at 17:51, <vijay.kilari@gmail.com> wrote: > From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> > > This actually implements pre_save and post_load methods for in-kernel > vGICv3. > > Signed-off-by: Pavel Fedin <p.fedin@samsung.com> > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > [PMM: > * use decimal, not 0bnnn > * fixed typo in names of ICC_APR0R_EL1 and ICC_AP1R_EL1 > * completely rearranged the get and put functions to read and write > the state in a natural order, rather than mixing distributor and > redistributor state together] > Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com> > [Vijay: > * Update macro KVM_VGIC_ATTR > * Use 32 bit access for gicd and gicr > * GICD_IROUTER, GICD_TYPER, GICR_PROPBASER and GICR_PENDBASER reg > access are changed from 64-bit to 32-bit access] > --- > + // TODO: there is no kernel API for reading/writing c->level We have now defined this API so this code should use it. > + // TODO: there is no kernel API for reading/writing s->level Also here (and similarly in the _get function). thanks -- PMM ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 2/2] hw/intc/arm_gicv3_kvm: Implement get/put functions @ 2016-08-08 16:57 ` Peter Maydell 0 siblings, 0 replies; 12+ messages in thread From: Peter Maydell @ 2016-08-08 16:57 UTC (permalink / raw) To: Vijay Kilari Cc: qemu-arm, Paolo Bonzini, Pavel Fedin, QEMU Developers, prasun.kapoor, Vijaya Kumar K On 8 August 2016 at 17:51, <vijay.kilari@gmail.com> wrote: > From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> > > This actually implements pre_save and post_load methods for in-kernel > vGICv3. > > Signed-off-by: Pavel Fedin <p.fedin@samsung.com> > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > [PMM: > * use decimal, not 0bnnn > * fixed typo in names of ICC_APR0R_EL1 and ICC_AP1R_EL1 > * completely rearranged the get and put functions to read and write > the state in a natural order, rather than mixing distributor and > redistributor state together] > Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com> > [Vijay: > * Update macro KVM_VGIC_ATTR > * Use 32 bit access for gicd and gicr > * GICD_IROUTER, GICD_TYPER, GICR_PROPBASER and GICR_PENDBASER reg > access are changed from 64-bit to 32-bit access] > --- > + // TODO: there is no kernel API for reading/writing c->level We have now defined this API so this code should use it. > + // TODO: there is no kernel API for reading/writing s->level Also here (and similarly in the _get function). thanks -- PMM ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-arm] [RFC PATCH v2 2/2] hw/intc/arm_gicv3_kvm: Implement get/put functions 2016-08-08 16:57 ` [Qemu-devel] " Peter Maydell @ 2016-08-09 6:52 ` Vijay Kilari -1 siblings, 0 replies; 12+ messages in thread From: Vijay Kilari @ 2016-08-09 6:52 UTC (permalink / raw) To: Peter Maydell Cc: prasun.kapoor, Pavel Fedin, QEMU Developers, Vijaya Kumar K, qemu-arm, Paolo Bonzini On Mon, Aug 8, 2016 at 10:27 PM, Peter Maydell <peter.maydell@linaro.org> wrote: > On 8 August 2016 at 17:51, <vijay.kilari@gmail.com> wrote: >> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> >> >> This actually implements pre_save and post_load methods for in-kernel >> vGICv3. >> >> Signed-off-by: Pavel Fedin <p.fedin@samsung.com> >> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> >> [PMM: >> * use decimal, not 0bnnn >> * fixed typo in names of ICC_APR0R_EL1 and ICC_AP1R_EL1 >> * completely rearranged the get and put functions to read and write >> the state in a natural order, rather than mixing distributor and >> redistributor state together] >> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com> >> [Vijay: >> * Update macro KVM_VGIC_ATTR >> * Use 32 bit access for gicd and gicr >> * GICD_IROUTER, GICD_TYPER, GICR_PROPBASER and GICR_PENDBASER reg >> access are changed from 64-bit to 32-bit access] >> --- > >> + // TODO: there is no kernel API for reading/writing c->level > > We have now defined this API so this code should use it. You mean storing and restoring of irq->line_level of kernel?. I don't see any API defined in new vgic to read line level. The irq pending information is updated when line_level is changed in kernel. Hence pending (ispendr) holds information of pending status of interrupt. Do you see line level is still required to save & restore? > >> + // TODO: there is no kernel API for reading/writing s->level > > Also here (and similarly in the _get function). > > thanks > -- PMM ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 2/2] hw/intc/arm_gicv3_kvm: Implement get/put functions @ 2016-08-09 6:52 ` Vijay Kilari 0 siblings, 0 replies; 12+ messages in thread From: Vijay Kilari @ 2016-08-09 6:52 UTC (permalink / raw) To: Peter Maydell Cc: qemu-arm, Paolo Bonzini, Pavel Fedin, QEMU Developers, prasun.kapoor, Vijaya Kumar K On Mon, Aug 8, 2016 at 10:27 PM, Peter Maydell <peter.maydell@linaro.org> wrote: > On 8 August 2016 at 17:51, <vijay.kilari@gmail.com> wrote: >> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com> >> >> This actually implements pre_save and post_load methods for in-kernel >> vGICv3. >> >> Signed-off-by: Pavel Fedin <p.fedin@samsung.com> >> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> >> [PMM: >> * use decimal, not 0bnnn >> * fixed typo in names of ICC_APR0R_EL1 and ICC_AP1R_EL1 >> * completely rearranged the get and put functions to read and write >> the state in a natural order, rather than mixing distributor and >> redistributor state together] >> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com> >> [Vijay: >> * Update macro KVM_VGIC_ATTR >> * Use 32 bit access for gicd and gicr >> * GICD_IROUTER, GICD_TYPER, GICR_PROPBASER and GICR_PENDBASER reg >> access are changed from 64-bit to 32-bit access] >> --- > >> + // TODO: there is no kernel API for reading/writing c->level > > We have now defined this API so this code should use it. You mean storing and restoring of irq->line_level of kernel?. I don't see any API defined in new vgic to read line level. The irq pending information is updated when line_level is changed in kernel. Hence pending (ispendr) holds information of pending status of interrupt. Do you see line level is still required to save & restore? > >> + // TODO: there is no kernel API for reading/writing s->level > > Also here (and similarly in the _get function). > > thanks > -- PMM ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-arm] [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support 2016-08-08 16:51 ` vijay.kilari @ 2016-08-08 16:58 ` no-reply -1 siblings, 0 replies; 12+ messages in thread From: no-reply @ 2016-08-08 16:58 UTC (permalink / raw) To: vijay.kilari Cc: peter.maydell, famz, vijay.kilari, Prasun.Kapoor, p.fedin, qemu-devel, Vijaya.Kumar, qemu-arm, pbonzini Hi, Your series seems to have some coding style problems. See output below for more information: Message-id: 1470675071-23677-1-git-send-email-vijay.kilari@gmail.com Type: series Subject: [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support === TEST SCRIPT BEGIN === #!/bin/bash BASE=base n=1 total=$(git log --oneline $BASE.. | wc -l) failed=0 commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..." if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then failed=1 echo fi n=$((n+1)) done exit $failed === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 From https://github.com/patchew-project/qemu * [new tag] patchew/1470675071-23677-1-git-send-email-vijay.kilari@gmail.com -> patchew/1470675071-23677-1-git-send-email-vijay.kilari@gmail.com Switched to a new branch 'test' 52635e4 hw/intc/arm_gicv3_kvm: Implement get/put functions 15053e8 kernel: Add definitions for GICv3 attributes === OUTPUT BEGIN === Checking PATCH 1/2: kernel: Add definitions for GICv3 attributes... ERROR: code indent should never use tabs #22: FILE: linux-headers/asm-arm64/kvm.h:183: +^I(ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \$ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ total: 9 errors, 0 warnings, 38 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. Checking PATCH 2/2: hw/intc/arm_gicv3_kvm: Implement get/put functions... ERROR: do not use C99 // comments #291: FILE: hw/intc/arm_gicv3_kvm.c:300: + // TODO: there is no kernel API for reading/writing c->level ERROR: do not use C99 // comments #347: FILE: hw/intc/arm_gicv3_kvm.c:356: + // TODO: there is no kernel API for reading/writing s->level total: 2 errors, 0 warnings, 512 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. === OUTPUT END === Test command exited with code: 1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support @ 2016-08-08 16:58 ` no-reply 0 siblings, 0 replies; 12+ messages in thread From: no-reply @ 2016-08-08 16:58 UTC (permalink / raw) To: vijay.kilari Cc: famz, qemu-arm, peter.maydell, pbonzini, Prasun.Kapoor, p.fedin, qemu-devel, Vijaya.Kumar Hi, Your series seems to have some coding style problems. See output below for more information: Message-id: 1470675071-23677-1-git-send-email-vijay.kilari@gmail.com Type: series Subject: [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support === TEST SCRIPT BEGIN === #!/bin/bash BASE=base n=1 total=$(git log --oneline $BASE.. | wc -l) failed=0 commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..." if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then failed=1 echo fi n=$((n+1)) done exit $failed === TEST SCRIPT END === Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 From https://github.com/patchew-project/qemu * [new tag] patchew/1470675071-23677-1-git-send-email-vijay.kilari@gmail.com -> patchew/1470675071-23677-1-git-send-email-vijay.kilari@gmail.com Switched to a new branch 'test' 52635e4 hw/intc/arm_gicv3_kvm: Implement get/put functions 15053e8 kernel: Add definitions for GICv3 attributes === OUTPUT BEGIN === Checking PATCH 1/2: kernel: Add definitions for GICv3 attributes... ERROR: code indent should never use tabs #22: FILE: linux-headers/asm-arm64/kvm.h:183: +^I(ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \$ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #47: FILE: linux-headers/asm-arm64/kvm.h:211: +#define KVM_DEV_ARM_VGIC_SYSREG(op0,op1,crn,crm,op2) \ ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ ERROR: space required after that ',' (ctx:VxV) #48: FILE: linux-headers/asm-arm64/kvm.h:212: + __ARM64_SYS_REG(op0,op1,crn,crm,op2) ^ total: 9 errors, 0 warnings, 38 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. Checking PATCH 2/2: hw/intc/arm_gicv3_kvm: Implement get/put functions... ERROR: do not use C99 // comments #291: FILE: hw/intc/arm_gicv3_kvm.c:300: + // TODO: there is no kernel API for reading/writing c->level ERROR: do not use C99 // comments #347: FILE: hw/intc/arm_gicv3_kvm.c:356: + // TODO: there is no kernel API for reading/writing s->level total: 2 errors, 0 warnings, 512 lines checked Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. === OUTPUT END === Test command exited with code: 1 ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-08-09 7:00 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-08-08 16:51 [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support vijay.kilari 2016-08-08 16:51 ` vijay.kilari 2016-08-08 16:51 ` [Qemu-arm] [RFC PATCH v2 1/2] kernel: Add definitions for GICv3 attributes vijay.kilari 2016-08-08 16:51 ` [Qemu-devel] " vijay.kilari 2016-08-08 16:51 ` [Qemu-devel] [RFC PATCH v2 2/2] hw/intc/arm_gicv3_kvm: Implement get/put functions vijay.kilari 2016-08-08 16:51 ` vijay.kilari 2016-08-08 16:57 ` [Qemu-arm] " Peter Maydell 2016-08-08 16:57 ` [Qemu-devel] " Peter Maydell 2016-08-09 6:52 ` [Qemu-arm] " Vijay Kilari 2016-08-09 6:52 ` [Qemu-devel] " Vijay Kilari 2016-08-08 16:58 ` [Qemu-arm] [Qemu-devel] [RFC PATCH v2 0/2] GICv3 live migration support no-reply 2016-08-08 16:58 ` no-reply
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.