mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Add the support of x2apic logical cluster mode.
Add a xen boolean parameter 'x2apic'. Add a xen boolean parameter 'x2apic_phys'(by default, we use logical cluster mode). Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
This commit is contained in:
1 parent
5c53154b61
commit
b8fae2f777
3 files changed
+100
-28
No files matched your search
+25
-10
@@ -848,8 +848,31 @@ void enable_x2apic(void)
|
||||
{
|
||||
u32 lo, hi;
|
||||
|
||||
if ( !iommu_supports_eim() )
|
||||
return;
|
||||
if ( smp_processor_id() == 0 )
|
||||
{
|
||||
if ( !iommu_supports_eim() )
|
||||
{
|
||||
printk("x2APIC would not be enabled without EIM.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( apic_x2apic_phys.probe() )
|
||||
genapic = &apic_x2apic_phys;
|
||||
else if ( apic_x2apic_cluster.probe() )
|
||||
genapic = &apic_x2apic_cluster;
|
||||
else
|
||||
{
|
||||
printk("x2APIC would not be enabled due to x2apic=off.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
x2apic_enabled = 1;
|
||||
printk("Switched to APIC driver %s.\n", genapic->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
BUG_ON(!x2apic_enabled); /* APs only enable x2apic when BSP did so. */
|
||||
}
|
||||
|
||||
rdmsr(MSR_IA32_APICBASE, lo, hi);
|
||||
if ( !(lo & MSR_IA32_APICBASE_EXTD) )
|
||||
@@ -860,14 +883,6 @@ void enable_x2apic(void)
|
||||
}
|
||||
else
|
||||
printk("x2APIC mode enabled by BIOS.\n");
|
||||
|
||||
if ( !x2apic_enabled )
|
||||
{
|
||||
x2apic_enabled = 1;
|
||||
genapic = &apic_x2apic;
|
||||
printk(KERN_INFO "Switched to APIC driver %s.\n",
|
||||
genapic->name);
|
||||
}
|
||||
}
|
||||
|
||||
void __init init_apic_mappings(void)
|
||||
|
||||
@@ -23,25 +23,46 @@
|
||||
#include <xen/smp.h>
|
||||
#include <asm/mach-default/mach_mpparse.h>
|
||||
|
||||
__init int probe_x2apic(void)
|
||||
static int x2apic = 1;
|
||||
boolean_param("x2apic", x2apic);
|
||||
|
||||
static int x2apic_phys = 0; /* By default we use logical cluster mode. */
|
||||
boolean_param("x2apic_phys", x2apic_phys);
|
||||
|
||||
__init int probe_x2apic_phys(void)
|
||||
{
|
||||
return x2apic_is_available();
|
||||
return x2apic && x2apic_phys && x2apic_is_available() &&
|
||||
iommu_supports_eim();
|
||||
}
|
||||
|
||||
struct genapic apic_x2apic= {
|
||||
APIC_INIT("x2apic", probe_x2apic),
|
||||
GENAPIC_X2APIC
|
||||
__init int probe_x2apic_cluster(void)
|
||||
{
|
||||
return x2apic && !x2apic_phys && x2apic_is_available() &&
|
||||
iommu_supports_eim();
|
||||
}
|
||||
|
||||
struct genapic apic_x2apic_phys= {
|
||||
APIC_INIT("x2apic_phys", probe_x2apic_phys),
|
||||
GENAPIC_X2APIC_PHYS
|
||||
};
|
||||
|
||||
void init_apic_ldr_x2apic(void)
|
||||
struct genapic apic_x2apic_cluster= {
|
||||
APIC_INIT("x2apic_cluster", probe_x2apic_cluster),
|
||||
GENAPIC_X2APIC_CLUSTER
|
||||
};
|
||||
|
||||
void init_apic_ldr_x2apic_phys(void)
|
||||
{
|
||||
/* We only use physical delivery mode. */
|
||||
return;
|
||||
}
|
||||
|
||||
void init_apic_ldr_x2apic_cluster(void)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
cpu_2_logical_apicid[cpu] = apic_read(APIC_LDR);
|
||||
}
|
||||
void clustered_apic_check_x2apic(void)
|
||||
{
|
||||
/* We only use physical delivery mode. */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,12 +76,17 @@ cpumask_t vector_allocation_domain_x2apic(int cpu)
|
||||
return cpumask_of_cpu(cpu);
|
||||
}
|
||||
|
||||
unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask)
|
||||
unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask)
|
||||
{
|
||||
return cpu_physical_id(first_cpu(cpumask));
|
||||
}
|
||||
|
||||
void send_IPI_mask_x2apic(const cpumask_t *cpumask, int vector)
|
||||
unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask)
|
||||
{
|
||||
return cpu_2_logical_apicid[first_cpu(cpumask)];
|
||||
}
|
||||
|
||||
void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector)
|
||||
{
|
||||
unsigned int cpu, cfg;
|
||||
unsigned long flags;
|
||||
@@ -87,3 +113,19 @@ void send_IPI_mask_x2apic(const cpumask_t *cpumask, int vector)
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector)
|
||||
{
|
||||
unsigned int cpu, cfg;
|
||||
unsigned long flags;
|
||||
|
||||
mb(); /* see the comment in send_IPI_mask_x2apic_phys() */
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
cfg = APIC_DM_FIXED | 0 /* no shorthand */ | APIC_DEST_LOGICAL | vector;
|
||||
for_each_cpu_mask ( cpu, *cpumask )
|
||||
if ( cpu != smp_processor_id() )
|
||||
apic_wrmsr(APIC_ICR, cfg, cpu_2_logical_apicid[cpu]);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
@@ -49,7 +49,8 @@ struct genapic {
|
||||
APICFUNC(acpi_madt_oem_check)
|
||||
|
||||
extern struct genapic *genapic;
|
||||
extern struct genapic apic_x2apic;
|
||||
extern struct genapic apic_x2apic_phys;
|
||||
extern struct genapic apic_x2apic_cluster;
|
||||
|
||||
void init_apic_ldr_flat(void);
|
||||
void clustered_apic_check_flat(void);
|
||||
@@ -69,24 +70,38 @@ cpumask_t vector_allocation_domain_flat(int cpu);
|
||||
.send_IPI_mask = send_IPI_mask_flat, \
|
||||
.send_IPI_self = send_IPI_self_flat
|
||||
|
||||
void init_apic_ldr_x2apic(void);
|
||||
void init_apic_ldr_x2apic_phys(void);
|
||||
void init_apic_ldr_x2apic_cluster(void);
|
||||
void clustered_apic_check_x2apic(void);
|
||||
cpumask_t target_cpus_x2apic(void);
|
||||
unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask);
|
||||
void send_IPI_mask_x2apic(const cpumask_t *mask, int vector);
|
||||
unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask);
|
||||
unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask);
|
||||
void send_IPI_mask_x2apic_phys(const cpumask_t *mask, int vector);
|
||||
void send_IPI_mask_x2apic_cluster(const cpumask_t *mask, int vector);
|
||||
void send_IPI_self_x2apic(int vector);
|
||||
cpumask_t vector_allocation_domain_x2apic(int cpu);
|
||||
#define GENAPIC_X2APIC \
|
||||
#define GENAPIC_X2APIC_PHYS \
|
||||
.int_delivery_mode = dest_Fixed, \
|
||||
.int_dest_mode = 0 /* physical delivery */, \
|
||||
.init_apic_ldr = init_apic_ldr_x2apic, \
|
||||
.init_apic_ldr = init_apic_ldr_x2apic_phys, \
|
||||
.clustered_apic_check = clustered_apic_check_x2apic, \
|
||||
.target_cpus = target_cpus_x2apic, \
|
||||
.vector_allocation_domain = vector_allocation_domain_x2apic, \
|
||||
.cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic, \
|
||||
.send_IPI_mask = send_IPI_mask_x2apic, \
|
||||
.cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_phys, \
|
||||
.send_IPI_mask = send_IPI_mask_x2apic_phys, \
|
||||
.send_IPI_self = send_IPI_self_x2apic
|
||||
|
||||
#define GENAPIC_X2APIC_CLUSTER \
|
||||
.int_delivery_mode = dest_LowestPrio, \
|
||||
.int_dest_mode = 1 /* logical delivery */, \
|
||||
.init_apic_ldr = init_apic_ldr_x2apic_cluster, \
|
||||
.clustered_apic_check = clustered_apic_check_x2apic, \
|
||||
.target_cpus = target_cpus_x2apic, \
|
||||
.vector_allocation_domain = vector_allocation_domain_x2apic, \
|
||||
.cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_cluster, \
|
||||
.send_IPI_mask = send_IPI_mask_x2apic_cluster, \
|
||||
.send_IPI_self = send_IPI_self_x2apic
|
||||
|
||||
void init_apic_ldr_phys(void);
|
||||
void clustered_apic_check_phys(void);
|
||||
cpumask_t target_cpus_phys(void);
|
||||
|
||||