pc,pci,virtio,hotplug fixes, enhancements

numa work by Hu Tao and others
 memory hotplug by Igor
 vhost-user by Nikolay, Antonios and others
 guest virtio announcements by Jason
 qtest fixes by Sergey
 qdev hotplug fixes by Paolo
 misc other fixes mostly by myself
 
 Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJTowW+AAoJECgfDbjSjVRpnMMH/jp3sKGzJumYLbi5ihjmYyND
 jYd6ySXoVAjUTgaCvdje5srisOap8pbc783kQvQS4CeWsjZ5Vvh+PZjkBPIqF1pD
 celxGQ43CY7QSUWq+02Dg9VIUwLwZqdKlxNsV01FligQn+ZBQ6sQ6ksWx7oGzqRt
 5/HMZykbwUvSk/4xGUaMn2+/4uhQ0Wz5EsCkv9L/u8kS72k6ldc/tCGZMzBUNHTM
 rW5FPYwMQP0MXgGTXnlLEQjJ7Lozc66IaMZoHw/a/aGSIxdag9Otj0ADuXq6yZaV
 Xi4O/EOJWd1JpSG7w8LOyIZNakpHkU43fmJCLzBjDAupHeRp57TcW5ox4PJYAtg=
 =Oxdt
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging

pc,pci,virtio,hotplug fixes, enhancements

numa work by Hu Tao and others
memory hotplug by Igor
vhost-user by Nikolay, Antonios and others
guest virtio announcements by Jason
qtest fixes by Sergey
qdev hotplug fixes by Paolo
misc other fixes mostly by myself

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

* remotes/mst/tags/for_upstream: (109 commits)
  numa: use RAM_ADDR_FMT with ram_addr_t
  qapi/string-output-visitor: fix bugs
  tests: simplify code
  qapi: fix input visitor bugs
  acpi: rephrase comment
  qmp: add ACPI_DEVICE_OST event handling
  qmp: add query-acpi-ospm-status command
  acpi: implement ospm_status() method for PIIX4/ICH9_LPC devices
  acpi: introduce TYPE_ACPI_DEVICE_IF interface
  qmp: add query-memory-devices command
  numa: handle mmaped memory allocation failure correctly
  pc: acpi: do not hardcode preprocessor
  qmp: clean out whitespace
  qdev: recursively unrealize devices when unrealizing bus
  qdev: reorganize error reporting in bus_set_realized
  qapi: fix build on glib < 2.28
  qapi: make string output visitor parse int list
  qapi: make string input visitor parse int list
  tests: fix memory leak in test of string input visitor
  hmp: add info memdev
  ...

Conflicts:
	include/hw/i386/pc.h
[PMM: fixed minor conflict in pc.h]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-06-20 18:01:24 +01:00
commit 0a99aae5fa
126 changed files with 7421 additions and 733 deletions

View file

@ -297,11 +297,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
/* memory API */
extern ram_addr_t ram_size;
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
#define RAM_PREALLOC_MASK (1 << 0)
typedef struct RAMBlock {
struct MemoryRegion *mr;
uint8_t *host;
@ -327,9 +322,6 @@ typedef struct RAMList {
} RAMList;
extern RAMList ram_list;
extern const char *mem_path;
extern int mem_prealloc;
/* Flags stored in the low bits of the TLB virtual address. These are
defined so that fast path ram access is all zeros. */
/* Zero if TLB entry is valid. */

View file

@ -45,6 +45,8 @@ typedef uintptr_t ram_addr_t;
# define RAM_ADDR_FMT "%" PRIxPTR
#endif
extern ram_addr_t ram_size;
/* memory API */
typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);

View file

@ -31,6 +31,7 @@
#include "qemu/queue.h"
#include "qemu/int128.h"
#include "qemu/notify.h"
#include "qapi/error.h"
#define MAX_PHYS_ADDR_SPACE_BITS 62
#define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
@ -311,6 +312,28 @@ void memory_region_init_ram(MemoryRegion *mr,
const char *name,
uint64_t size);
#ifdef __linux__
/**
* memory_region_init_ram_from_file: Initialize RAM memory region with a
* mmap-ed backend.
*
* @mr: the #MemoryRegion to be initialized.
* @owner: the object that tracks the region's reference count
* @name: the name of the region.
* @size: size of the region.
* @share: %true if memory must be mmaped with the MAP_SHARED flag
* @path: the path in which to allocate the RAM.
* @errp: pointer to Error*, to store an error if it happens.
*/
void memory_region_init_ram_from_file(MemoryRegion *mr,
struct Object *owner,
const char *name,
uint64_t size,
bool share,
const char *path,
Error **errp);
#endif
/**
* memory_region_init_ram_ptr: Initialize RAM memory region from a
* user-provided pointer. Accesses into the
@ -512,6 +535,16 @@ bool memory_region_is_logging(MemoryRegion *mr);
*/
bool memory_region_is_rom(MemoryRegion *mr);
/**
* memory_region_get_fd: Get a file descriptor backing a RAM memory region.
*
* Returns a file descriptor backing a file-based RAM memory region,
* or -1 if the region is not a file-based RAM memory region.
*
* @mr: the RAM or alias memory region being queried.
*/
int memory_region_get_fd(MemoryRegion *mr);
/**
* memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
*
@ -847,6 +880,14 @@ void memory_region_set_alias_offset(MemoryRegion *mr,
*/
bool memory_region_present(MemoryRegion *container, hwaddr addr);
/**
* memory_region_is_mapped: returns true if #MemoryRegion is mapped
* into any address space.
*
* @mr: a #MemoryRegion which should be checked if it's mapped
*/
bool memory_region_is_mapped(MemoryRegion *mr);
/**
* memory_region_find: translate an address/size relative to a
* MemoryRegion into a #MemoryRegionSection.

View file

@ -22,9 +22,13 @@
#ifndef CONFIG_USER_ONLY
#include "hw/xen/xen.h"
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
bool share, const char *mem_path,
Error **errp);
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
int qemu_get_ram_fd(ram_addr_t addr);
void *qemu_get_ram_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr);

View file

@ -26,6 +26,11 @@
#include "exec/memory.h"
#include "hw/irq.h"
/*
* current device naming scheme supports up to 256 memory devices
*/
#define ACPI_MAX_RAM_SLOTS 256
/* from linux include/acpi/actype.h */
/* Default ACPI register widths */

View file

@ -0,0 +1,43 @@
#ifndef ACPI_DEV_INTERFACE_H
#define ACPI_DEV_INTERFACE_H
#include "qom/object.h"
#include "qapi-types.h"
#define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
#define ACPI_DEVICE_IF_CLASS(klass) \
OBJECT_CLASS_CHECK(AcpiDeviceIfClass, (klass), \
TYPE_ACPI_DEVICE_IF)
#define ACPI_DEVICE_IF_GET_CLASS(obj) \
OBJECT_GET_CLASS(AcpiDeviceIfClass, (obj), \
TYPE_ACPI_DEVICE_IF)
#define ACPI_DEVICE_IF(obj) \
INTERFACE_CHECK(AcpiDeviceIf, (obj), \
TYPE_ACPI_DEVICE_IF)
typedef struct AcpiDeviceIf {
/* <private> */
Object Parent;
} AcpiDeviceIf;
/**
* AcpiDeviceIfClass:
*
* ospm_status: returns status of ACPI device objects, reported
* via _OST method if device supports it.
*
* Interface is designed for providing unified interface
* to generic ACPI functionality that could be used without
* knowledge about internals of actual device that implements
* ACPI interface.
*/
typedef struct AcpiDeviceIfClass {
/* <private> */
InterfaceClass parent_class;
/* <public> */
void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
} AcpiDeviceIfClass;
#endif

View file

@ -13,7 +13,7 @@
#define ACPI_HOTPLUG_H
#include "hw/acpi/acpi.h"
#include "hw/acpi/cpu_hotplug_defs.h"
#include "hw/acpi/pc-hotplug.h"
typedef struct AcpiCpuHotplug {
MemoryRegion io;

View file

@ -1,32 +0,0 @@
/*
* QEMU ACPI hotplug utilities shared defines
*
* Copyright (C) 2013 Red Hat Inc
*
* Authors:
* 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 ACPI_HOTPLUG_DEFS_H
#define ACPI_HOTPLUG_DEFS_H
/*
* ONLY DEFINEs are permited in this file since it's shared
* between C and ASL code.
*/
#define ACPI_CPU_HOTPLUG_STATUS 4
/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
* have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
*/
#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
/* 256 CPU IDs, 8 bits per entry: */
#define ACPI_GPE_PROC_LEN 32
#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
#endif

View file

@ -23,6 +23,8 @@
#include "hw/acpi/acpi.h"
#include "hw/acpi/cpu_hotplug.h"
#include "hw/acpi/memory_hotplug.h"
#include "hw/acpi/acpi_dev_interface.h"
typedef struct ICH9LPCPMRegs {
/*
@ -46,6 +48,8 @@ typedef struct ICH9LPCPMRegs {
AcpiCpuHotplug gpe_cpu;
Notifier cpu_added_notifier;
MemHotplugState acpi_memory_hotplug;
} ICH9LPCPMRegs;
void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
@ -55,4 +59,7 @@ extern const VMStateDescription vmstate_ich9_pm;
void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp);
void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp);
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
#endif /* HW_ACPI_ICH9_H */

View file

@ -0,0 +1,38 @@
#ifndef QEMU_HW_ACPI_MEMORY_HOTPLUG_H
#define QEMU_HW_ACPI_MEMORY_HOTPLUG_H
#include "hw/qdev-core.h"
#include "hw/acpi/acpi.h"
#include "migration/vmstate.h"
#define ACPI_MEMORY_HOTPLUG_STATUS 8
typedef struct MemStatus {
DeviceState *dimm;
bool is_enabled;
bool is_inserting;
uint32_t ost_event;
uint32_t ost_status;
} MemStatus;
typedef struct MemHotplugState {
bool is_enabled; /* true if memory hotplug is supported */
MemoryRegion io;
uint32_t selector;
uint32_t dev_count;
MemStatus *devs;
} MemHotplugState;
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
MemHotplugState *state);
void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
DeviceState *dev, Error **errp);
extern const VMStateDescription vmstate_memory_hotplug;
#define VMSTATE_MEMORY_HOTPLUG(memhp, state) \
VMSTATE_STRUCT(memhp, state, 1, \
vmstate_memory_hotplug, MemHotplugState)
void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list);
#endif

View file

@ -0,0 +1,56 @@
/*
* QEMU ACPI hotplug utilities shared defines
*
* Copyright (C) 2014 Red Hat Inc
*
* Authors:
* 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 PC_HOTPLUG_H
#define PC_HOTPLUG_H
/*
* ONLY DEFINEs are permited in this file since it's shared
* between C and ASL code.
*/
#define ACPI_CPU_HOTPLUG_STATUS 4
/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
* have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
*/
#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
/* 256 CPU IDs, 8 bits per entry: */
#define ACPI_GPE_PROC_LEN 32
#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
#define MEMORY_HOPTLUG_DEVICE MHPD
#define MEMORY_SLOTS_NUMBER MDNR
#define MEMORY_HOTPLUG_IO_REGION HPMR
#define MEMORY_SLOT_ADDR_LOW MRBL
#define MEMORY_SLOT_ADDR_HIGH MRBH
#define MEMORY_SLOT_SIZE_LOW MRLL
#define MEMORY_SLOT_SIZE_HIGH MRLH
#define MEMORY_SLOT_PROXIMITY MPX
#define MEMORY_SLOT_ENABLED MES
#define MEMORY_SLOT_INSERT_EVENT MINS
#define MEMORY_SLOT_SLECTOR MSEL
#define MEMORY_SLOT_OST_EVENT MOEV
#define MEMORY_SLOT_OST_STATUS MOSC
#define MEMORY_SLOT_LOCK MLCK
#define MEMORY_SLOT_STATUS_METHOD MRST
#define MEMORY_SLOT_CRS_METHOD MCRS
#define MEMORY_SLOT_OST_METHOD MOST
#define MEMORY_SLOT_PROXIMITY_METHOD MPXM
#define MEMORY_SLOT_NOTIFY_METHOD MTFY
#define MEMORY_SLOT_SCAN_METHOD MSCN
#endif

View file

@ -43,9 +43,13 @@ struct QEMUMachine {
const char *hw_version;
};
#define TYPE_MACHINE_SUFFIX "-machine"
void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
const char *name,
uint64_t ram_size);
int qemu_register_machine(QEMUMachine *m);
#define TYPE_MACHINE_SUFFIX "-machine"
#define TYPE_MACHINE "machine"
#undef MACHINE /* BSD defines it and QEMU does not use it */
#define MACHINE(obj) \
@ -61,6 +65,11 @@ extern MachineState *current_machine;
/**
* MachineClass:
* @qemu_machine: #QEMUMachine
* @get_hotplug_handler: this function is called during bus-less
* device hotplug. If defined it returns pointer to an instance
* of HotplugHandler object, which handles hotplug operation
* for a given @dev. It may return NULL if @dev doesn't require
* any actions to be performed by hotplug handler.
*/
struct MachineClass {
/*< private >*/
@ -90,6 +99,9 @@ struct MachineClass {
const char *default_boot_order;
GlobalProperty *compat_props;
const char *hw_version;
HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
DeviceState *dev);
};
/**
@ -113,6 +125,8 @@ struct MachineState {
char *firmware;
ram_addr_t ram_size;
ram_addr_t maxram_size;
uint64_t ram_slots;
const char *boot_order;
char *kernel_filename;
char *kernel_cmdline;

View file

@ -24,7 +24,7 @@ I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
#define ICH9_CC_SIZE (16 * 1024) /* 16KB */
#define TYPE_ICH9_LPC_DEVICE "ICH9 LPC"
#define TYPE_ICH9_LPC_DEVICE "ICH9-LPC"
#define ICH9_LPC_DEVICE(obj) \
OBJECT_CHECK(ICH9LPCState, (obj), TYPE_ICH9_LPC_DEVICE)

View file

@ -3,6 +3,7 @@
#include "qemu-common.h"
#include "exec/memory.h"
#include "hw/boards.h"
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
#include "net/net.h"
@ -12,9 +13,57 @@
#include "qemu/bitmap.h"
#include "sysemu/sysemu.h"
#include "hw/pci/pci.h"
#include "hw/boards.h"
#define HPET_INTCAP "hpet-intcap"
/**
* PCMachineState:
* @hotplug_memory_base: address in guest RAM address space where hotplug memory
* address space begins.
* @hotplug_memory: hotplug memory addess space container
* @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
*/
struct PCMachineState {
/*< private >*/
MachineState parent_obj;
/* <public> */
ram_addr_t hotplug_memory_base;
MemoryRegion hotplug_memory;
HotplugHandler *acpi_dev;
};
#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
#define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size"
/**
* PCMachineClass:
* @get_hotplug_handler: pointer to parent class callback @get_hotplug_handler
*/
struct PCMachineClass {
/*< private >*/
MachineClass parent_class;
/*< public >*/
HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
DeviceState *dev);
};
typedef struct PCMachineState PCMachineState;
typedef struct PCMachineClass PCMachineClass;
#define TYPE_PC_MACHINE "generic-pc-machine"
#define PC_MACHINE(obj) \
OBJECT_CHECK(PCMachineState, (obj), TYPE_PC_MACHINE)
#define PC_MACHINE_GET_CLASS(obj) \
OBJECT_GET_CLASS(PCMachineClass, (obj), TYPE_PC_MACHINE)
#define PC_MACHINE_CLASS(klass) \
OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
void qemu_register_pc_machine(QEMUMachine *m);
/* PC-style peripherals (also used by other machines). */
typedef struct PcPciInfo {
@ -43,6 +92,7 @@ struct PcGuestInfo {
uint64_t *node_cpu;
FWCfgState *fw_cfg;
bool has_acpi_build;
bool has_reserved_memory;
};
/* parallel.c */
@ -134,10 +184,8 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
MemoryRegion *pci_address_space);
FWCfgState *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
FWCfgState *pc_memory_init(MachineState *machine,
MemoryRegion *system_memory,
ram_addr_t below_4g_mem_size,
ram_addr_t above_4g_mem_size,
MemoryRegion *rom_memory,
@ -167,7 +215,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq smi_irq,
int kvm_enabled, FWCfgState *fw_cfg);
int kvm_enabled, FWCfgState *fw_cfg,
DeviceState **piix4_pm);
void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
/* hpet.c */
@ -243,7 +292,12 @@ int e820_get_num_entries(void);
bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_Q35_COMPAT_2_0 \
PC_COMPAT_2_0
PC_COMPAT_2_0, \
{\
.driver = "ICH9-LPC",\
.property = "memory-hotplug-support",\
.value = "off",\
}
#define PC_Q35_COMPAT_1_7 \
PC_COMPAT_1_7, \
@ -272,10 +326,16 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
.property = "any_layout",\
.value = "off",\
},{\
.driver = "PIIX4_PM",\
.property = "memory-hotplug-support",\
.value = "off",\
},\
{\
.driver = "apic",\
.property = "version",\
.value = stringify(0x11),\
},{\
},\
{\
.driver = "nec-usb-xhci",\
.property = "superspeed-ports-first",\
.value = "off",\
@ -294,6 +354,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
.driver = "pci-serial-4x",\
.property = "prog_if",\
.value = stringify(0),\
},\
{\
.driver = "virtio-net-pci",\
.property = "guest_announce",\
.value = "off",\
}
#define PC_COMPAT_1_7 \

81
include/hw/mem/pc-dimm.h Normal file
View file

@ -0,0 +1,81 @@
/*
* PC DIMM device
*
* Copyright ProfitBricks GmbH 2012
* Copyright (C) 2013-2014 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_PC_DIMM_H
#define QEMU_PC_DIMM_H
#include "exec/memory.h"
#include "sysemu/hostmem.h"
#include "hw/qdev.h"
#define DEFAULT_PC_DIMMSIZE (1024*1024*1024)
#define TYPE_PC_DIMM "pc-dimm"
#define PC_DIMM(obj) \
OBJECT_CHECK(PCDIMMDevice, (obj), TYPE_PC_DIMM)
#define PC_DIMM_CLASS(oc) \
OBJECT_CLASS_CHECK(PCDIMMDeviceClass, (oc), TYPE_PC_DIMM)
#define PC_DIMM_GET_CLASS(obj) \
OBJECT_GET_CLASS(PCDIMMDeviceClass, (obj), TYPE_PC_DIMM)
#define PC_DIMM_ADDR_PROP "addr"
#define PC_DIMM_SLOT_PROP "slot"
#define PC_DIMM_NODE_PROP "node"
#define PC_DIMM_SIZE_PROP "size"
#define PC_DIMM_MEMDEV_PROP "memdev"
#define PC_DIMM_UNASSIGNED_SLOT -1
/**
* PCDIMMDevice:
* @addr: starting guest physical address, where @PCDIMMDevice is mapped.
* Default value: 0, means that address is auto-allocated.
* @node: numa node to which @PCDIMMDevice is attached.
* @slot: slot number into which @PCDIMMDevice is plugged in.
* Default value: -1, means that slot is auto-allocated.
* @hostmem: host memory backend providing memory for @PCDIMMDevice
*/
typedef struct PCDIMMDevice {
/* private */
DeviceState parent_obj;
/* public */
uint64_t addr;
uint32_t node;
int32_t slot;
HostMemoryBackend *hostmem;
} PCDIMMDevice;
/**
* PCDIMMDeviceClass:
* @get_memory_region: returns #MemoryRegion associated with @dimm
*/
typedef struct PCDIMMDeviceClass {
/* private */
DeviceClass parent_class;
/* public */
MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm);
} PCDIMMDeviceClass;
uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
uint64_t address_space_size,
uint64_t *hint, uint64_t size,
Error **errp);
int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
int qmp_pc_dimm_device_list(Object *obj, void *opaque);
#endif

View file

@ -0,0 +1,38 @@
/*
* vhost-backend
*
* Copyright (c) 2013 Virtual Open Systems Sarl.
*
* 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 VHOST_BACKEND_H_
#define VHOST_BACKEND_H_
typedef enum VhostBackendType {
VHOST_BACKEND_TYPE_NONE = 0,
VHOST_BACKEND_TYPE_KERNEL = 1,
VHOST_BACKEND_TYPE_USER = 2,
VHOST_BACKEND_TYPE_MAX = 3,
} VhostBackendType;
struct vhost_dev;
typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request,
void *arg);
typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
typedef struct VhostOps {
VhostBackendType backend_type;
vhost_call vhost_call;
vhost_backend_init vhost_backend_init;
vhost_backend_cleanup vhost_backend_cleanup;
} VhostOps;
int vhost_set_backend_type(struct vhost_dev *dev,
VhostBackendType backend_type);
#endif /* VHOST_BACKEND_H_ */

View file

@ -2,6 +2,7 @@
#define VHOST_H
#include "hw/hw.h"
#include "hw/virtio/vhost-backend.h"
#include "hw/virtio/virtio.h"
#include "exec/memory.h"
@ -25,11 +26,11 @@ typedef unsigned long vhost_log_chunk_t;
#define VHOST_LOG_PAGE 0x1000
#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
#define VHOST_INVALID_FEATURE_BIT (0xff)
struct vhost_memory;
struct vhost_dev {
MemoryListener memory_listener;
int control;
struct vhost_memory *mem;
int n_mem_sections;
MemoryRegionSection *mem_sections;
@ -48,10 +49,12 @@ struct vhost_dev {
bool memory_changed;
hwaddr mem_changed_start_addr;
hwaddr mem_changed_end_addr;
const VhostOps *vhost_ops;
void *opaque;
};
int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
bool force);
int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
VhostBackendType backend_type, bool force);
void vhost_dev_cleanup(struct vhost_dev *hdev);
bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
@ -68,4 +71,8 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n);
*/
void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
bool mask);
unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
unsigned features);
void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
unsigned features);
#endif

View file

@ -49,12 +49,14 @@
#define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */
#define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */
#define VIRTIO_NET_F_CTRL_RX_EXTRA 20 /* Extra RX mode control support */
#define VIRTIO_NET_F_GUEST_ANNOUNCE 21 /* Guest can announce itself */
#define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
* Steering */
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */
#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */
#define TX_TIMER_INTERVAL 150000 /* 150 us */
@ -193,6 +195,8 @@ typedef struct VirtIONet {
char *netclient_name;
char *netclient_type;
uint64_t curr_guest_offloads;
QEMUTimer *announce_timer;
int announce_counter;
} VirtIONet;
#define VIRTIO_NET_CTRL_MAC 1
@ -212,6 +216,18 @@ typedef struct VirtIONet {
#define VIRTIO_NET_CTRL_VLAN_ADD 0
#define VIRTIO_NET_CTRL_VLAN_DEL 1
/*
* Control link announce acknowledgement
*
* VIRTIO_NET_S_ANNOUNCE bit in the status field requests link announcement from
* guest driver. The driver is notified by config space change interrupt. The
* command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that the driver has
* received the notification. It makes the device clear the bit
* VIRTIO_NET_S_ANNOUNCE in the status field.
*/
#define VIRTIO_NET_CTRL_ANNOUNCE 3
#define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0
/*
* Control Multiqueue
*
@ -251,6 +267,7 @@ struct virtio_net_ctrl_mq {
DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
DEFINE_PROP_BIT("guest_announce", _state, _field, VIRTIO_NET_F_GUEST_ANNOUNCE, true), \
DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \

View file

@ -752,6 +752,8 @@ extern const VMStateInfo vmstate_info_bitmap;
#define VMSTATE_END_OF_LIST() \
{}
#define SELF_ANNOUNCE_ROUNDS 5
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id);
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
@ -778,4 +780,12 @@ void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev);
void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev);
void vmstate_register_ram_global(struct MemoryRegion *memory);
static inline
int64_t self_announce_delay(int round)
{
assert(round < SELF_ANNOUNCE_ROUNDS && round > 0);
/* delay 50ms, 150ms, 250ms, ... */
return 50 + (SELF_ANNOUNCE_ROUNDS - round - 1) * 100;
}
#endif

View file

@ -51,6 +51,7 @@ typedef enum MonitorEvent {
QEVENT_BLOCK_IMAGE_CORRUPTED,
QEVENT_QUORUM_FAILURE,
QEVENT_QUORUM_REPORT_BAD,
QEVENT_ACPI_OST,
/* Add to 'monitor_event_names' array in monitor.c when
* defining new events here */

17
include/net/vhost-user.h Normal file
View file

@ -0,0 +1,17 @@
/*
* vhost-user.h
*
* Copyright (c) 2013 Virtual Open Systems Sarl.
*
* 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 VHOST_USER_H_
#define VHOST_USER_H_
struct vhost_net;
struct vhost_net *vhost_user_get_vhost_net(NetClientState *nc);
#endif /* VHOST_USER_H_ */

View file

@ -2,11 +2,19 @@
#define VHOST_NET_H
#include "net/net.h"
#include "hw/virtio/vhost-backend.h"
struct vhost_net;
typedef struct vhost_net VHostNetState;
VHostNetState *vhost_net_init(NetClientState *backend, int devfd, bool force);
typedef struct VhostNetOptions {
VhostBackendType backend_type;
NetClientState *net_backend;
void *opaque;
bool force;
} VhostNetOptions;
struct vhost_net *vhost_net_init(VhostNetOptions *options);
bool vhost_net_query(VHostNetState *net, VirtIODevice *dev);
int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, int total_queues);
@ -20,4 +28,5 @@ void vhost_net_ack_features(VHostNetState *net, unsigned features);
bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
int idx, bool mask);
VHostNetState *get_vhost_net(NetClientState *nc);
#endif

View file

@ -116,6 +116,16 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#else
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
#endif
#ifdef MADV_UNMERGEABLE
#define QEMU_MADV_UNMERGEABLE MADV_UNMERGEABLE
#else
#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
#endif
#ifdef MADV_DODUMP
#define QEMU_MADV_DODUMP MADV_DODUMP
#else
#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
#endif
#ifdef MADV_DONTDUMP
#define QEMU_MADV_DONTDUMP MADV_DONTDUMP
#else
@ -133,6 +143,8 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#define QEMU_MADV_DONTNEED POSIX_MADV_DONTNEED
#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
@ -142,6 +154,8 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#define QEMU_MADV_DONTNEED QEMU_MADV_INVALID
#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
#define QEMU_MADV_UNMERGEABLE QEMU_MADV_INVALID
#define QEMU_MADV_DODUMP QEMU_MADV_INVALID
#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
@ -251,4 +265,6 @@ void qemu_init_auxval(char **envp);
void qemu_set_tty_echo(int fd, bool echo);
void os_mem_prealloc(int fd, char *area, size_t sz);
#endif

View file

@ -3,6 +3,7 @@
#include <inttypes.h>
#include <qemu/typedefs.h>
#include "qemu/queue.h"
/*
* Operations on 64 bit address ranges.
@ -60,4 +61,75 @@ static inline int ranges_overlap(uint64_t first1, uint64_t len1,
return !(last2 < first1 || last1 < first2);
}
/* 0,1 can merge with 1,2 but don't overlap */
static inline bool ranges_can_merge(Range *range1, Range *range2)
{
return !(range1->end < range2->begin || range2->end < range1->begin);
}
static inline int range_merge(Range *range1, Range *range2)
{
if (ranges_can_merge(range1, range2)) {
if (range1->end < range2->end) {
range1->end = range2->end;
}
if (range1->begin > range2->begin) {
range1->begin = range2->begin;
}
return 0;
}
return -1;
}
static inline GList *g_list_insert_sorted_merged(GList *list,
gpointer data,
GCompareFunc func)
{
GList *l, *next = NULL;
Range *r, *nextr;
if (!list) {
list = g_list_insert_sorted(list, data, func);
return list;
}
nextr = data;
l = list;
while (l && l != next && nextr) {
r = l->data;
if (ranges_can_merge(r, nextr)) {
range_merge(r, nextr);
l = g_list_remove_link(l, next);
next = g_list_next(l);
if (next) {
nextr = next->data;
} else {
nextr = NULL;
}
} else {
l = g_list_next(l);
}
}
if (!l) {
list = g_list_insert_sorted(list, data, func);
}
return list;
}
static inline gint range_compare(gconstpointer a, gconstpointer b)
{
Range *ra = (Range *)a, *rb = (Range *)b;
if (ra->begin == rb->begin && ra->end == rb->end) {
return 0;
} else if (range_get_last(ra->begin, ra->end) <
range_get_last(rb->begin, rb->end)) {
return -1;
} else {
return 1;
}
}
#endif

View file

@ -916,6 +916,34 @@ void object_property_set_int(Object *obj, int64_t value,
int64_t object_property_get_int(Object *obj, const char *name,
Error **errp);
/**
* object_property_get_enum:
* @obj: the object
* @name: the name of the property
* @strings: strings corresponding to enums
* @errp: returns an error if this function fails
*
* Returns: the value of the property, converted to an integer, or
* undefined if an error occurs (including when the property value is not
* an enum).
*/
int object_property_get_enum(Object *obj, const char *name,
const char *strings[], Error **errp);
/**
* object_property_get_uint16List:
* @obj: the object
* @name: the name of the property
* @list: the returned int list
* @errp: returns an error if this function fails
*
* Returns: the value of the property, converted to integers, or
* undefined if an error occurs (including when the property value is not
* an list of integers).
*/
void object_property_get_uint16List(Object *obj, const char *name,
uint16List **list, Error **errp);
/**
* object_property_set:
* @obj: the object

View file

@ -56,10 +56,13 @@ typedef void IOEventHandler(void *opaque, int event);
struct CharDriverState {
void (*init)(struct CharDriverState *s);
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
int (*chr_sync_read)(struct CharDriverState *s,
const uint8_t *buf, int len);
GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond);
void (*chr_update_read_handler)(struct CharDriverState *s);
int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
int (*get_msgfd)(struct CharDriverState *s);
int (*get_msgfds)(struct CharDriverState *s, int* fds, int num);
int (*set_msgfds)(struct CharDriverState *s, int *fds, int num);
int (*chr_add_client)(struct CharDriverState *chr, int fd);
IOEventHandler *chr_event;
IOCanReadHandler *chr_can_read;
@ -80,6 +83,7 @@ struct CharDriverState {
int avail_connections;
int is_mux;
guint fd_in_tag;
guint fd_hup_tag;
QemuOpts *opts;
QTAILQ_ENTRY(CharDriverState) next;
};
@ -188,6 +192,18 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
*/
int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len);
/**
* @qemu_chr_fe_read_all:
*
* Read data to a buffer from the back end.
*
* @buf the data buffer
* @len the number of bytes to read
*
* Returns: the number of bytes read
*/
int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len);
/**
* @qemu_chr_fe_ioctl:
*
@ -214,6 +230,32 @@ int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
*/
int qemu_chr_fe_get_msgfd(CharDriverState *s);
/**
* @qemu_chr_fe_get_msgfds:
*
* For backends capable of fd passing, return the number of file received
* descriptors and fills the fds array up to num elements
*
* Returns: -1 if fd passing isn't supported or there are no pending file
* descriptors. If file descriptors are returned, subsequent calls to
* this function will return -1 until a client sends a new set of file
* descriptors.
*/
int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num);
/**
* @qemu_chr_fe_set_msgfds:
*
* For backends capable of fd passing, set an array of fds to be passed with
* the next send operation.
* A subsequent call to this function before calling a write function will
* result in overwriting the fd array with the new value without being send.
* Upon writing the message the fd array is freed.
*
* Returns: -1 if fd passing isn't supported.
*/
int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num);
/**
* @qemu_chr_fe_claim:
*

View file

@ -23,7 +23,6 @@ extern int smp_threads;
#define smp_threads 1
#endif
void set_numa_modes(void);
void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
#endif

68
include/sysemu/hostmem.h Normal file
View file

@ -0,0 +1,68 @@
/*
* QEMU Host Memory Backend
*
* Copyright (C) 2013-2014 Red Hat Inc
*
* Authors:
* 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_RAM_H
#define QEMU_RAM_H
#include "sysemu/sysemu.h" /* for MAX_NODES */
#include "qom/object.h"
#include "qapi/error.h"
#include "exec/memory.h"
#include "qemu/option.h"
#include "qemu/bitmap.h"
#define TYPE_MEMORY_BACKEND "memory-backend"
#define MEMORY_BACKEND(obj) \
OBJECT_CHECK(HostMemoryBackend, (obj), TYPE_MEMORY_BACKEND)
#define MEMORY_BACKEND_GET_CLASS(obj) \
OBJECT_GET_CLASS(HostMemoryBackendClass, (obj), TYPE_MEMORY_BACKEND)
#define MEMORY_BACKEND_CLASS(klass) \
OBJECT_CLASS_CHECK(HostMemoryBackendClass, (klass), TYPE_MEMORY_BACKEND)
typedef struct HostMemoryBackend HostMemoryBackend;
typedef struct HostMemoryBackendClass HostMemoryBackendClass;
/**
* HostMemoryBackendClass:
* @parent_class: opaque parent class container
*/
struct HostMemoryBackendClass {
ObjectClass parent_class;
void (*alloc)(HostMemoryBackend *backend, Error **errp);
};
/**
* @HostMemoryBackend
*
* @parent: opaque parent object container
* @size: amount of memory backend provides
* @id: unique identification string in memdev namespace
* @mr: MemoryRegion representing host memory belonging to backend
*/
struct HostMemoryBackend {
/* private */
Object parent;
/* protected */
uint64_t size;
bool merge, dump;
bool prealloc, force_prealloc;
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
HostMemPolicy policy;
MemoryRegion mr;
};
MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend,
Error **errp);
#endif

View file

@ -43,6 +43,7 @@ extern bool kvm_allowed;
extern bool kvm_kernel_irqchip;
extern bool kvm_async_interrupts_allowed;
extern bool kvm_halt_in_kernel_allowed;
extern bool kvm_eventfds_allowed;
extern bool kvm_irqfds_allowed;
extern bool kvm_msi_via_irqfd_allowed;
extern bool kvm_gsi_routing_allowed;
@ -82,6 +83,15 @@ extern bool kvm_readonly_mem_allowed;
*/
#define kvm_halt_in_kernel() (kvm_halt_in_kernel_allowed)
/**
* kvm_eventfds_enabled:
*
* Returns: true if we can use eventfds to receive notifications
* from a KVM CPU (ie the kernel supports eventds and we are running
* with a configuration where it is meaningful to use them).
*/
#define kvm_eventfds_enabled() (kvm_eventfds_allowed)
/**
* kvm_irqfds_enabled:
*
@ -128,6 +138,7 @@ extern bool kvm_readonly_mem_allowed;
#define kvm_irqchip_in_kernel() (false)
#define kvm_async_interrupts_enabled() (false)
#define kvm_halt_in_kernel() (false)
#define kvm_eventfds_enabled() (false)
#define kvm_irqfds_enabled() (false)
#define kvm_msi_via_irqfd_enabled() (false)
#define kvm_gsi_routing_allowed() (false)

View file

@ -89,6 +89,8 @@ static inline void os_setup_post(void) {}
void os_set_line_buffering(void);
static inline void os_set_proc_name(const char *dummy) {}
size_t getpagesize(void);
#if !defined(EPROTONOSUPPORT)
# define EPROTONOSUPPORT EINVAL
#endif

View file

@ -9,6 +9,8 @@
#include "qapi-types.h"
#include "qemu/notify.h"
#include "qemu/main-loop.h"
#include "qemu/bitmap.h"
#include "qom/object.h"
/* vl.c */
@ -131,8 +133,10 @@ extern uint8_t *boot_splash_filedata;
extern size_t boot_splash_filedata_size;
extern uint8_t qemu_extra_params_fw[2];
extern QEMUClockType rtc_clock;
extern const char *mem_path;
extern int mem_prealloc;
#define MAX_NODES 64
#define MAX_NODES 128
/* The following shall be true for all CPUs:
* cpu->cpu_index < max_cpus <= MAX_CPUMASK_BITS
@ -142,8 +146,16 @@ extern QEMUClockType rtc_clock;
#define MAX_CPUMASK_BITS 255
extern int nb_numa_nodes;
extern uint64_t node_mem[MAX_NODES];
extern unsigned long *node_cpumask[MAX_NODES];
typedef struct node_info {
uint64_t node_mem;
DECLARE_BITMAP(node_cpu, MAX_CPUMASK_BITS);
struct HostMemoryBackend *node_memdev;
} NodeInfo;
extern NodeInfo numa_info[MAX_NODES];
void set_numa_nodes(void);
void set_numa_modes(void);
extern QemuOptsList qemu_numa_opts;
int numa_init_func(QemuOpts *opts, void *opaque);
#define MAX_OPTION_ROMS 16
typedef struct QEMUOptionRom {