[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-ia64-devel] 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 _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ia64-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |