/* * The Revision field in the IIDR have the following meanings: * * Revision 1: Report GICv2 interrupts as group 0 instead of group 1 * Revision 2: Interrupt groups are guest-configurable and signaled using * their configured groups.
*/
switch (addr & 0x0c) { case GIC_DIST_CTRL:
dist->enabled = val & GICD_ENABLE; if (!was_enabled && dist->enabled)
vgic_kick_vcpus(vcpu->kvm); break; case GIC_DIST_CTR: case GIC_DIST_IIDR: /* Nothing to do */ return;
}
}
switch (addr & 0x0c) { case GIC_DIST_IIDR:
reg = vgic_mmio_read_v2_misc(vcpu, addr, len); if ((reg ^ val) & ~GICD_IIDR_REVISION_MASK) return -EINVAL;
/* * If we observe a write to GICD_IIDR we know that userspace * has been updated and has had a chance to cope with older * kernels (VGICv2 IIDR.Revision == 0) incorrectly reporting * interrupts as group 1, and therefore we now allow groups to * be user writable. Doing this by default would break * migration from old kernels to new kernels with legacy * userspace.
*/
reg = FIELD_GET(GICD_IIDR_REVISION_MASK, reg); switch (reg) { case KVM_VGIC_IMP_REV_2: case KVM_VGIC_IMP_REV_3:
vcpu->kvm->arch.vgic.v2_groups_user_writable = true;
dist->implementation_rev = reg; return 0; default: return -EINVAL;
}
}
/* These are for userland accesses only, there is no guest-facing emulation. */ staticunsignedlong vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu,
gpa_t addr, unsignedint len)
{ struct vgic_vmcr vmcr;
u32 val;
vgic_get_vmcr(vcpu, &vmcr);
switch (addr & 0xff) { case GIC_CPU_CTRL:
val = vmcr.grpen0 << GIC_CPU_CTRL_EnableGrp0_SHIFT;
val |= vmcr.grpen1 << GIC_CPU_CTRL_EnableGrp1_SHIFT;
val |= vmcr.ackctl << GIC_CPU_CTRL_AckCtl_SHIFT;
val |= vmcr.fiqen << GIC_CPU_CTRL_FIQEn_SHIFT;
val |= vmcr.cbpr << GIC_CPU_CTRL_CBPR_SHIFT;
val |= vmcr.eoim << GIC_CPU_CTRL_EOImodeNS_SHIFT;
break; case GIC_CPU_PRIMASK: /* * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the * PMR field as GICH_VMCR.VMPriMask rather than * GICC_PMR.Priority, so we expose the upper five bits of * priority mask to userspace using the lower bits in the * unsigned long.
*/
val = (vmcr.pmr & GICV_PMR_PRIORITY_MASK) >>
GICV_PMR_PRIORITY_SHIFT; break; case GIC_CPU_BINPOINT:
val = vmcr.bpr; break; case GIC_CPU_ALIAS_BINPOINT:
val = vmcr.abpr; break; case GIC_CPU_IDENT:
val = ((PRODUCT_ID_KVM << 20) |
(GICC_ARCH_VERSION_V2 << 16) |
IMPLEMENTER_ARM); break; default: return 0;
}
break; case GIC_CPU_PRIMASK: /* * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the * PMR field as GICH_VMCR.VMPriMask rather than * GICC_PMR.Priority, so we expose the upper five bits of * priority mask to userspace using the lower bits in the * unsigned long.
*/
vmcr.pmr = (val << GICV_PMR_PRIORITY_SHIFT) &
GICV_PMR_PRIORITY_MASK; break; case GIC_CPU_BINPOINT:
vmcr.bpr = val; break; case GIC_CPU_ALIAS_BINPOINT:
vmcr.abpr = val; break;
}
vgic_set_vmcr(vcpu, &vmcr);
}
staticunsignedlong vgic_mmio_read_apr(struct kvm_vcpu *vcpu,
gpa_t addr, unsignedint len)
{ int n; /* which APRn is this */
n = (addr >> 2) & 0x3;
if (kvm_vgic_global_state.type == VGIC_V2) { /* GICv2 hardware systems support max. 32 groups */ if (n != 0) return 0; return vcpu->arch.vgic_cpu.vgic_v2.vgic_apr;
} else { struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
if (n > vgic_v3_max_apr_idx(vcpu)) return 0;
n = array_index_nospec(n, 4);
/* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */ return vgicv3->vgic_ap1r[n];
}
}
staticvoid vgic_mmio_write_apr(struct kvm_vcpu *vcpu,
gpa_t addr, unsignedint len, unsignedlong val)
{ int n; /* which APRn is this */
n = (addr >> 2) & 0x3;
if (kvm_vgic_global_state.type == VGIC_V2) { /* GICv2 hardware systems support max. 32 groups */ if (n != 0) return;
vcpu->arch.vgic_cpu.vgic_v2.vgic_apr = val;
} else { struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
if (n > vgic_v3_max_apr_idx(vcpu)) return;
n = array_index_nospec(n, 4);
/* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */
vgicv3->vgic_ap1r[n] = val;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.