summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell2017-08-02 10:49:02 +0200
committerPeter Maydell2017-08-02 10:49:02 +0200
commitd3d183a638d6a3ead515618a6547b3f80d39fcb9 (patch)
tree1321968e685e92cc2a0ba4bbb6032d93b9972658 /hw
parentMerge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (diff)
parentpc: acpi: force FADT rev1 for 440fx based machine types (diff)
downloadqemu-d3d183a638d6a3ead515618a6547b3f80d39fcb9.tar.gz
qemu-d3d183a638d6a3ead515618a6547b3f80d39fcb9.tar.xz
qemu-d3d183a638d6a3ead515618a6547b3f80d39fcb9.zip
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc, acpi, virtio: fixes, test speedup for rc1 Some fixes all over the place. Notably vhost-user gained a new message to set endian-ness. Borderline for 2.10 but seems to be the only way to fix legacy guests. Also pc tests are run on kvm now. Not a fix at all but doesn't touch qemu itself, so I merged it since I had to run these a lot and I just got tired of waiting for these to finish. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Tue 01 Aug 2017 22:36:47 BST # gpg: using RSA key 0x281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: pc: acpi: force FADT rev1 for 440fx based machine types pc: make 'pc.rom' readonly when machine has PCI enabled vhost-user: fix watcher need be removed when vhost-user hotplug tests/bios-tables-test: Compiler warning fix accel: cleanup error output intel_iommu: use access_flags for iotlb intel_iommu: fix iova for pt vhost-user: fix legacy cross-endian configurations vhost: fix a memory leak tests: switch pxe and vm gen id tests to use kvm Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/i386/acpi-build.c22
-rw-r--r--hw/i386/intel_iommu.c19
-rw-r--r--hw/i386/intel_iommu_internal.h1
-rw-r--r--hw/i386/pc.c3
-rw-r--r--hw/virtio/vhost-backend.c2
-rw-r--r--hw/virtio/vhost-user.c23
6 files changed, 53 insertions, 17 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 6b7bade183..b9c245c9bb 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -90,6 +90,7 @@ typedef struct AcpiMcfgInfo {
} AcpiMcfgInfo;
typedef struct AcpiPmInfo {
+ bool force_rev1_fadt;
bool s3_disabled;
bool s4_disabled;
bool pcihp_bridge_en;
@@ -129,10 +130,13 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
Object *obj = NULL;
QObject *o;
+ pm->force_rev1_fadt = false;
pm->cpu_hp_io_base = 0;
pm->pcihp_io_base = 0;
pm->pcihp_io_len = 0;
if (piix) {
+ /* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
+ pm->force_rev1_fadt = true;
obj = piix;
pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
pm->pcihp_io_base =
@@ -304,6 +308,9 @@ static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, AcpiPmInfo *pm)
fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
}
fadt->century = RTC_CENTURY;
+ if (pm->force_rev1_fadt) {
+ return;
+ }
fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_RESET_REG_SUP);
fadt->reset_value = 0xf;
@@ -342,6 +349,8 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
+ int fadt_size = sizeof(*fadt);
+ int rev = 3;
/* FACS address to be filled by Guest linker */
bios_linker_loader_add_pointer(linker,
@@ -353,12 +362,17 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
bios_linker_loader_add_pointer(linker,
ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
- bios_linker_loader_add_pointer(linker,
- ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
- ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+ if (pm->force_rev1_fadt) {
+ rev = 1;
+ fadt_size = offsetof(typeof(*fadt), reset_register);
+ } else {
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
+ ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+ }
build_header(linker, table_data,
- (void *)fadt, "FACP", sizeof(*fadt), 3, oem_id, oem_table_id);
+ (void *)fadt, "FACP", fadt_size, rev, oem_id, oem_table_id);
}
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index e398746b4b..a7bf87a19e 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -237,8 +237,7 @@ out:
static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
uint16_t domain_id, hwaddr addr, uint64_t slpte,
- bool read_flags, bool write_flags,
- uint32_t level)
+ uint8_t access_flags, uint32_t level)
{
VTDIOTLBEntry *entry = g_malloc(sizeof(*entry));
uint64_t *key = g_malloc(sizeof(*key));
@@ -253,8 +252,7 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id,
entry->gfn = gfn;
entry->domain_id = domain_id;
entry->slpte = slpte;
- entry->read_flags = read_flags;
- entry->write_flags = write_flags;
+ entry->access_flags = access_flags;
entry->mask = vtd_slpt_level_page_mask(level);
*key = vtd_get_iotlb_key(gfn, source_id, level);
g_hash_table_replace(s->iotlb, key, entry);
@@ -1087,6 +1085,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
bool is_fpd_set = false;
bool reads = true;
bool writes = true;
+ uint8_t access_flags;
VTDIOTLBEntry *iotlb_entry;
/*
@@ -1101,8 +1100,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte,
iotlb_entry->domain_id);
slpte = iotlb_entry->slpte;
- reads = iotlb_entry->read_flags;
- writes = iotlb_entry->write_flags;
+ access_flags = iotlb_entry->access_flags;
page_mask = iotlb_entry->mask;
goto out;
}
@@ -1139,9 +1137,9 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
* Also, let's ignore IOTLB caching as well for PT devices.
*/
if (vtd_ce_get_type(&ce) == VTD_CONTEXT_TT_PASS_THROUGH) {
- entry->iova = addr & VTD_PAGE_MASK;
+ entry->iova = addr & VTD_PAGE_MASK_4K;
entry->translated_addr = entry->iova;
- entry->addr_mask = VTD_PAGE_MASK;
+ entry->addr_mask = ~VTD_PAGE_MASK_4K;
entry->perm = IOMMU_RW;
trace_vtd_translate_pt(source_id, entry->iova);
@@ -1172,13 +1170,14 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
}
page_mask = vtd_slpt_level_page_mask(level);
+ access_flags = IOMMU_ACCESS_FLAG(reads, writes);
vtd_update_iotlb(s, source_id, VTD_CONTEXT_ENTRY_DID(ce.hi), addr, slpte,
- reads, writes, level);
+ access_flags, level);
out:
entry->iova = addr & page_mask;
entry->translated_addr = vtd_get_slpte_addr(slpte) & page_mask;
entry->addr_mask = ~page_mask;
- entry->perm = IOMMU_ACCESS_FLAG(reads, writes);
+ entry->perm = access_flags;
return true;
error:
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index f50ecd8b73..0e73a65bf2 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -384,7 +384,6 @@ typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo;
/* Pagesize of VTD paging structures, including root and context tables */
#define VTD_PAGE_SHIFT 12
#define VTD_PAGE_SIZE (1ULL << VTD_PAGE_SHIFT)
-#define VTD_PAGE_MASK (VTD_PAGE_SIZE - 1)
#define VTD_PAGE_SHIFT_4K 12
#define VTD_PAGE_MASK_4K (~((1ULL << VTD_PAGE_SHIFT_4K) - 1))
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 22e16031b0..59435390ba 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1443,6 +1443,9 @@ void pc_memory_init(PCMachineState *pcms,
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
&error_fatal);
+ if (pcmc->pci_enabled) {
+ memory_region_set_readonly(option_rom_mr, true);
+ }
memory_region_add_subregion_overlap(rom_memory,
PC_ROM_MIN_VGA,
option_rom_mr,
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index cb055e8f21..7f09efab8b 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -52,11 +52,13 @@ static int vhost_kernel_memslots_limit(struct vhost_dev *dev)
&s, NULL, NULL)) {
uint64_t val = g_ascii_strtoull(s, NULL, 10);
if (!((val == G_MAXUINT64 || !val) && errno)) {
+ g_free(s);
return val;
}
error_report("ignoring invalid max_mem_regions value in vhost module:"
" %s", s);
}
+ g_free(s);
return limit;
}
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 2203011125..093675ed98 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -33,6 +33,7 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_REPLY_ACK = 3,
VHOST_USER_PROTOCOL_F_NET_MTU = 4,
VHOST_USER_PROTOCOL_F_SLAVE_REQ = 5,
+ VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6,
VHOST_USER_PROTOCOL_F_MAX
};
@@ -63,6 +64,7 @@ typedef enum VhostUserRequest {
VHOST_USER_NET_SET_MTU = 20,
VHOST_USER_SET_SLAVE_REQ_FD = 21,
VHOST_USER_IOTLB_MSG = 22,
+ VHOST_USER_SET_VRING_ENDIAN = 23,
VHOST_USER_MAX
} VhostUserRequest;
@@ -367,8 +369,25 @@ static int vhost_user_set_vring_addr(struct vhost_dev *dev,
static int vhost_user_set_vring_endian(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
- error_report("vhost-user trying to send unhandled ioctl");
- return -1;
+ bool cross_endian = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_CROSS_ENDIAN);
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_VRING_ENDIAN,
+ .flags = VHOST_USER_VERSION,
+ .payload.state = *ring,
+ .size = sizeof(msg.payload.state),
+ };
+
+ if (!cross_endian) {
+ error_report("vhost-user trying to send unhandled ioctl");
+ return -1;
+ }
+
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ return -1;
+ }
+
+ return 0;
}
static int vhost_set_vring(struct vhost_dev *dev,