qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

vmcoreinfo.c (3271B)


      1 /*
      2  * Virtual Machine coreinfo device
      3  *
      4  * Copyright (C) 2017 Red Hat, Inc.
      5  *
      6  * Authors: Marc-André Lureau <marcandre.lureau@redhat.com>
      7  *
      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.
     10  *
     11  */
     12 
     13 #include "qemu/osdep.h"
     14 #include "qapi/error.h"
     15 #include "qemu/module.h"
     16 #include "sysemu/reset.h"
     17 #include "hw/nvram/fw_cfg.h"
     18 #include "migration/vmstate.h"
     19 #include "hw/misc/vmcoreinfo.h"
     20 
     21 static void fw_cfg_vmci_write(void *dev, off_t offset, size_t len)
     22 {
     23     VMCoreInfoState *s = VMCOREINFO(dev);
     24 
     25     s->has_vmcoreinfo = offset == 0 && len == sizeof(s->vmcoreinfo)
     26         && s->vmcoreinfo.guest_format != FW_CFG_VMCOREINFO_FORMAT_NONE;
     27 }
     28 
     29 static void vmcoreinfo_reset(void *dev)
     30 {
     31     VMCoreInfoState *s = VMCOREINFO(dev);
     32 
     33     s->has_vmcoreinfo = false;
     34     memset(&s->vmcoreinfo, 0, sizeof(s->vmcoreinfo));
     35     s->vmcoreinfo.host_format = cpu_to_le16(FW_CFG_VMCOREINFO_FORMAT_ELF);
     36 }
     37 
     38 static void vmcoreinfo_realize(DeviceState *dev, Error **errp)
     39 {
     40     VMCoreInfoState *s = VMCOREINFO(dev);
     41     FWCfgState *fw_cfg = fw_cfg_find();
     42     /* for gdb script dump-guest-memory.py */
     43     static VMCoreInfoState * volatile vmcoreinfo_state G_GNUC_UNUSED;
     44 
     45     /* Given that this function is executing, there is at least one VMCOREINFO
     46      * device. Check if there are several.
     47      */
     48     if (!vmcoreinfo_find()) {
     49         error_setg(errp, "at most one %s device is permitted",
     50                    VMCOREINFO_DEVICE);
     51         return;
     52     }
     53 
     54     if (!fw_cfg || !fw_cfg->dma_enabled) {
     55         error_setg(errp, "%s device requires fw_cfg with DMA",
     56                    VMCOREINFO_DEVICE);
     57         return;
     58     }
     59 
     60     fw_cfg_add_file_callback(fw_cfg, FW_CFG_VMCOREINFO_FILENAME,
     61                              NULL, fw_cfg_vmci_write, s,
     62                              &s->vmcoreinfo, sizeof(s->vmcoreinfo), false);
     63 
     64     /*
     65      * This device requires to register a global reset because it is
     66      * not plugged to a bus (which, as its QOM parent, would reset it).
     67      */
     68     qemu_register_reset(vmcoreinfo_reset, dev);
     69     vmcoreinfo_state = s;
     70 }
     71 
     72 static const VMStateDescription vmstate_vmcoreinfo = {
     73     .name = "vmcoreinfo",
     74     .version_id = 1,
     75     .minimum_version_id = 1,
     76     .fields = (VMStateField[]) {
     77         VMSTATE_BOOL(has_vmcoreinfo, VMCoreInfoState),
     78         VMSTATE_UINT16(vmcoreinfo.host_format, VMCoreInfoState),
     79         VMSTATE_UINT16(vmcoreinfo.guest_format, VMCoreInfoState),
     80         VMSTATE_UINT32(vmcoreinfo.size, VMCoreInfoState),
     81         VMSTATE_UINT64(vmcoreinfo.paddr, VMCoreInfoState),
     82         VMSTATE_END_OF_LIST()
     83     },
     84 };
     85 
     86 static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data)
     87 {
     88     DeviceClass *dc = DEVICE_CLASS(klass);
     89 
     90     dc->vmsd = &vmstate_vmcoreinfo;
     91     dc->realize = vmcoreinfo_realize;
     92     dc->hotpluggable = false;
     93     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     94 }
     95 
     96 static const TypeInfo vmcoreinfo_device_info = {
     97     .name          = VMCOREINFO_DEVICE,
     98     .parent        = TYPE_DEVICE,
     99     .instance_size = sizeof(VMCoreInfoState),
    100     .class_init    = vmcoreinfo_device_class_init,
    101 };
    102 
    103 static void vmcoreinfo_register_types(void)
    104 {
    105     type_register_static(&vmcoreinfo_device_info);
    106 }
    107 
    108 type_init(vmcoreinfo_register_types)