hw/intc/arm_gicv3_its: Implement a minimalist reset
At the moment the ITS is not properly reset and this causes various bugs on save/restore. We implement a minimalist reset through individual register writes but for kernel versions before v4.15 this fails voiding the vITS cache. We cannot claim we have a comprehensive reset (hence the error message) but that's better than nothing. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1511883692-11511-3-git-send-email-eric.auger@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
7e7244796b
commit
c9aedf8ca4
|
@ -28,6 +28,16 @@
|
||||||
|
|
||||||
#define TYPE_KVM_ARM_ITS "arm-its-kvm"
|
#define TYPE_KVM_ARM_ITS "arm-its-kvm"
|
||||||
#define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
|
#define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
|
||||||
|
#define KVM_ARM_ITS_CLASS(klass) \
|
||||||
|
OBJECT_CLASS_CHECK(KVMARMITSClass, (klass), TYPE_KVM_ARM_ITS)
|
||||||
|
#define KVM_ARM_ITS_GET_CLASS(obj) \
|
||||||
|
OBJECT_GET_CLASS(KVMARMITSClass, (obj), TYPE_KVM_ARM_ITS)
|
||||||
|
|
||||||
|
typedef struct KVMARMITSClass {
|
||||||
|
GICv3ITSCommonClass parent_class;
|
||||||
|
void (*parent_reset)(DeviceState *dev);
|
||||||
|
} KVMARMITSClass;
|
||||||
|
|
||||||
|
|
||||||
static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
|
static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
|
||||||
{
|
{
|
||||||
|
@ -186,6 +196,34 @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
|
||||||
GITS_CTLR, &s->ctlr, true, &error_abort);
|
GITS_CTLR, &s->ctlr, true, &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void kvm_arm_its_reset(DeviceState *dev)
|
||||||
|
{
|
||||||
|
GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
|
||||||
|
KVMARMITSClass *c = KVM_ARM_ITS_GET_CLASS(s);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
c->parent_reset(dev);
|
||||||
|
|
||||||
|
error_report("ITS KVM: full reset is not supported by QEMU");
|
||||||
|
|
||||||
|
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
||||||
|
GITS_CTLR)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
||||||
|
GITS_CTLR, &s->ctlr, true, &error_abort);
|
||||||
|
|
||||||
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
||||||
|
GITS_CBASER, &s->cbaser, true, &error_abort);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
|
||||||
|
GITS_BASER + i * 8, &s->baser[i], true,
|
||||||
|
&error_abort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Property kvm_arm_its_props[] = {
|
static Property kvm_arm_its_props[] = {
|
||||||
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
|
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
|
||||||
GICv3State *),
|
GICv3State *),
|
||||||
|
@ -196,12 +234,15 @@ static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
|
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
|
||||||
|
KVMARMITSClass *ic = KVM_ARM_ITS_CLASS(klass);
|
||||||
|
|
||||||
dc->realize = kvm_arm_its_realize;
|
dc->realize = kvm_arm_its_realize;
|
||||||
dc->props = kvm_arm_its_props;
|
dc->props = kvm_arm_its_props;
|
||||||
|
ic->parent_reset = dc->reset;
|
||||||
icc->send_msi = kvm_its_send_msi;
|
icc->send_msi = kvm_its_send_msi;
|
||||||
icc->pre_save = kvm_arm_its_pre_save;
|
icc->pre_save = kvm_arm_its_pre_save;
|
||||||
icc->post_load = kvm_arm_its_post_load;
|
icc->post_load = kvm_arm_its_post_load;
|
||||||
|
dc->reset = kvm_arm_its_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo kvm_arm_its_info = {
|
static const TypeInfo kvm_arm_its_info = {
|
||||||
|
@ -209,6 +250,7 @@ static const TypeInfo kvm_arm_its_info = {
|
||||||
.parent = TYPE_ARM_GICV3_ITS_COMMON,
|
.parent = TYPE_ARM_GICV3_ITS_COMMON,
|
||||||
.instance_size = sizeof(GICv3ITSState),
|
.instance_size = sizeof(GICv3ITSState),
|
||||||
.class_init = kvm_arm_its_class_init,
|
.class_init = kvm_arm_its_class_init,
|
||||||
|
.class_size = sizeof(KVMARMITSClass),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void kvm_arm_its_register_types(void)
|
static void kvm_arm_its_register_types(void)
|
||||||
|
|
Loading…
Reference in New Issue