Use generic getreg/setreg pv_cpu_ops instead of
specific ones that may vary per hypervisor.
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@xxxxxxxxx>
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index 8e9fb96..072a1de 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -83,27 +83,6 @@ struct pv_init_ops pv_init_ops;
return ia64_native_ ## name(arg); \
} \
-#define DEFINE_SET_KR(N) \
- static void \
- ia64_native_set_kr ## N ## _func(unsigned long val) \
- { \
- ia64_native_setreg(_IA64_REG_AR_KR ## N, val); \
- } \
-
-#define DEFINE_GETREG(name, reg) \
- static unsigned long \
- ia64_native_get_ ## name ## _func(void) \
- { \
- return ia64_native_getreg(_IA64_REG_ ## reg); \
- }
-
-#define DEFINE_SETREG(name, reg) \
- static void \
- ia64_native_set_ ## name ## _func(unsigned long val) \
- { \
- ia64_native_setreg(_IA64_REG_ ## reg, val); \
- }
-
DEFINE_VOID_FUNC1(fc);
DEFINE_VOID_FUNC1(intrin_local_irq_restore);
@@ -117,25 +96,6 @@ DEFINE_FUNC1(get_cpuid, int);
DEFINE_FUNC1(get_pmd, int);
DEFINE_FUNC1(get_rr, unsigned long);
-DEFINE_SET_KR(0)
-DEFINE_SET_KR(1)
-DEFINE_SET_KR(2)
-DEFINE_SET_KR(3)
-DEFINE_SET_KR(4)
-DEFINE_SET_KR(5)
-DEFINE_SET_KR(6)
-DEFINE_SET_KR(7)
-
-DEFINE_GETREG(eflag, AR_EFLAG)
-DEFINE_GETREG(psr, PSR)
-DEFINE_GETREG(ivr, CR_IVR)
-DEFINE_GETREG(tpr, CR_TPR)
-
-DEFINE_SETREG(eflag, AR_EFLAG)
-DEFINE_SETREG(tpr, CR_TPR)
-DEFINE_SETREG(eoi, CR_EOI)
-DEFINE_SETREG(itm, CR_ITM)
-
static void
ia64_native_ssm_i_func(void)
{
@@ -156,32 +116,165 @@ ia64_native_set_rr0_to_rr4_func(unsigned long
val0, unsigned long val1,
ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4);
}
+#define CASE_REG(id) case id: res = ia64_native_getreg(id); break;
+#define CASE_AR(id) CASE_REG(id)
+#define CASE_CR(id) CASE_REG(id)
+
+unsigned long native_ia64_getreg (int regnum)
+{
+ unsigned long res = -1;
+ switch (regnum) {
+ CASE_REG(_IA64_REG_GP);
+ CASE_REG(_IA64_REG_IP);
+ CASE_REG(_IA64_REG_PSR);
+ CASE_REG(_IA64_REG_TP);
+ CASE_REG(_IA64_REG_SP);
+
+ CASE_AR(_IA64_REG_AR_KR0);
+ CASE_AR(_IA64_REG_AR_KR1);
+ CASE_AR(_IA64_REG_AR_KR2);
+ CASE_AR(_IA64_REG_AR_KR3);
+ CASE_AR(_IA64_REG_AR_KR4);
+ CASE_AR(_IA64_REG_AR_KR5);
+ CASE_AR(_IA64_REG_AR_KR6);
+ CASE_AR(_IA64_REG_AR_KR7);
+ CASE_AR(_IA64_REG_AR_RSC);
+ CASE_AR(_IA64_REG_AR_BSP);
+ CASE_AR(_IA64_REG_AR_BSPSTORE);
+ CASE_AR(_IA64_REG_AR_RNAT);
+ CASE_AR(_IA64_REG_AR_FCR);
+ CASE_AR(_IA64_REG_AR_EFLAG);
+ CASE_AR(_IA64_REG_AR_CSD);
+ CASE_AR(_IA64_REG_AR_SSD);
+ CASE_AR(_IA64_REG_AR_CFLAG);
+ CASE_AR(_IA64_REG_AR_FSR);
+ CASE_AR(_IA64_REG_AR_FIR);
+ CASE_AR(_IA64_REG_AR_FDR);
+ CASE_AR(_IA64_REG_AR_CCV);
+ CASE_AR(_IA64_REG_AR_UNAT);
+ CASE_AR(_IA64_REG_AR_FPSR);
+ CASE_AR(_IA64_REG_AR_ITC);
+ CASE_AR(_IA64_REG_AR_PFS);
+ CASE_AR(_IA64_REG_AR_LC);
+ CASE_AR(_IA64_REG_AR_EC);
+
+ CASE_CR(_IA64_REG_CR_DCR);
+ CASE_CR(_IA64_REG_CR_ITM);
+ CASE_CR(_IA64_REG_CR_IVA);
+ CASE_CR(_IA64_REG_CR_PTA);
+ CASE_CR(_IA64_REG_CR_IPSR);
+ CASE_CR(_IA64_REG_CR_ISR);
+ CASE_CR(_IA64_REG_CR_IIP);
+ CASE_CR(_IA64_REG_CR_IFA);
+ CASE_CR(_IA64_REG_CR_ITIR);
+ CASE_CR(_IA64_REG_CR_IIPA);
+ CASE_CR(_IA64_REG_CR_IFS);
+ CASE_CR(_IA64_REG_CR_IIM);
+ CASE_CR(_IA64_REG_CR_IHA);
+ CASE_CR(_IA64_REG_CR_LID);
+ CASE_CR(_IA64_REG_CR_IVR);
+ CASE_CR(_IA64_REG_CR_TPR);
+ CASE_CR(_IA64_REG_CR_EOI);
+ CASE_CR(_IA64_REG_CR_IRR0);
+ CASE_CR(_IA64_REG_CR_IRR1);
+ CASE_CR(_IA64_REG_CR_IRR2);
+ CASE_CR(_IA64_REG_CR_IRR3);
+ CASE_CR(_IA64_REG_CR_ITV);
+ CASE_CR(_IA64_REG_CR_PMV);
+ CASE_CR(_IA64_REG_CR_CMCV);
+ CASE_CR(_IA64_REG_CR_LRR0);
+ CASE_CR(_IA64_REG_CR_LRR1);
+
+ default:
+ printk("wrong_getreg %d\n", regnum);
+ break;
+ }
+ return res;
+}
+
+#define CASE_SET_REG(id) case id: ia64_native_setreg(id, val);
break;
+#define CASE_SET_AR(id) CASE_SET_REG(id)
+#define CASE_SET_CR(id) CASE_SET_REG(id)
+
+void native_ia64_setreg (int regnum, unsigned long val)
+{
+ switch (regnum) {
+ CASE_SET_REG(_IA64_REG_PSR_L);
+ CASE_SET_REG(_IA64_REG_SP);
+ CASE_SET_REG(_IA64_REG_GP)
+
+ CASE_SET_AR(_IA64_REG_AR_KR0);
+ CASE_SET_AR(_IA64_REG_AR_KR1);
+ CASE_SET_AR(_IA64_REG_AR_KR2);
+ CASE_SET_AR(_IA64_REG_AR_KR3);
+ CASE_SET_AR(_IA64_REG_AR_KR4);
+ CASE_SET_AR(_IA64_REG_AR_KR5);
+ CASE_SET_AR(_IA64_REG_AR_KR6);
+ CASE_SET_AR(_IA64_REG_AR_KR7);
+ CASE_SET_AR(_IA64_REG_AR_RSC);
+ CASE_SET_AR(_IA64_REG_AR_BSP);
+ CASE_SET_AR(_IA64_REG_AR_BSPSTORE);
+ CASE_SET_AR(_IA64_REG_AR_RNAT);
+ CASE_SET_AR(_IA64_REG_AR_FCR);
+ CASE_SET_AR(_IA64_REG_AR_EFLAG);
+ CASE_SET_AR(_IA64_REG_AR_CSD);
+ CASE_SET_AR(_IA64_REG_AR_SSD);
+ CASE_SET_AR(_IA64_REG_AR_CFLAG);
+ CASE_SET_AR(_IA64_REG_AR_FSR);
+ CASE_SET_AR(_IA64_REG_AR_FIR);
+ CASE_SET_AR(_IA64_REG_AR_FDR);
+ CASE_SET_AR(_IA64_REG_AR_CCV);
+ CASE_SET_AR(_IA64_REG_AR_UNAT);
+ CASE_SET_AR(_IA64_REG_AR_FPSR);
+ CASE_SET_AR(_IA64_REG_AR_ITC);
+ CASE_SET_AR(_IA64_REG_AR_PFS);
+ CASE_SET_AR(_IA64_REG_AR_LC);
+ CASE_SET_AR(_IA64_REG_AR_EC);
+
+ CASE_SET_CR(_IA64_REG_CR_DCR);
+ CASE_SET_CR(_IA64_REG_CR_ITM);
+ CASE_SET_CR(_IA64_REG_CR_IVA);
+ CASE_SET_CR(_IA64_REG_CR_PTA);
+ CASE_SET_CR(_IA64_REG_CR_IPSR);
+ CASE_SET_CR(_IA64_REG_CR_ISR);
+ CASE_SET_CR(_IA64_REG_CR_IIP);
+ CASE_SET_CR(_IA64_REG_CR_IFA);
+ CASE_SET_CR(_IA64_REG_CR_ITIR);
+ CASE_SET_CR(_IA64_REG_CR_IIPA);
+ CASE_SET_CR(_IA64_REG_CR_IFS);
+ CASE_SET_CR(_IA64_REG_CR_IIM);
+ CASE_SET_CR(_IA64_REG_CR_IHA);
+ CASE_SET_CR(_IA64_REG_CR_LID);
+ CASE_SET_CR(_IA64_REG_CR_IVR);
+ CASE_SET_CR(_IA64_REG_CR_TPR);
+ CASE_SET_CR(_IA64_REG_CR_EOI);
+ CASE_SET_CR(_IA64_REG_CR_IRR0);
+ CASE_SET_CR(_IA64_REG_CR_IRR1);
+ CASE_SET_CR(_IA64_REG_CR_IRR2);
+ CASE_SET_CR(_IA64_REG_CR_IRR3);
+ CASE_SET_CR(_IA64_REG_CR_ITV);
+ CASE_SET_CR(_IA64_REG_CR_PMV);
+ CASE_SET_CR(_IA64_REG_CR_CMCV);
+ CASE_SET_CR(_IA64_REG_CR_LRR0);
+ CASE_SET_CR(_IA64_REG_CR_LRR1);
+ default:
+ printk("wrong setreg %d\n", regnum);
+ break;
+ }
+}
+
struct pv_cpu_ops pv_cpu_ops = {
.fc = ia64_native_fc_func,
.thash = ia64_native_thash_func,
.get_cpuid = ia64_native_get_cpuid_func,
.get_pmd = ia64_native_get_pmd_func,
- .get_eflag = ia64_native_get_eflag_func,
- .set_eflag = ia64_native_set_eflag_func,
- .get_psr = ia64_native_get_psr_func,
- .get_ivr = ia64_native_get_ivr_func,
- .get_tpr = ia64_native_get_tpr_func,
- .set_tpr = ia64_native_set_tpr_func,
- .eoi = ia64_native_set_eoi_func,
- .set_itm = ia64_native_set_itm_func,
.ptcga = ia64_native_ptcga_func,
.get_rr = ia64_native_get_rr_func,
.set_rr = ia64_native_set_rr_func,
.set_rr0_to_rr4 = ia64_native_set_rr0_to_rr4_func,
- .set_kr0 = ia64_native_set_kr0_func,
- .set_kr1 = ia64_native_set_kr1_func,
- .set_kr2 = ia64_native_set_kr2_func,
- .set_kr3 = ia64_native_set_kr3_func,
- .set_kr4 = ia64_native_set_kr4_func,
- .set_kr5 = ia64_native_set_kr5_func,
- .set_kr6 = ia64_native_set_kr6_func,
- .set_kr7 = ia64_native_set_kr7_func,
.ssm_i = ia64_native_ssm_i_func,
+ .getreg = native_ia64_getreg,
+ .setreg = native_ia64_setreg,
.rsm_i = ia64_native_rsm_i_func,
.get_psr_i = ia64_native_get_psr_i_func,
.intrin_local_irq_restore
diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c
index d78932b..25c8196 100644
--- a/arch/ia64/xen/xen_pv_ops.c
+++ b/arch/ia64/xen/xen_pv_ops.c
@@ -168,21 +168,47 @@ static const struct pv_init_ops xen_init_ops
__initdata = {
* intrinsics hooks.
*/
-#define DEFINE_XEN_SET_KR(N)
\
- static void
\
- xen_set_kr##N(unsigned long val)
\
- {
\
- xen_set_kr(_IA64_REG_AR_KR##N - _IA64_REG_AR_KR0, val);
\
+static void xen_setreg(int regnum, unsigned long val)
+{
+ switch (regnum) {
+ case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:
+ xen_set_kr(regnum - _IA64_REG_AR_KR0, val);
+ break;
+ case _IA64_REG_CR_TPR:
+ xen_set_tpr(val);
+ break;
+ case _IA64_REG_CR_ITM:
+ xen_set_itm(val);
+ break;
+ case _IA64_REG_CR_EOI:
+ xen_eoi(val);
+ break;
+ default:
+ native_ia64_setreg(regnum, val);
+ break;
}
+}
-DEFINE_XEN_SET_KR(0)
-DEFINE_XEN_SET_KR(1)
-DEFINE_XEN_SET_KR(2)
-DEFINE_XEN_SET_KR(3)
-DEFINE_XEN_SET_KR(4)
-DEFINE_XEN_SET_KR(5)
-DEFINE_XEN_SET_KR(6)
-DEFINE_XEN_SET_KR(7)
+static unsigned long xen_getreg(int regnum)
+{
+ unsigned long res;
+
+ switch (regnum) {
+ case _IA64_REG_PSR:
+ res = xen_get_psr();
+ break;
+ case _IA64_REG_CR_IVR:
+ res = xen_get_ivr();
+ break;
+ case _IA64_REG_CR_TPR:
+ res = xen_get_tpr();
+ break;
+ default:
+ res = native_ia64_getreg(regnum);
+ break;
+ }
+ return res;
+}
/* turning on interrupts is a bit more complicated.. write to the
* memory-mapped virtual psr.i bit first (to avoid race condition),
@@ -227,28 +253,12 @@ static const struct pv_cpu_ops xen_cpu_ops
__initdata = {
.thash = xen_thash,
.get_cpuid = xen_get_cpuid,
.get_pmd = xen_get_pmd,
-#ifdef CONFIG_IA32_SUPPORT
- .get_eflag = xen_get_eflag,
- .set_eflag = xen_set_eflag,
-#endif
- .get_psr = xen_get_psr,
- .get_ivr = xen_get_ivr,
- .get_tpr = xen_get_tpr,
- .set_tpr = xen_set_tpr,
- .eoi = xen_eoi,
- .set_itm = xen_set_itm,
+ .getreg = xen_getreg,
+ .setreg = xen_setreg,
.ptcga = xen_ptcga,
.get_rr = xen_get_rr,
.set_rr = xen_set_rr,
.set_rr0_to_rr4 = xen_set_rr0_to_rr4,
- .set_kr0 = xen_set_kr0,
- .set_kr1 = xen_set_kr1,
- .set_kr2 = xen_set_kr2,
- .set_kr3 = xen_set_kr3,
- .set_kr4 = xen_set_kr4,
- .set_kr5 = xen_set_kr5,
- .set_kr6 = xen_set_kr6,
- .set_kr7 = xen_set_kr7,
.ssm_i = xen_ssm_i,
.rsm_i = xen_rsm_i,
.get_psr_i = xen_get_psr_i,
diff --git a/include/asm-ia64/paravirt_privop.h
b/include/asm-ia64/paravirt_privop.h
index a5845cf..d6d3a37 100644
--- a/include/asm-ia64/paravirt_privop.h
+++ b/include/asm-ia64/paravirt_privop.h
@@ -39,28 +39,14 @@ struct pv_cpu_ops {
unsigned long (*thash)(unsigned long addr);
unsigned long (*get_cpuid)(int index);
unsigned long (*get_pmd)(int index);
- unsigned long (*get_eflag)(void);
- void (*set_eflag)(unsigned long val);
- unsigned long (*get_psr)(void);
- unsigned long (*get_ivr)(void);
- unsigned long (*get_tpr)(void);
- void (*set_tpr)(unsigned long val);
- void (*eoi)(unsigned long val);
- void (*set_itm)(unsigned long val);
+ 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 (*set_kr0)(unsigned long val);
- void (*set_kr1)(unsigned long val);
- void (*set_kr2)(unsigned long val);
- void (*set_kr3)(unsigned long val);
- void (*set_kr4)(unsigned long val);
- void (*set_kr5)(unsigned long val);
- void (*set_kr6)(unsigned long val);
- void (*set_kr7)(unsigned long val);
void (*ssm_i)(void);
void (*rsm_i)(void);
unsigned long (*get_psr_i)(void);
@@ -73,89 +59,8 @@ extern struct pv_cpu_ops pv_cpu_ops;
/* Instructions paravirtualized for performance */
/************************************************/
-/* index must be constant. but static inline function sometimes fails
to be
- * optimized. */
-#define paravirt_set_kr(index, val) \
- do { \
- switch (index) { \
- case _IA64_REG_AR_KR0: \
- pv_cpu_ops.set_kr0(val); \
- break; \
- case _IA64_REG_AR_KR1: \
- pv_cpu_ops.set_kr1(val); \
- break; \
- case _IA64_REG_AR_KR2: \
- pv_cpu_ops.set_kr2(val); \
- break; \
- case _IA64_REG_AR_KR3: \
- pv_cpu_ops.set_kr3(val); \
- break; \
- case _IA64_REG_AR_KR4: \
- pv_cpu_ops.set_kr4(val); \
- break; \
- case _IA64_REG_AR_KR5: \
- pv_cpu_ops.set_kr5(val); \
- break; \
- case _IA64_REG_AR_KR6: \
- pv_cpu_ops.set_kr6(val); \
- break; \
- case _IA64_REG_AR_KR7: \
- pv_cpu_ops.set_kr7(val); \
- break; \
- default: \
- ia64_setreg_unknown_kr(); \
- } \
- } while (0)
-
-/* regnum for ia64_native_getreg/setreg() must be constnat. ("i"
constraint)
- * static inline function doesn't satisfy it. */
-#define paravirt_getreg(regnum)
\
- ({
\
- __u64 ia64_intri_res;
\
-
\
- switch (regnum) {
\
- case _IA64_REG_PSR:
\
- ia64_intri_res = pv_cpu_ops.get_psr();
\
- break;
\
- case _IA64_REG_CR_IVR:
\
- ia64_intri_res = pv_cpu_ops.get_ivr();
\
- break;
\
- case _IA64_REG_CR_TPR:
\
- ia64_intri_res = pv_cpu_ops.get_tpr();
\
- break;
\
- case _IA64_REG_AR_EFLAG:
\
- ia64_intri_res = pv_cpu_ops.get_eflag();
\
- break;
\
- default:
\
- ia64_intri_res = ia64_native_getreg(regnum);
\
- break;
\
- }
\
- ia64_intri_res;
\
- })
-
-#define paravirt_setreg(regnum, val) \
- do { \
- switch (regnum) { \
- case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7: \
- paravirt_set_kr((regnum), (val)); \
- break; \
- case _IA64_REG_CR_ITM: \
- pv_cpu_ops.set_itm(val); \
- break; \
- case _IA64_REG_CR_TPR: \
- pv_cpu_ops.set_tpr(val); \
- break; \
- case _IA64_REG_CR_EOI: \
- pv_cpu_ops.eoi(val); \
- break; \
- case _IA64_REG_AR_EFLAG: \
- pv_cpu_ops.set_eflag(val); \
- break; \
- default: \
- ia64_native_setreg((regnum), (val)); \
- break; \
- } \
- } while (0)
+#define paravirt_getreg(regnum)
pv_cpu_ops.getreg(regnum)
+#define paravirt_setreg(regnum, val) pv_cpu_ops.setreg(regnum, val)
/* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
* static inline function doesn't satisfy it. */
diff --git a/include/asm-ia64/xen/privop.h
b/include/asm-ia64/xen/privop.h
index 71ec754..7b145f0 100644
--- a/include/asm-ia64/xen/privop.h
+++ b/include/asm-ia64/xen/privop.h
@@ -80,9 +80,6 @@ extern unsigned long xen_thash(unsigned long addr);
extern unsigned long xen_get_cpuid(int index);
extern unsigned long xen_get_pmd(int index);
-extern unsigned long xen_get_eflag(void); /* see xen_ia64_getreg
*/
-extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg
*/
-
/************************************************/
/* Instructions paravirtualized for performance */
/************************************************/
@@ -123,6 +120,8 @@ extern void xen_set_rr0_to_rr4(unsigned long val0,
unsigned long val1,
unsigned long val4);
extern void xen_set_kr(unsigned long index, unsigned long val);
extern void xen_ptcga(unsigned long addr, unsigned long size);
+extern void native_ia64_setreg(int regnum, unsigned long val);
+extern unsigned long native_ia64_getreg(int regnum);
#endif /* !__ASSEMBLY__ */
getsetreg.patch
Description: getsetreg.patch
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|