* Copyright (c) 2017 Citrix Systems Ltd.
*/
#include <xen/init.h>
+#include <xen/mm.h>
+#include <xen/pfn.h>
+#include <xen/rangeset.h>
#include <xen/types.h>
+#include <asm/e820.h>
#include <asm/guest.h>
#include <asm/msr.h>
#include <asm/processor.h>
static __read_mostly uint32_t xen_cpuid_base;
extern char hypercall_page[];
+static struct rangeset *mem;
static void __init find_xen_leaves(void)
{
xen_guest = true;
}
+static void __init init_memmap(void)
+{
+ unsigned int i;
+
+ mem = rangeset_new(NULL, "host memory map", 0);
+ if ( !mem )
+ panic("failed to allocate PFN usage rangeset");
+
+ /*
+ * Mark up to the last memory page (or 4GiB) as RAM. This is done because
+ * Xen doesn't know the position of possible MMIO holes, so at least try to
+ * avoid the know MMIO hole below 4GiB. Note that this is subject to future
+ * discussion and improvements.
+ */
+ if ( rangeset_add_range(mem, 0, max_t(unsigned long, max_page - 1,
+ PFN_DOWN(GB(4) - 1))) )
+ panic("unable to add RAM to in-use PFN rangeset");
+
+ for ( i = 0; i < e820.nr_map; i++ )
+ {
+ struct e820entry *e = &e820.map[i];
+
+ if ( rangeset_add_range(mem, PFN_DOWN(e->addr),
+ PFN_UP(e->addr + e->size - 1)) )
+ panic("unable to add range [%#lx, %#lx] to in-use PFN rangeset",
+ PFN_DOWN(e->addr), PFN_UP(e->addr + e->size - 1));
+ }
+}
+
+void __init hypervisor_setup(void)
+{
+ init_memmap();
+}
+
+int hypervisor_alloc_unused_page(mfn_t *mfn)
+{
+ unsigned long m;
+ int rc;
+
+ rc = rangeset_claim_range(mem, 1, &m);
+ if ( !rc )
+ *mfn = _mfn(m);
+
+ return rc;
+}
+
+int hypervisor_free_unused_page(mfn_t mfn)
+{
+ return rangeset_remove_range(mem, mfn_x(mfn), mfn_x(mfn));
+}
+
/*
* Local variables:
* mode: C
extern bool xen_guest;
void probe_hypervisor(void);
+void hypervisor_setup(void);
+int hypervisor_alloc_unused_page(mfn_t *mfn);
+int hypervisor_free_unused_page(mfn_t mfn);
#else
#define xen_guest 0
static inline void probe_hypervisor(void) {};
+static inline void hypervisor_setup(void)
+{
+ ASSERT_UNREACHABLE();
+}
#endif /* CONFIG_XEN_GUEST */
#endif /* __X86_GUEST_XEN_H__ */