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>
 -----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJZgPRvAAoJECgfDbjSjVRpUKAH/RE1PohaH/klzEVFLPZUdISN
 /1zOdFN0BgVOUxS2udLVdZBUrWBiJWt11fbzASeGtOu3ruTpVfp69C7HUH8z4MOB
 cyBWgtcf7qQc9cqE0VGO1kLU+ujSyPlkZonjWVfeCrf298SElIXUNVXcihqVsglA
 VAL+tIUFT2Bbc3SH5xGsqHCMAy1hNRkEuF5t7enphOoxm7CdqghDLMfUEW65igYg
 XNt3DELfFDQVnwGP8DWSWjgLVAvGAGWGNHQ9QD/FO5mdVrXh1lukV8ZtXf6K2VJc
 svR670n3ZbMOkEIOGJYcYUFEKMgJXLNEpQX8WRM+vjnuEpDML6bBROtA8hckRv8=
 =9TSs
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2017-08-02 09:49:02 +01:00
commit d3d183a638
12 changed files with 77 additions and 22 deletions

View File

@ -326,6 +326,7 @@ Protocol features
#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
#define VHOST_USER_PROTOCOL_F_MTU 4
#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
#define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6
Master message types
--------------------
@ -580,6 +581,21 @@ Master message types
This request should be send only when VIRTIO_F_IOMMU_PLATFORM feature
has been successfully negotiated.
* VHOST_USER_SET_VRING_ENDIAN
Id: 23
Equivalent ioctl: VHOST_SET_VRING_ENDIAN
Master payload: vring state description
Set the endianess of a VQ for legacy devices. Little-endian is indicated
with state.num set to 0 and big-endian is indicated with state.num set
to 1. Other values are invalid.
This request should be sent only when VHOST_USER_PROTOCOL_F_CROSS_ENDIAN
has been negotiated.
Backends that negotiated this feature should handle both endianesses
and expect this message once (per VQ) during device configuration
(ie. before the master starts the VQ).
Slave message types
-------------------

View File

@ -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,

View File

@ -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:

View File

@ -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))

View File

@ -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,

View File

@ -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;
}

View File

@ -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,

View File

@ -103,8 +103,7 @@ struct VTDIOTLBEntry {
uint16_t domain_id;
uint64_t slpte;
uint64_t mask;
bool read_flags;
bool write_flags;
uint8_t access_flags;
};
/* VT-d Source-ID Qualifier types */

View File

@ -151,6 +151,10 @@ static void vhost_user_cleanup(NetClientState *nc)
s->vhost_net = NULL;
}
if (nc->queue_index == 0) {
if (s->watch) {
g_source_remove(s->watch);
s->watch = 0;
}
qemu_chr_fe_deinit(&s->chr, true);
}

View File

@ -108,7 +108,7 @@ static void test_acpi_rsdt_table(test_data *data)
/* compute the table entries in rsdt */
tables_nr = (rsdt_table->length - sizeof(AcpiRsdtDescriptorRev1)) /
sizeof(uint32_t);
g_assert_cmpint(tables_nr, >, 0);
g_assert(tables_nr > 0);
/* get the addresses of the tables pointed by rsdt */
tables = g_new0(uint32_t, tables_nr);

View File

@ -25,7 +25,7 @@ static void test_pxe_one(const char *params, bool ipv6)
{
char *args;
args = g_strdup_printf("-machine accel=tcg -nodefaults -boot order=n "
args = g_strdup_printf("-machine accel=kvm:tcg -nodefaults -boot order=n "
"-netdev user,id=" NETNAME ",tftp=./,bootfile=%s,"
"ipv4=%s,ipv6=%s %s", disk, ipv6 ? "off" : "on",
ipv6 ? "on" : "off", params);

View File

@ -132,7 +132,7 @@ static char disk[] = "tests/vmgenid-test-disk-XXXXXX";
static char *guid_cmd_strdup(const char *guid)
{
return g_strdup_printf("-machine accel=tcg "
return g_strdup_printf("-machine accel=kvm:tcg "
"-device vmgenid,id=testvgid,guid=%s "
"-drive id=hd0,if=none,file=%s,format=raw "
"-device ide-hd,drive=hd0 ",