/*
* Knob to control our willingness to enable the local APIC.
*/
-int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
/*
* Debug level
static void __init lapic_disable(char *str)
{
enable_local_apic = -1;
- clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+ setup_clear_cpu_cap(X86_FEATURE_APIC);
}
custom_param("nolapic", lapic_disable);
*/
u64 host_pat = 0x050100070406;
+static unsigned int __cpuinitdata cleared_caps[NCAPINTS];
+
+void __init setup_clear_cpu_cap(unsigned int cap)
+{
+ __clear_bit(cap, boot_cpu_data.x86_capability);
+ __set_bit(cap, cleared_caps);
+}
+
static void default_init(struct cpuinfo_x86 * c)
{
/* Not much we can do here... */
if (c->x86 >= 0x6)
c->x86_model += ((tfms >> 16) & 0xF) << 4;
c->x86_mask = tfms & 15;
+ cap0 &= ~cleared_caps[0];
if (cap0 & (1<<19))
c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
c->x86_capability[0] = cap0; /* Added for Xen bootstrap */
if (disable_pse)
clear_bit(X86_FEATURE_PSE, c->x86_capability);
+ for (i = 0 ; i < NCAPINTS ; ++i)
+ c->x86_capability[i] &= ~cleared_caps[i];
+
/* If the model name is still unset, do table lookup. */
if ( !c->x86_model_id[0] ) {
char *p;
static struct irq_pin_list {
int apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
+} irq_2_pin[PIN_MAP_SIZE] = {
+ [0 ... PIN_MAP_SIZE-1].pin = -1
+};
static int irq_2_pin_free_entry = NR_IRQS;
int vector_irq[NR_VECTORS] __read_mostly = {
int i, apic;
unsigned long flags;
- for (i = 0; i < PIN_MAP_SIZE; i++) {
- irq_2_pin[i].pin = -1;
- irq_2_pin[i].next = 0;
- }
-
/* Initialise dynamic irq_2_pin free list. */
for (i = NR_IRQS; i < PIN_MAP_SIZE; i++)
irq_2_pin[i].next = i + 1;
return -EINVAL;
}
- old_vector = d->arch.pirq_vector[pirq];
- old_pirq = d->arch.vector_pirq[vector];
+ old_vector = domain_irq_to_vector(d, pirq);
+ old_pirq = domain_vector_to_irq(d, vector);
if ( (old_vector && (old_vector != vector) ) ||
(old_pirq && (old_pirq != pirq)) )
{
struct msi_info *msi = (struct msi_info *)data;
+ ret = -ENODEV;
+ if ( !cpu_has_apic )
+ goto done;
+
pdev = pci_get_pdev(msi->bus, msi->devfn);
ret = pci_enable_msi(msi, &msi_desc);
if ( ret )
ASSERT(spin_is_locked(&pcidevs_lock));
ASSERT(spin_is_locked(&d->event_lock));
- vector = d->arch.pirq_vector[pirq];
+ vector = domain_irq_to_vector(d, pirq);
if ( vector <= 0 )
{
dprintk(XENLOG_G_ERR, "dom%d: pirq %d not mapped\n",
spin_lock_irqsave(&desc->lock, flags);
- BUG_ON(vector != d->arch.pirq_vector[pirq]);
+ BUG_ON(vector != domain_irq_to_vector(d, pirq));
if ( msi_desc )
teardown_msi_vector(vector);
spin_lock(&pcidevs_lock);
/* Verify or get pirq. */
spin_lock(&d->event_lock);
+ pirq = domain_vector_to_irq(d, vector);
if ( map->pirq < 0 )
{
- if ( d->arch.vector_pirq[vector] )
+ if ( pirq )
{
dprintk(XENLOG_G_ERR, "dom%d: %d:%d already mapped to %d\n",
d->domain_id, map->index, map->pirq,
- d->arch.vector_pirq[vector]);
- pirq = d->arch.vector_pirq[vector];
+ pirq);
if ( pirq < 0 )
{
ret = -EBUSY;
}
else
{
- if ( d->arch.vector_pirq[vector] &&
- d->arch.vector_pirq[vector] != map->pirq )
+ if ( pirq && pirq != map->pirq )
{
dprintk(XENLOG_G_ERR, "dom%d: vector %d conflicts with irq %d\n",
d->domain_id, map->index, map->pirq);
int get_free_pirq(struct domain *d, int type, int index);
void free_domain_pirqs(struct domain *d);
-#define domain_irq_to_vector(d, irq) ((d)->arch.pirq_vector[(irq)])
-#define domain_vector_to_irq(d, vec) ((d)->arch.vector_pirq[(vec)])
+#define domain_irq_to_vector(d, irq) ((d)->arch.pirq_vector[irq] ?: \
+ IO_APIC_IRQ(irq) ? 0 : LEGACY_VECTOR(irq))
+#define domain_vector_to_irq(d, vec) ((d)->arch.vector_pirq[vec] ?: \
+ ((vec) < FIRST_LEGACY_VECTOR || \
+ (vec) > LAST_LEGACY_VECTOR) ? \
+ 0 : LEGACY_IRQ_FROM_VECTOR(vec))
int pirq_guest_force_unbind(struct domain *d, int irq);
extern int cpu_core_id[NR_CPUS];
extern void identify_cpu(struct cpuinfo_x86 *);
+extern void setup_clear_cpu_cap(unsigned int);
extern void print_cpu_info(struct cpuinfo_x86 *);
extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
extern void dodgy_tsc(void);