/*
 * PCI Stub Driver - Grabs devices in backend to be exported later
 *
 * Ryan Wilson <hap9@epoch.ncsc.mil>
 * Chris Bookholt <hap10@epoch.ncsc.mil>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/init.h>
#include <linux/rwsem.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <linux/pci.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/atomic.h>
#include <xen/events.h>
#include <asm/xen/pci.h>
#include <asm/xen/hypervisor.h>
#include <xen/interface/physdev.h>
#include "pciback.h"
#include "conf_space.h"
#include "conf_space_quirks.h"

static char *pci_devs_to_hide;
wait_queue_head_t xen_pcibk_aer_wait_queue;
/*Add sem for sync AER handling and xen_pcibk remove/reconfigue ops,
* We want to avoid in middle of AER ops, xen_pcibk devices is being removed
*/
static DECLARE_RWSEM(pcistub_sem);
module_param_named(hide, pci_devs_to_hide, charp, 0444);

struct pcistub_device_id {
	struct list_head slot_list;
	int domain;
	unsigned char bus;
	unsigned int devfn;
};
static LIST_HEAD(pcistub_device_ids);
static DEFINE_SPINLOCK(device_ids_lock);

struct pcistub_device {
	struct kref kref;
	struct list_head dev_list;
	spinlock_t lock;

	struct pci_dev *dev;
	struct xen_pcibk_device *pdev;/* non-NULL if struct pci_dev is in use */
};

/* Access to pcistub_devices & seized_devices lists and the initialize_devices
 * flag must be locked with pcistub_devices_lock
 */
static DEFINE_SPINLOCK(pcistub_devices_lock);
static LIST_HEAD(pcistub_devices);

/* wait for device_initcall before initializing our devices
 * (see pcistub_init_devices_late)
 */
static int initialize_devices;
static LIST_HEAD(seized_devices);

static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
{
	struct pcistub_device *psdev;

	dev_dbg(&dev->dev, "pcistub_device_alloc\n");

	psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
	if (!psdev)
		return NULL;

	psdev->dev = pci_dev_get(dev);
	if (!psdev->dev) {
		kfree(psdev);
		return NULL;
	}

	kref_init(&psdev->kref);
	spin_lock_init(&psdev->lock);

	return psdev;
}

/* Don't call this directly as it's called by pcistub_device_put */
static void pcistub_device_release(struct kref *kref)
{
	struct pcistub_device *psdev;
	struct pci_dev *dev;
	struct xen_pcibk_dev_data *dev_data;

	psdev = container_of(kref, struct pcistub_device, kref);
	dev = psdev->dev;
	dev_data = pci_get_drvdata(dev);

	dev_dbg(&dev->dev, "pcistub_device_release\n");

	xen_unregister_device_domain_owner(dev);

	/* Call the reset function which does not take lock as this
	 * is called from "unbind" which takes a device_lock mutex.
	 */
	__pci_reset_function_locked(dev);
	if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state))
		dev_dbg(&dev->dev, "Could not reload PCI state\n");
	else
		pci_restore_state(dev);

	if (dev->msix_cap) {
		struct physdev_pci_device ppdev = {
			.seg = pci_domain_nr(dev->bus),
			.bus = dev->bus->number,
			.devfn = dev->devfn
		};
		int err = HYPERVISOR_physdev_op(PHYSDEVOP_release_msix,
						&ppdev);

		if (err)
			dev_warn(&dev->dev, "MSI-X release failed (%d)\n",
				 err);
	}

	/* Disable the device */
	xen_pcibk_reset_device(dev);

	kfree(dev_data);
	pci_set_drvdata(dev, NULL);

	/* Clean-up the device */
	xen_pcibk_config_free_dyn_fields(dev);
	xen_pcibk_config_free_dev(dev);

	dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
	pci_dev_put(dev);

	kfree(psdev);
}

static inline void pcistub_device_get(struct pcistub_device *psdev)
{
	kref_get(&psdev->kref);
}

static inline void pcistub_device_put(struct pcistub_device *psdev)
{
	kref_put(&psdev->kref, pcistub_device_release);
}

static struct pcistub_device *pcistub_device_find(int domain, int bus,
						  int slot, int func)
{
	struct pcistub_device *psdev = NULL;
	unsigned long flags;

	spin_lock_irqsave(&pcistub_devices_lock, flags);

	list_for_each_entry(psdev, &pcistub_devices, dev_list) {
		if (psdev->dev != NULL
		    && domain == pci_domain_nr(psdev->dev->bus)
		    && bus == psdev->dev->bus->number
		    && slot == PCI_SLOT(psdev->dev->devfn)
		    && func == PCI_FUNC(psdev->dev->devfn)) {
			pcistub_device_get(psdev);
			goto out;
		}
	}

	/* didn't find it */
	psdev = NULL;

out:
	spin_unlock_irqrestore(&pcistub_devices_lock, flags);
	return psdev;
}

static struct pci_dev *pcistub_device_get_pci_dev(struct xen_pcibk_device *pdev,
						  struct pcistub_device *psdev)
{
	struct pci_dev *pci_dev = NULL;
	unsigned long flags;

	pcistub_device_get(psdev);

	spin_lock_irqsave(&psdev->lock, flags);
	if (!psdev->pdev) {
		psdev->pdev = pdev;
		pci_dev = psdev->dev;
	}
	spin_unlock_irqrestore(&psdev->lock, flags);

	if (!pci_dev)
		pcistub_device_put(psdev);

	return pci_dev;
}

struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev,
					    int domain, int bus,
					    int slot, int func)
{
	struct pcistub_device *psdev;
	struct pci_dev *found_dev = NULL;
	unsigned long flags;

	spin_lock_irqsave(&pcistub_devices_lock, flags);

	list_for_each_entry(psdev, &pcistub_devices, dev_list) {
		if (psdev->dev != NULL
		    && domain == pci_domain_nr(psdev->dev->bus)
		    && bus == psdev->dev->bus->number
		    && slot == PCI_SLOT(psdev->dev->devfn)
		    && func == PCI_FUNC(psdev->dev->devfn)) {
			found_dev = pcistub_device_get_pci_dev(pdev, psdev);
			break;
		}
	}

	spin_unlock_irqrestore(&pcistub_devices_lock, flags);
	return found_dev;
}

struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev,
				    struct pci_dev *dev)
{
	struct pcistub_device *psdev;
	struct pci_dev *found_dev = NULL;
	unsigned long flags;

	spin_lock_irqsave(&pcistub_devices_lock, flags);

	list_for_each_entry(psdev, &pcistub_devices, dev_list) {
		if (psdev->dev == dev) {
			found_dev = pcistub_device_get_pci_dev(pdev, psdev);
			break;
		}
	}

	spin_unlock_irqrestore(&pcistub_devices_lock, flags);
	return found_dev;
}

void pcistub_put_pci_dev(struct pci_dev *dev)
{
	struct pcistub_device *psdev, *found_psdev = NULL;
	unsigned long flags;

	spin_lock_irqsave(&pcistub_devices_lock, flags);

	list_for_each_entry(psdev, &pcistub_devices, dev_list) {
		if (psdev->dev == dev) {
			found_psdev = psdev;
			break;
		}
	}

	spin_unlock_irqrestore(&pcistub_devices_lock, flags);
	if (WARN_ON(!found_psdev))
		return;

	/*hold this lock for avoiding breaking link between
	* pcistub and xen_pcibk when AER is in processing
	*/
	down_write(&pcistub_sem);
	/* Cleanup our device
	 * (so it's ready for the next domain)
	 */

	/* This is OK - we are running from workqueue context
	 * and want to inhibit the user from fiddling with 'reset'
	 */
	pci_reset_function(dev);
	pci_restore_state(psdev->dev);

	/* This disables the device. */
	xen_pcibk_reset_device(found_psdev->dev);

	/* And cleanup up our emulated fields. */
	xen_pcibk_config_free_dyn_fields(found_psdev->dev);
	xen_pcibk_config_reset_dev(found_psdev->dev);

	xen_unregister_device_domain_owner(found_psdev->dev);

	spin_lock_irqsave(&found_psdev->lock, flags);
	found_psdev->pdev = NULL;
	spin_unlock_irqrestore(&found_psdev->lock, flags);

	pcistub_device_put(found_psdev);
	up_write(&pcistub_sem);
}

static int pcistub_match_one(struct pci_dev *dev,
			     struct pcistub_device_id *pdev_id)
{
	/* Match the specified device by domain, bus, slot, func and also if
	 * any of the device's parent bridges match.
	 */
	for (; dev != NULL; dev = dev->bus->self) {
		if (pci_domain_nr(dev->bus) == pdev_id->domain
		    && dev->bus->number == pdev_id->bus
		    && dev->devfn == pdev_id->devfn)
			return 1;

		/* Sometimes topmost bridge links to itself. */
		if (dev == dev->bus->self)
			break;
	}

	return 0;
}

static int pcistub_match(struct pci_dev *dev)
{
	struct pcistub_device_id *pdev_id;
	unsigned long flags;
	int found = 0;

	spin_lock_irqsave(&device_ids_lock, flags);
	list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) {
		if (pcistub_match_one(dev, pdev_id)) {
			found = 1;
			break;
		}
	}
	spin_unlock_irqrestore(&device_ids_lock, flags);

	return found;
}

static int pcistub_init_device(struct pci_dev *dev)
{
	struct xen_pcibk_dev_data *dev_data;
	int err = 0;

	dev_dbg(&dev->dev, "initializing...\n");

	/* The PCI backend is not intended to be a module (or to work with
	 * removable PCI devices (yet). If it were, xen_pcibk_config_free()
	 * would need to be called somewhere to free the memory allocated
	 * here and then to call kfree(pci_get_drvdata(psdev->dev)).
	 */
	dev_data = kzalloc(sizeof(*dev_data) +  strlen(DRV_NAME "[]")
				+ strlen(pci_name(dev)) + 1, GFP_ATOMIC);
	if (!dev_data) {
		err = -ENOMEM;
		goto out;
	}
	pci_set_drvdata(dev, dev_data);

	/*
	 * Setup name for fake IRQ handler. It will only be enabled
	 * once the device is turned on by the guest.
	 */
	sprintf(dev_data->irq_name, DRV_NAME "[%s]", pci_name(dev));

	dev_dbg(&dev->dev, "initializing config\n");

	init_waitqueue_head(&xen_pcibk_aer_wait_queue);
	err = xen_pcibk_config_init_dev(dev);
	if (err)
		goto out;

	/* HACK: Force device (& ACPI) to determine what IRQ it's on - we
	 * must do this here because pcibios_enable_device may specify
	 * the pci device's true irq (and possibly its other resources)
	 * if they differ from what's in the configuration space.
	 * This makes the assumption that the device's resources won't
	 * change after this point (otherwise this code may break!)
	 */
	dev_dbg(&dev->dev, "enabling device\n");
	err = pci_enable_device(dev);
	if (err)
		goto config_release;

	if (dev->msix_cap) {
		struct physdev_pci_device ppdev = {
			.seg = pci_domain_nr(dev->bus),
			.bus = dev->bus->number,
			.devfn = dev->devfn
		};

		err = HYPERVISOR_physdev_op(PHYSDEVOP_prepare_msix, &ppdev);
		if (err)
			dev_err(&dev->dev, "MSI-X preparation failed (%d)\n",
				err);
	}

	/* We need the device active to save the state. */
	dev_dbg(&dev->dev, "save state of device\n");
	pci_save_state(dev);
	dev_data->pci_saved_state = pci_store_saved_state(dev);
	if (!dev_data->pci_saved_state)
		dev_err(&dev->dev, "Could not store PCI conf saved state!\n");
	else {
		dev_dbg(&dev->dev, "resetting (FLR, D3, etc) the device\n");
		__pci_reset_function_locked(dev);
		pci_restore_state(dev);
	}
	/* Now disable the device (this also ensures some private device
	 * data is setup before we export)
	 */
	dev_dbg(&dev->dev, "reset device\n");
	xen_pcibk_reset_device(dev);

	dev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;
	return 0;

config_release:
	xen_pcibk_config_free_dev(dev);

out:
	pci_set_drvdata(dev, NULL);
	kfree(dev_data);
	return err;
}

/*
 * Because some initialization still happens on
 * devices during fs_initcall, we need to defer
 * full initialization of our devices until
 * device_initcall.
 */
static int __init pcistub_init_devices_late(void)
{
	struct pcistub_device *psdev;
	unsigned long flags;
	int err = 0;

	spin_lock_irqsave(&pcistub_devices_lock, flags);

	while (!list_empty(&seized_devices)) {
		psdev = container_of(seized_devices.next,
				     struct pcistub_device, dev_list);
		list_del(&psdev->dev_list);

		spin_unlock_irqrestore(&pcistub_devices_lock, flags);

		err = pcistub_init_device(psdev->dev);
		if (err) {
			dev_err(&psdev->dev->dev,
				"error %d initializing device\n", err);
			kfree(psdev);
			psdev = NULL;
		}

		spin_lock_irqsave(&pcistub_devices_lock, flags);

		if (psdev)
			list_add_tail(&psdev->dev_list, &pcistub_devices);
	}

	initialize_devices = 1;

	spin_unlock_irqrestore(&pcistub_devices_lock, flags);

	return 0;
}

static int pcistub_seize(struct pci_dev *dev)
{
	struct pcistub_device *psdev;
	unsigned long flags;
	int err = 0;

	psdev = pcistub_device_alloc(dev);
	if (!psdev)
		return -ENOMEM;

	spin_lock_irqsave(&pcistub_devices_lock, flags);

	if (initialize_devices) {
		spin_unlock_irqrestore(&pcistub_devices_lock, flags);

		/* don't want irqs disabled when calling pcistub_init_device */
		err = pcistub_init_device(psdev->dev);

		spin_lock_irqsave(&pcistub_devices_lock, flags);

		if (!err)
			list_add(&psdev->dev_list, &pcistub_devices);
	} else {
		dev_dbg(&dev->dev, "deferring initialization\n");
		list_add(&psdev->dev_list, &seized_devices);
	}

	spin_unlock_irqrestore(&pcistub_devices_lock, flags);

	if (err)
		pcistub_device_put(psdev);

	return err;
}

static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	int err = 0;

	dev_dbg(&dev->dev, "probing...\n");

	if (pcistub_match(dev)) {

		if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
		    && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
			dev_err(&dev->dev, "can't export pci devices that "
				"don't have a normal (0) or bridge (1) "
				"header type!\n");
			err = -ENODEV;
			goto out;
		}

		dev_info(&dev->dev, "seizing device\n");
		err = pcistub_seize(dev);
	} else
		/* Didn't find the device */
		err = -ENODEV;

out:
	return err;
}

static void pcistub_remove(struct pci_dev *dev)
{
	struct pcistub_device *psdev, *found_psdev = NULL;
	unsigned long flags;

	dev_dbg(&dev->dev, "removing\n");

	spin_lock_irqsave(&pcistub_devices_lock, flags);

	xen_pcibk_config_quirk_release(dev);

	list_for_each_entry(psdev, &pcistub_devices, dev_list) {
		if (psdev->dev == dev) {
			found_psdev = psdev;
			break;
		}
	}

	spin_unlock_irqrestore(&pcistub_devices_lock, flags);

	if (found_psdev) {
		dev_dbg(&dev->dev, "found device to remove - in use? %p\n",
			found_psdev->pdev);

		if (found_psdev->pdev) {
			pr_warn("****** removing device %s while still in-use! ******\n",
			       pci_name(found_psdev->dev));
			pr_warn("****** driver domain may still access this device's i/o resources!\n");
			pr_warn("****** shutdown driver domain before binding device\n");
			pr_warn("****** to other drivers or domains\n");

			xen_pcibk_release_pci_dev(found_psdev->pdev,
						found_psdev->dev);
		}

		spin_lock_irqsave(&pcistub_devices_lock, flags);
		list_del(&found_psdev->dev_list);
		spin_unlock_irqrestore(&pcistub_devices_lock, flags);

		/* the final put for releasing from the list */
		pcistub_device_put(found_psdev);
	}
}

static DEFINE_PCI_DEVICE_TABLE(pcistub_ids) = {
	{
	 .vendor = PCI_ANY_ID,
	 .device = PCI_ANY_ID,
	 .subvendor = PCI_ANY_ID,
	 .subdevice = PCI_ANY_ID,
	 },
	{0,},
};

#define PCI_NODENAME_MAX 40
static void kill_domain_by_device(struct pcistub_device *psdev)
{
	struct xenbus_transaction xbt;
	int err;
	char nodename[PCI_NODENAME_MAX];

	BUG_ON(!psdev);
	snprintf(nodename, PCI_NODENAME_MAX, "/local/domain/0/backend/pci/%d/0",
		psdev->pdev->xdev->otherend_id);

again:
	err = xenbus_transaction_start(&xbt);
	if (err) {
		dev_err(&psdev->dev->dev,
			"error %d when start xenbus transaction\n", err);
		return;
	}
	/*PV AER handlers will set this flag*/
	xenbus_printf(xbt, nodename, "aerState" , "aerfail");
	err = xenbus_transaction_end(xbt, 0);
	if (err) {
		if (err == -EAGAIN)
			goto again;
		dev_err(&psdev->dev->dev,
			"error %d when end xenbus transaction\n", err);
		return;
	}
}

/* For each aer recovery step error_detected, mmio_enabled, etc, front_end and
 * backend need to have cooperation. In xen_pcibk, those steps will do similar
 * jobs: send service request and waiting for front_end response.
*/
static pci_ers_result_t common_process(struct pcistub_device *psdev,
				       pci_channel_state_t state, int aer_cmd,
				       pci_ers_result_t result)
{
	pci_ers_result_t res = result;
	struct xen_pcie_aer_op *aer_op;
	int ret;

	/*with PV AER drivers*/
	aer_op = &(psdev->pdev->sh_info->aer_op);
	aer_op->cmd = aer_cmd ;
	/*useful for error_detected callback*/
	aer_op->err = state;
	/*pcifront_end BDF*/
	ret = xen_pcibk_get_pcifront_dev(psdev->dev, psdev->pdev,
		&aer_op->domain, &aer_op->bus, &aer_op->devfn);
	if (!ret) {
		dev_err(&psdev->dev->dev,
			DRV_NAME ": failed to get pcifront device\n");
		return PCI_ERS_RESULT_NONE;
	}
	wmb();

	dev_dbg(&psdev->dev->dev,
			DRV_NAME ": aer_op %x dom %x bus %x devfn %x\n",
			aer_cmd, aer_op->domain, aer_op->bus, aer_op->devfn);
	/*local flag to mark there's aer request, xen_pcibk callback will use
	* this flag to judge whether we need to check pci-front give aer
	* service ack signal
	*/
	set_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags);

	/*It is possible that a pcifront conf_read_write ops request invokes
	* the callback which cause the spurious execution of wake_up.
	* Yet it is harmless and better than a spinlock here
	*/
	set_bit(_XEN_PCIB_active,
		(unsigned long *)&psdev->pdev->sh_info->flags);
	wmb();
	notify_remote_via_irq(psdev->pdev->evtchn_irq);

	ret = wait_event_timeout(xen_pcibk_aer_wait_queue,
				 !(test_bit(_XEN_PCIB_active, (unsigned long *)
				 &psdev->pdev->sh_info->flags)), 300*HZ);

	if (!ret) {
		if (test_bit(_XEN_PCIB_active,
			(unsigned long *)&psdev->pdev->sh_info->flags)) {
			dev_err(&psdev->dev->dev,
				"pcifront aer process not responding!\n");
			clear_bit(_XEN_PCIB_active,
			  (unsigned long *)&psdev->pdev->sh_info->flags);
			aer_op->err = PCI_ERS_RESULT_NONE;
			return res;
		}
	}
	clear_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags);

	if (test_bit(_XEN_PCIF_active,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_dbg(&psdev->dev->dev,
			"schedule pci_conf service in " DRV_NAME "\n");
		xen_pcibk_test_and_schedule_op(psdev->pdev);
	}

	res = (pci_ers_result_t)aer_op->err;
	return res;
}

/*
* xen_pcibk_slot_reset: it will send the slot_reset request to  pcifront in case
* of the device driver could provide this service, and then wait for pcifront
* ack.
* @dev: pointer to PCI devices
* return value is used by aer_core do_recovery policy
*/
static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
{
	struct pcistub_device *psdev;
	pci_ers_result_t result;

	result = PCI_ERS_RESULT_RECOVERED;
	dev_dbg(&dev->dev, "xen_pcibk_slot_reset(bus:%x,devfn:%x)\n",
		dev->bus->number, dev->devfn);

	down_write(&pcistub_sem);
	psdev = pcistub_device_find(pci_domain_nr(dev->bus),
				dev->bus->number,
				PCI_SLOT(dev->devfn),
				PCI_FUNC(dev->devfn));

	if (!psdev || !psdev->pdev) {
		dev_err(&dev->dev,
			DRV_NAME " device is not found/assigned\n");
		goto end;
	}

	if (!psdev->pdev->sh_info) {
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		goto end;
	}

	if (!test_bit(_XEN_PCIB_AERHANDLER,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_err(&dev->dev,
			"guest with no AER driver should have been killed\n");
		goto end;
	}
	result = common_process(psdev, 1, XEN_PCI_OP_aer_slotreset, result);

	if (result == PCI_ERS_RESULT_NONE ||
		result == PCI_ERS_RESULT_DISCONNECT) {
		dev_dbg(&dev->dev,
			"No AER slot_reset service or disconnected!\n");
		kill_domain_by_device(psdev);
	}
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	return result;

}


/*xen_pcibk_mmio_enabled: it will send the mmio_enabled request to  pcifront
* in case of the device driver could provide this service, and then wait
* for pcifront ack
* @dev: pointer to PCI devices
* return value is used by aer_core do_recovery policy
*/

static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
{
	struct pcistub_device *psdev;
	pci_ers_result_t result;

	result = PCI_ERS_RESULT_RECOVERED;
	dev_dbg(&dev->dev, "xen_pcibk_mmio_enabled(bus:%x,devfn:%x)\n",
		dev->bus->number, dev->devfn);

	down_write(&pcistub_sem);
	psdev = pcistub_device_find(pci_domain_nr(dev->bus),
				dev->bus->number,
				PCI_SLOT(dev->devfn),
				PCI_FUNC(dev->devfn));

	if (!psdev || !psdev->pdev) {
		dev_err(&dev->dev,
			DRV_NAME " device is not found/assigned\n");
		goto end;
	}

	if (!psdev->pdev->sh_info) {
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		goto end;
	}

	if (!test_bit(_XEN_PCIB_AERHANDLER,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_err(&dev->dev,
			"guest with no AER driver should have been killed\n");
		goto end;
	}
	result = common_process(psdev, 1, XEN_PCI_OP_aer_mmio, result);

	if (result == PCI_ERS_RESULT_NONE ||
		result == PCI_ERS_RESULT_DISCONNECT) {
		dev_dbg(&dev->dev,
			"No AER mmio_enabled service or disconnected!\n");
		kill_domain_by_device(psdev);
	}
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	return result;
}

/*xen_pcibk_error_detected: it will send the error_detected request to  pcifront
* in case of the device driver could provide this service, and then wait
* for pcifront ack.
* @dev: pointer to PCI devices
* @error: the current PCI connection state
* return value is used by aer_core do_recovery policy
*/

static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
	pci_channel_state_t error)
{
	struct pcistub_device *psdev;
	pci_ers_result_t result;

	result = PCI_ERS_RESULT_CAN_RECOVER;
	dev_dbg(&dev->dev, "xen_pcibk_error_detected(bus:%x,devfn:%x)\n",
		dev->bus->number, dev->devfn);

	down_write(&pcistub_sem);
	psdev = pcistub_device_find(pci_domain_nr(dev->bus),
				dev->bus->number,
				PCI_SLOT(dev->devfn),
				PCI_FUNC(dev->devfn));

	if (!psdev || !psdev->pdev) {
		dev_err(&dev->dev,
			DRV_NAME " device is not found/assigned\n");
		goto end;
	}

	if (!psdev->pdev->sh_info) {
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		goto end;
	}

	/*Guest owns the device yet no aer handler regiested, kill guest*/
	if (!test_bit(_XEN_PCIB_AERHANDLER,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n");
		kill_domain_by_device(psdev);
		goto end;
	}
	result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result);

	if (result == PCI_ERS_RESULT_NONE ||
		result == PCI_ERS_RESULT_DISCONNECT) {
		dev_dbg(&dev->dev,
			"No AER error_detected service or disconnected!\n");
		kill_domain_by_device(psdev);
	}
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	return result;
}

/*xen_pcibk_error_resume: it will send the error_resume request to  pcifront
* in case of the device driver could provide this service, and then wait
* for pcifront ack.
* @dev: pointer to PCI devices
*/

static void xen_pcibk_error_resume(struct pci_dev *dev)
{
	struct pcistub_device *psdev;

	dev_dbg(&dev->dev, "xen_pcibk_error_resume(bus:%x,devfn:%x)\n",
		dev->bus->number, dev->devfn);

	down_write(&pcistub_sem);
	psdev = pcistub_device_find(pci_domain_nr(dev->bus),
				dev->bus->number,
				PCI_SLOT(dev->devfn),
				PCI_FUNC(dev->devfn));

	if (!psdev || !psdev->pdev) {
		dev_err(&dev->dev,
			DRV_NAME " device is not found/assigned\n");
		goto end;
	}

	if (!psdev->pdev->sh_info) {
		dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
			" by HVM, kill it\n");
		kill_domain_by_device(psdev);
		goto end;
	}

	if (!test_bit(_XEN_PCIB_AERHANDLER,
		(unsigned long *)&psdev->pdev->sh_info->flags)) {
		dev_err(&dev->dev,
			"guest with no AER driver should have been killed\n");
		kill_domain_by_device(psdev);
		goto end;
	}
	common_process(psdev, 1, XEN_PCI_OP_aer_resume,
		       PCI_ERS_RESULT_RECOVERED);
end:
	if (psdev)
		pcistub_device_put(psdev);
	up_write(&pcistub_sem);
	return;
}

/*add xen_pcibk AER handling*/
static const struct pci_error_handlers xen_pcibk_error_handler = {
	.error_detected = xen_pcibk_error_detected,
	.mmio_enabled = xen_pcibk_mmio_enabled,
	.slot_reset = xen_pcibk_slot_reset,
	.resume = xen_pcibk_error_resume,
};

/*
 * Note: There is no MODULE_DEVICE_TABLE entry here because this isn't
 * for a normal device. I don't want it to be loaded automatically.
 */

static struct pci_driver xen_pcibk_pci_driver = {
	/* The name should be xen_pciback, but until the tools are updated
	 * we will keep it as pciback. */
	.name = "pciback",
	.id_table = pcistub_ids,
	.probe = pcistub_probe,
	.remove = pcistub_remove,
	.err_handler = &xen_pcibk_error_handler,
};

static inline int str_to_slot(const char *buf, int *domain, int *bus,
			      int *slot, int *func)
{
	int parsed = 0;

	switch (sscanf(buf, " %x:%x:%x.%x %n", domain, bus, slot, func,
		       &parsed)) {
	case 3:
		*func = -1;
		sscanf(buf, " %x:%x:%x.* %n", domain, bus, slot, &parsed);
		break;
	case 2:
		*slot = *func = -1;
		sscanf(buf, " %x:%x:*.* %n", domain, bus, &parsed);
		break;
	}
	if (parsed && !buf[parsed])
		return 0;

	/* try again without domain */
	*domain = 0;
	switch (sscanf(buf, " %x:%x.%x %n", bus, slot, func, &parsed)) {
	case 2:
		*func = -1;
		sscanf(buf, " %x:%x.* %n", bus, slot, &parsed);
		break;
	case 1:
		*slot = *func = -1;
		sscanf(buf, " %x:*.* %n", bus, &parsed);
		break;
	}
	if (parsed && !buf[parsed])
		return 0;

	return -EINVAL;
}

static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
			       *slot, int *func, int *reg, int *size, int *mask)
{
	int parsed = 0;

	sscanf(buf, " %x:%x:%x.%x-%x:%x:%x %n", domain, bus, slot, func,
	       reg, size, mask, &parsed);
	if (parsed && !buf[parsed])
		return 0;

	/* try again without domain */
	*domain = 0;
	sscanf(buf, " %x:%x.%x-%x:%x:%x %n", bus, slot, func, reg, size,
	       mask, &parsed);
	if (parsed && !buf[parsed])
		return 0;

	return -EINVAL;
}

static int pcistub_device_id_add(int domain, int bus, int slot, int func)
{
	struct pcistub_device_id *pci_dev_id;
	unsigned long flags;
	int rc = 0, devfn = PCI_DEVFN(slot, func);

	if (slot < 0) {
		for (slot = 0; !rc && slot < 32; ++slot)
			rc = pcistub_device_id_add(domain, bus, slot, func);
		return rc;
	}

	if (func < 0) {
		for (func = 0; !rc && func < 8; ++func)
			rc = pcistub_device_id_add(domain, bus, slot, func);
		return rc;
	}

	if ((
#if !defined(MODULE) /* pci_domains_supported is not being exported */ \
    || !defined(CONFIG_PCI_DOMAINS)
	     !pci_domains_supported ? domain :
#endif
	     domain < 0 || domain > 0xffff)
	    || bus < 0 || bus > 0xff
	    || PCI_SLOT(devfn) != slot
	    || PCI_FUNC(devfn) != func)
		return -EINVAL;

	pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
	if (!pci_dev_id)
		return -ENOMEM;

	pci_dev_id->domain = domain;
	pci_dev_id->bus = bus;
	pci_dev_id->devfn = devfn;

	pr_debug("wants to seize %04x:%02x:%02x.%d\n",
		 domain, bus, slot, func);

	spin_lock_irqsave(&device_ids_lock, flags);
	list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids);
	spin_unlock_irqrestore(&device_ids_lock, flags);

	return 0;
}

static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
{
	struct pcistub_device_id *pci_dev_id, *t;
	int err = -ENOENT;
	unsigned long flags;

	spin_lock_irqsave(&device_ids_lock, flags);
	list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids,
				 slot_list) {
		if (pci_dev_id->domain == domain && pci_dev_id->bus == bus
		    && (slot < 0 || PCI_SLOT(pci_dev_id->devfn) == slot)
		    && (func < 0 || PCI_FUNC(pci_dev_id->devfn) == func)) {
			/* Don't break; here because it's possible the same
			 * slot could be in the list more than once
			 */
			list_del(&pci_dev_id->slot_list);
			kfree(pci_dev_id);

			err = 0;

			pr_debug("removed %04x:%02x:%02x.%d from seize list\n",
				 domain, bus, slot, func);
		}
	}
	spin_unlock_irqrestore(&device_ids_lock, flags);

	return err;
}

static int pcistub_reg_add(int domain, int bus, int slot, int func,
			   unsigned int reg, unsigned int size,
			   unsigned int mask)
{
	int err = 0;
	struct pcistub_device *psdev;
	struct pci_dev *dev;
	struct config_field *field;

	if (reg > 0xfff || (size < 4 && (mask >> (size * 8))))
		return -EINVAL;

	psdev = pcistub_device_find(domain, bus, slot, func);
	if (!psdev) {
		err = -ENODEV;
		goto out;
	}
	dev = psdev->dev;

	field = kzalloc(sizeof(*field), GFP_ATOMIC);
	if (!field) {
		err = -ENOMEM;
		goto out;
	}

	field->offset = reg;
	field->size = size;
	field->mask = mask;
	field->init = NULL;
	field->reset = NULL;
	field->release = NULL;
	field->clean = xen_pcibk_config_field_free;

	err = xen_pcibk_config_quirks_add_field(dev, field);
	if (err)
		kfree(field);
out:
	if (psdev)
		pcistub_device_put(psdev);
	return err;
}

static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
				size_t count)
{
	int domain, bus, slot, func;
	int err;

	err = str_to_slot(buf, &domain, &bus, &slot, &func);
	if (err)
		goto out;

	err = pcistub_device_id_add(domain, bus, slot, func);

out:
	if (!err)
		err = count;
	return err;
}
static DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);

static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
				   size_t count)
{
	int domain, bus, slot, func;
	int err;

	err = str_to_slot(buf, &domain, &bus, &slot, &func);
	if (err)
		goto out;

	err = pcistub_device_id_remove(domain, bus, slot, func);

out:
	if (!err)
		err = count;
	return err;
}
static DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);

static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
{
	struct pcistub_device_id *pci_dev_id;
	size_t count = 0;
	unsigned long flags;

	spin_lock_irqsave(&device_ids_lock, flags);
	list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) {
		if (count >= PAGE_SIZE)
			break;

		count += scnprintf(buf + count, PAGE_SIZE - count,
				   "%04x:%02x:%02x.%d\n",
				   pci_dev_id->domain, pci_dev_id->bus,
				   PCI_SLOT(pci_dev_id->devfn),
				   PCI_FUNC(pci_dev_id->devfn));
	}
	spin_unlock_irqrestore(&device_ids_lock, flags);

	return count;
}
static DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);

static ssize_t pcistub_irq_handler_show(struct device_driver *drv, char *buf)
{
	struct pcistub_device *psdev;
	struct xen_pcibk_dev_data *dev_data;
	size_t count = 0;
	unsigned long flags;

	spin_lock_irqsave(&pcistub_devices_lock, flags);
	list_for_each_entry(psdev, &pcistub_devices, dev_list) {
		if (count >= PAGE_SIZE)
			break;
		if (!psdev->dev)
			continue;
		dev_data = pci_get_drvdata(psdev->dev);
		if (!dev_data)
			continue;
		count +=
		    scnprintf(buf + count, PAGE_SIZE - count,
			      "%s:%s:%sing:%ld\n",
			      pci_name(psdev->dev),
			      dev_data->isr_on ? "on" : "off",
			      dev_data->ack_intr ? "ack" : "not ack",
			      dev_data->handled);
	}
	spin_unlock_irqrestore(&pcistub_devices_lock, flags);
	return count;
}
static DRIVER_ATTR(irq_handlers, S_IRUSR, pcistub_irq_handler_show, NULL);

static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
					  const char *buf,
					  size_t count)
{
	struct pcistub_device *psdev;
	struct xen_pcibk_dev_data *dev_data;
	int domain, bus, slot, func;
	int err;

	err = str_to_slot(buf, &domain, &bus, &slot, &func);
	if (err)
		return err;

	psdev = pcistub_device_find(domain, bus, slot, func);
	if (!psdev) {
		err = -ENOENT;
		goto out;
	}

	dev_data = pci_get_drvdata(psdev->dev);
	if (!dev_data) {
		err = -ENOENT;
		goto out;
	}

	dev_dbg(&psdev->dev->dev, "%s fake irq handler: %d->%d\n",
		dev_data->irq_name, dev_data->isr_on,
		!dev_data->isr_on);

	dev_data->isr_on = !(dev_data->isr_on);
	if (dev_data->isr_on)
		dev_data->ack_intr = 1;
out:
	if (psdev)
		pcistub_device_put(psdev);
	if (!err)
		err = count;
	return err;
}
static DRIVER_ATTR(irq_handler_state, S_IWUSR, NULL,
		   pcistub_irq_handler_switch);

static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf,
				 size_t count)
{
	int domain, bus, slot, func, reg, size, mask;
	int err;

	err = str_to_quirk(buf, &domain, &bus, &slot, &func, &reg, &size,
			   &mask);
	if (err)
		goto out;

	err = pcistub_reg_add(domain, bus, slot, func, reg, size, mask);

out:
	if (!err)
		err = count;
	return err;
}

static ssize_t pcistub_quirk_show(struct device_driver *drv, char *buf)
{
	int count = 0;
	unsigned long flags;
	struct xen_pcibk_config_quirk *quirk;
	struct xen_pcibk_dev_data *dev_data;
	const struct config_field *field;
	const struct config_field_entry *cfg_entry;

	spin_lock_irqsave(&device_ids_lock, flags);
	list_for_each_entry(quirk, &xen_pcibk_quirks, quirks_list) {
		if (count >= PAGE_SIZE)
			goto out;

		count += scnprintf(buf + count, PAGE_SIZE - count,
				   "%02x:%02x.%01x\n\t%04x:%04x:%04x:%04x\n",
				   quirk->pdev->bus->number,
				   PCI_SLOT(quirk->pdev->devfn),
				   PCI_FUNC(quirk->pdev->devfn),
				   quirk->devid.vendor, quirk->devid.device,
				   quirk->devid.subvendor,
				   quirk->devid.subdevice);

		dev_data = pci_get_drvdata(quirk->pdev);

		list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
			field = cfg_entry->field;
			if (count >= PAGE_SIZE)
				goto out;

			count += scnprintf(buf + count, PAGE_SIZE - count,
					   "\t\t%08x:%01x:%08x\n",
					   cfg_entry->base_offset +
					   field->offset, field->size,
					   field->mask);
		}
	}

out:
	spin_unlock_irqrestore(&device_ids_lock, flags);

	return count;
}
static DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show,
		   pcistub_quirk_add);

static ssize_t permissive_add(struct device_driver *drv, const char *buf,
			      size_t count)
{
	int domain, bus, slot, func;
	int err;
	struct pcistub_device *psdev;
	struct xen_pcibk_dev_data *dev_data;

	err = str_to_slot(buf, &domain, &bus, &slot, &func);
	if (err)
		goto out;

	psdev = pcistub_device_find(domain, bus, slot, func);
	if (!psdev) {
		err = -ENODEV;
		goto out;
	}

	dev_data = pci_get_drvdata(psdev->dev);
	/* the driver data for a device should never be null at this point */
	if (!dev_data) {
		err = -ENXIO;
		goto release;
	}
	if (!dev_data->permissive) {
		dev_data->permissive = 1;
		/* Let user know that what they're doing could be unsafe */
		dev_warn(&psdev->dev->dev, "enabling permissive mode "
			 "configuration space accesses!\n");
		dev_warn(&psdev->dev->dev,
			 "permissive mode is potentially unsafe!\n");
	}
release:
	pcistub_device_put(psdev);
out:
	if (!err)
		err = count;
	return err;
}

static ssize_t permissive_show(struct device_driver *drv, char *buf)
{
	struct pcistub_device *psdev;
	struct xen_pcibk_dev_data *dev_data;
	size_t count = 0;
	unsigned long flags;
	spin_lock_irqsave(&pcistub_devices_lock, flags);
	list_for_each_entry(psdev, &pcistub_devices, dev_list) {
		if (count >= PAGE_SIZE)
			break;
		if (!psdev->dev)
			continue;
		dev_data = pci_get_drvdata(psdev->dev);
		if (!dev_data || !dev_data->permissive)
			continue;
		count +=
		    scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
			      pci_name(psdev->dev));
	}
	spin_unlock_irqrestore(&pcistub_devices_lock, flags);
	return count;
}
static DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show,
		   permissive_add);

static void pcistub_exit(void)
{
	driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_new_slot);
	driver_remove_file(&xen_pcibk_pci_driver.driver,
			   &driver_attr_remove_slot);
	driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_slots);
	driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_quirks);
	driver_remove_file(&xen_pcibk_pci_driver.driver,
			   &driver_attr_permissive);
	driver_remove_file(&xen_pcibk_pci_driver.driver,
			   &driver_attr_irq_handlers);
	driver_remove_file(&xen_pcibk_pci_driver.driver,
			   &driver_attr_irq_handler_state);
	pci_unregister_driver(&xen_pcibk_pci_driver);
}

static int __init pcistub_init(void)
{
	int pos = 0;
	int err = 0;
	int domain, bus, slot, func;
	int parsed;

	if (pci_devs_to_hide && *pci_devs_to_hide) {
		do {
			parsed = 0;

			err = sscanf(pci_devs_to_hide + pos,
				     " (%x:%x:%x.%x) %n",
				     &domain, &bus, &slot, &func, &parsed);
			switch (err) {
			case 3:
				func = -1;
				sscanf(pci_devs_to_hide + pos,
				       " (%x:%x:%x.*) %n",
				       &domain, &bus, &slot, &parsed);
				break;
			case 2:
				slot = func = -1;
				sscanf(pci_devs_to_hide + pos,
				       " (%x:%x:*.*) %n",
				       &domain, &bus, &parsed);
				break;
			}

			if (!parsed) {
				domain = 0;
				err = sscanf(pci_devs_to_hide + pos,
					     " (%x:%x.%x) %n",
					     &bus, &slot, &func, &parsed);
				switch (err) {
				case 2:
					func = -1;
					sscanf(pci_devs_to_hide + pos,
					       " (%x:%x.*) %n",
					       &bus, &slot, &parsed);
					break;
				case 1:
					slot = func = -1;
					sscanf(pci_devs_to_hide + pos,
					       " (%x:*.*) %n",
					       &bus, &parsed);
					break;
				}
			}

			if (parsed <= 0)
				goto parse_error;

			err = pcistub_device_id_add(domain, bus, slot, func);
			if (err)
				goto out;

			pos += parsed;
		} while (pci_devs_to_hide[pos]);
	}

	/* If we're the first PCI Device Driver to register, we're the
	 * first one to get offered PCI devices as they become
	 * available (and thus we can be the first to grab them)
	 */
	err = pci_register_driver(&xen_pcibk_pci_driver);
	if (err < 0)
		goto out;

	err = driver_create_file(&xen_pcibk_pci_driver.driver,
				 &driver_attr_new_slot);
	if (!err)
		err = driver_create_file(&xen_pcibk_pci_driver.driver,
					 &driver_attr_remove_slot);
	if (!err)
		err = driver_create_file(&xen_pcibk_pci_driver.driver,
					 &driver_attr_slots);
	if (!err)
		err = driver_create_file(&xen_pcibk_pci_driver.driver,
					 &driver_attr_quirks);
	if (!err)
		err = driver_create_file(&xen_pcibk_pci_driver.driver,
					 &driver_attr_permissive);

	if (!err)
		err = driver_create_file(&xen_pcibk_pci_driver.driver,
					 &driver_attr_irq_handlers);
	if (!err)
		err = driver_create_file(&xen_pcibk_pci_driver.driver,
					&driver_attr_irq_handler_state);
	if (err)
		pcistub_exit();

out:
	return err;

parse_error:
	pr_err("Error parsing pci_devs_to_hide at \"%s\"\n",
	       pci_devs_to_hide + pos);
	return -EINVAL;
}

#ifndef MODULE
/*
 * fs_initcall happens before device_initcall
 * so xen_pcibk *should* get called first (b/c we
 * want to suck up any device before other drivers
 * get a chance by being the first pci device
 * driver to register)
 */
fs_initcall(pcistub_init);
#endif

static int __init xen_pcibk_init(void)
{
	int err;

	if (!xen_initial_domain())
		return -ENODEV;

	err = xen_pcibk_config_init();
	if (err)
		return err;

#ifdef MODULE
	err = pcistub_init();
	if (err < 0)
		return err;
#endif

	pcistub_init_devices_late();
	err = xen_pcibk_xenbus_register();
	if (err)
		pcistub_exit();

	return err;
}

static void __exit xen_pcibk_cleanup(void)
{
	xen_pcibk_xenbus_unregister();
	pcistub_exit();
}

module_init(xen_pcibk_init);
module_exit(xen_pcibk_cleanup);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("xen-backend:pci");
