[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 09/17] xev/hvm: Add HVMOP_get|set_ecam_space hypercalls



This patch adds 2 HVMOP hypercalls, HVMOP_get|set_ecam_space, used to
set and get the base address and size of the PCIe ECAM space as
configured by hvmloader.

Signed-off-by: Thierry Escande <thierry.escande@xxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c            | 52 +++++++++++++++++++++++++++++++
 xen/arch/x86/include/asm/domain.h |  4 +++
 xen/include/public/hvm/hvm_op.h   | 11 +++++++
 3 files changed, 67 insertions(+)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 4d37a93c57..a46dfa955d 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -5195,6 +5195,58 @@ long do_hvm_op(unsigned long op, 
XEN_GUEST_HANDLE_PARAM(void) arg)
         rc = current->hcall_compat ? compat_altp2m_op(arg) : do_altp2m_op(arg);
         break;
 
+    case HVMOP_set_ecam_space: {
+        xen_hvm_ecam_space_t ecam;
+        struct domain *d;
+
+        if ( copy_from_guest( &ecam, guest_handle_cast(arg, 
xen_hvm_ecam_space_t), 1 ) )
+            return -EFAULT;
+
+        d = rcu_lock_domain_by_any_id(ecam.domid);
+        if ( d == NULL )
+            return -ESRCH;
+
+        if ( d->arch.ecam_addr ) {
+            rcu_unlock_domain(d);
+            return -EFAULT;
+        }
+
+        if ( (ecam.size >> 28) || (!ecam.addr) ) {
+            rcu_unlock_domain(d);
+            return -EINVAL;
+        }
+
+        d->arch.ecam_addr = ecam.addr;
+        d->arch.ecam_size = ecam.size;
+
+        rcu_unlock_domain(d);
+        break;
+    }
+
+    case HVMOP_get_ecam_space: {
+        xen_hvm_ecam_space_t ecam;
+        struct domain *d;
+
+        if ( copy_from_guest( &ecam, guest_handle_cast(arg, 
xen_hvm_ecam_space_t), 1 ) )
+            return -EFAULT;
+
+        d = rcu_lock_domain_by_any_id(ecam.domid);
+        if ( d == NULL )
+            return -ESRCH;
+
+        if ( ! d->arch.ecam_addr || ! d->arch.ecam_size ) {
+            rcu_unlock_domain(d);
+            return -EINVAL;
+        }
+
+        ecam.addr = d->arch.ecam_addr;
+        ecam.size = d->arch.ecam_size;
+        rc = __copy_to_guest(arg, &ecam, 1) ? -EFAULT : 0;
+
+        rcu_unlock_domain(d);
+        break;
+    }
+
     default:
         rc = -ENOSYS;
         break;
diff --git a/xen/arch/x86/include/asm/domain.h 
b/xen/arch/x86/include/asm/domain.h
index ad7f6adb2c..24ec33fc4d 100644
--- a/xen/arch/x86/include/asm/domain.h
+++ b/xen/arch/x86/include/asm/domain.h
@@ -476,6 +476,10 @@ struct arch_domain
 
     /* Emulated devices enabled bitmap. */
     uint32_t emulation_flags;
+
+    /* PCI ECAM space emulation */
+    uint64_t ecam_addr;
+    uint32_t ecam_size;
 } __cacheline_aligned;
 
 #ifdef CONFIG_HVM
diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h
index e22adf0319..c84febc37c 100644
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -166,6 +166,17 @@ struct xen_hvm_get_mem_type {
 typedef struct xen_hvm_get_mem_type xen_hvm_get_mem_type_t;
 DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t);
 
+#define HVMOP_set_ecam_space    16
+#define HVMOP_get_ecam_space    17
+struct xen_hvm_ecam_space {
+    domid_t  domid;
+    uint16_t pad[3]; /* align next field on 8-byte boundary */
+    uint64_t addr;
+    uint32_t size;
+};
+typedef struct xen_hvm_ecam_space xen_hvm_ecam_space_t;
+DEFINE_XEN_GUEST_HANDLE(xen_hvm_ecam_space_t);
+
 /* Following tools-only interfaces may change in future. */
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 
-- 
2.51.0



--
Thierry Escande | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.