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 <gws...@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/eeh-rtas.c | 52 +++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/eeh-rtas.c 
b/arch/powerpc/platforms/powernv/eeh-rtas.c
index fded461..f04b820 100644
--- a/arch/powerpc/platforms/powernv/eeh-rtas.c
+++ b/arch/powerpc/platforms/powernv/eeh-rtas.c
@@ -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
-- 
1.8.3.2

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to