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
!= FW_CFG_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(FW_CFG_VMCOREINFO_FORMAT_ELF
);
34 static void vmcoreinfo_realize(DeviceState
*dev
, Error
**errp
)
36 VMCoreInfoState
*s
= VMCOREINFO(dev
);
37 FWCfgState
*fw_cfg
= fw_cfg_find();
38 /* for gdb script dump-guest-memory.py */
39 static VMCoreInfoState
* volatile vmcoreinfo_state G_GNUC_UNUSED
;
41 /* Given that this function is executing, there is at least one VMCOREINFO
42 * device. Check if there are several.
44 if (!vmcoreinfo_find()) {
45 error_setg(errp
, "at most one %s device is permitted",
50 if (!fw_cfg
|| !fw_cfg
->dma_enabled
) {
51 error_setg(errp
, "%s device requires fw_cfg with DMA",
56 fw_cfg_add_file_callback(fw_cfg
, FW_CFG_VMCOREINFO_FILENAME
,
57 NULL
, fw_cfg_vmci_write
, s
,
58 &s
->vmcoreinfo
, sizeof(s
->vmcoreinfo
), false);
60 qemu_register_reset(vmcoreinfo_reset
, dev
);
64 static const VMStateDescription vmstate_vmcoreinfo
= {
67 .minimum_version_id
= 1,
68 .fields
= (VMStateField
[]) {
69 VMSTATE_BOOL(has_vmcoreinfo
, VMCoreInfoState
),
70 VMSTATE_UINT16(vmcoreinfo
.host_format
, VMCoreInfoState
),
71 VMSTATE_UINT16(vmcoreinfo
.guest_format
, VMCoreInfoState
),
72 VMSTATE_UINT32(vmcoreinfo
.size
, VMCoreInfoState
),
73 VMSTATE_UINT64(vmcoreinfo
.paddr
, VMCoreInfoState
),
78 static void vmcoreinfo_device_class_init(ObjectClass
*klass
, void *data
)
80 DeviceClass
*dc
= DEVICE_CLASS(klass
);
82 dc
->vmsd
= &vmstate_vmcoreinfo
;
83 dc
->realize
= vmcoreinfo_realize
;
84 dc
->hotpluggable
= false;
85 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
88 static const TypeInfo vmcoreinfo_device_info
= {
89 .name
= VMCOREINFO_DEVICE
,
90 .parent
= TYPE_DEVICE
,
91 .instance_size
= sizeof(VMCoreInfoState
),
92 .class_init
= vmcoreinfo_device_class_init
,
95 static void vmcoreinfo_register_types(void)
97 type_register_static(&vmcoreinfo_device_info
);
100 type_init(vmcoreinfo_register_types
)