summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8dfbacd)
raw | patch | inline | side by side (parent: 8dfbacd)
author | Jan Kiszka <jan.kiszka@siemens.com> | |
Wed, 3 Apr 2019 09:37:26 +0000 (09:37 +0000) | ||
committer | Jan Kiszka <jan.kiszka@siemens.com> | |
Mon, 8 Apr 2019 15:21:33 +0000 (17:21 +0200) |
Analogously to gic-v2: When enabling Jailhouse, Linux may have some SGIs
pending that have to be taken off the physical interface and forwarded
to the virtual one. Otherwise, we would lose them or even confuse
Jailhouse because it expects SGIs to be injected virtually only (done on
interception of GICD_SGIR).
Based on original patch by Peng Fan.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
pending that have to be taken off the physical interface and forwarded
to the virtual one. Otherwise, we would lose them or even confuse
Jailhouse because it expects SGIs to be injected virtually only (done on
interception of GICD_SGIR).
Based on original patch by Peng Fan.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
hypervisor/arch/arm-common/gic-v3.c | patch | blob | history |
index 8f82eb54238d9b4e1e2351247f6e6c1b3a3ff003..906d9a8d64e868542a26de0519699d61ba802a81 100644 (file)
unsigned long redist_addr = system_config->platform_info.arm.gicr_base;
unsigned long redist_size = GIC_V3_REDIST_SIZE;
void *redist_base = gicr_base;
+ unsigned long gicr_ispendr;
+ unsigned int n;
+ void *gicr;
u64 typer, mpidr;
u32 pidr, aff;
u32 cell_icc_ctlr, cell_icc_pmr, cell_icc_igrpen1;
return trace_error(-EIO);
/* Ensure all IPIs and the maintenance PPI are enabled. */
- mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER,
- 0x0000ffff | (1 << mnt_irq));
+ gicr = redist_base + GICR_SGI_BASE;
+ mmio_write32(gicr + GICR_ISENABLER, 0x0000ffff | (1 << mnt_irq));
/*
* Set EOIMode to 1
/* After this, the cells access the virtual interface of the GIC. */
arm_write_sysreg(ICH_HCR_EL2, ICH_HCR_EN);
+ /* Forward any pending physical SGIs to the virtual queue. */
+ gicr_ispendr = mmio_read32(gicr + GICR_ISPENDR);
+ for (n = 0; n < 16; n++) {
+ if (test_bit(n, &gicr_ispendr)) {
+ mmio_write32(gicr + GICR_ICPENDR, 1UL << n);
+ irqchip_set_pending(&cpu_data->public, n);
+ }
+ }
+
return 0;
}