[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] xen/riscv: copy_to_guest/copy_from_guest functionality.
From: Slavisa Petrovic <Slavisa.Petrovic@xxxxxxxxx> This patch implements copy_to_guest/copy_from_guest functions for RISC-V. These functions are designed to facilitate data exchange between guest and hypervisor. Signed-off-by: Milan Djokic <Milan.Djokic@xxxxxxxxx> Signed-off-by: Slavisa Petrovic <Slavisa.Petrovic@xxxxxxxxx> --- Tested on qemu with xcp-ng latest branch https://gitlab.com/xen-project/people/olkur/xen/-/merge_requests/6 Full description on how to setup test environment can be found in attached PR link (Linux kernel patching to support copy_from_guest/copy_to_guest for RISC-V). Linux kernel patch shall be upstreamed after these changes are merged. --- xen/arch/riscv/Makefile | 1 + xen/arch/riscv/addr_translation.S | 63 +++++++++++++++++++++++ xen/arch/riscv/arch.mk | 6 ++- xen/arch/riscv/guestcopy.c | 43 ++++++++++++++++ xen/arch/riscv/include/asm/guest_access.h | 5 ++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 xen/arch/riscv/addr_translation.S create mode 100644 xen/arch/riscv/guestcopy.c diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile index a5eb2aed4b..1bd61cc993 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -10,6 +10,7 @@ obj-y += smp.o obj-y += stubs.o obj-y += traps.o obj-y += vm_event.o +obj-y += addr_translation.o $(TARGET): $(TARGET)-syms $(OBJCOPY) -O binary -S $< $@ diff --git a/xen/arch/riscv/addr_translation.S b/xen/arch/riscv/addr_translation.S new file mode 100644 index 0000000000..7e94774b47 --- /dev/null +++ b/xen/arch/riscv/addr_translation.S @@ -0,0 +1,63 @@ +#include <asm/riscv_encoding.h> +#include <asm/asm.h> + +.macro add_extable lbl +.pushsection .extable, "a" /* Start .extable section */ +.balign 8 /* Align to 8 bytes */ +.quad \lbl /* Add label address to extable */ +.popsection /* End section */ +.endm + +.section .text + +/* + * size_t _copy_to(uint64_t dest, const void *src, size_t len) + * + * a0 - dest + * a1 - src + * a2 - len + * + */ + +.global _copy_to +_copy_to: + la t0, copy_done /* Load address of return label */ + mv t2, zero /* Initialize counter to zero */ +loop_check: + beq t2, a2, copy_done /* Check if all bytes are copied */ + lb t3, (a1) /* Load byte from source (guest address) */ +store_byte: + hsv.b t3, (a0) /* Store byte to destination (host address) */ + add_extable store_byte /* Add exception table for this location */ + addi a0, a0, 1 /* Increment destination pointer */ + addi a1, a1, 1 /* Increment source pointer */ + addi t2, t2, 1 /* Increment byte counter */ + j loop_check /* Loop back if not done */ + +/* + * size_t _copy_from(void *dest, uint64_t src, size_t len) + * + * a0 - dest + * a1 - src + * a2 - len + * + */ + +.global _copy_from +_copy_from: + la t0, copy_done + mv t2, zero +loop_check_from: + beq t2, a2, copy_done +load_byte: + hlv.b t3, (a1) /* Load byte from guest address */ + add_extable load_byte + sb t3, (a0) + addi a0, a0, 1 + addi a1, a1, 1 + addi t2, t2, 1 + j loop_check_from + +copy_done: + mv a0, t2 /* Return number of bytes copied */ + ret diff --git a/xen/arch/riscv/arch.mk b/xen/arch/riscv/arch.mk index 17827c302c..f4098f5b5e 100644 --- a/xen/arch/riscv/arch.mk +++ b/xen/arch/riscv/arch.mk @@ -23,13 +23,17 @@ $(eval $(1) := \ $(call as-insn,$(CC) $(riscv-generic-flags)_$(1),$(value $(1)-insn),_$(1))) endef +h-extension-name := $(call cc-ifversion,-lt,1301, hh, h) +$(h-extension-name)-insn := "hfence.gvma" +$(call check-extension,$(h-extension-name)) + zbb-insn := "andn t0$(comma)t0$(comma)t0" $(call check-extension,zbb) zihintpause-insn := "pause" $(call check-extension,zihintpause) -extensions := $(zbb) $(zihintpause) +extensions := $(value $(h-extension-name)) $(zbb) $(zihintpause) extensions := $(subst $(space),,$(extensions)) diff --git a/xen/arch/riscv/guestcopy.c b/xen/arch/riscv/guestcopy.c new file mode 100644 index 0000000000..0325956845 --- /dev/null +++ b/xen/arch/riscv/guestcopy.c @@ -0,0 +1,43 @@ +#include <xen/bug.h> +#include <xen/domain_page.h> +#include <xen/errno.h> +#include <xen/sched.h> + +#include <asm/csr.h> +#include <asm/guest_access.h> +#include <asm/system.h> +#include <asm/traps.h> + +unsigned long copy_to(uint64_t dest, void* src, size_t len) +{ + size_t bytes; + + bytes = _copy_to(dest, src, len); + + if (bytes == len) + return 0; + else + return -ENOSYS; +} + +unsigned long copy_from(void *dest, uint64_t src, size_t len) +{ + size_t bytes; + + bytes = _copy_from(dest, src, len); + + if (bytes == len) + return 0; + else + return -ENOSYS; +} + +unsigned long raw_copy_to_guest(void *to, const void *from, unsigned len) +{ + return copy_to((vaddr_t)to, (void *)from, len); +} + +unsigned long raw_copy_from_guest(void *to, const void __user *from, unsigned len) +{ + return copy_from((void *)to, (vaddr_t)from, len); +} diff --git a/xen/arch/riscv/include/asm/guest_access.h b/xen/arch/riscv/include/asm/guest_access.h index 7cd51fbbde..4fcf3fbf68 100644 --- a/xen/arch/riscv/include/asm/guest_access.h +++ b/xen/arch/riscv/include/asm/guest_access.h @@ -2,6 +2,11 @@ #ifndef ASM__RISCV__GUEST_ACCESS_H #define ASM__RISCV__GUEST_ACCESS_H +#include <xen/types.h> + +extern size_t _copy_to(uint64_t dest, const void *src, size_t len); +extern size_t _copy_from(void *dest, uint64_t src, size_t len); + unsigned long raw_copy_to_guest(void *to, const void *from, unsigned len); unsigned long raw_copy_from_guest(void *to, const void *from, unsigned len); unsigned long raw_clear_guest(void *to, unsigned int len); -- 2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |