* [PATCH v2 3/5] powerpc/tm: Fix restoration of MSR on 32bit signal return
From: Michael Neuling @ 2013-06-09 11:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Matt Evans
In-Reply-To: <1370776999-14108-1-git-send-email-mikey@neuling.org>
Currently we clear out the MSR TM bits on signal return assuming that the
signal should never return to an active transaction.
This is bogus as the user may do this. It's most likely the transaction will
be doomed due to a treclaim but that's a problem for the HW not the kernel.
The current code is a legacy of earlier kernel implementations which did
software rollback of active transactions in the kernel. That code has now gone
but we didn't correctly fix up this part of the signals code which still makes
the assumption that it must be returning to a suspended transaction.
This pulls out both MSR TM bits from the user supplied context rather than just
setting TM suspend. We pull out only the bits needed to ensure the user can't
do anything dangerous to the MSR.
Signed-off-by: Michael Neuling <mikey@neuling.org>
cc: stable@vger.kernel.org (v3.9 only)
---
arch/powerpc/kernel/signal_32.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index fa81462..364cb1e 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -754,7 +754,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
struct mcontext __user *tm_sr)
{
long err;
- unsigned long msr;
+ unsigned long msr, msr_hi;
#ifdef CONFIG_VSX
int i;
#endif
@@ -859,8 +859,11 @@ static long restore_tm_user_regs(struct pt_regs *regs,
tm_enable();
/* This loads the checkpointed FP/VEC state, if used */
tm_recheckpoint(¤t->thread, msr);
- /* The task has moved into TM state S, so ensure MSR reflects this */
- regs->msr = (regs->msr & ~MSR_TS_MASK) | MSR_TS_S;
+ /* Get the top half of the MSR */
+ if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
+ return 1;
+ /* Pull in MSR TM from user context */
+ regs->msr = (regs->msr & ~MSR_TS_MASK) | ((msr_hi<<32) & MSR_TS_MASK);
/* This loads the speculative FP/VEC state, if used */
if (msr & MSR_FP) {
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 2/5] powerpc/tm: Fix 32 bit non-rt signals
From: Michael Neuling @ 2013-06-09 11:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Matt Evans
In-Reply-To: <1370776999-14108-1-git-send-email-mikey@neuling.org>
Currently sys_sigreturn() is TM unaware. Therefore, if we take a 32 bit signal
without SIGINFO (non RT) inside a transaction, on signal return we don't
restore the signal frame correctly.
This checks if the signal frame being restoring is an active transaction, and
if so, it copies the additional state to ptregs so it can be restored.
Signed-off-by: Michael Neuling <mikey@neuling.org>
cc: stable@vger.kernel.org (v3.9 only)
---
arch/powerpc/kernel/signal_32.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 5bc819f..fa81462 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1494,16 +1494,22 @@ badframe:
long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
struct pt_regs *regs)
{
+ struct sigframe __user *sf;
struct sigcontext __user *sc;
struct sigcontext sigctx;
struct mcontext __user *sr;
void __user *addr;
sigset_t set;
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ struct mcontext __user *mcp, *tm_mcp;
+ unsigned long msr_hi;
+#endif
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
- sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+ sf = (struct sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+ sc = &sf->sctx;
addr = sc;
if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
goto badframe;
@@ -1520,11 +1526,25 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
#endif
set_current_blocked(&set);
- sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
- addr = sr;
- if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
- || restore_user_regs(regs, sr, 1))
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ mcp = (struct mcontext __user *)&sf->mctx;
+ tm_mcp = (struct mcontext __user *)&sf->mctx_transact;
+ if (__get_user(msr_hi, &tm_mcp->mc_gregs[PT_MSR]))
goto badframe;
+ if (MSR_TM_ACTIVE(msr_hi<<32)) {
+ if (!cpu_has_feature(CPU_FTR_TM))
+ goto badframe;
+ if (restore_tm_user_regs(regs, mcp, tm_mcp))
+ goto badframe;
+ } else
+#endif
+ {
+ sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
+ addr = sr;
+ if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
+ || restore_user_regs(regs, sr, 1))
+ goto badframe;
+ }
set_thread_flag(TIF_RESTOREALL);
return 0;
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 1/5] powerpc/tm: Fix writing top half of MSR on 32 bit signals
From: Michael Neuling @ 2013-06-09 11:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Matt Evans
The MSR TM controls are in the top 32 bits of the MSR hence on 32 bit signals,
we stick the top half of the MSR in the checkpointed signal context so that the
user can access it.
Unfortunately, we don't currently write anything to the checkpointed signal
context when coming in a from a non transactional process and hence the top MSR
bits can contain junk.
This updates the 32 bit signal handling code to always write something to the
top MSR bits so that users know if the process is transactional or not and the
kernel can use it on signal return.
Signed-off-by: Michael Neuling <mikey@neuling.org>
cc: stable@vger.kernel.org (v3.9 only)
---
arch/powerpc/kernel/signal_32.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 201385c..5bc819f 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -407,7 +407,8 @@ inline unsigned long copy_transact_fpr_from_user(struct task_struct *task,
* altivec/spe instructions at some point.
*/
static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
- int sigret, int ctx_has_vsx_region)
+ struct mcontext __user *tm_frame, int sigret,
+ int ctx_has_vsx_region)
{
unsigned long msr = regs->msr;
@@ -475,6 +476,12 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
return 1;
+ /* We need to write 0 the MSR top 32 bits in the tm frame so that we
+ * can check it on the restore to see if TM is active
+ */
+ if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
+ return 1;
+
if (sigret) {
/* Set up the sigreturn trampoline: li r0,sigret; sc */
if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
@@ -952,6 +959,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
{
struct rt_sigframe __user *rt_sf;
struct mcontext __user *frame;
+ struct mcontext __user *tm_frame = NULL;
void __user *addr;
unsigned long newsp = 0;
int sigret;
@@ -985,23 +993,24 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ tm_frame = &rt_sf->uc_transact.uc_mcontext;
if (MSR_TM_ACTIVE(regs->msr)) {
- if (save_tm_user_regs(regs, &rt_sf->uc.uc_mcontext,
- &rt_sf->uc_transact.uc_mcontext, sigret))
+ if (save_tm_user_regs(regs, frame, tm_frame, sigret))
goto badframe;
}
else
#endif
- if (save_user_regs(regs, frame, sigret, 1))
+ {
+ if (save_user_regs(regs, frame, tm_frame, sigret, 1))
goto badframe;
+ }
regs->link = tramp;
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
if (MSR_TM_ACTIVE(regs->msr)) {
if (__put_user((unsigned long)&rt_sf->uc_transact,
&rt_sf->uc.uc_link)
- || __put_user(to_user_ptr(&rt_sf->uc_transact.uc_mcontext),
- &rt_sf->uc_transact.uc_regs))
+ || __put_user((unsigned long)tm_frame, &rt_sf->uc_transact.uc_regs))
goto badframe;
}
else
@@ -1170,7 +1179,7 @@ long sys_swapcontext(struct ucontext __user *old_ctx,
mctx = (struct mcontext __user *)
((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
if (!access_ok(VERIFY_WRITE, old_ctx, ctx_size)
- || save_user_regs(regs, mctx, 0, ctx_has_vsx_region)
+ || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)
|| put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
|| __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
return -EFAULT;
@@ -1392,6 +1401,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
{
struct sigcontext __user *sc;
struct sigframe __user *frame;
+ struct mcontext __user *tm_mctx = NULL;
unsigned long newsp = 0;
int sigret;
unsigned long tramp;
@@ -1425,6 +1435,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ tm_mctx = &frame->mctx_transact;
if (MSR_TM_ACTIVE(regs->msr)) {
if (save_tm_user_regs(regs, &frame->mctx, &frame->mctx_transact,
sigret))
@@ -1432,8 +1443,10 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
}
else
#endif
- if (save_user_regs(regs, &frame->mctx, sigret, 1))
+ {
+ if (save_user_regs(regs, &frame->mctx, tm_mctx, sigret, 1))
goto badframe;
+ }
regs->link = tramp;
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH 2/5] powerpc/tm: Fix 32 bit non-rt signals
From: Michael Neuling @ 2013-06-09 10:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Matt Evans
In-Reply-To: <1370762745.14883.11.camel@pasglop>
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> On Fri, 2013-06-07 at 20:36 +1000, Michael Neuling wrote:
> > Currently sys_sigreturn() is TM unaware. Therefore, if we take a 32 bit signal
> > without SIGINFO (non RT) inside a transaction, on signal return we don't
> > restore the signal frame correctly.
> >
> > This checks if the signal frame being restoring is an active transaction, and
> > if so, it copies the additional state to ptregs so it can be restored.
> >
> > Signed-off-by: Michael Neuling <mikey@neuling.org>
> > ---
>
> .../...
>
> > +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> > + mcp = (struct mcontext __user *)&sf->mctx;
> > + tm_mcp = (struct mcontext __user *)&sf->mctx_transact;
> > + if (__get_user(msr_hi, &tm_mcp->mc_gregs[PT_MSR]))
> > goto badframe;
> > + if MSR_TM_ACTIVE(msr_hi<<32) {
>
> Mising ( and ). I'll apply that fix locally.
>
> Appart from that, I suppose it's ok. I don't see any exposure
> coming from users "cooking" the tm_frame and calling sigreturn,
> so as long as we are confident userspace generally only uses
> sigreturn with frames it got from an actual signal, and doesn't
> try to "generate" frames by hand, we should be ok.
We should add a has_cpu_feature(TM) here also in case someone cooks up
an sig frame with MSR TM active, but on a non TM CPU. This could possibly
result in a trecheckpoint on a non TM CPU hence an illegal in the
kernel.
I'll repost.
Thanks,
Mikey
^ permalink raw reply
* Re: [PATCH 3/5] powerpc/tm: Fix restoration of MSR on 32bit signal return
From: Michael Neuling @ 2013-06-09 9:56 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Matt Evans
In-Reply-To: <1370762860.14883.13.camel@pasglop>
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> On Fri, 2013-06-07 at 20:36 +1000, Michael Neuling wrote:
> > Currently we clear out the MSR TM bits on signal return assuming that the
> > signal should never return to an active transaction.
> >
> > This is bogus as the user may do this. It's most likely the transaction will
> > be doomed due to a treclaim but that's a problem for the HW not the kernel.
> >
> > This removes the stripping of these MSR TM bits.
> >
> > Signed-off-by: Michael Neuling <mikey@neuling.org>
> > ---
>
> > @@ -859,8 +860,10 @@ static long restore_tm_user_regs(struct pt_regs *regs,
> > tm_enable();
> > /* This loads the checkpointed FP/VEC state, if used */
> > tm_recheckpoint(¤t->thread, msr);
> > - /* The task has moved into TM state S, so ensure MSR reflects this */
> > - regs->msr = (regs->msr & ~MSR_TS_MASK) | MSR_TS_S;
> > + /* Retore the top half of the MSR */
> > + if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
> > + return 1;
> > + regs->msr = (regs->msr | (((unsigned long)msr_hi) << 32));
>
> What kind of damage can I do by calling sigreturn with a cooked
> frame with random MSR bits set ? You should probably filter
> what bits you allow to come from the frame.
Lots of damage.. good, point.
We do that in the 64 bit version of this. I'll update to do the same.
> Additionally, I would also make sure I only do that if the CPU
> features say TM is supported in case that MSR bit means something else
> on a different/older CPU...
Ok, I'll add that also.
Mikey
^ permalink raw reply
* Re: Linux 3.9.5 [patch to fix powerpc build error attached]
From: Michael Neuling @ 2013-06-09 9:47 UTC (permalink / raw)
To: Guenter Roeck
Cc: Jiri Slaby, Greg KH, linuxppc-dev, linux-kernel, stable,
Paul Mackerras, lwn, Andrew Morton, torvalds
In-Reply-To: <20130608143055.GA21207@roeck-us.net>
Guenter Roeck <linux@roeck-us.net> wrote:
> On Fri, Jun 07, 2013 at 12:58:16PM -0700, Greg KH wrote:
> > I'm announcing the release of the 3.9.5 kernel.
> >
> > All users of the 3.9 kernel series must upgrade.
> >
> > The updated 3.9.y git tree can be found at:
> > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-3.9.y
> > and can be browsed at the normal kernel.org git web browser:
> > http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
> >
> Powerpc build is fixed with the following patch.
>
> From 8ce3edac0a86f103bd1037110662d5d80a42dd5b Mon Sep 17 00:00:00 2001
> From: Guenter Roeck <linux@roeck-us.net>
> Date: Sat, 8 Jun 2013 07:23:47 -0700
> Subject: [PATCH] powerpc: Fix build error in stable/3.9
>
> Commit e71c42189 (powerpc/tm: Abort on emulation and alignment faults)
> introduced a powerpc build error in 3.9.5.
ACK.
Looks like ba12eed (powerpc: Exception hooks for context tracking
subsyste) was the cause (but not a prerequisite) that was introduced
post 3.9.
Thanks,
Mikey
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
> No upstream commit. Compile tested only.
>
> arch/powerpc/kernel/traps.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index 1c22b2d..29857c6 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -1151,7 +1151,7 @@ void alignment_exception(struct pt_regs *regs)
> local_irq_enable();
>
> if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT))
> - goto bail;
> + return;
>
> /* we don't implement logging of alignment exceptions */
> if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
> --
> 1.7.9.7
>
^ permalink raw reply
* RE: [PATCH] powerpc/mpc85xx: fix non-bootcpu cannot up after hibernation resume
From: Wang Dongsheng-B40534 @ 2013-06-09 8:23 UTC (permalink / raw)
To: galak@kernel.crashing.org
Cc: Wood Scott-B07421, Li Yang-R58472, Zhao Chenhui-B35336,
Anton Vorontsov, rjw@sisk.pl, paulus@samba.org,
johannes@sipsolutions.net, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20130523173332.GC30160@teo>
SGkga3VtYXIsDQoNCkNvdWxkIHlvdSBhcHBseSB0aGlzIHBhdGNoZT8gDQoNClRoYW5rcy4NCg0K
LWRvbmdzaGVuZw0KDQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IEFudG9u
IFZvcm9udHNvdiBbbWFpbHRvOmFudG9uQHNjYXJ5YnVncy5vcmddIE9uIEJlaGFsZiBPZiBBbnRv
bg0KPiBWb3JvbnRzb3YNCj4gU2VudDogRnJpZGF5LCBNYXkgMjQsIDIwMTMgMTozNCBBTQ0KPiBU
bzogV2FuZyBEb25nc2hlbmctQjQwNTM0DQo+IENjOiBwYXVsdXNAc2FtYmEub3JnOyByandAc2lz
ay5wbDsgYmVuaEBrZXJuZWwuY3Jhc2hpbmcub3JnOw0KPiBqb2hhbm5lc0BzaXBzb2x1dGlvbnMu
bmV0OyBXb29kIFNjb3R0LUIwNzQyMTsgTGkgWWFuZy1SNTg0NzI7IFpoYW8NCj4gQ2hlbmh1aS1C
MzUzMzY7IGxpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFU
Q0hdIHBvd2VycGMvbXBjODV4eDogZml4IG5vbi1ib290Y3B1IGNhbm5vdCB1cCBhZnRlcg0KPiBo
aWJlcm5hdGlvbiByZXN1bWUNCj4gDQo+IEhpIQ0KPiANCj4gT24gVHVlLCBNYXkgMTQsIDIwMTMg
YXQgMDg6NTk6MTNBTSArMDAwMCwgV2FuZyBEb25nc2hlbmctQjQwNTM0IHdyb3RlOg0KPiA+IEkg
c2VuZCB0byBhIHdyb25nIGVtYWlsIGFkZHJlc3MgIkFudG9uIFZvcm9udHNvdg0KPiA8YXZvcm9u
dHNvdkBydS5tdmlzdGEuY29tPiINCj4gPg0KPiA+IEFkZCBBbnRvbiBWb3JvbnRzb3YgPGFudG9u
LnZvcm9udHNvdkBsaW5hcm8ub3JnPiB0byB0aGlzIGVtYWlsLg0KPiANCj4gSSBkb24ndCBoYXZl
IGFueSBtZWFucyB0byB0ZXN0IGl0LCBidXQgdGhlIHBhdGNoIGl0c2VsZiBsb29rcyBnb29kIGFu
ZA0KPiB0aGUgZGVzY3JpcHRpb24gbWFrZXMgc2Vuc2UuIFNvLA0KPiANCj4gUmV2aWV3ZWQtYnk6
IEFudG9uIFZvcm9udHNvdiA8YW50b25AZW5vbXNnLm9yZz4NCj4gDQo+IFRoYW5rcyENCj4gDQo+
ID4NCj4gPiBUaGFua3MgYWxsLg0KPiA+DQo+ID4gPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0t
LQ0KPiA+ID4gRnJvbTogV2FuZyBEb25nc2hlbmctQjQwNTM0DQo+ID4gPiBTZW50OiBUdWVzZGF5
LCBNYXkgMTQsIDIwMTMgNDowNiBQTQ0KPiA+ID4gVG86IGF2b3JvbnRzb3ZAcnUubXZpc3RhLmNv
bQ0KPiA+ID4gQ2M6IHBhdWx1c0BzYW1iYS5vcmc7IHJqd0BzaXNrLnBsOyBiZW5oQGtlcm5lbC5j
cmFzaGluZy5vcmc7DQo+ID4gPiBqb2hhbm5lc0BzaXBzb2x1dGlvbnMubmV0OyBXb29kIFNjb3R0
LUIwNzQyMTsgTGkgWWFuZy1SNTg0NzI7IFpoYW8NCj4gPiA+IENoZW5odWktQjM1MzM2OyBsaW51
eHBwYy1kZXZAbGlzdHMub3psYWJzLm9yZzsgV2FuZyBEb25nc2hlbmctQjQwNTM0DQo+ID4gPiBT
dWJqZWN0OiBbUEFUQ0hdIHBvd2VycGMvbXBjODV4eDogZml4IG5vbi1ib290Y3B1IGNhbm5vdCB1
cCBhZnRlcg0KPiA+ID4gaGliZXJuYXRpb24gcmVzdW1lDQo+ID4gPg0KPiA+ID4gVGhpcyBwcm9i
bGVtIGJlbG9uZ3MgdG8gdGhlIGNvcmUgc3luY2hyb25pemF0aW9uIGlzc3Vlcy4NCj4gPiA+IFRo
ZSBjcHUxIGFscmVhZHkgdXBkYXRlZCBzcGluX3RhYmxlIHZhbHVlcywgYnV0IGJvb3Rjb3JlIGNh
bm5vdCBnZXQNCj4gPiA+IHRoaXMgdmFsdWUgaW4gdGltZS4NCj4gPiA+DQo+ID4gPiBBZnRlciBi
b290Y3B1IGhpYmllcm5hdGlvbiByZXN0b3JlIHRoZSBwYWdlcy4gd2UgYXJlIG5vdyBydW5uaW5n
DQo+ID4gPiB3aXRoIHRoZSBrZXJuZWwgZGF0YSBvZiB0aGUgb2xkIGtlcm5lbCBmdWxseSByZXN0
b3JlZC4gaWYgd2UgcmVzZXQNCj4gPiA+IHRoZSBub24tYm9vdGNwdXMgdGhhdCB3aWxsIGJlIHJl
c2V0IGNhY2hlKHRsYiksIHRoZSBub24tYm9vdGNwdXMNCj4gPiA+IHdpbGwgZ2V0IG5ldyBhZGRy
ZXNzKG1hcCB2aXJ0dWFsIGFuZCBwaHlzaWNhbCBhZGRyZXNzIHNwYWNlcykuDQo+ID4gPiBidXQg
Ym9vdGNwdSB0bGIgY2FjaGUgc3RpbGwgdXNlIGJvb3Qga2VybmVsIGRhdGEsIHNvIHdlIG5lZWQg
dG8NCj4gPiA+IGludmFsaWRhdGUgdGhlIGJvb3RjcHUgdGxiIGNhY2hlIG1ha2UgaXQgdG8gZ2V0
IG5ldyBtYWluIG1lbW9yeSBkYXRhLg0KPiA+ID4NCj4gPiA+IGxvZzoNCj4gPiA+IEVuYWJsaW5n
IG5vbi1ib290IENQVXMgLi4uDQo+ID4gPiBzbXBfODV4eF9raWNrX2NwdTogdGltZW91dCB3YWl0
aW5nIGZvciBjb3JlIDEgdG8gcmVzZXQNCj4gPiA+IHNtcDogZmFpbGVkIHN0YXJ0aW5nIGNwdSAx
IChyYyAtMikNCj4gPiA+IEVycm9yIHRha2luZyBDUFUxIHVwOiAtMg0KPiA+ID4NCj4gPiA+IFNp
Z25lZC1vZmYtYnk6IFdhbmcgRG9uZ3NoZW5nIDxkb25nc2hlbmcud2FuZ0BmcmVlc2NhbGUuY29t
Pg0KPiA+ID4NCj4gPiA+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMva2VybmVsL3N3c3VzcF9i
b29rZS5TDQo+ID4gPiBiL2FyY2gvcG93ZXJwYy9rZXJuZWwvc3dzdXNwX2Jvb2tlLlMNCj4gPiA+
IGluZGV4IDExYTM5MzAuLjk1MDMyNDkgMTAwNjQ0DQo+ID4gPiAtLS0gYS9hcmNoL3Bvd2VycGMv
a2VybmVsL3N3c3VzcF9ib29rZS5TDQo+ID4gPiArKysgYi9hcmNoL3Bvd2VycGMva2VybmVsL3N3
c3VzcF9ib29rZS5TDQo+ID4gPiBAQCAtMTQxLDYgKzE0MSwxOSBAQCBfR0xPQkFMKHN3c3VzcF9h
cmNoX3Jlc3VtZSkNCj4gPiA+ICAJbGlzCXIxMSxzd3N1c3Bfc2F2ZV9hcmVhQGgNCj4gPiA+ICAJ
b3JpCXIxMSxyMTEsc3dzdXNwX3NhdmVfYXJlYUBsDQo+ID4gPg0KPiA+ID4gKwkvKg0KPiA+ID4g
KwkgKiBUaGUgYm9vdCBjb3JlIGdldCBhIHZpcnR1YWwgYWRkcmVzcywgd2hlbiB0aGUgYm9vdCBw
cm9jZXNzLA0KPiA+ID4gKwkgKiB0aGUgdmlydHVhbCBhZGRyZXNzIGNvcnJlc3BvbmRzIHRvIGEg
cGh5c2ljYWwgYWRkcmVzcy4gQWZ0ZXINCj4gPiA+ICsJICogaGliZXJuYXRpb24gcmVzdW1lIG1l
bW9yeSBzbmFwc2hvdHMsIFRoZSBjb3JyZXNwb25kaW5nDQo+ID4gPiArCSAqIHJlbGF0aW9uc2hp
cCBiZXR3ZWVuIHRoZSB2aXJ0dWFsIG1lbW9yeSBhbmQgcGh5c2ljYWwgbWVtb3J5DQo+ID4gPiAr
CSAqIG1pZ2h0IGNoYW5nZSBhZ2Fpbi4gV2UgbmVlZCB0byBnZXQgYSBuZXcgcGFnZSB0YWJsZS4g
U28gd2UNCj4gPiA+ICsJICogbmVlZCB0byBpbnZhbGlkYXRlIFRMQiBhZnRlciByZXN1bWUgcGFn
ZXMuDQo+ID4gPiArCSAqDQo+ID4gPiArCSAqIEludmFsaWRhdGlvbnMgVExCIFVzaW5nIHRsYmls
eC90bGJpdmF4L01NVUNTUjAuDQo+ID4gPiArCSAqIHRsYmlseCB1c2VkIGhlcmUuDQo+ID4gPiAr
CSAqLw0KPiA+ID4gKwlibAlfdGxiaWxfYWxsDQo+ID4gPiArDQo+ID4gPiAgCWx3eglyNCxTTF9T
UFJHMChyMTEpDQo+ID4gPiAgCW10c3ByZwkwLHI0DQo+ID4gPiAgCWx3eglyNCxTTF9TUFJHMShy
MTEpDQo+ID4gPiAtLQ0KPiA+ID4gMS44LjANCj4gPg0KPiA+DQoNCg==
^ permalink raw reply
* RE: [PATCH v3 1/4] powerpc/mpic: add irq_set_wake support
From: Wang Dongsheng-B40534 @ 2013-06-09 8:20 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1368421223.19924.16.camel@pasglop>
SGkgYmVuLA0KDQpDb3VsZCB5b3UgYXBwbHkgdGhlc2UgcGF0Y2hlcz8gVGhhbmtzLiA6KQ0KDQot
IGRvbmdzaGVuZw0KDQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IEJlbmph
bWluIEhlcnJlbnNjaG1pZHQgW21haWx0bzpiZW5oQGtlcm5lbC5jcmFzaGluZy5vcmddDQo+IFNl
bnQ6IE1vbmRheSwgTWF5IDEzLCAyMDEzIDE6MDAgUE0NCj4gVG86IFdhbmcgRG9uZ3NoZW5nLUI0
MDUzNA0KPiBDYzogbGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmc7IFdvb2QgU2NvdHQtQjA3
NDIxOw0KPiBnYWxha0BrZXJuZWwuY3Jhc2hpbmcub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0gg
djMgMS80XSBwb3dlcnBjL21waWM6IGFkZCBpcnFfc2V0X3dha2Ugc3VwcG9ydA0KPiANCj4gT24g
TW9uLCAyMDEzLTA1LTEzIGF0IDA0OjI1ICswMDAwLCBXYW5nIERvbmdzaGVuZy1CNDA1MzQgd3Jv
dGU6DQo+ID4gSGkgQmVuamFtaW4sDQo+ID4NCj4gPiBDb3VsZCB5b3UgYXBwbHkgdGhlc2UgcGF0
Y2hlcz8NCj4gDQo+IEknbGwgaGF2ZSBhIGxvb2ssIEkgd2FzIGFzc3VtaW5nIEt1bWFyIHdvdWxk
IHRha2UgdGhlbSBidXQgc2luY2Ugbm90IEknbGwNCj4gcXVldWUgdGhlbSB1cC4NCj4gDQo+IENo
ZWVycywNCj4gQmVuLg0KPiANCj4gPiBTY290dCBhbHJlYWR5IEFDSy4NCj4gPg0KPiA+IFt2Mywx
LzRdIHBvd2VycGMvbXBpYzogYWRkIGlycV9zZXRfd2FrZSBzdXBwb3J0DQo+ID4gaHR0cDovL3Bh
dGNod29yay5vemxhYnMub3JnL3BhdGNoLzIzNDkzNC8NCj4gPg0KPiA+IFt2MywyLzRdIHBvd2Vy
cGMvbXBpYzogYWRkIGdsb2JhbCB0aW1lciBzdXBwb3J0DQo+ID4gaHR0cDovL3BhdGNod29yay5v
emxhYnMub3JnL3BhdGNoLzIzNDkzNS8NCj4gPg0KPiA+IFt2MywzLzRdIHBvd2VycGMvbXBpYzog
Y3JlYXRlIG1waWMgc3Vic3lzdGVtIG9iamVjdA0KPiA+IGh0dHA6Ly9wYXRjaHdvcmsub3psYWJz
Lm9yZy9wYXRjaC8yMzQ5MzYvDQo+ID4NCj4gPiBbdjMsNC80XSBwb3dlcnBjL2ZzbDogYWRkIE1Q
SUMgdGltZXIgd2FrZXVwIHN1cHBvcnQNCj4gPiBodHRwOi8vcGF0Y2h3b3JrLm96bGFicy5vcmcv
cGF0Y2gvMjM0OTM3Lw0KPiA+DQo+ID4gVGhhbmtzLg0KPiA+DQo+ID4gPiAtLS0tLU9yaWdpbmFs
IE1lc3NhZ2UtLS0tLQ0KPiA+ID4gRnJvbTogV2FuZyBEb25nc2hlbmctQjQwNTM0DQo+ID4gPiBT
ZW50OiBGcmlkYXksIE1heSAwMywgMjAxMyA5OjU0IEFNDQo+ID4gPiBUbzogJ2dhbGFrQGtlcm5l
bC5jcmFzaGluZy5vcmcnDQo+ID4gPiBDYzogJ2xpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3Jn
JzsgV29vZCBTY290dC1CMDc0MjE7DQo+ID4gPiAnYmVuaEBrZXJuZWwuY3Jhc2hpbmcub3JnJw0K
PiA+ID4gU3ViamVjdDogUkU6IFtQQVRDSCB2MyAxLzRdIHBvd2VycGMvbXBpYzogYWRkIGlycV9z
ZXRfd2FrZSBzdXBwb3J0DQo+ID4gPg0KPiA+ID4gSGkgS3VtYXIsDQo+ID4gPg0KPiA+ID4gQ291
bGQgeW91IGFwcGx5IHRoZXNlIHBhdGNoZXM/DQo+ID4gPg0KPiA+ID4gVGhhbmtzLg0KPiA+ID4N
Cj4gPiA+ID4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gPiA+ID4gRnJvbTogV2FuZyBE
b25nc2hlbmctQjQwNTM0DQo+ID4gPiA+IFNlbnQ6IFR1ZXNkYXksIEFwcmlsIDIzLCAyMDEzIDY6
MTAgUE0NCj4gPiA+ID4gVG86IGdhbGFrQGtlcm5lbC5jcmFzaGluZy5vcmcNCj4gPiA+ID4gQ2M6
IGxpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnOyBXb29kIFNjb3R0LUIwNzQyMQ0KPiA+ID4g
PiBTdWJqZWN0OiBSRTogW1BBVENIIHYzIDEvNF0gcG93ZXJwYy9tcGljOiBhZGQgaXJxX3NldF93
YWtlIHN1cHBvcnQNCj4gPiA+ID4NCj4gPiA+ID4gSGkgS3VtYXIsDQo+ID4gPiA+DQo+ID4gPiA+
IENvdWxkIHlvdSBhcHBseSB0aGVzZSBwYXRjaGVzPw0KPiA+ID4gPg0KPiA+ID4gPiBUaGFua3Mu
DQo+ID4gPiA+DQo+ID4gPiA+IFt2MywxLzRdIHBvd2VycGMvbXBpYzogYWRkIGlycV9zZXRfd2Fr
ZSBzdXBwb3J0DQo+ID4gPiA+IGh0dHA6Ly9wYXRjaHdvcmsub3psYWJzLm9yZy9wYXRjaC8yMzQ5
MzQvDQo+ID4gPiA+DQo+ID4gPiA+IFt2MywyLzRdIHBvd2VycGMvbXBpYzogYWRkIGdsb2JhbCB0
aW1lciBzdXBwb3J0DQo+ID4gPiA+IGh0dHA6Ly9wYXRjaHdvcmsub3psYWJzLm9yZy9wYXRjaC8y
MzQ5MzUvDQo+ID4gPiA+DQo+ID4gPiA+IFt2MywzLzRdIHBvd2VycGMvbXBpYzogY3JlYXRlIG1w
aWMgc3Vic3lzdGVtIG9iamVjdA0KPiA+ID4gPiBodHRwOi8vcGF0Y2h3b3JrLm96bGFicy5vcmcv
cGF0Y2gvMjM0OTM2Lw0KPiA+ID4gPg0KPiA+ID4gPiBbdjMsNC80XSBwb3dlcnBjL2ZzbDogYWRk
IE1QSUMgdGltZXIgd2FrZXVwIHN1cHBvcnQNCj4gPiA+ID4gaHR0cDovL3BhdGNod29yay5vemxh
YnMub3JnL3BhdGNoLzIzNDkzNy8NCj4gPiA+ID4NCj4gPiA+ID4NCj4gPiA+ID4gPiAtLS0tLU9y
aWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+ID4gPiA+IEZyb206IFdvb2QgU2NvdHQtQjA3NDIxDQo+
ID4gPiA+ID4gU2VudDogV2VkbmVzZGF5LCBBcHJpbCAxNywgMjAxMyA3OjMwIEFNDQo+ID4gPiA+
ID4gVG86IFdhbmcgRG9uZ3NoZW5nLUI0MDUzNA0KPiA+ID4gPiA+IENjOiBXb29kIFNjb3R0LUIw
NzQyMTsgbGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmc7DQo+ID4gPiA+ID4gZ2FsYWtAa2Vy
bmVsLmNyYXNoaW5nLm9yZw0KPiA+ID4gPiA+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjMgMS80XSBw
b3dlcnBjL21waWM6IGFkZCBpcnFfc2V0X3dha2UNCj4gPiA+ID4gPiBzdXBwb3J0DQo+ID4gPiA+
ID4NCj4gPiA+ID4gPiBBQ0sNCj4gPiA+ID4gPg0KPiA+ID4gPiA+IC1TY290dA0KPiA+ID4gPiA+
DQo+ID4gPiA+ID4gT24gMDQvMTYvMjAxMyAwNTo1ODo1MiBBTSwgV2FuZyBEb25nc2hlbmctQjQw
NTM0IHdyb3RlOg0KPiA+ID4gPiA+ID4gSGkgc2NvdHQsDQo+ID4gPiA+ID4gPg0KPiA+ID4gPiA+
ID4gQ291bGQgeW91IEFDSyB0aGVzZSBwYXRjaGVzPw0KPiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+
IFtQQVRDSCB2MyAyLzRdIHBvd2VycGMvbXBpYzogYWRkIGdsb2JhbCB0aW1lciBzdXBwb3J0IFtQ
QVRDSA0KPiA+ID4gPiA+ID4gdjMgMy80XQ0KPiA+ID4gPiA+ID4gcG93ZXJwYy9tcGljOiBjcmVh
dGUgbXBpYyBzdWJzeXN0ZW0gb2JqZWN0IFtQQVRDSCB2MyA0LzRdDQo+ID4gPiA+ID4gPiBwb3dl
cnBjL2ZzbDogYWRkIE1QSUMgdGltZXIgd2FrZXVwIHN1cHBvcnQNCj4gPiA+ID4gPiA+DQo+ID4g
PiA+ID4gPiBUaGFua3MuDQo+ID4gPiA+ID4gPg0KPiANCj4gDQoNCg==
^ permalink raw reply
* RE: [PATCH v2 2/2] powerpc/hibernate: PPC64 fix user threads access to kernel space
From: Wang Dongsheng-B40534 @ 2013-06-09 7:57 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Wood Scott-B07421, johannes@sipsolutions.net, anton@enomsg.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1370763946.14883.24.camel@pasglop>
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogQmVuamFtaW4gSGVycmVu
c2NobWlkdCBbbWFpbHRvOmJlbmhAa2VybmVsLmNyYXNoaW5nLm9yZ10NCj4gU2VudDogU3VuZGF5
LCBKdW5lIDA5LCAyMDEzIDM6NDYgUE0NCj4gVG86IFdhbmcgRG9uZ3NoZW5nLUI0MDUzNA0KPiBD
Yzogam9oYW5uZXNAc2lwc29sdXRpb25zLm5ldDsgYW50b25AZW5vbXNnLm9yZzsgV29vZCBTY290
dC1CMDc0MjE7DQo+IGdhbGFrQGtlcm5lbC5jcmFzaGluZy5vcmc7IGxpbnV4cHBjLWRldkBsaXN0
cy5vemxhYnMub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjIgMi8yXSBwb3dlcnBjL2hpYmVy
bmF0ZTogUFBDNjQgZml4IHVzZXIgdGhyZWFkcw0KPiBhY2Nlc3MgdG8ga2VybmVsIHNwYWNlDQo+
IA0KPiBPbiBTdW4sIDIwMTMtMDYtMDkgYXQgMDc6NDQgKzAwMDAsIFdhbmcgRG9uZ3NoZW5nLUI0
MDUzNCB3cm90ZToNCj4gPiBTbyB3ZSBqdXN0IG5lZWQgc2V0IHNldF9jb250ZXh0KCkgaW4gcmVz
dG9yZV9tbXVfY29udGV4dCgpLg0KPiA+DQo+ID4gdm9pZCByZXN0b3JlX21tdV9jb250ZXh0KHN0
cnVjdCBtbV9zdHJ1Y3QgKm5leHQpIHsNCj4gPiAgICAgICAgIHNldF9jb250ZXh0KG5leHQtPmNv
bnRleHQuaWQsIG5leHQtPnBnZCk7IH0NCj4gDQo+IFdlIHByb2JhYmx5IGFsc28gd2FudCB0byBm
bHVzaCB0aGUgVExCLCBqdXN0IGluIGNhc2UgdGhlIGJvb3Qga2VybmVsIGhhcw0KPiBsZWZ0ICJz
b21ldGhpbmciIHRoZXJlICh0aG91Z2ggSSB3b3VsZG4ndCBleHBlY3QgaXQgdG8gaGF2ZSBydW4g
dXNlcnNwYWNlDQo+IGl0J3Mgbm90IGNvbXBsZXRlbHkgaW1wb3NzaWJsZSkuDQo+IA0KWWVzLCBi
dXQgVExCIGhhcyBhbHJlYWR5IGludmFsaWRhdGVkLg0KU2VlIG15IG90aGVyIHBhdGNoOg0KaHR0
cDovL3BhdGNod29yay5vemxhYnMub3JnL3BhdGNoLzI1MDAwNi8NCg0KPiBDaGVlcnMsDQo+IEJl
bi4NCj4gDQo+IA0KDQo=
^ permalink raw reply
* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2013-06-09 7:56 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list
Hi Linus !
Here are a few more powerpc changes for 3.10. I've merged your
tree in at some point (which I generally avoid) in order to get
the compat network fixes as soon as possible.
Mostly regressions, and stuff I judged could/should still go in at
this stage.
I'm still waiting on some more fixes to the signal handling
vs. transactional memory (this is really ugly btw) which are
hopefully coming next week.
Cheers,
Ben.
The following changes since commit 1612e111e4e565422242727efb59499cce8738e4:
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2013-06-06 18:09:05 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge
for you to fetch changes up to 227331303afdca06e44dcda41d27b72015153827:
powerpc: Print instruction when logging unhandled exceptions (2013-06-09 17:29:16 +1000)
----------------------------------------------------------------
Anton Blanchard (1):
powerpc: Print instruction when logging unhandled exceptions
Benjamin Herrenschmidt (1):
Merge remote-tracking branch 'origin/master' into merge
Gavin Shan (1):
powerpc/eeh: Don't check RTAS token to get PE addr
Kevin Hao (1):
powerpc/pci: Check the bus address instead of resource address in pcibios_fixup_resources
Michael Ellerman (3):
powerpc: Rename PMU interrupts from CNT to PMI
powerpc/perf: Fix deadlock caused by calling printk() in PMU exception
powerpc: Partial revert of "Context switch more PMU related SPRs"
Michael Neuling (4):
powerpc/power8: Fix oprofile and perf
powerpc/pseries: Simplify denormalization handler
powerpc/power8: Update denormalization handler
powerpc/hw_breakpoints: Add DABRX cpu feature to fix 32-bit regression
arch/powerpc/include/asm/cputable.h | 17 +++--
arch/powerpc/kernel/cputable.c | 8 +--
arch/powerpc/kernel/entry_64.S | 28 --------
arch/powerpc/kernel/exceptions-64s.S | 90 ++++++++------------------
arch/powerpc/kernel/irq.c | 2 +-
arch/powerpc/kernel/pci-common.c | 4 +-
arch/powerpc/kernel/process.c | 3 +-
arch/powerpc/kernel/traps.c | 11 +++-
arch/powerpc/perf/core-book3s.c | 2 +-
arch/powerpc/platforms/pseries/eeh_pseries.c | 12 ++--
10 files changed, 60 insertions(+), 117 deletions(-)
^ permalink raw reply
* Re: [PATCH v2 2/2] powerpc/hibernate: PPC64 fix user threads access to kernel space
From: Benjamin Herrenschmidt @ 2013-06-09 7:45 UTC (permalink / raw)
To: Wang Dongsheng-B40534
Cc: Wood Scott-B07421, johannes@sipsolutions.net, anton@enomsg.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259F6D57B@039-SN2MPN1-021.039d.mgd.msft.net>
On Sun, 2013-06-09 at 07:44 +0000, Wang Dongsheng-B40534 wrote:
> So we just need set set_context() in restore_mmu_context().
>
> void restore_mmu_context(struct mm_struct *next) {
> set_context(next->context.id, next->pgd);
> }
We probably also want to flush the TLB, just in case the boot kernel has
left "something" there (though I wouldn't expect it to have run
userspace it's not completely impossible).
Cheers,
Ben.
^ permalink raw reply
* RE: [PATCH v2 2/2] powerpc/hibernate: PPC64 fix user threads access to kernel space
From: Wang Dongsheng-B40534 @ 2013-06-09 7:44 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Wood Scott-B07421, johannes@sipsolutions.net, anton@enomsg.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1370760236.3766.481.camel@pasglop>
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogQmVuamFtaW4gSGVycmVu
c2NobWlkdCBbbWFpbHRvOmJlbmhAa2VybmVsLmNyYXNoaW5nLm9yZ10NCj4gU2VudDogU3VuZGF5
LCBKdW5lIDA5LCAyMDEzIDI6NDQgUE0NCj4gVG86IFdhbmcgRG9uZ3NoZW5nLUI0MDUzNA0KPiBD
Yzogam9oYW5uZXNAc2lwc29sdXRpb25zLm5ldDsgYW50b25AZW5vbXNnLm9yZzsgV29vZCBTY290
dC1CMDc0MjE7DQo+IGdhbGFrQGtlcm5lbC5jcmFzaGluZy5vcmc7IGxpbnV4cHBjLWRldkBsaXN0
cy5vemxhYnMub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjIgMi8yXSBwb3dlcnBjL2hpYmVy
bmF0ZTogUFBDNjQgZml4IHVzZXIgdGhyZWFkcw0KPiBhY2Nlc3MgdG8ga2VybmVsIHNwYWNlDQo+
IA0KPiBPbiBTdW4sIDIwMTMtMDYtMDkgYXQgMTM6MjIgKzA4MDAsIFdhbmcgRG9uZ3NoZW5nIHdy
b3RlOg0KPiA+IElmIFBJRCBpcyB1c2VkIGluIHRoZSBUTEIsIGFmdGVyIGhpYmVybmF0aW9uIHJl
c3VtZSwgdGhlIHVzZXIgdGhyZWFkcw0KPiA+IHdpbGwgYWNjZXNzIHRvIGtlcm5lbCBzcGFjZS4N
Cj4gDQo+ICAuLi4vLi4uDQo+IA0KPiBJIHRoaW5rIHRoZSBleHBsYW5hdGlvbiBpcyB3YXkgbW9y
ZSBjb252b2x1dGVkIGFuZCBjb25mdXNpbmcgaGVyZSB0aGFuDQo+IGFueXRoaW5nIGVsc2UuDQo+
IA0KPiBTaW1wbHkgc2F5IHRoYXQgdXBvbiByZXN1bWUgZnJvbSBoaWJlcm5hdGlvbiwgdGhlIE1N
VSBjb250ZXh0IG5lZWRzIHRvIGJlDQo+IHJlc3RvcmVkICh0aGlzIGluY2x1ZGVzIHRoZSBQSUQg
cmVnaXN0ZXIgdG9kYXkgaXQgbWlnaHQgaW5jbHVkZSBtb3JlIGlmDQo+IHdlIGRlY2lkZWQgdG8g
cHJlLXNldCBzb21lIE1BUyBmb3IgZXhhbXBsZQ0KPiBldGMuLi4pIGFuZCBiZSBkb25lIHdpdGgg
aXQuDQo+IA0KPiBOb3RlIHRoYXQgc3dpdGNoX21tdV9jb250ZXh0KCkgdXNlZCB0aGUgd2F5IHlv
dSBkbyBpcyBxdWl0ZSAiZnVsbCBvbiIsIGl0DQo+IHdpbGwgZG8gYSB3aG9sZSBwaWxlIG9mIHN0
dWZmIHRoYXQgYXJlIHByb2JhYmx5IGNvbXBsZXRlbHkgdW5uZWNlc3NhcnksDQo+IGFuZCBpbiBh
ZGRpdGlvbiBtaWdodCBzdGlsbCBtaXNzIHRoZSBuZWVkIHRvIGNvbXBsZXRlbHkgZmx1c2ggdGhl
IFRMQg0KPiBhbnl3YXkuDQo+IA0KPiBJIHdvdWxkIHN1Z2dlc3QgdGhhdCBpbnN0ZWFkLCBzb21l
Ym9keSBhZGRzIHRoZSBuZWNlc3Nhcnkgcm91dGluZSB0bw0KPiB0bGJfbm9oYXNoLmMsIHNvbWV0
aGluZyBsaWtlIHJlc3RvcmVfbW11X2NvbnRleHQoKSB3aGljaCB3aWxsIGRvIHRoYXQuDQo+IA0K
VGhhbmtzIGJlbiwgVGhpcyBpcyBhIGdvb2QgaWRlYS4NCg0KV2UgZG8gbm90IG5lZWQgdG8gZGVj
aWRlIHRoZSBjdXJyZW50IHRocmVhZCBoYXMgYSBjb250ZXh0IGluIHJlc3RvcmVfbW11X2NvbnRl
eHQoKS4NCkJlY2F1c2UgdGhlIGN1cnJlbnQgaGFzIGFscmVhZHkgZ2V0IGEgY29udGV4dCBpbiBo
aWJlcm5hdGlvbiBzdXNwZW5kIGZsb3cuDQoNClNvIHdlIGp1c3QgbmVlZCBzZXQgc2V0X2NvbnRl
eHQoKSBpbiByZXN0b3JlX21tdV9jb250ZXh0KCkuDQoNCnZvaWQgcmVzdG9yZV9tbXVfY29udGV4
dChzdHJ1Y3QgbW1fc3RydWN0ICpuZXh0KSB7DQoJc2V0X2NvbnRleHQobmV4dC0+Y29udGV4dC5p
ZCwgbmV4dC0+cGdkKTsNCn0NCg0KLWRvbmdzaGVuZw0KDQo+IENoZWVycywNCj4gQmVuLg0KPiAN
Cj4gPiBTaWduZWQtb2ZmLWJ5OiBXYW5nIERvbmdzaGVuZyA8ZG9uZ3NoZW5nLndhbmdAZnJlZXNj
YWxlLmNvbT4NCj4gPiAtLS0NCj4gPiAgYXJjaC9wb3dlcnBjL2tlcm5lbC9zd3N1c3AuYyB8IDIg
LS0NCj4gPiAgMSBmaWxlIGNoYW5nZWQsIDIgZGVsZXRpb25zKC0pDQo+ID4NCj4gPiBkaWZmIC0t
Z2l0IGEvYXJjaC9wb3dlcnBjL2tlcm5lbC9zd3N1c3AuYw0KPiA+IGIvYXJjaC9wb3dlcnBjL2tl
cm5lbC9zd3N1c3AuYyBpbmRleCBlYWUzM2UxLi4xOTMwZTQ0IDEwMDY0NA0KPiA+IC0tLSBhL2Fy
Y2gvcG93ZXJwYy9rZXJuZWwvc3dzdXNwLmMNCj4gPiArKysgYi9hcmNoL3Bvd2VycGMva2VybmVs
L3N3c3VzcC5jDQo+ID4gQEAgLTMyLDcgKzMyLDUgQEAgdm9pZCBzYXZlX3Byb2Nlc3Nvcl9zdGF0
ZSh2b2lkKQ0KPiA+DQo+ID4gIHZvaWQgcmVzdG9yZV9wcm9jZXNzb3Jfc3RhdGUodm9pZCkNCj4g
PiAgew0KPiA+IC0jaWZkZWYgQ09ORklHX1BQQzMyDQo+ID4gIAlzd2l0Y2hfbW11X2NvbnRleHQo
Y3VycmVudC0+YWN0aXZlX21tLCBjdXJyZW50LT5hY3RpdmVfbW0pOyAtI2VuZGlmDQo+ID4gfQ0K
PiANCj4gDQoNCg==
^ permalink raw reply
* Re: [PATCH 3/5] powerpc/tm: Fix restoration of MSR on 32bit signal return
From: Benjamin Herrenschmidt @ 2013-06-09 7:27 UTC (permalink / raw)
To: Michael Neuling; +Cc: linuxppc-dev, Matt Evans
In-Reply-To: <1370601390-29065-3-git-send-email-mikey@neuling.org>
On Fri, 2013-06-07 at 20:36 +1000, Michael Neuling wrote:
> Currently we clear out the MSR TM bits on signal return assuming that the
> signal should never return to an active transaction.
>
> This is bogus as the user may do this. It's most likely the transaction will
> be doomed due to a treclaim but that's a problem for the HW not the kernel.
>
> This removes the stripping of these MSR TM bits.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
> @@ -859,8 +860,10 @@ static long restore_tm_user_regs(struct pt_regs *regs,
> tm_enable();
> /* This loads the checkpointed FP/VEC state, if used */
> tm_recheckpoint(¤t->thread, msr);
> - /* The task has moved into TM state S, so ensure MSR reflects this */
> - regs->msr = (regs->msr & ~MSR_TS_MASK) | MSR_TS_S;
> + /* Retore the top half of the MSR */
> + if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
> + return 1;
> + regs->msr = (regs->msr | (((unsigned long)msr_hi) << 32));
What kind of damage can I do by calling sigreturn with a cooked
frame with random MSR bits set ? You should probably filter
what bits you allow to come from the frame.
Additionally, I would also make sure I only do that if the CPU
features say TM is supported in case that MSR bit means something else
on a different/older CPU...
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 2/5] powerpc/tm: Fix 32 bit non-rt signals
From: Benjamin Herrenschmidt @ 2013-06-09 7:25 UTC (permalink / raw)
To: Michael Neuling; +Cc: linuxppc-dev, Matt Evans
In-Reply-To: <1370601390-29065-2-git-send-email-mikey@neuling.org>
On Fri, 2013-06-07 at 20:36 +1000, Michael Neuling wrote:
> Currently sys_sigreturn() is TM unaware. Therefore, if we take a 32 bit signal
> without SIGINFO (non RT) inside a transaction, on signal return we don't
> restore the signal frame correctly.
>
> This checks if the signal frame being restoring is an active transaction, and
> if so, it copies the additional state to ptregs so it can be restored.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
.../...
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> + mcp = (struct mcontext __user *)&sf->mctx;
> + tm_mcp = (struct mcontext __user *)&sf->mctx_transact;
> + if (__get_user(msr_hi, &tm_mcp->mc_gregs[PT_MSR]))
> goto badframe;
> + if MSR_TM_ACTIVE(msr_hi<<32) {
Mising ( and ). I'll apply that fix locally.
Appart from that, I suppose it's ok. I don't see any exposure
coming from users "cooking" the tm_frame and calling sigreturn,
so as long as we are confident userspace generally only uses
sigreturn with frames it got from an actual signal, and doesn't
try to "generate" frames by hand, we should be ok.
Cheers,
Ben.
^ permalink raw reply
* [PATCH 3/3] powerpc/8xx: Remove 8xx specific "minimal FPU emulation"
From: Benjamin Herrenschmidt @ 2013-06-09 7:04 UTC (permalink / raw)
To: linuxppc-dev
This is duplicated code from math-emu and implements such a small
subset of the FPU (load/stores/fmr) that it's essentially pointless
nowdays.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Note that arch/powerpc/math-emu/math.c seems to have code in there
to do exactly the same thing (subset emulation) if CONFIG_MATH_EMULATION
isn't set. However that code isn't used since we simply don't call
do_mathemu() not build any of the relevant files when this is not
set.
I'm not removing this just yet. If somebody thinks there is value
in supporting that "minimal set emulation", then send me a patch
that provides a Kconfig/Makefile way of enabling that code, which
makes it work on all soft-fpu powerpc's and not just 8xx.
If nobody reacts, I'll probably just rip the code out by the next
kernel version.
arch/powerpc/Kconfig | 11 -----------
arch/powerpc/kernel/traps.c | 22 +---------------------
2 files changed, 1 insertion(+), 32 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e3009ab..5374776 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -319,17 +319,6 @@ config PPC_TRANSACTIONAL_MEM
---help---
Support user-mode Transactional Memory on POWERPC.
-config 8XX_MINIMAL_FPEMU
- bool "Minimal math emulation for 8xx"
- depends on 8xx && !MATH_EMULATION
- help
- Older arch/ppc kernels still emulated a few floating point
- instructions such as load and store, even when full math
- emulation is disabled. Say "Y" here if you want to preserve
- this behavior.
-
- It is recommended that you build a soft-float userspace instead.
-
config IOMMU_HELPER
def_bool PPC64
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index ff315a7..8093156 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1401,8 +1401,7 @@ void performance_monitor_exception(struct pt_regs *regs)
void SoftwareEmulation(struct pt_regs *regs)
{
extern int do_mathemu(struct pt_regs *);
- extern int Soft_emulate_8xx(struct pt_regs *);
-#if defined(CONFIG_MATH_EMULATION) || defined(CONFIG_8XX_MINIMAL_FPEMU)
+#if defined(CONFIG_MATH_EMULATION)
int errcode;
#endif
@@ -1435,23 +1434,6 @@ void SoftwareEmulation(struct pt_regs *regs)
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
return;
}
-
-#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
- errcode = Soft_emulate_8xx(regs);
- if (errcode >= 0)
- PPC_WARN_EMULATED(8xx, regs);
-
- switch (errcode) {
- case 0:
- emulate_single_step(regs);
- return;
- case 1:
- _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
- return;
- case -EFAULT:
- _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
- return;
- }
#else
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
#endif
@@ -1801,8 +1783,6 @@ struct ppc_emulated ppc_emulated = {
WARN_EMULATED_SETUP(unaligned),
#ifdef CONFIG_MATH_EMULATION
WARN_EMULATED_SETUP(math),
-#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
- WARN_EMULATED_SETUP(8xx),
#endif
#ifdef CONFIG_VSX
WARN_EMULATED_SETUP(vsx),
^ permalink raw reply related
* [PATCH 2/3] powerpc/math-emu: Allow math-emu to be used for HW FPU
From: Benjamin Herrenschmidt @ 2013-06-09 7:01 UTC (permalink / raw)
To: linuxppc-dev
(Including 64-bit ones)
This allow SW emulation by the kernel of optional instructions
such as fsqrt which aren't implemented on some processors, and
thus fixes some Fedora 19 issues such as Anaconda since the
compiler is set to generate those by default on 64-bit.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/Kconfig | 6 +++++-
arch/powerpc/kernel/traps.c | 12 +++++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c33e3ad..e3009ab 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -298,7 +298,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE
config MATH_EMULATION
bool "Math emulation"
- depends on 4xx || 8xx || E200 || PPC_MPC832x || E500
+ depends on 4xx || 8xx || PPC_MPC832x || BOOKE
---help---
Some PowerPC chips designed for embedded applications do not have
a floating-point unit and therefore do not implement the
@@ -307,6 +307,10 @@ config MATH_EMULATION
unit, which will allow programs that use floating-point
instructions to run.
+ This is also useful to emulate missing (optional) instructions
+ such as fsqrt on cores that do have an FPU but do not implement
+ them (such as Freescale BookE).
+
config PPC_TRANSACTIONAL_MEM
bool "Transactional Memory support for POWERPC"
depends on PPC_BOOK3S_64
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6dfbb38..ff315a7 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1130,7 +1130,17 @@ void __kprobes program_check_exception(struct pt_regs *regs)
* ESR_DST (!?) or 0. In the process of chasing this with the
* hardware people - not sure if it can happen on any illegal
* instruction or only on FP instructions, whether there is a
- * pattern to occurrences etc. -dgibson 31/Mar/2003 */
+ * pattern to occurrences etc. -dgibson 31/Mar/2003
+ */
+
+ /*
+ * If we support a HW FPU, we need to ensure the FP state
+ * if flushed into the thread_struct before attempting
+ * emulation
+ */
+#ifdef CONFIG_PPC_FPU
+ flush_fp_to_thread(current);
+#endif
switch (do_mathemu(regs)) {
case 0:
emulate_single_step(regs);
^ permalink raw reply related
* [PATCH 1/3] powerpc/math-emu: Fix decoding of some instructions
From: Benjamin Herrenschmidt @ 2013-06-09 7:00 UTC (permalink / raw)
To: linuxppc-dev
The decoding of some instructions such as fsqrt{s} was incorrect,
using the wrong registers, and thus could not work.
This fixes it and also adds a couple of place holders for missing
instructions.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Note: fre.c etc.. are still empty placeholders, just like fres.c
is today. Eventually somebody needs to fill-in the missing bits
arch/powerpc/math-emu/Makefile | 3 ++-
arch/powerpc/math-emu/fre.c | 11 +++++++++++
arch/powerpc/math-emu/frsqrtes.c | 11 +++++++++++
arch/powerpc/math-emu/math.c | 14 ++++++++++----
4 files changed, 34 insertions(+), 5 deletions(-)
create mode 100644 arch/powerpc/math-emu/fre.c
create mode 100644 arch/powerpc/math-emu/frsqrtes.c
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 7d1dba0..8d035d2 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -4,7 +4,8 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
fmadd.o fmadds.o fmsub.o fmsubs.o \
fmul.o fmuls.o fnabs.o fneg.o \
fnmadd.o fnmadds.o fnmsub.o fnmsubs.o \
- fres.o frsp.o frsqrte.o fsel.o lfs.o \
+ fres.o fre.o frsp.o fsel.o lfs.o \
+ frsqrte.o frsqrtes.o \
fsqrt.o fsqrts.o fsub.o fsubs.o \
mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
mtfsf.o mtfsfi.o stfiwx.o stfs.o \
diff --git a/arch/powerpc/math-emu/fre.c b/arch/powerpc/math-emu/fre.c
new file mode 100644
index 0000000..49ccf2c
--- /dev/null
+++ b/arch/powerpc/math-emu/fre.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+int fre(void *frD, void *frB)
+{
+#ifdef DEBUG
+ printk("%s: %p %p\n", __func__, frD, frB);
+#endif
+ return -ENOSYS;
+}
diff --git a/arch/powerpc/math-emu/frsqrtes.c b/arch/powerpc/math-emu/frsqrtes.c
new file mode 100644
index 0000000..7e838e3
--- /dev/null
+++ b/arch/powerpc/math-emu/frsqrtes.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+int frsqrtes(void *frD, void *frB)
+{
+#ifdef DEBUG
+ printk("%s: %p %p\n", __func__, frD, frB);
+#endif
+ return 0;
+}
diff --git a/arch/powerpc/math-emu/math.c b/arch/powerpc/math-emu/math.c
index 164d559..0328e66 100644
--- a/arch/powerpc/math-emu/math.c
+++ b/arch/powerpc/math-emu/math.c
@@ -58,8 +58,10 @@ FLOATFUNC(fnabs);
FLOATFUNC(fneg);
/* Optional */
+FLOATFUNC(fre);
FLOATFUNC(fres);
FLOATFUNC(frsqrte);
+FLOATFUNC(frsqrtes);
FLOATFUNC(fsel);
FLOATFUNC(fsqrt);
FLOATFUNC(fsqrts);
@@ -97,6 +99,7 @@ FLOATFUNC(fsqrts);
#define FSQRTS 0x016 /* 22 */
#define FRES 0x018 /* 24 */
#define FMULS 0x019 /* 25 */
+#define FRSQRTES 0x01a /* 26 */
#define FMSUBS 0x01c /* 28 */
#define FMADDS 0x01d /* 29 */
#define FNMSUBS 0x01e /* 30 */
@@ -109,6 +112,7 @@ FLOATFUNC(fsqrts);
#define FADD 0x015 /* 21 */
#define FSQRT 0x016 /* 22 */
#define FSEL 0x017 /* 23 */
+#define FRE 0x018 /* 24 */
#define FMUL 0x019 /* 25 */
#define FRSQRTE 0x01a /* 26 */
#define FMSUB 0x01c /* 28 */
@@ -299,9 +303,10 @@ do_mathemu(struct pt_regs *regs)
case FDIVS: func = fdivs; type = AB; break;
case FSUBS: func = fsubs; type = AB; break;
case FADDS: func = fadds; type = AB; break;
- case FSQRTS: func = fsqrts; type = AB; break;
- case FRES: func = fres; type = AB; break;
+ case FSQRTS: func = fsqrts; type = XB; break;
+ case FRES: func = fres; type = XB; break;
case FMULS: func = fmuls; type = AC; break;
+ case FRSQRTES: func = frsqrtes;type = XB; break;
case FMSUBS: func = fmsubs; type = ABC; break;
case FMADDS: func = fmadds; type = ABC; break;
case FNMSUBS: func = fnmsubs; type = ABC; break;
@@ -317,10 +322,11 @@ do_mathemu(struct pt_regs *regs)
case FDIV: func = fdiv; type = AB; break;
case FSUB: func = fsub; type = AB; break;
case FADD: func = fadd; type = AB; break;
- case FSQRT: func = fsqrt; type = AB; break;
+ case FSQRT: func = fsqrt; type = XB; break;
+ case FRE: func = fre; type = XB; break;
case FSEL: func = fsel; type = ABC; break;
case FMUL: func = fmul; type = AC; break;
- case FRSQRTE: func = frsqrte; type = AB; break;
+ case FRSQRTE: func = frsqrte; type = XB; break;
case FMSUB: func = fmsub; type = ABC; break;
case FMADD: func = fmadd; type = ABC; break;
case FNMSUB: func = fnmsub; type = ABC; break;
^ permalink raw reply related
* Re: [PATCH v2 2/2] powerpc/hibernate: PPC64 fix user threads access to kernel space
From: Benjamin Herrenschmidt @ 2013-06-09 6:43 UTC (permalink / raw)
To: Wang Dongsheng; +Cc: scottwood, johannes, anton, linuxppc-dev
In-Reply-To: <1370755352-29901-1-git-send-email-dongsheng.wang@freescale.com>
On Sun, 2013-06-09 at 13:22 +0800, Wang Dongsheng wrote:
> If PID is used in the TLB, after hibernation resume, the user
> threads will access to kernel space.
.../...
I think the explanation is way more convoluted and confusing
here than anything else.
Simply say that upon resume from hibernation, the MMU context
needs to be restored (this includes the PID register today
it might include more if we decided to pre-set some MAS for example
etc...) and be done with it.
Note that switch_mmu_context() used the way you do is quite "full on",
it will do a whole pile of stuff that are probably completely
unnecessary, and in addition might still miss the need to completely
flush the TLB anyway.
I would suggest that instead, somebody adds the necessary routine
to tlb_nohash.c, something like restore_mmu_context() which will
do that.
Cheers,
Ben.
> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> ---
> arch/powerpc/kernel/swsusp.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
> index eae33e1..1930e44 100644
> --- a/arch/powerpc/kernel/swsusp.c
> +++ b/arch/powerpc/kernel/swsusp.c
> @@ -32,7 +32,5 @@ void save_processor_state(void)
>
> void restore_processor_state(void)
> {
> -#ifdef CONFIG_PPC32
> switch_mmu_context(current->active_mm, current->active_mm);
> -#endif
> }
^ permalink raw reply
* Re: fsqrt
From: Benjamin Herrenschmidt @ 2013-06-09 6:32 UTC (permalink / raw)
To: Dan Malek, Kumar Gala
Cc: Xie Shaohui-B21989, Liu Qiang-B32616, Zang Roy-R61911, Timur Tabi,
tiejun.chen, David Laight, Fleming Andy-AFLEMING,
Bhushan Bharat-R65777, linuxppc-dev
In-Reply-To: <4A771AC5-37F2-4EC2-A733-52FFAAAB3C92@digitaldans.com>
The interesting thing I'm finding is that our math-emu is actually
quite busted :-)
For example look at fsqrt. It's defined as type AB which is incorrect,
it should be type XB. It ends up looking for it's arguments in the wrong
registers, same for fsrqts, fre, and a few others.
Also quite a few functions are simply left unimplemented... (fre is
completely missing from the decode, fres is there but returns -ENOSYS,
as does frsqrte, etc...)
I'll post a quick for for fsqrt{s} that I need for anaconda, but I
would strongly encourage somebody from FSL (primary users of that
stuff still) to have a close look at the rest. It shouldn't be terribly
hard to fix them up and add the few missing instructions, even if not
with the amount of precision requested by the spec (better than -ENOSYS)
Cheers,
Ben.
^ permalink raw reply
* [PATCH v2 2/2] powerpc/hibernate: PPC64 fix user threads access to kernel space
From: Wang Dongsheng @ 2013-06-09 5:22 UTC (permalink / raw)
To: benh, johannes, anton; +Cc: scottwood, linuxppc-dev, Wang Dongsheng
If PID is used in the TLB, after hibernation resume, the user
threads will access to kernel space.
We must restore PID register, because TLB will use PID. The
hibernation suspend flow is trapped from user space to kernel
space, the PID register is user thread pid.
The hibernation resume is begin in kernel start flow, the PID
alway 0. After the kernel thread back to user thread, there is
not have context switch and the pid can not update, because the
kernel thread is trapped form user space. So if we did't restore
PID the user space of thread will be addressing in the kernel
space.
There are two ways to restore PID:
1/ In swsusp_arch_suspend/swsusp_arch_resume, save/resotre PID register.
2/ Form restore_processor_state to restore. this function will
do context switch.
switch_mmu_context(current->active_mm, current->active_mm)
PPC32 Using the second method. For consistency reason, PPC64 using
the same way.
Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
---
arch/powerpc/kernel/swsusp.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
index eae33e1..1930e44 100644
--- a/arch/powerpc/kernel/swsusp.c
+++ b/arch/powerpc/kernel/swsusp.c
@@ -32,7 +32,5 @@ void save_processor_state(void)
void restore_processor_state(void)
{
-#ifdef CONFIG_PPC32
switch_mmu_context(current->active_mm, current->active_mm);
-#endif
}
--
1.8.0
^ permalink raw reply related
* [PATCH v2 1/2] powerpc: add Book E support to 64-bit hibernation
From: Wang Dongsheng @ 2013-06-09 5:21 UTC (permalink / raw)
To: johannes, anton, scottwood; +Cc: linuxppc-dev, Wang Dongsheng
Update the 64-bit hibernation code to support Book E CPUs.
Some registers and instructions are not defined for Book3e
(SDR reg, tlbia instruction).
SDR: Storage Description Register. Book3S and Book3E have different
address translation mode, we do not need HTABORG & HTABSIZE to
translate virtual address to real address.
More registers are saved in BookE-64bit.(TCR, SPRGx, ...)
Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
---
v2:
* Add: _tlbil_all
*
* The boot core get a virtual address, when the boot process,
* the virtual address corresponds to a physical address. After
* hibernation resume memory snapshots, The corresponding
* relationship between the virtual memory and physical memory
* might change again. We need to get a new page table. So we
* need to invalidate TLB after resume pages.
*
* Invalidations TLB Using tlbilx/tlbivax/MMUCSR0.
* tlbilx used here.
*
* Add: save/restore PID
*
* We must restore PID register, because TLB will use PID. The
* hibernation suspend flow is trapped from user space to kernel
* space, the PID register is user thread pid.
*
* The hibernation resume is begin in kernel start flow, the PID
* alway 0. After the kernel thread back to user thread, there is
* not have context switch and the pid can not update, because the
* kernel thread is trapped form user space. So if we did't restore
* PID the user space of thread will be addressing in the kernel
* space.
*
* There are two ways to restore PID:
* 1/ In this file save/resotre PID register.
* 2/ Form restore_processor_state to restore. this function will
* do context switch.
* switch_mmu_context(current->active_mm, current->active_mm)
*
* PPC32 Using the second method. For consistency reason, PPC64
* using the same way.
*
* History:
* Wood Scott(A): Please investigate the issue of whether we are loading
* kernel module code in this step
* R: Kernel will allocate the memory for module code segment and data
* segment. First allocate a memory, and copy the umod to hdr members
* of the struct load_info. Due to the temporary assigned module belongs
* to the kernel space, so it belongs to the kernel data.
*
* The kernel of all data will be saved when hibernation suspend. So
* the module which has already been inserted will be saved.
arch/powerpc/kernel/swsusp_asm64.S | 102 ++++++++++++++++++++++++++++++++++++-
1 file changed, 100 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S
index 86ac1d9..c7e2b4a 100644
--- a/arch/powerpc/kernel/swsusp_asm64.S
+++ b/arch/powerpc/kernel/swsusp_asm64.S
@@ -46,10 +46,30 @@
#define SL_r29 0xe8
#define SL_r30 0xf0
#define SL_r31 0xf8
-#define SL_SIZE SL_r31+8
+#define SL_SPRG0 0x100
+#define SL_SPRG1 0x108
+#define SL_SPRG2 0x110
+#define SL_SPRG3 0x118
+#define SL_SPRG4 0x120
+#define SL_SPRG5 0x128
+#define SL_SPRG6 0x130
+#define SL_SPRG7 0x138
+#define SL_TCR 0x140
+#define SL_PID 0x148
+#define SL_SIZE SL_PID+8
/* these macros rely on the save area being
* pointed to by r11 */
+
+#define SAVE_SPR(register) \
+ mfspr r0,SPRN_##register ;\
+ std r0,SL_##register(r11)
+#define RESTORE_SPR(register) \
+ ld r0,SL_##register(r11) ;\
+ mtspr SPRN_##register,r0
+#define RESTORE_SPRG(n) \
+ ld r0,SL_SPRG##n(r11) ;\
+ mtsprg n,r0
#define SAVE_SPECIAL(special) \
mf##special r0 ;\
std r0, SL_##special(r11)
@@ -103,8 +123,22 @@ _GLOBAL(swsusp_arch_suspend)
SAVE_REGISTER(r30)
SAVE_REGISTER(r31)
SAVE_SPECIAL(MSR)
- SAVE_SPECIAL(SDR1)
SAVE_SPECIAL(XER)
+#ifdef CONFIG_PPC_BOOK3S_64
+ SAVE_SPECIAL(SDR1)
+#else
+ SAVE_SPR(TCR)
+ /* Save SPRGs */
+ SAVE_SPR(SPRG0)
+ SAVE_SPR(SPRG1)
+ SAVE_SPR(SPRG2)
+ SAVE_SPR(SPRG3)
+ SAVE_SPR(SPRG4)
+ SAVE_SPR(SPRG5)
+ SAVE_SPR(SPRG6)
+ SAVE_SPR(SPRG7)
+ SAVE_SPR(PID);
+#endif
/* we push the stack up 128 bytes but don't store the
* stack pointer on the stack like a real stackframe */
@@ -151,6 +185,7 @@ copy_page_loop:
bne+ copyloop
nothing_to_copy:
+#ifdef CONFIG_PPC_BOOK3S_64
/* flush caches */
lis r3, 0x10
mtctr r3
@@ -167,6 +202,7 @@ nothing_to_copy:
sync
tlbia
+#endif
ld r11,swsusp_save_area_ptr@toc(r2)
@@ -208,16 +244,78 @@ nothing_to_copy:
RESTORE_REGISTER(r29)
RESTORE_REGISTER(r30)
RESTORE_REGISTER(r31)
+
+#ifdef CONFIG_PPC_BOOK3S_64
/* can't use RESTORE_SPECIAL(MSR) */
ld r0, SL_MSR(r11)
mtmsrd r0, 0
RESTORE_SPECIAL(SDR1)
+#else
+ /* Save SPRGs */
+ RESTORE_SPRG(0)
+ RESTORE_SPRG(1)
+ RESTORE_SPRG(2)
+ RESTORE_SPRG(3)
+ RESTORE_SPRG(4)
+ RESTORE_SPRG(5)
+ RESTORE_SPRG(6)
+ RESTORE_SPRG(7)
+
+ /*
+ * We must restore PID register, because TLB will use PID. The
+ * hibernation suspend flow is trapped from user space to kernel
+ * space, the PID register is user thread pid.
+ *
+ * The hibernation resume is begin in kernel start flow, the PID
+ * alway 0. After the kernel thread back to user thread, there is
+ * not have context switch and the pid can not update, because the
+ * kernel thread is trapped form user space. So if we did't restore
+ * PID the user space of thread will be addressing in the kernel
+ * space.
+ *
+ * There are two ways to restore PID:
+ * 1/ In this file save/resotre PID register.
+ * 2/ Form restore_processor_state to restore. this function will
+ * do context switch.
+ * switch_mmu_context(current->active_mm, current->active_mm)
+ *
+ * PPC32 Using the second method. For consistency reason, PPC64
+ * using the same way.
+ */
+// RESTORE_SPR(PID)
+
+ RESTORE_SPECIAL(MSR)
+
+ /* Restore TCR and clear any pending bits in TSR. */
+ RESTORE_SPR(TCR)
+ lis r0, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h
+ mtspr SPRN_TSR,r0
+
+ /* Kick decrementer */
+ li r0,1
+ mtdec r0
+#endif
RESTORE_SPECIAL(XER)
+ /*
+ * The boot core get a virtual address, when the boot process,
+ * the virtual address corresponds to a physical address. After
+ * hibernation resume memory snapshots, The corresponding
+ * relationship between the virtual memory and physical memory
+ * might change again. We need to get a new page table. So we
+ * need to invalidate TLB after resume pages.
+ *
+ * Invalidations TLB Using tlbilx/tlbivax/MMUCSR0.
+ * tlbilx used here.
+ */
+ bl _tlbil_all
+
sync
addi r1,r1,-128
+#ifdef CONFIG_PPC_BOOK3S_64
bl slb_flush_and_rebolt
+#endif
bl do_after_copyback
addi r1,r1,128
--
1.8.0
^ permalink raw reply related
* [PATCH 06/26] block: Convert bio_for_each_segment() to bvec_iter
From: Kent Overstreet @ 2013-06-09 2:18 UTC (permalink / raw)
To: axboe, tytso, linux-kernel, linux-fsdevel
Cc: Jeremy Fitzhardinge, Herton Ronaldo Krzesinski, Jan Kara,
Ed L. Cashin, Neil Brown, Kent Overstreet, support,
Heiko Carstens, virtualization, Keith Busch, linux-mm,
Quoc-Son Anh, Paul Mackerras, James E.J. Bottomley,
Stephen Hemminger, Joshua Morris, Nick Piggin, devel, linux-s390,
xen-devel, Jerome Marchand, Mike Snitzer, linux-scsi, Minchan Kim,
Sebastian Ott, Philip Kelleher, Steven Whitehouse, cluster-devel,
Geert Uytterhoeven, Asai Thambi S P, Lars Ellenberg, Sam Bradshaw,
Nitin Gupta, cbe-oss-dev, nbd-general, Sage Weil,
Konrad Rzeszutek Wilk, Paul Clements, DL-MPTFusionLinux,
Chris Metcalf, linux-raid, Tejun Heo, linux-m68k, Alexander Viro,
Selvan Mani, ceph-devel, drbd-user, Nagalakshmi Nandigama,
Yehuda Sadeh, Alex Elder, Seth Jennings, Martin K. Petersen,
Geoff Levand, Jiri Kosina, Darrick J. Wong, Jim Paris,
Sreekanth Reddy, Vivek Goyal, Greg Kroah-Hartman,
Martin Schwidefsky, linux390, Andrew Morton, linuxppc-dev,
Guo Chao, Matthew Wilcox
In-Reply-To: <1370744348-15407-1-git-send-email-koverstreet@google.com>
More prep work for immutable biovecs - with immutable bvecs drivers
won't be able to use the biovec directly, they'll need to use helpers
that take into account bio->bi_iter.bi_bvec_done.
This updates callers for the new usage without changing the
implementation yet.
Signed-off-by: Kent Overstreet <koverstreet@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: "Ed L. Cashin" <ecashin@coraid.com>
Cc: Nick Piggin <npiggin@kernel.dk>
Cc: Lars Ellenberg <drbd-dev@lists.linbit.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Paul Clements <Paul.Clements@steeleye.com>
Cc: Jim Paris <jim@jtan.com>
Cc: Geoff Levand <geoff@infradead.org>
Cc: Yehuda Sadeh <yehuda@inktank.com>
Cc: Sage Weil <sage@inktank.com>
Cc: Alex Elder <elder@inktank.com>
Cc: ceph-devel@vger.kernel.org
Cc: Joshua Morris <josh.h.morris@us.ibm.com>
Cc: Philip Kelleher <pjk1939@linux.vnet.ibm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Neil Brown <neilb@suse.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com>
Cc: Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
Cc: support@lsi.com
Cc: "James E.J. Bottomley" <JBottomley@parallels.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Kent Overstreet <koverstreet@google.com>
Cc: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Guo Chao <yan@linux.vnet.ibm.com>
Cc: Asai Thambi S P <asamymuthupa@micron.com>
Cc: Selvan Mani <smani@micron.com>
Cc: Sam Bradshaw <sbradshaw@micron.com>
Cc: Matthew Wilcox <matthew.r.wilcox@intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Quoc-Son Anh <quoc-sonx.anh@intel.com>
Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
Cc: Nitin Gupta <ngupta@vflare.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Jerome Marchand <jmarchan@redhat.com>
Cc: Seth Jennings <sjenning@linux.vnet.ibm.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Mike Snitzer <snitzer@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-m68k@lists.linux-m68k.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: drbd-user@lists.linbit.com
Cc: nbd-general@lists.sourceforge.net
Cc: cbe-oss-dev@lists.ozlabs.org
Cc: xen-devel@lists.xensource.com
Cc: virtualization@lists.linux-foundation.org
Cc: linux-raid@vger.kernel.org
Cc: linux-s390@vger.kernel.org
Cc: DL-MPTFusionLinux@lsi.com
Cc: linux-scsi@vger.kernel.org
Cc: devel@driverdev.osuosl.org
Cc: linux-fsdevel@vger.kernel.org
Cc: cluster-devel@redhat.com
Cc: linux-mm@kvack.org
---
arch/m68k/emu/nfblock.c | 11 ++---
arch/powerpc/sysdev/axonram.c | 18 ++++-----
block/blk-merge.c | 45 ++++++++++-----------
drivers/block/aoe/aoecmd.c | 16 ++++----
drivers/block/brd.c | 12 +++---
drivers/block/drbd/drbd_main.c | 27 +++++++------
drivers/block/drbd/drbd_receiver.c | 13 +++---
drivers/block/drbd/drbd_worker.c | 8 ++--
drivers/block/floppy.c | 12 +++---
drivers/block/loop.c | 23 ++++++-----
drivers/block/mtip32xx/mtip32xx.c | 13 +++---
drivers/block/nbd.c | 12 +++---
drivers/block/nvme-core.c | 33 ++++++++-------
drivers/block/ps3vram.c | 10 ++---
drivers/block/rbd.c | 36 ++++++++---------
drivers/block/rsxx/dma.c | 11 ++---
drivers/block/xen-blkfront.c | 14 +++----
drivers/md/bcache/btree.c | 4 +-
drivers/md/bcache/debug.c | 23 ++++++-----
drivers/md/bcache/io.c | 69 ++++++++++++++------------------
drivers/md/bcache/request.c | 28 ++++++-------
drivers/md/md.c | 16 ++++----
drivers/md/raid5.c | 12 +++---
drivers/s390/block/dcssblk.c | 14 +++----
drivers/s390/block/xpram.c | 10 ++---
drivers/scsi/mpt2sas/mpt2sas_transport.c | 31 +++++++-------
drivers/scsi/mpt3sas/mpt3sas_transport.c | 31 +++++++-------
drivers/staging/zram/zram_drv.c | 19 ++++-----
fs/bio-integrity.c | 30 +++++++-------
fs/bio.c | 16 ++++----
include/linux/bio.h | 25 ++++++------
include/linux/blkdev.h | 7 ++--
mm/bounce.c | 44 ++++++++++----------
33 files changed, 349 insertions(+), 344 deletions(-)
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 9070d6c..d2b260c 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -62,17 +62,18 @@ struct nfhd_device {
static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
{
struct nfhd_device *dev = queue->queuedata;
- struct bio_vec *bvec;
- int i, dir, len, shift;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+ int dir, len, shift;
sector_t sec = bio->bi_iter.bi_sector;
dir = bio_data_dir(bio);
shift = dev->bshift;
- bio_for_each_segment(bvec, bio, i) {
- len = bvec->bv_len;
+ bio_for_each_segment(bvec, bio, iter) {
+ len = bvec.bv_len;
len >>= 9;
nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
- bvec_to_phys(bvec));
+ bvec_to_phys(&bvec));
sec += len;
}
bio_endio(bio, 0);
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index f33bcba..47b6b9f 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -109,28 +109,28 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data;
unsigned long phys_mem, phys_end;
void *user_mem;
- struct bio_vec *vec;
+ struct bio_vec vec;
unsigned int transfered;
- unsigned short idx;
+ struct bvec_iter iter;
phys_mem = bank->io_addr + (bio->bi_iter.bi_sector <<
AXON_RAM_SECTOR_SHIFT);
phys_end = bank->io_addr + bank->size;
transfered = 0;
- bio_for_each_segment(vec, bio, idx) {
- if (unlikely(phys_mem + vec->bv_len > phys_end)) {
+ bio_for_each_segment(vec, bio, iter) {
+ if (unlikely(phys_mem + vec.bv_len > phys_end)) {
bio_io_error(bio);
return;
}
- user_mem = page_address(vec->bv_page) + vec->bv_offset;
+ user_mem = page_address(vec.bv_page) + vec.bv_offset;
if (bio_data_dir(bio) == READ)
- memcpy(user_mem, (void *) phys_mem, vec->bv_len);
+ memcpy(user_mem, (void *) phys_mem, vec.bv_len);
else
- memcpy((void *) phys_mem, user_mem, vec->bv_len);
+ memcpy((void *) phys_mem, user_mem, vec.bv_len);
- phys_mem += vec->bv_len;
- transfered += vec->bv_len;
+ phys_mem += vec.bv_len;
+ transfered += vec.bv_len;
}
bio_endio(bio, 0);
}
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 7750b25..8940562 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -12,10 +12,11 @@
static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
struct bio *bio)
{
- struct bio_vec *bv, *bvprv = NULL;
- int cluster, i, high, highprv = 1;
+ struct bio_vec bv, bvprv;
+ int cluster, high, highprv = 1;
unsigned int seg_size, nr_phys_segs;
struct bio *fbio, *bbio;
+ struct bvec_iter iter;
if (!bio)
return 0;
@@ -25,25 +26,25 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
seg_size = 0;
nr_phys_segs = 0;
for_each_bio(bio) {
- bio_for_each_segment(bv, bio, i) {
+ bio_for_each_segment(bv, bio, iter) {
/*
* the trick here is making sure that a high page is
* never considered part of another segment, since that
* might change with the bounce page.
*/
- high = page_to_pfn(bv->bv_page) > queue_bounce_pfn(q);
+ high = page_to_pfn(bv.bv_page) > queue_bounce_pfn(q);
if (high || highprv)
goto new_segment;
if (cluster) {
- if (seg_size + bv->bv_len
+ if (seg_size + bv.bv_len
> queue_max_segment_size(q))
goto new_segment;
- if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
+ if (!BIOVEC_PHYS_MERGEABLE(&bvprv, &bv))
goto new_segment;
- if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
+ if (!BIOVEC_SEG_BOUNDARY(q, &bvprv, &bv))
goto new_segment;
- seg_size += bv->bv_len;
+ seg_size += bv.bv_len;
bvprv = bv;
continue;
}
@@ -54,7 +55,7 @@ new_segment:
nr_phys_segs++;
bvprv = bv;
- seg_size = bv->bv_len;
+ seg_size = bv.bv_len;
highprv = high;
}
bbio = bio;
@@ -110,21 +111,21 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
return 0;
}
-static void
+static inline void
__blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
- struct scatterlist *sglist, struct bio_vec **bvprv,
+ struct scatterlist *sglist, struct bio_vec *bvprv,
struct scatterlist **sg, int *nsegs, int *cluster)
{
int nbytes = bvec->bv_len;
- if (*bvprv && *cluster) {
+ if (*sg && *cluster) {
if ((*sg)->length + nbytes > queue_max_segment_size(q))
goto new_segment;
- if (!BIOVEC_PHYS_MERGEABLE(*bvprv, bvec))
+ if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
goto new_segment;
- if (!BIOVEC_SEG_BOUNDARY(q, *bvprv, bvec))
+ if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
goto new_segment;
(*sg)->length += nbytes;
@@ -150,7 +151,7 @@ new_segment:
sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset);
(*nsegs)++;
}
- *bvprv = bvec;
+ *bvprv = *bvec;
}
/*
@@ -160,7 +161,7 @@ new_segment:
int blk_rq_map_sg(struct request_queue *q, struct request *rq,
struct scatterlist *sglist)
{
- struct bio_vec *bvec, *bvprv;
+ struct bio_vec bvec, bvprv;
struct req_iterator iter;
struct scatterlist *sg;
int nsegs, cluster;
@@ -171,10 +172,9 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
/*
* for each bio in rq
*/
- bvprv = NULL;
sg = NULL;
rq_for_each_segment(bvec, rq, iter) {
- __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+ __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
&nsegs, &cluster);
} /* segments in rq */
@@ -223,18 +223,17 @@ EXPORT_SYMBOL(blk_rq_map_sg);
int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
struct scatterlist *sglist)
{
- struct bio_vec *bvec, *bvprv;
+ struct bio_vec bvec, bvprv;
struct scatterlist *sg;
int nsegs, cluster;
- unsigned long i;
+ struct bvec_iter iter;
nsegs = 0;
cluster = blk_queue_cluster(q);
- bvprv = NULL;
sg = NULL;
- bio_for_each_segment(bvec, bio, i) {
- __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
+ bio_for_each_segment(bvec, bio, iter) {
+ __blk_segment_map_sg(q, &bvec, sglist, &bvprv, &sg,
&nsegs, &cluster);
} /* segments in bio */
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 1fb2d6d..a52975a 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -888,12 +888,12 @@ rqbiocnt(struct request *r)
static void
bio_pageinc(struct bio *bio)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
struct page *page;
- int i;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i) {
- page = bv->bv_page;
+ bio_for_each_segment(bv, bio, iter) {
+ page = bv.bv_page;
/* Non-zero page count for non-head members of
* compound pages is no longer allowed by the kernel,
* but this has never been seen here.
@@ -910,11 +910,11 @@ bio_pageinc(struct bio *bio)
static void
bio_pagedec(struct bio *bio)
{
- struct bio_vec *bv;
- int i;
+ struct bio_vec bv;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i)
- atomic_dec(&bv->bv_page->_count);
+ bio_for_each_segment(bv, bio, iter)
+ atomic_dec(&bv.bv_page->_count);
}
static void
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index e269532..0395a3f 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -328,9 +328,9 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
struct block_device *bdev = bio->bi_bdev;
struct brd_device *brd = bdev->bd_disk->private_data;
int rw;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
sector_t sector;
- int i;
+ struct bvec_iter iter;
int err = -EIO;
sector = bio->bi_iter.bi_sector;
@@ -347,10 +347,10 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
if (rw == READA)
rw = READ;
- bio_for_each_segment(bvec, bio, i) {
- unsigned int len = bvec->bv_len;
- err = brd_do_bvec(brd, bvec->bv_page, len,
- bvec->bv_offset, rw, sector);
+ bio_for_each_segment(bvec, bio, iter) {
+ unsigned int len = bvec.bv_len;
+ err = brd_do_bvec(brd, bvec.bv_page, len,
+ bvec.bv_offset, rw, sector);
if (err)
break;
sector += len >> SECTOR_SHIFT;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a5dca6a..30b0f91 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1537,15 +1537,17 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page,
static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
{
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+
/* hint all but last page with MSG_MORE */
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_no_send_page(mdev, bvec->bv_page,
- bvec->bv_offset, bvec->bv_len,
- i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+ err = _drbd_no_send_page(mdev, bvec.bv_page,
+ bvec.bv_offset, bvec.bv_len,
+ bio_iter_last(bio, iter)
+ ? 0 : MSG_MORE);
if (err)
return err;
}
@@ -1554,15 +1556,16 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio)
static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
{
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
+
/* hint all but last page with MSG_MORE */
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int err;
- err = _drbd_send_page(mdev, bvec->bv_page,
- bvec->bv_offset, bvec->bv_len,
- i == bio->bi_vcnt - 1 ? 0 : MSG_MORE);
+ err = _drbd_send_page(mdev, bvec.bv_page,
+ bvec.bv_offset, bvec.bv_len,
+ bio_iter_last(bio, iter) ? 0 : MSG_MORE);
if (err)
return err;
}
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index c342f93..2c92af4 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1595,9 +1595,10 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size)
static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
sector_t sector, int data_size)
{
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct bio *bio;
- int dgs, err, i, expect;
+ int dgs, err, expect;
void *dig_in = mdev->tconn->int_dig_in;
void *dig_vv = mdev->tconn->int_dig_vv;
@@ -1617,11 +1618,11 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req,
bio = req->master_bio;
D_ASSERT(sector == bio->bi_iter.bi_sector);
- bio_for_each_segment(bvec, bio, i) {
- void *mapped = kmap(bvec->bv_page) + bvec->bv_offset;
- expect = min_t(int, data_size, bvec->bv_len);
+ bio_for_each_segment(bvec, bio, iter) {
+ void *mapped = kmap(bvec.bv_page) + bvec.bv_offset;
+ expect = min_t(int, data_size, bvec.bv_len);
err = drbd_recv_all_warn(mdev->tconn, mapped, expect);
- kunmap(bvec->bv_page);
+ kunmap(bvec.bv_page);
if (err)
return err;
data_size -= expect;
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 891c0ec..84d3175 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -313,8 +313,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
{
struct hash_desc desc;
struct scatterlist sg;
- struct bio_vec *bvec;
- int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
desc.tfm = tfm;
desc.flags = 0;
@@ -322,8 +322,8 @@ void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *
sg_init_table(&sg, 1);
crypto_hash_init(&desc);
- bio_for_each_segment(bvec, bio, i) {
- sg_set_page(&sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset);
+ bio_for_each_segment(bvec, bio, iter) {
+ sg_set_page(&sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
crypto_hash_update(&desc, &sg, sg.length);
}
crypto_hash_final(&desc, digest);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index bf7b8b2..f312e06 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2351,7 +2351,7 @@ static void rw_interrupt(void)
/* Compute maximal contiguous buffer size. */
static int buffer_chain_size(void)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
int size;
struct req_iterator iter;
char *base;
@@ -2360,10 +2360,10 @@ static int buffer_chain_size(void)
size = 0;
rq_for_each_segment(bv, current_req, iter) {
- if (page_address(bv->bv_page) + bv->bv_offset != base + size)
+ if (page_address(bv.bv_page) + bv.bv_offset != base + size)
break;
- size += bv->bv_len;
+ size += bv.bv_len;
}
return size >> 9;
@@ -2389,7 +2389,7 @@ static int transfer_size(int ssize, int max_sector, int max_size)
static void copy_buffer(int ssize, int max_sector, int max_sector_2)
{
int remaining; /* number of transferred 512-byte sectors */
- struct bio_vec *bv;
+ struct bio_vec bv;
char *buffer;
char *dma_buffer;
int size;
@@ -2427,10 +2427,10 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
if (!remaining)
break;
- size = bv->bv_len;
+ size = bv.bv_len;
SUPBOUND(size, remaining);
- buffer = page_address(bv->bv_page) + bv->bv_offset;
+ buffer = page_address(bv.bv_page) + bv.bv_offset;
if (dma_buffer + size >
floppy_track_buffer + (max_buffer_sectors << 10) ||
dma_buffer < floppy_track_buffer) {
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 3df42e6..c41f188 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -288,9 +288,10 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
{
int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,
struct page *page);
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct page *page = NULL;
- int i, ret = 0;
+ int ret = 0;
if (lo->transfer != transfer_none) {
page = alloc_page(GFP_NOIO | __GFP_HIGHMEM);
@@ -302,11 +303,11 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)
do_lo_send = do_lo_send_direct_write;
}
- bio_for_each_segment(bvec, bio, i) {
- ret = do_lo_send(lo, bvec, pos, page);
+ bio_for_each_segment(bvec, bio, iter) {
+ ret = do_lo_send(lo, &bvec, pos, page);
if (ret < 0)
break;
- pos += bvec->bv_len;
+ pos += bvec.bv_len;
}
if (page) {
kunmap(page);
@@ -392,20 +393,20 @@ do_lo_receive(struct loop_device *lo,
static int
lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
{
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
ssize_t s;
- int i;
- bio_for_each_segment(bvec, bio, i) {
- s = do_lo_receive(lo, bvec, bsize, pos);
+ bio_for_each_segment(bvec, bio, iter) {
+ s = do_lo_receive(lo, &bvec, bsize, pos);
if (s < 0)
return s;
- if (s != bvec->bv_len) {
+ if (s != bvec.bv_len) {
zero_fill_bio(bio);
break;
}
- pos += bvec->bv_len;
+ pos += bvec.bv_len;
}
return 0;
}
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 8d6729c..9fd1751 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3862,7 +3862,8 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
{
struct driver_data *dd = queue->queuedata;
struct scatterlist *sg;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
int nents = 0;
int tag = 0, unaligned = 0;
@@ -3922,11 +3923,11 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
}
/* Create the scatter list for this bio. */
- bio_for_each_segment(bvec, bio, nents) {
- sg_set_page(&sg[nents],
- bvec->bv_page,
- bvec->bv_len,
- bvec->bv_offset);
+ bio_for_each_segment(bvec, bio, iter) {
+ sg_set_page(&sg[nents++],
+ bvec.bv_page,
+ bvec.bv_len,
+ bvec.bv_offset);
}
/* Issue the read/write. */
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 037288e..b446f50 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -271,7 +271,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
if (nbd_cmd(req) == NBD_CMD_WRITE) {
struct req_iterator iter;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
/*
* we are really probing at internals to determine
* whether to set MSG_MORE or not...
@@ -281,8 +281,8 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
if (!rq_iter_last(req, iter))
flags = MSG_MORE;
dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n",
- nbd->disk->disk_name, req, bvec->bv_len);
- result = sock_send_bvec(nbd, bvec, flags);
+ nbd->disk->disk_name, req, bvec.bv_len);
+ result = sock_send_bvec(nbd, &bvec, flags);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk),
"Send data failed (result %d)\n",
@@ -378,10 +378,10 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
nbd->disk->disk_name, req);
if (nbd_cmd(req) == NBD_CMD_READ) {
struct req_iterator iter;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
rq_for_each_segment(bvec, req, iter) {
- result = sock_recv_bvec(nbd, bvec);
+ result = sock_recv_bvec(nbd, &bvec);
if (result <= 0) {
dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
result);
@@ -389,7 +389,7 @@ static struct request *nbd_read_stat(struct nbd_device *nbd)
return req;
}
dprintk(DBG_RX, "%s: request %p: got %d bytes data\n",
- nbd->disk->disk_name, req, bvec->bv_len);
+ nbd->disk->disk_name, req, bvec.bv_len);
}
}
return req;
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index c80d308..e4f2c37 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -517,9 +517,11 @@ static int nvme_split_and_submit(struct bio *bio, struct nvme_queue *nvmeq,
static int nvme_map_bio(struct nvme_queue *nvmeq, struct nvme_iod *iod,
struct bio *bio, enum dma_data_direction dma_dir, int psegs)
{
- struct bio_vec *bvec, *bvprv = NULL;
+ struct bio_vec bvec, bvprv;
+ struct bvec_iter iter;
struct scatterlist *sg = NULL;
- int i, length = 0, nsegs = 0, split_len = bio->bi_iter.bi_size;
+ int length = 0, nsegs = 0, split_len = bio->bi_iter.bi_size;
+ int first = 1;
if (nvmeq->dev->stripe_size)
split_len = nvmeq->dev->stripe_size -
@@ -527,25 +529,28 @@ static int nvme_map_bio(struct nvme_queue *nvmeq, struct nvme_iod *iod,
(nvmeq->dev->stripe_size - 1));
sg_init_table(iod->sg, psegs);
- bio_for_each_segment(bvec, bio, i) {
- if (bvprv && BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) {
- sg->length += bvec->bv_len;
+ bio_for_each_segment(bvec, bio, iter) {
+ if (!first && BIOVEC_PHYS_MERGEABLE(&bvprv, &bvec)) {
+ sg->length += bvec.bv_len;
} else {
- if (bvprv && BIOVEC_NOT_VIRT_MERGEABLE(bvprv, bvec))
- return nvme_split_and_submit(bio, nvmeq, i,
- length, 0);
+ if (!first && BIOVEC_NOT_VIRT_MERGEABLE(&bvprv, &bvec))
+ return nvme_split_and_submit(bio, nvmeq,
+ iter.bi_idx,
+ length, 0);
sg = sg ? sg + 1 : iod->sg;
- sg_set_page(sg, bvec->bv_page, bvec->bv_len,
- bvec->bv_offset);
+ sg_set_page(sg, bvec.bv_page,
+ bvec.bv_len, bvec.bv_offset);
nsegs++;
}
- if (split_len - length < bvec->bv_len)
- return nvme_split_and_submit(bio, nvmeq, i, split_len,
- split_len - length);
- length += bvec->bv_len;
+ if (split_len - length < bvec.bv_len)
+ return nvme_split_and_submit(bio, nvmeq, iter.bi_idx,
+ split_len,
+ split_len - length);
+ length += bvec.bv_len;
bvprv = bvec;
+ first = 0;
}
iod->nents = nsegs;
sg_mark_end(sg);
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 06a2e53..e473c2e 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -555,14 +555,14 @@ static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
const char *op = write ? "write" : "read";
loff_t offset = bio->bi_sector << 9;
int error = 0;
- struct bio_vec *bvec;
- unsigned int i;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
struct bio *next;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
/* PS3 is ppc64, so we don't handle highmem */
- char *ptr = page_address(bvec->bv_page) + bvec->bv_offset;
- size_t len = bvec->bv_len, retlen;
+ char *ptr = page_address(bvec.bv_page) + bvec.bv_offset;
+ size_t len = bvec.bv_len, retlen;
dev_dbg(&dev->core, " %s %zu bytes at offset %llu\n", op,
len, offset);
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index ce7b1aa..2a27dca 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1108,22 +1108,22 @@ static void bio_chain_put(struct bio *chain)
*/
static void zero_bio_chain(struct bio *chain, int start_ofs)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
unsigned long flags;
void *buf;
- int i;
int pos = 0;
while (chain) {
- bio_for_each_segment(bv, chain, i) {
- if (pos + bv->bv_len > start_ofs) {
+ bio_for_each_segment(bv, chain, iter) {
+ if (pos + bv.bv_len > start_ofs) {
int remainder = max(start_ofs - pos, 0);
- buf = bvec_kmap_irq(bv, &flags);
+ buf = bvec_kmap_irq(&bv, &flags);
memset(buf + remainder, 0,
- bv->bv_len - remainder);
+ bv.bv_len - remainder);
bvec_kunmap_irq(buf, &flags);
}
- pos += bv->bv_len;
+ pos += bv.bv_len;
}
chain = chain->bi_next;
@@ -1170,11 +1170,11 @@ static struct bio *bio_clone_range(struct bio *bio_src,
unsigned int len,
gfp_t gfpmask)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
+ struct bvec_iter end_iter;
unsigned int resid;
- unsigned short idx;
unsigned int voff;
- unsigned short end_idx;
unsigned short vcnt;
struct bio *bio;
@@ -1193,22 +1193,22 @@ static struct bio *bio_clone_range(struct bio *bio_src,
/* Find first affected segment... */
resid = offset;
- bio_for_each_segment(bv, bio_src, idx) {
- if (resid < bv->bv_len)
+ bio_for_each_segment(bv, bio_src, iter) {
+ if (resid < bv.bv_len)
break;
- resid -= bv->bv_len;
+ resid -= bv.bv_len;
}
voff = resid;
/* ...and the last affected segment */
resid += len;
- __bio_for_each_segment(bv, bio_src, end_idx, idx) {
- if (resid <= bv->bv_len)
+ __bio_for_each_segment(bv, bio_src, end_iter, iter) {
+ if (resid <= bv.bv_len)
break;
- resid -= bv->bv_len;
+ resid -= bv.bv_len;
}
- vcnt = end_idx - idx + 1;
+ vcnt = end_iter.bi_idx = iter.bi_idx + 1;
/* Build the clone */
@@ -1226,7 +1226,7 @@ static struct bio *bio_clone_range(struct bio *bio_src,
* Copy over our part of the bio_vec, then update the first
* and last (or only) entries.
*/
- memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[idx],
+ memcpy(&bio->bi_io_vec[0], &bio_src->bi_io_vec[iter.bi_idx],
vcnt * sizeof (struct bio_vec));
bio->bi_io_vec[0].bv_offset += voff;
if (vcnt > 1) {
diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c
index c9bba8b..ac3fa93 100644
--- a/drivers/block/rsxx/dma.c
+++ b/drivers/block/rsxx/dma.c
@@ -630,7 +630,8 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
void *cb_data)
{
struct list_head dma_list[RSXX_MAX_TARGETS];
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned long long addr8;
unsigned int laddr;
unsigned int bv_len;
@@ -668,9 +669,9 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
bv_len -= RSXX_HW_BLK_SIZE;
}
} else {
- bio_for_each_segment(bvec, bio, i) {
- bv_len = bvec->bv_len;
- bv_off = bvec->bv_offset;
+ bio_for_each_segment(bvec, bio, iter) {
+ bv_len = bvec.bv_len;
+ bv_off = bvec.bv_offset;
while (bv_len > 0) {
tgt = rsxx_get_dma_tgt(card, addr8);
@@ -682,7 +683,7 @@ int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
st = rsxx_queue_dma(card, &dma_list[tgt],
bio_data_dir(bio),
dma_off, dma_len,
- laddr, bvec->bv_page,
+ laddr, bvec.bv_page,
bv_off, cb, cb_data);
if (st)
goto bvec_err;
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index d89ef86..eed3987 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -867,7 +867,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
struct blkif_response *bret)
{
int i = 0;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
struct req_iterator iter;
unsigned long flags;
char *bvec_data;
@@ -882,18 +882,18 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
* to be sure we are copying the data from the right shared page.
*/
rq_for_each_segment(bvec, s->request, iter) {
- BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE);
- if (bvec->bv_offset < offset)
+ BUG_ON((bvec.bv_offset + bvec.bv_len) > PAGE_SIZE);
+ if (bvec.bv_offset < offset)
i++;
BUG_ON(i >= s->req.u.rw.nr_segments);
shared_data = kmap_atomic(
pfn_to_page(s->grants_used[i]->pfn));
- bvec_data = bvec_kmap_irq(bvec, &flags);
- memcpy(bvec_data, shared_data + bvec->bv_offset,
- bvec->bv_len);
+ bvec_data = bvec_kmap_irq(&bvec, &flags);
+ memcpy(bvec_data, shared_data + bvec.bv_offset,
+ bvec.bv_len);
bvec_kunmap_irq(bvec_data, &flags);
kunmap_atomic(shared_data);
- offset = bvec->bv_offset + bvec->bv_len;
+ offset = bvec.bv_offset + bvec.bv_len;
}
}
/* Add the persistent grant into the list of free grants */
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index d43f480..b6c3a05 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -310,7 +310,7 @@ static void btree_write_done(struct closure *cl)
struct bio_vec *bv;
int n;
- __bio_for_each_segment(bv, b->bio, n, 0)
+ bio_for_each_segment_all(bv, b->bio, n)
__free_page(bv->bv_page);
__btree_write_done(cl);
@@ -338,7 +338,7 @@ static void do_btree_write(struct btree *b)
struct bio_vec *bv;
void *base = (void *) ((unsigned long) i & ~(PAGE_SIZE - 1));
- bio_for_each_segment(bv, b->bio, j)
+ bio_for_each_segment_all(bv, b->bio, j)
memcpy(page_address(bv->bv_page),
base + j * PAGE_SIZE, PAGE_SIZE);
diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c
index 4bc7c14..2077848 100644
--- a/drivers/md/bcache/debug.c
+++ b/drivers/md/bcache/debug.c
@@ -189,7 +189,8 @@ void bch_data_verify(struct search *s)
struct cached_dev *dc = container_of(s->d, struct cached_dev, disk);
struct closure *cl = &s->cl;
struct bio *check;
- struct bio_vec *bv;
+ struct bio_vec bv, *bv2;
+ struct bvec_iter iter;
int i;
check = bio_clone(s->orig_bio, GFP_NOIO);
@@ -206,24 +207,24 @@ void bch_data_verify(struct search *s)
closure_bio_submit(check, cl, &dc->disk);
closure_sync(cl);
- bio_for_each_segment(bv, s->orig_bio, i) {
- void *p1 = kmap(bv->bv_page);
- void *p2 = kmap(check->bi_io_vec[i].bv_page);
+ bio_for_each_segment(bv, s->orig_bio, iter) {
+ void *p1 = kmap(bv.bv_page);
+ void *p2 = kmap(check->bi_io_vec[iter.bi_idx].bv_page);
- if (memcmp(p1 + bv->bv_offset,
- p2 + bv->bv_offset,
- bv->bv_len))
+ if (memcmp(p1 + bv.bv_offset,
+ p2 + bv.bv_offset,
+ bv.bv_len))
printk(KERN_ERR
"bcache (%s): verify failed at sector %llu\n",
bdevname(dc->bdev, name),
(uint64_t) s->orig_bio->bi_iter.bi_sector);
- kunmap(bv->bv_page);
- kunmap(check->bi_io_vec[i].bv_page);
+ kunmap(bv.bv_page);
+ kunmap(check->bi_io_vec[iter.bi_idx].bv_page);
}
- __bio_for_each_segment(bv, check, i, 0)
- __free_page(bv->bv_page);
+ bio_for_each_segment_all(bv2, check, i)
+ __free_page(bv2->bv_page);
out_put:
bio_put(check);
}
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index 13580e5..da198da 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -20,12 +20,12 @@ static void bch_bi_idx_hack_endio(struct bio *bio, int error)
static void bch_generic_make_request_hack(struct bio *bio)
{
if (bio->bi_iter.bi_idx) {
- int i;
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
struct bio *clone = bio_alloc(GFP_NOIO, bio_segments(bio));
- bio_for_each_segment(bv, bio, i)
- clone->bi_io_vec[clone->bi_vcnt++] = *bv;
+ bio_for_each_segment(bv, bio, iter)
+ clone->bi_io_vec[clone->bi_vcnt++] = bv;
clone->bi_iter.bi_sector = bio->bi_iter.bi_sector;
clone->bi_bdev = bio->bi_bdev;
@@ -71,8 +71,9 @@ static void bch_generic_make_request_hack(struct bio *bio)
struct bio *bch_bio_split(struct bio *bio, int sectors,
gfp_t gfp, struct bio_set *bs)
{
- unsigned idx = bio->bi_iter.bi_idx, vcnt = 0, nbytes = sectors << 9;
- struct bio_vec *bv;
+ unsigned vcnt = 0, nbytes = sectors << 9;
+ struct bio_vec bv;
+ struct bvec_iter iter;
struct bio *ret = NULL;
BUG_ON(sectors <= 0);
@@ -82,49 +83,35 @@ struct bio *bch_bio_split(struct bio *bio, int sectors,
if (bio->bi_rw & REQ_DISCARD) {
ret = bio_alloc_bioset(gfp, 1, bs);
- idx = 0;
goto out;
}
- bio_for_each_segment(bv, bio, idx) {
- vcnt = idx - bio->bi_iter.bi_idx;
+ bio_for_each_segment(bv, bio, iter) {
+ vcnt++;
- if (!nbytes) {
- ret = bio_alloc_bioset(gfp, vcnt, bs);
- if (!ret)
- return NULL;
+ if (nbytes <= bv.bv_len)
+ break;
- memcpy(ret->bi_io_vec, __bio_iovec(bio),
- sizeof(struct bio_vec) * vcnt);
+ nbytes -= bv.bv_len;
+ }
- break;
- } else if (nbytes < bv->bv_len) {
- ret = bio_alloc_bioset(gfp, ++vcnt, bs);
- if (!ret)
- return NULL;
+ ret = bio_alloc_bioset(gfp, vcnt, bs);
+ if (!ret)
+ return NULL;
- memcpy(ret->bi_io_vec, __bio_iovec(bio),
- sizeof(struct bio_vec) * vcnt);
+ bio_for_each_segment(bv, bio, iter) {
+ ret->bi_io_vec[ret->bi_vcnt++] = bv;
- ret->bi_io_vec[vcnt - 1].bv_len = nbytes;
- bv->bv_offset += nbytes;
- bv->bv_len -= nbytes;
+ if (ret->bi_vcnt == vcnt)
break;
- }
-
- nbytes -= bv->bv_len;
}
+
+ ret->bi_io_vec[ret->bi_vcnt - 1].bv_len = nbytes;
out:
ret->bi_bdev = bio->bi_bdev;
ret->bi_iter.bi_sector = bio->bi_iter.bi_sector;
ret->bi_iter.bi_size = sectors << 9;
ret->bi_rw = bio->bi_rw;
- ret->bi_vcnt = vcnt;
- ret->bi_max_vecs = vcnt;
-
- bio->bi_iter.bi_sector += sectors;
- bio->bi_iter.bi_size -= sectors << 9;
- bio->bi_iter.bi_idx = idx;
if (bio_integrity(bio)) {
if (bio_integrity_clone(ret, bio, gfp)) {
@@ -133,9 +120,10 @@ out:
}
bio_integrity_trim(ret, 0, bio_sectors(ret));
- bio_integrity_trim(bio, bio_sectors(ret), bio_sectors(bio));
}
+ bio_advance(bio, ret->bi_iter.bi_size);
+
return ret;
}
@@ -151,12 +139,13 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
if (bio_segments(bio) > max_segments ||
q->merge_bvec_fn) {
- struct bio_vec *bv;
- int i, seg = 0;
+ struct bio_vec bv;
+ struct bvec_iter iter;
+ unsigned seg = 0;
ret = 0;
- bio_for_each_segment(bv, bio, i) {
+ bio_for_each_segment(bv, bio, iter) {
struct bvec_merge_data bvm = {
.bi_bdev = bio->bi_bdev,
.bi_sector = bio->bi_iter.bi_sector,
@@ -168,11 +157,11 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
break;
if (q->merge_bvec_fn &&
- q->merge_bvec_fn(q, &bvm, bv) < (int) bv->bv_len)
+ q->merge_bvec_fn(q, &bvm, &bv) < (int) bv.bv_len)
break;
seg++;
- ret += bv->bv_len >> 9;
+ ret += bv.bv_len >> 9;
}
}
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 6360df5..b0de7a43 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -199,14 +199,14 @@ static bool verify(struct cached_dev *dc, struct bio *bio)
static void bio_csum(struct bio *bio, struct bkey *k)
{
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
uint64_t csum = 0;
- int i;
- bio_for_each_segment(bv, bio, i) {
- void *d = kmap(bv->bv_page) + bv->bv_offset;
- csum = bch_crc64_update(csum, d, bv->bv_len);
- kunmap(bv->bv_page);
+ bio_for_each_segment(bv, bio, iter) {
+ void *d = kmap(bv.bv_page) + bv.bv_offset;
+ csum = bch_crc64_update(csum, d, bv.bv_len);
+ kunmap(bv.bv_page);
}
k->ptr[KEY_PTRS(k)] = csum & (~0ULL >> 1);
@@ -757,7 +757,7 @@ static void cached_dev_read_complete(struct closure *cl)
int i;
struct bio_vec *bv;
- __bio_for_each_segment(bv, s->op.cache_bio, i, 0)
+ bio_for_each_segment_all(bv, s->op.cache_bio, i)
__free_page(bv->bv_page);
}
@@ -1224,17 +1224,17 @@ void bch_cached_dev_request_init(struct cached_dev *dc)
static int flash_dev_cache_miss(struct btree *b, struct search *s,
struct bio *bio, unsigned sectors)
{
- struct bio_vec *bv;
- int i;
+ struct bio_vec bv;
+ struct bvec_iter iter;
/* Zero fill bio */
- bio_for_each_segment(bv, bio, i) {
- unsigned j = min(bv->bv_len >> 9, sectors);
+ bio_for_each_segment(bv, bio, iter) {
+ unsigned j = min(bv.bv_len >> 9, sectors);
- void *p = kmap(bv->bv_page);
- memset(p + bv->bv_offset, 0, j << 9);
- kunmap(bv->bv_page);
+ void *p = kmap(bv.bv_page);
+ memset(p + bv.bv_offset, 0, j << 9);
+ kunmap(bv.bv_page);
sectors -= j;
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 38464ce..1ed2426 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -189,8 +189,8 @@ void md_trim_bio(struct bio *bio, int offset, int size)
* the given offset and size.
* This requires adjusting bi_sector, bi_size, and bi_io_vec
*/
- int i;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
int sofar = 0;
size <<= 9;
@@ -212,14 +212,14 @@ void md_trim_bio(struct bio *bio, int offset, int size)
bio->bi_iter.bi_idx = 0;
}
/* Make sure vcnt and last bv are not too big */
- bio_for_each_segment(bvec, bio, i) {
- if (sofar + bvec->bv_len > size)
- bvec->bv_len = size - sofar;
- if (bvec->bv_len == 0) {
- bio->bi_vcnt = i;
+ bio_for_each_segment(bvec, bio, iter) {
+ if (sofar + bvec.bv_len > size)
+ bvec.bv_len = size - sofar;
+ if (bvec.bv_len == 0) {
+ bio->bi_vcnt = iter.bi_idx;
break;
}
- sofar += bvec->bv_len;
+ sofar += bvec.bv_len;
}
}
EXPORT_SYMBOL_GPL(md_trim_bio);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 1b87468..a54eb37 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -725,9 +725,9 @@ static struct dma_async_tx_descriptor *
async_copy_data(int frombio, struct bio *bio, struct page *page,
sector_t sector, struct dma_async_tx_descriptor *tx)
{
- struct bio_vec *bvl;
+ struct bio_vec bvl;
+ struct bvec_iter iter;
struct page *bio_page;
- int i;
int page_offset;
struct async_submit_ctl submit;
enum async_tx_flags flags = 0;
@@ -741,8 +741,8 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
flags |= ASYNC_TX_FENCE;
init_async_submit(&submit, flags, tx, NULL, NULL, NULL);
- bio_for_each_segment(bvl, bio, i) {
- int len = bvl->bv_len;
+ bio_for_each_segment(bvl, bio, iter) {
+ int len = bvl.bv_len;
int clen;
int b_offset = 0;
@@ -758,8 +758,8 @@ async_copy_data(int frombio, struct bio *bio, struct page *page,
clen = len;
if (clen > 0) {
- b_offset += bvl->bv_offset;
- bio_page = bvl->bv_page;
+ b_offset += bvl.bv_offset;
+ bio_page = bvl.bv_page;
if (frombio)
tx = async_memcpy(page, bio_page, page_offset,
b_offset, clen, &submit);
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 16814a8..7fef1f9 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -808,12 +808,12 @@ static void
dcssblk_make_request(struct request_queue *q, struct bio *bio)
{
struct dcssblk_dev_info *dev_info;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned long index;
unsigned long page_addr;
unsigned long source_addr;
unsigned long bytes_done;
- int i;
bytes_done = 0;
dev_info = bio->bi_bdev->bd_disk->private_data;
@@ -844,21 +844,21 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
}
index = (bio->bi_iter.bi_sector >> 3);
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
page_addr = (unsigned long)
- page_address(bvec->bv_page) + bvec->bv_offset;
+ page_address(bvec.bv_page) + bvec.bv_offset;
source_addr = dev_info->start + (index<<12) + bytes_done;
if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0)
// More paranoia.
goto fail;
if (bio_data_dir(bio) == READ) {
memcpy((void*)page_addr, (void*)source_addr,
- bvec->bv_len);
+ bvec.bv_len);
} else {
memcpy((void*)source_addr, (void*)page_addr,
- bvec->bv_len);
+ bvec.bv_len);
}
- bytes_done += bvec->bv_len;
+ bytes_done += bvec.bv_len;
}
bio_endio(bio, 0);
return;
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index dd4e73f..3e530f9 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -184,11 +184,11 @@ static unsigned long xpram_highest_page_index(void)
static void xpram_make_request(struct request_queue *q, struct bio *bio)
{
xpram_device_t *xdev = bio->bi_bdev->bd_disk->private_data;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
unsigned int index;
unsigned long page_addr;
unsigned long bytes;
- int i;
if ((bio->bi_iter.bi_sector & 7) != 0 ||
(bio->bi_iter.bi_size & 4095) != 0)
@@ -200,10 +200,10 @@ static void xpram_make_request(struct request_queue *q, struct bio *bio)
if ((bio->bi_iter.bi_sector >> 3) > 0xffffffffU - xdev->offset)
goto fail;
index = (bio->bi_iter.bi_sector >> 3) + xdev->offset;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
page_addr = (unsigned long)
- kmap(bvec->bv_page) + bvec->bv_offset;
- bytes = bvec->bv_len;
+ kmap(bvec.bv_page) + bvec.bv_offset;
+ bytes = bvec.bv_len;
if ((page_addr & 4095) != 0 || (bytes & 4095) != 0)
/* More paranoia. */
goto fail;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 193e7ae..2c2e01e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -1898,7 +1898,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
Mpi2SmpPassthroughRequest_t *mpi_request;
Mpi2SmpPassthroughReply_t *mpi_reply;
- int rc, i;
+ int rc;
u16 smid;
u32 ioc_state;
unsigned long timeleft;
@@ -1913,7 +1913,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
void *pci_addr_out = NULL;
u16 wait_state_count;
struct request *rsp = req->next_rq;
- struct bio_vec *bvec = NULL;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
if (!rsp) {
printk(MPT2SAS_ERR_FMT "%s: the smp response space is "
@@ -1952,11 +1953,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
goto out;
}
- bio_for_each_segment(bvec, req->bio, i) {
+ bio_for_each_segment(bvec, req->bio, iter) {
memcpy(pci_addr_out + offset,
- page_address(bvec->bv_page) + bvec->bv_offset,
- bvec->bv_len);
- offset += bvec->bv_len;
+ page_address(bvec.bv_page) + bvec.bv_offset,
+ bvec.bv_len);
+ offset += bvec.bv_len;
}
} else {
dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -2103,19 +2104,19 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
u32 offset = 0;
u32 bytes_to_copy =
le16_to_cpu(mpi_reply->ResponseDataLength);
- bio_for_each_segment(bvec, rsp->bio, i) {
- if (bytes_to_copy <= bvec->bv_len) {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
+ bio_for_each_segment(bvec, rsp->bio, iter) {
+ if (bytes_to_copy <= bvec.bv_len) {
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
offset, bytes_to_copy);
break;
} else {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
- offset, bvec->bv_len);
- bytes_to_copy -= bvec->bv_len;
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
+ offset, bvec.bv_len);
+ bytes_to_copy -= bvec.bv_len;
}
- offset += bvec->bv_len;
+ offset += bvec.bv_len;
}
}
} else {
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index 87ca2b7..dd15b2d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -1881,7 +1881,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
Mpi2SmpPassthroughRequest_t *mpi_request;
Mpi2SmpPassthroughReply_t *mpi_reply;
- int rc, i;
+ int rc;
u16 smid;
u32 ioc_state;
unsigned long timeleft;
@@ -1895,7 +1895,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
void *pci_addr_out = NULL;
u16 wait_state_count;
struct request *rsp = req->next_rq;
- struct bio_vec *bvec = NULL;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
if (!rsp) {
pr_err(MPT3SAS_FMT "%s: the smp response space is missing\n",
@@ -1935,11 +1936,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
goto out;
}
- bio_for_each_segment(bvec, req->bio, i) {
+ bio_for_each_segment(bvec, req->bio, iter) {
memcpy(pci_addr_out + offset,
- page_address(bvec->bv_page) + bvec->bv_offset,
- bvec->bv_len);
- offset += bvec->bv_len;
+ page_address(bvec.bv_page) + bvec.bv_offset,
+ bvec.bv_len);
+ offset += bvec.bv_len;
}
} else {
dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio),
@@ -2064,19 +2065,19 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
u32 offset = 0;
u32 bytes_to_copy =
le16_to_cpu(mpi_reply->ResponseDataLength);
- bio_for_each_segment(bvec, rsp->bio, i) {
- if (bytes_to_copy <= bvec->bv_len) {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
+ bio_for_each_segment(bvec, rsp->bio, iter) {
+ if (bytes_to_copy <= bvec.bv_len) {
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
offset, bytes_to_copy);
break;
} else {
- memcpy(page_address(bvec->bv_page) +
- bvec->bv_offset, pci_addr_in +
- offset, bvec->bv_len);
- bytes_to_copy -= bvec->bv_len;
+ memcpy(page_address(bvec.bv_page) +
+ bvec.bv_offset, pci_addr_in +
+ offset, bvec.bv_len);
+ bytes_to_copy -= bvec.bv_len;
}
- offset += bvec->bv_len;
+ offset += bvec.bv_len;
}
}
} else {
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 7680d53..9a45129 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -364,9 +364,10 @@ static void update_position(u32 *index, int *offset, struct bio_vec *bvec)
static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
{
- int i, offset;
+ int offset;
u32 index;
- struct bio_vec *bvec;
+ struct bio_vec bvec;
+ struct bvec_iter iter;
switch (rw) {
case READ:
@@ -381,33 +382,33 @@ static void __zram_make_request(struct zram *zram, struct bio *bio, int rw)
offset = (bio->bi_iter.bi_sector &
(SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
- bio_for_each_segment(bvec, bio, i) {
+ bio_for_each_segment(bvec, bio, iter) {
int max_transfer_size = PAGE_SIZE - offset;
- if (bvec->bv_len > max_transfer_size) {
+ if (bvec.bv_len > max_transfer_size) {
/*
* zram_bvec_rw() can only make operation on a single
* zram page. Split the bio vector.
*/
struct bio_vec bv;
- bv.bv_page = bvec->bv_page;
+ bv.bv_page = bvec.bv_page;
bv.bv_len = max_transfer_size;
- bv.bv_offset = bvec->bv_offset;
+ bv.bv_offset = bvec.bv_offset;
if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0)
goto out;
- bv.bv_len = bvec->bv_len - max_transfer_size;
+ bv.bv_len = bvec.bv_len - max_transfer_size;
bv.bv_offset += max_transfer_size;
if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0)
goto out;
} else
- if (zram_bvec_rw(zram, bvec, index, offset, bio, rw)
+ if (zram_bvec_rw(zram, &bvec, index, offset, bio, rw)
< 0)
goto out;
- update_position(&index, &offset, bvec);
+ update_position(&index, &offset, &bvec);
}
set_bit(BIO_UPTODATE, &bio->bi_flags);
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index f824c30..4220b96 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -299,25 +299,26 @@ static void bio_integrity_generate(struct bio *bio)
{
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
struct blk_integrity_exchg bix;
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
sector_t sector = bio->bi_iter.bi_sector;
- unsigned int i, sectors, total;
+ unsigned int sectors, total;
void *prot_buf = bio->bi_integrity->bip_buf;
total = 0;
bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
bix.sector_size = bi->sector_size;
- bio_for_each_segment(bv, bio, i) {
- void *kaddr = kmap_atomic(bv->bv_page);
- bix.data_buf = kaddr + bv->bv_offset;
- bix.data_size = bv->bv_len;
+ bio_for_each_segment(bv, bio, iter) {
+ void *kaddr = kmap_atomic(bv.bv_page);
+ bix.data_buf = kaddr + bv.bv_offset;
+ bix.data_size = bv.bv_len;
bix.prot_buf = prot_buf;
bix.sector = sector;
bi->generate_fn(&bix);
- sectors = bv->bv_len / bi->sector_size;
+ sectors = bv.bv_len / bi->sector_size;
sector += sectors;
prot_buf += sectors * bi->tuple_size;
total += sectors * bi->tuple_size;
@@ -441,19 +442,20 @@ static int bio_integrity_verify(struct bio *bio)
{
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
struct blk_integrity_exchg bix;
- struct bio_vec *bv;
+ struct bio_vec bv;
+ struct bvec_iter iter;
sector_t sector = bio->bi_integrity->bip_sector;
- unsigned int i, sectors, total, ret;
+ unsigned int sectors, total, ret;
void *prot_buf = bio->bi_integrity->bip_buf;
ret = total = 0;
bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
bix.sector_size = bi->sector_size;
- bio_for_each_segment(bv, bio, i) {
- void *kaddr = kmap_atomic(bv->bv_page);
- bix.data_buf = kaddr + bv->bv_offset;
- bix.data_size = bv->bv_len;
+ bio_for_each_segment(bv, bio, iter) {
+ void *kaddr = kmap_atomic(bv.bv_page);
+ bix.data_buf = kaddr + bv.bv_offset;
+ bix.data_size = bv.bv_len;
bix.prot_buf = prot_buf;
bix.sector = sector;
@@ -464,7 +466,7 @@ static int bio_integrity_verify(struct bio *bio)
return ret;
}
- sectors = bv->bv_len / bi->sector_size;
+ sectors = bv.bv_len / bi->sector_size;
sector += sectors;
prot_buf += sectors * bi->tuple_size;
total += sectors * bi->tuple_size;
diff --git a/fs/bio.c b/fs/bio.c
index f1e7c68..018e3a8 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -473,13 +473,13 @@ EXPORT_SYMBOL(bio_alloc_bioset);
void zero_fill_bio(struct bio *bio)
{
unsigned long flags;
- struct bio_vec *bv;
- int i;
+ struct bio_vec bv;
+ struct bvec_iter iter;
- bio_for_each_segment(bv, bio, i) {
- char *data = bvec_kmap_irq(bv, &flags);
- memset(data, 0, bv->bv_len);
- flush_dcache_page(bv->bv_page);
+ bio_for_each_segment(bv, bio, iter) {
+ char *data = bvec_kmap_irq(&bv, &flags);
+ memset(data, 0, bv.bv_len);
+ flush_dcache_page(bv.bv_page);
bvec_kunmap_irq(data, &flags);
}
}
@@ -1677,10 +1677,10 @@ void bio_check_pages_dirty(struct bio *bio)
#if ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
void bio_flush_dcache_pages(struct bio *bi)
{
- int i;
struct bio_vec *bvec;
+ struct bvec_iter iter;
- bio_for_each_segment(bvec, bi, i)
+ bio_for_each_segment(bvec, bi, iter)
flush_dcache_page(bvec->bv_page);
}
EXPORT_SYMBOL(bio_flush_dcache_pages);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 580c9ae..a31bcd2 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -61,6 +61,8 @@
* various member access, note that bio_data should of course not be used
* on highmem page vectors
*/
+#define bio_iovec_iter(bio, iter) ((bio)->bi_io_vec[(iter).bi_idx])
+
#define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(idx)]))
#define __bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_iter.bi_idx)
#define bio_iovec(bio) (*__bio_iovec(bio))
@@ -134,15 +136,6 @@ static inline void *bio_data(struct bio *bio)
#define bio_io_error(bio) bio_endio((bio), -EIO)
/*
- * drivers should not use the __ version unless they _really_ know what
- * they're doing
- */
-#define __bio_for_each_segment(bvl, bio, i, start_idx) \
- for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx); \
- i < (bio)->bi_vcnt; \
- bvl++, i++)
-
-/*
* drivers should _never_ use the all version - the bio may have been split
* before it got to the driver and the driver won't own all of it
*/
@@ -151,10 +144,16 @@ static inline void *bio_data(struct bio *bio)
bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \
i++)
-#define bio_for_each_segment(bvl, bio, i) \
- for (i = (bio)->bi_iter.bi_idx; \
- bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \
- i++)
+#define __bio_for_each_segment(bvl, bio, iter, start) \
+ for (iter = (start); \
+ bvl = bio_iovec_iter((bio), (iter)), \
+ (iter).bi_idx < (bio)->bi_vcnt; \
+ (iter).bi_idx++)
+
+#define bio_for_each_segment(bvl, bio, iter) \
+ __bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)
+
+#define bio_iter_last(bio, iter) ((iter).bi_idx == (bio)->bi_vcnt - 1)
/*
* get a reference to a bio, so it won't disappear. the intended use is
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2fdb4a4..1b9d47b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -699,7 +699,7 @@ struct rq_map_data {
};
struct req_iterator {
- int i;
+ struct bvec_iter iter;
struct bio *bio;
};
@@ -712,10 +712,11 @@ struct req_iterator {
#define rq_for_each_segment(bvl, _rq, _iter) \
__rq_for_each_bio(_iter.bio, _rq) \
- bio_for_each_segment(bvl, _iter.bio, _iter.i)
+ bio_for_each_segment(bvl, _iter.bio, _iter.iter)
#define rq_iter_last(rq, _iter) \
- (_iter.bio->bi_next == NULL && _iter.i == _iter.bio->bi_vcnt-1)
+ (_iter.bio->bi_next == NULL && \
+ bio_iter_last(_iter.bio, _iter.iter))
#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
# error "You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform"
diff --git a/mm/bounce.c b/mm/bounce.c
index c9f0a43..4525e3d 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -98,27 +98,24 @@ int init_emergency_isa_pool(void)
static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
{
unsigned char *vfrom;
- struct bio_vec *tovec, *fromvec;
- int i;
-
- bio_for_each_segment(tovec, to, i) {
- fromvec = from->bi_io_vec + i;
-
- /*
- * not bounced
- */
- if (tovec->bv_page == fromvec->bv_page)
- continue;
-
- /*
- * fromvec->bv_offset and fromvec->bv_len might have been
- * modified by the block layer, so use the original copy,
- * bounce_copy_vec already uses tovec->bv_len
- */
- vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;
+ struct bio_vec tovec, *fromvec = from->bi_io_vec;
+ struct bvec_iter iter;
+
+ bio_for_each_segment(tovec, to, iter) {
+ if (tovec.bv_page != fromvec->bv_page) {
+ /*
+ * fromvec->bv_offset and fromvec->bv_len might have
+ * been modified by the block layer, so use the original
+ * copy, bounce_copy_vec already uses tovec->bv_len
+ */
+ vfrom = page_address(fromvec->bv_page) +
+ tovec.bv_offset;
+
+ bounce_copy_vec(&tovec, vfrom);
+ flush_dcache_page(tovec.bv_page);
+ }
- bounce_copy_vec(tovec, vfrom);
- flush_dcache_page(tovec->bv_page);
+ fromvec++;
}
}
@@ -201,11 +198,12 @@ static void __blk_queue_bounce(struct request_queue *q, struct bio **bio_orig,
{
struct bio *bio;
int rw = bio_data_dir(*bio_orig);
- struct bio_vec *to, *from;
+ struct bio_vec *to, from;
+ struct bvec_iter iter;
unsigned i;
- bio_for_each_segment(from, *bio_orig, i)
- if (page_to_pfn(from->bv_page) > queue_bounce_pfn(q))
+ bio_for_each_segment(from, *bio_orig, iter)
+ if (page_to_pfn(from.bv_page) > queue_bounce_pfn(q))
goto bounce;
return;
--
1.8.3.rc1
^ permalink raw reply related
* Re: [BUG] PCI related panic on powerpc based board with 3.10-rcX
From: Michael Guntsche @ 2013-06-08 19:39 UTC (permalink / raw)
To: linux-kernel; +Cc: Rojhalat Ibrahim, linuxppc-dev
After bisecting I found the responsible commit.
50d8f87d2b3: powerpc/fsl-pci Make PCIe hotplug work with Freescale
PCIe controllers
Reverting this commit allowed my board to boot again.
@Rojhalat: Please have a look at
http://marc.info/?l=linux-kernel&m=137071294204858&w=2
for my initial bugreport.
What I do not understand at all is why this is affecting my platform.
AFAIK there is no PCIe hardware on it AND I completely disabled PCIe
support in config.
Kind regards,
Mike
^ permalink raw reply
* [BUG] PCI related panic on powerpc based board with 3.10-rcX
From: Michael Guntsche @ 2013-06-08 17:30 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 4118 bytes --]
Good evening,
I recently tested the latest 3.10-rc release (rc4) on my powerpc based routerboard which is currently running very stable on a 3.9 release.
During boot I immediately got a kernel panic.
I was able to get a log of the trace with the serial console.
[ 0.039522] PCI: Probing PCI hardware
[ 0.043159] PCI: Memory resource 0 not set for host bridge /pci@e0008500 (domain 0)
[ 0.050778] PCI: Memory resource 0 not set for host bridge /pci@e0008500 (domain 0)
[ 0.058855] PCI host bridge to bus 0000:00
[ 0.062938] pci_bus 0000:00: root bus resource [io 0x0000-0xffffff]
[ 0.069255] pci_bus 0000:00: root bus resource [mem 0x80000000-0x9fffffff]
[ 0.076131] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 0.081639] Unable to handle kernel paging request for data at address 0x00000f14
[ 0.089068] Faulting instruction address: 0xc0014d40
[ 0.094031] Oops: Kernel access of bad area, sig: 11 [#1]
[ 0.099420] MikroTik RouterBOARD 600 series
[ 0.103597] Modules linked in:
[ 0.106651] CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.0-rc1+ #15
[ 0.112910] task: c782e000 ti: c7834000 task.ti: c7834000
[ 0.118303] NIP: c0014d40 LR: c0014dd8 CTR: c0014e10
[ 0.123262] REGS: c7835b40 TRAP: 0300 Not tainted (3.10.0-rc1+)
[ 0.129435] MSR: 00001032 <ME,IR,DR,RI> CR: 22000084 XER: 20000000
[ 0.135788] DAR: 00000f14, DSISR: 20000000
[ 0.139875]
GPR00: c0014e40 c7835bf0 c782e000 c0417000 00000000 00000000 00000004 00000000
GPR08: 00000000 00000000 00000000 00000037 22000084 00000000 c0003e90 00000000
GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000045
GPR24: c0400000 c03f0000 c036134c c782de00 00000000 0000ea60 c782de00 c0417000
[ 0.169567] NIP [c0014d40] fsl_pcie_check_link.part.4+0x8/0x2c
[ 0.175380] LR [c0014dd8] fsl_pcie_check_link+0x74/0xac
[ 0.180591] Call Trace:
[ 0.183033] [c7835bf0] [00000025] 0x25 (unreliable)
[ 0.187909] [c7835d80] [c0014e40] fsl_indirect_read_config+0x30/0x8c
[ 0.194270] [c7835da0] [c019c108] pci_bus_read_config_dword+0x60/0x80
[ 0.200703] [c7835dc0] [c019df3c] pci_bus_read_dev_vendor_id+0x34/0x108
[ 0.207321] [c7835df0] [c022d394] pci_scan_single_device+0x58/0xc8
[ 0.213488] [c7835e20] [c019f068] pci_scan_slot+0x54/0x110
[ 0.218969] [c7835e40] [c019fc40] pci_scan_child_bus+0x28/0xdc
[ 0.224811] [c7835e60] [c0010aa4] pcibios_scan_phb+0x19c/0x210
[ 0.230640] [c7835e90] [c03b4658] pcibios_init+0x7c/0x114
[ 0.236025] [c7835ec0] [c00039a4] do_one_initcall+0x150/0x1a4
[ 0.241763] [c7835ef0] [c03b1888] kernel_init_freeable+0x114/0x1bc
[ 0.247938] [c7835f30] [c0003ea8] kernel_init+0x18/0x110
[ 0.253247] [c7835f40] [c000e098] ret_from_kernel_thread+0x64/0x6c
[ 0.259417] --- Exception: 0 at (null)
[ 0.259417] LR = (null)
[ 0.266287] Instruction dump:
[ 0.269246] 3d400006 614a0400 915f0028 3d40c040 912afc88 80010024 83e1001c 38210020
[ 0.276988] 7c0803a6 4e800020 812300ec 7c0004ac <80690f14> 0c030000 4c00012c 5463f6be
[ 0.284945] ---[ end trace 074b946a523243d5 ]---
Compare this to booting with 3.9
[ 0.039088] PCI: Probing PCI hardware
[ 0.043151] PCI host bridge to bus 0000:00
[ 0.047232] pci_bus 0000:00: root bus resource [io 0x0000-0xffffff]
[ 0.053546] pci_bus 0000:00: root bus resource [mem 0x80000000-0x9fffffff]
[ 0.060419] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 0.068080] pci 0000:00:0d.0: BAR 0: assigned [mem 0x80000000-0x8000ffff]
[ 0.074854] pci 0000:00:0b.0: BAR 0: assigned [io 0x1000-0x10ff]
[ 0.080908] pci 0000:00:0b.0: BAR 1: assigned [mem 0x80010000-0x800100ff]
[ 0.103986] bio: create slab <bio-0> at 0
[ 0.108589] Freescale Elo / Elo Plus DMA driver
[ 0.115166] SCSI subsystem initialized
Especially I do not understand why this message shows up now
PCI: Memory resource 0 not set for host bridge
Does someone have an idea what's happening here?
I tested this also on rc1 and got the same panic there.
Please CC me on any replies since I am not subscribed to the list.
Thank you very much in advance,
Michael Guntsche
[-- Attachment #2: Type: text/html, Size: 5630 bytes --]
^ permalink raw reply
* Re: [PATCH -V7 09/18] powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format
From: Aneesh Kumar K.V @ 2013-06-08 16:57 UTC (permalink / raw)
To: Scott Wood; +Cc: linux-mm, paulus, linuxppc-dev, dwg
In-Reply-To: <1370632664.6813.10@snotra>
Scott Wood <scottwood@freescale.com> writes:
> On 06/06/2013 10:55:22 PM, Aneesh Kumar K.V wrote:
>> Scott Wood <scottwood@freescale.com> writes:
>>
>> > On 04/28/2013 02:37:30 PM, Aneesh Kumar K.V wrote:
>> >> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>> >>
>> >> We will be switching PMD_SHIFT to 24 bits to facilitate THP
.....
>> >>
>> >> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
>> >> ---
>> >> arch/powerpc/include/asm/page.h | 2 +
>> >> arch/powerpc/include/asm/pgtable.h | 2 +
>> >> arch/powerpc/mm/gup.c | 18 +++-
>> >> arch/powerpc/mm/hugetlbpage.c | 176
>> >> +++++++++++++++++++++++++++++++------
>> >> 4 files changed, 168 insertions(+), 30 deletions(-)
>> >
>> > After this patch, on 64-bit book3e (e5500, and thus 4K pages), I see
>> > messages like this after exiting a program that uses hugepages
>> > (specifically, qemu):
>> >
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221516.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221516.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc2214d6.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc2214d6.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221916.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221916.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc2218d6.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc2218d6.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221496.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221496.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221856.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221856.
>> > /home/scott/fsl/git/linux/upstream/mm/memory.c:407: bad pmd
>> > 40000001fc221816.
>>
>> hmm that implies some of the code paths are not properly #ifdef.
>> The goal was to limit the new format CONFIG_PPC_BOOK3S_64 as seen in
>> the
>> definition of huge_pte_alloc. Can you send me the .config ?
>
> Attached.
>
>
That didn't give much hint on why we are finding bad pmd. One of the
reason for finding bad pmd is we are finding hugepd with the new format,
ie, bottom two bits == 00, next 4 bits indicate size of table, but use
the old functions to check whether it is hugepd
static inline int hugepd_ok(hugepd_t hpd)
{
return (hpd.pd > 0);
}
Can you check the intermediate file generated and verify that the
huge_pte_alloc is doing the right thing. All the new changes should be
limitted to book3s 64. Hence boo3e should all work as before.
With the config shared I am not finding anything wrong, but I can't test
these configs. Also can you confirm what you bisect this to
e2b3d202d1dba8f3546ed28224ce485bc50010be
powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format
or
cf9427b85e90bb1ff90e2397ff419691d983c68b "powerpc: New hugepage directory format"
-aneesh
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox