]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
Refresh of percpu-map-l4shadow
authorRoger Pau Monne <roger.pau@citrix.com>
Wed, 26 Jun 2024 12:50:04 +0000 (14:50 +0200)
committerRoger Pau Monne <roger.pau@citrix.com>
Thu, 27 Jun 2024 15:18:10 +0000 (17:18 +0200)
xen/arch/x86/include/asm/fixmap.h
xen/arch/x86/mm.c
xen/arch/x86/pv/mm.c

index 516ec3fa6c955adb49e68ab8bae82b308dac08e7..e30a8112bf4777cf50b90bf9cab1b504af2d3160 100644 (file)
@@ -118,6 +118,50 @@ extern void __set_fixmap_x(
 #define __fix_x_to_virt(x) (FIXADDR_X_TOP - ((x) << PAGE_SHIFT))
 #define fix_x_to_virt(x)   ((void *)__fix_x_to_virt(x))
 
+/* per-CPU fixmap area. */
+enum percpu_fixed_addresses {
+    /* Index 0 is reserved since fix_to_virt(0) == FIXADDR_TOP. */
+    PCPU_FIX_RESERVED,
+    PCPU_FIX_PV_L4SHADOW,
+    __end_of_percpu_fixed_addresses
+};
+
+#define PERCPU_FIXADDR_SIZE (__end_of_percpu_fixed_addresses << PAGE_SHIFT)
+#define PERCPU_FIXADDR_TOP (PERCPU_VIRT_SLOT(0) + PERCPU_FIXADDR_SIZE - \
+                            PAGE_SIZE)
+
+static inline void *percpu_fix_to_virt(enum percpu_fixed_addresses idx)
+{
+    BUG_ON(idx >=__end_of_percpu_fixed_addresses || idx <= PCPU_FIX_RESERVED);
+    return (void *)PERCPU_FIXADDR_TOP - (idx << PAGE_SHIFT);
+}
+
+static inline void percpu_set_fixmap_remote(
+    unsigned int cpu, enum percpu_fixed_addresses idx, mfn_t mfn,
+    unsigned long flags)
+{
+    map_pages_to_xen_cpu((unsigned long)percpu_fix_to_virt(idx), mfn, 1, flags,
+                         cpu);
+}
+
+static inline void percpu_clear_fixmap_remote(
+    unsigned int cpu, enum percpu_fixed_addresses idx)
+{
+    map_pages_to_xen_cpu((unsigned long)percpu_fix_to_virt(idx), INVALID_MFN, 1,
+                         0, cpu);
+}
+
+static inline void percpu_set_fixmap(enum percpu_fixed_addresses idx, mfn_t mfn,
+                                     unsigned long flags)
+{
+    percpu_set_fixmap_remote(smp_processor_id(), idx, mfn, flags);
+}
+
+static inline void percpu_clear_fixmap(enum percpu_fixed_addresses idx)
+{
+    percpu_clear_fixmap_remote(smp_processor_id(), idx);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif
index 70941c056857164fb38116985ac4a2df677ecb9f..3fe032b2c19f711a7c85919313eaed075e3f6c36 100644 (file)
@@ -6423,6 +6423,9 @@ int allocate_perdomain_local_l3(unsigned int cpu)
     clear_page(l2);
     clear_page(l1);
 
+    /* Ensure one L1 table is enough to cover for the per-CPU fixmap. */
+    BUILD_BUG_ON(PERCPU_FIXADDR_SIZE > (1U << L2_PAGETABLE_SHIFT));
+
     l3[l3_table_offset(PERCPU_VIRT_START)] =
         l3e_from_mfn(virt_to_mfn(l2), __PAGE_HYPERVISOR_RW);
     l2[l2_table_offset(PERCPU_VIRT_START)] =
@@ -6479,11 +6482,10 @@ void setup_perdomain_slot(const struct vcpu *v, root_pgentry_t *root_pgt)
         }
 
         if ( is_pv_domain(d) )
-            map_pages_to_xen(PERCPU_VIRT_START, v->arch.pv.guest_l4, 1,
-                             __PAGE_HYPERVISOR_RO);
+            percpu_set_fixmap(PCPU_FIX_PV_L4SHADOW, v->arch.pv.guest_l4,
+                              __PAGE_HYPERVISOR_RO);
         else
-            destroy_xen_mappings(PERCPU_VIRT_START,
-                                 PERCPU_VIRT_START + PAGE_SIZE);
+            percpu_clear_fixmap(PCPU_FIX_PV_L4SHADOW);
 
         root_pgt[root_table_offset(PERDOMAIN_VIRT_START)] =
             l4e_from_mfn(virt_to_mfn(l3), __PAGE_HYPERVISOR_RW);
index 8e813d24bef5f387ab82637e1a5685169de1f38c..15a02e685775fb40cb41ce11ad85c8f063cda07e 100644 (file)
@@ -11,6 +11,7 @@
 #include <xen/guest_access.h>
 
 #include <asm/current.h>
+#include <asm/fixmap.h>
 #include <asm/p2m.h>
 
 #include "mm.h"
@@ -112,7 +113,7 @@ void pv_maybe_update_shadow_l4(struct vcpu *v)
     ASSERT(mfn_eq(maddr_to_mfn(v->arch.cr3),
                   _mfn(virt_to_mfn(this_cpu(root_pgt)))));
 
-    copy_page(this_cpu(root_pgt), (void *)PERCPU_VIRT_START);
+    copy_page(this_cpu(root_pgt), percpu_fix_to_virt(PCPU_FIX_PV_L4SHADOW));
 
     setup_perdomain_slot(v, this_cpu(root_pgt));
 }
@@ -127,8 +128,8 @@ mfn_t pv_maybe_shadow_l4(struct vcpu *v, mfn_t mfn)
     v->arch.pv.guest_l4 = mfn;
 
     if ( this_cpu(root_pgt) )
-        map_pages_to_xen(PERCPU_VIRT_START, v->arch.pv.guest_l4, 1,
-                         __PAGE_HYPERVISOR_RO);
+        percpu_set_fixmap(PCPU_FIX_PV_L4SHADOW, v->arch.pv.guest_l4,
+                          __PAGE_HYPERVISOR_RO);
 
     /*
      * No need to copy the contents of the guest L4 to the per-CPU shadow.