Message ID | 1331844737-30869-5-git-send-email-stuart.yoder@freescale.com |
---|---|
State | New, archived |
Headers | show |
On 15.03.2012, at 21:52, Stuart Yoder wrote: > From: Liu Yu-B13201 <Yu.Liu@freescale.com> > > Signed-off-by: Liu Yu <yu.liu@freescale.com> > [stuart: update patch description] > Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com> > --- > v10: > -add spaces as per comments > -use PPC_LL/PPC_STL for long accesses > > arch/powerpc/include/asm/epapr_hcalls.h | 11 ++++++----- > arch/powerpc/kernel/epapr_hcalls.S | 28 ++++++++++++++++++++++++++++ > arch/powerpc/kernel/epapr_paravirt.c | 11 ++++++++++- > 3 files changed, 44 insertions(+), 6 deletions(-) > > diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h > index 2173d4c..78460ac 100644 > --- a/arch/powerpc/include/asm/epapr_hcalls.h > +++ b/arch/powerpc/include/asm/epapr_hcalls.h > @@ -50,10 +50,6 @@ > #ifndef _EPAPR_HCALLS_H > #define _EPAPR_HCALLS_H > > -#include <linux/types.h> > -#include <linux/errno.h> > -#include <asm/byteorder.h> > - > #define EV_BYTE_CHANNEL_SEND 1 > #define EV_BYTE_CHANNEL_RECEIVE 2 > #define EV_BYTE_CHANNEL_POLL 3 > @@ -108,6 +104,11 @@ > #define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ > #define EV_BUFFER_OVERFLOW 13 /* Caller-supplied buffer too small */ > > +#ifndef __ASSEMBLY__ > +#include <linux/types.h> > +#include <linux/errno.h> > +#include <asm/byteorder.h> > + > /* > * Hypercall register clobber list > * > @@ -500,5 +501,5 @@ static inline unsigned int ev_idle(void) > > return r3; > } > - > +#endif /* !__ASSEMBLY__ */ > #endif > diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S > index 697b390..698e7d9 100644 > --- a/arch/powerpc/kernel/epapr_hcalls.S > +++ b/arch/powerpc/kernel/epapr_hcalls.S > @@ -8,13 +8,41 @@ > */ > > #include <linux/threads.h> > +#include <asm/epapr_hcalls.h> > #include <asm/reg.h> > #include <asm/page.h> > #include <asm/cputable.h> > #include <asm/thread_info.h> > #include <asm/ppc_asm.h> > +#include <asm/asm-compat.h> > #include <asm/asm-offsets.h> > > +_GLOBAL(epapr_ev_idle) > +epapr_ev_idle: Please document here that this is a copy from the original idle code. > + rlwinm r3, r1, 0, 0, 31-THREAD_SHIFT /* current thread_info */ > + PPC_LL r4, TI_LOCAL_FLAGS(r3) /* set napping bit */ > + ori r4, r4,_TLF_NAPPING /* so when we take an exception */ > + PPC_STL r4, TI_LOCAL_FLAGS(r3) /* it will return to our caller */ > + > + wrteei 1 > + > +idle_loop: > + LOAD_REG_IMMEDIATE(r11, EV_HCALL_TOKEN(EV_IDLE)) Ah, nice. So why not use EV_HCALL_TOKEN instead of the clumsy _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, EV_IDLE)? We could also add a KVM_HCALL_TOKEN() similar to the fsl one: arch/powerpc/include/asm/fsl_hcalls.h:#define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num) which would help us keep our lines short :). Alex -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h index 2173d4c..78460ac 100644 --- a/arch/powerpc/include/asm/epapr_hcalls.h +++ b/arch/powerpc/include/asm/epapr_hcalls.h @@ -50,10 +50,6 @@ #ifndef _EPAPR_HCALLS_H #define _EPAPR_HCALLS_H -#include <linux/types.h> -#include <linux/errno.h> -#include <asm/byteorder.h> - #define EV_BYTE_CHANNEL_SEND 1 #define EV_BYTE_CHANNEL_RECEIVE 2 #define EV_BYTE_CHANNEL_POLL 3 @@ -108,6 +104,11 @@ #define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ #define EV_BUFFER_OVERFLOW 13 /* Caller-supplied buffer too small */ +#ifndef __ASSEMBLY__ +#include <linux/types.h> +#include <linux/errno.h> +#include <asm/byteorder.h> + /* * Hypercall register clobber list * @@ -500,5 +501,5 @@ static inline unsigned int ev_idle(void) return r3; } - +#endif /* !__ASSEMBLY__ */ #endif diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S index 697b390..698e7d9 100644 --- a/arch/powerpc/kernel/epapr_hcalls.S +++ b/arch/powerpc/kernel/epapr_hcalls.S @@ -8,13 +8,41 @@ */ #include <linux/threads.h> +#include <asm/epapr_hcalls.h> #include <asm/reg.h> #include <asm/page.h> #include <asm/cputable.h> #include <asm/thread_info.h> #include <asm/ppc_asm.h> +#include <asm/asm-compat.h> #include <asm/asm-offsets.h> +_GLOBAL(epapr_ev_idle) +epapr_ev_idle: + rlwinm r3, r1, 0, 0, 31-THREAD_SHIFT /* current thread_info */ + PPC_LL r4, TI_LOCAL_FLAGS(r3) /* set napping bit */ + ori r4, r4,_TLF_NAPPING /* so when we take an exception */ + PPC_STL r4, TI_LOCAL_FLAGS(r3) /* it will return to our caller */ + + wrteei 1 + +idle_loop: + LOAD_REG_IMMEDIATE(r11, EV_HCALL_TOKEN(EV_IDLE)) + +.global epapr_ev_idle_start +epapr_ev_idle_start: + li r3, -1 + nop + nop + nop + + /* + * Guard against spurious wakeups from a hypervisor -- + * only interrupt will cause us to return to LR due to + * _TLF_NAPPING. + */ + b idle_loop + /* Hypercall entry point. Will be patched with device tree instructions. */ .global epapr_hypercall_start epapr_hypercall_start: diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c index 028aeae..f3eab85 100644 --- a/arch/powerpc/kernel/epapr_paravirt.c +++ b/arch/powerpc/kernel/epapr_paravirt.c @@ -21,6 +21,10 @@ #include <asm/epapr_hcalls.h> #include <asm/cacheflush.h> #include <asm/code-patching.h> +#include <asm/machdep.h> + +extern void epapr_ev_idle(void); +extern u32 epapr_ev_idle_start[]; bool epapr_paravirt_enabled; @@ -41,8 +45,13 @@ static int __init epapr_paravirt_init(void) if (len % 4 || len > (4 * 4)) return -ENODEV; - for (i = 0; i < (len / 4); i++) + for (i = 0; i < (len / 4); i++) { patch_instruction(epapr_hypercall_start + i, insts[i]); + patch_instruction(epapr_ev_idle_start + i, insts[i]); + } + + if (of_get_property(hyper_node, "has-idle", NULL)) + ppc_md.power_save = epapr_ev_idle; epapr_paravirt_enabled = true;