[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-ia64-devel] IMPLEMENT generic getreg/setreg pv_cpu_ops


  • To: <xen-ia64-devel@xxxxxxxxxxxxxxxxxxx>
  • From: "Dong, Eddie" <eddie.dong@xxxxxxxxx>
  • Date: Tue, 8 Apr 2008 13:09:44 +0800
  • Delivery-date: Mon, 07 Apr 2008 22:14:15 -0700
  • List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
  • Thread-index: AciZNsIyvhONE7lcS4G/81TcgtD6Xw==
  • Thread-topic: IMPLEMENT generic getreg/setreg pv_cpu_ops



    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__ */
 

Attachment: getsetreg.patch
Description: getsetreg.patch

_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.