@@ -39,6 +39,58 @@
#include "powernv.h"
#include "pci.h"
+/*
+ * Guest is passing 2 types of addresses. First one would be
+ * traditional bus/device/function combo and another one is
+ * PE address, which starts from 0x10000
+ */
+static int kvmppc_eeh_format_addr(struct kvm_vcpu *vcpu,
+ struct rtas_args *args,
+ struct eeh_vfio_pci_addr *addr,
+ bool is_legacy,
+ struct eeh_dev **pedev,
+ struct eeh_pe **ppe)
+{
+ struct eeh_dev *edev;
+ struct eeh_pe *pe;
+
+ if (pedev) *pedev = NULL;
+ if (ppe) *ppe = NULL;
+
+ addr->kvm = vcpu->kvm;
+ addr->buid_hi = args->args[1];
+ addr->buid_lo = args->args[2];
+ if (is_legacy) {
+ addr->bus = (args->args[0] >> 16) & 0xFF;
+ addr->devfn = (args->args[0] >> 8) & 0xFF;
+
+ edev = eeh_vfio_dev_get(addr);
+ if (!edev) {
+ pr_warn("%s: Can't find VFIO device "
+ "(%08x-%08x-%02x-%02x)\n",
+ __func__, addr->buid_hi,
+ addr->buid_lo, addr->bus, addr->devfn);
+ return -EEXIST;
+ }
+
+ if (pedev) *pedev = edev;
+ if (ppe) *ppe = edev->pe;
+ } else {
+ addr->pe_addr = args->args[0];
+ pe = eeh_vfio_pe_get(addr);
+ if (!pe) {
+ pr_warn("%s: Can't find PE (%08x-%08x-%x)\n",
+ __func__, addr->buid_hi,
+ addr->buid_lo, addr->pe_addr);
+ return -EEXIST;
+ }
+
+ if (ppe) *ppe = pe;
+ }
+
+ return 0;
+}
+
/**
* kvmppc_eeh_rtas - Backend for EEH RTAS emulation
* @vcpu: KVM virtual CPU
The guest will pass 2 kinds of addresses: tranditional bus/device/ function combo, and guest sensitive PE address returned from host. The patch introduces function kvmppc_eeh_format_addr() to convert the guest address information from RTAS call argument (struct rtas_args) and retrieve the EEH device or PE instance if necessary. The function will be used by subsequent patches. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> --- arch/powerpc/platforms/powernv/eeh-rtas.c | 52 +++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)