Commit 6d786fdb authored by Jan Beulich's avatar Jan Beulich

x86/IOMMU: abstract Intel-specific iommu_{en,dis}able_x2apic_IR()

Introduce respective elements in struct iommu_init_ops as well as a
pointer to the main ops structure.
Signed-off-by: default avatarJan Beulich <jbeulich@suse.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarAndrew Cooper <andrew.cooper3@citrix.com>
parent cd768032
......@@ -510,7 +510,7 @@ static void resume_x2apic(void)
mask_8259A();
mask_IO_APIC_setup(ioapic_entries);
iommu_enable_x2apic_IR();
iommu_enable_x2apic();
__enable_x2apic();
restore_IO_APIC_setup(ioapic_entries);
......@@ -720,7 +720,7 @@ int lapic_suspend(void)
local_irq_save(flags);
disable_local_APIC();
iommu_disable_x2apic_IR();
iommu_disable_x2apic();
local_irq_restore(flags);
return 0;
}
......@@ -924,7 +924,7 @@ void __init x2apic_bsp_setup(void)
mask_8259A();
mask_IO_APIC_setup(ioapic_entries);
switch ( iommu_enable_x2apic_IR() )
switch ( iommu_enable_x2apic() )
{
case 0:
break;
......
......@@ -35,6 +35,8 @@ void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn);
keyhandler_fn_t vtd_dump_iommu_info;
bool intel_iommu_supports_eim(void);
int intel_iommu_enable_eim(void);
void intel_iommu_disable_eim(void);
int enable_qinval(struct iommu *iommu);
void disable_qinval(struct iommu *iommu);
......
......@@ -887,23 +887,13 @@ out:
* This function is used to enable Interrupt remapping when
* enable x2apic
*/
int iommu_enable_x2apic_IR(void)
int intel_iommu_enable_eim(void)
{
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
if ( system_state < SYS_STATE_active )
{
if ( !intel_iommu_supports_eim() )
return -EOPNOTSUPP;
if ( !platform_supports_x2apic() )
return -ENXIO;
iommu_ops = intel_iommu_ops;
}
else if ( !x2apic_enabled )
return -EOPNOTSUPP;
if ( system_state < SYS_STATE_active && !platform_supports_x2apic() )
return -ENXIO;
for_each_drhd_unit ( drhd )
{
......@@ -948,17 +938,13 @@ int iommu_enable_x2apic_IR(void)
}
/*
* This function is used to disable Interrutp remapping when
* This function is used to disable Interrupt remapping when
* suspend local apic
*/
void iommu_disable_x2apic_IR(void)
void intel_iommu_disable_eim(void)
{
struct acpi_drhd_unit *drhd;
/* x2apic_enabled implies iommu_supports_eim(). */
if ( !x2apic_enabled )
return;
for_each_drhd_unit ( drhd )
disable_intremap(drhd->iommu);
......
......@@ -2720,6 +2720,8 @@ const struct iommu_ops __initconstrel intel_iommu_ops = {
.free_page_table = iommu_free_page_table,
.reassign_device = reassign_device_ownership,
.get_device_group_id = intel_iommu_group_id,
.enable_x2apic = intel_iommu_enable_eim,
.disable_x2apic = intel_iommu_disable_eim,
.update_ire_from_apic = io_apic_write_remap_rte,
.update_ire_from_msi = msi_msg_write_remap_rte,
.read_apic_from_ire = io_apic_read_remap_rte,
......@@ -2736,6 +2738,7 @@ const struct iommu_ops __initconstrel intel_iommu_ops = {
};
const struct iommu_init_ops __initconstrel intel_iommu_init_ops = {
.ops = &intel_iommu_ops,
.setup = vtd_setup,
.supports_x2apic = intel_iommu_supports_eim,
};
......
......@@ -26,6 +26,24 @@
const struct iommu_init_ops *__initdata iommu_init_ops;
struct iommu_ops __read_mostly iommu_ops;
int iommu_enable_x2apic(void)
{
if ( system_state < SYS_STATE_active )
{
if ( !iommu_supports_x2apic() )
return -EOPNOTSUPP;
iommu_ops = *iommu_init_ops->ops;
}
else if ( !x2apic_enabled )
return -EOPNOTSUPP;
if ( !iommu_ops.enable_x2apic )
return -EOPNOTSUPP;
return iommu_ops.enable_x2apic();
}
void iommu_update_ire_from_apic(
unsigned int apic, unsigned int reg, unsigned int value)
{
......
......@@ -25,7 +25,6 @@ enum apic_mode {
};
extern u8 apic_verbosity;
extern bool x2apic_enabled;
extern bool directed_eoi_enabled;
void check_x2apic_preenabled(void);
......
......@@ -126,4 +126,6 @@
#define MAX_IO_APICS 128
extern bool x2apic_enabled;
#endif
......@@ -17,6 +17,7 @@
#include <xen/errno.h>
#include <xen/list.h>
#include <xen/spinlock.h>
#include <asm/apicdef.h>
#include <asm/processor.h>
#include <asm/hvm/vmx/vmcs.h>
......@@ -65,6 +66,7 @@ static inline const struct iommu_ops *iommu_get_ops(void)
}
struct iommu_init_ops {
const struct iommu_ops *ops;
int (*setup)(void);
bool (*supports_x2apic)(void);
};
......@@ -96,8 +98,13 @@ static inline bool iommu_supports_x2apic(void)
: false;
}
int iommu_enable_x2apic_IR(void);
void iommu_disable_x2apic_IR(void);
int iommu_enable_x2apic(void);
static inline void iommu_disable_x2apic(void)
{
if ( x2apic_enabled && iommu_ops.disable_x2apic )
iommu_ops.disable_x2apic();
}
extern bool untrusted_msi;
......
......@@ -216,11 +216,16 @@ struct iommu_ops {
unsigned int *flags);
void (*free_page_table)(struct page_info *);
#ifdef CONFIG_X86
int (*enable_x2apic)(void);
void (*disable_x2apic)(void);
void (*update_ire_from_apic)(unsigned int apic, unsigned int reg, unsigned int value);
unsigned int (*read_apic_from_ire)(unsigned int apic, unsigned int reg);
int (*setup_hpet_msi)(struct msi_desc *);
#endif /* CONFIG_X86 */
int __must_check (*suspend)(void);
void (*resume)(void);
void (*share_p2m)(struct domain *d);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment