From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:05:38
Changelog:
v14:
- Fixed a bug in "arm64: hyp-stub: Move elx_sync into the vectors"
that was noticed by Marc Zyngier
- Merged with upstream
v13:
- Fixed a hang on ThunderX2, thank you Pingfan Liu for reporting
the problem. In relocation function we need civac not ivac, we
need to clean data in addition to invalidating it.
Since I was using ThunderX2 machine I also measured the new
performance data on this large ARM64 server. The MMU improves
kexec relocation 190 times on this machine! (see below for
raw data). Saves 7.5s during CentOS kexec reboot.
v12:
- A major change compared to previous version. Instead of using
contiguous VA range a copy of linear map is now used to perform
copying of segments during relocation as it was agreed in the
discussion of version 11 of this project.
- In addition to using linear map, I also took several ideas from
James Morse to better organize the kexec relocation:
1. skip relocation function entirely if that is not needed
2. remove the PoC flushing function since it is not needed
anymore with MMU enabled.
v11:
- Fixed missing KEXEC_CORE dependency for trans_pgd.c
- Removed useless "if(rc) return rc" statement (thank you Tyler Hicks)
- Another 12 patches were accepted into maintainer's get.
Re-based patches against:
https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Branch: for-next/kexec
v10:
- Addressed a lot of comments form James Morse and from Marc Zyngier
- Added review-by's
- Synchronized with mainline
v9: - 9 patches from previous series landed in upstream, so now series
is smaller
- Added two patches from James Morse to address idmap issues for machines
with high physical addresses.
- Addressed comments from Selin Dag about compiling issues. He also tested
my series and got similar performance results: ~60 ms instead of ~580 ms
with an initramfs size of ~120MB.
v8:
- Synced with mainline to keep series up-to-date
v7:
-- Addressed comments from James Morse
- arm64: hibernate: pass the allocated pgdp to ttbr0
Removed "Fixes" tag, and added Added Reviewed-by: James Morse
- arm64: hibernate: check pgd table allocation
Sent out as a standalone patch so it can be sent to stable
Series applies on mainline + this patch
- arm64: hibernate: add trans_pgd public functions
Remove second allocation of tmp_pg_dir in swsusp_arch_resume
Added Reviewed-by: James Morse [off-list ref]
- arm64: kexec: move relocation function setup and clean up
Fixed typo in commit log
Changed kern_reloc to phys_addr_t types.
Added explanation why kern_reloc is needed.
Split into four patches:
arm64: kexec: make dtb_mem always enabled
arm64: kexec: remove unnecessary debug prints
arm64: kexec: call kexec_image_info only once
arm64: kexec: move relocation function setup
- arm64: kexec: add expandable argument to relocation function
Changed types of new arguments from unsigned long to phys_addr_t.
Changed offset prefix to KEXEC_*
Split into four patches:
arm64: kexec: cpu_soft_restart change argument types
arm64: kexec: arm64_relocate_new_kernel clean-ups
arm64: kexec: arm64_relocate_new_kernel don't use x0 as temp
arm64: kexec: add expandable argument to relocation function
- arm64: kexec: configure trans_pgd page table for kexec
Added invalid entries into EL2 vector table
Removed KEXEC_EL2_VECTOR_TABLE_SIZE and KEXEC_EL2_VECTOR_TABLE_OFFSET
Copy relocation functions and table into separate pages
Changed types in kern_reloc_arg.
Split into three patches:
arm64: kexec: offset for relocation function
arm64: kexec: kexec EL2 vectors
arm64: kexec: configure trans_pgd page table for kexec
- arm64: kexec: enable MMU during kexec relocation
Split into two patches:
arm64: kexec: enable MMU during kexec relocation
arm64: kexec: remove head from relocation argument
v6:
- Sync with mainline tip
- Added Acked's from Dave Young
v5:
- Addressed comments from Matthias Brugger: added review-by's, improved
comments, and made cleanups to swsusp_arch_resume() in addition to
create_safe_exec_page().
- Synced with mainline tip.
v4:
- Addressed comments from James Morse.
- Split "check pgd table allocation" into two patches, and moved to
the beginning of series for simpler backport of the fixes.
Added "Fixes:" tags to commit logs.
- Changed "arm64, hibernate:" to "arm64: hibernate:"
- Added Reviewed-by's
- Moved "add PUD_SECT_RDONLY" earlier in series to be with other
clean-ups
- Added "Derived from:" to arch/arm64/mm/trans_pgd.c
- Removed "flags" from trans_info
- Changed .trans_alloc_page assumption to return zeroed page.
- Simplify changes to trans_pgd_map_page(), by keeping the old
code.
- Simplify changes to trans_pgd_create_copy, by keeping the old
code.
- Removed: "add trans_pgd_create_empty"
- replace init_mm with NULL, and keep using non "__" version of
populate functions.
v3:
- Split changes to create_safe_exec_page() into several patches for
easier review as request by Mark Rutland. This is why this series
has 3 more patches.
- Renamed trans_table to tans_pgd as agreed with Mark. The header
comment in trans_pgd.c explains that trans stands for
transitional page tables. Meaning they are used in transition
between two kernels.
v2:
- Fixed hibernate bug reported by James Morse
- Addressed comments from James Morse:
* More incremental changes to trans_table
* Removed TRANS_FORCEMAP
* Added kexec reboot data for image with 380M in size.
Enable MMU during kexec relocation in order to improve reboot performance.
If kexec functionality is used for a fast system update, with a minimal
downtime, the relocation of kernel + initramfs takes a significant portion
of reboot.
The reason for slow relocation is because it is done without MMU, and thus
not benefiting from D-Cache.
Performance data
----------------
Cavium ThunderX2:
Kernel Image size: 38M Iniramfs size: 46M Total relocation size: 84M
MMU-disabled:
relocation 7.489539915s
MMU-enabled:
relocation 0.03946095s
Relocation performance is improved 190 times.
Broadcom Stingray:
For this experiment, the size of kernel plus initramfs is small, only 25M.
If initramfs was larger, than the improvements would be greater, as time
spent in relocation is proportional to the size of relocation.
MMU-disabled::
kernel shutdown 0.022131328s
relocation 0.440510736s
kernel startup 0.294706768s
Relocation was taking: 58.2% of reboot time
MMU-enabled:
kernel shutdown 0.032066576s
relocation 0.022158152s
kernel startup 0.296055880s
Now: Relocation takes 6.3% of reboot time
Total reboot is x2.16 times faster.
With bigger userland (fitImage 380M), the reboot time is improved by 3.57s,
and is reduced from 3.9s down to 0.33s
Previous approaches and discussions
-----------------------------------
v13: https://lore.kernel.org/lkml/20210408040537.2703241-1-pasha.tatashin@soleen.com
v12: https://lore.kernel.org/lkml/20210303002230.1083176-1-pasha.tatashin@soleen.com
v11: https://lore.kernel.org/lkml/20210127172706.617195-1-pasha.tatashin@soleen.com
v10: https://lore.kernel.org/linux-arm-kernel/20210125191923.1060122-1-pasha.tatashin@soleen.com
v9: https://lore.kernel.org/lkml/20200326032420.27220-1-pasha.tatashin@soleen.com
v8: https://lore.kernel.org/lkml/20191204155938.2279686-1-pasha.tatashin@soleen.com
v7: https://lore.kernel.org/lkml/20191016200034.1342308-1-pasha.tatashin@soleen.com
v6: https://lore.kernel.org/lkml/20191004185234.31471-1-pasha.tatashin@soleen.com
v5: https://lore.kernel.org/lkml/20190923203427.294286-1-pasha.tatashin@soleen.com
v4: https://lore.kernel.org/lkml/20190909181221.309510-1-pasha.tatashin@soleen.com
v3: https://lore.kernel.org/lkml/20190821183204.23576-1-pasha.tatashin@soleen.com
v2: https://lore.kernel.org/lkml/20190817024629.26611-1-pasha.tatashin@soleen.com
v1: https://lore.kernel.org/lkml/20190801152439.11363-1-pasha.tatashin@soleen.com
James Morse (3):
arm64: hyp-stub: Check the size of the HYP stub's vectors
arm64: hyp-stub: Move invalid vector entries into the vectors
arm64: kexec: Use dcache ops macros instead of open-coding
Pavel Tatashin (14):
arm64: hyp-stub: Move elx_sync into the vectors
arm64: kernel: add helper for booted at EL2 and not VHE
arm64: trans_pgd: hibernate: Add trans_pgd_copy_el2_vectors
arm64: hibernate: abstract ttrb0 setup function
arm64: kexec: flush image and lists during kexec load time
arm64: kexec: skip relocation code for inplace kexec
arm64: kexec: pass kimage as the only argument to relocation function
arm64: kexec: kexec may require EL2 vectors
arm64: kexec: relocate in EL1 mode
arm64: kexec: use ld script for relocation function
arm64: kexec: install a copy of the linear-map
arm64: kexec: keep MMU enabled during kexec relocation
arm64: kexec: remove the pre-kexec PoC maintenance
arm64: kexec: Remove cpu-reset.h
Pingfan Liu (1):
arm64/mm: remove useless trans_pgd_map_page()
arch/arm64/Kconfig | 2 +-
arch/arm64/include/asm/assembler.h | 31 ++++-
arch/arm64/include/asm/kexec.h | 12 ++
arch/arm64/include/asm/mmu_context.h | 24 ++++
arch/arm64/include/asm/sections.h | 1 +
arch/arm64/include/asm/trans_pgd.h | 8 +-
arch/arm64/include/asm/virt.h | 8 ++
arch/arm64/kernel/asm-offsets.c | 11 ++
arch/arm64/kernel/cpu-reset.S | 7 +-
arch/arm64/kernel/cpu-reset.h | 32 -----
arch/arm64/kernel/hibernate-asm.S | 20 ----
arch/arm64/kernel/hibernate.c | 56 +++------
arch/arm64/kernel/hyp-stub.S | 90 +++++++-------
arch/arm64/kernel/machine_kexec.c | 168 +++++++++++++++------------
arch/arm64/kernel/relocate_kernel.S | 70 ++++++-----
arch/arm64/kernel/sdei.c | 2 +-
arch/arm64/kernel/vmlinux.lds.S | 19 +++
arch/arm64/mm/trans_pgd.c | 77 ++++--------
18 files changed, 312 insertions(+), 326 deletions(-)
delete mode 100644 arch/arm64/kernel/cpu-reset.h
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:05:43
The hyp-stub's elx_sync code fits in the vector.
With this, all of the hyp-stubs behaviour is contained in its vectors.
This lets kexec and hibernate copy the hyp-stub when they need its
behaviour, instead of re-implementing it.
Co-developed-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/hyp-stub.S | 64 +++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 31 deletions(-)
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:05:57
From: James Morse <james.morse@arm.com>
Hibernate contains a set of temporary EL2 vectors used to 'park'
EL2 somewhere safe while all the memory is thrown in the air.
Making kexec do its relocations with the MMU on means they have to
be done at EL1, so EL2 has to be parked. This means yet another
set of vectors.
All these things do is HVC_SET_VECTORS and HVC_SOFT_RESTART, both
of which are implemented by the hyp-stub. Lets copy it instead
of re-inventing it.
To do this the hyp-stub's entrails need to be packed neatly inside
its 2K vectors.
Start by moving the final 2K alignment inside the end marker, and
add a build check that we didn't overflow 2K.
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/hyp-stub.S | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:03
From: James Morse <james.morse@arm.com>
Most of the hyp-stub's vector entries are invalid. These are each
a unique function that branches to itself. To move these into the
vectors, merge the ventry and invalid_vector macros and give each
one a unique name.
This means we can copy the hyp-stub as it is self contained within
its vectors.
Signed-off-by: James Morse <james.morse@arm.com>
[Fixed merging issues]
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/hyp-stub.S | 62 +++++++++++++++---------------------
1 file changed, 26 insertions(+), 36 deletions(-)
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:07
Replace places that contain logic like this:
is_hyp_mode_available() && !is_kernel_in_hyp_mode()
With a dedicated boolean function is_hyp_callable(). This will be needed
later in kexec in order to sooner switch back to EL2.
Suggested-by: James Morse <james.morse@arm.com>
[Fixed merging issues]
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/virt.h | 5 +++++
arch/arm64/kernel/cpu-reset.h | 3 +--
arch/arm64/kernel/hibernate.c | 9 +++------
arch/arm64/kernel/sdei.c | 2 +-
4 files changed, 10 insertions(+), 9 deletions(-)
@@ -48,9 +48,6 @@*/externintin_suspend;-/* Do we need to reset el2? */-#define el2_reset_needed() (is_hyp_mode_available() && !is_kernel_in_hyp_mode())-/* temporary el2 vectors in the __hibernate_exit_text section. */externcharhibernate_el2_vectors[];
@@ -125,7 +122,7 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size)hdr->reenter_kernel=_cpu_resume;/* We can't use __hyp_get_vectors() because kvm may still be loaded */-if(el2_reset_needed())+if(is_hyp_callable())hdr->__hyp_stub_vectors=__pa_symbol(__hyp_stub_vectors);elsehdr->__hyp_stub_vectors=0;
@@ -387,7 +384,7 @@ int swsusp_arch_suspend(void)dcache_clean_range(__idmap_text_start,__idmap_text_end);/* Clean kvm setup code to PoC? */-if(el2_reset_needed()){+if(is_hyp_callable()){dcache_clean_range(__hyp_idmap_text_start,__hyp_idmap_text_end);dcache_clean_range(__hyp_text_start,__hyp_text_end);}
@@ -482,7 +479,7 @@ int swsusp_arch_resume(void)**WecanskipthisstepifwebootedatEL1,orarerunningwithVHE.*/-if(el2_reset_needed()){+if(is_hyp_callable()){phys_addr_tel2_vectors=(phys_addr_t)hibernate_exit;el2_vectors+=hibernate_el2_vectors-__hibernate_exit_text_start;/* offset */
@@ -200,7 +200,7 @@ unsigned long sdei_arch_get_entry_point(int conduit)*droppedtoEL1becausewedon'tsupportVHE,thenwecan'tsupport*SDEI.*/-if(is_hyp_mode_available()&&!is_kernel_in_hyp_mode()){+if(is_hyp_callable()){pr_err("Not supported on this hardware/boot configuration\n");gotoout_err;}
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:14
Users of trans_pgd may also need a copy of vector table because it is
also may be overwritten if a linear map can be overwritten.
Move setup of EL2 vectors from hibernate to trans_pgd, so it can be
later shared with kexec as well.
Suggested-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/trans_pgd.h | 3 +++
arch/arm64/include/asm/virt.h | 3 +++
arch/arm64/kernel/hibernate.c | 28 ++++++++++------------------
arch/arm64/mm/trans_pgd.c | 20 ++++++++++++++++++++
4 files changed, 36 insertions(+), 18 deletions(-)
@@ -48,12 +48,6 @@*/externintin_suspend;-/* temporary el2 vectors in the __hibernate_exit_text section. */-externcharhibernate_el2_vectors[];--/* hyp-stub vectors, used to restore el2 during resume from hibernate. */-externchar__hyp_stub_vectors[];-/**Thelogicalcpunumberweshouldresumeon,initialisedtoanon-cpu*number.
@@ -428,6 +422,7 @@ int swsusp_arch_resume(void)void*zero_page;size_texit_size;pgd_t*tmp_pg_dir;+phys_addr_tel2_vectors;void__noreturn(*hibernate_exit)(phys_addr_t,phys_addr_t,void*,void*,phys_addr_t,phys_addr_t);structtrans_pgd_infotrans_info={
@@ -455,6 +450,14 @@ int swsusp_arch_resume(void)return-ENOMEM;}+if(is_hyp_callable()){+rc=trans_pgd_copy_el2_vectors(&trans_info,&el2_vectors);+if(rc){+pr_err("Failed to setup el2 vectors\n");+returnrc;+}+}+exit_size=__hibernate_exit_text_end-__hibernate_exit_text_start;/**Copyswsusp_arch_suspend_exit()toasafepage.Thiswillgenerate
@@ -467,25 +470,14 @@ int swsusp_arch_resume(void)returnrc;}-/*-*Thehibernateexittextcontainsasetofel2vectors,thatwill-*beexecutedatel2withthemmuoffinordertoreloadhyp-stub.-*/-__flush_dcache_area(hibernate_exit,exit_size);-/**KASLRwillcausetheel2vectorstobeinadifferentlocationin*theresumedkernel.Loadhibernate'stemporarycopyintoel2.**WecanskipthisstepifwebootedatEL1,orarerunningwithVHE.*/-if(is_hyp_callable()){-phys_addr_tel2_vectors=(phys_addr_t)hibernate_exit;-el2_vectors+=hibernate_el2_vectors--__hibernate_exit_text_start;/* offset */-+if(is_hyp_callable())__hyp_set_vectors(el2_vectors);-}hibernate_exit(virt_to_phys(tmp_pg_dir),resume_hdr.ttbr1_el1,resume_hdr.reenter_kernel,restore_pblist,
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:21
Currently, only hibernate sets custom ttbr0 with safe idmaped function.
Kexec, is also going to be using this functinality when relocation code
is going to be idmapped.
Move the setup seqeuence to a dedicated cpu_install_ttbr0() for custom
ttbr0.
Suggested-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/mmu_context.h | 24 ++++++++++++++++++++++++
arch/arm64/kernel/hibernate.c | 21 +--------------------
2 files changed, 25 insertions(+), 20 deletions(-)
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:26
Currently, during kexec load we are copying relocation function and
flushing it. However, we can also flush kexec relocation buffers and
if new kernel image is already in place (i.e. crash kernel), we can
also flush the new kernel image itself.
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/machine_kexec.c | 49 +++++++++++++++----------------
1 file changed, 23 insertions(+), 26 deletions(-)
@@ -59,23 +59,6 @@ void machine_kexec_cleanup(struct kimage *kimage)/* Empty routine needed to avoid build errors. */}-intmachine_kexec_post_load(structkimage*kimage)-{-void*reloc_code=page_to_virt(kimage->control_code_page);--memcpy(reloc_code,arm64_relocate_new_kernel,-arm64_relocate_new_kernel_size);-kimage->arch.kern_reloc=__pa(reloc_code);-kexec_image_info(kimage);--/* Flush the reloc_code in preparation for its execution. */-__flush_dcache_area(reloc_code,arm64_relocate_new_kernel_size);-flush_icache_range((uintptr_t)reloc_code,(uintptr_t)reloc_code+-arm64_relocate_new_kernel_size);--return0;-}-/***machine_kexec_prepare-Prepareforakexecreboot.*
@@ -152,6 +135,29 @@ static void kexec_segment_flush(const struct kimage *kimage)}}+intmachine_kexec_post_load(structkimage*kimage)+{+void*reloc_code=page_to_virt(kimage->control_code_page);++/* If in place flush new kernel image, else flush lists and buffers */+if(kimage->head&IND_DONE)+kexec_segment_flush(kimage);+else+kexec_list_flush(kimage);++memcpy(reloc_code,arm64_relocate_new_kernel,+arm64_relocate_new_kernel_size);+kimage->arch.kern_reloc=__pa(reloc_code);+kexec_image_info(kimage);++/* Flush the reloc_code in preparation for its execution. */+__flush_dcache_area(reloc_code,arm64_relocate_new_kernel_size);+flush_icache_range((uintptr_t)reloc_code,(uintptr_t)reloc_code++arm64_relocate_new_kernel_size);++return0;+}+/***machine_kexec-Dothekexecreboot.*
@@ -169,13 +175,6 @@ void machine_kexec(struct kimage *kimage)WARN(in_kexec_crash&&(stuck_cpus||smp_crash_stop_failed()),"Some CPUs may be stale, kdump will be unreliable.\n");-/* Flush the kimage list and its buffers. */-kexec_list_flush(kimage);--/* Flush the new image if already in place. */-if((kimage!=kexec_crash_image)&&(kimage->head&IND_DONE))-kexec_segment_flush(kimage);-pr_info("Bye!\n");local_daif_mask();
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:37
In case of kdump or when segments are already in place the relocation
is not needed, therefore the setup of relocation function and call to
it can be skipped.
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
Suggested-by: James Morse <james.morse@arm.com>
---
arch/arm64/kernel/machine_kexec.c | 34 ++++++++++++++++++-----------
arch/arm64/kernel/relocate_kernel.S | 3 ---
2 files changed, 21 insertions(+), 16 deletions(-)
@@ -139,21 +139,23 @@ int machine_kexec_post_load(struct kimage *kimage){void*reloc_code=page_to_virt(kimage->control_code_page);-/* If in place flush new kernel image, else flush lists and buffers */-if(kimage->head&IND_DONE)+/* If in place, relocation is not used, only flush next kernel */+if(kimage->head&IND_DONE){kexec_segment_flush(kimage);-else-kexec_list_flush(kimage);+kexec_image_info(kimage);+return0;+}memcpy(reloc_code,arm64_relocate_new_kernel,arm64_relocate_new_kernel_size);kimage->arch.kern_reloc=__pa(reloc_code);-kexec_image_info(kimage);/* Flush the reloc_code in preparation for its execution. */__flush_dcache_area(reloc_code,arm64_relocate_new_kernel_size);flush_icache_range((uintptr_t)reloc_code,(uintptr_t)reloc_code+arm64_relocate_new_kernel_size);+kexec_list_flush(kimage);+kexec_image_info(kimage);return0;}
@@ -180,19 +182,25 @@ void machine_kexec(struct kimage *kimage)local_daif_mask();/*-*cpu_soft_restartwillshutdowntheMMU,disabledatacaches,then-*transfercontroltothekern_relocwhichcontainsacopyof-*thearm64_relocate_new_kernelroutine.arm64_relocate_new_kernel-*usesphysicaladdressingtorelocatethenewimagetoitsfinal-*positionandtransferscontroltotheimageentrypointwhenthe-*relocationiscomplete.+*Bothrestartandcpu_soft_restartwillshutdowntheMMU,disabledata+*caches.However,restartwillstartnewkernelorpurgatorydirectly,+*cpu_soft_restartwilltransfercontroltoarm64_relocate_new_kernel*Inkexeccase,kimage->startpointstopurgatoryassumingthat*kernelentryanddtbaddressareembeddedinpurgatoryby*userspace(kexec-tools).*Inkexec_filecase,thekernelstartsdirectlywithoutpurgatory.*/-cpu_soft_restart(kimage->arch.kern_reloc,kimage->head,kimage->start,-kimage->arch.dtb_mem);+if(kimage->head&IND_DONE){+typeof(__cpu_soft_restart)*restart;++cpu_install_idmap();+restart=(void*)__pa_symbol(function_nocfi(__cpu_soft_restart));+restart(is_hyp_callable(),kimage->start,kimage->arch.dtb_mem,+0,0);+}else{+cpu_soft_restart(kimage->arch.kern_reloc,kimage->head,+kimage->start,kimage->arch.dtb_mem);+}BUG();/* Should never get here. */}
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:46
From: James Morse <james.morse@arm.com>
kexec does dcache maintenance when it re-writes all memory. Our
dcache_by_line_op macro depends on reading the sanitised DminLine
from memory. Kexec may have overwritten this, so open-codes the
sequence.
dcache_by_line_op is a whole set of macros, it uses dcache_line_size
which uses read_ctr for the sanitsed DminLine. Reading the DminLine
is the first thing the dcache_by_line_op does.
Rename dcache_by_line_op dcache_by_myline_op and take DminLine as
an argument. Kexec can now use the slightly smaller macro.
This makes up-coming changes to the dcache maintenance easier on
the eye.
Code generated by the existing callers is unchanged.
Signed-off-by: James Morse <james.morse@arm.com>
[Fixed merging issues]
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/assembler.h | 12 ++++++++----
arch/arm64/kernel/relocate_kernel.S | 13 +++----------
2 files changed, 11 insertions(+), 14 deletions(-)
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:06:59
Currently, kexec relocation function (arm64_relocate_new_kernel) accepts
the following arguments:
head: start of array that contains relocation information.
entry: entry point for new kernel or purgatory.
dtb_mem: first and only argument to entry.
The number of arguments cannot be easily expended, because this
function is also called from HVC_SOFT_RESTART, which preserves only
three arguments. And, also arm64_relocate_new_kernel is written in
assembly but called without stack, thus no place to move extra arguments
to free registers.
Soon, we will need to pass more arguments: once we enable MMU we
will need to pass information about page tables.
Pass kimage to arm64_relocate_new_kernel, and teach it to get the
required fields from kimage.
Suggested-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/asm-offsets.c | 7 +++++++
arch/arm64/kernel/machine_kexec.c | 6 ++++--
arch/arm64/kernel/relocate_kernel.S | 10 ++++------
3 files changed, 15 insertions(+), 8 deletions(-)
@@ -198,8 +200,8 @@ void machine_kexec(struct kimage *kimage)restart(is_hyp_callable(),kimage->start,kimage->arch.dtb_mem,0,0);}else{-cpu_soft_restart(kimage->arch.kern_reloc,kimage->head,-kimage->start,kimage->arch.dtb_mem);+cpu_soft_restart(kimage->arch.kern_reloc,virt_to_phys(kimage),+0,0);}BUG();/* Should never get here. */
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:07:05
If we have a EL2 mode without VHE, the EL2 vectors are needed in order
to switch to EL2 and jump to new world with hypervisor privileges.
In preporation to MMU enabled relocation, configure our EL2 table now.
Suggested-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/Kconfig | 2 +-
arch/arm64/include/asm/kexec.h | 1 +
arch/arm64/kernel/asm-offsets.c | 1 +
arch/arm64/kernel/machine_kexec.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 34 insertions(+), 1 deletion(-)
@@ -137,9 +140,27 @@ static void kexec_segment_flush(const struct kimage *kimage)}}+/* Allocates pages for kexec page table */+staticvoid*kexec_page_alloc(void*arg)+{+structkimage*kimage=(structkimage*)arg;+structpage*page=kimage_alloc_control_pages(kimage,0);++if(!page)+returnNULL;++memset(page_address(page),0,PAGE_SIZE);++returnpage_address(page);+}+intmachine_kexec_post_load(structkimage*kimage){void*reloc_code=page_to_virt(kimage->control_code_page);+structtrans_pgd_infoinfo={+.trans_alloc_page=kexec_page_alloc,+.trans_alloc_arg=kimage,+};/* If in place, relocation is not used, only flush next kernel */if(kimage->head&IND_DONE){
@@ -148,6 +169,14 @@ int machine_kexec_post_load(struct kimage *kimage)return0;}+kimage->arch.el2_vectors=0;+if(is_hyp_callable()){+intrc=trans_pgd_copy_el2_vectors(&info,+&kimage->arch.el2_vectors);+if(rc)+returnrc;+}+memcpy(reloc_code,arm64_relocate_new_kernel,arm64_relocate_new_kernel_size);kimage->arch.kern_reloc=__pa(reloc_code);
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:07:11
Currently, relocation code declares start and end variables
which are used to compute its size.
The better way to do this is to use ld script incited, and put relocation
function in its own section.
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/sections.h | 1 +
arch/arm64/kernel/machine_kexec.c | 14 ++++++--------
arch/arm64/kernel/relocate_kernel.S | 15 ++-------------
arch/arm64/kernel/vmlinux.lds.S | 19 +++++++++++++++++++
4 files changed, 28 insertions(+), 21 deletions(-)
@@ -20,14 +20,11 @@#include<asm/mmu.h>#include<asm/mmu_context.h>#include<asm/page.h>+#include<asm/sections.h>#include<asm/trans_pgd.h>#include"cpu-reset.h"-/* Global variables for the arm64_relocate_new_kernel routine. */-externconstunsignedchararm64_relocate_new_kernel[];-externconstunsignedlongarm64_relocate_new_kernel_size;-/***kexec_image_info-Fordebuggingoutput.*/
@@ -177,14 +175,14 @@ int machine_kexec_post_load(struct kimage *kimage)returnrc;}-memcpy(reloc_code,arm64_relocate_new_kernel,-arm64_relocate_new_kernel_size);+reloc_size=__relocate_new_kernel_end-__relocate_new_kernel_start;+memcpy(reloc_code,__relocate_new_kernel_start,reloc_size);kimage->arch.kern_reloc=__pa(reloc_code);/* Flush the reloc_code in preparation for its execution. */-__flush_dcache_area(reloc_code,arm64_relocate_new_kernel_size);+__flush_dcache_area(reloc_code,reloc_size);flush_icache_range((uintptr_t)reloc_code,(uintptr_t)reloc_code+-arm64_relocate_new_kernel_size);+reloc_size);kexec_list_flush(kimage);kexec_image_info(kimage);
@@ -348,3 +360,10 @@ ASSERT(swapper_pg_dir - reserved_pg_dir == RESERVED_SWAPPER_OFFSET,ASSERT(swapper_pg_dir-tramp_pg_dir==TRAMP_SWAPPER_OFFSET,"TRAMP_SWAPPER_OFFSET is wrong!")#endif++#ifdef CONFIG_KEXEC_CORE+/*kexecrelocationcodeshouldfitintooneKEXEC_CONTROL_PAGE_SIZE*/+ASSERT(__relocate_new_kernel_end-(__relocate_new_kernel_start&~(SZ_4K-1))+<=SZ_4K,"kexec relocation code is too big or misaligned")+ASSERT(KEXEC_CONTROL_PAGE_SIZE>=SZ_4K,"KEXEC_CONTROL_PAGE_SIZE is brokern")+#endif
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:07:15
To perform the kexec relocations with the MMU enabled, we need a copy
of the linear map.
Create one, and install it from the relocation code. This has to be done
from the assembly code as it will be idmapped with TTBR0. The kernel
runs in TTRB1, so can't use the break-before-make sequence on the mapping
it is executing from.
The makes no difference yet as the relocation code runs with the MMU
disabled.
Co-developed-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/assembler.h | 19 +++++++++++++++++++
arch/arm64/include/asm/kexec.h | 2 ++
arch/arm64/kernel/asm-offsets.c | 2 ++
arch/arm64/kernel/hibernate-asm.S | 20 --------------------
arch/arm64/kernel/machine_kexec.c | 16 ++++++++++++++--
arch/arm64/kernel/relocate_kernel.S | 3 +++
6 files changed, 40 insertions(+), 22 deletions(-)
@@ -447,6 +447,25 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoUisb.endm+/*+*Topreventthepossibilityofoldandnewpartialtablewalksbeingvisible+*inthetlb,switchthettbrtoazeropagewhenweinvalidatetheold+*records.D4.7.1'GeneralTLBmaintenancerequirements'inARMDDI0487A.i+*Evenswitchingtoourcopiedtableswillcauseachangedoutputaddressat+*eachstageofthewalk.+*/+.macrobreak_before_make_ttbr_switchzero_page,page_table,tmp,tmp2+phys_to_ttbr\tmp,\zero_page+msrttbr1_el1,\tmp+isb+tlbivmalle1+dsbnsh+phys_to_ttbr\tmp,\page_table+offset_ttbr1\tmp,\tmp2+msrttbr1_el1,\tmp+isb+.endm+/**reset_pmuserenr_el0-resetPMUSERENR_EL0ifPMUv3present*/
@@ -169,12 +171,22 @@ int machine_kexec_post_load(struct kimage *kimage)kimage->arch.el2_vectors=0;if(is_hyp_callable()){-intrc=trans_pgd_copy_el2_vectors(&info,-&kimage->arch.el2_vectors);+rc=trans_pgd_copy_el2_vectors(&info,+&kimage->arch.el2_vectors);if(rc)returnrc;}+/* Create a copy of the linear map */+trans_pgd=kexec_page_alloc(kimage);+if(!trans_pgd)+return-ENOMEM;+rc=trans_pgd_create_copy(&info,&trans_pgd,PAGE_OFFSET,PAGE_END);+if(rc)+returnrc;+kimage->arch.ttbr1=__pa(trans_pgd);+kimage->arch.zero_page=__pa(empty_zero_page);+reloc_size=__relocate_new_kernel_end-__relocate_new_kernel_start;memcpy(reloc_code,__relocate_new_kernel_start,reloc_size);kimage->arch.kern_reloc=__pa(reloc_code);
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:07:38
Since we are going to keep MMU enabled during relocation, we need to
keep EL1 mode throughout the relocation.
Keep EL1 enabled, and switch EL2 only before enterying the new world.
Suggested-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/cpu-reset.h | 3 +--
arch/arm64/kernel/machine_kexec.c | 4 ++--
arch/arm64/kernel/relocate_kernel.S | 13 +++++++++++--
3 files changed, 14 insertions(+), 6 deletions(-)
@@ -231,8 +231,8 @@ void machine_kexec(struct kimage *kimage)}else{if(is_hyp_callable())__hyp_set_vectors(kimage->arch.el2_vectors);-cpu_soft_restart(kimage->arch.kern_reloc,virt_to_phys(kimage),-0,0);+cpu_soft_restart(kimage->arch.kern_reloc,+virt_to_phys(kimage),0,0);}BUG();/* Should never get here. */
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:07:47
Now that kexec does its relocations with the MMU enabled, we no longer
need to clean the relocation data to the PoC.
Co-developed-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/machine_kexec.c | 40 -------------------------------
1 file changed, 40 deletions(-)
@@ -76,45 +76,6 @@ int machine_kexec_prepare(struct kimage *kimage)return0;}-/**-*kexec_list_flush-HelpertoflushthekimagelistandsourcepagestoPoC.-*/-staticvoidkexec_list_flush(structkimage*kimage)-{-kimage_entry_t*entry;--__flush_dcache_area(kimage,sizeof(*kimage));--for(entry=&kimage->head;;entry++){-unsignedintflag;-void*addr;--/* flush the list entries. */-__flush_dcache_area(entry,sizeof(kimage_entry_t));--flag=*entry&IND_FLAGS;-if(flag==IND_DONE)-break;--addr=phys_to_virt(*entry&PAGE_MASK);--switch(flag){-caseIND_INDIRECTION:-/* Set entry point just before the new list page. */-entry=(kimage_entry_t*)addr-1;-break;-caseIND_SOURCE:-/* flush the source pages. */-__flush_dcache_area(addr,PAGE_SIZE);-break;-caseIND_DESTINATION:-break;-default:-BUG();-}-}-}-/***kexec_segment_flush-HelpertoflushthekimagesegmentstoPoC.*/
@@ -200,7 +161,6 @@ int machine_kexec_post_load(struct kimage *kimage)__flush_dcache_area(reloc_code,reloc_size);flush_icache_range((uintptr_t)reloc_code,(uintptr_t)reloc_code+reloc_size);-kexec_list_flush(kimage);kexec_image_info(kimage);return0;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:07:56
Now, that we have linear map page tables configured, keep MMU enabled
to allow faster relocation of segments to final destination.
Cavium ThunderX2:
Kernel Image size: 38M Iniramfs size: 46M Total relocation size: 84M
MMU-disabled:
relocation 7.489539915s
MMU-enabled:
relocation 0.03946095s
Broadcom Stingray:
The performance data: for a moderate size kernel + initramfs: 25M the
relocation was taking 0.382s, with enabled MMU it now takes
0.019s only or x20 improvement.
The time is proportional to the size of relocation, therefore if initramfs
is larger, 100M it could take over a second.
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/kexec.h | 3 +++
arch/arm64/kernel/asm-offsets.c | 1 +
arch/arm64/kernel/machine_kexec.c | 16 +++++++++++----
arch/arm64/kernel/relocate_kernel.S | 31 +++++++++++++++++++----------
4 files changed, 36 insertions(+), 15 deletions(-)
@@ -190,6 +190,11 @@ int machine_kexec_post_load(struct kimage *kimage)reloc_size=__relocate_new_kernel_end-__relocate_new_kernel_start;memcpy(reloc_code,__relocate_new_kernel_start,reloc_size);kimage->arch.kern_reloc=__pa(reloc_code);+rc=trans_pgd_idmap_page(&info,&kimage->arch.ttbr0,+&kimage->arch.t0sz,reloc_code);+if(rc)+returnrc;+kimage->arch.phys_offset=virt_to_phys(kimage)-(long)kimage;/* Flush the reloc_code in preparation for its execution. */__flush_dcache_area(reloc_code,reloc_size);
@@ -239,10 +244,13 @@ void machine_kexec(struct kimage *kimage)restart(is_hyp_callable(),kimage->start,kimage->arch.dtb_mem,0,0);}else{+void(*kernel_reloc)(structkimage*kimage);+if(is_hyp_callable())__hyp_set_vectors(kimage->arch.el2_vectors);-cpu_soft_restart(kimage->arch.kern_reloc,-virt_to_phys(kimage),0,0);+cpu_install_ttbr0(kimage->arch.ttbr0,kimage->arch.t0sz);+kernel_reloc=(void*)kimage->arch.kern_reloc;+kernel_reloc(kimage);}BUG();/* Should never get here. */
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:08:00
This header contains only cpu_soft_restart() which is never used directly
anymore. So, remove this header, and rename the helper to be
cpu_soft_restart().
Suggested-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/kexec.h | 6 ++++++
arch/arm64/kernel/cpu-reset.S | 7 +++----
arch/arm64/kernel/cpu-reset.h | 30 ------------------------------
arch/arm64/kernel/machine_kexec.c | 6 ++----
4 files changed, 11 insertions(+), 38 deletions(-)
delete mode 100644 arch/arm64/kernel/cpu-reset.h
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 15:08:04
From: Pingfan Liu <redacted>
The intend of trans_pgd_map_page() was to map contigous range of VA
memory to the memory that is getting relocated during kexec. However,
since we are now using linear map instead of contigous range this
function is not needed
Signed-off-by: Pingfan Liu <redacted>
[Changed commit message]
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/include/asm/trans_pgd.h | 5 +--
arch/arm64/mm/trans_pgd.c | 57 ------------------------------
2 files changed, 1 insertion(+), 61 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-05-27 15:54:41
On Thu, 27 May 2021 16:05:11 +0100,
Pavel Tatashin [off-list ref] wrote:
quoted hunk
The hyp-stub's elx_sync code fits in the vector.
With this, all of the hyp-stubs behaviour is contained in its vectors.
This lets kexec and hibernate copy the hyp-stub when they need its
behaviour, instead of re-implementing it.
Co-developed-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/hyp-stub.S | 64 +++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 31 deletions(-)
Now that this has turned into a macro, what are the guarantees that
mutate_to_vhe will be within reach of the site where this macro is
expanded? It does work here, but what about the other expansion sites
that will show up later in the series?
What was wrong with directly branching to the original call site?
Nothing in the commit message explains it.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-05-27 21:24:10
On Thu, May 27, 2021 at 11:54 AM Marc Zyngier [off-list ref] wrote:
On Thu, 27 May 2021 16:05:11 +0100,
Pavel Tatashin [off-list ref] wrote:
quoted
The hyp-stub's elx_sync code fits in the vector.
With this, all of the hyp-stubs behaviour is contained in its vectors.
This lets kexec and hibernate copy the hyp-stub when they need its
behaviour, instead of re-implementing it.
Co-developed-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/hyp-stub.S | 64 +++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 31 deletions(-)
Now that this has turned into a macro, what are the guarantees that
mutate_to_vhe will be within reach of the site where this macro is
expanded? It does work here, but what about the other expansion sites
that will show up later in the series?
What was wrong with directly branching to the original call site?
Nothing in the commit message explains it.
Hi Marc,
I need to explain this better in the commit log. Later in the series
we create our own vector copy that is outside of the old and new
kernel so it does not get overwritten during kexec relocation. When
VHE is enabled, the vector is passed so we can switch to el2 before
jumping to the new kernel.
arm64_relocate_new_kernel() which performs the relocation runs with
MMU being enabled until relocation is done, after that disables MMU
and if vectors are passed performs:
mov x0, #HVC_SOFT_RESTART
hvc #0 /* Jumps from el2 */
It cannot call mutate_to_vhe because #HVC_VHE_RESTART is not used
here. But, if it had to it would not work as we cannot return to the
old kernel text after relocation.
Thanks,
Pasha
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
From: Marc Zyngier <maz@kernel.org> Date: 2021-06-01 12:23:07
On Thu, 27 May 2021 22:23:22 +0100,
Pavel Tatashin [off-list ref] wrote:
On Thu, May 27, 2021 at 11:54 AM Marc Zyngier [off-list ref] wrote:
quoted
On Thu, 27 May 2021 16:05:11 +0100,
Pavel Tatashin [off-list ref] wrote:
quoted
The hyp-stub's elx_sync code fits in the vector.
With this, all of the hyp-stubs behaviour is contained in its vectors.
This lets kexec and hibernate copy the hyp-stub when they need its
behaviour, instead of re-implementing it.
Co-developed-by: James Morse <james.morse@arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
---
arch/arm64/kernel/hyp-stub.S | 64 +++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 31 deletions(-)
Now that this has turned into a macro, what are the guarantees that
mutate_to_vhe will be within reach of the site where this macro is
expanded? It does work here, but what about the other expansion sites
that will show up later in the series?
What was wrong with directly branching to the original call site?
Nothing in the commit message explains it.
Hi Marc,
I need to explain this better in the commit log. Later in the series
we create our own vector copy that is outside of the old and new
kernel so it does not get overwritten during kexec relocation. When
VHE is enabled, the vector is passed so we can switch to el2 before
jumping to the new kernel.
arm64_relocate_new_kernel() which performs the relocation runs with
MMU being enabled until relocation is done, after that disables MMU
and if vectors are passed performs:
mov x0, #HVC_SOFT_RESTART
hvc #0 /* Jumps from el2 */
It cannot call mutate_to_vhe because #HVC_VHE_RESTART is not used
here. But, if it had to it would not work as we cannot return to the
old kernel text after relocation.
OK, so you are happy with having a dangling branch pointing to
nowhere? Something in me screams that it isn't a good idea, in
general.
If HVC_SOFT_RESTART is all you need, I'd rather you have a small stub
that implements exactly that and nothing else. Feel free to extract it
as a reusable macro if you want.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-06-01 12:38:25
On Thu, 27 May 2021 16:05:12 +0100,
Pavel Tatashin [off-list ref] wrote:
Replace places that contain logic like this:
is_hyp_mode_available() && !is_kernel_in_hyp_mode()
With a dedicated boolean function is_hyp_callable(). This will be needed
later in kexec in order to sooner switch back to EL2.
This looks like the very definition of "run in nVHE mode", so I'd
rather you call it like this, rather than "callable", which is
extremely ambiguous (if running at EL2, I call it any time I want, for
free).
@@ -48,9 +48,6 @@*/externintin_suspend;-/* Do we need to reset el2? */-#define el2_reset_needed() (is_hyp_mode_available() && !is_kernel_in_hyp_mode())-
Please keep the macro, as it explains *why* we're doing things (we
need to reset EL2), and replacing it with a generic macro drops the
documentation aspect.
quoted hunk
/* temporary el2 vectors in the __hibernate_exit_text section. */
extern char hibernate_el2_vectors[];
@@ -125,7 +122,7 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size) hdr->reenter_kernel = _cpu_resume; /* We can't use __hyp_get_vectors() because kvm may still be loaded */- if (el2_reset_needed())+ if (is_hyp_callable()) hdr->__hyp_stub_vectors = __pa_symbol(__hyp_stub_vectors); else hdr->__hyp_stub_vectors = 0;
@@ -387,7 +384,7 @@ int swsusp_arch_suspend(void) dcache_clean_range(__idmap_text_start, __idmap_text_end); /* Clean kvm setup code to PoC? */- if (el2_reset_needed()) {+ if (is_hyp_callable()) { dcache_clean_range(__hyp_idmap_text_start, __hyp_idmap_text_end); dcache_clean_range(__hyp_text_start, __hyp_text_end); }
@@ -482,7 +479,7 @@ int swsusp_arch_resume(void) * * We can skip this step if we booted at EL1, or are running with VHE. */- if (el2_reset_needed()) {+ if (is_hyp_callable()) { phys_addr_t el2_vectors = (phys_addr_t)hibernate_exit; el2_vectors += hibernate_el2_vectors - __hibernate_exit_text_start; /* offset */
@@ -200,7 +200,7 @@ unsigned long sdei_arch_get_entry_point(int conduit)*droppedtoEL1becausewedon'tsupportVHE,thenwecan'tsupport*SDEI.*/-if(is_hyp_mode_available()&&!is_kernel_in_hyp_mode()){+if(is_hyp_callable()){pr_err("Not supported on this hardware/boot configuration\n");gotoout_err;}
--
2.25.1
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-06-02 01:19:37
quoted
It cannot call mutate_to_vhe because #HVC_VHE_RESTART is not used
here. But, if it had to it would not work as we cannot return to the
old kernel text after relocation.
OK, so you are happy with having a dangling branch pointing to
nowhere? Something in me screams that it isn't a good idea, in
general.
If HVC_SOFT_RESTART is all you need, I'd rather you have a small stub
that implements exactly that and nothing else. Feel free to extract it
as a reusable macro if you want.
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-06-02 01:34:32
On Tue, Jun 1, 2021 at 8:38 AM Marc Zyngier [off-list ref] wrote:
On Thu, 27 May 2021 16:05:12 +0100,
Pavel Tatashin [off-list ref] wrote:
quoted
Replace places that contain logic like this:
is_hyp_mode_available() && !is_kernel_in_hyp_mode()
With a dedicated boolean function is_hyp_callable(). This will be needed
later in kexec in order to sooner switch back to EL2.
This looks like the very definition of "run in nVHE mode", so I'd
rather you call it like this, rather than "callable", which is
extremely ambiguous (if running at EL2, I call it any time I want, for
free).
Hi Marc,
Naming is hard. Are you proposing s/is_hyp_callable/run_in_nvhe_mode/
? This is also not a very good name because it does not sound like a
boolean, but instead that we know that there is nvhe mode available
and we can switch to it.
nit: consider switching the two members of the expression so that you
don't have extra memory accesses when running at EL2.
Sure, I will do that.
quoted
-/* Do we need to reset el2? */
-#define el2_reset_needed() (is_hyp_mode_available() && !is_kernel_in_hyp_mode())
-
Please keep the macro, as it explains *why* we're doing things (we
need to reset EL2), and replacing it with a generic macro drops the
documentation aspect.
OK, I will keep the macro, and redefine it to use the common macro.
Thank you,
Pasha
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-06-02 08:21:02
On Wed, 02 Jun 2021 02:33:52 +0100,
Pavel Tatashin [off-list ref] wrote:
On Tue, Jun 1, 2021 at 8:38 AM Marc Zyngier [off-list ref] wrote:
quoted
On Thu, 27 May 2021 16:05:12 +0100,
Pavel Tatashin [off-list ref] wrote:
quoted
Replace places that contain logic like this:
is_hyp_mode_available() && !is_kernel_in_hyp_mode()
With a dedicated boolean function is_hyp_callable(). This will be needed
later in kexec in order to sooner switch back to EL2.
This looks like the very definition of "run in nVHE mode", so I'd
rather you call it like this, rather than "callable", which is
extremely ambiguous (if running at EL2, I call it any time I want, for
free).
Hi Marc,
Naming is hard.
News flash!
Are you proposing s/is_hyp_callable/run_in_nvhe_mode/ ? This is also
not a very good name because it does not sound like a boolean, but
instead that we know that there is nvhe mode available and we can
switch to it.
No, what I suggest is "is_hyp_nvhe()", or something along those
lines. It clearly identifies that we are in control of EL2, and which
mode it is in.
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pavel Tatashin <pasha.tatashin@soleen.com> Date: 2021-06-08 17:46:50
On Tue, Jun 1, 2021 at 9:18 PM Pavel Tatashin [off-list ref] wrote:
quoted
quoted
It cannot call mutate_to_vhe because #HVC_VHE_RESTART is not used
here. But, if it had to it would not work as we cannot return to the
old kernel text after relocation.
OK, so you are happy with having a dangling branch pointing to
nowhere? Something in me screams that it isn't a good idea, in
general.
If HVC_SOFT_RESTART is all you need, I'd rather you have a small stub
that implements exactly that and nothing else. Feel free to extract it
as a reusable macro if you want.
Using macro won't help here to save kernel text. Optimally, we would
want to use only one vector table to reduce kernel text memory usage.
I could do that by overwriting sync entries in
trans_pgd_copy_el2_vectors(). But, that would be ugly, as I would need
to have some specific assumptions about what entries need to be
overwritten. Therefore, I decided to move the vector table that we
currently have in hibernate code, and make it common between kexec and
hibernate; trans_pgd_copy_el2_vectors() will use that table's body to
create copies.
Thanks,
Pasha
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel