target-arm queue:
* translate-a64.c: silence gcc5 warning * highbank: validate register offset before access * MAINTAINERS: Add entries for Smartfusion2 * accel/tcg/translate-all: expand cpu_restore_state addr check (so usermode insn aborts don't crash with an assertion failure) * fix TCG initialization of some Arm boards by allowing them to specify min/default number of CPUs to create -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJaCaf9AAoJEDwlJe0UNgzeCvAP+wW30EnJ7QChmsk1QvYRlTSO fLOrsJj4xaBlH9ZQmTyanH1xwK4aT8Y/UDLW+AM3cM5u/2bnzoL0bgccgImqzzGt 4e0nPSWYmQ1OBSf9+sJulIPxjBCgzHKTxd4JxhO12a4yTaJFrBDhhCKhpK0yEp3H qd1uhWVeMnmub1EEBjPAUpDVWRngcRbkYk3QTU/RvC8WvOhpCFZJmELovog6R/0g r2gkY2aEp5mdnQv4knaRwpSepVedFmT9yBhF5X54bxIhx/iPWQFdlhe2wkzdSdpN I6/j3BTbg1hNB1/MDClgBp1/ZOd0Aajs2zeRvelA31te8UjEbU3cUW9EgUBd+BL7 wWxAl+RN7Ma9g8AG7Ip354kZPg3XrRAFOZbJwi0b3amO8NOQAC64f7bxAYZekU0a vHxC09r+u0kF+TYiZUC489S1W/PD+yiVyMrNg92Lw0SIHp0ZhDa+VuU25HYKrLle 0xYG1a4DV5R10x95ftsil/rTOIwh2tsUbvGooErXiqF950C1qLZEmfZMMnG2G//2 J5yVVIHL1J4R7edit/v1bcTfVrZJpJFSNsQS7Grf+psWXetSTrDOAhFzMqkpVZEe EfrljrlxCEjyAVEgWvbkLbSjQ+hGNa6Yfwktjo9wgcwTrEtDOsBXRnoC/m0SfXm5 MkrINCOUGX2/Iqa/dP+O =LC1U -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20171113' into staging target-arm queue: * translate-a64.c: silence gcc5 warning * highbank: validate register offset before access * MAINTAINERS: Add entries for Smartfusion2 * accel/tcg/translate-all: expand cpu_restore_state addr check (so usermode insn aborts don't crash with an assertion failure) * fix TCG initialization of some Arm boards by allowing them to specify min/default number of CPUs to create # gpg: Signature made Mon 13 Nov 2017 14:11:09 GMT # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20171113: accel/tcg/translate-all: expand cpu_restore_state addr check hw: add .min_cpus and .default_cpus fields to machine_class xlnx-zcu102: Specify the max number of CPUs for the EP108 xlnx-zcu102: Add an info message deprecating the EP108 xlnx-zynqmp: Properly support the smp command line option qom: move CPUClass.tcg_initialize to a global MAINTAINERS: Add entries for Smartfusion2 highbank: validate register offset before access arm/translate-a64: mark path as unreachable to eliminate warning Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
55ed8d600a
17
MAINTAINERS
17
MAINTAINERS
|
@ -564,6 +564,23 @@ M: Alistair Francis <alistair@alistair23.me>
|
|||
S: Maintained
|
||||
F: hw/arm/netduino2.c
|
||||
|
||||
SmartFusion2
|
||||
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
|
||||
S: Maintained
|
||||
F: hw/arm/msf2-soc.c
|
||||
F: hw/misc/msf2-sysreg.c
|
||||
F: hw/timer/mss-timer.c
|
||||
F: hw/ssi/mss-spi.c
|
||||
F: include/hw/arm/msf2-soc.h
|
||||
F: include/hw/misc/msf2-sysreg.h
|
||||
F: include/hw/timer/mss-timer.h
|
||||
F: include/hw/ssi/mss-spi.h
|
||||
|
||||
Emcraft M2S-FG484
|
||||
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
|
||||
S: Maintained
|
||||
F: hw/arm/msf2-som.c
|
||||
|
||||
CRIS Machines
|
||||
-------------
|
||||
Axis Dev88
|
||||
|
|
|
@ -352,36 +352,42 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
|
||||
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
bool r = false;
|
||||
uintptr_t check_offset;
|
||||
|
||||
/* A retaddr of zero is invalid so we really shouldn't have ended
|
||||
* up here. The target code has likely forgotten to check retaddr
|
||||
* != 0 before attempting to restore state. We return early to
|
||||
* avoid blowing up on a recursive tb_lock(). The target must have
|
||||
* previously survived a failed cpu_restore_state because
|
||||
* tb_find_pc(0) would have failed anyway. It still should be
|
||||
* fixed though.
|
||||
/* The host_pc has to be in the region of current code buffer. If
|
||||
* it is not we will not be able to resolve it here. The two cases
|
||||
* where host_pc will not be correct are:
|
||||
*
|
||||
* - fault during translation (instruction fetch)
|
||||
* - fault from helper (not using GETPC() macro)
|
||||
*
|
||||
* Either way we need return early to avoid blowing up on a
|
||||
* recursive tb_lock() as we can't resolve it here.
|
||||
*
|
||||
* We are using unsigned arithmetic so if host_pc <
|
||||
* tcg_init_ctx.code_gen_buffer check_offset will wrap to way
|
||||
* above the code_gen_buffer_size
|
||||
*/
|
||||
check_offset = host_pc - (uintptr_t) tcg_init_ctx.code_gen_buffer;
|
||||
|
||||
if (!retaddr) {
|
||||
return r;
|
||||
}
|
||||
|
||||
tb_lock();
|
||||
tb = tb_find_pc(retaddr);
|
||||
if (tb) {
|
||||
cpu_restore_state_from_tb(cpu, tb, retaddr);
|
||||
if (tb->cflags & CF_NOCACHE) {
|
||||
/* one-shot translation, invalidate it immediately */
|
||||
tb_phys_invalidate(tb, -1);
|
||||
tb_remove(tb);
|
||||
if (check_offset < tcg_init_ctx.code_gen_buffer_size) {
|
||||
tb_lock();
|
||||
tb = tb_find_pc(host_pc);
|
||||
if (tb) {
|
||||
cpu_restore_state_from_tb(cpu, tb, host_pc);
|
||||
if (tb->cflags & CF_NOCACHE) {
|
||||
/* one-shot translation, invalidate it immediately */
|
||||
tb_phys_invalidate(tb, -1);
|
||||
tb_remove(tb);
|
||||
}
|
||||
r = true;
|
||||
}
|
||||
r = true;
|
||||
tb_unlock();
|
||||
}
|
||||
tb_unlock();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
5
exec.c
5
exec.c
|
@ -792,11 +792,12 @@ void cpu_exec_initfn(CPUState *cpu)
|
|||
void cpu_exec_realizefn(CPUState *cpu, Error **errp)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
static bool tcg_target_initialized;
|
||||
|
||||
cpu_list_add(cpu);
|
||||
|
||||
if (tcg_enabled() && !cc->tcg_initialized) {
|
||||
cc->tcg_initialized = true;
|
||||
if (tcg_enabled() && !tcg_target_initialized) {
|
||||
tcg_target_initialized = true;
|
||||
cc->tcg_initialize();
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "net/net.h"
|
||||
#include "hw/arm/arm.h"
|
||||
|
@ -129,13 +128,6 @@ exynos4_boards_init_common(MachineState *machine,
|
|||
Exynos4BoardType board_type)
|
||||
{
|
||||
Exynos4BoardState *s = g_new(Exynos4BoardState, 1);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
|
||||
if (smp_cpus != EXYNOS4210_NCPUS && !qtest_enabled()) {
|
||||
error_report("%s board supports only %d CPU cores, ignoring smp_cpus"
|
||||
" value",
|
||||
mc->name, EXYNOS4210_NCPUS);
|
||||
}
|
||||
|
||||
exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
|
||||
exynos4_board_binfo.board_id = exynos4_board_id[board_type];
|
||||
|
@ -189,6 +181,8 @@ static void nuri_class_init(ObjectClass *oc, void *data)
|
|||
mc->desc = "Samsung NURI board (Exynos4210)";
|
||||
mc->init = nuri_init;
|
||||
mc->max_cpus = EXYNOS4210_NCPUS;
|
||||
mc->min_cpus = EXYNOS4210_NCPUS;
|
||||
mc->default_cpus = EXYNOS4210_NCPUS;
|
||||
mc->ignore_memory_transaction_failures = true;
|
||||
}
|
||||
|
||||
|
@ -205,6 +199,8 @@ static void smdkc210_class_init(ObjectClass *oc, void *data)
|
|||
mc->desc = "Samsung SMDKC210 board (Exynos4210)";
|
||||
mc->init = smdkc210_init;
|
||||
mc->max_cpus = EXYNOS4210_NCPUS;
|
||||
mc->min_cpus = EXYNOS4210_NCPUS;
|
||||
mc->default_cpus = EXYNOS4210_NCPUS;
|
||||
mc->ignore_memory_transaction_failures = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "hw/ide/ahci.h"
|
||||
#include "hw/cpu/a9mpcore.h"
|
||||
#include "hw/cpu/a15mpcore.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
#define SMP_BOOT_ADDR 0x100
|
||||
#define SMP_BOOT_REG 0x40
|
||||
|
@ -117,14 +118,26 @@ static void hb_regs_write(void *opaque, hwaddr offset,
|
|||
}
|
||||
}
|
||||
|
||||
regs[offset/4] = value;
|
||||
if (offset / 4 >= NUM_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"highbank: bad write offset 0x%" HWADDR_PRIx "\n", offset);
|
||||
return;
|
||||
}
|
||||
regs[offset / 4] = value;
|
||||
}
|
||||
|
||||
static uint64_t hb_regs_read(void *opaque, hwaddr offset,
|
||||
unsigned size)
|
||||
{
|
||||
uint32_t value;
|
||||
uint32_t *regs = opaque;
|
||||
uint32_t value = regs[offset/4];
|
||||
|
||||
if (offset / 4 >= NUM_REGS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"highbank: bad read offset 0x%" HWADDR_PRIx "\n", offset);
|
||||
return 0;
|
||||
}
|
||||
value = regs[offset / 4];
|
||||
|
||||
if ((offset == 0x100) || (offset == 0x108) || (offset == 0x10C)) {
|
||||
value |= 0x30000000;
|
||||
|
|
|
@ -167,6 +167,8 @@ static void raspi2_machine_init(MachineClass *mc)
|
|||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->max_cpus = BCM2836_NCPUS;
|
||||
mc->min_cpus = BCM2836_NCPUS;
|
||||
mc->default_cpus = BCM2836_NCPUS;
|
||||
mc->default_ram_size = 1024 * 1024 * 1024;
|
||||
mc->ignore_memory_transaction_failures = true;
|
||||
};
|
||||
|
|
|
@ -164,6 +164,9 @@ static void xlnx_ep108_init(MachineState *machine)
|
|||
{
|
||||
XlnxZCU102 *s = EP108_MACHINE(machine);
|
||||
|
||||
info_report("The Xilinx EP108 machine is deprecated, please use the "
|
||||
"ZCU102 machine instead. It has the same features supported.");
|
||||
|
||||
xlnx_zynqmp_init(s, machine);
|
||||
}
|
||||
|
||||
|
@ -185,6 +188,8 @@ static void xlnx_ep108_machine_class_init(ObjectClass *oc, void *data)
|
|||
mc->block_default_type = IF_IDE;
|
||||
mc->units_per_default_bus = 1;
|
||||
mc->ignore_memory_transaction_failures = true;
|
||||
mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
|
||||
mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
|
||||
}
|
||||
|
||||
static const TypeInfo xlnx_ep108_machine_init_typeinfo = {
|
||||
|
@ -235,12 +240,14 @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
|
|||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
mc->desc = "Xilinx ZynqMP ZCU102 board";
|
||||
mc->desc = "Xilinx ZynqMP ZCU102 board with 4xA53s and 2xR5s based on " \
|
||||
"the value of smp";
|
||||
mc->init = xlnx_zcu102_init;
|
||||
mc->block_default_type = IF_IDE;
|
||||
mc->units_per_default_bus = 1;
|
||||
mc->ignore_memory_transaction_failures = true;
|
||||
mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS;
|
||||
mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
|
||||
}
|
||||
|
||||
static const TypeInfo xlnx_zcu102_machine_init_typeinfo = {
|
||||
|
|
|
@ -98,8 +98,9 @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
|
|||
{
|
||||
Error *err = NULL;
|
||||
int i;
|
||||
int num_rpus = MIN(smp_cpus - XLNX_ZYNQMP_NUM_APU_CPUS, XLNX_ZYNQMP_NUM_RPU_CPUS);
|
||||
|
||||
for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
|
||||
for (i = 0; i < num_rpus; i++) {
|
||||
char *name;
|
||||
|
||||
object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
|
||||
|
@ -132,8 +133,9 @@ static void xlnx_zynqmp_init(Object *obj)
|
|||
{
|
||||
XlnxZynqMPState *s = XLNX_ZYNQMP(obj);
|
||||
int i;
|
||||
int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
|
||||
|
||||
for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
|
||||
for (i = 0; i < num_apus; i++) {
|
||||
object_initialize(&s->apu_cpu[i], sizeof(s->apu_cpu[i]),
|
||||
"cortex-a53-" TYPE_ARM_CPU);
|
||||
object_property_add_child(obj, "apu-cpu[*]", OBJECT(&s->apu_cpu[i]),
|
||||
|
@ -182,6 +184,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
|||
MemoryRegion *system_memory = get_system_memory();
|
||||
uint8_t i;
|
||||
uint64_t ram_size;
|
||||
int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
|
||||
const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]";
|
||||
ram_addr_t ddr_low_size, ddr_high_size;
|
||||
qemu_irq gic_spi[GIC_NUM_SPI_INTR];
|
||||
|
@ -233,10 +236,10 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32);
|
||||
qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
|
||||
qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_APU_CPUS);
|
||||
qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", num_apus);
|
||||
|
||||
/* Realize APUs before realizing the GIC. KVM requires this. */
|
||||
for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
|
||||
for (i = 0; i < num_apus; i++) {
|
||||
char *name;
|
||||
|
||||
object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC,
|
||||
|
@ -292,7 +295,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
|
||||
for (i = 0; i < num_apus; i++) {
|
||||
qemu_irq irq;
|
||||
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
|
||||
|
@ -307,11 +310,14 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
|
||||
if (s->has_rpu) {
|
||||
xlnx_zynqmp_create_rpu(s, boot_cpu, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
info_report("The 'has_rpu' property is no longer required, to use the "
|
||||
"RPUs just use -smp 6.");
|
||||
}
|
||||
|
||||
xlnx_zynqmp_create_rpu(s, boot_cpu, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!s->boot_cpu_ptr) {
|
||||
|
|
|
@ -45,6 +45,17 @@ void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
|
|||
target_ulong *data);
|
||||
|
||||
void cpu_gen_init(void);
|
||||
|
||||
/**
|
||||
* cpu_restore_state:
|
||||
* @cpu: the vCPU state is to be restore to
|
||||
* @searched_pc: the host PC the fault occurred at
|
||||
* @return: true if state was restored, false otherwise
|
||||
*
|
||||
* Attempt to restore the state for a fault occurring in translated
|
||||
* code. If the searched_pc is not in translated code no state is
|
||||
* restored and the function returns false.
|
||||
*/
|
||||
bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
|
||||
|
||||
void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu);
|
||||
|
|
|
@ -102,6 +102,9 @@ typedef struct {
|
|||
|
||||
/**
|
||||
* MachineClass:
|
||||
* @max_cpus: maximum number of CPUs supported. Default: 1
|
||||
* @min_cpus: minimum number of CPUs supported. Default: 1
|
||||
* @default_cpus: number of CPUs instantiated if none are specified. Default: 1
|
||||
* @get_hotplug_handler: this function is called during bus-less
|
||||
* device hotplug. If defined it returns pointer to an instance
|
||||
* of HotplugHandler object, which handles hotplug operation
|
||||
|
@ -167,6 +170,8 @@ struct MachineClass {
|
|||
BlockInterfaceType block_default_type;
|
||||
int units_per_default_bus;
|
||||
int max_cpus;
|
||||
int min_cpus;
|
||||
int default_cpus;
|
||||
unsigned int no_serial:1,
|
||||
no_parallel:1,
|
||||
use_virtcon:1,
|
||||
|
|
|
@ -209,7 +209,6 @@ typedef struct CPUClass {
|
|||
/* Keep non-pointer data at the end to minimize holes. */
|
||||
int gdb_num_core_regs;
|
||||
bool gdb_stop_before_watchpoint;
|
||||
bool tcg_initialized;
|
||||
} CPUClass;
|
||||
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
|
|
|
@ -2537,6 +2537,13 @@ or ``ivshmem-doorbell`` device types.
|
|||
The ``spapr-pci-vfio-host-bridge'' device type is replaced by
|
||||
the ``spapr-pci-host-bridge'' device type.
|
||||
|
||||
@section System emulator machines
|
||||
|
||||
@subsection Xilinx EP108 (since 2.11.0)
|
||||
|
||||
The ``xlnx-ep108'' machine has been replaced by the ``xlnx-zcu102'' machine.
|
||||
The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU.
|
||||
|
||||
@node License
|
||||
@appendix License
|
||||
|
||||
|
|
|
@ -2351,6 +2351,8 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
|
|||
post_index = false;
|
||||
writeback = true;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if (rn == 31) {
|
||||
|
|
21
vl.c
21
vl.c
|
@ -160,8 +160,8 @@ Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES];
|
|||
Chardev *sclp_hds[MAX_SCLP_CONSOLES];
|
||||
int win2k_install_hack = 0;
|
||||
int singlestep = 0;
|
||||
int smp_cpus = 1;
|
||||
unsigned int max_cpus = 1;
|
||||
int smp_cpus;
|
||||
unsigned int max_cpus;
|
||||
int smp_cores = 1;
|
||||
int smp_threads = 1;
|
||||
int acpi_enabled = 1;
|
||||
|
@ -4327,9 +4327,24 @@ int main(int argc, char **argv, char **envp)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
/* machine_class: default to UP */
|
||||
machine_class->max_cpus = machine_class->max_cpus ?: 1;
|
||||
machine_class->min_cpus = machine_class->min_cpus ?: 1;
|
||||
machine_class->default_cpus = machine_class->default_cpus ?: 1;
|
||||
|
||||
/* default to machine_class->default_cpus */
|
||||
smp_cpus = machine_class->default_cpus;
|
||||
max_cpus = machine_class->default_cpus;
|
||||
|
||||
smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
|
||||
|
||||
machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
|
||||
/* sanity-check smp_cpus and max_cpus against machine_class */
|
||||
if (smp_cpus < machine_class->min_cpus) {
|
||||
error_report("Invalid SMP CPUs %d. The min CPUs "
|
||||
"supported by machine '%s' is %d", smp_cpus,
|
||||
machine_class->name, machine_class->min_cpus);
|
||||
exit(1);
|
||||
}
|
||||
if (max_cpus > machine_class->max_cpus) {
|
||||
error_report("Invalid SMP CPUs %d. The max CPUs "
|
||||
"supported by machine '%s' is %d", max_cpus,
|
||||
|
|
Loading…
Reference in a new issue