[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 06/13] kvm: let kvm use AccelState.global_props
From: |
Peter Xu |
Subject: |
[Qemu-devel] [PATCH v3 06/13] kvm: let kvm use AccelState.global_props |
Date: |
Mon, 19 Jun 2017 20:49:41 +0800 |
Let KVM be the first user of the new AccelState.global_props field.
Basically kvm accel only contains accel props for TYPE_X86_CPUs but not
anything else yet.
There will be a change on how these global properties are applied for
TYPE_X86_CPU devices. The general workflow of the global property stuff
for TYPE_X86_CPU devices can be simplied as following (this is a example
routine of KVM that contains both old/new workflow, similar thing apply
to TCG, but even simpler):
- HW_COMPAT/type_init() magic played before even entering main() [1]
- main() in vl.c
- configure_accelerator()
- AccelClass.init_machine() [2]
- kvm_init() (for KVM accel)
- register global properties
- accel_register_compat_props(): register accel compat props [3]
- machine_register_compat_props(): register machine compat
props (here we'll apply all the HW_COMPAT magic into
global_props) [4]
- machine init()
- cpu init() [5]
- ...
Before this patch, the code setup TYPE_X86_CPU properties at [4] by
keeping the kvm_default_props list and apply them directly to the device
using x86_cpu_apply_props().
After this patch, the code setup the same properties in the sequence of
[1]->[2]->[3][4]->[5]:
- At [1] we setup machine global properties. Note: there will be
properties that with value==NULL but it's okay - when it was applied
to global list, it'll be used to remove an entry at step [4], it
works just like the old kvm_default_props, but we just unified it to
a single place, which is the global_props list.
- At [2] we setup accel global properties.
- At [3]/[4] we move machine/accel properties into global property
list. One thing to mention is that, we do [3] before [4], since we
have some cross-relation properties, e.g., property that is required
when both PC=2.1 && ACCEL=kvm happen. For now, all this kind of
properties are still in machine compat properties.
- At [5] when TYPE_X86_CPU creates, it applies the global property from
the global property list, which is now a merged list of three: accel
property list, machine property list, and user specified "-global"
properties.
So it's getting more complex in workflow, but better modulized.
After the refactoring, x86_cpu_change_kvm_default() is moved directly to
pc_piix.c since that'll be the only place to use it, also it is
rewritten to use the global property APIs.
One defect is that we hard coded TYPE_X86_CPU (both of its definitions,
for 32/64 bits) in accel_register_x86_cpu_props(). Comment explains
itself.
Signed-off-by: Peter Xu <address@hidden>
---
accel.c | 22 ++++++++++++++++++++++
hw/i386/pc_piix.c | 8 ++++++++
include/sysemu/accel.h | 9 +++++++++
kvm-all.c | 30 ++++++++++++++++++++++++++++++
target/i386/cpu.c | 42 +-----------------------------------------
target/i386/cpu.h | 11 -----------
vl.c | 5 +++++
7 files changed, 75 insertions(+), 52 deletions(-)
diff --git a/accel.c b/accel.c
index f747d65..ca1d0f5 100644
--- a/accel.c
+++ b/accel.c
@@ -130,6 +130,28 @@ void configure_accelerator(MachineState *ms)
}
}
+void accel_register_prop(AccelState *accel, const char *driver,
+ const char *prop, const char *value)
+{
+ accel->global_props = global_prop_list_add(accel->global_props,
+ driver, prop,
+ value, false);
+}
+
+void accel_register_x86_cpu_props(AccelState *accel, const char *prop,
+ const char *value)
+{
+ /*
+ * We hard-coded this for x86 cpus, trying to match TYPE_X86_CPU.
+ * We cannot just use TYPE_X86_CPU since that's target-dependent
+ * while accel.c is target-independent. For x86 platform, only one
+ * of below two lines will be used, but it does not hurt to
+ * register both. On non-x86 platforms, none of them are used.
+ */
+ accel_register_prop(accel, "i386-cpu", prop, value);
+ accel_register_prop(accel, "x86_64-cpu", prop, value);
+}
+
static void accel_prop_pass_to_global(gpointer data, gpointer user_data)
{
GlobalProperty *prop = data;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 46a2bc4..d1d8979 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -304,6 +304,14 @@ static void pc_init1(MachineState *machine,
}
}
+static void x86_cpu_change_kvm_default(const char *prop,
+ const char *value)
+{
+ if (kvm_enabled()) {
+ register_compat_prop(TYPE_X86_CPU, prop, value, false);
+ }
+}
+
/* Looking for a pc_compat_2_4() function? It doesn't exist.
* pc_compat_*() functions that run on machine-init time and
* change global QEMU state are deprecated. Please don't create
diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
index 83bb60e..ee2fbad 100644
--- a/include/sysemu/accel.h
+++ b/include/sysemu/accel.h
@@ -65,8 +65,17 @@ typedef struct AccelClass {
extern int tcg_tb_size;
+typedef struct AccelPropValue {
+ const char *prop, *value;
+} AccelPropValue;
+
void configure_accelerator(MachineState *ms);
/* Register accelerator specific global properties */
void accel_register_compat_props(AccelState *accel);
+/* Register single global property to the AccessState property list */
+void accel_register_prop(AccelState *accel, const char *driver,
+ const char *prop, const char *value);
+void accel_register_x86_cpu_props(AccelState *accel, const char *prop,
+ const char *value);
#endif
diff --git a/kvm-all.c b/kvm-all.c
index ab8262f..ef60ddf 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1564,6 +1564,34 @@ bool kvm_vcpu_id_is_valid(int vcpu_id)
return vcpu_id >= 0 && vcpu_id < kvm_max_vcpu_id(s);
}
+static AccelPropValue x86_kvm_default_props[] = {
+ { "kvmclock", "on" },
+ { "kvm-nopiodelay", "on" },
+ { "kvm-asyncpf", "on" },
+ { "kvm-steal-time", "on" },
+ { "kvm-pv-eoi", "on" },
+ { "kvmclock-stable-bit", "on" },
+ { "x2apic", "on" },
+ { "acpi", "off" },
+ { "monitor", "off" },
+ { "svm", "off" },
+ { NULL, NULL },
+};
+
+static void kvm_register_accel_props(KVMState *kvm)
+{
+ AccelState *accel = ACCEL(kvm);
+ AccelPropValue *entry;
+
+ for (entry = x86_kvm_default_props; entry->prop; entry++) {
+ accel_register_x86_cpu_props(accel, entry->prop, entry->value);
+ }
+
+ if (!kvm_irqchip_in_kernel()) {
+ accel_register_x86_cpu_props(accel, "x2apic", "off");
+ }
+}
+
static int kvm_init(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -1776,6 +1804,8 @@ static int kvm_init(MachineState *ms)
cpu_interrupt_handler = kvm_handle_interrupt;
+ kvm_register_accel_props(s);
+
return 0;
err:
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 1bd20e2..5214fba 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1484,23 +1484,6 @@ typedef struct PropValue {
const char *prop, *value;
} PropValue;
-/* KVM-specific features that are automatically added/removed
- * from all CPU models when KVM is enabled.
- */
-static PropValue kvm_default_props[] = {
- { "kvmclock", "on" },
- { "kvm-nopiodelay", "on" },
- { "kvm-asyncpf", "on" },
- { "kvm-steal-time", "on" },
- { "kvm-pv-eoi", "on" },
- { "kvmclock-stable-bit", "on" },
- { "x2apic", "on" },
- { "acpi", "off" },
- { "monitor", "off" },
- { "svm", "off" },
- { NULL, NULL },
-};
-
/* TCG-specific defaults that override all CPU models when using TCG
*/
static PropValue tcg_default_props[] = {
@@ -1508,23 +1491,6 @@ static PropValue tcg_default_props[] = {
{ NULL, NULL },
};
-
-void x86_cpu_change_kvm_default(const char *prop, const char *value)
-{
- PropValue *pv;
- for (pv = kvm_default_props; pv->prop; pv++) {
- if (!strcmp(pv->prop, prop)) {
- pv->value = value;
- break;
- }
- }
-
- /* It is valid to call this function only for properties that
- * are already present in the kvm_default_props table.
- */
- assert(pv->prop);
-}
-
static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
bool migratable_only);
@@ -2335,13 +2301,7 @@ static void x86_cpu_load_def(X86CPU *cpu,
X86CPUDefinition *def, Error **errp)
}
/* Special cases not set in the X86CPUDefinition structs: */
- if (kvm_enabled()) {
- if (!kvm_irqchip_in_kernel()) {
- x86_cpu_change_kvm_default("x2apic", "off");
- }
-
- x86_cpu_apply_props(cpu, kvm_default_props);
- } else if (tcg_enabled()) {
+ if (tcg_enabled()) {
x86_cpu_apply_props(cpu, tcg_default_props);
}
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index de0551f..93aebfb 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1669,17 +1669,6 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess
access);
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
TPRAccess access);
-
-/* Change the value of a KVM-specific default
- *
- * If value is NULL, no default will be set and the original
- * value from the CPU model table will be kept.
- *
- * It is valid to call this function only for properties that
- * are already present in the kvm_default_props table.
- */
-void x86_cpu_change_kvm_default(const char *prop, const char *value);
-
/* mpx_helper.c */
void cpu_sync_bndcs_hflags(CPUX86State *env);
diff --git a/vl.c b/vl.c
index d3f5594..a564139 100644
--- a/vl.c
+++ b/vl.c
@@ -4553,6 +4553,11 @@ int main(int argc, char **argv, char **envp)
exit (i == 1 ? 1 : 0);
}
+ /*
+ * Here we need to first register accelerator compat properties
+ * then machine properties, since cross-relationed properties are
+ * setup in machine compat bits.
+ */
accel_register_compat_props(current_machine->accelerator);
machine_register_compat_props(current_machine);
--
2.7.4
[Qemu-devel] [PATCH v3 07/13] tcg: use AccelState.global_props, Peter Xu, 2017/06/19
[Qemu-devel] [PATCH v3 08/13] trace: add qdev_global_prop_apply, Peter Xu, 2017/06/19
[Qemu-devel] [PATCH v3 09/13] migration: let MigrationState be a qdev, Peter Xu, 2017/06/19
[Qemu-devel] [PATCH v3 10/13] migration: move global_state.optional out, Peter Xu, 2017/06/19