提交 3046c984 编写于 作者: A Anthony Liguori

Merge remote-tracking branch 'agraf/xen-next' into staging

...@@ -3295,10 +3295,12 @@ case "$target_arch2" in ...@@ -3295,10 +3295,12 @@ case "$target_arch2" in
if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
target_phys_bits=64 target_phys_bits=64
echo "CONFIG_XEN=y" >> $config_target_mak echo "CONFIG_XEN=y" >> $config_target_mak
if test "$cpu" = "i386" -o "$cpu" = "x86_64"; then else
echo "CONFIG_XEN_MAPCACHE=y" >> $config_target_mak echo "CONFIG_NO_XEN=y" >> $config_target_mak
fi
fi fi
;;
*)
echo "CONFIG_NO_XEN=y" >> $config_target_mak
esac esac
case "$target_arch2" in case "$target_arch2" in
i386|x86_64|ppcemb|ppc|ppc64|s390x) i386|x86_64|ppcemb|ppc|ppc64|s390x)
......
...@@ -23,7 +23,15 @@ enum device_endian { ...@@ -23,7 +23,15 @@ enum device_endian {
}; };
/* address in the RAM (different from a physical address) */ /* address in the RAM (different from a physical address) */
#if defined(CONFIG_XEN_BACKEND) && TARGET_PHYS_ADDR_BITS == 64
typedef uint64_t ram_addr_t;
# define RAM_ADDR_MAX UINT64_MAX
# define RAM_ADDR_FMT "%" PRIx64
#else
typedef unsigned long ram_addr_t; typedef unsigned long ram_addr_t;
# define RAM_ADDR_MAX ULONG_MAX
# define RAM_ADDR_FMT "%lx"
#endif
/* memory API */ /* memory API */
......
...@@ -2870,13 +2870,13 @@ static void *file_ram_alloc(RAMBlock *block, ...@@ -2870,13 +2870,13 @@ static void *file_ram_alloc(RAMBlock *block,
static ram_addr_t find_ram_offset(ram_addr_t size) static ram_addr_t find_ram_offset(ram_addr_t size)
{ {
RAMBlock *block, *next_block; RAMBlock *block, *next_block;
ram_addr_t offset = 0, mingap = ULONG_MAX; ram_addr_t offset = 0, mingap = RAM_ADDR_MAX;
if (QLIST_EMPTY(&ram_list.blocks)) if (QLIST_EMPTY(&ram_list.blocks))
return 0; return 0;
QLIST_FOREACH(block, &ram_list.blocks, next) { QLIST_FOREACH(block, &ram_list.blocks, next) {
ram_addr_t end, next = ULONG_MAX; ram_addr_t end, next = RAM_ADDR_MAX;
end = block->offset + block->length; end = block->offset + block->length;
...@@ -3088,7 +3088,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) ...@@ -3088,7 +3088,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
#endif #endif
} }
if (area != vaddr) { if (area != vaddr) {
fprintf(stderr, "Could not remap addr: %lx@%lx\n", fprintf(stderr, "Could not remap addr: "
RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n",
length, addr); length, addr);
exit(1); exit(1);
} }
...@@ -3877,7 +3878,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, ...@@ -3877,7 +3878,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
uint8_t *ptr; uint8_t *ptr;
uint32_t val; uint32_t val;
target_phys_addr_t page; target_phys_addr_t page;
unsigned long pd; ram_addr_t pd;
PhysPageDesc *p; PhysPageDesc *p;
while (len > 0) { while (len > 0) {
...@@ -3917,7 +3918,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, ...@@ -3917,7 +3918,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
l = 1; l = 1;
} }
} else { } else {
unsigned long addr1; ram_addr_t addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */ /* RAM case */
ptr = qemu_get_ram_ptr(addr1); ptr = qemu_get_ram_ptr(addr1);
...@@ -4071,7 +4072,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, ...@@ -4071,7 +4072,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
target_phys_addr_t page; target_phys_addr_t page;
unsigned long pd; unsigned long pd;
PhysPageDesc *p; PhysPageDesc *p;
ram_addr_t raddr = ULONG_MAX; ram_addr_t raddr = RAM_ADDR_MAX;
ram_addr_t rlen; ram_addr_t rlen;
void *ret; void *ret;
......
...@@ -13,6 +13,7 @@ ISADevice *isa_ide_init(int iobase, int iobase2, int isairq, ...@@ -13,6 +13,7 @@ ISADevice *isa_ide_init(int iobase, int iobase2, int isairq,
/* ide-pci.c */ /* ide-pci.c */
void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
int secondary_ide_enabled); int secondary_ide_enabled);
PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
......
...@@ -149,6 +149,42 @@ static int pci_piix_ide_initfn(PCIDevice *dev) ...@@ -149,6 +149,42 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
return 0; return 0;
} }
static int pci_piix3_xen_ide_unplug(DeviceState *dev)
{
PCIDevice *pci_dev;
PCIIDEState *pci_ide;
DriveInfo *di;
int i = 0;
pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
pci_ide = DO_UPCAST(PCIIDEState, dev, pci_dev);
for (; i < 3; i++) {
di = drive_get_by_index(IF_IDE, i);
if (di != NULL && di->bdrv != NULL && !di->bdrv->removable) {
DeviceState *ds = bdrv_get_attached(di->bdrv);
if (ds) {
bdrv_detach(di->bdrv, ds);
}
bdrv_close(di->bdrv);
pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
drive_put_ref(di);
}
}
qdev_reset_all(&(pci_ide->dev.qdev));
return 0;
}
PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
{
PCIDevice *dev;
dev = pci_create_simple(bus, devfn, "piix3-ide-xen");
dev->qdev.info->unplug = pci_piix3_xen_ide_unplug;
pci_ide_create_devs(dev, hd_table);
return dev;
}
/* hd_table must contain 4 block drivers */ /* hd_table must contain 4 block drivers */
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
...@@ -181,6 +217,14 @@ static PCIDeviceInfo piix_ide_info[] = { ...@@ -181,6 +217,14 @@ static PCIDeviceInfo piix_ide_info[] = {
.vendor_id = PCI_VENDOR_ID_INTEL, .vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371SB_1, .device_id = PCI_DEVICE_ID_INTEL_82371SB_1,
.class_id = PCI_CLASS_STORAGE_IDE, .class_id = PCI_CLASS_STORAGE_IDE,
},{
.qdev.name = "piix3-ide-xen",
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.init = pci_piix_ide_initfn,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371SB_1,
.class_id = PCI_CLASS_STORAGE_IDE,
},{ },{
.qdev.name = "piix4-ide", .qdev.name = "piix4-ide",
.qdev.size = sizeof(PCIIDEState), .qdev.size = sizeof(PCIIDEState),
......
...@@ -160,7 +160,11 @@ static void pc_init1(MemoryRegion *system_memory, ...@@ -160,7 +160,11 @@ static void pc_init1(MemoryRegion *system_memory,
ide_drive_get(hd, MAX_IDE_BUS); ide_drive_get(hd, MAX_IDE_BUS);
if (pci_enabled) { if (pci_enabled) {
PCIDevice *dev; PCIDevice *dev;
dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); if (xen_enabled()) {
dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);
} else {
dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
}
idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
} else { } else {
......
...@@ -24,7 +24,7 @@ extern int xen_allowed; ...@@ -24,7 +24,7 @@ extern int xen_allowed;
static inline int xen_enabled(void) static inline int xen_enabled(void)
{ {
#ifdef CONFIG_XEN #if defined(CONFIG_XEN_BACKEND) && !defined(CONFIG_NO_XEN)
return xen_allowed; return xen_allowed;
#else #else
return 0; return 0;
......
...@@ -76,6 +76,35 @@ static void log_writeb(PCIXenPlatformState *s, char val) ...@@ -76,6 +76,35 @@ static void log_writeb(PCIXenPlatformState *s, char val)
} }
/* Xen Platform, Fixed IOPort */ /* Xen Platform, Fixed IOPort */
#define UNPLUG_ALL_IDE_DISKS 1
#define UNPLUG_ALL_NICS 2
#define UNPLUG_AUX_IDE_DISKS 4
static void unplug_nic(PCIBus *b, PCIDevice *d)
{
if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
PCI_CLASS_NETWORK_ETHERNET) {
qdev_unplug(&(d->qdev));
}
}
static void pci_unplug_nics(PCIBus *bus)
{
pci_for_each_device(bus, 0, unplug_nic);
}
static void unplug_disks(PCIBus *b, PCIDevice *d)
{
if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
PCI_CLASS_STORAGE_IDE) {
qdev_unplug(&(d->qdev));
}
}
static void pci_unplug_disks(PCIBus *bus)
{
pci_for_each_device(bus, 0, unplug_disks);
}
static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val) static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
{ {
...@@ -83,10 +112,22 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v ...@@ -83,10 +112,22 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
switch (addr - XEN_PLATFORM_IOPORT) { switch (addr - XEN_PLATFORM_IOPORT) {
case 0: case 0:
/* TODO: */
/* Unplug devices. Value is a bitmask of which devices to /* Unplug devices. Value is a bitmask of which devices to
unplug, with bit 0 the IDE devices, bit 1 the network unplug, with bit 0 the IDE devices, bit 1 the network
devices, and bit 2 the non-primary-master IDE devices. */ devices, and bit 2 the non-primary-master IDE devices. */
if (val & UNPLUG_ALL_IDE_DISKS) {
DPRINTF("unplug disks\n");
qemu_aio_flush();
bdrv_flush_all();
pci_unplug_disks(s->pci_dev.bus);
}
if (val & UNPLUG_ALL_NICS) {
DPRINTF("unplug nics\n");
pci_unplug_nics(s->pci_dev.bus);
}
if (val & UNPLUG_AUX_IDE_DISKS) {
DPRINTF("unplug auxiliary disks not supported\n");
}
break; break;
case 2: case 2:
switch (val) { switch (val) {
......
...@@ -2454,11 +2454,6 @@ int main(int argc, char **argv, char **envp) ...@@ -2454,11 +2454,6 @@ int main(int argc, char **argv, char **envp)
exit(1); exit(1);
} }
/* On 32-bit hosts, QEMU is limited by virtual address space */
if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
exit(1);
}
if (value != (uint64_t)(ram_addr_t)value) { if (value != (uint64_t)(ram_addr_t)value) {
fprintf(stderr, "qemu: ram size too large\n"); fprintf(stderr, "qemu: ram size too large\n");
exit(1); exit(1);
...@@ -3116,8 +3111,17 @@ int main(int argc, char **argv, char **envp) ...@@ -3116,8 +3111,17 @@ int main(int argc, char **argv, char **envp)
exit(1); exit(1);
/* init the memory */ /* init the memory */
if (ram_size == 0) if (ram_size == 0) {
ram_size = DEFAULT_RAM_SIZE * 1024 * 1024; ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
}
if (!xen_enabled()) {
/* On 32-bit hosts, QEMU is limited by virtual address space */
if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
exit(1);
}
}
/* init the dynamic translator */ /* init the dynamic translator */
cpu_exec_init_all(tb_size * 1024 * 1024); cpu_exec_init_all(tb_size * 1024 * 1024);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <xen/hvm/ioreq.h> #include <xen/hvm/ioreq.h>
#include <xen/hvm/params.h> #include <xen/hvm/params.h>
#include <xen/hvm/e820.h>
//#define DEBUG_XEN //#define DEBUG_XEN
...@@ -144,6 +145,12 @@ static void xen_ram_init(ram_addr_t ram_size) ...@@ -144,6 +145,12 @@ static void xen_ram_init(ram_addr_t ram_size)
new_block->host = NULL; new_block->host = NULL;
new_block->offset = 0; new_block->offset = 0;
new_block->length = ram_size; new_block->length = ram_size;
if (ram_size >= HVM_BELOW_4G_RAM_END) {
/* Xen does not allocate the memory continuously, and keep a hole at
* HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH
*/
new_block->length += HVM_BELOW_4G_MMIO_LENGTH;
}
QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
...@@ -152,20 +159,26 @@ static void xen_ram_init(ram_addr_t ram_size) ...@@ -152,20 +159,26 @@ static void xen_ram_init(ram_addr_t ram_size)
memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS), memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
0xff, new_block->length >> TARGET_PAGE_BITS); 0xff, new_block->length >> TARGET_PAGE_BITS);
if (ram_size >= 0xe0000000 ) { if (ram_size >= HVM_BELOW_4G_RAM_END) {
above_4g_mem_size = ram_size - 0xe0000000; above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END;
below_4g_mem_size = 0xe0000000; below_4g_mem_size = HVM_BELOW_4G_RAM_END;
} else { } else {
below_4g_mem_size = ram_size; below_4g_mem_size = ram_size;
} }
cpu_register_physical_memory(0, below_4g_mem_size, new_block->offset); cpu_register_physical_memory(0, 0xa0000, 0);
#if TARGET_PHYS_ADDR_BITS > 32 /* Skip of the VGA IO memory space, it will be registered later by the VGA
* emulated device.
*
* The area between 0xc0000 and 0x100000 will be used by SeaBIOS to load
* the Options ROM, so it is registered here as RAM.
*/
cpu_register_physical_memory(0xc0000, below_4g_mem_size - 0xc0000,
0xc0000);
if (above_4g_mem_size > 0) { if (above_4g_mem_size > 0) {
cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size, cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
new_block->offset + below_4g_mem_size); 0x100000000ULL);
} }
#endif
} }
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
...@@ -184,7 +197,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) ...@@ -184,7 +197,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
} }
if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) { if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
hw_error("xen: failed to populate ram at %lx", ram_addr); hw_error("xen: failed to populate ram at " RAM_ADDR_FMT, ram_addr);
} }
qemu_free(pfn_list); qemu_free(pfn_list);
...@@ -797,12 +810,17 @@ void xenstore_store_pv_console_info(int i, CharDriverState *chr) ...@@ -797,12 +810,17 @@ void xenstore_store_pv_console_info(int i, CharDriverState *chr)
} }
} }
static void xenstore_record_dm_state(XenIOState *s, const char *state) static void xenstore_record_dm_state(struct xs_handle *xs, const char *state)
{ {
char path[50]; char path[50];
if (xs == NULL) {
fprintf(stderr, "xenstore connection not initialized\n");
exit(1);
}
snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", xen_domid); snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", xen_domid);
if (!xs_write(s->xenstore, XBT_NULL, path, state, strlen(state))) { if (!xs_write(xs, XBT_NULL, path, state, strlen(state))) {
fprintf(stderr, "error recording dm state\n"); fprintf(stderr, "error recording dm state\n");
exit(1); exit(1);
} }
...@@ -823,15 +841,20 @@ static void xen_main_loop_prepare(XenIOState *state) ...@@ -823,15 +841,20 @@ static void xen_main_loop_prepare(XenIOState *state)
if (evtchn_fd != -1) { if (evtchn_fd != -1) {
qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state); qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
} }
/* record state running */
xenstore_record_dm_state(state, "running");
} }
/* Initialise Xen */ /* Initialise Xen */
static void xen_vm_change_state_handler(void *opaque, int running, int reason) static void xen_change_state_handler(void *opaque, int running, int reason)
{
if (running) {
/* record state running */
xenstore_record_dm_state(xenstore, "running");
}
}
static void xen_hvm_change_state_handler(void *opaque, int running, int reason)
{ {
XenIOState *state = opaque; XenIOState *state = opaque;
if (running) { if (running) {
...@@ -854,6 +877,7 @@ int xen_init(void) ...@@ -854,6 +877,7 @@ int xen_init(void)
xen_be_printf(NULL, 0, "can't open xen interface\n"); xen_be_printf(NULL, 0, "can't open xen interface\n");
return -1; return -1;
} }
qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
return 0; return 0;
} }
...@@ -915,7 +939,7 @@ int xen_hvm_init(void) ...@@ -915,7 +939,7 @@ int xen_hvm_init(void)
xen_map_cache_init(); xen_map_cache_init();
xen_ram_init(ram_size); xen_ram_init(ram_size);
qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state); qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
state->client = xen_cpu_phys_memory_client; state->client = xen_cpu_phys_memory_client;
QLIST_INIT(&state->physmap); QLIST_INIT(&state->physmap);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册