-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
1200-hypercall-XENMEM_get_mfn_from_pfn.patch
134 lines (127 loc) · 3.6 KB
/
1200-hypercall-XENMEM_get_mfn_from_pfn.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
From 6dea874a453d50cf064dd198679c26d22f84b527 Mon Sep 17 00:00:00 2001
From: Wei Ye <[email protected]>
Date: Thu, 21 Aug 2014 03:45:38 +0800
Subject: [PATCH] hypercall: XENMEM_get_mfn_from_pfn
Suppose that we should find an existing method to achieve the same
goal.
Signed-off-by: Wei Ye <[email protected]>
Signed-off-by: Yu Zhang <[email protected]>
---
xen/arch/x86/mm.c | 64 +++++++++++++++++++++++++++++++++++++
xen/include/public/memory.h | 23 +++++++++++++
2 files changed, 87 insertions(+)
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index b30453b9de11..54734371681e 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4693,6 +4693,61 @@ static int cf_check handle_iomem_range(
return err || s > e ? err : _handle_iomem_range(s, e, p);
}
+static int get_mfn_from_pfn(XEN_GUEST_HANDLE(xen_get_mfn_from_pfn_t) arg)
+{
+ struct xen_get_mfn_from_pfn cmd_info;
+ struct domain *d;
+ int rc=0, i;
+ xen_pfn_t *pfns = NULL;
+ xen_pfn_t pfn;
+ struct p2m_domain *p2m;
+ p2m_type_t t;
+
+ if ( !is_hardware_domain(current->domain) )
+ return -EPERM;
+
+ if ( copy_from_guest(&cmd_info, arg, 1) )
+ return -EFAULT;
+
+ d = rcu_lock_domain_by_any_id(cmd_info.domid);
+ if ( d == NULL )
+ return -ESRCH;
+
+ /* sanity check for security */
+ if (cmd_info.nr_pfns > 2048 )
+ return -ENOMEM;
+
+ pfns = xmalloc_array(xen_pfn_t, cmd_info.nr_pfns);
+ if (pfns == NULL)
+ return -ENOMEM;
+
+ if (copy_from_guest(pfns, cmd_info.pfn_list, cmd_info.nr_pfns)){
+ rc = -EFAULT;
+ goto out;
+ }
+
+ p2m = p2m_get_hostp2m(d);
+ for(i=0; i < cmd_info.nr_pfns; i++){
+ pfn = pfns[i];
+ pfns[i] = mfn_x(get_gfn_query(d, pfn, &t));
+ if(pfns[i] == mfn_x(INVALID_MFN)){
+ rc = -EINVAL;
+ goto out;
+ }
+ put_gfn(d, pfn);
+ }
+
+ if (copy_to_guest(cmd_info.pfn_list, pfns, cmd_info.nr_pfns)){
+ rc = -EFAULT;
+ goto out;
+ }
+
+out:
+ rcu_unlock_domain(d);
+ xfree(pfns);
+ return rc;
+}
+
long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
{
int rc;
@@ -4903,6 +4958,15 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
}
#endif
+#ifdef __x86_64__
+ case XENMEM_get_sharing_freed_pages:
+ return mem_sharing_get_nr_saved_mfns();
+#endif
+
+ case XENMEM_get_mfn_from_pfn:
+ return get_mfn_from_pfn(guest_handle_cast(arg, xen_get_mfn_from_pfn_t));
+ break;
+
default:
return subarch_memory_op(cmd, arg);
}
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 5e545ae9a418..c522241e141f 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -682,6 +682,29 @@ struct xen_mem_acquire_resource {
typedef struct xen_mem_acquire_resource xen_mem_acquire_resource_t;
DEFINE_XEN_GUEST_HANDLE(xen_mem_acquire_resource_t);
+/*
+ * Translate the given guest PFNs to MFNs
+ */
+#define XENMEM_get_mfn_from_pfn 29
+struct xen_get_mfn_from_pfn {
+ /*
+ * Pointer to buffer to fill with list of pfn.
+ * for IN, it contains the guest PFN that need to translated
+ * for OUT, it contains the translated MFN. or INVALID_MFN if no valid translation
+ */
+ XEN_GUEST_HANDLE(xen_pfn_t) pfn_list;
+
+ /*
+ * IN: Size of the pfn_array.
+ */
+ unsigned int nr_pfns;
+
+ /* IN: which domain */
+ domid_t domid;
+};
+typedef struct xen_get_mfn_from_pfn xen_get_mfn_from_pfn_t;
+DEFINE_XEN_GUEST_HANDLE(xen_get_mfn_from_pfn_t);
+
/*
* XENMEM_get_vnumainfo used by guest to get
* vNUMA topology from hypervisor.
--
2.44.0