@@ -145,7 +145,10 @@ vec_strcpy:
145145 mr DMS,SMD // IU1 |dst - src| = src - dst
146146Pos_value:
147147 subf. QBC,DST,ADD // IU1 Bytes to even QW start of vect (min 32)
148- addi ADD,DD,PAGE_SIZE // IU1 dst addr in next 4K page
148+ addi ADD,SRC,PAGE_SIZE // IU1 SRC addr in next 4K page (loads fault on
149+ // the SOURCE, so guard the source's page,
150+ // not the dest's -- else an unmapped page
151+ // just past src faults while dst is mid-page)
149152 cmpi cr7,0,DMS,MIN_VEC // IU1 Check for min byte count separation
150153
151154 mtctr QBC // IU2 Init counter
@@ -171,7 +174,12 @@ v_strcpy:
171174#ifdef VRSAVE
172175 mfspr RSV,VRSV // IU2 Get current VRSAVE contents
173176#endif
174- subf. PBC,DD,ADD // IU1 Now bytes to next 4K page
177+ rlwinm Rt,DS,0,0,27 // IU1 Align src down to QW first: lvx loads are
178+ // 16-aligned (use DS&~15), so an unaligned
179+ // (rg-DS)/16 rounds to 0 and New_page_0 then
180+ // loads a whole page past the src page end
181+ subf. PBC,Rt,ADD // IU1 QW-exact bytes from aligned src to its 4K
182+ // page boundary (loads fault on SRC, not dest)
175183
176184#ifdef VRSAVE
177185 oris Rt,RSV,0xff00 // IU1 Or in registers used by this routine
0 commit comments