mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
virtio,pc,pci: features, fixes, cleanups
CXL now can use Generic Port Affinity Structures. CXL now allows control of link speed and width vhost-user-blk now supports live resize, by means of a new device-sync-config command amd iommu now supports interrupt remapping pcie devices now report extended tag field support intel_iommu dropped support for Transient Mapping, to match VTD spec arch agnostic ACPI infrastructure for vCPU Hotplug Fixes, cleanups all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmcpNqUPHG1zdEByZWRo YXQuY29tAAoJECgfDbjSjVRp/2oH/0qO33prhDa48J5mqT9NuJzzYwp5QHKF9Zjv fDAplMUEmfxZIEgJchcyDWPYTGX2geT4pCFhRWioZMIR/0JyzrFgSwsk1kL88cMh 46gzhNVD6ybyPJ7O0Zq3GLy5jo7rlw/n+fFxKAuRCzcbK/fmH8gNC+RwW1IP64Na HDczYilHUhnO7yKZFQzQNQVbK4BckrG1bu0Fcx0EMUQBf4V6x7GLOrT+3hkKYcr6 +DG5DmUmv20or/FXnu2Ye+MzR8Ebx6JVK3A3sXEE4Ns2CCzK9QLzeeyc2aU13jWN OpZ6WcKF8HqYprIwnSsMTxhPcq0/c7TvrGrazVwna5RUBMyjjvc= =zSX4 -----END PGP SIGNATURE----- Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging virtio,pc,pci: features, fixes, cleanups CXL now can use Generic Port Affinity Structures. CXL now allows control of link speed and width vhost-user-blk now supports live resize, by means of a new device-sync-config command amd iommu now supports interrupt remapping pcie devices now report extended tag field support intel_iommu dropped support for Transient Mapping, to match VTD spec arch agnostic ACPI infrastructure for vCPU Hotplug Fixes, cleanups all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmcpNqUPHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRp/2oH/0qO33prhDa48J5mqT9NuJzzYwp5QHKF9Zjv # fDAplMUEmfxZIEgJchcyDWPYTGX2geT4pCFhRWioZMIR/0JyzrFgSwsk1kL88cMh # 46gzhNVD6ybyPJ7O0Zq3GLy5jo7rlw/n+fFxKAuRCzcbK/fmH8gNC+RwW1IP64Na # HDczYilHUhnO7yKZFQzQNQVbK4BckrG1bu0Fcx0EMUQBf4V6x7GLOrT+3hkKYcr6 # +DG5DmUmv20or/FXnu2Ye+MzR8Ebx6JVK3A3sXEE4Ns2CCzK9QLzeeyc2aU13jWN # OpZ6WcKF8HqYprIwnSsMTxhPcq0/c7TvrGrazVwna5RUBMyjjvc= # =zSX4 # -----END PGP SIGNATURE----- # gpg: Signature made Mon 04 Nov 2024 21:03:33 GMT # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # 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 * tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (65 commits) intel_iommu: Add missed reserved bit check for IEC descriptor intel_iommu: Add missed sanity check for 256-bit invalidation queue intel_iommu: Send IQE event when setting reserved bit in IQT_TAIL hw/acpi: Update GED with vCPU Hotplug VMSD for migration tests/qtest/bios-tables-test: Update DSDT golden masters for x86/{pc,q35} hw/acpi: Update ACPI `_STA` method with QOM vCPU ACPI Hotplug states qtest: allow ACPI DSDT Table changes hw/acpi: Make CPUs ACPI `presence` conditional during vCPU hot-unplug hw/pci: Add parenthesis to PCI_BUILD_BDF macro hw/cxl: Ensure there is enough data to read the input header in cmd_get_physical_port_state() hw/cxl: Ensure there is enough data for the header in cmd_ccls_set_lsa() hw/cxl: Check that writes do not go beyond end of target attributes hw/cxl: Ensuring enough data to read parameters in cmd_tunnel_management_cmd() hw/cxl: Avoid accesses beyond the end of cel_log. hw/cxl: Check the length of data requested fits in get_log() hw/cxl: Check enough data in cmd_firmware_update_transfer() hw/cxl: Check input length is large enough in cmd_events_clear_records() hw/cxl: Check input includes at least the header in cmd_features_set_feature() hw/cxl: Check size of input data to dynamic capacity mailbox commands hw/cxl/cxl-mailbox-util: Fix output buffer index update when retrieving DC extents ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9eb9350c0e
90 changed files with 1121 additions and 430 deletions
|
@ -68,7 +68,6 @@
|
|||
#include "hw/acpi/utils.h"
|
||||
#include "hw/acpi/pci.h"
|
||||
#include "hw/acpi/cxl.h"
|
||||
#include "hw/acpi/acpi_generic_initiator.h"
|
||||
|
||||
#include "qom/qom-qobject.h"
|
||||
#include "hw/i386/amd_iommu.h"
|
||||
|
@ -741,7 +740,8 @@ static Aml *build_prt(bool is_pci0_prt)
|
|||
int pin;
|
||||
|
||||
method = aml_method("_PRT", 0, AML_NOTSERIALIZED);
|
||||
rt_pkg = aml_varpackage(nroutes);
|
||||
assert(nroutes < 256);
|
||||
rt_pkg = aml_package(nroutes);
|
||||
|
||||
for (pin = 0; pin < nroutes; pin++) {
|
||||
Aml *pkg = aml_package(4);
|
||||
|
@ -1476,6 +1476,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
|||
QLIST_FOREACH(bus, &bus->child, sibling) {
|
||||
uint8_t bus_num = pci_bus_num(bus);
|
||||
uint8_t numa_node = pci_bus_numa_node(bus);
|
||||
uint32_t uid;
|
||||
|
||||
/* look only for expander root buses */
|
||||
if (!pci_bus_is_root(bus)) {
|
||||
|
@ -1486,6 +1487,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
|||
root_bus_limit = bus_num - 1;
|
||||
}
|
||||
|
||||
uid = object_property_get_uint(OBJECT(bus), "acpi_uid",
|
||||
&error_fatal);
|
||||
scope = aml_scope("\\_SB");
|
||||
|
||||
if (pci_bus_is_cxl(bus)) {
|
||||
|
@ -1493,7 +1496,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
|||
} else {
|
||||
dev = aml_device("PC%.02X", bus_num);
|
||||
}
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(bus_num)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(uid)));
|
||||
aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
|
||||
if (pci_bus_is_cxl(bus)) {
|
||||
struct Aml *aml_pkg = aml_package(2);
|
||||
|
@ -1971,7 +1974,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
|||
build_srat_memory(table_data, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
|
||||
}
|
||||
|
||||
build_srat_generic_pci_initiator(table_data);
|
||||
build_srat_generic_affinity_structures(table_data);
|
||||
|
||||
/*
|
||||
* Entry is required for Windows to enable memory hotplug in OS
|
||||
|
@ -2321,7 +2324,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,
|
|||
/* Capability offset */
|
||||
build_append_int_noprefix(table_data, s->pci.capab_offset, 2);
|
||||
/* IOMMU base address */
|
||||
build_append_int_noprefix(table_data, s->mmio.addr, 8);
|
||||
build_append_int_noprefix(table_data, s->mr_mmio.addr, 8);
|
||||
/* PCI Segment Group */
|
||||
build_append_int_noprefix(table_data, 0, 2);
|
||||
/* IOMMU info */
|
||||
|
@ -2356,7 +2359,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,
|
|||
/* Capability offset */
|
||||
build_append_int_noprefix(table_data, s->pci.capab_offset, 2);
|
||||
/* IOMMU base address */
|
||||
build_append_int_noprefix(table_data, s->mmio.addr, 8);
|
||||
build_append_int_noprefix(table_data, s->mr_mmio.addr, 8);
|
||||
/* PCI Segment Group */
|
||||
build_append_int_noprefix(table_data, 0, 2);
|
||||
/* IOMMU info */
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "trace.h"
|
||||
#include "hw/i386/apic-msidef.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "kvm/kvm_i386.h"
|
||||
|
||||
/* used AMD-Vi MMIO registers */
|
||||
const char *amdvi_mmio_low[] = {
|
||||
|
@ -60,8 +61,9 @@ struct AMDVIAddressSpace {
|
|||
uint8_t bus_num; /* bus number */
|
||||
uint8_t devfn; /* device function */
|
||||
AMDVIState *iommu_state; /* AMDVI - one per machine */
|
||||
MemoryRegion root; /* AMDVI Root memory map region */
|
||||
MemoryRegion root; /* AMDVI Root memory map region */
|
||||
IOMMUMemoryRegion iommu; /* Device's address translation region */
|
||||
MemoryRegion iommu_nodma; /* Alias of shared nodma memory region */
|
||||
MemoryRegion iommu_ir; /* Device's interrupt remapping region */
|
||||
AddressSpace as; /* device's corresponding address space */
|
||||
};
|
||||
|
@ -430,6 +432,12 @@ static void amdvi_complete_ppr(AMDVIState *s, uint64_t *cmd)
|
|||
trace_amdvi_ppr_exec();
|
||||
}
|
||||
|
||||
static void amdvi_intremap_inval_notify_all(AMDVIState *s, bool global,
|
||||
uint32_t index, uint32_t mask)
|
||||
{
|
||||
x86_iommu_iec_notify_all(X86_IOMMU_DEVICE(s), global, index, mask);
|
||||
}
|
||||
|
||||
static void amdvi_inval_all(AMDVIState *s, uint64_t *cmd)
|
||||
{
|
||||
if (extract64(cmd[0], 0, 60) || cmd[1]) {
|
||||
|
@ -437,6 +445,9 @@ static void amdvi_inval_all(AMDVIState *s, uint64_t *cmd)
|
|||
s->cmdbuf + s->cmdbuf_head);
|
||||
}
|
||||
|
||||
/* Notify global invalidation */
|
||||
amdvi_intremap_inval_notify_all(s, true, 0, 0);
|
||||
|
||||
amdvi_iotlb_reset(s);
|
||||
trace_amdvi_all_inval();
|
||||
}
|
||||
|
@ -485,6 +496,9 @@ static void amdvi_inval_inttable(AMDVIState *s, uint64_t *cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Notify global invalidation */
|
||||
amdvi_intremap_inval_notify_all(s, true, 0, 0);
|
||||
|
||||
trace_amdvi_intr_inval();
|
||||
}
|
||||
|
||||
|
@ -1412,6 +1426,7 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
|
|||
AMDVIState *s = opaque;
|
||||
AMDVIAddressSpace **iommu_as, *amdvi_dev_as;
|
||||
int bus_num = pci_bus_num(bus);
|
||||
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
|
||||
|
||||
iommu_as = s->address_spaces[bus_num];
|
||||
|
||||
|
@ -1436,13 +1451,13 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
|
|||
* Memory region relationships looks like (Address range shows
|
||||
* only lower 32 bits to make it short in length...):
|
||||
*
|
||||
* |-----------------+-------------------+----------|
|
||||
* | Name | Address range | Priority |
|
||||
* |-----------------+-------------------+----------+
|
||||
* | amdvi_root | 00000000-ffffffff | 0 |
|
||||
* | amdvi_iommu | 00000000-ffffffff | 1 |
|
||||
* | amdvi_iommu_ir | fee00000-feefffff | 64 |
|
||||
* |-----------------+-------------------+----------|
|
||||
* |--------------------+-------------------+----------|
|
||||
* | Name | Address range | Priority |
|
||||
* |--------------------+-------------------+----------+
|
||||
* | amdvi-root | 00000000-ffffffff | 0 |
|
||||
* | amdvi-iommu_nodma | 00000000-ffffffff | 0 |
|
||||
* | amdvi-iommu_ir | fee00000-feefffff | 1 |
|
||||
* |--------------------+-------------------+----------|
|
||||
*/
|
||||
memory_region_init_iommu(&amdvi_dev_as->iommu,
|
||||
sizeof(amdvi_dev_as->iommu),
|
||||
|
@ -1452,16 +1467,34 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
|
|||
memory_region_init(&amdvi_dev_as->root, OBJECT(s),
|
||||
"amdvi_root", UINT64_MAX);
|
||||
address_space_init(&amdvi_dev_as->as, &amdvi_dev_as->root, name);
|
||||
memory_region_init_io(&amdvi_dev_as->iommu_ir, OBJECT(s),
|
||||
&amdvi_ir_ops, s, "amd_iommu_ir",
|
||||
AMDVI_INT_ADDR_SIZE);
|
||||
memory_region_add_subregion_overlap(&amdvi_dev_as->root,
|
||||
AMDVI_INT_ADDR_FIRST,
|
||||
&amdvi_dev_as->iommu_ir,
|
||||
64);
|
||||
memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0,
|
||||
MEMORY_REGION(&amdvi_dev_as->iommu),
|
||||
1);
|
||||
0);
|
||||
|
||||
/* Build the DMA Disabled alias to shared memory */
|
||||
memory_region_init_alias(&amdvi_dev_as->iommu_nodma, OBJECT(s),
|
||||
"amdvi-sys", &s->mr_sys, 0,
|
||||
memory_region_size(&s->mr_sys));
|
||||
memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0,
|
||||
&amdvi_dev_as->iommu_nodma,
|
||||
0);
|
||||
/* Build the Interrupt Remapping alias to shared memory */
|
||||
memory_region_init_alias(&amdvi_dev_as->iommu_ir, OBJECT(s),
|
||||
"amdvi-ir", &s->mr_ir, 0,
|
||||
memory_region_size(&s->mr_ir));
|
||||
memory_region_add_subregion_overlap(MEMORY_REGION(&amdvi_dev_as->iommu),
|
||||
AMDVI_INT_ADDR_FIRST,
|
||||
&amdvi_dev_as->iommu_ir, 1);
|
||||
|
||||
if (!x86_iommu->pt_supported) {
|
||||
memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false);
|
||||
memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu),
|
||||
true);
|
||||
} else {
|
||||
memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu),
|
||||
false);
|
||||
memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, true);
|
||||
}
|
||||
}
|
||||
return &iommu_as[devfn]->as;
|
||||
}
|
||||
|
@ -1598,10 +1631,37 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
|
|||
x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID);
|
||||
|
||||
/* set up MMIO */
|
||||
memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio",
|
||||
AMDVI_MMIO_SIZE);
|
||||
memory_region_init_io(&s->mr_mmio, OBJECT(s), &mmio_mem_ops, s,
|
||||
"amdvi-mmio", AMDVI_MMIO_SIZE);
|
||||
memory_region_add_subregion(get_system_memory(), AMDVI_BASE_ADDR,
|
||||
&s->mmio);
|
||||
&s->mr_mmio);
|
||||
|
||||
/* Create the share memory regions by all devices */
|
||||
memory_region_init(&s->mr_sys, OBJECT(s), "amdvi-sys", UINT64_MAX);
|
||||
|
||||
/* set up the DMA disabled memory region */
|
||||
memory_region_init_alias(&s->mr_nodma, OBJECT(s),
|
||||
"amdvi-nodma", get_system_memory(), 0,
|
||||
memory_region_size(get_system_memory()));
|
||||
memory_region_add_subregion_overlap(&s->mr_sys, 0,
|
||||
&s->mr_nodma, 0);
|
||||
|
||||
/* set up the Interrupt Remapping memory region */
|
||||
memory_region_init_io(&s->mr_ir, OBJECT(s), &amdvi_ir_ops,
|
||||
s, "amdvi-ir", AMDVI_INT_ADDR_SIZE);
|
||||
memory_region_add_subregion_overlap(&s->mr_sys, AMDVI_INT_ADDR_FIRST,
|
||||
&s->mr_ir, 1);
|
||||
|
||||
/* AMD IOMMU with x2APIC mode requires xtsup=on */
|
||||
if (x86ms->apic_id_limit > 255 && !s->xtsup) {
|
||||
error_report("AMD IOMMU with x2APIC confguration requires xtsup=on");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (s->xtsup && kvm_irqchip_is_split() && !kvm_enable_x2apic()) {
|
||||
error_report("AMD IOMMU xtsup=on requires support on the KVM side");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pci_setup_iommu(bus, &amdvi_iommu_ops, s);
|
||||
amdvi_init(s);
|
||||
}
|
||||
|
|
|
@ -353,7 +353,10 @@ struct AMDVIState {
|
|||
uint32_t pprlog_head; /* ppr log head */
|
||||
uint32_t pprlog_tail; /* ppr log tail */
|
||||
|
||||
MemoryRegion mmio; /* MMIO region */
|
||||
MemoryRegion mr_mmio; /* MMIO region */
|
||||
MemoryRegion mr_sys;
|
||||
MemoryRegion mr_nodma;
|
||||
MemoryRegion mr_ir;
|
||||
uint8_t mmior[AMDVI_MMIO_SIZE]; /* read/write MMIO */
|
||||
uint8_t w1cmask[AMDVI_MMIO_SIZE]; /* read/write 1 clear mask */
|
||||
uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */
|
||||
|
|
|
@ -2532,15 +2532,51 @@ static bool vtd_get_inv_desc(IntelIOMMUState *s,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool vtd_inv_desc_reserved_check(IntelIOMMUState *s,
|
||||
VTDInvDesc *inv_desc,
|
||||
uint64_t mask[4], bool dw,
|
||||
const char *func_name,
|
||||
const char *desc_type)
|
||||
{
|
||||
if (s->iq_dw) {
|
||||
if (inv_desc->val[0] & mask[0] || inv_desc->val[1] & mask[1] ||
|
||||
inv_desc->val[2] & mask[2] || inv_desc->val[3] & mask[3]) {
|
||||
error_report("%s: invalid %s desc val[3]: 0x%"PRIx64
|
||||
" val[2]: 0x%"PRIx64" val[1]=0x%"PRIx64
|
||||
" val[0]=0x%"PRIx64" (reserved nonzero)",
|
||||
func_name, desc_type, inv_desc->val[3],
|
||||
inv_desc->val[2], inv_desc->val[1],
|
||||
inv_desc->val[0]);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (dw) {
|
||||
error_report("%s: 256-bit %s desc in 128-bit invalidation queue",
|
||||
func_name, desc_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inv_desc->lo & mask[0] || inv_desc->hi & mask[1]) {
|
||||
error_report("%s: invalid %s desc: hi=%"PRIx64", lo=%"PRIx64
|
||||
" (reserved nonzero)", func_name, desc_type,
|
||||
inv_desc->hi, inv_desc->lo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
|
||||
{
|
||||
if ((inv_desc->hi & VTD_INV_DESC_WAIT_RSVD_HI) ||
|
||||
(inv_desc->lo & VTD_INV_DESC_WAIT_RSVD_LO)) {
|
||||
error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64
|
||||
" (reserved nonzero)", __func__, inv_desc->hi,
|
||||
inv_desc->lo);
|
||||
uint64_t mask[4] = {VTD_INV_DESC_WAIT_RSVD_LO, VTD_INV_DESC_WAIT_RSVD_HI,
|
||||
VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
|
||||
|
||||
if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, false,
|
||||
__func__, "wait")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inv_desc->lo & VTD_INV_DESC_WAIT_SW) {
|
||||
/* Status Write */
|
||||
uint32_t status_data = (uint32_t)(inv_desc->lo >>
|
||||
|
@ -2574,13 +2610,14 @@ static bool vtd_process_context_cache_desc(IntelIOMMUState *s,
|
|||
VTDInvDesc *inv_desc)
|
||||
{
|
||||
uint16_t sid, fmask;
|
||||
uint64_t mask[4] = {VTD_INV_DESC_CC_RSVD, VTD_INV_DESC_ALL_ONE,
|
||||
VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
|
||||
|
||||
if ((inv_desc->lo & VTD_INV_DESC_CC_RSVD) || inv_desc->hi) {
|
||||
error_report_once("%s: invalid cc inv desc: hi=%"PRIx64", lo=%"PRIx64
|
||||
" (reserved nonzero)", __func__, inv_desc->hi,
|
||||
inv_desc->lo);
|
||||
if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, false,
|
||||
__func__, "cc inv")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (inv_desc->lo & VTD_INV_DESC_CC_G) {
|
||||
case VTD_INV_DESC_CC_DOMAIN:
|
||||
trace_vtd_inv_desc_cc_domain(
|
||||
|
@ -2610,12 +2647,11 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
|
|||
uint16_t domain_id;
|
||||
uint8_t am;
|
||||
hwaddr addr;
|
||||
uint64_t mask[4] = {VTD_INV_DESC_IOTLB_RSVD_LO, VTD_INV_DESC_IOTLB_RSVD_HI,
|
||||
VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
|
||||
|
||||
if ((inv_desc->lo & VTD_INV_DESC_IOTLB_RSVD_LO) ||
|
||||
(inv_desc->hi & VTD_INV_DESC_IOTLB_RSVD_HI)) {
|
||||
error_report_once("%s: invalid iotlb inv desc: hi=0x%"PRIx64
|
||||
", lo=0x%"PRIx64" (reserved bits unzero)",
|
||||
__func__, inv_desc->hi, inv_desc->lo);
|
||||
if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, false,
|
||||
__func__, "iotlb inv")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2656,6 +2692,14 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
|
|||
static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
|
||||
VTDInvDesc *inv_desc)
|
||||
{
|
||||
uint64_t mask[4] = {VTD_INV_DESC_IEC_RSVD, VTD_INV_DESC_ALL_ONE,
|
||||
VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
|
||||
|
||||
if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, false,
|
||||
__func__, "iec inv")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
trace_vtd_inv_desc_iec(inv_desc->iec.granularity,
|
||||
inv_desc->iec.index,
|
||||
inv_desc->iec.index_mask);
|
||||
|
@ -2705,19 +2749,19 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
|
|||
hwaddr addr;
|
||||
uint16_t sid;
|
||||
bool size;
|
||||
uint64_t mask[4] = {VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO,
|
||||
VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI,
|
||||
VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
|
||||
|
||||
if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, false,
|
||||
__func__, "dev-iotlb inv")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
addr = VTD_INV_DESC_DEVICE_IOTLB_ADDR(inv_desc->hi);
|
||||
sid = VTD_INV_DESC_DEVICE_IOTLB_SID(inv_desc->lo);
|
||||
size = VTD_INV_DESC_DEVICE_IOTLB_SIZE(inv_desc->hi);
|
||||
|
||||
if ((inv_desc->lo & VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO) ||
|
||||
(inv_desc->hi & VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI)) {
|
||||
error_report_once("%s: invalid dev-iotlb inv desc: hi=%"PRIx64
|
||||
", lo=%"PRIx64" (reserved nonzero)", __func__,
|
||||
inv_desc->hi, inv_desc->lo);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using sid is OK since the guest should have finished the
|
||||
* initialization of both the bus and device.
|
||||
|
@ -2847,6 +2891,7 @@ static void vtd_handle_iqt_write(IntelIOMMUState *s)
|
|||
if (s->iq_dw && (val & VTD_IQT_QT_256_RSV_BIT)) {
|
||||
error_report_once("%s: RSV bit is set: val=0x%"PRIx64,
|
||||
__func__, val);
|
||||
vtd_handle_inv_queue_error(s);
|
||||
return;
|
||||
}
|
||||
s->iq_tail = VTD_IQT_QT(s->iq_dw, val);
|
||||
|
@ -3372,6 +3417,7 @@ static Property vtd_properties[] = {
|
|||
DEFINE_PROP_BOOL("x-pasid-mode", IntelIOMMUState, pasid, false),
|
||||
DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
|
||||
DEFINE_PROP_BOOL("dma-translation", IntelIOMMUState, dma_translation, true),
|
||||
DEFINE_PROP_BOOL("stale-tm", IntelIOMMUState, stale_tm, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -4138,15 +4184,15 @@ static void vtd_init(IntelIOMMUState *s)
|
|||
*/
|
||||
vtd_spte_rsvd[0] = ~0ULL;
|
||||
vtd_spte_rsvd[1] = VTD_SPTE_PAGE_L1_RSVD_MASK(s->aw_bits,
|
||||
x86_iommu->dt_supported);
|
||||
x86_iommu->dt_supported && s->stale_tm);
|
||||
vtd_spte_rsvd[2] = VTD_SPTE_PAGE_L2_RSVD_MASK(s->aw_bits);
|
||||
vtd_spte_rsvd[3] = VTD_SPTE_PAGE_L3_RSVD_MASK(s->aw_bits);
|
||||
vtd_spte_rsvd[4] = VTD_SPTE_PAGE_L4_RSVD_MASK(s->aw_bits);
|
||||
|
||||
vtd_spte_rsvd_large[2] = VTD_SPTE_LPAGE_L2_RSVD_MASK(s->aw_bits,
|
||||
x86_iommu->dt_supported);
|
||||
x86_iommu->dt_supported && s->stale_tm);
|
||||
vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits,
|
||||
x86_iommu->dt_supported);
|
||||
x86_iommu->dt_supported && s->stale_tm);
|
||||
|
||||
if (s->scalable_mode || s->snoop_control) {
|
||||
vtd_spte_rsvd[1] &= ~VTD_SPTE_SNP;
|
||||
|
|
|
@ -356,6 +356,7 @@ union VTDInvDesc {
|
|||
typedef union VTDInvDesc VTDInvDesc;
|
||||
|
||||
/* Masks for struct VTDInvDesc */
|
||||
#define VTD_INV_DESC_ALL_ONE -1ULL
|
||||
#define VTD_INV_DESC_TYPE(val) ((((val) >> 5) & 0x70ULL) | \
|
||||
((val) & 0xfULL))
|
||||
#define VTD_INV_DESC_CC 0x1 /* Context-cache Invalidate Desc */
|
||||
|
@ -409,11 +410,14 @@ typedef union VTDInvDesc VTDInvDesc;
|
|||
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
|
||||
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0f1f0
|
||||
|
||||
/* Masks for Interrupt Entry Invalidate Descriptor */
|
||||
#define VTD_INV_DESC_IEC_RSVD 0xffff000007fff1e0ULL
|
||||
|
||||
/* Rsvd field masks for spte */
|
||||
#define VTD_SPTE_SNP 0x800ULL
|
||||
|
||||
#define VTD_SPTE_PAGE_L1_RSVD_MASK(aw, dt_supported) \
|
||||
dt_supported ? \
|
||||
#define VTD_SPTE_PAGE_L1_RSVD_MASK(aw, stale_tm) \
|
||||
stale_tm ? \
|
||||
(0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \
|
||||
(0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
|
||||
#define VTD_SPTE_PAGE_L2_RSVD_MASK(aw) \
|
||||
|
@ -423,12 +427,12 @@ typedef union VTDInvDesc VTDInvDesc;
|
|||
#define VTD_SPTE_PAGE_L4_RSVD_MASK(aw) \
|
||||
(0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
|
||||
|
||||
#define VTD_SPTE_LPAGE_L2_RSVD_MASK(aw, dt_supported) \
|
||||
dt_supported ? \
|
||||
#define VTD_SPTE_LPAGE_L2_RSVD_MASK(aw, stale_tm) \
|
||||
stale_tm ? \
|
||||
(0x1ff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \
|
||||
(0x1ff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
|
||||
#define VTD_SPTE_LPAGE_L3_RSVD_MASK(aw, dt_supported) \
|
||||
dt_supported ? \
|
||||
#define VTD_SPTE_LPAGE_L3_RSVD_MASK(aw, stale_tm) \
|
||||
stale_tm ? \
|
||||
(0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \
|
||||
(0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
GlobalProperty pc_compat_9_1[] = {
|
||||
{ "ICH9-LPC", "x-smi-swsmi-timer", "off" },
|
||||
{ "ICH9-LPC", "x-smi-periodic-timer", "off" },
|
||||
{ TYPE_INTEL_IOMMU_DEVICE, "stale-tm", "on" },
|
||||
};
|
||||
const size_t pc_compat_9_1_len = G_N_ELEMENTS(pc_compat_9_1);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue