add function for obtaining highest possible memory address
authorJuergen Gross <jgross@suse.com>
Thu, 28 Sep 2017 09:05:37 +0000 (11:05 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 28 Sep 2017 09:05:37 +0000 (11:05 +0200)
Add a function for obtaining the highest possible physical memory
address of the system. This value is influenced by:

- hypervisor configuration (CONFIG_BIGMEM)
- processor capability (max. addressable physical memory)
- memory map at boot time
- memory hotplug capability

Add this value to xen_sysctl_physinfo in order to enable dom0 to do a
proper sizing of grant frame limits of guests.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Julien Grall <julien.grall@arm.com>
xen/arch/arm/mm.c
xen/arch/x86/mm.c
xen/common/sysctl.c
xen/include/public/sysctl.h
xen/include/xen/mm.h

index f3834b3dab0b5a44402e64153adf9d02d1801b7d..9a37f29ce6f0e169c633d4c31f9585ddd0d4b926 100644 (file)
@@ -1472,6 +1472,12 @@ void clear_and_clean_page(struct page_info *page)
     unmap_domain_page(p);
 }
 
+unsigned long get_upper_mfn_bound(void)
+{
+    /* No memory hotplug yet, so current memory limit is the final one. */
+    return max_page - 1;
+}
+
 /*
  * Local variables:
  * mode: C
index afd5a101a4f5f42fd8f5984e325ab09835ac4e86..d9df5ca69f006a4f632aedd6135be94361d1a883 100644 (file)
@@ -5178,6 +5178,17 @@ void write_32bit_pse_identmap(uint32_t *l2)
                  _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE);
 }
 
+unsigned long get_upper_mfn_bound(void)
+{
+    unsigned long max_mfn;
+
+    max_mfn = mem_hotplug ? PFN_DOWN(mem_hotplug) : max_page;
+#ifndef CONFIG_BIGMEM
+    max_mfn = min(max_mfn, 1UL << 32);
+#endif
+    return min(max_mfn, 1UL << (paddr_bits - PAGE_SHIFT)) - 1;
+}
+
 /*
  * Local variables:
  * mode: C
index 3480f582faa8066ed7a9f360bcdfa13eb3a01ef4..08198b715095a490dd5e638f65831be809c92f1b 100644 (file)
@@ -266,6 +266,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
         get_outstanding_claims(&pi->free_pages, &pi->outstanding_pages);
         pi->scrub_pages = 0;
         pi->cpu_khz = cpu_khz;
+        pi->max_mfn = get_upper_mfn_bound();
         arch_do_physinfo(pi);
 
         if ( copy_to_guest(u_sysctl, op, 1) )
index 4d32a87cca65541cf2852ecacc6c5db0607b6a53..6140f1a059b28f915c5095f659fd334b211fabb7 100644 (file)
@@ -36,7 +36,7 @@
 #include "physdev.h"
 #include "tmem.h"
 
-#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000F
+#define XEN_SYSCTL_INTERFACE_VERSION 0x00000010
 
 /*
  * Read console content from Xen buffer ring.
@@ -96,14 +96,13 @@ struct xen_sysctl_physinfo {
     uint32_t nr_nodes;    /* # nodes currently online */
     uint32_t max_node_id; /* Largest possible node ID on this host */
     uint32_t cpu_khz;
+    uint32_t capabilities;/* XEN_SYSCTL_PHYSCAP_??? */
     uint64_aligned_t total_pages;
     uint64_aligned_t free_pages;
     uint64_aligned_t scrub_pages;
     uint64_aligned_t outstanding_pages;
+    uint64_aligned_t max_mfn; /* Largest possible MFN on this host */
     uint32_t hw_cap[8];
-
-    /* XEN_SYSCTL_PHYSCAP_??? */
-    uint32_t capabilities;
 };
 
 /*
index f8b6177c32ddf3fb1fc5f79e861c270fe365d535..e813c07b225cbadc7362f284a2b4b85333e9d9cc 100644 (file)
@@ -599,6 +599,9 @@ int prepare_ring_for_helper(struct domain *d, unsigned long gmfn,
                             struct page_info **_page, void **_va);
 void destroy_ring_for_helper(void **_va, struct page_info *page);
 
+/* Return the upper bound of MFNs, including hotplug memory. */
+unsigned long get_upper_mfn_bound(void);
+
 #include <asm/flushtlb.h>
 
 static inline void accumulate_tlbflush(bool *need_tlbflush,