linux-headers/arch/e2k/include/asm/gregs.h

220 lines
7.1 KiB
C

#ifndef _E2K_GREGS_H
#define _E2K_GREGS_H
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/machdep.h>
#include <asm/glob_regs.h>
#include <asm/ptrace.h>
/*
* Save new value of gN and set current pointer into these register
* to can use macroses current & current_thread_info()
*/
#define SET_CURRENTS_GREGS(__task) \
({ \
E2K_SET_DGREG_NV(CURRENT_TASK_GREG, (__task)); \
})
#define SET_SMP_CPUS_GREGS(__cpu, __per_cpu_off) \
({ \
E2K_SET_DGREG_NV(SMP_CPU_ID_GREG, (__cpu)); \
E2K_SET_DGREG_NV(MY_CPU_OFFSET_GREG, (__per_cpu_off)); \
})
#define SET_KERNEL_GREGS(__task, __cpu, __per_cpu_off) \
({ \
SET_CURRENTS_GREGS(__task); \
SET_SMP_CPUS_GREGS(__cpu, __per_cpu_off); \
})
#define ONLY_SET_CURRENTS_GREGS(__ti) \
({ \
SET_CURRENTS_GREGS(thread_info_task(__ti)); \
})
#define ONLY_SAVE_KERNEL_CURRENTS_GREGS(task__) \
({ \
(task__) = NATIVE_GET_UNTEGGED_DGREG(CURRENT_TASK_GREG); \
})
#ifdef CONFIG_SMP
#define ONLY_SAVE_KERNEL_SMP_CPUS_GREGS(cpu_id__, cpu_off__) \
({ \
(cpu_id__) = NATIVE_GET_UNTEGGED_DGREG(SMP_CPU_ID_GREG); \
(cpu_off__) = NATIVE_GET_UNTEGGED_DGREG(MY_CPU_OFFSET_GREG); \
})
#else /* ! CONFIG_SMP */
#define ONLY_SAVE_KERNEL_SMP_CPUS_GREGS(cpu_id__, cpu_off__)
#endif /* CONFIG_SMP */
#define ONLY_SAVE_KERNEL_GREGS(task__, cpu_id__, cpu_off__) \
({ \
ONLY_SAVE_KERNEL_CURRENTS_GREGS(task__); \
ONLY_SAVE_KERNEL_SMP_CPUS_GREGS(cpu_id__, cpu_off__); \
})
#define ONLY_RESTORE_KERNEL_CURRENTS_GREGS(task__) \
({ \
NATIVE_SET_DGREG(CURRENT_TASK_GREG, task__); \
})
#ifdef CONFIG_SMP
#define ONLY_RESTORE_KERNEL_SMP_CPUS_GREGS(cpu_id__, cpu_off__) \
({ \
NATIVE_SET_DGREG(SMP_CPU_ID_GREG, cpu_id__); \
NATIVE_SET_DGREG(MY_CPU_OFFSET_GREG, cpu_off__); \
})
#else /* ! CONFIG_SMP */
#define ONLY_RESTORE_KERNEL_SMP_CPUS_GREGS(cpu_id__, cpu_off__)
#endif /* CONFIG_SMP */
#define ONLY_RESTORE_KERNEL_GREGS(task__, cpu_id__, cpu_off__)\
({ \
ONLY_RESTORE_KERNEL_CURRENTS_GREGS(task__); \
ONLY_RESTORE_KERNEL_SMP_CPUS_GREGS(cpu_id__, cpu_off__); \
})
#ifdef CONFIG_SMP
#define ONLY_SET_SMP_CPUS_GREGS(__ti) \
({ \
long __cpu = task_cpu(thread_info_task(__ti)); \
\
SET_SMP_CPUS_GREGS(__cpu, per_cpu_offset(__cpu)); \
})
#else /* ! CONFIG_SMP */
#define ONLY_SET_SMP_CPUS_GREGS(__ti)
#endif /* CONFIG_SMP */
#define ONLY_SET_KERNEL_GREGS(__ti) \
({ \
ONLY_SET_CURRENTS_GREGS(__ti); \
ONLY_SET_SMP_CPUS_GREGS(__ti); \
})
#define CLEAR_KERNEL_GREGS() \
({ \
SET_KERNEL_GREGS(0, 0, 0); \
})
#define NATIVE_SAVE_KERNEL_GREGS_AND_SET(__ti) \
({ \
machine.save_kernel_gregs(&(__ti)->k_gregs); \
ONLY_SET_KERNEL_GREGS(__ti); \
})
/*
* global registers used as pointers to current task & thread info
* must be restored and current & current_thread_info() can not be
* used from now
*/
#define ONLY_COPY_FROM_KERNEL_CURRENT_GREGS(__k_gregs, task__) \
({ \
(task__) = (__k_gregs)->g[CURRENT_TASK_GREGS_PAIRS_INDEX].base; \
})
#ifdef CONFIG_SMP
#define ONLY_COPY_FROM_KERNEL_SMP_CPUS_GREGS(__k_gregs, cpu_id__, cpu_off__) \
({ \
(cpu_id__) = (__k_gregs)->g[SMP_CPU_ID_GREGS_PAIRS_INDEX].base; \
(cpu_off__) = (__k_gregs)->g[MY_CPU_OFFSET_GREGS_PAIRS_INDEX].base; \
})
#else /* ! CONFIG_SMP */
#define ONLY_COPY_FROM_KERNEL_SMP_CPUS_GREGS(__k_gregs, cpu_id__, cpu_off__)
#endif /* CONFIG_SMP */
#define ONLY_COPY_FROM_KERNEL_GREGS(__k_gregs, task__, cpu_id__, cpu_off__) \
({ \
ONLY_COPY_FROM_KERNEL_CURRENT_GREGS(__k_gregs, task__); \
ONLY_COPY_FROM_KERNEL_SMP_CPUS_GREGS(__k_gregs, cpu_id__, cpu_off__); \
})
#define ONLY_COPY_TO_KERNEL_CURRENT_GREGS(__k_gregs, task__) \
({ \
(__k_gregs)->g[CURRENT_TASK_GREGS_PAIRS_INDEX].base = (task__); \
})
#ifdef CONFIG_SMP
#define ONLY_COPY_TO_KERNEL_SMP_CPUS_GREGS(__k_gregs, cpu_id__, cpu_off__) \
({ \
(__k_gregs)->g[SMP_CPU_ID_GREGS_PAIRS_INDEX].base = (cpu_id__); \
(__k_gregs)->g[MY_CPU_OFFSET_GREGS_PAIRS_INDEX].base = (cpu_off__); \
})
#else /* ! CONFIG_SMP */
#define ONLY_COPY_TO_KERNEL_SMP_CPUS_GREGS(__k_gregs, cpu_id__, cpu_off__)
#endif /* CONFIG_SMP */
#define ONLY_COPY_TO_KERNEL_GREGS(__k_gregs, task__, cpu_id__, cpu_off__) \
({ \
ONLY_COPY_TO_KERNEL_CURRENT_GREGS(__k_gregs, task__); \
ONLY_COPY_TO_KERNEL_SMP_CPUS_GREGS(__k_gregs, cpu_id__, cpu_off__); \
})
#define CLEAR_KERNEL_GREGS_COPY(__ti) \
ONLY_COPY_TO_KERNEL_GREGS(&(__ti)->k_gregs, 0, 0, 0)
#define NATIVE_RESTORE_KERNEL_GREGS_IN_SYSCALL(thread_info) \
({ \
thread_info_t *__ti = (thread_info); \
\
NATIVE_RESTORE_KERNEL_GREG(__ti->k_gregs.g, \
GUEST_VCPU_STATE_GREGS_PAIRS_INDEX, \
CURRENT_TASK_GREGS_PAIRS_INDEX, \
MY_CPU_OFFSET_GREGS_PAIRS_INDEX, \
SMP_CPU_ID_GREGS_PAIRS_INDEX, \
GUEST_VCPU_STATE_GREG, CURRENT_TASK_GREG, \
MY_CPU_OFFSET_GREG, SMP_CPU_ID_GREG); \
})
/* User global registers, used by kernel, keep into thread info structure */
/* and save to/restore from while enter to/return from kernel */
#define CLEAR_GREGS_COPY_FROM_CURRENTS(thread_info) \
({ \
thread_info_t *__ti = (thread_info); \
\
__ti->k_gregs.g[GUEST_VCPU_STATE_GREGS_PAIRS_INDEX].base = 0; \
__ti->k_gregs.g[GUEST_VCPU_STATE_GREGS_PAIRS_INDEX].ext = 0; \
__ti->k_gregs.g[CURRENT_TASK_GREGS_PAIRS_INDEX].base = 0; \
__ti->k_gregs.g[CURRENT_TASK_GREGS_PAIRS_INDEX].ext = 0; \
})
#if !defined(CONFIG_PARAVIRT_GUEST) && !defined(CONFIG_KVM_GUEST_KERNEL)
/* it is native kernel without any virtualization */
/* or it is native host kernel with virtualization support */
#define SAVE_KERNEL_GREGS_AND_SET(thread_info) \
NATIVE_SAVE_KERNEL_GREGS_AND_SET(thread_info)
#define RESTORE_KERNEL_GREGS_AND_FREE(thread_info) \
NATIVE_RESTORE_KERNEL_GREGS(&(thread_info)->k_gregs)
#define RESTORE_KERNEL_GREGS_IN_SYSCALL(thread_info) \
NATIVE_RESTORE_KERNEL_GREGS_IN_SYSCALL(thread_info)
#ifdef CONFIG_VIRTUALIZATION
/* it is native host kernel with virtualization support */
#include <asm/kvm/gregs.h>
#endif /* CONFIG_VIRTUALIZATION */
#endif /* ! CONFIG_PARAVIRT_GUEST && ! CONFIG_KVM_GUEST_KERNEL */
static inline void copy_k_gregs_to_gregs(struct global_regs *dst,
const struct kernel_gregs *src)
{
tagged_memcpy_8(&dst->g[KERNEL_GREGS_PAIRS_START], src->g,
sizeof(src->g));
}
static inline void copy_k_gregs_to_k_gregs(struct kernel_gregs *dst,
const struct kernel_gregs *src)
{
tagged_memcpy_8(dst->g, src->g, sizeof(src->g));
}
static inline void get_k_gregs_from_gregs(struct kernel_gregs *dst,
const struct global_regs *src)
{
tagged_memcpy_8(dst->g, &src->g[KERNEL_GREGS_PAIRS_START],
sizeof(dst->g));
}
static inline void copy_k_gregs_to_l_gregs(struct local_gregs *dst,
const struct kernel_gregs *src)
{
BUG_ON(KERNEL_GREGS_PAIRS_START < LOCAL_GREGS_START);
tagged_memcpy_8(&dst->g[KERNEL_GREGS_PAIRS_START - LOCAL_GREGS_START],
src->g, sizeof(src->g));
}
static inline void get_k_gregs_from_l_regs(struct kernel_gregs *dst,
const struct local_gregs *src)
{
BUG_ON(KERNEL_GREGS_PAIRS_START < LOCAL_GREGS_START);
tagged_memcpy_8(dst->g,
&src->g[KERNEL_GREGS_PAIRS_START - LOCAL_GREGS_START],
sizeof(dst->g));
}
#endif