]> git.baikalelectronics.ru Git - kernel.git/commitdiff
KVM: arm64: Add .hyp.data..ro_after_init ELF section
authorDavid Brazdil <dbrazdil@google.com>
Wed, 2 Dec 2020 18:41:08 +0000 (18:41 +0000)
committerMarc Zyngier <maz@kernel.org>
Fri, 4 Dec 2020 10:08:33 +0000 (10:08 +0000)
Add rules for renaming the .data..ro_after_init ELF section in KVM nVHE
object files to .hyp.data..ro_after_init, linking it into the kernel
and mapping it in hyp at runtime.

The section is RW to the host, then mapped RO in hyp. The expectation is
that the host populates the variables in the section and they are never
changed by hyp afterwards.

Signed-off-by: David Brazdil <dbrazdil@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20201202184122.26046-13-dbrazdil@google.com
arch/arm64/include/asm/sections.h
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/arm.c
arch/arm64/kvm/hyp/nvhe/hyp.lds.S

index 3994169985efc62b2c84556934d31bd5c8c1cadd..8ff57936173111bc031543cdf0c40a48129d90f2 100644 (file)
@@ -11,6 +11,7 @@ extern char __alt_instructions[], __alt_instructions_end[];
 extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[];
 extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
 extern char __hyp_text_start[], __hyp_text_end[];
+extern char __hyp_data_ro_after_init_start[], __hyp_data_ro_after_init_end[];
 extern char __idmap_text_start[], __idmap_text_end[];
 extern char __initdata_begin[], __initdata_end[];
 extern char __inittext_begin[], __inittext_end[];
index d6cdcf4aa6a54d11e717d96387de229ea0c93aee..43af13968dfd3a7dc7589f0e1a58d4cbca3dd8a5 100644 (file)
@@ -30,6 +30,13 @@ jiffies = jiffies_64;
        *(__kvm_ex_table)                                       \
        __stop___kvm_ex_table = .;
 
+#define HYPERVISOR_DATA_SECTIONS                               \
+       HYP_SECTION_NAME(.data..ro_after_init) : {              \
+               __hyp_data_ro_after_init_start = .;             \
+               *(HYP_SECTION_NAME(.data..ro_after_init))       \
+               __hyp_data_ro_after_init_end = .;               \
+       }
+
 #define HYPERVISOR_PERCPU_SECTION                              \
        . = ALIGN(PAGE_SIZE);                                   \
        HYP_SECTION_NAME(.data..percpu) : {                     \
@@ -37,6 +44,7 @@ jiffies = jiffies_64;
        }
 #else /* CONFIG_KVM */
 #define HYPERVISOR_EXTABLE
+#define HYPERVISOR_DATA_SECTIONS
 #define HYPERVISOR_PERCPU_SECTION
 #endif
 
@@ -234,6 +242,8 @@ SECTIONS
        _sdata = .;
        RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
 
+       HYPERVISOR_DATA_SECTIONS
+
        /*
         * Data written with the MMU off but read with the MMU on requires
         * cache lines to be invalidated, discarding up to a Cache Writeback
index d9961f0b767e8d2d7dd649f3235ccf5191bceb0d..ef519e4826165d9c5588594d8f07a823143222a0 100644 (file)
@@ -1627,6 +1627,14 @@ static int init_hyp_mode(void)
                goto out_err;
        }
 
+       err = create_hyp_mappings(kvm_ksym_ref(__hyp_data_ro_after_init_start),
+                                 kvm_ksym_ref(__hyp_data_ro_after_init_end),
+                                 PAGE_HYP_RO);
+       if (err) {
+               kvm_err("Cannot map .hyp.data..ro_after_init section\n");
+               goto out_err;
+       }
+
        err = create_hyp_mappings(kvm_ksym_ref(__start_rodata),
                                  kvm_ksym_ref(__end_rodata), PAGE_HYP_RO);
        if (err) {
index bb2d986ff6962bbcb0b0bc31e0194487cb82d9e1..5d76ff2ba63e7d92c3d3d42a2aef0254e3c0323f 100644 (file)
@@ -16,4 +16,5 @@ SECTIONS {
        HYP_SECTION_NAME(.data..percpu) : {
                PERCPU_INPUT(L1_CACHE_BYTES)
        }
+       HYP_SECTION(.data..ro_after_init)
 }