cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vfio_spapr_eeh.c (2681B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * EEH functionality support for VFIO devices. The feature is only
      4 * available on sPAPR compatible platforms.
      5 *
      6 * Copyright Gavin Shan, IBM Corporation 2014.
      7 */
      8
      9#include <linux/module.h>
     10#include <linux/uaccess.h>
     11#include <linux/vfio.h>
     12#include <asm/eeh.h>
     13
     14#define DRIVER_VERSION	"0.1"
     15#define DRIVER_AUTHOR	"Gavin Shan, IBM Corporation"
     16#define DRIVER_DESC	"VFIO IOMMU SPAPR EEH"
     17
     18/* We might build address mapping here for "fast" path later */
     19void vfio_spapr_pci_eeh_open(struct pci_dev *pdev)
     20{
     21	eeh_dev_open(pdev);
     22}
     23EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_open);
     24
     25void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)
     26{
     27	eeh_dev_release(pdev);
     28}
     29EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_release);
     30
     31long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
     32				unsigned int cmd, unsigned long arg)
     33{
     34	struct eeh_pe *pe;
     35	struct vfio_eeh_pe_op op;
     36	unsigned long minsz;
     37	long ret = -EINVAL;
     38
     39	switch (cmd) {
     40	case VFIO_CHECK_EXTENSION:
     41		if (arg == VFIO_EEH)
     42			ret = eeh_enabled() ? 1 : 0;
     43		else
     44			ret = 0;
     45		break;
     46	case VFIO_EEH_PE_OP:
     47		pe = eeh_iommu_group_to_pe(group);
     48		if (!pe)
     49			return -ENODEV;
     50
     51		minsz = offsetofend(struct vfio_eeh_pe_op, op);
     52		if (copy_from_user(&op, (void __user *)arg, minsz))
     53			return -EFAULT;
     54		if (op.argsz < minsz || op.flags)
     55			return -EINVAL;
     56
     57		switch (op.op) {
     58		case VFIO_EEH_PE_DISABLE:
     59			ret = eeh_pe_set_option(pe, EEH_OPT_DISABLE);
     60			break;
     61		case VFIO_EEH_PE_ENABLE:
     62			ret = eeh_pe_set_option(pe, EEH_OPT_ENABLE);
     63			break;
     64		case VFIO_EEH_PE_UNFREEZE_IO:
     65			ret = eeh_pe_set_option(pe, EEH_OPT_THAW_MMIO);
     66			break;
     67		case VFIO_EEH_PE_UNFREEZE_DMA:
     68			ret = eeh_pe_set_option(pe, EEH_OPT_THAW_DMA);
     69			break;
     70		case VFIO_EEH_PE_GET_STATE:
     71			ret = eeh_pe_get_state(pe);
     72			break;
     73		case VFIO_EEH_PE_RESET_DEACTIVATE:
     74			ret = eeh_pe_reset(pe, EEH_RESET_DEACTIVATE, true);
     75			break;
     76		case VFIO_EEH_PE_RESET_HOT:
     77			ret = eeh_pe_reset(pe, EEH_RESET_HOT, true);
     78			break;
     79		case VFIO_EEH_PE_RESET_FUNDAMENTAL:
     80			ret = eeh_pe_reset(pe, EEH_RESET_FUNDAMENTAL, true);
     81			break;
     82		case VFIO_EEH_PE_CONFIGURE:
     83			ret = eeh_pe_configure(pe);
     84			break;
     85		case VFIO_EEH_PE_INJECT_ERR:
     86			minsz = offsetofend(struct vfio_eeh_pe_op, err.mask);
     87			if (op.argsz < minsz)
     88				return -EINVAL;
     89			if (copy_from_user(&op, (void __user *)arg, minsz))
     90				return -EFAULT;
     91
     92			ret = eeh_pe_inject_err(pe, op.err.type, op.err.func,
     93						op.err.addr, op.err.mask);
     94			break;
     95		default:
     96			ret = -EINVAL;
     97		}
     98	}
     99
    100	return ret;
    101}
    102EXPORT_SYMBOL_GPL(vfio_spapr_iommu_eeh_ioctl);
    103
    104MODULE_VERSION(DRIVER_VERSION);
    105MODULE_LICENSE("GPL v2");
    106MODULE_AUTHOR(DRIVER_AUTHOR);
    107MODULE_DESCRIPTION(DRIVER_DESC);