Mailing List Archive

[xen master] x86/iommu: call pi_update_irte through an hvm_function callback
commit 0d57bba8ad0ef3d1ae5dd1ad3677ec34351ef530
Author: Xenia Ragiadakou <burzalodowa@gmail.com>
AuthorDate: Mon Feb 13 16:28:32 2023 +0100
Commit: Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Feb 13 16:28:32 2023 +0100

x86/iommu: call pi_update_irte through an hvm_function callback

Posted interrupt support in Xen is currently implemented only for the
Intel platforms. Instead of calling directly pi_update_irte() from the
common hvm code, add a pi_update_irte callback to the hvm_function_table.
Then, create a wrapper function hvm_pi_update_irte() to be used by the
common hvm code.

In the pi_update_irte callback prototype, pass the vcpu as first parameter
instead of the posted-interrupt descriptor that is platform specific, and
remove the const qualifier from the parameter gvec since it is not needed
and because it does not compile with the alternative code patching in use.

Since the posted interrupt descriptor is Intel VT-x specific while
msi_msg_write_remap_rte is iommu specific, open code pi_update_irte() inside
vmx_pi_update_irte() but replace msi_msg_write_remap_rte() with generic
iommu_update_ire_from_msi(). That way vmx_pi_update_irte() is not bound to
Intel VT-d anymore.

Remove the now unused pi_update_irte() implementation.

No functional change intended.

Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
xen/arch/x86/hvm/vmx/vmx.c | 41 ++++++++++++++++++++++++++++++++++
xen/arch/x86/include/asm/hvm/hvm.h | 10 +++++++++
xen/arch/x86/include/asm/iommu.h | 4 ----
xen/drivers/passthrough/vtd/intremap.c | 36 -----------------------------
xen/drivers/passthrough/x86/hvm.c | 5 ++---
5 files changed, 53 insertions(+), 43 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index ade2a25ce7..270bc98195 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -397,6 +397,43 @@ void vmx_pi_hooks_deassign(struct domain *d)
domain_unpause(d);
}

+/*
+ * This function is used to update the IRTE for posted-interrupt
+ * when guest changes MSI/MSI-X information.
+ */
+static int cf_check vmx_pi_update_irte(const struct vcpu *v,
+ const struct pirq *pirq, uint8_t gvec)
+{
+ const struct pi_desc *pi_desc = v ? &v->arch.hvm.vmx.pi_desc : NULL;
+ struct irq_desc *desc;
+ struct msi_desc *msi_desc;
+ int rc;
+
+ desc = pirq_spin_lock_irq_desc(pirq, NULL);
+ if ( !desc )
+ return -EINVAL;
+
+ msi_desc = desc->msi_desc;
+ if ( !msi_desc )
+ {
+ rc = -ENODEV;
+ goto unlock_out;
+ }
+ msi_desc->pi_desc = pi_desc;
+ msi_desc->gvec = gvec;
+
+ spin_unlock_irq(&desc->lock);
+
+ ASSERT(pcidevs_locked());
+
+ return iommu_update_ire_from_msi(msi_desc, &msi_desc->msg);
+
+ unlock_out:
+ spin_unlock_irq(&desc->lock);
+
+ return rc;
+}
+
static const struct lbr_info {
u32 base, count;
} p4_lbr[] = {
@@ -2986,8 +3023,12 @@ const struct hvm_function_table * __init start_vmx(void)
{
alloc_direct_apic_vector(&posted_intr_vector, pi_notification_interrupt);
if ( iommu_intpost )
+ {
alloc_direct_apic_vector(&pi_wakeup_vector, pi_wakeup_interrupt);

+ vmx_function_table.pi_update_irte = vmx_pi_update_irte;
+ }
+
vmx_function_table.deliver_posted_intr = vmx_deliver_posted_intr;
vmx_function_table.sync_pir_to_irr = vmx_sync_pir_to_irr;
vmx_function_table.test_pir = vmx_test_pir;
diff --git a/xen/arch/x86/include/asm/hvm/hvm.h b/xen/arch/x86/include/asm/hvm/hvm.h
index 65768c797e..80e4565bd2 100644
--- a/xen/arch/x86/include/asm/hvm/hvm.h
+++ b/xen/arch/x86/include/asm/hvm/hvm.h
@@ -28,6 +28,8 @@
#include <asm/x86_emulate.h>
#include <asm/hvm/asid.h>

+struct pirq; /* needed by pi_update_irte */
+
#ifdef CONFIG_HVM_FEP
/* Permit use of the Forced Emulation Prefix in HVM guests */
extern bool_t opt_hvm_fep;
@@ -213,6 +215,8 @@ struct hvm_function_table {
void (*sync_pir_to_irr)(struct vcpu *v);
bool (*test_pir)(const struct vcpu *v, uint8_t vector);
void (*handle_eoi)(uint8_t vector, int isr);
+ int (*pi_update_irte)(const struct vcpu *v, const struct pirq *pirq,
+ uint8_t gvec);

/*Walk nested p2m */
int (*nhvm_hap_walk_L1_p2m)(struct vcpu *v, paddr_t L2_gpa,
@@ -776,6 +780,12 @@ static inline void hvm_set_nonreg_state(struct vcpu *v,
alternative_vcall(hvm_funcs.set_nonreg_state, v, nrs);
}

+static inline int hvm_pi_update_irte(const struct vcpu *v,
+ const struct pirq *pirq, uint8_t gvec)
+{
+ return alternative_call(hvm_funcs.pi_update_irte, v, pirq, gvec);
+}
+
#else /* CONFIG_HVM */

#define hvm_enabled false
diff --git a/xen/arch/x86/include/asm/iommu.h b/xen/arch/x86/include/asm/iommu.h
index fc0afe35bf..586c7434f2 100644
--- a/xen/arch/x86/include/asm/iommu.h
+++ b/xen/arch/x86/include/asm/iommu.h
@@ -21,7 +21,6 @@
#include <asm/apicdef.h>
#include <asm/cache.h>
#include <asm/processor.h>
-#include <asm/hvm/vmx/vmcs.h>

#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48

@@ -129,9 +128,6 @@ void iommu_identity_map_teardown(struct domain *d);

extern bool untrusted_msi;

-int pi_update_irte(const struct pi_desc *pi_desc, const struct pirq *pirq,
- const uint8_t gvec);
-
extern bool iommu_non_coherent, iommu_superpages;

static inline void iommu_sync_cache(const void *addr, unsigned int size)
diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c
index 1512e4866b..b39bc83282 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -866,39 +866,3 @@ void cf_check intel_iommu_disable_eim(void)
for_each_drhd_unit ( drhd )
disable_qinval(drhd->iommu);
}
-
-/*
- * This function is used to update the IRTE for posted-interrupt
- * when guest changes MSI/MSI-X information.
- */
-int pi_update_irte(const struct pi_desc *pi_desc, const struct pirq *pirq,
- const uint8_t gvec)
-{
- struct irq_desc *desc;
- struct msi_desc *msi_desc;
- int rc;
-
- desc = pirq_spin_lock_irq_desc(pirq, NULL);
- if ( !desc )
- return -EINVAL;
-
- msi_desc = desc->msi_desc;
- if ( !msi_desc )
- {
- rc = -ENODEV;
- goto unlock_out;
- }
- msi_desc->pi_desc = pi_desc;
- msi_desc->gvec = gvec;
-
- spin_unlock_irq(&desc->lock);
-
- ASSERT(pcidevs_locked());
-
- return msi_msg_write_remap_rte(msi_desc, &msi_desc->msg);
-
- unlock_out:
- spin_unlock_irq(&desc->lock);
-
- return rc;
-}
diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x86/hvm.c
index dd09ec22f1..7b9ad7bae2 100644
--- a/xen/drivers/passthrough/x86/hvm.c
+++ b/xen/drivers/passthrough/x86/hvm.c
@@ -380,8 +380,7 @@ int pt_irq_create_bind(

/* Use interrupt posting if it is supported. */
if ( iommu_intpost )
- pi_update_irte(vcpu ? &vcpu->arch.hvm.vmx.pi_desc : NULL,
- info, pirq_dpci->gmsi.gvec);
+ hvm_pi_update_irte(vcpu, info, pirq_dpci->gmsi.gvec);

if ( pt_irq_bind->u.msi.gflags & XEN_DOMCTL_VMSI_X86_UNMASKED )
{
@@ -671,7 +670,7 @@ int pt_irq_destroy_bind(
what = "bogus";
}
else if ( pirq_dpci && pirq_dpci->gmsi.posted )
- pi_update_irte(NULL, pirq, 0);
+ hvm_pi_update_irte(NULL, pirq, 0);

if ( pirq_dpci && (pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) &&
list_empty(&pirq_dpci->digl_list) )
--
generated by git-patchbot for /home/xen/git/xen.git#master