1 Star 0 Fork 123

zhouli57/src-qemu

forked from src-openEuler/qemu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch 12.00 KB
一键复制 编辑 原始数据 按行查看 历史
朱科潜 提交于 2020-04-22 21:59 . arm/virt: Add ACPI CPU hotplug support
From 0a75312c069d89be94bcaa688429d8f60a0c528b Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Fri, 10 Apr 2020 13:15:35 +0800
Subject: [PATCH] intc/gicv3: Add pre-sizing capability to GICv3
Currently GICv3 supports fixed smp_cpus CPUs, and all CPUs are
present always. Now we want to pre-sizing GICv3 to support max_cpus
CPUs and not all of them are present always, so some sizing codes
should be concerned.
GIC irqs, GICR and GICC are pre-created for all possible CPUs at
start, but only smp_cpus CPUs are realize and irqs of smp_cpus CPUs
are connected.
Other code changes are mainly for arm_gicv3, and we do little about
kvm_arm_gicv3 becasue KVM will deal with the sizing information properly.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
hw/arm/virt.c | 17 +++++++++++----
hw/intc/arm_gicv3.c | 43 +++++++++++++++++++++++++-------------
hw/intc/arm_gicv3_common.c | 23 ++++++++++++++++++--
hw/intc/arm_gicv3_cpuif.c | 4 ++++
hw/intc/arm_gicv3_kvm.c | 28 ++++++++++++++++++++++++-
include/hw/arm/virt.h | 3 ++-
6 files changed, 96 insertions(+), 22 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 55d403bad6..dda22194b5 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -761,14 +761,19 @@ static void create_gic(VirtMachineState *vms)
SysBusDevice *gicbusdev;
const char *gictype;
int type = vms->gic_version, i;
+ /* The max number of CPUs suppored by GIC */
+ unsigned int num_cpus = ms->smp.cpus;
+ /* The number of CPUs present before boot */
unsigned int smp_cpus = ms->smp.cpus;
uint32_t nb_redist_regions = 0;
+ assert(num_cpus >= smp_cpus);
+
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
vms->gic = qdev_create(NULL, gictype);
qdev_prop_set_uint32(vms->gic, "revision", type);
- qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
+ qdev_prop_set_uint32(vms->gic, "num-cpu", num_cpus);
/* Note that the num-irq property counts both internal and external
* interrupts; there are always 32 of the former (mandated by GIC spec).
*/
@@ -780,7 +785,7 @@ static void create_gic(VirtMachineState *vms)
if (type == 3) {
uint32_t redist0_capacity =
vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
- uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
+ uint32_t redist0_count = MIN(num_cpus, redist0_capacity);
nb_redist_regions = virt_gicv3_redist_region_count(vms);
@@ -793,7 +798,7 @@ static void create_gic(VirtMachineState *vms)
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
- MIN(smp_cpus - redist0_count, redist1_capacity));
+ MIN(num_cpus - redist0_count, redist1_capacity));
}
} else {
if (!kvm_irqchip_in_kernel()) {
@@ -820,7 +825,11 @@ static void create_gic(VirtMachineState *vms)
/* Wire the outputs from each CPU's generic timer and the GICv3
* maintenance interrupt signal to the appropriate GIC PPI inputs,
- * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's
+ * inputs.
+ *
+ * The irqs of remaining CPUs (if we has) will be connected during
+ * hotplugging.
*/
for (i = 0; i < smp_cpus; i++) {
connect_gic_cpu_irqs(vms, i);
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
index cacef26546..a60185113f 100644
--- a/hw/intc/arm_gicv3.c
+++ b/hw/intc/arm_gicv3.c
@@ -20,6 +20,7 @@
#include "qemu/module.h"
#include "hw/sysbus.h"
#include "hw/intc/arm_gicv3.h"
+#include "qom/cpu.h"
#include "gicv3_internal.h"
static bool irqbetter(GICv3CPUState *cs, int irq, uint8_t prio)
@@ -206,7 +207,9 @@ static void gicv3_update_noirqset(GICv3State *s, int start, int len)
assert(len > 0);
for (i = 0; i < s->num_cpu; i++) {
- s->cpu[i].seenbetter = false;
+ if (qemu_get_cpu(i)) {
+ s->cpu[i].seenbetter = false;
+ }
}
/* Find the highest priority pending interrupt in this range. */
@@ -248,16 +251,18 @@ static void gicv3_update_noirqset(GICv3State *s, int start, int len)
* now be the new best one).
*/
for (i = 0; i < s->num_cpu; i++) {
- GICv3CPUState *cs = &s->cpu[i];
+ if (qemu_get_cpu(i)) {
+ GICv3CPUState *cs = &s->cpu[i];
- if (cs->seenbetter) {
- cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
- }
+ if (cs->seenbetter) {
+ cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
+ }
- if (!cs->seenbetter && cs->hppi.prio != 0xff &&
- cs->hppi.irq >= start && cs->hppi.irq < start + len) {
- gicv3_full_update_noirqset(s);
- break;
+ if (!cs->seenbetter && cs->hppi.prio != 0xff &&
+ cs->hppi.irq >= start && cs->hppi.irq < start + len) {
+ gicv3_full_update_noirqset(s);
+ break;
+ }
}
}
}
@@ -268,7 +273,9 @@ void gicv3_update(GICv3State *s, int start, int len)
gicv3_update_noirqset(s, start, len);
for (i = 0; i < s->num_cpu; i++) {
- gicv3_cpuif_update(&s->cpu[i]);
+ if (qemu_get_cpu(i)) {
+ gicv3_cpuif_update(&s->cpu[i]);
+ }
}
}
@@ -280,7 +287,9 @@ void gicv3_full_update_noirqset(GICv3State *s)
int i;
for (i = 0; i < s->num_cpu; i++) {
- s->cpu[i].hppi.prio = 0xff;
+ if (qemu_get_cpu(i)) {
+ s->cpu[i].hppi.prio = 0xff;
+ }
}
/* Note that we can guarantee that these functions will not
@@ -291,7 +300,9 @@ void gicv3_full_update_noirqset(GICv3State *s)
gicv3_update_noirqset(s, GIC_INTERNAL, s->num_irq - GIC_INTERNAL);
for (i = 0; i < s->num_cpu; i++) {
- gicv3_redist_update_noirqset(&s->cpu[i]);
+ if (qemu_get_cpu(i)) {
+ gicv3_redist_update_noirqset(&s->cpu[i]);
+ }
}
}
@@ -304,7 +315,9 @@ void gicv3_full_update(GICv3State *s)
gicv3_full_update_noirqset(s);
for (i = 0; i < s->num_cpu; i++) {
- gicv3_cpuif_update(&s->cpu[i]);
+ if (qemu_get_cpu(i)) {
+ gicv3_cpuif_update(&s->cpu[i]);
+ }
}
}
@@ -401,7 +414,9 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
}
for (i = 0; i < s->num_cpu; i++) {
- gicv3_cpu_realize(s, i);
+ if (qemu_get_cpu(i)) {
+ gicv3_cpu_realize(s, i);
+ }
}
}
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 8740a52c9f..913bf068be 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -24,10 +24,12 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
+#include "qemu/error-report.h"
#include "qom/cpu.h"
#include "hw/intc/arm_gicv3_common.h"
#include "gicv3_internal.h"
#include "hw/arm/linux-boot-if.h"
+#include "hw/boards.h"
#include "sysemu/kvm.h"
@@ -363,10 +365,15 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
for (i = 0; i < s->num_cpu; i++) {
CPUState *cpu = qemu_get_cpu(i);
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ const CPUArchIdList *possible_cpus = NULL;
uint64_t cpu_affid;
int last;
- arm_gicv3_common_cpu_realize(s, i);
+ if (cpu) {
+ arm_gicv3_common_cpu_realize(s, i);
+ }
/* Pre-construct the GICR_TYPER:
* For our implementation:
@@ -380,7 +387,19 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
* VLPIS == 0 (virtual LPIs not supported)
* PLPIS == 0 (physical LPIs not supported)
*/
- cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
+ if (cpu) {
+ cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
+ } else {
+ if (!mc->possible_cpu_arch_ids) {
+ error_report("MachineClass must implement possible_cpu_arch_ids "
+ "hook to support pre-sizing GICv3");
+ exit(1);
+ }
+
+ possible_cpus = mc->possible_cpu_arch_ids(ms);
+ cpu_affid = possible_cpus->cpus[i].arch_id;
+ }
+
last = (i == s->num_cpu - 1);
/* The CPU mp-affinity property is in MPIDR register format; squash
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 56aa5efede..a20aa693ea 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -1648,6 +1648,10 @@ static void icc_generate_sgi(CPUARMState *env, GICv3CPUState *cs,
aff, targetlist);
for (i = 0; i < s->num_cpu; i++) {
+ if (!qemu_get_cpu(i)) {
+ continue;
+ }
+
GICv3CPUState *ocs = &s->cpu[i];
if (irm) {
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index f8d7be5479..8eea7c9dd9 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -341,6 +341,10 @@ static void kvm_arm_gicv3_put(GICv3State *s)
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
GICv3CPUState *c = &s->cpu[ncpu];
+ if (!qemu_get_cpu(ncpu)) {
+ continue;
+ }
+
reg64 = c->gicr_propbaser;
regl = (uint32_t)reg64;
kvm_gicr_access(s, GICR_PROPBASER, ncpu, &regl, true);
@@ -366,6 +370,10 @@ static void kvm_arm_gicv3_put(GICv3State *s)
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
GICv3CPUState *c = &s->cpu[ncpu];
+ if (!qemu_get_cpu(ncpu)) {
+ continue;
+ }
+
reg = c->gicr_ctlr;
kvm_gicr_access(s, GICR_CTLR, ncpu, &reg, true);
@@ -462,6 +470,10 @@ static void kvm_arm_gicv3_put(GICv3State *s)
GICv3CPUState *c = &s->cpu[ncpu];
int num_pri_bits;
+ if (!qemu_get_cpu(ncpu)) {
+ continue;
+ }
+
kvm_gicc_access(s, ICC_SRE_EL1, ncpu, &c->icc_sre_el1, true);
kvm_gicc_access(s, ICC_CTLR_EL1, ncpu,
&c->icc_ctlr_el1[GICV3_NS], true);
@@ -525,6 +537,10 @@ static void kvm_arm_gicv3_get(GICv3State *s)
/* Redistributor state (one per CPU) */
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
+ if (!qemu_get_cpu(ncpu)) {
+ continue;
+ }
+
GICv3CPUState *c = &s->cpu[ncpu];
kvm_gicr_access(s, GICR_CTLR, ncpu, &reg, false);
@@ -560,6 +576,10 @@ static void kvm_arm_gicv3_get(GICv3State *s)
if (redist_typer & GICR_TYPER_PLPIS) {
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
+ if (!qemu_get_cpu(ncpu)) {
+ continue;
+ }
+
GICv3CPUState *c = &s->cpu[ncpu];
kvm_gicr_access(s, GICR_PROPBASER, ncpu, &regl, false);
@@ -613,6 +633,10 @@ static void kvm_arm_gicv3_get(GICv3State *s)
*/
for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
+ if (!qemu_get_cpu(ncpu)) {
+ continue;
+ }
+
GICv3CPUState *c = &s->cpu[ncpu];
int num_pri_bits;
@@ -806,7 +830,9 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
}
for (i = 0; i < s->num_cpu; i++) {
- kvm_arm_gicv3_cpu_realize(s, i);
+ if (qemu_get_cpu(i)) {
+ kvm_arm_gicv3_cpu_realize(s, i);
+ }
}
/* Try to create the device via the device control API */
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 6880ebe07c..beef4c8002 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -168,8 +168,9 @@ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
assert(vms->gic_version == 3);
+ GICv3State *s = ARM_GICV3_COMMON(vms->gic);
- return vms->smp_cpus > redist0_capacity ? 2 : 1;
+ return s->num_cpu > redist0_capacity ? 2 : 1;
}
#endif /* QEMU_ARM_VIRT_H */
--
2.19.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zhouli57/src-qemu.git
git@gitee.com:zhouli57/src-qemu.git
zhouli57
src-qemu
src-qemu
master

搜索帮助