From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f42.google.com (mail-ej1-f42.google.com [209.85.218.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81009239E6C for ; Tue, 24 Feb 2026 16:33:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.42 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771950834; cv=none; b=VNvyUstMvbzSKCLqIwOc3+KGr3FNLyERJQnUgXSGCUQitY6WCG7KNVTwkPDLORUILyxrPzjiIokENH/NsGRM7FyMKZU4KzvKZvXEkT2N7/VHNfj3BR305CECTWY8mQdhEe8AfFOgBykH1OsLI88qLFNVlcFlUd8d0rrlgTryqkY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771950834; c=relaxed/simple; bh=rPJi/x3Z2zS1znWpx5fEjE95103EaTzwlxSsjhND1cY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=i7fEzk6dpqQOuE8bc3qUzFLZZhuQteStNJJPn7Psl0gix6MgJYWPxTiKNgjrJSalyL8CIgL15EySMkjTf2gFb7iVPFN/kBAqBjMAu/sQKbeyosXWZOnEj1nUciiZf2zsGCaqrwT7AhO3iPo0HoYjUCBs2wh8/uogHXMSoah73Ss= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=permerror header.from=versity.com; spf=pass smtp.mailfrom=versity.com; dkim=pass (2048-bit key) header.d=versity.com header.i=@versity.com header.b=UMHO3HT0; arc=none smtp.client-ip=209.85.218.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=permerror header.from=versity.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=versity.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=versity.com header.i=@versity.com header.b="UMHO3HT0" Received: by mail-ej1-f42.google.com with SMTP id a640c23a62f3a-b8d7f22d405so904800366b.0 for ; Tue, 24 Feb 2026 08:33:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=versity.com; s=google; t=1771950831; x=1772555631; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KiJ3xY8S995HRb10LVJQh5Fwewchlco0fUjoVngvqds=; b=UMHO3HT03HPMfvPytibPH/GCej7QfuFiDUBvgoh69APQkH9d24HsquzFaayBYxuU7X bNUNoCIqL+oSSpdEefVMRdsXKZ7Iave9OEVgR4cnYjgmiojGOcXne/AlqjuJx/xQN9m+ caVZmIotgkbVc3qGLnO7SnnslVbMLAargDsSnnrp705gcYsG1zxW/Zy9tni2W1SE4mP9 4t7fT1e4r4gOhnjGIMv8670ftz8ZmQuc0ZaaeXbN3Uo2e/23zlpsJqaZ6ssZSndPFgh9 43SLRMoxbmb8PoTNB6O72AxQuHwQmFXMpxWdqlLdH+R4Jr3Bj8Q7rioGiX77ZLpX5RGM ccDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771950831; x=1772555631; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=KiJ3xY8S995HRb10LVJQh5Fwewchlco0fUjoVngvqds=; b=oQt0z9IBbk0Ro2FEOIBRkSWYWfwOoptWP9BKu/1Ot5FpLVE4GGpCQzn2xJ5QKrH6je gT9VDNEQhoJNeR0eDjy9jzBdogxL8HkZpi2l5m6fOJRSc3vK6p0ORPqdWuByZyqxYp+r HmMklen9A/y3WuYxDGSV/tv+daa6Webchb7H+7RoDufhJbts8J9HUoEx0jAIet+JiYel xX9/jYYd41uZ54j7vn5thCjxJYsApMiRF98Z2Gv3DgFMa0PPSspY+Svz3StGpUyKDQEq x/AdWLiCvV+iMaPwQNYu+BfFheHO3hsfARrIU50ZHXOOH9agrx6f0c/WUybke+Jtjbv4 CO4w== X-Gm-Message-State: AOJu0YzKB99YfftzGf3iTHwBdNBmIHKH0LBlJsEDHScX7+X5eUwEKGK6 gvGCaDSNtmdkHGC4YvGP6I3/XXo7GSLVBX1n2AqeI43XzfpFcm2ZcCoiyPE0EPRg8T11wX8zoIG k62ku5dI= X-Gm-Gg: AZuq6aJckriz6c+5j4Y1kUrHfNt2Pjuhh0psF/+x9C1l1K5Cbf1ZCxhq6FXIyZLTG6J Z1dJSp2yWXc3CBQmnrFoOSFhRJzeTtgnEWVgfD4jMXBFsymuDFK2tEdmVAYl2n9LmIjnfHHHuYd 7hP3Aw3WE72cmLzyOw1rld1yqYcoJZV/R7YkRrAuEvUQ+1fl08yFyBHMr6iCBPazCnrUPljZ71c ZFuQ3s5kf7xtFrHtVKVsV1Xt0jpHJCg7dpAuytCSU+MrAdyGO5hSS36IyaqDx0JoOnB8rXaOHHt HeIJ6dPOM423eUi9h+N64Aorh8Ym16EbFknRUa5Ly6hQU3OxJCIRDyZXxdpkD/ei+a32gl7eiKg iGP32ZgOgL4ZuXBceqpo62tTX1fnbBxpxom7g8z2Ai9ThMGHJRZPUHwrn/tHt5NEq9BgYQD7vXL jnzmznXArmgV6Ezc/jVQL67urUa321Vcx85AjrgTuClVSFKsRN3lE76z/PTXEyqEQef5N6//M0b Sewjg== X-Received: by 2002:a17:907:724b:b0:b8a:f7ec:d995 with SMTP id a640c23a62f3a-b90819717e2mr786985366b.9.1771950830394; Tue, 24 Feb 2026 08:33:50 -0800 (PST) Received: from localhost.localdomain (46-117-212-87.ftth.glasoperator.nl. [87.212.117.46]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b90e250f74csm103652666b.16.2026.02.24.08.33.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Feb 2026 08:33:50 -0800 (PST) From: Valerie Aurora To: rpdfs-devel@lists.linux.dev Cc: Valerie Aurora Subject: [PATCH 1/3] Initial support for ARM64, incompatible with x86_64 Date: Tue, 24 Feb 2026 17:33:24 +0100 Message-ID: <20260224163327.2441-2-val@versity.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20260224163327.2441-1-val@versity.com> References: <20260224163327.2441-1-val@versity.com> Precedence: bulk X-Mailing-List: rpdfs-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A quick hack to support task switching on ARM64 without any attempt to make it portable or compatible with x86_64. Will come back to it later if there is interest. --- Makefile | 9 +++-- utask/utask.c | 17 +++++++++- utask/utask_asm.S | 84 ++++++++++++++++++++++++++++++---------------- utask/utask_defs.h | 2 +- 4 files changed, 79 insertions(+), 33 deletions(-) diff --git a/Makefile b/Makefile index 8253885..6511202 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,9 @@ # make every target depend on the makefile .EXTRA_PREREQS:= $(abspath $(lastword $(MAKEFILE_LIST))) -CFLAGS := -I. -O2 -ggdb -Wall -Werror -D_FILE_OFFSET_BITS=64 -msse4.2 -fno-strict-aliasing -fno-omit-frame-pointer +#CFLAGS := -I. -O2 -ggdb -Wall -Werror -D_FILE_OFFSET_BITS=64 -msse4.2 -fno-strict-aliasing -fno-omit-frame-pointer + +CFLAGS := -I. -I/usr/lib64/ -O2 -ggdb -Wall -Werror -D_FILE_OFFSET_BITS=64 -fno-strict-aliasing -fno-omit-frame-pointer # function entrance/exit profiling for uftrace CFLAGS += -pg @@ -16,6 +18,9 @@ LDFLAGS := -Wl,--gc-sections -lxxhash -luring -luuid -lsystemd # provide dynamic symbol tables for backtrace() LDFLAGS += -rdynamic +# aarch64 needs this to find libraries +LDFLAGS += -L/usr/lib64/ + # build all c files in source directories DIR := cli devd shared shared/lk utask SRC := $(foreach d,$(DIR),$(wildcard $(d)/*.c)) @@ -73,7 +78,7 @@ $(OBJ_S): %.o: %.S utask/utask_defs.h utask/utask_gen_defs.h utask/utask.s: utask/utask.c gcc -I. -S -o ./utask/utask.s ./utask/utask.c -# extract defines from complied asm so we can include it from asm source +# extract defines from compiled asm so we can include it from asm source utask/utask_gen_defs.h: utask/utask.s grep '#define.*\ utask/utask_gen_defs.h diff --git a/utask/utask.c b/utask/utask.c index 7006f5c..3575b67 100644 --- a/utask/utask.c +++ b/utask/utask.c @@ -97,7 +97,7 @@ static struct utask *get_current_utask(void) struct utask *tsk; unsigned long sp; - asm("movq %%rsp, %0 \n\t" + asm("mov %0, sp \n\t" : "=rm" (sp) : : ); tsk = (void *)(round_up(sp, UTASK_STACK_SIZE) - sizeof(struct utask)); @@ -405,6 +405,7 @@ int utask_create_name_nowake(char *name, utask_fn_t fn, void *data, struct utask struct utask *tsk = NULL; unsigned long after; void *stack; + void *fp; int ret; ret = posix_memalign(&stack, UTASK_STACK_SIZE, UTASK_STACK_SIZE); @@ -439,15 +440,29 @@ int utask_create_name_nowake(char *name, utask_fn_t fn, void *data, struct utask if (!IS_ALIGNED(after, 16)) tsk->sp -= 16 - (after & 15); + /* for alignment (I think?) */ + push_stack(tsk, NULL); + /* final null address to terminate backtracing unwinders */ push_stack(tsk, NULL); + /* first switch_to jumps to _entry */ push_stack(tsk, utask_entry); + /* aarch64 wants the return address and the frame pointer on the stack */ + fp = tsk->sp; + push_stack(tsk, fp); + /* initial zeroed saved registers */ tsk->sp -= UTASK_SAVED_BYTES; memset(tsk->sp, 0, UTASK_SAVED_BYTES); + /* aarch64 - write the frame pointer into the second to last register */ + *(void **)(tsk->sp) = fp; + + /* aarch64 - write the return address into the last register (link register) */ + *(void **)(tsk->sp + sizeof(void *)) = utask_entry; + ret = 0; out: if (ret < 0) diff --git a/utask/utask_asm.S b/utask/utask_asm.S index a693520..c69a090 100644 --- a/utask/utask_asm.S +++ b/utask/utask_asm.S @@ -14,46 +14,48 @@ # and epilogue. So we save and restore them as we switch to and from # stacks. # -# ``Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling +# ``Registers %rbp, %rbx and %r12 through %r15 "belong" to the calling # function and the called function is required to preserve their # values.'' -- x86_64 ABI. # .macro push_callee_saved - push %rbx - push %r12 - push %r13 - push %r14 - push %r15 - push %rbp + stp x19, x20, [sp, #-16]! + stp x21, x22, [sp, #-16]! + stp x23, x24, [sp, #-16]! + stp x25, x26, [sp, #-16]! + stp x27, x28, [sp, #-16]! + stp x29, x30, [sp, #-16]! .endm .macro pop_callee_saved - pop %rbp - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %rbx + ldp x29, x30, [sp], #16 + ldp x27, x28, [sp], #16 + ldp x25, x26, [sp], #16 + ldp x23, x24, [sp], #16 + ldp x21, x22, [sp], #16 + ldp x19, x20, [sp], #16 .endm # -# set rbx to the address of the utask struct found at the base of the +# set x9 to the address of the utask struct found at the base of the # stack. # -.macro load_utask_rbx - movq %rsp, %rbx - andq $UTASK_STACK_BASE_MASK, %rbx - addq $(UTASK_STACK_SIZE - UTASK_ASM_SIZEOF_UTASK), %rbx +.macro load_utask_x9 + mov x9, sp + mov x10, #UTASK_STACK_BASE_MASK + and x9, x9, x10 + mov x10, #(UTASK_STACK_SIZE - UTASK_ASM_SIZEOF_UTASK) + add x9, x9, x10 .endm # -# int utask_switch_to(utask *utask /* rdi */); +# int utask_switch_to(utask *utask /* x0 */); # # Resume execution of a utask that was previously stopped by switching # from the scheduler's stack to the task's. # # Save the calling scheduler's stack pointer, restore the utask's stack -# pointer, and return into the address that the utask pushed as they +# pointer, and return into the address that the utask saved as they # last called _switch_from. # # The ret here is returning to the caller of _switch_from, which is void, @@ -63,8 +65,18 @@ .type utask_switch_to, @function utask_switch_to: push_callee_saved - movq %rsp, UTASK_ASM_OFFSETOF_SCHED_SP(%rdi) - movq UTASK_ASM_OFFSETOF_SP(%rdi), %rsp + // store scheduler/caller sp into utask struct at x0 + mov x9, x0 + add x9, x9, UTASK_ASM_OFFSETOF_SCHED_SP + mov x10, sp + str x10, [x9] + + // load utask sp from utask struct into sp + mov x9, x0 + add x9, x9, UTASK_ASM_OFFSETOF_SP + ldr x10, [x9] + mov sp, x10 + pop_callee_saved ret @@ -83,11 +95,22 @@ utask_switch_to: .type utask_switch_from, @function utask_switch_from: push_callee_saved - load_utask_rbx - movq %rsp, UTASK_ASM_OFFSETOF_SP(%rbx) - movq UTASK_ASM_OFFSETOF_SCHED_SP(%rbx), %rsp + load_utask_x9 // load the calling utask's utask struct into x9 + + // store the utask sp into utask struct + mov x10, x9 + add x10, x10, UTASK_ASM_OFFSETOF_SP // add the utask sp offset + mov x11, sp + str x11, [x10] // store sp in utask sp + + // load the scheduler sp into the sp of the utask struct in x9 + mov x10, x9 + add x10, x10, UTASK_ASM_OFFSETOF_SCHED_SP // add the sched sp offset + ldr x11, [x10] + mov sp, x11 + pop_callee_saved - movq $UTASK_RET_SCHEDULED, %rax + mov x0, UTASK_RET_SCHEDULED ret # @@ -102,8 +125,11 @@ utask_switch_from: .globl utask_finish .type utask_finish, @function utask_finish: - load_utask_rbx - movq UTASK_ASM_OFFSETOF_SCHED_SP(%rbx), %rsp + // load scheduler sp out of utask struct into sp + load_utask_x9 + add x9, x9, UTASK_ASM_OFFSETOF_SCHED_SP // add the sched sp offset + ldr x10, [x9] + mov sp, x10 pop_callee_saved - mov $UTASK_RET_FINISHED, %rax + mov x0, UTASK_RET_FINISHED // return UTASK_RET_FINISHED ret diff --git a/utask/utask_defs.h b/utask/utask_defs.h index 5f186c3..f5cd62d 100644 --- a/utask/utask_defs.h +++ b/utask/utask_defs.h @@ -11,7 +11,7 @@ #define UTASK_STACK_SIZE (8 * 1024) #define UTASK_STACK_BASE_MASK (~(UTASK_STACK_SIZE - 1)) -#define UTASK_SAVED_BYTES (6 * 8) +#define UTASK_SAVED_BYTES (12 * 8) #define UTASK_RET_SCHEDULED 0 #define UTASK_RET_FINISHED 1 -- 2.49.0