Skip to content

Commit

Permalink
Merge tag 'intr-remapping-ops-for-ingo' of git://git.kernel.org/pub/s…
Browse files Browse the repository at this point in the history
…cm/linux/kernel/git/joro/iommu into core/iommu

- This patchset introduces a generic ops-interface for
  accessing interrupt remapping hardware on x86. It factors
  out the VT-d specific code from io_apic.c and moves it to
  drivers/iommu. These changes will be used to add support for
  AMD interrupt remapping hardware.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed May 7, 2012
2 parents febb72a + 8a8f422 commit 79fec2c
Show file tree
Hide file tree
Showing 12 changed files with 724 additions and 450 deletions.
4 changes: 4 additions & 0 deletions arch/ia64/include/asm/irq_remapping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#ifndef __IA64_INTR_REMAPPING_H
#define __IA64_INTR_REMAPPING_H
#define irq_remapping_enabled 0
#endif
120 changes: 89 additions & 31 deletions arch/x86/include/asm/irq_remapping.h
Original file line number Diff line number Diff line change
@@ -1,45 +1,103 @@
#ifndef _ASM_X86_IRQ_REMAPPING_H
#define _ASM_X86_IRQ_REMAPPING_H
/*
* Copyright (C) 2012 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This header file contains the interface of the interrupt remapping code to
* the x86 interrupt management code.
*/

#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8)
#ifndef __X86_IRQ_REMAPPING_H
#define __X86_IRQ_REMAPPING_H

#ifdef CONFIG_IRQ_REMAP
static void irq_remap_modify_chip_defaults(struct irq_chip *chip);
static inline void prepare_irte(struct irte *irte, int vector,
unsigned int dest)

struct IO_APIC_route_entry;
struct io_apic_irq_attr;
struct pci_dev;

extern int irq_remapping_enabled;

extern void setup_irq_remapping_ops(void);
extern int irq_remapping_supported(void);
extern int irq_remapping_prepare(void);
extern int irq_remapping_enable(void);
extern void irq_remapping_disable(void);
extern int irq_remapping_reenable(int);
extern int irq_remap_enable_fault_handling(void);
extern int setup_ioapic_remapped_entry(int irq,
struct IO_APIC_route_entry *entry,
unsigned int destination,
int vector,
struct io_apic_irq_attr *attr);
extern int set_remapped_irq_affinity(struct irq_data *data,
const struct cpumask *mask,
bool force);
extern void free_remapped_irq(int irq);
extern void compose_remapped_msi_msg(struct pci_dev *pdev,
unsigned int irq, unsigned int dest,
struct msi_msg *msg, u8 hpet_id);
extern int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec);
extern int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
int index, int sub_handle);
extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id);

#else /* CONFIG_IRQ_REMAP */

#define irq_remapping_enabled 0

static inline void setup_irq_remapping_ops(void) { }
static inline int irq_remapping_supported(void) { return 0; }
static inline int irq_remapping_prepare(void) { return -ENODEV; }
static inline int irq_remapping_enable(void) { return -ENODEV; }
static inline void irq_remapping_disable(void) { }
static inline int irq_remapping_reenable(int eim) { return -ENODEV; }
static inline int irq_remap_enable_fault_handling(void) { return -ENODEV; }
static inline int setup_ioapic_remapped_entry(int irq,
struct IO_APIC_route_entry *entry,
unsigned int destination,
int vector,
struct io_apic_irq_attr *attr)
{
return -ENODEV;
}
static inline int set_remapped_irq_affinity(struct irq_data *data,
const struct cpumask *mask,
bool force)
{
memset(irte, 0, sizeof(*irte));

irte->present = 1;
irte->dst_mode = apic->irq_dest_mode;
/*
* Trigger mode in the IRTE will always be edge, and for IO-APIC, the
* actual level or edge trigger will be setup in the IO-APIC
* RTE. This will help simplify level triggered irq migration.
* For more details, see the comments (in io_apic.c) explainig IO-APIC
* irq migration in the presence of interrupt-remapping.
*/
irte->trigger_mode = 0;
irte->dlvry_mode = apic->irq_delivery_mode;
irte->vector = vector;
irte->dest_id = IRTE_DEST(dest);
irte->redir_hint = 1;
return 0;
}
static inline bool irq_remapped(struct irq_cfg *cfg)
static inline void free_remapped_irq(int irq) { }
static inline void compose_remapped_msi_msg(struct pci_dev *pdev,
unsigned int irq, unsigned int dest,
struct msi_msg *msg, u8 hpet_id)
{
return cfg->irq_2_iommu.iommu != NULL;
}
#else
static void prepare_irte(struct irte *irte, int vector, unsigned int dest)
static inline int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec)
{
return -ENODEV;
}
static inline bool irq_remapped(struct irq_cfg *cfg)
static inline int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
int index, int sub_handle)
{
return false;
return -ENODEV;
}
static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip)
static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
{
return -ENODEV;
}
#endif
#endif /* CONFIG_IRQ_REMAP */

#endif /* _ASM_X86_IRQ_REMAPPING_H */
#endif /* __X86_IRQ_REMAPPING_H */
30 changes: 17 additions & 13 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <linux/smp.h>
#include <linux/mm.h>

#include <asm/irq_remapping.h>
#include <asm/perf_event.h>
#include <asm/x86_init.h>
#include <asm/pgalloc.h>
Expand Down Expand Up @@ -1441,8 +1442,8 @@ void __init bsp_end_local_APIC_setup(void)
* Now that local APIC setup is completed for BP, configure the fault
* handling for interrupt remapping.
*/
if (intr_remapping_enabled)
enable_drhd_fault_handling();
if (irq_remapping_enabled)
irq_remap_enable_fault_handling();

}

Expand Down Expand Up @@ -1517,7 +1518,7 @@ void enable_x2apic(void)
int __init enable_IR(void)
{
#ifdef CONFIG_IRQ_REMAP
if (!intr_remapping_supported()) {
if (!irq_remapping_supported()) {
pr_debug("intr-remapping not supported\n");
return -1;
}
Expand All @@ -1528,7 +1529,7 @@ int __init enable_IR(void)
return -1;
}

return enable_intr_remapping();
return irq_remapping_enable();
#endif
return -1;
}
Expand All @@ -1537,10 +1538,13 @@ void __init enable_IR_x2apic(void)
{
unsigned long flags;
int ret, x2apic_enabled = 0;
int dmar_table_init_ret;
int hardware_init_ret;

dmar_table_init_ret = dmar_table_init();
if (dmar_table_init_ret && !x2apic_supported())
/* Make sure irq_remap_ops are initialized */
setup_irq_remapping_ops();

hardware_init_ret = irq_remapping_prepare();
if (hardware_init_ret && !x2apic_supported())
return;

ret = save_ioapic_entries();
Expand All @@ -1556,7 +1560,7 @@ void __init enable_IR_x2apic(void)
if (x2apic_preenabled && nox2apic)
disable_x2apic();

if (dmar_table_init_ret)
if (hardware_init_ret)
ret = -1;
else
ret = enable_IR();
Expand Down Expand Up @@ -2176,8 +2180,8 @@ static int lapic_suspend(void)
local_irq_save(flags);
disable_local_APIC();

if (intr_remapping_enabled)
disable_intr_remapping();
if (irq_remapping_enabled)
irq_remapping_disable();

local_irq_restore(flags);
return 0;
Expand All @@ -2193,7 +2197,7 @@ static void lapic_resume(void)
return;

local_irq_save(flags);
if (intr_remapping_enabled) {
if (irq_remapping_enabled) {
/*
* IO-APIC and PIC have their own resume routines.
* We just mask them here to make sure the interrupt
Expand Down Expand Up @@ -2245,8 +2249,8 @@ static void lapic_resume(void)
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);

if (intr_remapping_enabled)
reenable_intr_remapping(x2apic_mode);
if (irq_remapping_enabled)
irq_remapping_reenable(x2apic_mode);

local_irq_restore(flags);
}
Expand Down
Loading

0 comments on commit 79fec2c

Please sign in to comment.