]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lin/ukreloc: Add `ur_pte` macro to create relocatable PTE's
authorSergiu Moga <sergiu.moga@protonmail.com>
Tue, 28 Feb 2023 19:54:24 +0000 (21:54 +0200)
committerUnikraft <monkey@unikraft.io>
Fri, 11 Aug 2023 08:11:27 +0000 (08:11 +0000)
In order to cope with our static page tables used by the bootstrap code
we need to also be able to relocate our page table entries if we want
to be position independent on platforms that makes use of such page
tables.

This macro makes use of the already existing `ur_data` macro to make the
script create the usual `struct uk_reloc`. However a small modification
to the script makes the script do an additional lookup for corresponding
`pte_attr` symbols that `ur_pte` creates, so that it knows to also add
the page table entry attributes to the final value that the self
relocator uses to properly resolve a relocation.

Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com>
Reviewed-by: Dragos Petre <dragos.petre27@gmail.com>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Razvan Deaconescu <razvand@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #772

lib/ukreloc/include/uk/reloc.h
support/scripts/mkukreloc.py

index eab37222bf9eaea2fd5d14b32e1846a0020847d4..75fb7857cfa01164a813e57ca69aec60cda2fae2 100644 (file)
 #endif /* !CONFIG_LIBUKRELOC */
 .endm
 
+/**
+ * For proper positional independence we require that whatever page table
+ * related entries in the static page table we may have, they must be
+ * relocatable against a dynamic physical address. In addition to what
+ * `ur_data` does, `ur_pte` also creates a uk_reloc symbol with `pte_attr0`
+ * suffix, containing the value of the PTE attribute. Example usage:
+ * ```
+ * ur_pte      x86_bpt_pd0_0, PTE_RW
+ * ```
+ * The above will make mkukreloc.py process the symbol
+ * x86_bpt_pd0_0_ukeloc_data8_phys representing in memory where this data is
+ * placed, x86_bpt_pd0_0_ukeloc_pte_attr0 representing the value of the
+ * page table entry attributes and the following entry:
+ * struct uk_reloc {
+ *        __u64 r_mem_off = x86_bpt_pd0_0_ukeloc_data8_phys - __BASE_ADDR
+ *        __u64 r_addr = x86_bpt_pd0_0 - __BASE_ADDR + PTE_RW
+ *        __u32 r_sz = 8 from x86_bpt_pd0_0_ukeloc_data[8]_phys
+ *        __u32 flags = UKRELOC_FLAGS_PHYS_REL from x86_bpt_pd0_0_uk_reloc_data8[_phys]
+ * } __packed;
+ *
+ * @param sym The symbol to relocate
+ * @param pte The page table entry's attribute flags
+ */
+.macro ur_pte  pte_sym:req, pte:req
+#if CONFIG_LIBUKRELOC
+       ur_data quad, \pte_sym, 8, _phys
+       ur_sym  \pte_sym\()_uk_reloc_pte_attr0, \pte
+#else /* CONFIG_LIBUKRELOC */
+       ur_data quad, (\pte_sym + \pte), 8, _phys
+#endif /* !CONFIG_LIBUKRELOC */
+.endm
+
 #if !CONFIG_LIBUKRELOC
 .align 4
 do_uk_reloc:
index 7f97092a1bf6347ef513a013a8d8d7d50b0cc3d8..423d0526e69097c95279d291e870af477b00a769 100755 (executable)
@@ -202,6 +202,15 @@ def uk_reloc_sym_to_struct(elf, uk_reloc_sym):
     # Value already has the link time address added to it.
     value = int(nm_syms[0][0], 16) - BASE_ADDR
 
+    # We must also check whether this is a relocatable Page Table Entry.
+    # If it is, we must add the PTE attributes to the value to properly
+    # resolve the final value of the symbol. So look for an additional
+    # symbol with the `pte_attr` suffix.
+    for pte_attr in uk_reloc_sym_to_struct.pte_attr_syms:
+        if uk_reloc_sym[2] == pte_attr[2]:
+            value += int(pte_attr[0], 16)
+            flags |= UKRELOC_FLAGS_PHYS_REL
+
     # Get the size in bytes of the relocation.
     size = int(uk_reloc_sym[4])
 
@@ -213,6 +222,11 @@ def build_uk_relocs(elf, rela_dyn_secs, max_r_mem_off):
     uk_relocs = [rela_to_uk_reloc(r) for r in rela_dyn_secs]
     uk_reloc_syms = get_nm_syms(elf, get_uk_reloc_sym_exp(r'data'))
 
+    # Also gather all of the PTE uk_reloc's for use against relocatable
+    # PTE's.
+    uk_reloc_sym_to_struct.pte_attr_syms = \
+                             get_nm_syms(elf, get_uk_reloc_sym_exp(r'pte_attr'))
+
     for s in uk_reloc_syms:
         uk_reloc_en = uk_reloc_sym_to_struct(elf, s)