pc-dimm: factor out MemoryDevice interface

On the qmp level, we already have the concept of memory devices:
    "query-memory-devices"
Right now, we only support NVDIMM and PCDIMM.

We want to map other devices later into the address space of the guest.
Such device could e.g. be virtio devices. These devices will have a
guest memory range assigned but won't be exposed via e.g. ACPI. We want
to make them look like memory device, but not glued to pc-dimm.

Especially, it will not always be possible to have TYPE_PC_DIMM as a parent
class (e.g. virtio devices). Let's use an interface instead. As a first
part, convert handling of
- qmp_pc_dimm_device_list
- get_plugged_memory_size
to our new model. plug/unplug stuff etc. will follow later.

A memory device will have to provide the following functions:
- get_addr(): Necessary, as the property "addr" can e.g. not be used for
              virtio devices (already defined).
- get_plugged_size(): The amount this device offers to the guest as of
                      now.
- get_region_size(): Because this can later on be bigger than the
                     plugged size.
- fill_device_info(): Fill MemoryDeviceInfo, e.g. for qmp.

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180423165126.15441-2-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
David Hildenbrand 2018-04-23 18:51:16 +02:00 committed by Eduardo Habkost
parent c8b7e627b4
commit 2cc0e2e814
12 changed files with 242 additions and 66 deletions

View file

@ -0,0 +1,45 @@
/*
* Memory Device Interface
*
* Copyright (c) 2018 Red Hat, Inc.
*
* Authors:
* David Hildenbrand <david@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef MEMORY_DEVICE_H
#define MEMORY_DEVICE_H
#include "qom/object.h"
#include "hw/qdev.h"
#define TYPE_MEMORY_DEVICE "memory-device"
#define MEMORY_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(MemoryDeviceClass, (klass), TYPE_MEMORY_DEVICE)
#define MEMORY_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(MemoryDeviceClass, (obj), TYPE_MEMORY_DEVICE)
#define MEMORY_DEVICE(obj) \
INTERFACE_CHECK(MemoryDeviceState, (obj), TYPE_MEMORY_DEVICE)
typedef struct MemoryDeviceState {
Object parent_obj;
} MemoryDeviceState;
typedef struct MemoryDeviceClass {
InterfaceClass parent_class;
uint64_t (*get_addr)(const MemoryDeviceState *md);
uint64_t (*get_plugged_size)(const MemoryDeviceState *md);
uint64_t (*get_region_size)(const MemoryDeviceState *md);
void (*fill_device_info)(const MemoryDeviceState *md,
MemoryDeviceInfo *info);
} MemoryDeviceClass;
MemoryDeviceInfoList *qmp_memory_device_list(void);
uint64_t get_plugged_memory_size(void);
#endif

View file

@ -93,9 +93,7 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
MemoryDeviceInfoList *qmp_pc_dimm_device_list(void);
uint64_t pc_existing_dimms_capacity(Error **errp);
uint64_t get_plugged_memory_size(void);
void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
MemoryRegion *mr, uint64_t align, Error **errp);
void pc_dimm_memory_unplug(DeviceState *dev, MemoryHotplugState *hpms,