linux-headers/arch/e2k/include/asm/kvm/guest/proc_context_stacks.h

79 lines
2.2 KiB
C

#ifndef KVM_GUEST_PROC_CTXT_STACKS
#define KVM_GUEST_PROC_CTXT_STACKS
#include <linux/mm_types.h>
#include <asm/machdep.h>
#include <asm/trap_table.h>
#include <asm/kvm/proc_context_types.h>
#include <asm/copy-hw-stacks.h>
static inline int
kvm_mkctxt_prepare_hw_user_stacks(void (*user_func)(void), void *args,
u64 args_size, size_t d_stack_sz,
bool protected, void *ps_frames,
e2k_mem_crs_t *cs_frames)
{
unsigned long ps_frames_k, cs_frames_k;
struct page *pg_ps_frames, *pg_cs_frames;
int ret;
/* Get kernel address for procedure stack */
pg_ps_frames = get_user_addr_to_kernel_page((unsigned long)ps_frames);
if (IS_ERR_OR_NULL(pg_ps_frames))
ret = (IS_ERR(pg_ps_frames)) ? PTR_ERR(pg_ps_frames) : -EINVAL;
else
ps_frames_k = ((unsigned long)page_address(pg_ps_frames)) +
(((unsigned long)ps_frames) & ~PAGE_MASK);
/* Get kernel address for chain stack */
pg_cs_frames = get_user_addr_to_kernel_page((unsigned long)cs_frames);
if (IS_ERR_OR_NULL(pg_cs_frames))
ret |= (IS_ERR(pg_cs_frames)) ? PTR_ERR(pg_cs_frames) : -EINVAL;
else
cs_frames_k = ((unsigned long)page_address(pg_cs_frames)) +
(((unsigned long)cs_frames) & ~PAGE_MASK);
if (ret)
return ret;
kvm_proc_ctxt_hw_stacks_t hw_stacks = {
.user_func = user_func,
.args = args,
.args_size = args_size,
.d_stack_sz = d_stack_sz,
.protected = protected,
.gst_mkctxt_trampoline = (u64)&kvm_guest_mkctxt_trampoline,
.ps_frames = (void *)ps_frames_k,
.cs_frames = (e2k_mem_crs_t *)cs_frames_k
};
ret = HYPERVISOR_prepare_mkctxt_hw_user_stacks(&hw_stacks);
put_user_addr_to_kernel_page(pg_ps_frames);
put_user_addr_to_kernel_page(pg_cs_frames);
return ret;
}
static inline int
mkctxt_prepare_hw_user_stacks(void (*user_func)(void), void *args,
u64 args_size, size_t d_stack_sz,
bool protected, void *ps_frames,
e2k_mem_crs_t *cs_frames)
{
if (IS_HV_GM()) {
return native_mkctxt_prepare_hw_user_stacks(user_func, args,
args_size, d_stack_sz,
protected, ps_frames,
cs_frames);
} else {
return kvm_mkctxt_prepare_hw_user_stacks(user_func, args,
args_size, d_stack_sz,
protected, ps_frames,
cs_frames);
}
}
#endif /* KVM_GUEST_PROC_CTXT_STACKS */