2 * Virtual Machine coreinfo device
4 * Copyright (C) 2017 Red Hat, Inc.
6 * Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
12 #include "qemu/osdep.h"
13 #include "qapi/error.h"
14 #include "hw/nvram/fw_cfg.h"
15 #include "hw/misc/vmcoreinfo.h"
17 static void fw_cfg_vmci_write(void *dev
, off_t offset
, size_t len
)
19 VMCoreInfoState
*s
= VMCOREINFO(dev
);
21 s
->has_vmcoreinfo
= offset
== 0 && len
== sizeof(s
->vmcoreinfo
)
22 && s
->vmcoreinfo
.guest_format
!= VMCOREINFO_FORMAT_NONE
;
25 static void vmcoreinfo_reset(void *dev
)
27 VMCoreInfoState
*s
= VMCOREINFO(dev
);
29 s
->has_vmcoreinfo
= false;
30 memset(&s
->vmcoreinfo
, 0, sizeof(s
->vmcoreinfo
));
31 s
->vmcoreinfo
.host_format
= cpu_to_le16(VMCOREINFO_FORMAT_ELF
);
34 static void vmcoreinfo_realize(DeviceState
*dev
, Error
**errp
)
36 VMCoreInfoState
*s
= VMCOREINFO(dev
);
37 FWCfgState
*fw_cfg
= fw_cfg_find();
39 /* Given that this function is executing, there is at least one VMCOREINFO
40 * device. Check if there are several.
42 if (!vmcoreinfo_find()) {
43 error_setg(errp
, "at most one %s device is permitted",
48 if (!fw_cfg
|| !fw_cfg
->dma_enabled
) {
49 error_setg(errp
, "%s device requires fw_cfg with DMA",
54 fw_cfg_add_file_callback(fw_cfg
, "etc/vmcoreinfo",
55 NULL
, fw_cfg_vmci_write
, s
,
56 &s
->vmcoreinfo
, sizeof(s
->vmcoreinfo
), false);
58 qemu_register_reset(vmcoreinfo_reset
, dev
);
61 static const VMStateDescription vmstate_vmcoreinfo
= {
64 .minimum_version_id
= 1,
65 .fields
= (VMStateField
[]) {
66 VMSTATE_BOOL(has_vmcoreinfo
, VMCoreInfoState
),
67 VMSTATE_UINT16(vmcoreinfo
.host_format
, VMCoreInfoState
),
68 VMSTATE_UINT16(vmcoreinfo
.guest_format
, VMCoreInfoState
),
69 VMSTATE_UINT32(vmcoreinfo
.size
, VMCoreInfoState
),
70 VMSTATE_UINT64(vmcoreinfo
.paddr
, VMCoreInfoState
),
75 static void vmcoreinfo_device_class_init(ObjectClass
*klass
, void *data
)
77 DeviceClass
*dc
= DEVICE_CLASS(klass
);
79 dc
->vmsd
= &vmstate_vmcoreinfo
;
80 dc
->realize
= vmcoreinfo_realize
;
81 dc
->hotpluggable
= false;
84 static const TypeInfo vmcoreinfo_device_info
= {
85 .name
= VMCOREINFO_DEVICE
,
86 .parent
= TYPE_DEVICE
,
87 .instance_size
= sizeof(VMCoreInfoState
),
88 .class_init
= vmcoreinfo_device_class_init
,
91 static void vmcoreinfo_register_types(void)
93 type_register_static(&vmcoreinfo_device_info
);
96 type_init(vmcoreinfo_register_types
)