Commit 38f9e4b9 authored by Kalesh Singh's avatar Kalesh Singh Committed by Marc Zyngier
Browse files

arm64: kvm: Introduce nvhe stack size constants



Refactor nvhe stack code to use NVHE_STACK_SIZE/SHIFT constants,
instead of directly using PAGE_SIZE/SHIFT. This makes the code a bit
easier to read, without introducing any functional changes.

Cc: Marc Zyngier <maz@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: default avatarKalesh Singh <kaleshsingh@google.com>
Link: https://lore.kernel.org/r/20241112003336.1375584-1-kaleshsingh@google.com


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 68344037
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -145,13 +145,16 @@

#define OVERFLOW_STACK_SIZE	SZ_4K

#define NVHE_STACK_SHIFT       PAGE_SHIFT
#define NVHE_STACK_SIZE        (UL(1) << NVHE_STACK_SHIFT)

/*
 * With the minimum frame size of [x29, x30], exactly half the combined
 * sizes of the hyp and overflow stacks is the maximum size needed to
 * save the unwinded stacktrace; plus an additional entry to delimit the
 * end.
 */
#define NVHE_STACKTRACE_SIZE	((OVERFLOW_STACK_SIZE + PAGE_SIZE) / 2 + sizeof(long))
#define NVHE_STACKTRACE_SIZE	((OVERFLOW_STACK_SIZE + NVHE_STACK_SIZE) / 2 + sizeof(long))

/*
 * Alignment of kernel segments (e.g. .text, .data).
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ static inline void kvm_nvhe_unwind_init(struct unwind_state *state,

DECLARE_KVM_NVHE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack);
DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_stacktrace_info, kvm_stacktrace_info);
DECLARE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
DECLARE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base);

void kvm_nvhe_dump_backtrace(unsigned long hyp_offset);

+9 −9
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTR

DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);

DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base);
DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);

DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
@@ -2339,7 +2339,7 @@ static void __init teardown_hyp_mode(void)

	free_hyp_pgds();
	for_each_possible_cpu(cpu) {
		free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
		free_pages(per_cpu(kvm_arm_hyp_stack_base, cpu), NVHE_STACK_SHIFT - PAGE_SHIFT);
		free_pages(kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu], nvhe_percpu_order());

		if (free_sve) {
@@ -2527,15 +2527,15 @@ static int __init init_hyp_mode(void)
	 * Allocate stack pages for Hypervisor-mode
	 */
	for_each_possible_cpu(cpu) {
		unsigned long stack_page;
		unsigned long stack_base;

		stack_page = __get_free_page(GFP_KERNEL);
		if (!stack_page) {
		stack_base = __get_free_pages(GFP_KERNEL, NVHE_STACK_SHIFT - PAGE_SHIFT);
		if (!stack_base) {
			err = -ENOMEM;
			goto out_err;
		}

		per_cpu(kvm_arm_hyp_stack_page, cpu) = stack_page;
		per_cpu(kvm_arm_hyp_stack_base, cpu) = stack_base;
	}

	/*
@@ -2604,9 +2604,9 @@ static int __init init_hyp_mode(void)
	 */
	for_each_possible_cpu(cpu) {
		struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu);
		char *stack_page = (char *)per_cpu(kvm_arm_hyp_stack_page, cpu);
		char *stack_base = (char *)per_cpu(kvm_arm_hyp_stack_base, cpu);

		err = create_hyp_stack(__pa(stack_page), &params->stack_hyp_va);
		err = create_hyp_stack(__pa(stack_base), &params->stack_hyp_va);
		if (err) {
			kvm_err("Cannot map hyp stack\n");
			goto out_err;
@@ -2618,7 +2618,7 @@ static int __init init_hyp_mode(void)
		 * __hyp_pa() won't do the right thing there, since the stack
		 * has been mapped in the flexible private VA space.
		 */
		params->stack_pa = __pa(stack_page);
		params->stack_pa = __pa(stack_base);
	}

	for_each_possible_cpu(cpu) {
+2 −2
Original line number Diff line number Diff line
@@ -188,12 +188,12 @@ SYM_FUNC_END(__host_hvc)

	/*
	 * Test whether the SP has overflowed, without corrupting a GPR.
	 * nVHE hypervisor stacks are aligned so that the PAGE_SHIFT bit
	 * nVHE hypervisor stacks are aligned so that the NVHE_STACK_SHIFT bit
	 * of SP should always be 1.
	 */
	add	sp, sp, x0			// sp' = sp + x0
	sub	x0, sp, x0			// x0' = sp' - x0 = (sp + x0) - x0 = sp
	tbz	x0, #PAGE_SHIFT, .L__hyp_sp_overflow\@
	tbz	x0, #NVHE_STACK_SHIFT, .L__hyp_sp_overflow\@
	sub	x0, sp, x0			// x0'' = sp' - x0' = (sp + x0) - sp = x0
	sub	sp, sp, x0			// sp'' = sp' - x0 = (sp + x0) - x0 = sp

+6 −6
Original line number Diff line number Diff line
@@ -360,10 +360,10 @@ int pkvm_create_stack(phys_addr_t phys, unsigned long *haddr)

	prev_base = __io_map_base;
	/*
	 * Efficient stack verification using the PAGE_SHIFT bit implies
	 * Efficient stack verification using the NVHE_STACK_SHIFT bit implies
	 * an alignment of our allocation on the order of the size.
	 */
	size = PAGE_SIZE * 2;
	size = NVHE_STACK_SIZE * 2;
	addr = ALIGN(__io_map_base, size);

	ret = __pkvm_alloc_private_va_range(addr, size);
@@ -373,12 +373,12 @@ int pkvm_create_stack(phys_addr_t phys, unsigned long *haddr)
		 * at the higher address and leave the lower guard page
		 * unbacked.
		 *
		 * Any valid stack address now has the PAGE_SHIFT bit as 1
		 * Any valid stack address now has the NVHE_STACK_SHIFT bit as 1
		 * and addresses corresponding to the guard page have the
		 * PAGE_SHIFT bit as 0 - this is used for overflow detection.
		 * NVHE_STACK_SHIFT bit as 0 - this is used for overflow detection.
		 */
		ret = kvm_pgtable_hyp_map(&pkvm_pgtable, addr + PAGE_SIZE,
					  PAGE_SIZE, phys, PAGE_HYP);
		ret = kvm_pgtable_hyp_map(&pkvm_pgtable, addr + NVHE_STACK_SIZE,
					  NVHE_STACK_SIZE, phys, PAGE_HYP);
		if (ret)
			__io_map_base = prev_base;
	}
Loading