Merge remote-tracking branch 'remotes/sstabellini/xen-20140801' into staging

* remotes/sstabellini/xen-20140801:
  qemu: support xen hvm direct kernel boot
  tap-bsd: implement a FreeBSD only version of tap_open
  xen: fix usage of ENODATA

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-08-04 11:17:24 +01:00
commit 7b13ff3f15
6 changed files with 112 additions and 3 deletions

View file

@ -1190,6 +1190,31 @@ void pc_acpi_init(const char *default_dsdt)
}
}
FWCfgState *xen_load_linux(const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
ram_addr_t below_4g_mem_size,
PcGuestInfo *guest_info)
{
int i;
FWCfgState *fw_cfg;
assert(kernel_filename != NULL);
fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
rom_set_fw(fw_cfg);
load_linux(fw_cfg, kernel_filename, initrd_filename,
kernel_cmdline, below_4g_mem_size);
for (i = 0; i < nb_option_roms; i++) {
assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
!strcmp(option_rom[i].name, "multiboot.bin"));
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
}
guest_info->fw_cfg = fw_cfg;
return fw_cfg;
}
FWCfgState *pc_memory_init(MachineState *machine,
MemoryRegion *system_memory,
ram_addr_t below_4g_mem_size,

View file

@ -182,6 +182,13 @@ static void pc_init1(MachineState *machine,
fw_cfg = pc_memory_init(machine, system_memory,
below_4g_mem_size, above_4g_mem_size,
rom_memory, &ram_memory, guest_info);
} else if (machine->kernel_filename != NULL) {
/* For xen HVM direct kernel boot, load linux here */
fw_cfg = xen_load_linux(machine->kernel_filename,
machine->kernel_cmdline,
machine->initrd_filename,
below_4g_mem_size,
guest_info);
}
gsi_state = g_malloc0(sizeof(*gsi_state));

View file

@ -40,6 +40,7 @@ static void xen_apic_realize(DeviceState *dev, Error **errp)
{
APICCommonState *s = APIC_COMMON(dev);
s->vapic_control = 0;
memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s,
"xen-apic-msi", APIC_SPACE_SIZE);

View file

@ -188,6 +188,11 @@ 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 *xen_load_linux(const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
ram_addr_t below_4g_mem_size,
PcGuestInfo *guest_info);
FWCfgState *pc_memory_init(MachineState *machine,
MemoryRegion *system_memory,
ram_addr_t below_4g_mem_size,

View file

@ -27,12 +27,13 @@
#include "sysemu/sysemu.h"
#include "qemu/error-report.h"
#ifdef __NetBSD__
#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_tap.h>
#endif
#ifndef __FreeBSD__
int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
int vnet_hdr_required, int mq_required)
{
@ -108,6 +109,73 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
return fd;
}
#else /* __FreeBSD__ */
#define PATH_NET_TAP "/dev/tap"
int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
int vnet_hdr_required, int mq_required)
{
int fd, s, ret;
struct ifreq ifr;
TFR(fd = open(PATH_NET_TAP, O_RDWR));
if (fd < 0) {
error_report("could not open %s: %s", PATH_NET_TAP, strerror(errno));
return -1;
}
memset(&ifr, 0, sizeof(ifr));
ret = ioctl(fd, TAPGIFNAME, (void *)&ifr);
if (ret < 0) {
error_report("could not get tap interface name");
goto error;
}
if (ifname[0] != '\0') {
/* User requested the interface to have a specific name */
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (s < 0) {
error_report("could not open socket to set interface name");
goto error;
}
ifr.ifr_data = ifname;
ret = ioctl(s, SIOCSIFNAME, (void *)&ifr);
close(s);
if (ret < 0) {
error_report("could not set tap interface name");
goto error;
}
} else {
pstrcpy(ifname, ifname_size, ifr.ifr_name);
}
if (*vnet_hdr) {
/* BSD doesn't have IFF_VNET_HDR */
*vnet_hdr = 0;
if (vnet_hdr_required && !*vnet_hdr) {
error_report("vnet_hdr=1 requested, but no kernel "
"support for IFF_VNET_HDR available");
goto error;
}
}
if (mq_required) {
error_report("mq_required requested, but not kernel support"
"for IFF_MULTI_QUEUE available");
goto error;
}
fcntl(fd, F_SETFL, O_NONBLOCK);
return fd;
error:
close(fd);
return -1;
}
#endif /* __FreeBSD__ */
int tap_set_sndbuf(int fd, const NetdevTapOptions *tap)
{
return 0;

View file

@ -513,11 +513,14 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
start_addr >> TARGET_PAGE_BITS, npages,
bitmap);
if (rc < 0) {
if (rc != -ENODATA) {
#ifndef ENODATA
#define ENODATA ENOENT
#endif
if (errno == ENODATA) {
memory_region_set_dirty(framebuffer, 0, size);
DPRINTF("xen: track_dirty_vram failed (0x" TARGET_FMT_plx
", 0x" TARGET_FMT_plx "): %s\n",
start_addr, start_addr + size, strerror(-rc));
start_addr, start_addr + size, strerror(errno));
}
return;
}