diff options
author | Peter Maydell | 2016-07-20 22:32:56 +0200 |
---|---|---|
committer | Peter Maydell | 2016-07-20 22:32:56 +0200 |
commit | e66b05e9ca471715388182613217503160ed7a4d (patch) | |
tree | 42d50d35e80d75e3d6494c1fef25b793c2afc6bd /hw/intc | |
parent | Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20160720' into staging (diff) | |
parent | pc: Make device_del CPU work for x86 CPUs (diff) | |
download | qemu-e66b05e9ca471715388182613217503160ed7a4d.tar.gz qemu-e66b05e9ca471715388182613217503160ed7a4d.tar.xz qemu-e66b05e9ca471715388182613217503160ed7a4d.zip |
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
x86 queue, 2016-07-20
# gpg: Signature made Wed 20 Jul 2016 16:07:38 BST
# gpg: using RSA key 0x2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6
* remotes/ehabkost/tags/x86-pull-request: (28 commits)
pc: Make device_del CPU work for x86 CPUs
target-i386: Add x86_cpu_unrealizefn()
apic: Use apic_id as apic's migration instance_id
(kvm)apic: Add unrealize callbacks
apic: kvm-apic: Fix crash due to access to freed memory region
apic: Drop APICCommonState.idx and use APIC ID as index in local_apics[]
apic: move MAX_APICS check to 'apic' class
pc: Implement query-hotpluggable-cpus callback
pc: cpu: Allow device_add to be used with x86 cpu
pc: Enforce adding CPUs contiguously and removing them in opposite order
pc: Forbid BSP removal
pc: Register created initial and hotpluged CPUs in one place pc_cpu_plug()
pc: Delay setting number of boot CPUs to machine_done time
pc: Set APIC ID based on socket/core/thread ids if it's not been set yet
target-i386: Fix apic object leak when CPU is deleted
target-i386: cpu: Do not ignore error and fix apic parent
target-i386: Add support for UMIP and RDPID CPUID bits
target-i386: Add socket/core/thread properties to X86CPU
target-i386: Replace custom apic-id setter/getter with static property
pc: cpu: Consolidate apic-id validity checks in pc_cpu_pre_plug()
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/apic.c | 26 | ||||
-rw-r--r-- | hw/intc/apic_common.c | 33 |
2 files changed, 46 insertions, 13 deletions
diff --git a/hw/intc/apic.c b/hw/intc/apic.c index e1ab9354c6..45887d99c0 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -28,7 +28,9 @@ #include "trace.h" #include "hw/i386/pc.h" #include "hw/i386/apic-msidef.h" +#include "qapi/error.h" +#define MAX_APICS 255 #define MAX_APIC_WORDS 8 #define SYNC_FROM_VAPIC 0x1 @@ -419,7 +421,7 @@ static int apic_find_dest(uint8_t dest) int i; if (apic && apic->id == dest) - return dest; /* shortcut in case apic->id == apic->idx */ + return dest; /* shortcut in case apic->id == local_apics[dest]->id */ for (i = 0; i < MAX_APICS; i++) { apic = local_apics[i]; @@ -502,14 +504,14 @@ static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode, break; case 1: memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask)); - apic_set_bit(deliver_bitmask, s->idx); + apic_set_bit(deliver_bitmask, s->id); break; case 2: memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask)); break; case 3: memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask)); - apic_reset_bit(deliver_bitmask, s->idx); + apic_reset_bit(deliver_bitmask, s->id); break; } @@ -870,20 +872,36 @@ static void apic_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); + if (s->id >= MAX_APICS) { + error_setg(errp, "%s initialization failed. APIC ID %d is invalid", + object_get_typename(OBJECT(dev)), s->id); + return; + } + memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi", APIC_SPACE_SIZE); s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, apic_timer, s); - local_apics[s->idx] = s; + local_apics[s->id] = s; msi_nonbroken = true; } +static void apic_unrealize(DeviceState *dev, Error **errp) +{ + APICCommonState *s = APIC_COMMON(dev); + + timer_del(s->timer); + timer_free(s->timer); + local_apics[s->id] = NULL; +} + static void apic_class_init(ObjectClass *klass, void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); k->realize = apic_realize; + k->unrealize = apic_unrealize; k->set_base = apic_set_base; k->set_tpr = apic_set_tpr; k->get_tpr = apic_get_tpr; diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index e6eb694de0..14ac43c186 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -294,19 +294,14 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id) return 0; } +static const VMStateDescription vmstate_apic_common; + static void apic_common_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info; static DeviceState *vapic; - static int apic_no; - - if (apic_no >= MAX_APICS) { - error_setg(errp, "%s initialization failed.", - object_get_typename(OBJECT(dev))); - return; - } - s->idx = apic_no++; + int instance_id = s->id; info = APIC_COMMON_GET_CLASS(s); info->realize(dev, errp); @@ -321,6 +316,24 @@ static void apic_common_realize(DeviceState *dev, Error **errp) info->enable_tpr_reporting(s, true); } + if (s->legacy_instance_id) { + instance_id = -1; + } + vmstate_register_with_alias_id(NULL, instance_id, &vmstate_apic_common, + s, -1, 0); +} + +static void apic_common_unrealize(DeviceState *dev, Error **errp) +{ + APICCommonState *s = APIC_COMMON(dev); + APICCommonClass *info = APIC_COMMON_GET_CLASS(s); + + vmstate_unregister(NULL, &vmstate_apic_common, s); + info->unrealize(dev, errp); + + if (apic_report_tpr_access && info->enable_tpr_reporting) { + info->enable_tpr_reporting(s, false); + } } static int apic_pre_load(void *opaque) @@ -418,6 +431,8 @@ static Property apic_properties_common[] = { DEFINE_PROP_UINT8("version", APICCommonState, version, 0x14), DEFINE_PROP_BIT("vapic", APICCommonState, vapic_control, VAPIC_ENABLE_BIT, true), + DEFINE_PROP_BOOL("legacy-instance-id", APICCommonState, legacy_instance_id, + false), DEFINE_PROP_END_OF_LIST(), }; @@ -425,10 +440,10 @@ static void apic_common_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->vmsd = &vmstate_apic_common; dc->reset = apic_reset_common; dc->props = apic_properties_common; dc->realize = apic_common_realize; + dc->unrealize = apic_common_unrealize; /* * Reason: APIC and CPU need to be wired up by * x86_cpu_apic_create() |