提交 95eb49c8 编写于 作者: A Andrew Jones 提交者: Peter Maydell

hw/arm/virt: tcg: adjust MPIDR like KVM

KVM adjusts the MPIDR of guest vcpus based on the architecture of
the host, 32-bit vs. 64-bit, and, for 64-bit, also on the type of
GIC the guest is using. To be consistent and improve SGI efficiency
we make the same adjustments for TCG as 64-bit KVM hosts. We neglect
to add consistency with 32-bit KVM hosts, as that would reduce SGI
efficiency and KVM is expected to change.

As MPIDR is a system register, and thus guest visible, we only make
adjustments for current and later versioned machines.
Signed-off-by: NAndrew Jones <drjones@redhat.com>
Message-id: 1467378129-23302-3-git-send-email-drjones@redhat.com
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 c8efd802
...@@ -52,7 +52,8 @@ ...@@ -52,7 +52,8 @@
#include "hw/arm/sysbus-fdt.h" #include "hw/arm/sysbus-fdt.h"
#include "hw/platform-bus.h" #include "hw/platform-bus.h"
#include "hw/arm/fdt.h" #include "hw/arm/fdt.h"
#include "hw/intc/arm_gic_common.h" #include "hw/intc/arm_gic.h"
#include "hw/intc/arm_gicv3_common.h"
#include "kvm_arm.h" #include "kvm_arm.h"
#include "hw/smbios/smbios.h" #include "hw/smbios/smbios.h"
#include "qapi/visitor.h" #include "qapi/visitor.h"
...@@ -82,6 +83,7 @@ typedef struct VirtBoardInfo { ...@@ -82,6 +83,7 @@ typedef struct VirtBoardInfo {
typedef struct { typedef struct {
MachineClass parent; MachineClass parent;
VirtBoardInfo *daughterboard; VirtBoardInfo *daughterboard;
bool disallow_affinity_adjustment;
} VirtMachineClass; } VirtMachineClass;
typedef struct { typedef struct {
...@@ -1165,6 +1167,7 @@ void virt_guest_info_machine_done(Notifier *notifier, void *data) ...@@ -1165,6 +1167,7 @@ void virt_guest_info_machine_done(Notifier *notifier, void *data)
static void machvirt_init(MachineState *machine) static void machvirt_init(MachineState *machine)
{ {
VirtMachineState *vms = VIRT_MACHINE(machine); VirtMachineState *vms = VIRT_MACHINE(machine);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
qemu_irq pic[NUM_IRQS]; qemu_irq pic[NUM_IRQS];
MemoryRegion *sysmem = get_system_memory(); MemoryRegion *sysmem = get_system_memory();
MemoryRegion *secure_sysmem = NULL; MemoryRegion *secure_sysmem = NULL;
...@@ -1181,6 +1184,7 @@ static void machvirt_init(MachineState *machine) ...@@ -1181,6 +1184,7 @@ static void machvirt_init(MachineState *machine)
CPUClass *cc; CPUClass *cc;
Error *err = NULL; Error *err = NULL;
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0); bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
uint8_t clustersz;
if (!cpu_model) { if (!cpu_model) {
cpu_model = "cortex-a15"; cpu_model = "cortex-a15";
...@@ -1226,8 +1230,10 @@ static void machvirt_init(MachineState *machine) ...@@ -1226,8 +1230,10 @@ static void machvirt_init(MachineState *machine)
*/ */
if (gic_version == 3) { if (gic_version == 3) {
virt_max_cpus = vbi->memmap[VIRT_GIC_REDIST].size / 0x20000; virt_max_cpus = vbi->memmap[VIRT_GIC_REDIST].size / 0x20000;
clustersz = GICV3_TARGETLIST_BITS;
} else { } else {
virt_max_cpus = GIC_NCPU; virt_max_cpus = GIC_NCPU;
clustersz = GIC_TARGETLIST_BITS;
} }
if (max_cpus > virt_max_cpus) { if (max_cpus > virt_max_cpus) {
...@@ -1281,6 +1287,20 @@ static void machvirt_init(MachineState *machine) ...@@ -1281,6 +1287,20 @@ static void machvirt_init(MachineState *machine)
for (n = 0; n < smp_cpus; n++) { for (n = 0; n < smp_cpus; n++) {
Object *cpuobj = object_new(typename); Object *cpuobj = object_new(typename);
if (!vmc->disallow_affinity_adjustment) {
/* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
* GIC's target-list limitations. 32-bit KVM hosts currently
* always create clusters of 4 CPUs, but that is expected to
* change when they gain support for gicv3. When KVM is enabled
* it will override the changes we make here, therefore our
* purposes are to make TCG consistent (with 64-bit KVM hosts)
* and to improve SGI efficiency.
*/
uint8_t aff1 = n / clustersz;
uint8_t aff0 = n % clustersz;
object_property_set_int(cpuobj, (aff1 << ARM_AFF1_SHIFT) | aff0,
"mp-affinity", NULL);
}
if (!vms->secure) { if (!vms->secure) {
object_property_set_bool(cpuobj, false, "has_el3", NULL); object_property_set_bool(cpuobj, false, "has_el3", NULL);
...@@ -1507,7 +1527,10 @@ static void virt_2_6_instance_init(Object *obj) ...@@ -1507,7 +1527,10 @@ static void virt_2_6_instance_init(Object *obj)
static void virt_machine_2_6_options(MachineClass *mc) static void virt_machine_2_6_options(MachineClass *mc)
{ {
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_2_7_options(mc); virt_machine_2_7_options(mc);
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6); SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6);
vmc->disallow_affinity_adjustment = true;
} }
DEFINE_VIRT_MACHINE(2, 6) DEFINE_VIRT_MACHINE(2, 6)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册