@@ -44,3 +44,4 @@ CONFIG_APIC=y
CONFIG_IOAPIC=y
CONFIG_ICC_BUS=y
CONFIG_PVPANIC=y
+CONFIG_MEM_HOTPLUG=y
@@ -44,3 +44,4 @@ CONFIG_APIC=y
CONFIG_IOAPIC=y
CONFIG_ICC_BUS=y
CONFIG_PVPANIC=y
+CONFIG_MEM_HOTPLUG=y
@@ -29,6 +29,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += usb/
devices-dirs-$(CONFIG_VIRTIO) += virtio/
devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
devices-dirs-$(CONFIG_SOFTMMU) += xen/
+devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
devices-dirs-y += core/
common-obj-y += $(devices-dirs-y)
obj-y += $(devices-dirs-y)
new file mode 100644
@@ -0,0 +1 @@
+common-obj-$(CONFIG_MEM_HOTPLUG) += dimm.o
new file mode 100644
@@ -0,0 +1,103 @@
+/*
+ * Dimm device for Memory Hotplug
+ *
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
+ */
+
+#include "hw/mem/dimm.h"
+#include "qemu/config-file.h"
+#include "qapi/visitor.h"
+
+static Property dimm_properties[] = {
+ DEFINE_PROP_UINT64("start", DimmDevice, start, 0),
+ DEFINE_PROP_UINT32("node", DimmDevice, node, 0),
+ DEFINE_PROP_INT32("slot", DimmDevice, slot, -1),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void dimm_get_size(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ int64_t value;
+ MemoryRegion *mr;
+ DimmDevice *dimm = DIMM(obj);
+
+ mr = host_memory_backend_get_memory(dimm->hostmem, errp);
+ value = memory_region_size(mr);
+
+ visit_type_int(v, &value, name, errp);
+}
+
+static void dimm_initfn(Object *obj)
+{
+ DimmDevice *dimm = DIMM(obj);
+
+ object_property_add(obj, "size", "int", dimm_get_size,
+ NULL, NULL, NULL, &error_abort);
+ object_property_add_link(obj, "memdev", TYPE_MEMORY_BACKEND,
+ (Object **)&dimm->hostmem,
+ qdev_prop_allow_set_link_before_realize,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE,
+ &error_abort);
+}
+
+static void dimm_realize(DeviceState *dev, Error **errp)
+{
+ DimmDevice *dimm = DIMM(dev);
+
+ if (!dimm->hostmem) {
+ error_setg(errp, "'memdev' property is not set");
+ return;
+ }
+
+ if (!dev->id) {
+ error_setg(errp, "'id' property is not set");
+ return;
+ }
+}
+
+static MemoryRegion *dimm_get_memory_region(DimmDevice *dimm)
+{
+ return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
+}
+
+static void dimm_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ DimmDeviceClass *ddc = DIMM_CLASS(oc);
+
+ dc->realize = dimm_realize;
+ dc->props = dimm_properties;
+
+ ddc->get_memory_region = dimm_get_memory_region;
+}
+
+static TypeInfo dimm_info = {
+ .name = TYPE_DIMM,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(DimmDevice),
+ .instance_init = dimm_initfn,
+ .class_init = dimm_class_init,
+ .class_size = sizeof(DimmDeviceClass),
+};
+
+static void dimm_register_types(void)
+{
+ type_register_static(&dimm_info);
+}
+
+type_init(dimm_register_types)
new file mode 100644
@@ -0,0 +1,65 @@
+/*
+ * DIMM device
+ *
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ * Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
+ * Igor Mammedov <imammedo@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 QEMU_DIMM_H
+#define QEMU_DIMM_H
+
+#include "exec/memory.h"
+#include "sysemu/hostmem.h"
+#include "hw/qdev.h"
+
+#define DEFAULT_DIMMSIZE (1024*1024*1024)
+
+#define TYPE_DIMM "dimm"
+#define DIMM(obj) \
+ OBJECT_CHECK(DimmDevice, (obj), TYPE_DIMM)
+#define DIMM_CLASS(oc) \
+ OBJECT_CLASS_CHECK(DimmDeviceClass, (oc), TYPE_DIMM)
+#define DIMM_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(DimmDeviceClass, (obj), TYPE_DIMM)
+
+/**
+ * DimmDevice:
+ * @start: starting guest physical address, where @DimmDevice is mapped.
+ * Default value: 0, means that address is auto-allocated.
+ * @node: numa node to which @DimmDevice is attached.
+ * @slot: slot number into which @DimmDevice is plugged in.
+ * Default value: -1, means that slot is auto-allocated.
+ * @hostmem: host memory backend providing memory for @DimmDevice
+ */
+typedef struct DimmDevice {
+ /* private */
+ DeviceState parent_obj;
+
+ /* public */
+ ram_addr_t start;
+ uint32_t node;
+ int32_t slot;
+ HostMemoryBackend *hostmem;
+} DimmDevice;
+
+/**
+ * DimmDeviceClass:
+ * @get_memory_region: returns #MemoryRegion associated with @dimm
+ */
+typedef struct DimmDeviceClass {
+ /* private */
+ DeviceClass parent_class;
+
+ /* public */
+ MemoryRegion *(*get_memory_region)(DimmDevice *dimm);
+} DimmDeviceClass;
+
+#endif