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:
Peter Maydell 2024-11-05 15:47:52 +00:00
commit 9eb9350c0e
90 changed files with 1121 additions and 430 deletions

View file

@ -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 */

View file

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

View file

@ -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 */

View file

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

View file

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

View file

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