linux-headers/arch/e2k/include/asm/kvm/ptrace.h

655 lines
24 KiB
C

#ifndef _E2K_KVM_PTRACE_H
#define _E2K_KVM_PTRACE_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/types.h>
#include <linux/threads.h>
#endif /* __ASSEMBLY__ */
#include <asm/page.h>
#ifndef __ASSEMBLY__
#include <asm/bug.h>
#include <asm/e2k_api.h>
#include <asm/pv_info.h>
#include <asm/cpu_regs.h>
#include <asm/glob_regs.h>
#include <asm/mmu_regs_types.h>
#ifdef CONFIG_USE_AAU
#include <asm/aau_regs.h>
#endif /* CONFIG_USE_AAU */
#include <asm/mlt.h>
#include <asm/ptrace-abi.h>
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
typedef enum inject_caller {
FROM_HOST_INJECT = 1 << 0,
FROM_PV_VCPU_TRAP_INJECT = 1 << 1,
FROM_PV_VCPU_SYSCALL_INJECT = 1 << 2
} inject_caller_t;
#ifdef CONFIG_VIRTUALIZATION
#if !defined(CONFIG_PARAVIRT_GUEST) && !defined(CONFIG_KVM_GUEST_KERNEL)
/* it is native host kernel with virtualization support */
#define BOOT_TASK_SIZE (BOOT_HOST_TASK_SIZE)
#elif defined(CONFIG_KVM_GUEST_KERNEL)
/* it is pure guest kernel */
#include <asm/kvm/guest/pv_info.h>
/* #define TASK_SIZE (GUEST_TASK_SIZE) */
/* #define BOOT_TASK_SIZE (BOOT_GUEST_TASK_SIZE) */
#else /* CONFIG_PARAVIRT_GUEST */
/* it is paravirtualized host and guest kernel */
#include <asm/paravirt/pv_info.h>
/* #define TASK_SIZE (PARAVIRT_TASK_SIZE) */
/* #define BOOT_TASK_SIZE (BOOT_PARAVIRT_TASK_SIZE) */
#endif /* ! CONFIG_PARAVIRT_GUEST && ! CONFIG_KVM_GUEST_KERNEL */
#endif /* CONFIG_VIRTUALIZATION */
#ifdef __KERNEL__
/*
* We could check CR.pm and TIR.ip here, but that is not needed
* because whenever CR.pm = 1 or TIR.ip < TASK_SIZE, SBR points
* to user space. So checking SBR alone is enough.
*
* Testing SBR is necessary because of HW bug #59886 - the 'ct' command
* (return to user) may be interrupted with closed interrupts.
* The result - kernel's ip, psr.pm=1, but SBR points to user space.
* This case should be detected as user mode.
*
* Checking via SBR is also useful for detecting fast system calls as
* user mode.
*/
#define is_user_mode(regs, __USER_SPACE_TOP__) \
((regs)->stacks.top < (__USER_SPACE_TOP__))
#define is_kernel_mode(regs, __KERNEL_SPACE_BOTTOM__) \
((regs)->stacks.top >= (__KERNEL_SPACE_BOTTOM__))
#define from_kernel_mode(cr1_lo) ((cr1_lo).CR1_lo_pm)
#define from_user_mode(cr1_lo) (!((cr1_lo).CR1_lo_pm))
#define is_from_user_IP(cr0_hi, __USER_SPACE_TOP__) \
({ \
unsigned long IP; \
bool ret; \
IP = (cr0_hi).CR0_hi_IP; \
ret = (IP < (__USER_SPACE_TOP__)); \
ret; \
})
#define is_from_kernel_IP(cr0_hi, __KERNEL_SPACE_BOTTOM__) \
({ \
unsigned long IP; \
bool ret; \
IP = (cr0_hi).CR0_hi_IP; \
ret = (IP >= (__KERNEL_SPACE_BOTTOM__)); \
ret; \
})
#define from_user_IP(cr0_hi) is_from_user_IP(cr0_hi, TASK_SIZE)
#define from_kernel_IP(cr0_hi) is_from_kernel_IP(cr0_hi, TASK_SIZE)
#define is_trap_from_user(regs, __USER_SPACE_TOP__) \
({ \
e2k_tir_lo_t tir_lo; \
tir_lo.TIR_lo_reg = (regs)->TIR_lo; \
tir_lo.TIR_lo_ip < (__USER_SPACE_TOP__); \
})
#define is_trap_from_kernel(regs, __KERNEL_SPACE_BOTTOM__) \
({ \
e2k_tir_lo_t tir_lo; \
tir_lo.TIR_lo_reg = (regs)->TIR_lo; \
tir_lo.TIR_lo_ip >= (__KERNEL_SPACE_BOTTOM__); \
})
#if !defined(CONFIG_KVM_GUEST_KERNEL) && !defined(CONFIG_PARAVIRT_GUEST)
/* it is native kernel without any virtualization */
/* or host kernel with virtualization support */
static inline void atomic_load_osgd_to_gd(void)
{
native_atomic_load_osgd_to_gd();
}
#define SAVE_DAM(__dam) NATIVE_SAVE_DAM(__dam)
#elif defined(CONFIG_PARAVIRT_GUEST)
/* it is paravirtualized host and guest kernel */
#include <asm/paravirt/mmu.h>
#elif defined(CONFIG_KVM_GUEST_KERNEL)
/* it is pure guest kernel (not paravirtualized based on pv_ops) */
#include <asm/kvm/guest/ptrace.h>
#else
#error "Undefined type of virtualization"
#endif /* ! CONFIG_KVM_GUEST_KERNEL && ! CONFIG_PARAVIRT_GUEST */
#if defined(CONFIG_VIRTUALIZATION)
/* it is host kernel with virtualization support */
/* or paravirtualized host and guest kernel */
/* or pure guest kernel (not paravirtualized based on pv_ops) */
#define guest_task_mode(task) \
test_ti_thread_flag(task_thread_info(task), \
TIF_VIRTUALIZED_GUEST)
#define native_user_mode(regs) is_user_mode(regs, NATIVE_TASK_SIZE)
#define guest_user_mode(regs) is_user_mode(regs, GUEST_TASK_SIZE)
#define native_kernel_mode(regs) is_kernel_mode(regs, NATIVE_TASK_SIZE)
#define guest_kernel_mode(regs) \
(is_kernel_mode(regs, GUEST_TASK_SIZE) && \
!native_kernel_mode(regs))
#define from_host_user_IP(cr0_hi) \
is_from_user_IP(cr0_hi, NATIVE_TASK_SIZE)
#define from_host_kernel_IP(cr0_hi) \
is_from_kernel_IP(cr0_hi, NATIVE_TASK_SIZE)
#define from_guest_user_IP(cr0_hi) \
is_from_user_IP(cr0_hi, GUEST_TASK_SIZE)
#define from_guest_kernel_IP(cr0_hi) \
(is_from_kernel_IP(cr0_hi, GUEST_TASK_SIZE) && \
!from_host_kernel_IP(cr0_hi))
#define from_host_user_mode(cr1_lo) from_user_mode(cr1_lo)
#define from_host_kernel_mode(cr1_lo) from_kernel_mode(cr1_lo)
/* guest user is user of guest kernel, so USER MODE (pm = 0) */
#define from_guest_user_mode(cr1_lo) from_user_mode(cr1_lo)
#define is_call_from_user(cr0_hi, cr1_lo, __HOST__) \
((__HOST__) ? \
is_call_from_host_user(cr0_hi, cr1_lo) : \
is_call_from_guest_user(cr0_hi, cr1_lo))
#define is_call_from_kernel(cr0_hi, cr1_lo, __HOST__) \
((__HOST__) ? \
is_call_from_host_kernel(cr0_hi, cr1_lo) : \
is_call_from_guest_kernel(cr0_hi, cr1_lo))
#ifndef CONFIG_KVM_GUEST_KERNEL
/* it is host kernel with virtualization support */
/* or paravirtualized host and guest kernel */
#define user_mode(regs) \
((regs) ? is_user_mode(regs, TASK_SIZE) : false)
#define kernel_mode(regs) \
((regs) ? is_kernel_mode(regs, TASK_SIZE) : true)
#ifdef CONFIG_KVM_HW_VIRTUALIZATION
/* guest kernel can be: */
/* user of host kernel, so USER MODE (pm = 0) */
/* hardware virtualized guest kernel, so KERNEL MODE (pm = 1) */
#define from_guest_kernel_mode(cr1_lo) \
(from_kernel_mode(cr1_lo) || from_user_mode(cr1_lo))
#define from_guest_kernel(cr0_hi, cr1_lo) \
(from_guest_kernel_mode(cr1_lo) && \
from_guest_kernel_IP(cr0_hi))
#else /* ! CONFIG_KVM_HW_VIRTUALIZATION */
/* guest kernel is user of host kernel, so USER MODE (pm = 0) */
#define from_guest_kernel_mode(cr1_lo) \
from_user_mode(cr1_lo)
#define from_guest_kernel(cr0_hi, cr1_lo) \
(from_guest_kernel_mode(cr1_lo) && \
from_guest_kernel_IP(cr0_hi))
#endif /* CONFIG_KVM_HW_VIRTUALIZATION */
#define is_trap_from_host_kernel(regs) \
is_trap_from_kernel(regs, NATIVE_TASK_SIZE)
#define is_call_from_host_user(cr0_hi, cr1_lo) \
(from_host_user_IP(cr0_hi) && from_host_user_mode(cr1_lo))
#define is_call_from_host_user_IP(cr0_hi, cr1_lo, ignore_IP) \
((!(ignore_IP)) ? is_call_from_host_user(cr0_hi, cr1_lo) : \
from_host_user_mode(cr1_lo))
#define is_call_from_guest_user(cr0_hi, cr1_lo) \
(from_guest_user_IP(cr0_hi) && from_guest_user_mode(cr1_lo))
#define is_call_from_guest_user_IP(cr0_hi, cr1_lo, ignore_IP) \
((!(ignore_IP)) ? is_call_from_guest_user(cr0_hi, cr1_lo) : \
from_guest_user_mode(cr1_lo))
#define is_call_from_host_kernel(cr0_hi, cr1_lo) \
(from_host_kernel_IP(cr0_hi) && from_host_kernel_mode(cr1_lo))
#define is_call_from_host_kernel_IP(cr0_hi, cr1_lo, ignore_IP) \
((!(ignore_IP)) ? is_call_from_host_kernel(cr0_hi, cr1_lo) : \
from_host_kernel_mode(cr1_lo))
#define is_call_from_guest_kernel(cr0_hi, cr1_lo) \
from_guest_kernel(cr0_hi, cr1_lo)
#define is_call_from_guest_kernel_IP(cr0_hi, cr1_lo, ignore_IP) \
((!(ignore_IP)) ? is_call_from_guest_kernel(cr0_hi, cr1_lo) : \
from_guest_kernel_mode(cr1_lo))
#define call_from_guest_kernel(regs) \
is_call_from_guest_kernel((regs)->crs.cr0_hi, (regs)->crs.cr1_lo)
#define is_trap_on_user(regs, __HOST__) \
((__HOST__) ? \
trap_from_host_user(regs) : \
trap_from_guest_user(regs))
#define is_trap_on_kernel(regs, __HOST__) \
((__HOST__) ? \
trap_from_host_kernel(regs) : \
(trap_from_guest_kernel(regs) || \
is_trap_from_host_kernel(regs)))
#define ON_HOST_KERNEL() (NATIVE_NV_READ_PSR_REG_VALUE() & PSR_PM)
#define __trap_from_user(regs) \
is_trap_on_user(regs, ON_HOST_KERNEL())
#define __trap_from_kernel(regs) \
is_trap_on_kernel(regs, ON_HOST_KERNEL())
#define trap_on_user(regs) __trap_from_user(regs)
#define trap_on_kernel(regs) __trap_from_kernel(regs)
#define call_from_user_mode(cr0_hi, cr1_lo) \
is_call_from_user(cr0_hi, cr1_lo, ON_HOST_KERNEL())
#define call_from_kernel_mode(cr0_hi, cr1_lo) \
is_call_from_kernel(cr0_hi, cr1_lo, ON_HOST_KERNEL())
#define call_from_user(regs) \
call_from_user_mode((regs)->crs.cr0_hi, (regs)->crs.cr1_lo)
#define call_from_kernel(regs) \
call_from_kernel_mode((regs)->crs.cr0_hi, (regs)->crs.cr1_lo)
#define __trap_from_host_user(regs) native_user_mode(regs)
#define __trap_from_host_kernel(regs) native_kernel_mode(regs)
#define __trap_from_guest_user(regs) guest_user_mode(regs)
#define __trap_from_guest_kernel(regs) guest_kernel_mode(regs)
#define __call_from_kernel(regs) call_from_kernel(regs)
#define __call_from_user(regs) call_from_user(regs)
#define trap_on_guest_kernel_mode(regs) \
from_guest_kernel_mode((regs)->crs.cr1_lo)
#define trap_on_guest_kernel_IP(regs) \
(from_guest_kernel_IP((regs)->crs.cr0_hi) && \
!from_host_kernel_IP((regs)->crs.cr0_hi))
#define host_trap_guest_user_mode(regs) \
(from_guest_user_mode((regs)->crs.cr1_lo) && \
__trap_from_guest_user(regs))
#define host_trap_guest_kernel_mode(regs) \
(from_guest_kernel((regs)->crs.cr0_hi, \
(regs)->crs.cr1_lo) && \
__trap_from_guest_kernel(regs))
#define guest_trap_user_mode(regs) \
(from_guest_kernel((regs)->crs.cr0_hi, \
(regs)->crs.cr1_lo) && \
__trap_from_guest_user(regs))
#define guest_trap_kernel_mode(regs) \
(from_guest_kernel((regs)->crs.cr0_hi, \
(regs)->crs.cr1_lo) && \
__trap_from_guest_kernel(regs))
#define trap_from_host_kernel_mode(regs) \
from_host_kernel_mode((regs)->crs.cr1_lo)
#define trap_from_host_kernel_IP(regs) \
from_host_kernel_IP((regs)->crs.cr0_hi)
#define trap_from_host_kernel(regs) \
(trap_from_host_kernel_mode(regs) && \
__trap_from_host_kernel(regs))
#define trap_from_host_user(regs) \
(from_host_user_mode((regs)->crs.cr1_lo) && \
__trap_from_host_user(regs))
/* macros to detect guest kernel traps on guest and on host */
/* trap only on guest kernel */
#define trap_from_guest_kernel(regs) \
(from_guest_kernel_mode((regs)->crs.cr1_lo) && \
__trap_from_guest_kernel(regs))
/* macros to detect guest traps on host, guest has not own guest, so */
/* macros should always return 'false' for guest */
/* trap occurred on guest user only */
#define trap_from_guest_user(regs) \
({ \
bool is; \
\
if (paravirt_enabled() || \
!test_thread_flag(TIF_VIRTUALIZED_GUEST)) \
/* It is guest and it cannot run own guest */ \
/* or trap is not on guest process */ \
is = false; \
else if (host_trap_guest_user_mode(regs)) \
is = true; \
else \
is = false; \
is; \
})
/* macroses to detect guest traps on host, guest has not own guest, so */
/* macroses should always return 'false' for guest */
/* trap occurred on guest process (guest user or guest kernel or on host */
/* while running guest process (guest VCPU thread) */
#define trap_on_guest(regs) \
(!paravirt_enabled() && \
test_thread_flag(TIF_VIRTUALIZED_GUEST))
#define trap_on_pv_hv_guest(vcpu, regs) \
((vcpu) != NULL && \
!((vcpu)->arch.is_hv) && trap_on_guest(regs))
/* guest trap occurred on guest user or kernel */
#define guest_trap_on_host(regs) \
(trap_on_guest(regs) && user_mode(regs))
#define guest_trap_on_pv_hv_host(vcpu, regs) \
(trap_on_pv_hv_guest(vcpu, regs) && user_mode(regs))
/* trap occurred on guest kernel or user, but in host mode */
/* and the trap can be due to guest or not */
#define host_trap_on_guest(regs) \
(guest_trap_on_host(regs) && \
trap_from_host_kernel_mode(regs) && \
trap_from_host_kernel_IP(regs))
/* guest trap occurred on guest user or kernel or on host but due to guest */
/* for example guest kernel address in hypercalls */
#define due_to_guest_trap_on_host(regs) \
(trap_on_guest(regs) && \
(user_mode(regs) || \
LIGHT_HYPERCALL_MODE(regs) || \
GENERIC_HYPERCALL_MODE()))
#define due_to_guest_trap_on_pv_hv_host(vcpu, regs) \
(trap_on_pv_hv_guest(vcpu, regs) && \
(user_mode(regs) || \
LIGHT_HYPERCALL_MODE(regs) || \
GENERIC_HYPERCALL_MODE()))
/* page fault is from intercept */
#define due_to_intc_page_fault(vcpu, regs) \
((vcpu) != NULL && \
(vcpu)->arch.is_hv && \
(regs)->trap->is_intc)
/* trap occurred on guest user only */
#define guest_user_trap_on_host(regs) \
(trap_on_guest(regs) && guest_trap_user_mode(regs))
/* trap occurred on guest kernel only */
#define guest_kernel_trap_on_host(regs) \
(trap_on_guest(regs) && guest_trap_kernel_mode(regs))
/* macros to detect guest traps on guest and on host */
/* trap on guest user, kernel or on host kernel due to guest */
#define __guest_trap(regs) \
(paravirt_enabled() || \
test_thread_flag(TIF_VIRTUALIZED_GUEST))
#define addr_from_guest_user(addr) ((addr) < GUEST_TASK_SIZE)
#define addr_from_guest_kernel(addr) \
((addr) >= GUEST_TASK_SIZE && (addr) < HOST_TASK_SIZE)
#define guest_user_addr_mode_page_fault(regs, instr_page, addr) \
((instr_page) ? guest_user_mode(regs) : \
guest_user_mode(regs) || \
(addr_from_guest_user(addr) && \
(!trap_from_host_kernel(regs) || \
LIGHT_HYPERCALL_MODE(regs) || \
GENERIC_HYPERCALL_MODE())))
/* macros to detect guest user address on host, */
/* guest has not own guest, so macros should always return 'false' for guest */
/* faulted address is from guest user space */
#define guest_mode_page_fault(regs, instr_page, addr) \
(trap_on_guest(regs) && \
guest_user_addr_mode_page_fault(regs, \
instr_page, addr))
/* macros to detect instruction page fault on guest kernel access */
/* such traps should be handled by host because of guest kernel */
/* is user of host */
#define guest_kernel_instr_page_fault(regs) \
(trap_on_guest(regs) && \
guest_trap_kernel_mode(regs) && \
trap_on_guest_kernel_IP(regs))
/* macros to detect instruction page fault on guest user access */
/* such traps should be handled by guest kernel */
#define guest_user_instr_page_fault(regs) \
(trap_on_guest(regs) && guest_user_mode(regs))
static inline e2k_addr_t
check_is_user_address(struct task_struct *task, e2k_addr_t address)
{
if (likely(address < TASK_SIZE))
return 0;
if (!paravirt_enabled()) {
pr_err("Address 0x%016lx is host kernel address\n",
address);
return -1;
} else if (address < NATIVE_TASK_SIZE) {
pr_err("Address 0x%016lx is guest kernel address\n",
address);
return -1;
} else {
pr_err("Address 0x%016lx is host kernel address\n",
address);
return -1;
}
}
#define IS_GUEST_USER_ADDRESS_TO_PVA(task, address) \
(test_ti_thread_flag(task_thread_info(tsk), \
TIF_VIRTUALIZED_GUEST) && \
IS_GUEST_USER_ADDRESS(address))
#define IS_GUEST_ADDRESS_TO_HOST(address) \
(paravirt_enabled() && !IS_HV_GM() && \
IS_HOST_KERNEL_ADDRESS(address))
#ifdef CONFIG_KVM_GUEST_HW_PV
/* FIXME Instead of ifdef, this should check for is_pv */
#define print_host_user_address_ptes(mm, address) \
native_print_host_user_address_ptes(mm, address)
#else
/* guest page table is pseudo PT and only host PT is used */
/* to translate any guest addresses */
#define print_host_user_address_ptes(mm, address) \
({ \
/* function is actual only for guest kernel */ \
if (paravirt_enabled()) \
HYPERVISOR_print_guest_user_address_ptes((mm)->gmmid_nr, \
address); \
})
#endif /* CONFIG_KVM_GUEST_HW_PV */
#else /* CONFIG_KVM_GUEST_KERNEL */
/* it is pure guest kernel (not paravirtualized based on pv_ops) */
#include <asm/kvm/guest/ptrace.h>
#endif /* ! CONFIG_KVM_GUEST_KERNEL */
#else /* ! CONFIG_VIRTUALIZATION */
/* it is native kernel without any virtualization */
#define guest_task_mode(task) false /* only native tasks */
#define user_mode(regs) is_user_mode(regs, TASK_SIZE)
#define kernel_mode(regs) is_kernel_mode(regs, TASK_SIZE)
#define is_call_from_host_user(cr0_hi, cr1_lo) \
(from_user_IP(cr0_hi) && from_user_mode(cr1_lo))
#define is_call_from_host_user_IP(cr0_hi, cr1_lo, ignore_IP) \
((!(ignore_IP)) ? is_call_from_host_user(cr0_hi, cr1_lo) : \
from_user_mode(cr1_lo))
#define is_call_from_guest_user(cr0_hi, cr1_lo) false
#define is_call_from_guest_user_IP(cr0_hi, cr1_lo, ignoreIP) false
#define is_call_from_host_kernel(cr0_hi, cr1_lo) \
(from_kernel_IP(cr0_hi) && from_kernel_mode(cr1_lo))
#define is_call_from_host_kernel_IP(cr0_hi, cr1_lo, ignore_IP) \
((!(ignore_IP)) ? is_call_from_host_kernel(cr0_hi, cr1_lo) : \
from_kernel_mode(cr1_lo))
#define is_call_from_guest_kernel(cr0_hi, cr1_lo) false
#define is_call_from_guest_kernel_IP(cr0_hi, cr1_lo, ignore_IP) false
#define call_from_guest_kernel(regs) false
#define is_call_from_user(cr0_hi, cr1_lo, __HOST__) \
is_call_from_host_user(cr0_hi, cr1_lo)
#define is_call_from_kernel(cr0_hi, cr1_lo, __HOST__) \
is_call_from_host_kernel(cr0_hi, cr1_lo)
#define __trap_from_user(regs) is_trap_from_user(regs, TASK_SIZE)
#define __trap_from_kernel(regs) is_trap_from_kernel(regs, TASK_SIZE)
#define trap_on_user(regs) user_mode(regs)
#define trap_on_kernel(regs) kernel_mode(regs)
/* macroses to detect guest traps on host */
/* Virtualization is off, so nothing guests exist, */
/* so macroses should always return 'false' */
#define trap_on_guest(regs) false
/* trap occurred on guest user or kernel */
#define guest_trap_on_host(regs) \
false /* guest is not supported */
/* trap occurred on guest kernel or user, but in host mode */
/* and the trap can be due to guest or not */
#define host_trap_on_guest(regs) \
false /* guest is not supported */
/* trap occurred on guest user or kernel or on host but due to guest */
#define due_to_guest_trap_on_host(regs) \
false /* guest is not supported */
/* page fault is from intercept */
#define due_to_intc_page_fault(vcpu, regs) \
false /* guest is not supported */
/* trap occurred on guest user only */
#define guest_user_trap_on_host(regs) \
false /* guest is not supported */
/* trap occurred on guest kernel only */
#define guest_kernel_trap_on_host(regs) \
false /* guest is not supported */
/* macros to detect guest traps on guest and on host */
/* trap on guest user, kernel or on host kernel due to guest */
#define __guest_trap(regs) \
false /* guest is not supported */
/* macros to detect guest kernel traps on guest and on host */
/* trap only on guest kernel */
#define trap_from_guest_kernel(regs) \
false /* guest is not supported */
#define __call_from_kernel(regs) from_kernel_mode((regs)->crs.cr1_lo)
#define __call_from_user(regs) from_user_mode((regs)->crs.cr1_lo)
#define ON_HOST_KERNEL() true
#define call_from_user_mode(cr0_hi, cr1_lo) \
is_call_from_user(cr0_hi, cr1_lo, ON_HOST_KERNEL())
#define call_from_kernel_mode(cr0_hi, cr1_lo) \
is_call_from_kernel(cr0_hi, cr1_lo, ON_HOST_KERNEL())
#define call_from_user(regs) \
call_from_user_mode((regs)->crs.cr0_hi, (regs)->crs.cr1_lo)
#define call_from_kernel(regs) \
call_from_kernel_mode((regs)->crs.cr0_hi, (regs)->crs.cr1_lo)
static inline e2k_addr_t
check_is_user_address(struct task_struct *task, e2k_addr_t address)
{
return native_check_is_user_address(task, address);
}
#define IS_GUEST_USER_ADDRESS_TO_PVA(task, address) \
NATIVE_IS_GUEST_USER_ADDRESS_TO_PVA(task, address)
#define IS_GUEST_ADDRESS_TO_HOST(address) \
NATIVE_IS_GUEST_ADDRESS_TO_HOST(address)
#define print_host_user_address_ptes(mm, address) \
native_print_host_user_address_ptes(mm, address)
#define guest_mode_page_fault(regs, instr_page, addr) false
#endif /* CONFIG_VIRTUALIZATION */
#ifndef CONFIG_VIRTUALIZATION
/* it is native kernel without virtualization support */
#define LIGHT_HYPERCALL_MODE(regs) 0 /* hypercalls not supported */
#define TI_GENERIC_HYPERCALL_MODE(thread_info) 0 /* hypercalls not supported */
#define GENERIC_HYPERCALL_MODE() 0 /* hypercalls not supported */
#define IN_LIGHT_HYPERCALL() 0 /* hypercalls not supported */
#define IN_GENERIC_HYPERCALL() 0 /* hypercalls not supported */
#define IN_HYPERCALL() 0 /* hypercalls not supported */
#elif defined(CONFIG_KVM_GUEST_KERNEL)
/* it is pure guest kernel (not paravirtualized) */
#include <asm/kvm/guest/ptrace.h>
#elif defined(CONFIG_VIRTUALIZATION) || defined(CONFIG_PARAVIRT_GUEST)
/* It is native host kernel with virtualization support on */
/* or it is paravirtualized host and guest kernel */
#define LIGHT_HYPERCALL_MODE(pt_regs) \
({ \
pt_regs_t *__regs = (pt_regs); \
bool is_ligh_hypercall; \
\
is_ligh_hypercall = __regs->flags.light_hypercall; \
is_ligh_hypercall; \
})
#define TI_LIGHT_HYPERCALL_MODE(thread_info) \
({ \
thread_info_t *__ti = (thread_info); \
test_ti_thread_flag(__ti, TIF_LIGHT_HYPERCALL); \
})
#define IN_LIGHT_HYPERCALL() TI_LIGHT_HYPERCALL_MODE(current_thread_info())
#define TI_GENERIC_HYPERCALL_MODE(thread_info) \
({ \
thread_info_t *__ti = (thread_info); \
test_ti_thread_flag(__ti, TIF_GENERIC_HYPERCALL); \
})
#define GENERIC_HYPERCALL_MODE() \
TI_GENERIC_HYPERCALL_MODE(current_thread_info())
#define IN_GENERIC_HYPERCALL() GENERIC_HYPERCALL_MODE()
#define IN_HYPERCALL() \
(IN_LIGHT_HYPERCALL() || IN_GENERIC_HYPERCALL())
#else /* ! CONFIG_VIRTUALIZATION && ! CONFIG_PARAVIRT_GUEST */
#error "Unknown virtualization type"
#endif /* ! CONFIG_VIRTUALIZATION */
#ifdef CONFIG_KVM_HOST_MODE
/* It is native host kernel with virtualization support on */
/*
* Additional context for paravirtualized guest to save/restore at
* 'signal_stack_context' structure to handle traps/syscalls by guest
*/
typedef struct pv_vcpu_ctxt {
inject_caller_t inject_from; /* reason of injection */
int trap_no; /* number of recursive trap */
int skip_frames; /* number signal stack frame to remove */
int skip_traps; /* number of traps frames to remove */
int skip_syscalls; /* number of syscall frames to remove */
u64 sys_rval; /* return value of guest system call */
e2k_psr_t guest_psr; /* guest PSR state before trap */
bool irq_under_upsr; /* is IRQ control under UOSR? */
bool in_sig_handler; /* signal handler in progress */
unsigned long sigreturn_entry; /* guest signal return start IP */
} pv_vcpu_ctxt_t;
#else /* !CONFIG_KVM_HOST_MODE */
/* it is native kernel without any virtualization */
/* or pure guest kernel (not paravirtualized) */
typedef struct pv_vcpu_ctxt {
/* empty structure */
} pv_vcpu_ctxt_t;
#endif /* CONFIG_KVM_HOST_MODE */
#ifdef CONFIG_VIRTUALIZATION
static inline struct pt_regs *find_guest_user_regs(struct pt_regs *regs)
{
struct pt_regs *guser_regs = regs;
do {
if (guest_user_mode(guser_regs))
break;
if (guser_regs->next != NULL &&
guser_regs->next <= guser_regs) {
/* pt_regs allocated only at the stack, stack grows */
/* down, so next structure can be only above current */
pr_err("%s(): invalid list of pt_regs structures: "
"next regs %px below current %px\n",
__func__, guser_regs->next, guser_regs);
WARN_ON(true);
guser_regs = NULL;
break;
}
guser_regs = guser_regs->next;
} while (guser_regs);
return guser_regs;
}
#else /* ! CONFIG_VIRTUALIZATION */
static inline struct pt_regs *find_guest_user_regs(struct pt_regs *regs)
{
return NULL;
}
#endif /* CONFIG_VIRTUALIZATION */
#if defined(CONFIG_SMP)
extern unsigned long profile_pc(struct pt_regs *regs);
#else
#define profile_pc(regs) instruction_pointer(regs)
#endif
extern void show_regs(struct pt_regs *);
extern int syscall_trace_entry(struct pt_regs *regs);
extern void syscall_trace_leave(struct pt_regs *regs);
#endif /* __KERNEL__ */
#endif /* _E2K_KVM_PTRACE_H */