diff --git a/build.sh b/build.sh index 8d869d10f3..f69b06e91b 100755 --- a/build.sh +++ b/build.sh @@ -122,10 +122,37 @@ build_system_target_list() { build_system_lib_list() { local arch + local target + local lib + local libs=() IFS=',' read -ra split_arches <<< "$PENGUIN_SYSTEM_ARCHES" for arch in "${split_arches[@]}"; do - printf "libqemu-system-%s.so\n" "$arch" + target="$(penguin_system_arch_to_qemu_target "$arch")" + lib="libqemu-system-${target%-softmmu}.so" + if append_unique "$lib" "${libs[@]}"; then + libs+=("$lib") + fi + done + + printf "%s\n" "${libs[@]}" +} + +stage_system_lib_aliases() { + local arch + local target + local source + local alias + + IFS=',' read -ra split_arches <<< "$PENGUIN_SYSTEM_ARCHES" + for arch in "${split_arches[@]}"; do + target="$(penguin_system_arch_to_qemu_target "$arch")" + source="build-system/libqemu-system-${target%-softmmu}.so" + alias="build-system/libqemu-system-${arch}.so" + + if [ "$source" != "$alias" ]; then + cp -f "$source" "$alias" + fi done } @@ -148,6 +175,7 @@ configure_build_dir build-system \ mapfile -t system_libs < <(build_system_lib_list) ninja -C build-system "${system_libs[@]}" qemu-img +stage_system_lib_aliases python3 scripts/penguin-cffi-gen.py \ --mode system \ --build-dir build-system \ diff --git a/include/system/penguin.h b/include/system/penguin.h index a7eaecba0f..6a62fea2c7 100644 --- a/include/system/penguin.h +++ b/include/system/penguin.h @@ -28,6 +28,10 @@ typedef void (*penguin_mmio_write_cb_t)(uint64_t addr, uint64_t data, void set_penguin_guest_hypercall_callback(penguin_guest_hypercall_cb_t cb, void *opaque); +void penguin_register_guest_hypercall(uint64_t nr); +void penguin_unregister_guest_hypercall(uint64_t nr); +void penguin_clear_guest_hypercalls(void); +bool penguin_guest_hypercall_registered(uint64_t nr); void set_kvm_penguin_hypercall_callback(kvm_penguin_hypercall_cb_t cb); bool penguin_handle_guest_hypercall(CPUState *cs, uint64_t nr, diff --git a/scripts/penguin-cffi-gen.py b/scripts/penguin-cffi-gen.py index d4b2f9c49a..b2d0db8ae1 100644 --- a/scripts/penguin-cffi-gen.py +++ b/scripts/penguin-cffi-gen.py @@ -100,6 +100,10 @@ void set_penguin_guest_hypercall_callback(penguin_guest_hypercall_cb_t cb, void *opaque); +void penguin_register_guest_hypercall(uint64_t nr); +void penguin_unregister_guest_hypercall(uint64_t nr); +void penguin_clear_guest_hypercalls(void); +bool penguin_guest_hypercall_registered(uint64_t nr); void set_kvm_penguin_hypercall_callback(kvm_penguin_hypercall_cb_t cb); void set_kvm_penguin_after_guest_init_callback( kvm_penguin_after_guest_init_cb_t cb, void *opaque); diff --git a/system/penguin.c b/system/penguin.c index b345b58099..e8db587be0 100644 --- a/system/penguin.c +++ b/system/penguin.c @@ -15,6 +15,54 @@ typedef struct PenguinMmioRegion { static penguin_guest_hypercall_cb_t penguin_guest_hypercall_cb; static void *penguin_guest_hypercall_opaque; static kvm_penguin_hypercall_cb_t kvm_penguin_hypercall_cb; +static GHashTable *penguin_guest_hypercall_numbers; + +static void penguin_guest_hypercalls_init(void) +{ + if (!penguin_guest_hypercall_numbers) { + penguin_guest_hypercall_numbers = g_hash_table_new_full(g_int64_hash, + g_int64_equal, + g_free, NULL); + } +} + +void __attribute__((visibility("default"))) +penguin_register_guest_hypercall(uint64_t nr) +{ + uint64_t *key; + + penguin_guest_hypercalls_init(); + if (g_hash_table_contains(penguin_guest_hypercall_numbers, &nr)) { + return; + } + + key = g_new(uint64_t, 1); + *key = nr; + g_hash_table_add(penguin_guest_hypercall_numbers, key); +} + +void __attribute__((visibility("default"))) +penguin_unregister_guest_hypercall(uint64_t nr) +{ + if (penguin_guest_hypercall_numbers) { + g_hash_table_remove(penguin_guest_hypercall_numbers, &nr); + } +} + +void __attribute__((visibility("default"))) +penguin_clear_guest_hypercalls(void) +{ + if (penguin_guest_hypercall_numbers) { + g_hash_table_remove_all(penguin_guest_hypercall_numbers); + } +} + +bool __attribute__((visibility("default"))) +penguin_guest_hypercall_registered(uint64_t nr) +{ + return penguin_guest_hypercall_numbers && + g_hash_table_contains(penguin_guest_hypercall_numbers, &nr); +} void __attribute__((visibility("default"))) set_penguin_guest_hypercall_callback(penguin_guest_hypercall_cb_t cb, @@ -36,7 +84,8 @@ bool penguin_handle_guest_hypercall(CPUState *cs, uint64_t nr, uint64_t a4, uint64_t a5, uint64_t *ret) { - if (penguin_guest_hypercall_cb) { + if (penguin_guest_hypercall_cb && + penguin_guest_hypercall_registered(nr)) { return penguin_guest_hypercall_cb(cs, nr, a0, a1, a2, a3, a4, a5, ret, penguin_guest_hypercall_opaque) == 0; diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c index 81cfccbb74..878f19d1a9 100644 --- a/target/arm/tcg/op_helper.c +++ b/target/arm/tcg/op_helper.c @@ -95,7 +95,7 @@ uint64_t HELPER(penguin_guest_hypercall)(CPUARMState *env, uint64_t nr, if (penguin_handle_guest_hypercall(cs, nr, a0, a1, a2, a3, a4, 0, &ret)) { return ret; } - return 0; + return a0; } uint64_t HELPER(neon_tbl)(CPUARMState *env, uint32_t desc, diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c index 29803b45ad..7c5cfb3d7b 100644 --- a/target/loongarch/tcg/op_helper.c +++ b/target/loongarch/tcg/op_helper.c @@ -35,7 +35,7 @@ target_ulong helper_penguin_guest_hypercall(CPULoongArchState *env, if (penguin_handle_guest_hypercall(cs, nr, a0, a1, a2, a3, a4, 0, &ret)) { return ret; } - return 0; + return a0; } target_ulong helper_bitrev_w(target_ulong rj) diff --git a/target/mips/tcg/op_helper.c b/target/mips/tcg/op_helper.c index b40ef66e63..b4409db4d4 100644 --- a/target/mips/tcg/op_helper.c +++ b/target/mips/tcg/op_helper.c @@ -62,7 +62,7 @@ target_ulong helper_penguin_guest_hypercall(CPUMIPSState *env, target_ulong nr, if (penguin_handle_guest_hypercall(cs, nr, a0, a1, a2, a3, a4, 0, &ret)) { return ret; } - return 0; + return nr; } target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx, diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 787c83f938..bfa048a59f 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -55,7 +55,7 @@ target_ulong helper_penguin_guest_hypercall(CPUPPCState *env, target_ulong nr, if (penguin_handle_guest_hypercall(cs, nr, a0, a1, a2, a3, a4, 0, &ret)) { return ret; } - return 0; + return a0; } void helper_spr_core_write_generic(CPUPPCState *env, uint32_t sprn, diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 530a96ed3d..d86686872e 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -60,7 +60,7 @@ target_ulong helper_penguin_guest_hypercall(CPURISCVState *env, target_ulong nr, if (penguin_handle_guest_hypercall(cs, nr, a0, a1, a2, a3, a4, 0, &ret)) { return ret; } - return 0; + return a0; } target_ulong helper_csrr(CPURISCVState *env, int csr)