diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 50e8317342..2c6194e57f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -97,7 +97,9 @@ #include "trace.h" #include CONFIG_DEVICES -GlobalProperty pc_compat_5_1[] = {}; +GlobalProperty pc_compat_5_1[] = { + { "ICH9-LPC", "x-smi-cpu-hotplug", "off" }, +}; const size_t pc_compat_5_1_len = G_N_ELEMENTS(pc_compat_5_1); GlobalProperty pc_compat_5_0[] = { diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 3303d2eab6..a54b3ec8bd 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -373,6 +373,15 @@ static void smi_features_ok_callback(void *opaque) /* guest requests invalid features, leave @features_ok at zero */ return; } + if (!(guest_features & BIT_ULL(ICH9_LPC_SMI_F_BROADCAST_BIT)) && + guest_features & (BIT_ULL(ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT) | + BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT))) { + /* + * cpu hot-[un]plug with SMI requires SMI broadcast, + * leave @features_ok at zero + */ + return; + } /* valid feature subset requested, lock it down, report success */ lpc->smi_negotiated_features = guest_features; @@ -747,6 +756,10 @@ static Property ich9_lpc_properties[] = { DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, true), DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features, ICH9_LPC_SMI_F_BROADCAST_BIT, true), + DEFINE_PROP_BIT64("x-smi-cpu-hotplug", ICH9LPCState, smi_host_features, + ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT, true), + DEFINE_PROP_BIT64("x-smi-cpu-hotunplug", ICH9LPCState, smi_host_features, + ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index 48b442bc0b..703d56036a 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -247,5 +247,7 @@ struct ICH9LPCState { /* bit positions used in fw_cfg SMI feature negotiation */ #define ICH9_LPC_SMI_F_BROADCAST_BIT 0 +#define ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT 1 +#define ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT 2 #endif /* HW_ICH9_H */