From c5e57685f9a6ae8af823728812ae3be7741f83e4 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sun, 20 Sep 2015 10:20:42 +0100 Subject: [PATCH] Fix emulation of various instructions, required by libm in F22 ppc64 guests. --- ...cipher-vcipherlast-vncipherlast-and-.patch | 98 +++++++++++++++++++ ...c-fix-xscmpodp-and-xscmpudp-decoding.patch | 53 ++++++++++ qemu.spec | 8 +- 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 0001-target-ppc-fix-vcipher-vcipherlast-vncipherlast-and-.patch create mode 100644 0002-target-ppc-fix-xscmpodp-and-xscmpudp-decoding.patch diff --git a/0001-target-ppc-fix-vcipher-vcipherlast-vncipherlast-and-.patch b/0001-target-ppc-fix-vcipher-vcipherlast-vncipherlast-and-.patch new file mode 100644 index 0000000..2b099a4 --- /dev/null +++ b/0001-target-ppc-fix-vcipher-vcipherlast-vncipherlast-and-.patch @@ -0,0 +1,98 @@ +From d233fc09d20fa24f6ee03f8505333d73f559eacf Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sun, 13 Sep 2015 23:03:44 +0200 +Subject: [PATCH 1/2] target-ppc: fix vcipher, vcipherlast, vncipherlast and + vpermxor + +For vector instructions, the helpers get pointers to the vector register +in arguments. Some operands might point to the same register, including +the operand holding the result. + +When emulating instructions which access the vector elements in a +non-linear way, we need to store the result in an temporary variable. + +This fixes openssl when emulating a POWER8 CPU. + +Cc: Tom Musta +Cc: Alexander Graf +Cc: qemu-stable@nongnu.org +Signed-off-by: Aurelien Jarno +--- + target-ppc/int_helper.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c +index 0a55d5e..b122868 100644 +--- a/target-ppc/int_helper.c ++++ b/target-ppc/int_helper.c +@@ -2327,24 +2327,28 @@ void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a) + + void helper_vcipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) + { ++ ppc_avr_t result; + int i; + + VECTOR_FOR_INORDER_I(i, u32) { +- r->AVRW(i) = b->AVRW(i) ^ ++ result.AVRW(i) = b->AVRW(i) ^ + (AES_Te0[a->AVRB(AES_shifts[4*i + 0])] ^ + AES_Te1[a->AVRB(AES_shifts[4*i + 1])] ^ + AES_Te2[a->AVRB(AES_shifts[4*i + 2])] ^ + AES_Te3[a->AVRB(AES_shifts[4*i + 3])]); + } ++ *r = result; + } + + void helper_vcipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) + { ++ ppc_avr_t result; + int i; + + VECTOR_FOR_INORDER_I(i, u8) { +- r->AVRB(i) = b->AVRB(i) ^ (AES_sbox[a->AVRB(AES_shifts[i])]); ++ result.AVRB(i) = b->AVRB(i) ^ (AES_sbox[a->AVRB(AES_shifts[i])]); + } ++ *r = result; + } + + void helper_vncipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +@@ -2369,11 +2373,13 @@ void helper_vncipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) + + void helper_vncipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) + { ++ ppc_avr_t result; + int i; + + VECTOR_FOR_INORDER_I(i, u8) { +- r->AVRB(i) = b->AVRB(i) ^ (AES_isbox[a->AVRB(AES_ishifts[i])]); ++ result.AVRB(i) = b->AVRB(i) ^ (AES_isbox[a->AVRB(AES_ishifts[i])]); + } ++ *r = result; + } + + #define ROTRu32(v, n) (((v) >> (n)) | ((v) << (32-n))) +@@ -2460,16 +2466,19 @@ void helper_vshasigmad(ppc_avr_t *r, ppc_avr_t *a, uint32_t st_six) + + void helper_vpermxor(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) + { ++ ppc_avr_t result; + int i; ++ + VECTOR_FOR_INORDER_I(i, u8) { + int indexA = c->u8[i] >> 4; + int indexB = c->u8[i] & 0xF; + #if defined(HOST_WORDS_BIGENDIAN) +- r->u8[i] = a->u8[indexA] ^ b->u8[indexB]; ++ result.u8[i] = a->u8[indexA] ^ b->u8[indexB]; + #else +- r->u8[i] = a->u8[15-indexA] ^ b->u8[15-indexB]; ++ result.u8[i] = a->u8[15-indexA] ^ b->u8[15-indexB]; + #endif + } ++ *r = result; + } + + #undef VECTOR_FOR_INORDER_I +-- +2.5.0 + diff --git a/0002-target-ppc-fix-xscmpodp-and-xscmpudp-decoding.patch b/0002-target-ppc-fix-xscmpodp-and-xscmpudp-decoding.patch new file mode 100644 index 0000000..94e7b83 --- /dev/null +++ b/0002-target-ppc-fix-xscmpodp-and-xscmpudp-decoding.patch @@ -0,0 +1,53 @@ +From d539a02e18916c558985f26cf37af1e83851d9fd Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sun, 13 Sep 2015 23:03:45 +0200 +Subject: [PATCH 2/2] target-ppc: fix xscmpodp and xscmpudp decoding + +The xscmpodp and xscmpudp instructions only have the AX, BX bits in +there encoding, the lowest bit (usually TX) is marked as an invalid +bit. We therefore can't decode them with GEN_XX2FORM, which decodes +the two lowest bit. + +Introduce a new form GEN_XX2FORM, which decodes AX and BX and mark +the lowest bit as invalid. + +Cc: Tom Musta +Cc: Alexander Graf +Cc: qemu-stable@nongnu.org +Signed-off-by: Aurelien Jarno +--- + target-ppc/translate.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/target-ppc/translate.c b/target-ppc/translate.c +index 84c5cea..c0eed13 100644 +--- a/target-ppc/translate.c ++++ b/target-ppc/translate.c +@@ -10670,6 +10670,13 @@ GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2), \ + GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \ + GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2) + ++#undef GEN_XX2IFORM ++#define GEN_XX2IFORM(name, opc2, opc3, fl2) \ ++GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 1, PPC_NONE, fl2), \ ++GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 1, PPC_NONE, fl2), \ ++GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 1, PPC_NONE, fl2), \ ++GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 1, PPC_NONE, fl2) ++ + #undef GEN_XX3_RC_FORM + #define GEN_XX3_RC_FORM(name, opc2, opc3, fl2) \ + GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x00, 0, PPC_NONE, fl2), \ +@@ -10731,8 +10738,8 @@ GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX), + GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX), + GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX), + GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX), +-GEN_XX2FORM(xscmpodp, 0x0C, 0x05, PPC2_VSX), +-GEN_XX2FORM(xscmpudp, 0x0C, 0x04, PPC2_VSX), ++GEN_XX2IFORM(xscmpodp, 0x0C, 0x05, PPC2_VSX), ++GEN_XX2IFORM(xscmpudp, 0x0C, 0x04, PPC2_VSX), + GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX), + GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX), + GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX), +-- +2.5.0 + diff --git a/qemu.spec b/qemu.spec index 0bc40bc..1e7d1f8 100644 --- a/qemu.spec +++ b/qemu.spec @@ -40,7 +40,7 @@ Summary: QEMU is a FAST! processor emulator Name: qemu Version: 2.4.0 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD Group: Development/Tools @@ -72,6 +72,9 @@ Source13: qemu-kvm.sh # (bz #1255899) Patch0001: 0001-vnc-fix-memory-corruption-CVE-2015-5225.patch +# Fix emulation of various instructions, required by libm in F22 ppc64 guests. +Patch0002: 0001-target-ppc-fix-vcipher-vcipherlast-vncipherlast-and-.patch +Patch0003: 0002-target-ppc-fix-xscmpodp-and-xscmpudp-decoding.patch BuildRequires: SDL2-devel BuildRequires: zlib-devel @@ -1204,6 +1207,9 @@ getent passwd qemu >/dev/null || \ %changelog +* Sun Sep 20 2015 Richard W.M. Jones - 2:2.4.0-3 +- Fix emulation of various instructions, required by libm in F22 ppc64 guests. + * Mon Aug 31 2015 Cole Robinson - 2:2.4.0-2 - CVE-2015-5255: heap memory corruption in vnc_refresh_server_surface (bz #1255899)