From feeb8283a593e780234c025edb1134e73696400d Mon Sep 17 00:00:00 2001 From: Caroline Newcombe Date: Fri, 19 Nov 2021 14:29:32 -0600 Subject: [PATCH] Fix unsafe read during final iteration of zsymv_L_sse2.S --- kernel/x86_64/zsymv_L_sse2.S | 16 +++++++-- test_zhemv.c | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 test_zhemv.c diff --git a/kernel/x86_64/zsymv_L_sse2.S b/kernel/x86_64/zsymv_L_sse2.S index cba167f..bfe0cf7 100644 --- a/kernel/x86_64/zsymv_L_sse2.S +++ b/kernel/x86_64/zsymv_L_sse2.S @@ -451,7 +451,6 @@ #endif MOVDDUP(4 * SIZE, A1, a1) - MOVDDUP(6 * SIZE, A2, a2) movsd 0 * SIZE(YY), yy1 movhpd 1 * SIZE(YY), yy1 @@ -471,7 +470,9 @@ subq IS, I subq $2, I sarq $2, I - jle .L15 + jle .L14 + + MOVDDUP(6 * SIZE - (4 * SIZE), A2, a2) ALIGN_3 .L12: @@ -632,6 +633,16 @@ jg .L12 ALIGN_3 +.L14: + movq M, I + subq IS, I + subq $2, I + testq $2, I + jle .L16 + + MOVDDUP(6 * SIZE - (4 * SIZE), A2, a2) + jmp .L15_pastcheck + .L15: movq M, I subq IS, I @@ -639,6 +650,7 @@ testq $2, I jle .L16 +.L15_pastcheck: movapd xtemp1, xt1 mulpd a1, xt1 mulpd atemp1, a1 diff --git a/test_zhemv.c b/test_zhemv.c new file mode 100644 index 0000000..6b3df5f --- /dev/null +++ b/test_zhemv.c @@ -0,0 +1,85 @@ +// reproduce segfault in zhemv() from zsymv_L_sse2.S +// + +#include +#include +#include +#include +#include +#include + +#define CALL_ZHEMV zhemv_ + +void zhemv_(char *UPLO, int *N, double *alpha, double *A, int *LDA, + double *X, int *INCX, double *beta, double *Y, int *INCY); + +int main () { + + // zhemv parameters + char uplo = 'L'; + int n = 14; + int lda = 16; + int incx = 1; + int incy = 1; + double *A, *X, *Y; + double alpha[] = {1, 0}; + double beta[] = {0, 0}; + + // other parameters + int i, j; + double *data, *data_end, *no_access; + double real, imag; + int size; + size_t len; + int A_offset; + + size = sizeof(complex double); + len = lda * lda * size; + + // allocate memory for data + // use mmap address hints to set up inaccessible memory section following data + no_access = mmap(NULL, len, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + data = mmap(no_access, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + data_end = data + (lda * lda * 2); + printf("data start/end: %p/%p. Blocked region starts at %p.\n", data, data_end, no_access); + + // set up pointer offsets into data + A_offset = (lda + 1) * 2; + A = data + A_offset * 2; // A starts in the third column of data matrix + X = data + A_offset + 2; // X is the second column of data matrix + Y = (double *)malloc(n * incy * size); // Y is stored elsewhere + printf("Address of data: %p; A: %p; X: %p; Y: %p.\n", data, A, X, Y); + + + // hermitian matrix + srand(lda); + for (j=0; j