diff mbox

[10/22] powerpc/eeh: Introduce kvmppc_eeh_format_addr()

Message ID 1399253291-3975-11-git-send-email-gwshan@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gavin Shan May 5, 2014, 1:27 a.m. UTC
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(+)
diff mbox

Patch

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