hv: align the MAX_IR_ENTRIES to MAX_PT_IRQ_ENTRIES

The CONFIG_MAX_IR_ENTRIES and CONFIG_MAX_PT_IRQ_ENTRIES are separate
configuration items, and they can be configured through configuration tool

When the number of PT irq entries are more than IR entries, then some
passthrough devices' irqs may failed to be protected by interrupt
remapping or automatically injected by post-interrupt mechanism.
And it waste memory if the CONFIG_MAX_IR_ENTRIES is larger.

This patch replace the CONFIG_MAX_IR_ENTRIES to MAX_IR_ENTRIES and
enforce it align to CONFIG_PT_IRQ_ENTRIES and round up to > 2^n as the
IRTA_REG spec.This way can enforce all PT irqs works with IR or PI
mechanism.

Tracked-On: #6745
Signed-off-by: Chenli Wei <chenli.wei@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
Reviewed-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Chenli Wei
2021-10-25 18:44:36 +08:00
committed by wenlingz
parent 58e27983b4
commit 022df1fb2e
4 changed files with 40 additions and 11 deletions

View File

@@ -42,6 +42,13 @@
#define DMAR_ICS_REG 0x9cU /* Invalidation complete status register */
#define DMAR_IRTA_REG 0xb8U /* Interrupt remapping table addr register */
/* Make sure all PT IRQs work w/ interrupt remapping or post interrupt */
#if (CONFIG_MAX_PT_IRQ_ENTRIES <= 256)
#define MAX_IR_ENTRIES 256
#else
#define MAX_IR_ENTRIES powerof2_roundup(CONFIG_MAX_PT_IRQ_ENTRIES)
#endif
/* Values for entry_type in ACPI_DMAR_DEVICE_SCOPE - device types */
enum acpi_dmar_scope_type {
ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,

View File

@@ -25,6 +25,27 @@
/** Replaces 'x' by the string "x". */
#define STRINGIFY(x) #x
/*
* This algorithm get the round up 2^n
*
* n = input - 1; 0x1002 ----> 0x1001
* n |= n >> 1; 0x1001 | 0x800
* n |= n >> 2; 0x1801 | 0x600
* n |= n >> 4; 0x1e01 | 0x1e0
* n |= n >> 8; 0x1fe1 | 0x1f
* n |= n >> 16; 0x1fff
* n |= n >> 32; 0x1fff
* n += 1; 0x2000
*/
#define ROUND0(x) ((x)-1)
#define ROUND1(x) (ROUND0(x) |(ROUND0(x)>>1))
#define ROUND2(x) (ROUND1(x) |(ROUND1(x)>>2))
#define ROUND4(x) (ROUND2(x) |(ROUND2(x)>>4))
#define ROUND8(x) (ROUND4(x) |(ROUND4(x)>>8))
#define ROUND16(x) (ROUND8(x) |(ROUND8(x)>>16))
#define ROUND32(x) (ROUND16(x) |(ROUND16(x)>>32))
#define powerof2_roundup(x) ((ROUND32(x) == (~0UL)) ? ~0UL : (ROUND32(x) +1))
/* Macro used to check if a value is aligned to the required boundary.
* Returns TRUE if aligned; FALSE if not aligned
* NOTE: The required alignment must be a power of 2 (2, 4, 8, 16, 32, etc)