4df8d22bbb
paravirtualize ia64_swtich_to, ia64_leave_syscall and ia64_leave_kernel. They include sensitive or performance critical privileged instructions so that they need paravirtualization. To paravirtualize them by single source and multi compile they are converted into indirect jump. And define each pv instances. Cc: Keith Owens <kaos@ocs.com.au> Cc: "Dong, Eddie" <eddie.dong@intel.com> Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
115 lines
3.7 KiB
C
115 lines
3.7 KiB
C
/******************************************************************************
|
|
* include/asm-ia64/paravirt_privops.h
|
|
*
|
|
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
|
|
* VA Linux Systems Japan K.K.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
#ifndef _ASM_IA64_PARAVIRT_PRIVOP_H
|
|
#define _ASM_IA64_PARAVIRT_PRIVOP_H
|
|
|
|
#ifdef CONFIG_PARAVIRT
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include <linux/types.h>
|
|
#include <asm/kregs.h> /* for IA64_PSR_I */
|
|
|
|
/******************************************************************************
|
|
* replacement of intrinsics operations.
|
|
*/
|
|
|
|
struct pv_cpu_ops {
|
|
void (*fc)(unsigned long addr);
|
|
unsigned long (*thash)(unsigned long addr);
|
|
unsigned long (*get_cpuid)(int index);
|
|
unsigned long (*get_pmd)(int index);
|
|
unsigned long (*getreg)(int reg);
|
|
void (*setreg)(int reg, unsigned long val);
|
|
void (*ptcga)(unsigned long addr, unsigned long size);
|
|
unsigned long (*get_rr)(unsigned long index);
|
|
void (*set_rr)(unsigned long index, unsigned long val);
|
|
void (*set_rr0_to_rr4)(unsigned long val0, unsigned long val1,
|
|
unsigned long val2, unsigned long val3,
|
|
unsigned long val4);
|
|
void (*ssm_i)(void);
|
|
void (*rsm_i)(void);
|
|
unsigned long (*get_psr_i)(void);
|
|
void (*intrin_local_irq_restore)(unsigned long flags);
|
|
};
|
|
|
|
extern struct pv_cpu_ops pv_cpu_ops;
|
|
|
|
extern void ia64_native_setreg_func(int regnum, unsigned long val);
|
|
extern unsigned long ia64_native_getreg_func(int regnum);
|
|
|
|
/************************************************/
|
|
/* Instructions paravirtualized for performance */
|
|
/************************************************/
|
|
|
|
/* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
|
|
* static inline function doesn't satisfy it. */
|
|
#define paravirt_ssm(mask) \
|
|
do { \
|
|
if ((mask) == IA64_PSR_I) \
|
|
pv_cpu_ops.ssm_i(); \
|
|
else \
|
|
ia64_native_ssm(mask); \
|
|
} while (0)
|
|
|
|
#define paravirt_rsm(mask) \
|
|
do { \
|
|
if ((mask) == IA64_PSR_I) \
|
|
pv_cpu_ops.rsm_i(); \
|
|
else \
|
|
ia64_native_rsm(mask); \
|
|
} while (0)
|
|
|
|
/******************************************************************************
|
|
* replacement of hand written assembly codes.
|
|
*/
|
|
struct pv_cpu_asm_switch {
|
|
unsigned long switch_to;
|
|
unsigned long leave_syscall;
|
|
unsigned long work_processed_syscall;
|
|
unsigned long leave_kernel;
|
|
};
|
|
void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch);
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#define IA64_PARAVIRT_ASM_FUNC(name) paravirt_ ## name
|
|
|
|
#else
|
|
|
|
/* fallback for native case */
|
|
#define IA64_PARAVIRT_ASM_FUNC(name) ia64_native_ ## name
|
|
|
|
#endif /* CONFIG_PARAVIRT */
|
|
|
|
/* these routines utilize privilege-sensitive or performance-sensitive
|
|
* privileged instructions so the code must be replaced with
|
|
* paravirtualized versions */
|
|
#define ia64_switch_to IA64_PARAVIRT_ASM_FUNC(switch_to)
|
|
#define ia64_leave_syscall IA64_PARAVIRT_ASM_FUNC(leave_syscall)
|
|
#define ia64_work_processed_syscall \
|
|
IA64_PARAVIRT_ASM_FUNC(work_processed_syscall)
|
|
#define ia64_leave_kernel IA64_PARAVIRT_ASM_FUNC(leave_kernel)
|
|
|
|
#endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */
|