提交 01eea2ad 编写于 作者: M Marc Zyngier 提交者: Xie XiuQi

irqchip/gic-v3-its: Allow use of pre-programmed LPI tables

mainline inclusion
from 4.20-rc1
commit: c440a9d9d113b9b3cd99bb5096c4aa47d515e463
category: kdump
bugzilla: 5272
CVE: NA

This 10 patches is used for secondary kernel using LPI.

[PATCH 01/10] irqchip/gic-v3-its: Change initialization ordering for LPIs
[PATCH 02/10] irqchip/gic-v3-its: Simplify LPI_PENDBASE_SZ usage
[PATCH 03/10] irqchip/gic-v3-its: Split property table clearing from allocation
[PATCH 04/10] irqchip/gic-v3-its: Move pending table allocation to init time
[PATCH 05/10] irqchip/gic-v3-its: Keep track of property table's PA and VA
[PATCH 06/10] irqchip/gic-v3-its: Allow use of pre-programmed LPI tables
[PATCH 07/10] irqchip/gic-v3-its: Use pre-programmed redistributor tables with kdump kernels
[PATCH 08/10] irqchip/gic-v3-its: Check that all RDs have the same property table
[PATCH 09/10] irqchip/gic-v3-its: Register LPI tables with EFI config table
[PATCH 10/10] irqchip/gic-v3-its: Allow use of LPI tables in reserved memory

--------------------------------------

In order to cope with kexec and GICv3, let's try and spot when
we're booting with LPIs already enabled, and the tables already
programmed into the redistributors.

This code is currently guarded by a predicate that is always false,
meaning this is not functionnal just yet.
Reviewed-by: NJulien Thierry <julien.thierry@arm.com>
Tested-by: NJeremy Linton <jeremy.linton@arm.com>
Tested-by: NBhupesh Sharma <bhsharma@redhat.com>
Tested-by: NLei Zhang <zhang.lei@jp.fujitsu.com>
Signed-off-by: NMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
上级 7c29f300
......@@ -52,6 +52,7 @@
#define ITS_FLAGS_SAVE_SUSPEND_STATE (1ULL << 3)
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
static u32 lpi_id_bits;
......@@ -1628,18 +1629,32 @@ static void its_free_prop_table(struct page *prop_page)
static int __init its_setup_lpi_prop_table(void)
{
struct page *page;
if (gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) {
u64 val;
lpi_id_bits = min_t(u32, GICD_TYPER_ID_BITS(gic_rdists->gicd_typer),
ITS_MAX_LPI_NRBITS);
page = its_allocate_prop_table(GFP_NOWAIT);
if (!page) {
pr_err("Failed to allocate PROPBASE\n");
return -ENOMEM;
}
val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER);
lpi_id_bits = (val & GICR_PROPBASER_IDBITS_MASK) + 1;
gic_rdists->prop_table_pa = page_to_phys(page);
gic_rdists->prop_table_va = page_address(page);
gic_rdists->prop_table_pa = val & GENMASK_ULL(51, 12);
gic_rdists->prop_table_va = memremap(gic_rdists->prop_table_pa,
LPI_PROPBASE_SZ,
MEMREMAP_WB);
gic_reset_prop_table(gic_rdists->prop_table_va);
} else {
struct page *page;
lpi_id_bits = min_t(u32,
GICD_TYPER_ID_BITS(gic_rdists->gicd_typer),
ITS_MAX_LPI_NRBITS);
page = its_allocate_prop_table(GFP_NOWAIT);
if (!page) {
pr_err("Failed to allocate PROPBASE\n");
return -ENOMEM;
}
gic_rdists->prop_table_pa = page_to_phys(page);
gic_rdists->prop_table_va = page_address(page);
}
pr_info("GICv3: using LPI property table @%pa\n",
&gic_rdists->prop_table_pa);
......@@ -1948,10 +1963,27 @@ static void its_free_pending_table(struct page *pt)
free_pages((unsigned long)page_address(pt), get_order(LPI_PENDBASE_SZ));
}
static bool enabled_lpis_allowed(void)
{
return false;
}
static int __init allocate_lpi_tables(void)
{
u64 val;
int err, cpu;
/*
* If LPIs are enabled while we run this from the boot CPU,
* flag the RD tables as pre-allocated if the stars do align.
*/
val = readl_relaxed(gic_data_rdist_rd_base() + GICR_CTLR);
if ((val & GICR_CTLR_ENABLE_LPIS) && enabled_lpis_allowed()) {
gic_rdists->flags |= (RDIST_FLAGS_RD_TABLES_PREALLOCATED |
RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING);
pr_info("GICv3: Using preallocated redistributor tables\n");
}
err = its_setup_lpi_prop_table();
if (err)
return err;
......@@ -1986,6 +2018,18 @@ static void its_cpu_init_lpis(void)
if (gic_data_rdist()->lpi_enabled)
return;
val = readl_relaxed(rbase + GICR_CTLR);
if ((gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) &&
(val & GICR_CTLR_ENABLE_LPIS)) {
paddr = gicr_read_pendbaser(rbase + GICR_PENDBASER);
paddr &= GENMASK_ULL(51, 16);
its_free_pending_table(gic_data_rdist()->pend_page);
gic_data_rdist()->pend_page = NULL;
goto out;
}
pend_page = gic_data_rdist()->pend_page;
paddr = page_to_phys(pend_page);
......@@ -2040,9 +2084,11 @@ static void its_cpu_init_lpis(void)
/* Make sure the GIC has seen the above */
dsb(sy);
out:
gic_data_rdist()->lpi_enabled = true;
pr_info("GICv3: CPU%d: using LPI pending table @%pa\n",
pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
smp_processor_id(),
gic_data_rdist()->pend_page ? "allocated" : "reserved",
&paddr);
}
......@@ -3535,8 +3581,11 @@ static int redist_disable_lpis(void)
* If coming via a CPU hotplug event, we don't need to disable
* LPIs before trying to re-enable them. They are already
* configured and all is well in the world.
*
* If running with preallocated tables, there is nothing to do.
*/
if (gic_data_rdist()->lpi_enabled)
if (gic_data_rdist()->lpi_enabled ||
(gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED))
return 0;
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册