diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index c684faa..e6fc5d7 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -30,6 +30,7 @@ void pciehp_queue_interrupt_event(struct slot *p_slot, u32 event_type)
 	info = kmalloc(sizeof(*info), GFP_ATOMIC);
 	if (!info) {
 		ctrl_err(p_slot->ctrl, "dropped event %d (ENOMEM)\n", event_type);
+		slot_being_removed_rescanned = 0;
 		return;
 	}
 
@@ -174,6 +175,7 @@ static void pciehp_power_thread(struct work_struct *work)
 		mutex_lock(&p_slot->lock);
 		p_slot->state = STATIC_STATE;
 		mutex_unlock(&p_slot->lock);
+		slot_being_removed_rescanned = 0;
 		break;
 	case ENABLE_REQ:
 		mutex_lock(&p_slot->hotplug_lock);
@@ -184,6 +186,7 @@ static void pciehp_power_thread(struct work_struct *work)
 		mutex_lock(&p_slot->lock);
 		p_slot->state = STATIC_STATE;
 		mutex_unlock(&p_slot->lock);
+		slot_being_removed_rescanned = 0;
 		break;
 	default:
 		break;
@@ -202,6 +205,7 @@ static void pciehp_queue_power_work(struct slot *p_slot, int req)
 	if (!info) {
 		ctrl_err(p_slot->ctrl, "no memory to queue %s request\n",
 			 (req == ENABLE_REQ) ? "poweron" : "poweroff");
+		slot_being_removed_rescanned = 0;
 		return;
 	}
 	info->p_slot = p_slot;
@@ -270,6 +274,7 @@ static void handle_button_press_event(struct slot *p_slot)
 		ctrl_info(ctrl, "Slot(%s): Action canceled due to button press\n",
 			  slot_name(p_slot));
 		p_slot->state = STATIC_STATE;
+		slot_being_removed_rescanned = 0;
 		break;
 	case POWEROFF_STATE:
 	case POWERON_STATE:
@@ -280,10 +285,12 @@ static void handle_button_press_event(struct slot *p_slot)
 		 */
 		ctrl_info(ctrl, "Slot(%s): Button ignored\n",
 			  slot_name(p_slot));
+		slot_being_removed_rescanned = 0;
 		break;
 	default:
 		ctrl_err(ctrl, "Slot(%s): Ignoring invalid state %#x\n",
 			 slot_name(p_slot), p_slot->state);
+		slot_being_removed_rescanned = 0;
 		break;
 	}
 }
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 18a42f8..5ef5387 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -608,7 +608,17 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
 	if (events & PCI_EXP_SLTSTA_ABP) {
 		ctrl_info(ctrl, "Slot(%s): Attention button pressed\n",
 			  slot_name(slot));
-		pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS);
+
+		if (!test_and_set_bit(0, &slot_being_removed_rescanned))
+			pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS);
+		else {
+			if (slot->state == BLINKINGOFF_STATE || slot->state == BLINKINGON_STATE)
+				pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS);
+			else
+				ctrl_info(ctrl, "Slot(%s): Slot operation failed because a remove or"
+					" rescan operation is under processing, please try later!\n",
+					slot_name(slot));
+		}
 	}
 
 	/*
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index eb6bee8..9fd1699 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -499,8 +499,15 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
 	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
-	if (val && device_remove_file_self(dev, attr))
-		pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
+	if (val && device_remove_file_self(dev, attr)) {
+		if (!test_and_set_bit(0, &slot_being_removed_rescanned)) {
+			pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
+			slot_being_removed_rescanned = 0;
+		} else {
+			pr_info("Slot is being removed or rescanned, please try later!\n");
+			return -EPERM;
+		}
+	}
 	return count;
 }
 static struct device_attribute dev_remove_attr = __ATTR(remove,
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 6f072ea..6d36d53 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -4,6 +4,12 @@
 #include <linux/pci-aspm.h>
 #include "pci.h"
 
+/*
+ * When a slot is being hotplug through Attention Button or being
+ * removed/rescanned through sysfs, this flag is set.
+ */
+unsigned long slot_being_removed_rescanned;
+
 static void pci_free_resources(struct pci_dev *dev)
 {
 	int i;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 024a1be..e1711ce 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -846,6 +846,9 @@ enum pcie_bus_config_types {
 /* Do NOT directly access these two variables, unless you are arch-specific PCI
  * code, or PCI core code. */
 extern struct list_head pci_root_buses;	/* List of all known PCI buses */
+
+extern unsigned long slot_being_removed_rescanned;
+
 /* Some device drivers need know if PCI is initiated */
 int no_pci_devices(void);
 
