diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 12dd938f5d54f70f01795773e020bbfb976ce4de..fd52fcb6fa1657420812a5064c8e83d8963c6d3c 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1254,11 +1254,6 @@ static int ioapic_retrigger_vector(unsigned int vector)
  * races.
  */
 
-static void ack_apic(unsigned int irq)
-{
-	ack_APIC_irq();
-}
-
 static void ack_apic_edge(unsigned int irq)
 {
 	move_native_irq(irq);
@@ -1698,6 +1693,52 @@ static int __init ioapic_init_sysfs(void)
 
 device_initcall(ioapic_init_sysfs);
 
+#ifdef CONFIG_PCI_MSI
+/*
+ * Dynamic irq allocate and deallocation for MSI
+ */
+int create_irq(void)
+{
+	/* Hack of the day: irq == vector.
+	 *
+	 * Ultimately this will be be more general,
+	 * and not depend on the irq to vector identity mapping.
+	 * But this version is needed until msi.c can cope with
+	 * the more general form.
+	 */
+	int irq, vector;
+	unsigned long flags;
+	vector = assign_irq_vector(AUTO_ASSIGN);
+	irq = vector;
+
+	if (vector >= 0) {
+		spin_lock_irqsave(&vector_lock, flags);
+		vector_irq[vector] = irq;
+		irq_vector[irq] = vector;
+		spin_unlock_irqrestore(&vector_lock, flags);
+
+		set_intr_gate(vector, interrupt[irq]);
+
+		dynamic_irq_init(irq);
+	}
+	return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+	unsigned long flags;
+	unsigned int vector;
+
+	dynamic_irq_cleanup(irq);
+
+	spin_lock_irqsave(&vector_lock, flags);
+	vector = irq_vector[irq];
+	vector_irq[vector] = -1;
+	irq_vector[irq] = 0;
+	spin_unlock_irqrestore(&vector_lock, flags);
+}
+#endif
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- */