Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging

virtio,pci,pc: features, fixes, tests

vhost will now no longer set a call notifier if unused
some work towards loongarch testing based on bios-tables-test
some core pci work for SVM support in vtd
vhost vdpa init has been optimized for response time to QMP
A couple more fixes

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# -----BEGIN PGP SIGNATURE-----
#
# iQFDBAABCgAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmg97ZUPHG1zdEByZWRo
# YXQuY29tAAoJECgfDbjSjVRpRBsH/0Fx4NNMaynXmVOgV1rMFirTydhQG5NSdeJv
# i1RHd25Rne/RXH0CL71UPuOPADWh6bv9iZTg6RU6g7TwI8K9v3M0R71RlPLh1Lh1
# x7fifWNSNXVi18fM9/j+mIg7I2Ye0AaqveezRJWGzqoOxQKKlVI2xspKZBCCkygd
# i2tgtR1ORB6+ji6wVoTDPlL42X5Jef5MUT3XOcRR5biHm0JfqxxQKVM83mD+5yMI
# 0YqjT2BVRzo5rGN7mSuf7tQ50xI6I0wI1+eoWeKHRbg08f709M8TZRDKuVh24Evg
# 9WnIhKLTzRVdCNLNbw9h9EhxoANpWCyvmnn6GCfkJui40necFHY=
# =0lO6
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 02 Jun 2025 14:29:41 EDT
# 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: (26 commits)
  hw/i386/pc_piix: Fix RTC ISA IRQ wiring of isapc machine
  vdpa: move memory listener register to vhost_vdpa_init
  vdpa: move iova_tree allocation to net_vhost_vdpa_init
  vdpa: reorder listener assignment
  vdpa: add listener_registered
  vdpa: set backend capabilities at vhost_vdpa_init
  vdpa: reorder vhost_vdpa_set_backend_cap
  vdpa: check for iova tree initialized at net_client_start
  vhost: Don't set vring call if guest notifier is unused
  tests/qtest/bios-tables-test: Use MiB macro rather hardcode value
  tests/data/uefi-boot-images: Add ISO image for LoongArch system
  uefi-test-tools:: Add LoongArch64 support
  pci: Add a PCI-level API for PRI
  pci: Add a pci-level API for ATS
  pci: Add a pci-level initialization function for IOMMU notifiers
  memory: Store user data pointer in the IOMMU notifiers
  pci: Add an API to get IOMMU's min page size and virtual address width
  pci: Cache the bus mastering status in the device
  pcie: Helper functions to check to check if PRI is enabled
  pcie: Add a helper to declare the PRI capability for a pcie device
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2025-06-02 14:52:45 -04:00
19 changed files with 764 additions and 106 deletions
+10 -10
View File
@@ -1426,7 +1426,6 @@ 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];
@@ -1486,15 +1485,8 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
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);
}
memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false);
memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu), true);
}
return &iommu_as[devfn]->as;
}
@@ -1723,6 +1715,14 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
exit(EXIT_FAILURE);
}
if (s->xtsup) {
if (kvm_irqchip_is_split() && !kvm_enable_x2apic()) {
error_report("AMD IOMMU xtsup=on requires x2APIC support on "
"the KVM side");
exit(EXIT_FAILURE);
}
}
pci_setup_iommu(bus, &amdvi_iommu_ops, s);
amdvi_init(s);
}
+5
View File
@@ -285,6 +285,8 @@ static void pc_init1(MachineState *machine, const char *pci_type)
pcms->idebus[0] = qdev_get_child_bus(dev, "ide.0");
pcms->idebus[1] = qdev_get_child_bus(dev, "ide.1");
} else {
uint32_t irq;
isa_bus = isa_bus_new(NULL, system_memory, system_io,
&error_abort);
isa_bus_register_input_irqs(isa_bus, x86ms->gsi);
@@ -292,6 +294,9 @@ static void pc_init1(MachineState *machine, const char *pci_type)
x86ms->rtc = isa_new(TYPE_MC146818_RTC);
qdev_prop_set_int32(DEVICE(x86ms->rtc), "base_year", 2000);
isa_realize_and_unref(x86ms->rtc, isa_bus, &error_fatal);
irq = object_property_get_uint(OBJECT(x86ms->rtc), "irq",
&error_fatal);
isa_connect_gpio_out(ISA_DEVICE(x86ms->rtc), 0, irq);
i8257_dma_init(OBJECT(machine), isa_bus, 0);
pcms->hpet_enabled = false;
+195 -11
View File
@@ -128,6 +128,12 @@ static GSequence *pci_acpi_index_list(void)
return used_acpi_index_list;
}
static void pci_set_master(PCIDevice *d, bool enable)
{
memory_region_set_enabled(&d->bus_master_enable_region, enable);
d->is_master = enable; /* cache the status */
}
static void pci_init_bus_master(PCIDevice *pci_dev)
{
AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev);
@@ -135,7 +141,7 @@ static void pci_init_bus_master(PCIDevice *pci_dev)
memory_region_init_alias(&pci_dev->bus_master_enable_region,
OBJECT(pci_dev), "bus master",
dma_as->root, 0, memory_region_size(dma_as->root));
memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
pci_set_master(pci_dev, false);
memory_region_add_subregion(&pci_dev->bus_master_container_region, 0,
&pci_dev->bus_master_enable_region);
}
@@ -804,9 +810,8 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
pci_bridge_update_mappings(PCI_BRIDGE(s));
}
memory_region_set_enabled(&s->bus_master_enable_region,
pci_get_word(s->config + PCI_COMMAND)
& PCI_COMMAND_MASTER);
pci_set_master(s, pci_get_word(s->config + PCI_COMMAND)
& PCI_COMMAND_MASTER);
g_free(config);
return 0;
@@ -1725,7 +1730,7 @@ static void pci_update_mappings(PCIDevice *d)
pci_update_vga(d);
}
static inline int pci_irq_disabled(PCIDevice *d)
int pci_irq_disabled(PCIDevice *d)
{
return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
}
@@ -1787,9 +1792,8 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int
if (ranges_overlap(addr, l, PCI_COMMAND, 2)) {
pci_update_irq_disabled(d, was_irq_disabled);
memory_region_set_enabled(&d->bus_master_enable_region,
(pci_get_word(d->config + PCI_COMMAND)
& PCI_COMMAND_MASTER) && d->enabled);
pci_set_master(d, (pci_get_word(d->config + PCI_COMMAND) &
PCI_COMMAND_MASTER) && d->enabled);
}
msi_write_config(d, addr, val_in, l);
@@ -2935,6 +2939,23 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
return &address_space_memory;
}
int pci_iommu_init_iotlb_notifier(PCIDevice *dev, IOMMUNotifier *n,
IOMMUNotify fn, void *opaque)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->init_iotlb_notifier) {
iommu_bus->iommu_ops->init_iotlb_notifier(bus, iommu_bus->iommu_opaque,
devfn, n, fn, opaque);
return 0;
}
return -ENODEV;
}
bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
Error **errp)
{
@@ -2966,6 +2987,170 @@ void pci_device_unset_iommu_device(PCIDevice *dev)
}
}
int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req,
bool exec_req, hwaddr addr, bool lpig,
uint16_t prgi, bool is_read, bool is_write)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
if (!dev->is_master ||
((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) {
return -EPERM;
}
if (!pcie_pri_enabled(dev)) {
return -EPERM;
}
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->pri_request_page) {
return iommu_bus->iommu_ops->pri_request_page(bus,
iommu_bus->iommu_opaque,
devfn, pasid, priv_req,
exec_req, addr, lpig, prgi,
is_read, is_write);
}
return -ENODEV;
}
int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid,
IOMMUPRINotifier *notifier)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
if (!dev->is_master ||
((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) {
return -EPERM;
}
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->pri_register_notifier) {
iommu_bus->iommu_ops->pri_register_notifier(bus,
iommu_bus->iommu_opaque,
devfn, pasid, notifier);
return 0;
}
return -ENODEV;
}
void pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->pri_unregister_notifier) {
iommu_bus->iommu_ops->pri_unregister_notifier(bus,
iommu_bus->iommu_opaque,
devfn, pasid);
}
}
ssize_t pci_ats_request_translation(PCIDevice *dev, uint32_t pasid,
bool priv_req, bool exec_req,
hwaddr addr, size_t length,
bool no_write, IOMMUTLBEntry *result,
size_t result_length,
uint32_t *err_count)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
if (!dev->is_master ||
((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) {
return -EPERM;
}
if (result_length == 0) {
return -ENOSPC;
}
if (!pcie_ats_enabled(dev)) {
return -EPERM;
}
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->ats_request_translation) {
return iommu_bus->iommu_ops->ats_request_translation(bus,
iommu_bus->iommu_opaque,
devfn, pasid, priv_req,
exec_req, addr, length,
no_write, result,
result_length, err_count);
}
return -ENODEV;
}
int pci_iommu_register_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
IOMMUNotifier *n)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
if ((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev)) {
return -EPERM;
}
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->register_iotlb_notifier) {
iommu_bus->iommu_ops->register_iotlb_notifier(bus,
iommu_bus->iommu_opaque, devfn,
pasid, n);
return 0;
}
return -ENODEV;
}
int pci_iommu_unregister_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
IOMMUNotifier *n)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
if ((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev)) {
return -EPERM;
}
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->unregister_iotlb_notifier) {
iommu_bus->iommu_ops->unregister_iotlb_notifier(bus,
iommu_bus->iommu_opaque,
devfn, pasid, n);
return 0;
}
return -ENODEV;
}
int pci_iommu_get_iotlb_info(PCIDevice *dev, uint8_t *addr_width,
uint32_t *min_page_size)
{
PCIBus *bus;
PCIBus *iommu_bus;
int devfn;
pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->get_iotlb_info) {
iommu_bus->iommu_ops->get_iotlb_info(iommu_bus->iommu_opaque,
addr_width, min_page_size);
return 0;
}
return -ENODEV;
}
void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque)
{
/*
@@ -3100,9 +3285,8 @@ void pci_set_enabled(PCIDevice *d, bool state)
d->enabled = state;
pci_update_mappings(d);
memory_region_set_enabled(&d->bus_master_enable_region,
(pci_get_word(d->config + PCI_COMMAND)
& PCI_COMMAND_MASTER) && d->enabled);
pci_set_master(d, (pci_get_word(d->config + PCI_COMMAND)
& PCI_COMMAND_MASTER) && d->enabled);
if (qdev_is_realized(&d->qdev)) {
pci_device_reset(d);
}
+78
View File
@@ -1214,3 +1214,81 @@ void pcie_acs_reset(PCIDevice *dev)
pci_set_word(dev->config + dev->exp.acs_cap + PCI_ACS_CTRL, 0);
}
}
/* PASID */
void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
bool exec_perm, bool priv_mod)
{
static const uint16_t control_reg_rw_mask = 0x07;
uint16_t capability_reg;
assert(pasid_width <= PCI_EXT_CAP_PASID_MAX_WIDTH);
pcie_add_capability(dev, PCI_EXT_CAP_ID_PASID, PCI_PASID_VER, offset,
PCI_EXT_CAP_PASID_SIZEOF);
capability_reg = ((uint16_t)pasid_width) << PCI_PASID_CAP_WIDTH_SHIFT;
capability_reg |= exec_perm ? PCI_PASID_CAP_EXEC : 0;
capability_reg |= priv_mod ? PCI_PASID_CAP_PRIV : 0;
pci_set_word(dev->config + offset + PCI_PASID_CAP, capability_reg);
/* Everything is disabled by default */
pci_set_word(dev->config + offset + PCI_PASID_CTRL, 0);
pci_set_word(dev->wmask + offset + PCI_PASID_CTRL, control_reg_rw_mask);
dev->exp.pasid_cap = offset;
}
/* PRI */
void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
bool prg_response_pasid_req)
{
static const uint16_t control_reg_rw_mask = 0x3;
static const uint16_t status_reg_rw1_mask = 0x3;
static const uint32_t pr_alloc_reg_rw_mask = 0xffffffff;
uint16_t status_reg;
status_reg = prg_response_pasid_req ? PCI_PRI_STATUS_PASID : 0;
status_reg |= PCI_PRI_STATUS_STOPPED; /* Stopped by default */
pcie_add_capability(dev, PCI_EXT_CAP_ID_PRI, PCI_PRI_VER, offset,
PCI_EXT_CAP_PRI_SIZEOF);
/* Disabled by default */
pci_set_word(dev->config + offset + PCI_PRI_STATUS, status_reg);
pci_set_long(dev->config + offset + PCI_PRI_MAX_REQ, outstanding_pr_cap);
pci_set_word(dev->wmask + offset + PCI_PRI_CTRL, control_reg_rw_mask);
pci_set_word(dev->w1cmask + offset + PCI_PRI_STATUS, status_reg_rw1_mask);
pci_set_long(dev->wmask + offset + PCI_PRI_ALLOC_REQ, pr_alloc_reg_rw_mask);
dev->exp.pri_cap = offset;
}
bool pcie_pri_enabled(const PCIDevice *dev)
{
if (!pci_is_express(dev) || !dev->exp.pri_cap) {
return false;
}
return (pci_get_word(dev->config + dev->exp.pri_cap + PCI_PRI_CTRL) &
PCI_PRI_CTRL_ENABLE) != 0;
}
bool pcie_pasid_enabled(const PCIDevice *dev)
{
if (!pci_is_express(dev) || !dev->exp.pasid_cap) {
return false;
}
return (pci_get_word(dev->config + dev->exp.pasid_cap + PCI_PASID_CTRL) &
PCI_PASID_CTRL_ENABLE) != 0;
}
bool pcie_ats_enabled(const PCIDevice *dev)
{
if (!pci_is_express(dev) || !dev->exp.ats_cap) {
return false;
}
return (pci_get_word(dev->config + dev->exp.ats_cap + PCI_ATS_CTRL) &
PCI_ATS_CTRL_ENABLE) != 0;
}
+69 -38
View File
@@ -594,6 +594,36 @@ static void vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v)
v->shadow_vqs = g_steal_pointer(&shadow_vqs);
}
static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
{
struct vhost_vdpa *v = dev->opaque;
uint64_t features;
uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 |
0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH |
0x1ULL << VHOST_BACKEND_F_IOTLB_ASID |
0x1ULL << VHOST_BACKEND_F_SUSPEND;
int r;
if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) {
return -EFAULT;
}
features &= f;
if (vhost_vdpa_first_dev(dev)) {
r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features);
if (r) {
return -EFAULT;
}
}
dev->backend_cap = features;
v->shared->backend_cap = features;
return 0;
}
static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
{
struct vhost_vdpa *v = opaque;
@@ -603,7 +633,12 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
v->dev = dev;
dev->opaque = opaque ;
v->shared->listener = vhost_vdpa_memory_listener;
ret = vhost_vdpa_set_backend_cap(dev);
if (unlikely(ret != 0)) {
return ret;
}
vhost_vdpa_init_svq(dev, v);
error_propagate(&dev->migration_blocker, v->migration_blocker);
@@ -639,6 +674,7 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER);
v->shared->listener = vhost_vdpa_memory_listener;
return 0;
}
@@ -841,36 +877,6 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev,
return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
}
static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
{
struct vhost_vdpa *v = dev->opaque;
uint64_t features;
uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 |
0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH |
0x1ULL << VHOST_BACKEND_F_IOTLB_ASID |
0x1ULL << VHOST_BACKEND_F_SUSPEND;
int r;
if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) {
return -EFAULT;
}
features &= f;
if (vhost_vdpa_first_dev(dev)) {
r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features);
if (r) {
return -EFAULT;
}
}
dev->backend_cap = features;
v->shared->backend_cap = features;
return 0;
}
static int vhost_vdpa_get_device_id(struct vhost_dev *dev,
uint32_t *device_id)
{
@@ -888,8 +894,14 @@ static int vhost_vdpa_reset_device(struct vhost_dev *dev)
ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
trace_vhost_vdpa_reset_device(dev);
if (ret) {
return ret;
}
memory_listener_unregister(&v->shared->listener);
v->shared->listener_registered = false;
v->suspended = false;
return ret;
return 0;
}
static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
@@ -1373,7 +1385,15 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
"IOMMU and try again");
return -1;
}
memory_listener_register(&v->shared->listener, dev->vdev->dma_as);
if (v->shared->listener_registered &&
dev->vdev->dma_as != v->shared->listener.address_space) {
memory_listener_unregister(&v->shared->listener);
v->shared->listener_registered = false;
}
if (!v->shared->listener_registered) {
memory_listener_register(&v->shared->listener, dev->vdev->dma_as);
v->shared->listener_registered = true;
}
return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
}
@@ -1383,8 +1403,6 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
static void vhost_vdpa_reset_status(struct vhost_dev *dev)
{
struct vhost_vdpa *v = dev->opaque;
if (!vhost_vdpa_last_dev(dev)) {
return;
}
@@ -1392,7 +1410,6 @@ static void vhost_vdpa_reset_status(struct vhost_dev *dev)
vhost_vdpa_reset_device(dev);
vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
VIRTIO_CONFIG_S_DRIVER);
memory_listener_unregister(&v->shared->listener);
}
static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
@@ -1526,12 +1543,27 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev,
static int vhost_vdpa_set_owner(struct vhost_dev *dev)
{
int r;
struct vhost_vdpa *v;
if (!vhost_vdpa_first_dev(dev)) {
return 0;
}
trace_vhost_vdpa_set_owner(dev);
return vhost_vdpa_call(dev, VHOST_SET_OWNER, NULL);
r = vhost_vdpa_call(dev, VHOST_SET_OWNER, NULL);
if (unlikely(r < 0)) {
return r;
}
/*
* Being optimistic and listening address space memory. If the device
* uses vIOMMU, it is changed at vhost_vdpa_dev_start.
*/
v = dev->opaque;
memory_listener_register(&v->shared->listener, &address_space_memory);
v->shared->listener_registered = true;
return 0;
}
static int vhost_vdpa_vq_get_addr(struct vhost_dev *dev,
@@ -1563,7 +1595,6 @@ const VhostOps vdpa_ops = {
.vhost_set_vring_kick = vhost_vdpa_set_vring_kick,
.vhost_set_vring_call = vhost_vdpa_set_vring_call,
.vhost_get_features = vhost_vdpa_get_features,
.vhost_set_backend_cap = vhost_vdpa_set_backend_cap,
.vhost_set_owner = vhost_vdpa_set_owner,
.vhost_set_vring_endian = NULL,
.vhost_backend_memslots_limit = vhost_vdpa_memslots_limit,
+6 -1
View File
@@ -1213,7 +1213,12 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
static bool virtio_pci_query_guest_notifiers(DeviceState *d)
{
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
return msix_enabled(&proxy->pci_dev);
if (msix_enabled(&proxy->pci_dev)) {
return true;
} else {
return pci_irq_disabled(&proxy->pci_dev);
}
}
static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
+11
View File
@@ -205,6 +205,15 @@ static const char *virtio_id_to_name(uint16_t device_id)
return name;
}
static void virtio_check_indirect_feature(VirtIODevice *vdev)
{
if (!virtio_vdev_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC)) {
qemu_log_mask(LOG_GUEST_ERROR,
"Device %s: indirect_desc was not negotiated!\n",
vdev->name);
}
}
/* Called within call_rcu(). */
static void virtio_free_region_cache(VRingMemoryRegionCaches *caches)
{
@@ -1733,6 +1742,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
virtio_error(vdev, "Invalid size for indirect buffer table");
goto done;
}
virtio_check_indirect_feature(vdev);
/* loop over the indirect descriptor table */
len = address_space_cache_init(&indirect_desc_cache, vdev->dma_as,
@@ -1870,6 +1880,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz)
virtio_error(vdev, "Invalid size for indirect buffer table");
goto done;
}
virtio_check_indirect_feature(vdev);
/* loop over the indirect descriptor table */
len = address_space_cache_init(&indirect_desc_cache, vdev->dma_as,
+316
View File
@@ -375,6 +375,28 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range);
void pci_device_deassert_intx(PCIDevice *dev);
/* Page Request Interface */
typedef enum {
IOMMU_PRI_RESP_SUCCESS,
IOMMU_PRI_RESP_INVALID_REQUEST,
IOMMU_PRI_RESP_FAILURE,
} IOMMUPRIResponseCode;
typedef struct IOMMUPRIResponse {
IOMMUPRIResponseCode response_code;
uint16_t prgi;
} IOMMUPRIResponse;
struct IOMMUPRINotifier;
typedef void (*IOMMUPRINotify)(struct IOMMUPRINotifier *notifier,
IOMMUPRIResponse *response);
typedef struct IOMMUPRINotifier {
IOMMUPRINotify notify;
} IOMMUPRINotifier;
#define PCI_PRI_PRGI_MASK 0x1ffU
/**
* struct PCIIOMMUOps: callbacks structure for specific IOMMU handlers
@@ -429,6 +451,179 @@ typedef struct PCIIOMMUOps {
* @devfn: device and function number of the PCI device.
*/
void (*unset_iommu_device)(PCIBus *bus, void *opaque, int devfn);
/**
* @get_iotlb_info: get properties required to initialize a device IOTLB.
*
* Callback required if devices are allowed to cache translations.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @addr_width: the address width of the IOMMU (output parameter).
*
* @min_page_size: the page size of the IOMMU (output parameter).
*/
void (*get_iotlb_info)(void *opaque, uint8_t *addr_width,
uint32_t *min_page_size);
/**
* @init_iotlb_notifier: initialize an IOMMU notifier.
*
* Optional callback.
*
* @bus: the #PCIBus of the PCI device.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @devfn: device and function number of the PCI device.
*
* @n: the notifier to be initialized.
*
* @fn: the callback to be installed.
*
* @user_opaque: a user pointer that can be used to track a state.
*/
void (*init_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn,
IOMMUNotifier *n, IOMMUNotify fn,
void *user_opaque);
/**
* @register_iotlb_notifier: setup an IOTLB invalidation notifier.
*
* Callback required if devices are allowed to cache translations.
*
* @bus: the #PCIBus of the PCI device.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @devfn: device and function number of the PCI device.
*
* @pasid: the pasid of the address space to watch.
*
* @n: the notifier to register.
*/
void (*register_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn,
uint32_t pasid, IOMMUNotifier *n);
/**
* @unregister_iotlb_notifier: remove an IOTLB invalidation notifier.
*
* Callback required if devices are allowed to cache translations.
*
* @bus: the #PCIBus of the PCI device.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @devfn: device and function number of the PCI device.
*
* @pasid: the pasid of the address space to stop watching.
*
* @n: the notifier to unregister.
*/
void (*unregister_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn,
uint32_t pasid, IOMMUNotifier *n);
/**
* @ats_request_translation: issue an ATS request.
*
* Callback required if devices are allowed to use the address
* translation service.
*
* @bus: the #PCIBus of the PCI device.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @devfn: device and function number of the PCI device.
*
* @pasid: the pasid of the address space to use for the request.
*
* @priv_req: privileged mode bit (PASID TLP).
*
* @exec_req: execute request bit (PASID TLP).
*
* @addr: start address of the memory range to be translated.
*
* @length: length of the memory range in bytes.
*
* @no_write: request a read-only translation (if supported).
*
* @result: buffer in which the TLB entries will be stored.
*
* @result_length: result buffer length.
*
* @err_count: number of untranslated subregions.
*
* Returns: the number of translations stored in the result buffer, or
* -ENOMEM if the buffer is not large enough.
*/
ssize_t (*ats_request_translation)(PCIBus *bus, void *opaque, int devfn,
uint32_t pasid, bool priv_req,
bool exec_req, hwaddr addr,
size_t length, bool no_write,
IOMMUTLBEntry *result,
size_t result_length,
uint32_t *err_count);
/**
* @pri_register_notifier: setup the PRI completion callback.
*
* Callback required if devices are allowed to use the page request
* interface.
*
* @bus: the #PCIBus of the PCI device.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @devfn: device and function number of the PCI device.
*
* @pasid: the pasid of the address space to track.
*
* @notifier: the notifier to register.
*/
void (*pri_register_notifier)(PCIBus *bus, void *opaque, int devfn,
uint32_t pasid, IOMMUPRINotifier *notifier);
/**
* @pri_unregister_notifier: remove the PRI completion callback.
*
* Callback required if devices are allowed to use the page request
* interface.
*
* @bus: the #PCIBus of the PCI device.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @devfn: device and function number of the PCI device.
*
* @pasid: the pasid of the address space to stop tracking.
*/
void (*pri_unregister_notifier)(PCIBus *bus, void *opaque, int devfn,
uint32_t pasid);
/**
* @pri_request_page: issue a PRI request.
*
* Callback required if devices are allowed to use the page request
* interface.
*
* @bus: the #PCIBus of the PCI device.
*
* @opaque: the data passed to pci_setup_iommu().
*
* @devfn: device and function number of the PCI device.
*
* @pasid: the pasid of the address space to use for the request.
*
* @priv_req: privileged mode bit (PASID TLP).
*
* @exec_req: execute request bit (PASID TLP).
*
* @addr: untranslated address of the requested page.
*
* @lpig: last page in group.
*
* @prgi: page request group index.
*
* @is_read: request read access.
*
* @is_write: request write access.
*/
int (*pri_request_page)(PCIBus *bus, void *opaque, int devfn,
uint32_t pasid, bool priv_req, bool exec_req,
hwaddr addr, bool lpig, uint16_t prgi, bool is_read,
bool is_write);
} PCIIOMMUOps;
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
@@ -436,6 +631,126 @@ bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
Error **errp);
void pci_device_unset_iommu_device(PCIDevice *dev);
/**
* pci_iommu_get_iotlb_info: get properties required to initialize a
* device IOTLB.
*
* Returns 0 on success, or a negative errno otherwise.
*
* @dev: the device that wants to get the information.
* @addr_width: the address width of the IOMMU (output parameter).
* @min_page_size: the page size of the IOMMU (output parameter).
*/
int pci_iommu_get_iotlb_info(PCIDevice *dev, uint8_t *addr_width,
uint32_t *min_page_size);
/**
* pci_iommu_init_iotlb_notifier: initialize an IOMMU notifier.
*
* This function is used by devices before registering an IOTLB notifier.
*
* @dev: the device.
* @n: the notifier to be initialized.
* @fn: the callback to be installed.
* @opaque: a user pointer that can be used to track a state.
*/
int pci_iommu_init_iotlb_notifier(PCIDevice *dev, IOMMUNotifier *n,
IOMMUNotify fn, void *opaque);
/**
* pci_ats_request_translation: perform an ATS request.
*
* Returns the number of translations stored in @result in case of success,
* a negative error code otherwise.
* -ENOMEM is returned when the result buffer is not large enough to store
* all the translations.
*
* @dev: the ATS-capable PCI device.
* @pasid: the pasid of the address space in which the translation will be done.
* @priv_req: privileged mode bit (PASID TLP).
* @exec_req: execute request bit (PASID TLP).
* @addr: start address of the memory range to be translated.
* @length: length of the memory range in bytes.
* @no_write: request a read-only translation (if supported).
* @result: buffer in which the TLB entries will be stored.
* @result_length: result buffer length.
* @err_count: number of untranslated subregions.
*/
ssize_t pci_ats_request_translation(PCIDevice *dev, uint32_t pasid,
bool priv_req, bool exec_req,
hwaddr addr, size_t length,
bool no_write, IOMMUTLBEntry *result,
size_t result_length,
uint32_t *err_count);
/**
* pci_pri_request_page: perform a PRI request.
*
* Returns 0 if the PRI request has been sent to the guest OS,
* an error code otherwise.
*
* @dev: the PRI-capable PCI device.
* @pasid: the pasid of the address space in which the translation will be done.
* @priv_req: privileged mode bit (PASID TLP).
* @exec_req: execute request bit (PASID TLP).
* @addr: untranslated address of the requested page.
* @lpig: last page in group.
* @prgi: page request group index.
* @is_read: request read access.
* @is_write: request write access.
*/
int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req,
bool exec_req, hwaddr addr, bool lpig,
uint16_t prgi, bool is_read, bool is_write);
/**
* pci_pri_register_notifier: register the PRI callback for a given address
* space.
*
* Returns 0 on success, an error code otherwise.
*
* @dev: the PRI-capable PCI device.
* @pasid: the pasid of the address space to track.
* @notifier: the notifier to register.
*/
int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid,
IOMMUPRINotifier *notifier);
/**
* pci_pri_unregister_notifier: remove the PRI callback from a given address
* space.
*
* @dev: the PRI-capable PCI device.
* @pasid: the pasid of the address space to stop tracking.
*/
void pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid);
/**
* pci_iommu_register_iotlb_notifier: register a notifier for changes to
* IOMMU translation entries in a specific address space.
*
* Returns 0 on success, or a negative errno otherwise.
*
* @dev: the device that wants to get notified.
* @pasid: the pasid of the address space to track.
* @n: the notifier to register.
*/
int pci_iommu_register_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
IOMMUNotifier *n);
/**
* pci_iommu_unregister_iotlb_notifier: unregister a notifier that has been
* registerd with pci_iommu_register_iotlb_notifier.
*
* Returns 0 on success, or a negative errno otherwise.
*
* @dev: the device that wants to stop notifications.
* @pasid: the pasid of the address space to stop tracking.
* @n: the notifier to unregister.
*/
int pci_iommu_unregister_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
IOMMUNotifier *n);
/**
* pci_setup_iommu: Initialize specific IOMMU handlers for a PCIBus
*
@@ -668,6 +983,7 @@ void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev);
qemu_irq pci_allocate_irq(PCIDevice *pci_dev);
void pci_set_irq(PCIDevice *pci_dev, int level);
int pci_irq_disabled(PCIDevice *d);
static inline void pci_irq_assert(PCIDevice *pci_dev)
{
+1
View File
@@ -90,6 +90,7 @@ struct PCIDevice {
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
AddressSpace bus_master_as;
bool is_master;
MemoryRegion bus_master_container_region;
MemoryRegion bus_master_enable_region;
+12 -1
View File
@@ -70,8 +70,10 @@ struct PCIExpressDevice {
uint16_t aer_cap;
PCIEAERLog aer_log;
/* Offset of ATS capability in config space */
/* Offset of ATS, PRI and PASID capabilities in config space */
uint16_t ats_cap;
uint16_t pasid_cap;
uint16_t pri_cap;
/* ACS */
uint16_t acs_cap;
@@ -150,4 +152,13 @@ void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp);
void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
bool exec_perm, bool priv_mod);
void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
bool prg_response_pasid_req);
bool pcie_pri_enabled(const PCIDevice *dev);
bool pcie_pasid_enabled(const PCIDevice *dev);
bool pcie_ats_enabled(const PCIDevice *dev);
#endif /* QEMU_PCIE_H */
+8
View File
@@ -86,6 +86,14 @@ typedef enum PCIExpLinkWidth {
#define PCI_ARI_VER 1
#define PCI_ARI_SIZEOF 8
/* PASID */
#define PCI_PASID_VER 1
#define PCI_EXT_CAP_PASID_MAX_WIDTH 20
#define PCI_PASID_CAP_WIDTH_SHIFT 8
/* PRI */
#define PCI_PRI_VER 1
/* AER */
#define PCI_ERR_VER 2
#define PCI_ERR_SIZEOF 0x48
+21 -1
View File
@@ -43,7 +43,21 @@ typedef struct vhost_vdpa_shared {
struct vhost_vdpa_iova_range iova_range;
QLIST_HEAD(, vdpa_iommu) iommu_list;
/* IOVA mapping used by the Shadow Virtqueue */
/*
* IOVA mapping used by the Shadow Virtqueue
*
* It is shared among all ASID for simplicity, whether CVQ shares ASID with
* guest or not:
* - Memory listener need access to guest's memory addresses allocated in
* the IOVA tree.
* - There should be plenty of IOVA address space for both ASID not to
* worry about collisions between them. Guest's translations are still
* validated with virtio virtqueue_pop so there is no risk for the guest
* to access memory that it shouldn't.
*
* To allocate a iova tree per ASID is doable but it complicates the code
* and it is not worth it for the moment.
*/
VhostIOVATree *iova_tree;
/* Copy of backend features */
@@ -51,6 +65,12 @@ typedef struct vhost_vdpa_shared {
bool iotlb_batch_begin_sent;
/*
* The memory listener has been registered, so DMA maps have been sent to
* the device.
*/
bool listener_registered;
/* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */
bool shadow_data;
+1
View File
@@ -183,6 +183,7 @@ struct IOMMUNotifier {
hwaddr start;
hwaddr end;
int iommu_idx;
void *opaque;
QLIST_ENTRY(IOMMUNotifier) node;
};
typedef struct IOMMUNotifier IOMMUNotifier;
+3 -31
View File
@@ -235,6 +235,7 @@ static void vhost_vdpa_cleanup(NetClientState *nc)
return;
}
qemu_close(s->vhost_vdpa.shared->device_fd);
g_clear_pointer(&s->vhost_vdpa.shared->iova_tree, vhost_iova_tree_delete);
g_free(s->vhost_vdpa.shared);
}
@@ -362,14 +363,8 @@ static int vdpa_net_migration_state_notifier(NotifierWithReturn *notifier,
static void vhost_vdpa_net_data_start_first(VhostVDPAState *s)
{
struct vhost_vdpa *v = &s->vhost_vdpa;
migration_add_notifier(&s->migration_state,
vdpa_net_migration_state_notifier);
if (v->shadow_vqs_enabled) {
v->shared->iova_tree = vhost_iova_tree_new(v->shared->iova_range.first,
v->shared->iova_range.last);
}
}
static int vhost_vdpa_net_data_start(NetClientState *nc)
@@ -416,19 +411,12 @@ static int vhost_vdpa_net_data_load(NetClientState *nc)
static void vhost_vdpa_net_client_stop(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
struct vhost_dev *dev;
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
if (s->vhost_vdpa.index == 0) {
migration_remove_notifier(&s->migration_state);
}
dev = s->vhost_vdpa.dev;
if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
g_clear_pointer(&s->vhost_vdpa.shared->iova_tree,
vhost_iova_tree_delete);
}
}
static NetClientInfo net_vhost_vdpa_info = {
@@ -600,24 +588,6 @@ out:
return 0;
}
/*
* If other vhost_vdpa already have an iova_tree, reuse it for simplicity,
* whether CVQ shares ASID with guest or not, because:
* - Memory listener need access to guest's memory addresses allocated in
* the IOVA tree.
* - There should be plenty of IOVA address space for both ASID not to
* worry about collisions between them. Guest's translations are still
* validated with virtio virtqueue_pop so there is no risk for the guest
* to access memory that it shouldn't.
*
* To allocate a iova tree per ASID is doable but it complicates the code
* and it is not worth it for the moment.
*/
if (!v->shared->iova_tree) {
v->shared->iova_tree = vhost_iova_tree_new(v->shared->iova_range.first,
v->shared->iova_range.last);
}
r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer,
vhost_vdpa_net_cvq_cmd_page_len(), false);
if (unlikely(r < 0)) {
@@ -1726,6 +1696,8 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->vhost_vdpa.shared->device_fd = vdpa_device_fd;
s->vhost_vdpa.shared->iova_range = iova_range;
s->vhost_vdpa.shared->shadow_data = svq;
s->vhost_vdpa.shared->iova_tree = vhost_iova_tree_new(iova_range.first,
iova_range.last);
} else if (!is_datapath) {
s->cvq_cmd_out_buffer = mmap(NULL, vhost_vdpa_net_cvq_cmd_page_len(),
PROT_READ | PROT_WRITE,
+10 -10
View File
@@ -1622,7 +1622,7 @@ static void test_acpi_aarch64_virt_tcg_memhp(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 256ULL * 1024 * 1024,
.scan_len = 256ULL * MiB,
};
data.variant = ".memhp";
@@ -1717,7 +1717,7 @@ static void test_acpi_riscv64_virt_tcg_numamem(void)
.uefi_fl2 = "pc-bios/edk2-riscv-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2",
.ram_start = 0x80000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
data.variant = ".numamem";
@@ -1743,7 +1743,7 @@ static void test_acpi_aarch64_virt_tcg_numamem(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
data.variant = ".numamem";
@@ -1765,7 +1765,7 @@ static void test_acpi_aarch64_virt_tcg_pxb(void)
.uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
/*
* While using -cdrom, the cdrom would auto plugged into pxb-pcie,
@@ -1841,7 +1841,7 @@ static void test_acpi_aarch64_virt_tcg_acpi_hmat(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
data.variant = ".acpihmatvirt";
@@ -2095,7 +2095,7 @@ static void test_acpi_riscv64_virt_tcg(void)
.uefi_fl2 = "pc-bios/edk2-riscv-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2",
.ram_start = 0x80000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
/*
@@ -2117,7 +2117,7 @@ static void test_acpi_aarch64_virt_tcg(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
data.smbios_cpu_max_speed = 2900;
@@ -2138,7 +2138,7 @@ static void test_acpi_aarch64_virt_tcg_topology(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
test_acpi_one("-cpu cortex-a57 "
@@ -2223,7 +2223,7 @@ static void test_acpi_aarch64_virt_viot(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
test_acpi_one("-cpu cortex-a57 "
@@ -2407,7 +2407,7 @@ static void test_acpi_aarch64_virt_oem_fields(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
.scan_len = 128ULL * MiB,
};
char *args;
+3 -2
View File
@@ -12,7 +12,7 @@
edk2_dir := ../../roms/edk2
images_dir := ../data/uefi-boot-images
emulation_targets := arm aarch64 i386 x86_64 riscv64
emulation_targets := arm aarch64 i386 x86_64 riscv64 loongarch64
uefi_binaries := bios-tables-test
intermediate_suffixes := .efi .fat .iso.raw
@@ -56,7 +56,8 @@ Build/%.iso.raw: Build/%.fat
# stripped from, the argument.
map_arm_to_uefi = $(subst arm,ARM,$(1))
map_aarch64_to_uefi = $(subst aarch64,AA64,$(call map_arm_to_uefi,$(1)))
map_riscv64_to_uefi = $(subst riscv64,RISCV64,$(call map_aarch64_to_uefi,$(1)))
map_loongarch64_to_uefi = $(subst loongarch64,LOONGARCH64,$(call map_aarch64_to_uefi,$(1)))
map_riscv64_to_uefi = $(subst riscv64,RISCV64,$(call map_loongarch64_to_uefi,$(1)))
map_i386_to_uefi = $(subst i386,IA32,$(call map_riscv64_to_uefi,$(1)))
map_x86_64_to_uefi = $(subst x86_64,X64,$(call map_i386_to_uefi,$(1)))
map_to_uefi = $(subst .,,$(call map_x86_64_to_uefi,$(1)))
@@ -19,7 +19,7 @@
PLATFORM_VERSION = 0.1
PLATFORM_NAME = UefiTestTools
SKUID_IDENTIFIER = DEFAULT
SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64|RISCV64
SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64|RISCV64|LOONGARCH64
BUILD_TARGETS = DEBUG
[BuildOptions.IA32]
@@ -65,6 +65,10 @@
[LibraryClasses.RISCV64]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
[LibraryClasses.LOONGARCH64]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
@@ -21,6 +21,16 @@ dest = ./Build
arch = AARCH64
cpy1 = AARCH64/BiosTablesTest.efi bios-tables-test.aarch64.efi
####################################################################################
# loongarch64
[build.loongarch64]
conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc
plat = UefiTestTools
dest = ./Build
arch = LOONGARCH64
cpy1 = LOONGARCH64/BiosTablesTest.efi bios-tables-test.loongarch64.efi
####################################################################################
# riscv64