X86 queue 2015-06-02

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJVbgItAAoJECgHk2+YTcWmGhYP/RMNvcoOQzfRZ1xqztQlm2cp
 WRSnsQm2+16omGypuEGTgjr/pojlD/xRllhFMJqYPGt0ZSmwsd6AgZtU5hLnHGRb
 HJdq1js7GPsduR8/DPoBCAD6nA8wsrdjBt5WZkCf35WU4CaPFDTx1w35KdekdzVS
 0guhSypAQdrxIULvPteJw/S6u6OA42nads2xClfvmzE3kKnedeBcLLE/GzrrkIc3
 5aFjS1ndVK9rtOBldnIqq10q89c7ug60wuZi0SFqf1r4Do9cZqQgmXU7c0OiJu1G
 05F0racvGaCMNp1JyH6z5pvPVjImZfu06Wz0+433hKSHvNqh25mJ4lZVGcqfHFoB
 Ek2+iam6xej1+I2Wbt3NOBR8K0ldDMtnVpUiXMUvT2j4AUQBc2Cs79rXBgY8Qz3P
 48fI2xMlOY0TFIQTra38ZomX4Jkukhu38BRixed2/CGi1mo6N9GT5OCYBBsy2MgW
 o4yFmnzJD8eCopWXFXc93Pvdvrpn5/NJsmiNDFO66lxfQr+VfqzlG6eWpxQ7wXpR
 /JY8k21R0gHB02v7B2Kyqdj9UXmunYWS28P6LJ/z5UtCCivr/+szUTdKDOvKXt42
 HrVGgpEscs0huvsUPzJRtCYYsgKIEZB7UTxOxHiAPmBOBBnB/pLiOrkoZuQIiQee
 KxjJWNd9wMOyx90t54AI
 =VKFL
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging

X86 queue 2015-06-02

# gpg: Signature made Tue Jun  2 20:21:17 2015 BST using RSA key ID 984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/x86-pull-request:
  arch_init: Drop target-x86_64.conf
  target-i386: Register QOM properties for feature flags
  apic: convert ->busdev.qdev casts to C casts
  target-i386: Fix signedness of MSR_IA32_APICBASE_BASE
  pc: Ensure non-zero CPU ref count after attaching to ICC bus

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-06-04 11:44:32 +01:00
commit 6fa6b31276
7 changed files with 139 additions and 13 deletions

View File

@ -389,13 +389,8 @@ ifneq (,$(findstring qemu-ga,$(TOOLS)))
endif endif
endif endif
install-confdir:
$(INSTALL_DIR) "$(DESTDIR)$(qemu_confdir)"
install-sysconfig: install-datadir install-confdir install: all $(if $(BUILD_DOCS),install-doc) \
$(INSTALL_DATA) $(SRC_PATH)/sysconfigs/target/target-x86_64.conf "$(DESTDIR)$(qemu_confdir)"
install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig \
install-datadir install-localstatedir install-datadir install-localstatedir
ifneq ($(TOOLS),) ifneq ($(TOOLS),)
$(call install-prog,$(TOOLS),$(DESTDIR)$(bindir)) $(call install-prog,$(TOOLS),$(DESTDIR)$(bindir))

View File

@ -136,7 +136,6 @@ static struct defconfig_file {
bool userconfig; bool userconfig;
} default_config_files[] = { } default_config_files[] = {
{ CONFIG_QEMU_CONFDIR "/qemu.conf", true }, { CONFIG_QEMU_CONFDIR "/qemu.conf", true },
{ CONFIG_QEMU_CONFDIR "/target-" TARGET_NAME ".conf", true },
{ NULL }, /* end of list */ { NULL }, /* end of list */
}; };

View File

@ -1006,7 +1006,6 @@ static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
} }
qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
object_unref(OBJECT(cpu));
object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
@ -1025,7 +1024,9 @@ static const char *current_cpu_model;
void pc_hot_add_cpu(const int64_t id, Error **errp) void pc_hot_add_cpu(const int64_t id, Error **errp)
{ {
DeviceState *icc_bridge; DeviceState *icc_bridge;
X86CPU *cpu;
int64_t apic_id = x86_cpu_apic_id_from_index(id); int64_t apic_id = x86_cpu_apic_id_from_index(id);
Error *local_err = NULL;
if (id < 0) { if (id < 0) {
error_setg(errp, "Invalid CPU id: %" PRIi64, id); error_setg(errp, "Invalid CPU id: %" PRIi64, id);
@ -1053,7 +1054,12 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
icc_bridge = DEVICE(object_resolve_path_type("icc-bridge", icc_bridge = DEVICE(object_resolve_path_type("icc-bridge",
TYPE_ICC_BRIDGE, NULL)); TYPE_ICC_BRIDGE, NULL));
pc_new_cpu(current_cpu_model, apic_id, icc_bridge, errp); cpu = pc_new_cpu(current_cpu_model, apic_id, icc_bridge, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
object_unref(OBJECT(cpu));
} }
void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
@ -1087,6 +1093,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
error_report_err(error); error_report_err(error);
exit(1); exit(1);
} }
object_unref(OBJECT(cpu));
} }
/* map APIC MMIO area if CPU has APIC */ /* map APIC MMIO area if CPU has APIC */

View File

@ -370,13 +370,14 @@ static int apic_irq_pending(APICCommonState *s)
static void apic_update_irq(APICCommonState *s) static void apic_update_irq(APICCommonState *s)
{ {
CPUState *cpu; CPUState *cpu;
DeviceState *dev = (DeviceState *)s;
cpu = CPU(s->cpu); cpu = CPU(s->cpu);
if (!qemu_cpu_is_self(cpu)) { if (!qemu_cpu_is_self(cpu)) {
cpu_interrupt(cpu, CPU_INTERRUPT_POLL); cpu_interrupt(cpu, CPU_INTERRUPT_POLL);
} else if (apic_irq_pending(s) > 0) { } else if (apic_irq_pending(s) > 0) {
cpu_interrupt(cpu, CPU_INTERRUPT_HARD); cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
} else if (!apic_accept_pic_intr(&s->busdev.qdev) || !pic_get_output(isa_pic)) { } else if (!apic_accept_pic_intr(dev) || !pic_get_output(isa_pic)) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD); cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
} }
} }
@ -549,10 +550,12 @@ static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode,
static bool apic_check_pic(APICCommonState *s) static bool apic_check_pic(APICCommonState *s)
{ {
if (!apic_accept_pic_intr(&s->busdev.qdev) || !pic_get_output(isa_pic)) { DeviceState *dev = (DeviceState *)s;
if (!apic_accept_pic_intr(dev) || !pic_get_output(isa_pic)) {
return false; return false;
} }
apic_deliver_pic_intr(&s->busdev.qdev, 1); apic_deliver_pic_intr(dev, 1);
return true; return true;
} }

View File

@ -2841,12 +2841,126 @@ out:
} }
} }
typedef struct BitProperty {
uint32_t *ptr;
uint32_t mask;
} BitProperty;
static void x86_cpu_get_bit_prop(Object *obj,
struct Visitor *v,
void *opaque,
const char *name,
Error **errp)
{
BitProperty *fp = opaque;
bool value = (*fp->ptr & fp->mask) == fp->mask;
visit_type_bool(v, &value, name, errp);
}
static void x86_cpu_set_bit_prop(Object *obj,
struct Visitor *v,
void *opaque,
const char *name,
Error **errp)
{
DeviceState *dev = DEVICE(obj);
BitProperty *fp = opaque;
Error *local_err = NULL;
bool value;
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
return;
}
visit_type_bool(v, &value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
if (value) {
*fp->ptr |= fp->mask;
} else {
*fp->ptr &= ~fp->mask;
}
}
static void x86_cpu_release_bit_prop(Object *obj, const char *name,
void *opaque)
{
BitProperty *prop = opaque;
g_free(prop);
}
/* Register a boolean property to get/set a single bit in a uint32_t field.
*
* The same property name can be registered multiple times to make it affect
* multiple bits in the same FeatureWord. In that case, the getter will return
* true only if all bits are set.
*/
static void x86_cpu_register_bit_prop(X86CPU *cpu,
const char *prop_name,
uint32_t *field,
int bitnr)
{
BitProperty *fp;
ObjectProperty *op;
uint32_t mask = (1UL << bitnr);
op = object_property_find(OBJECT(cpu), prop_name, NULL);
if (op) {
fp = op->opaque;
assert(fp->ptr == field);
fp->mask |= mask;
} else {
fp = g_new0(BitProperty, 1);
fp->ptr = field;
fp->mask = mask;
object_property_add(OBJECT(cpu), prop_name, "bool",
x86_cpu_get_bit_prop,
x86_cpu_set_bit_prop,
x86_cpu_release_bit_prop, fp, &error_abort);
}
}
static void x86_cpu_register_feature_bit_props(X86CPU *cpu,
FeatureWord w,
int bitnr)
{
Object *obj = OBJECT(cpu);
int i;
char **names;
FeatureWordInfo *fi = &feature_word_info[w];
if (!fi->feat_names) {
return;
}
if (!fi->feat_names[bitnr]) {
return;
}
names = g_strsplit(fi->feat_names[bitnr], "|", 0);
feat2prop(names[0]);
x86_cpu_register_bit_prop(cpu, names[0], &cpu->env.features[w], bitnr);
for (i = 1; names[i]; i++) {
feat2prop(names[i]);
object_property_add_alias(obj, names[i], obj, g_strdup(names[0]),
&error_abort);
}
g_strfreev(names);
}
static void x86_cpu_initfn(Object *obj) static void x86_cpu_initfn(Object *obj)
{ {
CPUState *cs = CPU(obj); CPUState *cs = CPU(obj);
X86CPU *cpu = X86_CPU(obj); X86CPU *cpu = X86_CPU(obj);
X86CPUClass *xcc = X86_CPU_GET_CLASS(obj); X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
FeatureWord w;
static int inited; static int inited;
cs->env_ptr = env; cs->env_ptr = env;
@ -2887,6 +3001,14 @@ static void x86_cpu_initfn(Object *obj)
cpu->apic_id = -1; cpu->apic_id = -1;
#endif #endif
for (w = 0; w < FEATURE_WORDS; w++) {
int bitnr;
for (bitnr = 0; bitnr < 32; bitnr++) {
x86_cpu_register_feature_bit_props(cpu, w, bitnr);
}
}
x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort); x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
/* init various static tables used in TCG mode */ /* init various static tables used in TCG mode */

View File

@ -305,7 +305,7 @@
#define MSR_IA32_APICBASE 0x1b #define MSR_IA32_APICBASE 0x1b
#define MSR_IA32_APICBASE_BSP (1<<8) #define MSR_IA32_APICBASE_BSP (1<<8)
#define MSR_IA32_APICBASE_ENABLE (1<<11) #define MSR_IA32_APICBASE_ENABLE (1<<11)
#define MSR_IA32_APICBASE_BASE (0xfffff<<12) #define MSR_IA32_APICBASE_BASE (0xfffffU<<12)
#define MSR_IA32_FEATURE_CONTROL 0x0000003a #define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define MSR_TSC_ADJUST 0x0000003b #define MSR_TSC_ADJUST 0x0000003b
#define MSR_IA32_TSCDEADLINE 0x6e0 #define MSR_IA32_TSCDEADLINE 0x6e0