|
|
9ae3a8 |
From 43d319c65b1a27349fd329cb2f9c6f5c54f32379 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
Message-Id: <43d319c65b1a27349fd329cb2f9c6f5c54f32379.1387298827.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
In-Reply-To: <3ed0fb61a3dc912ef036d7ef450bed192090709e.1387298827.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
References: <3ed0fb61a3dc912ef036d7ef450bed192090709e.1387298827.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
From: "Michael S. Tsirkin" <mst@redhat.com>
|
|
|
9ae3a8 |
Date: Tue, 17 Dec 2013 15:17:22 +0100
|
|
|
9ae3a8 |
Subject: [PATCH 13/56] pci: store PCI hole ranges in guestinfo structure
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Michael S. Tsirkin <mst@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1387293161-4085-14-git-send-email-mst@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 56318
|
|
|
9ae3a8 |
O-Subject: [PATCH qemu-kvm RHEL7.0 v2 13/57] pci: store PCI hole ranges in guestinfo structure
|
|
|
9ae3a8 |
Bugzilla: 1034876
|
|
|
9ae3a8 |
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Marcel Apfelbaum <marcel.a@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Will be used to pass hole ranges to guests.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit 3459a625215449b67b9c67d9151ff72892d0a42a)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Conflicts:
|
|
|
9ae3a8 |
hw/i386/pc_piix.c
|
|
|
9ae3a8 |
hw/i386/pc_q35.c
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
include/hw/i386/pc.h | 19 ++++++++++++++++++-
|
|
|
9ae3a8 |
include/hw/pci-host/q35.h | 2 ++
|
|
|
9ae3a8 |
include/qemu/typedefs.h | 1 +
|
|
|
9ae3a8 |
hw/i386/pc.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
9ae3a8 |
hw/i386/pc_piix.c | 14 +++++++++++++-
|
|
|
9ae3a8 |
hw/i386/pc_q35.c | 6 +++++-
|
|
|
9ae3a8 |
hw/pci-host/q35.c | 8 ++++++++
|
|
|
9ae3a8 |
7 files changed, 92 insertions(+), 4 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Michal Novotny <minovotn@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
hw/i386/pc.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
9ae3a8 |
hw/i386/pc_piix.c | 14 +++++++++++++-
|
|
|
9ae3a8 |
hw/i386/pc_q35.c | 6 +++++-
|
|
|
9ae3a8 |
hw/pci-host/q35.c | 8 ++++++++
|
|
|
9ae3a8 |
include/hw/i386/pc.h | 19 ++++++++++++++++++-
|
|
|
9ae3a8 |
include/hw/pci-host/q35.h | 2 ++
|
|
|
9ae3a8 |
include/qemu/typedefs.h | 1 +
|
|
|
9ae3a8 |
7 files changed, 92 insertions(+), 4 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
|
|
9ae3a8 |
index 2948781..68a8e1b 100644
|
|
|
9ae3a8 |
--- a/hw/i386/pc.c
|
|
|
9ae3a8 |
+++ b/hw/i386/pc.c
|
|
|
9ae3a8 |
@@ -985,6 +985,48 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+typedef struct PcGuestInfoState {
|
|
|
9ae3a8 |
+ PcGuestInfo info;
|
|
|
9ae3a8 |
+ Notifier machine_done;
|
|
|
9ae3a8 |
+} PcGuestInfoState;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+static
|
|
|
9ae3a8 |
+void pc_guest_info_machine_done(Notifier *notifier, void *data)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ PcGuestInfoState *guest_info_state = container_of(notifier,
|
|
|
9ae3a8 |
+ PcGuestInfoState,
|
|
|
9ae3a8 |
+ machine_done);
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
|
|
|
9ae3a8 |
+ ram_addr_t above_4g_mem_size)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
|
|
|
9ae3a8 |
+ PcGuestInfo *guest_info = &guest_info_state->info;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ guest_info->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
|
|
|
9ae3a8 |
+ if (sizeof(hwaddr) == 4) {
|
|
|
9ae3a8 |
+ guest_info->pci_info.w64.begin = 0;
|
|
|
9ae3a8 |
+ guest_info->pci_info.w64.end = 0;
|
|
|
9ae3a8 |
+ } else {
|
|
|
9ae3a8 |
+ /*
|
|
|
9ae3a8 |
+ * BIOS does not set MTRR entries for the 64 bit window, so no need to
|
|
|
9ae3a8 |
+ * align address to power of two. Align address at 1G, this makes sure
|
|
|
9ae3a8 |
+ * it can be exactly covered with a PAT entry even when using huge
|
|
|
9ae3a8 |
+ * pages.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+ guest_info->pci_info.w64.begin =
|
|
|
9ae3a8 |
+ ROUND_UP((0x1ULL << 32) + above_4g_mem_size, 0x1ULL << 30);
|
|
|
9ae3a8 |
+ guest_info->pci_info.w64.end = guest_info->pci_info.w64.begin +
|
|
|
9ae3a8 |
+ (0x1ULL << 62);
|
|
|
9ae3a8 |
+ assert(guest_info->pci_info.w64.begin <= guest_info->pci_info.w64.end);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ guest_info_state->machine_done.notify = pc_guest_info_machine_done;
|
|
|
9ae3a8 |
+ qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
|
|
|
9ae3a8 |
+ return guest_info;
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
void pc_acpi_init(const char *default_dsdt)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
char *filename;
|
|
|
9ae3a8 |
@@ -1026,7 +1068,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
|
|
|
9ae3a8 |
ram_addr_t below_4g_mem_size,
|
|
|
9ae3a8 |
ram_addr_t above_4g_mem_size,
|
|
|
9ae3a8 |
MemoryRegion *rom_memory,
|
|
|
9ae3a8 |
- MemoryRegion **ram_memory)
|
|
|
9ae3a8 |
+ MemoryRegion **ram_memory,
|
|
|
9ae3a8 |
+ PcGuestInfo *guest_info)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
int linux_boot, i;
|
|
|
9ae3a8 |
MemoryRegion *ram, *option_rom_mr;
|
|
|
9ae3a8 |
@@ -1078,6 +1121,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
|
|
|
9ae3a8 |
for (i = 0; i < nb_option_roms; i++) {
|
|
|
9ae3a8 |
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
+ guest_info->fw_cfg = fw_cfg;
|
|
|
9ae3a8 |
return fw_cfg;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
|
|
|
9ae3a8 |
index 07848c1..3a77998 100644
|
|
|
9ae3a8 |
--- a/hw/i386/pc_piix.c
|
|
|
9ae3a8 |
+++ b/hw/i386/pc_piix.c
|
|
|
9ae3a8 |
@@ -87,6 +87,7 @@ static void pc_init1(QEMUMachineInitArgs *args,
|
|
|
9ae3a8 |
MemoryRegion *rom_memory;
|
|
|
9ae3a8 |
DeviceState *icc_bridge;
|
|
|
9ae3a8 |
FWCfgState *fw_cfg = NULL;
|
|
|
9ae3a8 |
+ PcGuestInfo *guest_info;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);
|
|
|
9ae3a8 |
object_property_add_child(qdev_get_machine(), "icc-bridge",
|
|
|
9ae3a8 |
@@ -120,13 +121,24 @@ static void pc_init1(QEMUMachineInitArgs *args,
|
|
|
9ae3a8 |
smbios_set_type1_defaults("Red Hat", "KVM", args->machine->desc);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ /* Set PCI window size the way seabios has always done it. */
|
|
|
9ae3a8 |
+ /* Power of 2 so bios can cover it with a single MTRR */
|
|
|
9ae3a8 |
+ if (ram_size <= 0x80000000)
|
|
|
9ae3a8 |
+ guest_info->pci_info.w32.begin = 0x80000000;
|
|
|
9ae3a8 |
+ else if (ram_size <= 0xc0000000)
|
|
|
9ae3a8 |
+ guest_info->pci_info.w32.begin = 0xc0000000;
|
|
|
9ae3a8 |
+ else
|
|
|
9ae3a8 |
+ guest_info->pci_info.w32.begin = 0xe0000000;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/* allocate ram and load rom/bios */
|
|
|
9ae3a8 |
if (!xen_enabled()) {
|
|
|
9ae3a8 |
fw_cfg = pc_memory_init(system_memory,
|
|
|
9ae3a8 |
args->kernel_filename, args->kernel_cmdline,
|
|
|
9ae3a8 |
args->initrd_filename,
|
|
|
9ae3a8 |
below_4g_mem_size, above_4g_mem_size,
|
|
|
9ae3a8 |
- rom_memory, &ram_memory);
|
|
|
9ae3a8 |
+ rom_memory, &ram_memory, guest_info);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
gsi_state = g_malloc0(sizeof(*gsi_state));
|
|
|
9ae3a8 |
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
|
|
9ae3a8 |
index 8fa6793..9fab93c 100644
|
|
|
9ae3a8 |
--- a/hw/i386/pc_q35.c
|
|
|
9ae3a8 |
+++ b/hw/i386/pc_q35.c
|
|
|
9ae3a8 |
@@ -73,6 +73,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
|
|
|
9ae3a8 |
ICH9LPCState *ich9_lpc;
|
|
|
9ae3a8 |
PCIDevice *ahci;
|
|
|
9ae3a8 |
DeviceState *icc_bridge;
|
|
|
9ae3a8 |
+ PcGuestInfo *guest_info;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);
|
|
|
9ae3a8 |
object_property_add_child(qdev_get_machine(), "icc-bridge",
|
|
|
9ae3a8 |
@@ -106,13 +107,15 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
|
|
|
9ae3a8 |
smbios_set_type1_defaults("Red Hat", "KVM", args->machine->desc);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/* allocate ram and load rom/bios */
|
|
|
9ae3a8 |
if (!xen_enabled()) {
|
|
|
9ae3a8 |
pc_memory_init(get_system_memory(),
|
|
|
9ae3a8 |
args->kernel_filename, args->kernel_cmdline,
|
|
|
9ae3a8 |
args->initrd_filename,
|
|
|
9ae3a8 |
below_4g_mem_size, above_4g_mem_size,
|
|
|
9ae3a8 |
- rom_memory, &ram_memory);
|
|
|
9ae3a8 |
+ rom_memory, &ram_memory, guest_info);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* irq lines */
|
|
|
9ae3a8 |
@@ -134,6 +137,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
|
|
|
9ae3a8 |
q35_host->mch.address_space_io = get_system_io();
|
|
|
9ae3a8 |
q35_host->mch.below_4g_mem_size = below_4g_mem_size;
|
|
|
9ae3a8 |
q35_host->mch.above_4g_mem_size = above_4g_mem_size;
|
|
|
9ae3a8 |
+ q35_host->mch.guest_info = guest_info;
|
|
|
9ae3a8 |
/* pci */
|
|
|
9ae3a8 |
qdev_init_nofail(DEVICE(q35_host));
|
|
|
9ae3a8 |
host_bus = q35_host->host.pci.bus;
|
|
|
9ae3a8 |
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
|
|
|
9ae3a8 |
index ed934c3..0989fc5 100644
|
|
|
9ae3a8 |
--- a/hw/pci-host/q35.c
|
|
|
9ae3a8 |
+++ b/hw/pci-host/q35.c
|
|
|
9ae3a8 |
@@ -245,6 +245,14 @@ static int mch_init(PCIDevice *d)
|
|
|
9ae3a8 |
hwaddr pci_hole64_size;
|
|
|
9ae3a8 |
MCHPCIState *mch = MCH_PCI_DEVICE(d);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ /* Leave enough space for the biggest MCFG BAR */
|
|
|
9ae3a8 |
+ /* TODO: this matches current bios behaviour, but
|
|
|
9ae3a8 |
+ * it's not a power of two, which means an MTRR
|
|
|
9ae3a8 |
+ * can't cover it exactly.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+ mch->guest_info->pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT +
|
|
|
9ae3a8 |
+ MCH_HOST_BRIDGE_PCIEXBAR_MAX;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/* setup pci memory regions */
|
|
|
9ae3a8 |
memory_region_init_alias(&mch->pci_hole, "pci-hole",
|
|
|
9ae3a8 |
mch->pci_address_space,
|
|
|
9ae3a8 |
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
|
|
9ae3a8 |
index 2cf7baa..2518db6 100644
|
|
|
9ae3a8 |
--- a/include/hw/i386/pc.h
|
|
|
9ae3a8 |
+++ b/include/hw/i386/pc.h
|
|
|
9ae3a8 |
@@ -10,8 +10,20 @@
|
|
|
9ae3a8 |
#include "exec/memory.h"
|
|
|
9ae3a8 |
#include "hw/i386/ioapic.h"
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+#include "qemu/range.h"
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/* PC-style peripherals (also used by other machines). */
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+typedef struct PcPciInfo {
|
|
|
9ae3a8 |
+ Range w32;
|
|
|
9ae3a8 |
+ Range w64;
|
|
|
9ae3a8 |
+} PcPciInfo;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+struct PcGuestInfo {
|
|
|
9ae3a8 |
+ PcPciInfo pci_info;
|
|
|
9ae3a8 |
+ FWCfgState *fw_cfg;
|
|
|
9ae3a8 |
+};
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/* parallel.c */
|
|
|
9ae3a8 |
static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
@@ -84,6 +96,10 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
|
|
|
9ae3a8 |
void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge);
|
|
|
9ae3a8 |
void pc_hot_add_cpu(const int64_t id, Error **errp);
|
|
|
9ae3a8 |
void pc_acpi_init(const char *default_dsdt);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
|
|
|
9ae3a8 |
+ ram_addr_t above_4g_mem_size);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
FWCfgState *pc_memory_init(MemoryRegion *system_memory,
|
|
|
9ae3a8 |
const char *kernel_filename,
|
|
|
9ae3a8 |
const char *kernel_cmdline,
|
|
|
9ae3a8 |
@@ -91,7 +107,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
|
|
|
9ae3a8 |
ram_addr_t below_4g_mem_size,
|
|
|
9ae3a8 |
ram_addr_t above_4g_mem_size,
|
|
|
9ae3a8 |
MemoryRegion *rom_memory,
|
|
|
9ae3a8 |
- MemoryRegion **ram_memory);
|
|
|
9ae3a8 |
+ MemoryRegion **ram_memory,
|
|
|
9ae3a8 |
+ PcGuestInfo *guest_info);
|
|
|
9ae3a8 |
qemu_irq *pc_allocate_cpu_irq(void);
|
|
|
9ae3a8 |
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
|
|
|
9ae3a8 |
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
|
|
|
9ae3a8 |
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
|
|
|
9ae3a8 |
index e182c82..b083831 100644
|
|
|
9ae3a8 |
--- a/include/hw/pci-host/q35.h
|
|
|
9ae3a8 |
+++ b/include/hw/pci-host/q35.h
|
|
|
9ae3a8 |
@@ -55,6 +55,7 @@ typedef struct MCHPCIState {
|
|
|
9ae3a8 |
uint8_t smm_enabled;
|
|
|
9ae3a8 |
ram_addr_t below_4g_mem_size;
|
|
|
9ae3a8 |
ram_addr_t above_4g_mem_size;
|
|
|
9ae3a8 |
+ PcGuestInfo *guest_info;
|
|
|
9ae3a8 |
} MCHPCIState;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
typedef struct Q35PCIHost {
|
|
|
9ae3a8 |
@@ -81,6 +82,7 @@ typedef struct Q35PCIHost {
|
|
|
9ae3a8 |
#define MCH_HOST_BRIDGE_PCIEXBAR 0x60 /* 64bit register */
|
|
|
9ae3a8 |
#define MCH_HOST_BRIDGE_PCIEXBAR_SIZE 8 /* 64bit register */
|
|
|
9ae3a8 |
#define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT 0xb0000000
|
|
|
9ae3a8 |
+#define MCH_HOST_BRIDGE_PCIEXBAR_MAX (0x10000000) /* 256M */
|
|
|
9ae3a8 |
#define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK Q35_MASK(64, 35, 28)
|
|
|
9ae3a8 |
#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 26))
|
|
|
9ae3a8 |
#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 25))
|
|
|
9ae3a8 |
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
|
|
|
9ae3a8 |
index a332d88..70d250f 100644
|
|
|
9ae3a8 |
--- a/include/qemu/typedefs.h
|
|
|
9ae3a8 |
+++ b/include/qemu/typedefs.h
|
|
|
9ae3a8 |
@@ -64,6 +64,7 @@ typedef struct VirtIODevice VirtIODevice;
|
|
|
9ae3a8 |
typedef struct QEMUSGList QEMUSGList;
|
|
|
9ae3a8 |
typedef struct SHPCDevice SHPCDevice;
|
|
|
9ae3a8 |
typedef struct FWCfgState FWCfgState;
|
|
|
9ae3a8 |
+typedef struct PcGuestInfo PcGuestInfo;
|
|
|
9ae3a8 |
typedef struct Range Range;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#endif /* QEMU_TYPEDEFS_H */
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.11.7
|
|
|
9ae3a8 |
|