已合并
Automatically generate code patches with openeuler #132
zhendongchen创建于 2020年9月24日
Automatically generate code patches with openeuler #132
已合并
从refs/pull/132/head合入到openEuler-20.03-LTS
共 8 个文件变更+806-1
| @@ -0,0 +1,40 @@ | |||
| 1 | +From d65a00000e56ee2cec2f506b1408128d2df56ad9 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Mauro Matteo Cascella <mcascell@redhat.com> | ||
| 3 | +Date: Sat, 1 Aug 2020 18:42:38 +0200 | ||
| 4 | +Subject: [PATCH] hw/net/net_tx_pkt: fix assertion failure in | ||
| 5 | + net_tx_pkt_add_raw_fragment() | ||
| 6 | + | ||
| 7 | +An assertion failure issue was found in the code that processes network packets | ||
| 8 | +while adding data fragments into the packet context. It could be abused by a | ||
| 9 | +malicious guest to abort the QEMU process on the host. This patch replaces the | ||
| 10 | +affected assert() with a conditional statement, returning false if the current | ||
| 11 | +data fragment exceeds max_raw_frags. | ||
| 12 | + | ||
| 13 | +Reported-by: Alexander Bulekov <alxndr@bu.edu> | ||
| 14 | +Reported-by: Ziming Zhang <ezrakiez@gmail.com> | ||
| 15 | +Reviewed-by: Dmitry Fleytman <dmitry.fleytman@gmail.com> | ||
| 16 | +Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com> | ||
| 17 | +Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
| 18 | +--- | ||
| 19 | + hw/net/net_tx_pkt.c | 5 ++++- | ||
| 20 | + 1 file changed, 4 insertions(+), 1 deletion(-) | ||
| 21 | + | ||
| 22 | +diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c | ||
| 23 | +index 162f802dd7..54d4c3bbd0 100644 | ||
| 24 | +--- a/hw/net/net_tx_pkt.c | ||
| 25 | ++++ b/hw/net/net_tx_pkt.c | ||
| 26 | + bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, hwaddr pa, | ||
| 27 | + hwaddr mapped_len = 0; | ||
| 28 | + struct iovec *ventry; | ||
| 29 | + assert(pkt); | ||
| 30 | +- assert(pkt->max_raw_frags > pkt->raw_frags); | ||
| 31 | ++ | ||
| 32 | ++ if (pkt->raw_frags >= pkt->max_raw_frags) { | ||
| 33 | ++ return false; | ||
| 34 | ++ } | ||
| 35 | + | ||
| 36 | + if (!len) { | ||
| 37 | + return true; | ||
| 38 | +-- | ||
| 39 | +2.23.0 | ||
| 40 | + | ||
| @@ -0,0 +1,58 @@ | |||
| 1 | +From a80a85c7c358febb164ace0dfa75c468f43e0f02 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Mauro Matteo Cascella <mcascell@redhat.com> | ||
| 3 | +Date: Fri, 10 Jul 2020 11:19:41 +0200 | ||
| 4 | +Subject: [PATCH] hw/net/xgmac: Fix buffer overflow in xgmac_enet_send() | ||
| 5 | + | ||
| 6 | +A buffer overflow issue was reported by Mr. Ziming Zhang, CC'd here. It | ||
| 7 | +occurs while sending an Ethernet frame due to missing break statements | ||
| 8 | +and improper checking of the buffer size. | ||
| 9 | + | ||
| 10 | +Reported-by: Ziming Zhang <ezrakiez@gmail.com> | ||
| 11 | +Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com> | ||
| 12 | +Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
| 13 | +Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
| 14 | +--- | ||
| 15 | + hw/net/xgmac.c | 14 ++++++++++++-- | ||
| 16 | + 1 file changed, 12 insertions(+), 2 deletions(-) | ||
| 17 | + | ||
| 18 | +diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c | ||
| 19 | +index f49df95b07..f496f7ed4c 100644 | ||
| 20 | +--- a/hw/net/xgmac.c | ||
| 21 | ++++ b/hw/net/xgmac.c | ||
| 22 | + static void xgmac_enet_send(XgmacState *s) | ||
| 23 | + } | ||
| 24 | + len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff); | ||
| 25 | + | ||
| 26 | ++ /* | ||
| 27 | ++ * FIXME: these cases of malformed tx descriptors (bad sizes) | ||
| 28 | ++ * should probably be reported back to the guest somehow | ||
| 29 | ++ * rather than simply silently stopping processing, but we | ||
| 30 | ++ * don't know what the hardware does in this situation. | ||
| 31 | ++ * This will only happen for buggy guests anyway. | ||
| 32 | ++ */ | ||
| 33 | + if ((bd.buffer1_size & 0xfff) > 2048) { | ||
| 34 | + DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- " | ||
| 35 | + "xgmac buffer 1 len on send > 2048 (0x%x)\n", | ||
| 36 | + __func__, bd.buffer1_size & 0xfff); | ||
| 37 | ++ break; | ||
| 38 | + } | ||
| 39 | + if ((bd.buffer2_size & 0xfff) != 0) { | ||
| 40 | + DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- " | ||
| 41 | + "xgmac buffer 2 len on send != 0 (0x%x)\n", | ||
| 42 | + __func__, bd.buffer2_size & 0xfff); | ||
| 43 | ++ break; | ||
| 44 | + } | ||
| 45 | +- if (len >= sizeof(frame)) { | ||
| 46 | ++ if (frame_size + len >= sizeof(frame)) { | ||
| 47 | + DEBUGF_BRK("qemu:%s: buffer overflow %d read into %zu " | ||
| 48 | +- "buffer\n" , __func__, len, sizeof(frame)); | ||
| 49 | ++ "buffer\n" , __func__, frame_size + len, sizeof(frame)); | ||
| 50 | + DEBUGF_BRK("qemu:%s: buffer1.size=%d; buffer2.size=%d\n", | ||
| 51 | + __func__, bd.buffer1_size, bd.buffer2_size); | ||
| 52 | ++ break; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + cpu_physical_memory_read(bd.buffer1_addr, ptr, len); | ||
| 56 | +-- | ||
| 57 | +2.23.0 | ||
| 58 | + | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | Name: qemu | 1 | Name: qemu |
| 2 | Version: 4.1.0 | 2 | Version: 4.1.0 |
| 3 | -Release: 21 | 3 | +Release: 22 |
| 4 | Epoch: 2 | 4 | Epoch: 2 |
| 5 | Summary: QEMU is a generic and open source machine emulator and virtualizer | 5 | Summary: QEMU is a generic and open source machine emulator and virtualizer |
| 6 | License: GPLv2 and BSD and MIT and CC-BY | 6 | License: GPLv2 and BSD and MIT and CC-BY |
| @@ -187,6 +187,13 @@ Patch0174: hw-usb-core-fix-buffer-overflow.patch | |||
| 187 | Patch0175: slirp-drop-bogus-IPv6-messages.patch | 187 | Patch0175: slirp-drop-bogus-IPv6-messages.patch |
| 188 | Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch | 188 | Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch |
| 189 | Patch0177: hw-xhci-check-return-value-of-usb_packet_map.patch | 189 | Patch0177: hw-xhci-check-return-value-of-usb_packet_map.patch |
| 190 | +Patch0178: hw-net-xgmac-Fix-buffer-overflow-in-xgmac_enet_send.patch | ||
| 191 | +Patch0179: hw-net-net_tx_pkt-fix-assertion-failure-in-net_tx_pk.patch | ||
| 192 | +Patch0180: sm501-Convert-printf-abort-to-qemu_log_mask.patch | ||
| 193 | +Patch0181: sm501-Shorten-long-variable-names-in-sm501_2d_operat.patch | ||
| 194 | +Patch0182: sm501-Use-BIT-x-macro-to-shorten-constant.patch | ||
| 195 | +Patch0183: sm501-Clean-up-local-variables-in-sm501_2d_operation.patch | ||
| 196 | +Patch0184: sm501-Replace-hand-written-implementation-with-pixma.patch | ||
| 190 | 197 | ||
| 191 | BuildRequires: flex | 198 | BuildRequires: flex |
| 192 | BuildRequires: bison | 199 | BuildRequires: bison |
| @@ -532,6 +539,15 @@ getent passwd qemu >/dev/null || \ | |||
| 532 | %endif | 539 | %endif |
| 533 | 540 | ||
| 534 | %changelog | 541 | %changelog |
| 542 | +* Thu May 21 2020 BALATON Zoltan <balaton@eik.bme.hu> | ||
| 543 | +- hw/net/xgmac: Fix buffer overflow in xgmac_enet_send() | ||
| 544 | +- hw/net/net_tx_pkt: fix assertion failure in net_tx_pkt_add_raw_fragment() | ||
| 545 | +- sm501: Convert printf + abort to qemu_log_mask | ||
| 546 | +- sm501: Shorten long variable names in sm501_2d_operation | ||
| 547 | +- sm501: Use BIT(x) macro to shorten constant | ||
| 548 | +- sm501: Clean up local variables in sm501_2d_operation | ||
| 549 | +- sm501: Replace hand written implementation with pixman where possible | ||
| 550 | + | ||
| 535 | * Thu Sep 24 2020 Huawei Technologies Co., Ltd <alex.chen@huawei.com> | 551 | * Thu Sep 24 2020 Huawei Technologies Co., Ltd <alex.chen@huawei.com> |
| 536 | - enrich commit info for some patches | 552 | - enrich commit info for some patches |
| 537 | - rename some patches for slirp | 553 | - rename some patches for slirp |
| @@ -0,0 +1,95 @@ | |||
| 1 | +From b08fddd2931fa2e3d12d2c26074835956b114d56 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 3 | +Date: Thu, 21 May 2020 21:39:44 +0200 | ||
| 4 | +Subject: [PATCH] sm501: Clean up local variables in sm501_2d_operation | ||
| 5 | +MIME-Version: 1.0 | ||
| 6 | +Content-Type: text/plain; charset=UTF-8 | ||
| 7 | +Content-Transfer-Encoding: 8bit | ||
| 8 | + | ||
| 9 | +Make variables local to the block they are used in to make it clearer | ||
| 10 | +which operation they are needed for. | ||
| 11 | + | ||
| 12 | +Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 13 | +Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
| 14 | +Message-id: ae59f8138afe7f6a5a4a82539d0f61496a906b06.1590089984.git.balaton@eik.bme.hu | ||
| 15 | +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 16 | +--- | ||
| 17 | + hw/display/sm501.c | 31 ++++++++++++++++--------------- | ||
| 18 | + 1 file changed, 16 insertions(+), 15 deletions(-) | ||
| 19 | + | ||
| 20 | +diff --git a/hw/display/sm501.c b/hw/display/sm501.c | ||
| 21 | +index f3d11d0b23..98b3b97f7b 100644 | ||
| 22 | +--- a/hw/display/sm501.c | ||
| 23 | ++++ b/hw/display/sm501.c | ||
| 24 | + static inline void hwc_invalidate(SM501State *s, int crt) | ||
| 25 | + | ||
| 26 | + static void sm501_2d_operation(SM501State *s) | ||
| 27 | + { | ||
| 28 | +- /* obtain operation parameters */ | ||
| 29 | + int cmd = (s->twoD_control >> 16) & 0x1F; | ||
| 30 | + int rtl = s->twoD_control & BIT(27); | ||
| 31 | +- int src_x = (s->twoD_source >> 16) & 0x01FFF; | ||
| 32 | +- int src_y = s->twoD_source & 0xFFFF; | ||
| 33 | +- int dst_x = (s->twoD_destination >> 16) & 0x01FFF; | ||
| 34 | +- int dst_y = s->twoD_destination & 0xFFFF; | ||
| 35 | +- int width = (s->twoD_dimension >> 16) & 0x1FFF; | ||
| 36 | +- int height = s->twoD_dimension & 0xFFFF; | ||
| 37 | +- uint32_t color = s->twoD_foreground; | ||
| 38 | + int format = (s->twoD_stretch >> 20) & 0x3; | ||
| 39 | + int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */ | ||
| 40 | + /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */ | ||
| 41 | + int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1; | ||
| 42 | + int rop = s->twoD_control & 0xFF; | ||
| 43 | +- uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; | ||
| 44 | ++ int dst_x = (s->twoD_destination >> 16) & 0x01FFF; | ||
| 45 | ++ int dst_y = s->twoD_destination & 0xFFFF; | ||
| 46 | ++ int width = (s->twoD_dimension >> 16) & 0x1FFF; | ||
| 47 | ++ int height = s->twoD_dimension & 0xFFFF; | ||
| 48 | + uint32_t dst_base = s->twoD_destination_base & 0x03FFFFFF; | ||
| 49 | +- | ||
| 50 | +- /* get frame buffer info */ | ||
| 51 | +- uint8_t *src = s->local_mem + src_base; | ||
| 52 | + uint8_t *dst = s->local_mem + dst_base; | ||
| 53 | +- int src_pitch = s->twoD_pitch & 0x1FFF; | ||
| 54 | + int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; | ||
| 55 | + int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0; | ||
| 56 | + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); | ||
| 57 | + static void sm501_2d_operation(SM501State *s) | ||
| 58 | + | ||
| 59 | + switch (cmd) { | ||
| 60 | + case 0x00: /* copy area */ | ||
| 61 | ++ { | ||
| 62 | ++ int src_x = (s->twoD_source >> 16) & 0x01FFF; | ||
| 63 | ++ int src_y = s->twoD_source & 0xFFFF; | ||
| 64 | ++ uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; | ||
| 65 | ++ uint8_t *src = s->local_mem + src_base; | ||
| 66 | ++ int src_pitch = s->twoD_pitch & 0x1FFF; | ||
| 67 | ++ | ||
| 68 | + #define COPY_AREA(_bpp, _pixel_type, rtl) { \ | ||
| 69 | + int y, x, index_d, index_s; \ | ||
| 70 | + for (y = 0; y < height; y++) { \ | ||
| 71 | + static void sm501_2d_operation(SM501State *s) | ||
| 72 | + break; | ||
| 73 | + } | ||
| 74 | + break; | ||
| 75 | +- | ||
| 76 | ++ } | ||
| 77 | + case 0x01: /* fill rectangle */ | ||
| 78 | ++ { | ||
| 79 | ++ uint32_t color = s->twoD_foreground; | ||
| 80 | ++ | ||
| 81 | + #define FILL_RECT(_bpp, _pixel_type) { \ | ||
| 82 | + int y, x; \ | ||
| 83 | + for (y = 0; y < height; y++) { \ | ||
| 84 | + static void sm501_2d_operation(SM501State *s) | ||
| 85 | + break; | ||
| 86 | + } | ||
| 87 | + break; | ||
| 88 | +- | ||
| 89 | ++ } | ||
| 90 | + default: | ||
| 91 | + qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n", | ||
| 92 | + cmd); | ||
| 93 | +-- | ||
| 94 | +2.23.0 | ||
| 95 | + | ||
| @@ -0,0 +1,159 @@ | |||
| 1 | +From c52852158aa010d534ee6d1c7a44f72ef87857a3 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 3 | +Date: Thu, 21 May 2020 21:39:44 +0200 | ||
| 4 | +Subject: [PATCH] sm501: Convert printf + abort to qemu_log_mask | ||
| 5 | +MIME-Version: 1.0 | ||
| 6 | +Content-Type: text/plain; charset=UTF-8 | ||
| 7 | +Content-Transfer-Encoding: 8bit | ||
| 8 | + | ||
| 9 | +Some places already use qemu_log_mask() to log unimplemented features | ||
| 10 | +or errors but some others have printf() then abort(). Convert these to | ||
| 11 | +qemu_log_mask() and avoid aborting to prevent guests to easily cause | ||
| 12 | +denial of service. | ||
| 13 | + | ||
| 14 | +Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 15 | +Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
| 16 | +Message-id: 305af87f59d81e92f2aaff09eb8a3603b8baa322.1590089984.git.balaton@eik.bme.hu | ||
| 17 | +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 18 | +--- | ||
| 19 | + hw/display/sm501.c | 57 ++++++++++++++++++++++------------------------ | ||
| 20 | + 1 file changed, 27 insertions(+), 30 deletions(-) | ||
| 21 | + | ||
| 22 | +diff --git a/hw/display/sm501.c b/hw/display/sm501.c | ||
| 23 | +index 5918f59b2b..aa4b202a48 100644 | ||
| 24 | +--- a/hw/display/sm501.c | ||
| 25 | ++++ b/hw/display/sm501.c | ||
| 26 | + static void sm501_2d_operation(SM501State *s) | ||
| 27 | + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); | ||
| 28 | + | ||
| 29 | + if (addressing != 0x0) { | ||
| 30 | +- printf("%s: only XY addressing is supported.\n", __func__); | ||
| 31 | +- abort(); | ||
| 32 | ++ qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n"); | ||
| 33 | ++ return; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + if (rop_mode == 0) { | ||
| 37 | + static void sm501_2d_operation(SM501State *s) | ||
| 38 | + | ||
| 39 | + if ((s->twoD_source_base & 0x08000000) || | ||
| 40 | + (s->twoD_destination_base & 0x08000000)) { | ||
| 41 | +- printf("%s: only local memory is supported.\n", __func__); | ||
| 42 | +- abort(); | ||
| 43 | ++ qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n"); | ||
| 44 | ++ return; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + switch (operation) { | ||
| 48 | + static void sm501_2d_operation(SM501State *s) | ||
| 49 | + break; | ||
| 50 | + | ||
| 51 | + default: | ||
| 52 | +- printf("non-implemented SM501 2D operation. %d\n", operation); | ||
| 53 | +- abort(); | ||
| 54 | +- break; | ||
| 55 | ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n", | ||
| 56 | ++ operation); | ||
| 57 | ++ return; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + if (dst_base >= get_fb_addr(s, crt) && | ||
| 61 | + static uint64_t sm501_system_config_read(void *opaque, hwaddr addr, | ||
| 62 | + break; | ||
| 63 | + | ||
| 64 | + default: | ||
| 65 | +- printf("sm501 system config : not implemented register read." | ||
| 66 | +- " addr=%x\n", (int)addr); | ||
| 67 | +- abort(); | ||
| 68 | ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config" | ||
| 69 | ++ "register read. addr=%" HWADDR_PRIx "\n", addr); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + return ret; | ||
| 73 | + static void sm501_system_config_write(void *opaque, hwaddr addr, | ||
| 74 | + break; | ||
| 75 | + case SM501_ENDIAN_CONTROL: | ||
| 76 | + if (value & 0x00000001) { | ||
| 77 | +- printf("sm501 system config : big endian mode not implemented.\n"); | ||
| 78 | +- abort(); | ||
| 79 | ++ qemu_log_mask(LOG_UNIMP, "sm501: system config big endian mode not" | ||
| 80 | ++ " implemented.\n"); | ||
| 81 | + } | ||
| 82 | + break; | ||
| 83 | + | ||
| 84 | + default: | ||
| 85 | +- printf("sm501 system config : not implemented register write." | ||
| 86 | +- " addr=%x, val=%x\n", (int)addr, (uint32_t)value); | ||
| 87 | +- abort(); | ||
| 88 | ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config" | ||
| 89 | ++ "register write. addr=%" HWADDR_PRIx | ||
| 90 | ++ ", val=%" PRIx64 "\n", addr, value); | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr, | ||
| 95 | + break; | ||
| 96 | + | ||
| 97 | + default: | ||
| 98 | +- printf("sm501 disp ctrl : not implemented register read." | ||
| 99 | +- " addr=%x\n", (int)addr); | ||
| 100 | +- abort(); | ||
| 101 | ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " | ||
| 102 | ++ "read. addr=%" HWADDR_PRIx "\n", addr); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + return ret; | ||
| 106 | + static void sm501_disp_ctrl_write(void *opaque, hwaddr addr, | ||
| 107 | + break; | ||
| 108 | + | ||
| 109 | + default: | ||
| 110 | +- printf("sm501 disp ctrl : not implemented register write." | ||
| 111 | +- " addr=%x, val=%x\n", (int)addr, (unsigned)value); | ||
| 112 | +- abort(); | ||
| 113 | ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " | ||
| 114 | ++ "write. addr=%" HWADDR_PRIx | ||
| 115 | ++ ", val=%" PRIx64 "\n", addr, value); | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr, | ||
| 120 | + ret = 0; /* Should return interrupt status */ | ||
| 121 | + break; | ||
| 122 | + default: | ||
| 123 | +- printf("sm501 disp ctrl : not implemented register read." | ||
| 124 | +- " addr=%x\n", (int)addr); | ||
| 125 | +- abort(); | ||
| 126 | ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " | ||
| 127 | ++ "read. addr=%" HWADDR_PRIx "\n", addr); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + return ret; | ||
| 131 | + static void sm501_2d_engine_write(void *opaque, hwaddr addr, | ||
| 132 | + /* ignored, writing 0 should clear interrupt status */ | ||
| 133 | + break; | ||
| 134 | + default: | ||
| 135 | +- printf("sm501 2d engine : not implemented register write." | ||
| 136 | +- " addr=%x, val=%x\n", (int)addr, (unsigned)value); | ||
| 137 | +- abort(); | ||
| 138 | ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2d engine register " | ||
| 139 | ++ "write. addr=%" HWADDR_PRIx | ||
| 140 | ++ ", val=%" PRIx64 "\n", addr, value); | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + static void sm501_update_display(void *opaque) | ||
| 145 | + draw_line = draw_line32_funcs[dst_depth_index]; | ||
| 146 | + break; | ||
| 147 | + default: | ||
| 148 | +- printf("sm501 update display : invalid control register value.\n"); | ||
| 149 | +- abort(); | ||
| 150 | +- break; | ||
| 151 | ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: update display" | ||
| 152 | ++ "invalid control register value.\n"); | ||
| 153 | ++ return; | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + /* set up to draw hardware cursor */ | ||
| 157 | +-- | ||
| 158 | +2.23.0 | ||
| 159 | + | ||
| @@ -0,0 +1,261 @@ | |||
| 1 | +From 2f57a288065de4fffcf182deacd3c75aec90a9ef Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 3 | +Date: Thu, 21 May 2020 21:39:44 +0200 | ||
| 4 | +Subject: [PATCH] sm501: Replace hand written implementation with pixman where | ||
| 5 | + possible | ||
| 6 | + | ||
| 7 | +Besides being faster this should also prevent malicious guests to | ||
| 8 | +abuse 2D engine to overwrite data or cause a crash. | ||
| 9 | + | ||
| 10 | +Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 11 | +Message-id: 58666389b6cae256e4e972a32c05cf8aa51bffc0.1590089984.git.balaton@eik.bme.hu | ||
| 12 | +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 13 | +--- | ||
| 14 | + hw/display/sm501.c | 207 ++++++++++++++++++++++++++------------------- | ||
| 15 | + 1 file changed, 119 insertions(+), 88 deletions(-) | ||
| 16 | + | ||
| 17 | +diff --git a/hw/display/sm501.c b/hw/display/sm501.c | ||
| 18 | +index 98b3b97f7b..7dc4bb18b7 100644 | ||
| 19 | +--- a/hw/display/sm501.c | ||
| 20 | ++++ b/hw/display/sm501.c | ||
| 21 | + static void sm501_2d_operation(SM501State *s) | ||
| 22 | + /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */ | ||
| 23 | + int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1; | ||
| 24 | + int rop = s->twoD_control & 0xFF; | ||
| 25 | +- int dst_x = (s->twoD_destination >> 16) & 0x01FFF; | ||
| 26 | +- int dst_y = s->twoD_destination & 0xFFFF; | ||
| 27 | +- int width = (s->twoD_dimension >> 16) & 0x1FFF; | ||
| 28 | +- int height = s->twoD_dimension & 0xFFFF; | ||
| 29 | ++ unsigned int dst_x = (s->twoD_destination >> 16) & 0x01FFF; | ||
| 30 | ++ unsigned int dst_y = s->twoD_destination & 0xFFFF; | ||
| 31 | ++ unsigned int width = (s->twoD_dimension >> 16) & 0x1FFF; | ||
| 32 | ++ unsigned int height = s->twoD_dimension & 0xFFFF; | ||
| 33 | + uint32_t dst_base = s->twoD_destination_base & 0x03FFFFFF; | ||
| 34 | +- uint8_t *dst = s->local_mem + dst_base; | ||
| 35 | +- int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; | ||
| 36 | ++ unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; | ||
| 37 | + int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0; | ||
| 38 | + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); | ||
| 39 | + | ||
| 40 | + static void sm501_2d_operation(SM501State *s) | ||
| 41 | + return; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | +- if (rop_mode == 0) { | ||
| 45 | +- if (rop != 0xcc) { | ||
| 46 | +- /* Anything other than plain copies are not supported */ | ||
| 47 | +- qemu_log_mask(LOG_UNIMP, "sm501: rop3 mode with rop %x is not " | ||
| 48 | +- "supported.\n", rop); | ||
| 49 | +- } | ||
| 50 | +- } else { | ||
| 51 | +- if (rop2_source_is_pattern && rop != 0x5) { | ||
| 52 | +- /* For pattern source, we support only inverse dest */ | ||
| 53 | +- qemu_log_mask(LOG_UNIMP, "sm501: rop2 source being the pattern and " | ||
| 54 | +- "rop %x is not supported.\n", rop); | ||
| 55 | +- } else { | ||
| 56 | +- if (rop != 0x5 && rop != 0xc) { | ||
| 57 | +- /* Anything other than plain copies or inverse dest is not | ||
| 58 | +- * supported */ | ||
| 59 | +- qemu_log_mask(LOG_UNIMP, "sm501: rop mode %x is not " | ||
| 60 | +- "supported.\n", rop); | ||
| 61 | +- } | ||
| 62 | +- } | ||
| 63 | +- } | ||
| 64 | +- | ||
| 65 | + if (s->twoD_source_base & BIT(27) || s->twoD_destination_base & BIT(27)) { | ||
| 66 | + qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n"); | ||
| 67 | + return; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | ++ if (!dst_pitch) { | ||
| 71 | ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero dest pitch.\n"); | ||
| 72 | ++ return; | ||
| 73 | ++ } | ||
| 74 | ++ | ||
| 75 | ++ if (!width || !height) { | ||
| 76 | ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero size 2D op.\n"); | ||
| 77 | ++ return; | ||
| 78 | ++ } | ||
| 79 | ++ | ||
| 80 | ++ if (rtl) { | ||
| 81 | ++ dst_x -= width - 1; | ||
| 82 | ++ dst_y -= height - 1; | ||
| 83 | ++ } | ||
| 84 | ++ | ||
| 85 | ++ if (dst_base >= get_local_mem_size(s) || dst_base + | ||
| 86 | ++ (dst_x + width + (dst_y + height) * (dst_pitch + width)) * | ||
| 87 | ++ (1 << format) >= get_local_mem_size(s)) { | ||
| 88 | ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: 2D op dest is outside vram.\n"); | ||
| 89 | ++ return; | ||
| 90 | ++ } | ||
| 91 | ++ | ||
| 92 | + switch (cmd) { | ||
| 93 | +- case 0x00: /* copy area */ | ||
| 94 | ++ case 0: /* BitBlt */ | ||
| 95 | + { | ||
| 96 | +- int src_x = (s->twoD_source >> 16) & 0x01FFF; | ||
| 97 | +- int src_y = s->twoD_source & 0xFFFF; | ||
| 98 | ++ unsigned int src_x = (s->twoD_source >> 16) & 0x01FFF; | ||
| 99 | ++ unsigned int src_y = s->twoD_source & 0xFFFF; | ||
| 100 | + uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; | ||
| 101 | +- uint8_t *src = s->local_mem + src_base; | ||
| 102 | +- int src_pitch = s->twoD_pitch & 0x1FFF; | ||
| 103 | +- | ||
| 104 | +-#define COPY_AREA(_bpp, _pixel_type, rtl) { \ | ||
| 105 | +- int y, x, index_d, index_s; \ | ||
| 106 | +- for (y = 0; y < height; y++) { \ | ||
| 107 | +- for (x = 0; x < width; x++) { \ | ||
| 108 | +- _pixel_type val; \ | ||
| 109 | +- \ | ||
| 110 | +- if (rtl) { \ | ||
| 111 | +- index_s = ((src_y - y) * src_pitch + src_x - x) * _bpp; \ | ||
| 112 | +- index_d = ((dst_y - y) * dst_pitch + dst_x - x) * _bpp; \ | ||
| 113 | +- } else { \ | ||
| 114 | +- index_s = ((src_y + y) * src_pitch + src_x + x) * _bpp; \ | ||
| 115 | +- index_d = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ | ||
| 116 | +- } \ | ||
| 117 | +- if (rop_mode == 1 && rop == 5) { \ | ||
| 118 | +- /* Invert dest */ \ | ||
| 119 | +- val = ~*(_pixel_type *)&dst[index_d]; \ | ||
| 120 | +- } else { \ | ||
| 121 | +- val = *(_pixel_type *)&src[index_s]; \ | ||
| 122 | +- } \ | ||
| 123 | +- *(_pixel_type *)&dst[index_d] = val; \ | ||
| 124 | +- } \ | ||
| 125 | +- } \ | ||
| 126 | +- } | ||
| 127 | +- switch (format) { | ||
| 128 | +- case 0: | ||
| 129 | +- COPY_AREA(1, uint8_t, rtl); | ||
| 130 | +- break; | ||
| 131 | +- case 1: | ||
| 132 | +- COPY_AREA(2, uint16_t, rtl); | ||
| 133 | +- break; | ||
| 134 | +- case 2: | ||
| 135 | +- COPY_AREA(4, uint32_t, rtl); | ||
| 136 | +- break; | ||
| 137 | ++ unsigned int src_pitch = s->twoD_pitch & 0x1FFF; | ||
| 138 | ++ | ||
| 139 | ++ if (!src_pitch) { | ||
| 140 | ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero src pitch.\n"); | ||
| 141 | ++ return; | ||
| 142 | ++ } | ||
| 143 | ++ | ||
| 144 | ++ if (rtl) { | ||
| 145 | ++ src_x -= width - 1; | ||
| 146 | ++ src_y -= height - 1; | ||
| 147 | ++ } | ||
| 148 | ++ | ||
| 149 | ++ if (src_base >= get_local_mem_size(s) || src_base + | ||
| 150 | ++ (src_x + width + (src_y + height) * (src_pitch + width)) * | ||
| 151 | ++ (1 << format) >= get_local_mem_size(s)) { | ||
| 152 | ++ qemu_log_mask(LOG_GUEST_ERROR, | ||
| 153 | ++ "sm501: 2D op src is outside vram.\n"); | ||
| 154 | ++ return; | ||
| 155 | ++ } | ||
| 156 | ++ | ||
| 157 | ++ if ((rop_mode && rop == 0x5) || (!rop_mode && rop == 0x55)) { | ||
| 158 | ++ /* Invert dest, is there a way to do this with pixman? */ | ||
| 159 | ++ unsigned int x, y, i; | ||
| 160 | ++ uint8_t *d = s->local_mem + dst_base; | ||
| 161 | ++ | ||
| 162 | ++ for (y = 0; y < height; y++) { | ||
| 163 | ++ i = (dst_x + (dst_y + y) * dst_pitch) * (1 << format); | ||
| 164 | ++ for (x = 0; x < width; x++, i += (1 << format)) { | ||
| 165 | ++ switch (format) { | ||
| 166 | ++ case 0: | ||
| 167 | ++ d[i] = ~d[i]; | ||
| 168 | ++ break; | ||
| 169 | ++ case 1: | ||
| 170 | ++ *(uint16_t *)&d[i] = ~*(uint16_t *)&d[i]; | ||
| 171 | ++ break; | ||
| 172 | ++ case 2: | ||
| 173 | ++ *(uint32_t *)&d[i] = ~*(uint32_t *)&d[i]; | ||
| 174 | ++ break; | ||
| 175 | ++ } | ||
| 176 | ++ } | ||
| 177 | ++ } | ||
| 178 | ++ } else { | ||
| 179 | ++ /* Do copy src for unimplemented ops, better than unpainted area */ | ||
| 180 | ++ if ((rop_mode && (rop != 0xc || rop2_source_is_pattern)) || | ||
| 181 | ++ (!rop_mode && rop != 0xcc)) { | ||
| 182 | ++ qemu_log_mask(LOG_UNIMP, | ||
| 183 | ++ "sm501: rop%d op %x%s not implemented\n", | ||
| 184 | ++ (rop_mode ? 2 : 3), rop, | ||
| 185 | ++ (rop2_source_is_pattern ? | ||
| 186 | ++ " with pattern source" : "")); | ||
| 187 | ++ } | ||
| 188 | ++ /* Check for overlaps, this could be made more exact */ | ||
| 189 | ++ uint32_t sb, se, db, de; | ||
| 190 | ++ sb = src_base + src_x + src_y * (width + src_pitch); | ||
| 191 | ++ se = sb + width + height * (width + src_pitch); | ||
| 192 | ++ db = dst_base + dst_x + dst_y * (width + dst_pitch); | ||
| 193 | ++ de = db + width + height * (width + dst_pitch); | ||
| 194 | ++ if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) { | ||
| 195 | ++ /* regions may overlap: copy via temporary */ | ||
| 196 | ++ int llb = width * (1 << format); | ||
| 197 | ++ int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t)); | ||
| 198 | ++ uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) * | ||
| 199 | ++ height); | ||
| 200 | ++ pixman_blt((uint32_t *)&s->local_mem[src_base], tmp, | ||
| 201 | ++ src_pitch * (1 << format) / sizeof(uint32_t), | ||
| 202 | ++ tmp_stride, 8 * (1 << format), 8 * (1 << format), | ||
| 203 | ++ src_x, src_y, 0, 0, width, height); | ||
| 204 | ++ pixman_blt(tmp, (uint32_t *)&s->local_mem[dst_base], | ||
| 205 | ++ tmp_stride, | ||
| 206 | ++ dst_pitch * (1 << format) / sizeof(uint32_t), | ||
| 207 | ++ 8 * (1 << format), 8 * (1 << format), | ||
| 208 | ++ 0, 0, dst_x, dst_y, width, height); | ||
| 209 | ++ g_free(tmp); | ||
| 210 | ++ } else { | ||
| 211 | ++ pixman_blt((uint32_t *)&s->local_mem[src_base], | ||
| 212 | ++ (uint32_t *)&s->local_mem[dst_base], | ||
| 213 | ++ src_pitch * (1 << format) / sizeof(uint32_t), | ||
| 214 | ++ dst_pitch * (1 << format) / sizeof(uint32_t), | ||
| 215 | ++ 8 * (1 << format), 8 * (1 << format), | ||
| 216 | ++ src_x, src_y, dst_x, dst_y, width, height); | ||
| 217 | ++ } | ||
| 218 | + } | ||
| 219 | + break; | ||
| 220 | + } | ||
| 221 | +- case 0x01: /* fill rectangle */ | ||
| 222 | ++ case 1: /* Rectangle Fill */ | ||
| 223 | + { | ||
| 224 | + uint32_t color = s->twoD_foreground; | ||
| 225 | + | ||
| 226 | +-#define FILL_RECT(_bpp, _pixel_type) { \ | ||
| 227 | +- int y, x; \ | ||
| 228 | +- for (y = 0; y < height; y++) { \ | ||
| 229 | +- for (x = 0; x < width; x++) { \ | ||
| 230 | +- int index = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ | ||
| 231 | +- *(_pixel_type *)&dst[index] = (_pixel_type)color; \ | ||
| 232 | +- } \ | ||
| 233 | +- } \ | ||
| 234 | +- } | ||
| 235 | +- | ||
| 236 | +- switch (format) { | ||
| 237 | +- case 0: | ||
| 238 | +- FILL_RECT(1, uint8_t); | ||
| 239 | +- break; | ||
| 240 | +- case 1: | ||
| 241 | +- color = cpu_to_le16(color); | ||
| 242 | +- FILL_RECT(2, uint16_t); | ||
| 243 | +- break; | ||
| 244 | +- case 2: | ||
| 245 | ++ if (format == 2) { | ||
| 246 | + color = cpu_to_le32(color); | ||
| 247 | +- FILL_RECT(4, uint32_t); | ||
| 248 | +- break; | ||
| 249 | ++ } else if (format == 1) { | ||
| 250 | ++ color = cpu_to_le16(color); | ||
| 251 | + } | ||
| 252 | ++ | ||
| 253 | ++ pixman_fill((uint32_t *)&s->local_mem[dst_base], | ||
| 254 | ++ dst_pitch * (1 << format) / sizeof(uint32_t), | ||
| 255 | ++ 8 * (1 << format), dst_x, dst_y, width, height, color); | ||
| 256 | + break; | ||
| 257 | + } | ||
| 258 | + default: | ||
| 259 | +-- | ||
| 260 | +2.23.0 | ||
| 261 | + | ||
| @@ -0,0 +1,134 @@ | |||
| 1 | +From 54c647d867891b58084d6b36ac2db794c19bed22 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 3 | +Date: Thu, 21 May 2020 21:39:44 +0200 | ||
| 4 | +Subject: [PATCH] sm501: Shorten long variable names in sm501_2d_operation | ||
| 5 | + | ||
| 6 | +This increases readability and cleans up some confusing naming. | ||
| 7 | + | ||
| 8 | +Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 9 | +Message-id: b9b67b94c46e945252a73c77dfd117132c63c4fb.1590089984.git.balaton@eik.bme.hu | ||
| 10 | +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 11 | +--- | ||
| 12 | + hw/display/sm501.c | 45 ++++++++++++++++++++++----------------------- | ||
| 13 | + 1 file changed, 22 insertions(+), 23 deletions(-) | ||
| 14 | + | ||
| 15 | +diff --git a/hw/display/sm501.c b/hw/display/sm501.c | ||
| 16 | +index aa4b202a48..51e7ccc39d 100644 | ||
| 17 | +--- a/hw/display/sm501.c | ||
| 18 | ++++ b/hw/display/sm501.c | ||
| 19 | + static inline void hwc_invalidate(SM501State *s, int crt) | ||
| 20 | + static void sm501_2d_operation(SM501State *s) | ||
| 21 | + { | ||
| 22 | + /* obtain operation parameters */ | ||
| 23 | +- int operation = (s->twoD_control >> 16) & 0x1f; | ||
| 24 | ++ int cmd = (s->twoD_control >> 16) & 0x1F; | ||
| 25 | + int rtl = s->twoD_control & 0x8000000; | ||
| 26 | + int src_x = (s->twoD_source >> 16) & 0x01FFF; | ||
| 27 | + int src_y = s->twoD_source & 0xFFFF; | ||
| 28 | + int dst_x = (s->twoD_destination >> 16) & 0x01FFF; | ||
| 29 | + int dst_y = s->twoD_destination & 0xFFFF; | ||
| 30 | +- int operation_width = (s->twoD_dimension >> 16) & 0x1FFF; | ||
| 31 | +- int operation_height = s->twoD_dimension & 0xFFFF; | ||
| 32 | ++ int width = (s->twoD_dimension >> 16) & 0x1FFF; | ||
| 33 | ++ int height = s->twoD_dimension & 0xFFFF; | ||
| 34 | + uint32_t color = s->twoD_foreground; | ||
| 35 | +- int format_flags = (s->twoD_stretch >> 20) & 0x3; | ||
| 36 | +- int addressing = (s->twoD_stretch >> 16) & 0xF; | ||
| 37 | ++ int format = (s->twoD_stretch >> 20) & 0x3; | ||
| 38 | + int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */ | ||
| 39 | + /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */ | ||
| 40 | + int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1; | ||
| 41 | + static void sm501_2d_operation(SM501State *s) | ||
| 42 | + /* get frame buffer info */ | ||
| 43 | + uint8_t *src = s->local_mem + src_base; | ||
| 44 | + uint8_t *dst = s->local_mem + dst_base; | ||
| 45 | +- int src_width = s->twoD_pitch & 0x1FFF; | ||
| 46 | +- int dst_width = (s->twoD_pitch >> 16) & 0x1FFF; | ||
| 47 | ++ int src_pitch = s->twoD_pitch & 0x1FFF; | ||
| 48 | ++ int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; | ||
| 49 | + int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0; | ||
| 50 | + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); | ||
| 51 | + | ||
| 52 | +- if (addressing != 0x0) { | ||
| 53 | ++ if ((s->twoD_stretch >> 16) & 0xF) { | ||
| 54 | + qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n"); | ||
| 55 | + return; | ||
| 56 | + } | ||
| 57 | + static void sm501_2d_operation(SM501State *s) | ||
| 58 | + return; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | +- switch (operation) { | ||
| 62 | ++ switch (cmd) { | ||
| 63 | + case 0x00: /* copy area */ | ||
| 64 | + #define COPY_AREA(_bpp, _pixel_type, rtl) { \ | ||
| 65 | + int y, x, index_d, index_s; \ | ||
| 66 | +- for (y = 0; y < operation_height; y++) { \ | ||
| 67 | +- for (x = 0; x < operation_width; x++) { \ | ||
| 68 | ++ for (y = 0; y < height; y++) { \ | ||
| 69 | ++ for (x = 0; x < width; x++) { \ | ||
| 70 | + _pixel_type val; \ | ||
| 71 | + \ | ||
| 72 | + if (rtl) { \ | ||
| 73 | +- index_s = ((src_y - y) * src_width + src_x - x) * _bpp; \ | ||
| 74 | +- index_d = ((dst_y - y) * dst_width + dst_x - x) * _bpp; \ | ||
| 75 | ++ index_s = ((src_y - y) * src_pitch + src_x - x) * _bpp; \ | ||
| 76 | ++ index_d = ((dst_y - y) * dst_pitch + dst_x - x) * _bpp; \ | ||
| 77 | + } else { \ | ||
| 78 | +- index_s = ((src_y + y) * src_width + src_x + x) * _bpp; \ | ||
| 79 | +- index_d = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \ | ||
| 80 | ++ index_s = ((src_y + y) * src_pitch + src_x + x) * _bpp; \ | ||
| 81 | ++ index_d = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ | ||
| 82 | + } \ | ||
| 83 | + if (rop_mode == 1 && rop == 5) { \ | ||
| 84 | + /* Invert dest */ \ | ||
| 85 | + static void sm501_2d_operation(SM501State *s) | ||
| 86 | + } \ | ||
| 87 | + } \ | ||
| 88 | + } | ||
| 89 | +- switch (format_flags) { | ||
| 90 | ++ switch (format) { | ||
| 91 | + case 0: | ||
| 92 | + COPY_AREA(1, uint8_t, rtl); | ||
| 93 | + break; | ||
| 94 | + static void sm501_2d_operation(SM501State *s) | ||
| 95 | + case 0x01: /* fill rectangle */ | ||
| 96 | + #define FILL_RECT(_bpp, _pixel_type) { \ | ||
| 97 | + int y, x; \ | ||
| 98 | +- for (y = 0; y < operation_height; y++) { \ | ||
| 99 | +- for (x = 0; x < operation_width; x++) { \ | ||
| 100 | +- int index = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \ | ||
| 101 | ++ for (y = 0; y < height; y++) { \ | ||
| 102 | ++ for (x = 0; x < width; x++) { \ | ||
| 103 | ++ int index = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ | ||
| 104 | + *(_pixel_type *)&dst[index] = (_pixel_type)color; \ | ||
| 105 | + } \ | ||
| 106 | + } \ | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | +- switch (format_flags) { | ||
| 110 | ++ switch (format) { | ||
| 111 | + case 0: | ||
| 112 | + FILL_RECT(1, uint8_t); | ||
| 113 | + break; | ||
| 114 | + static void sm501_2d_operation(SM501State *s) | ||
| 115 | + | ||
| 116 | + default: | ||
| 117 | + qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n", | ||
| 118 | +- operation); | ||
| 119 | ++ cmd); | ||
| 120 | + return; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + if (dst_base >= get_fb_addr(s, crt) && | ||
| 124 | + dst_base <= get_fb_addr(s, crt) + fb_len) { | ||
| 125 | +- int dst_len = MIN(fb_len, ((dst_y + operation_height - 1) * dst_width + | ||
| 126 | +- dst_x + operation_width) * (1 << format_flags)); | ||
| 127 | ++ int dst_len = MIN(fb_len, ((dst_y + height - 1) * dst_pitch + | ||
| 128 | ++ dst_x + width) * (1 << format)); | ||
| 129 | + if (dst_len) { | ||
| 130 | + memory_region_set_dirty(&s->local_mem_region, dst_base, dst_len); | ||
| 131 | + } | ||
| 132 | +-- | ||
| 133 | +2.23.0 | ||
| 134 | + | ||
| @@ -0,0 +1,42 @@ | |||
| 1 | +From a2622f39d8050c86100b40e47b2586d0ebf3b541 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 3 | +Date: Thu, 21 May 2020 21:39:44 +0200 | ||
| 4 | +Subject: [PATCH] sm501: Use BIT(x) macro to shorten constant | ||
| 5 | +MIME-Version: 1.0 | ||
| 6 | +Content-Type: text/plain; charset=UTF-8 | ||
| 7 | +Content-Transfer-Encoding: 8bit | ||
| 8 | + | ||
| 9 | +Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> | ||
| 10 | +Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
| 11 | +Message-id: 124bf5de8d7cf503b32b377d0445029a76bfbd49.1590089984.git.balaton@eik.bme.hu | ||
| 12 | +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> | ||
| 13 | +--- | ||
| 14 | + hw/display/sm501.c | 5 ++--- | ||
| 15 | + 1 file changed, 2 insertions(+), 3 deletions(-) | ||
| 16 | + | ||
| 17 | +diff --git a/hw/display/sm501.c b/hw/display/sm501.c | ||
| 18 | +index 51e7ccc39d..f3d11d0b23 100644 | ||
| 19 | +--- a/hw/display/sm501.c | ||
| 20 | ++++ b/hw/display/sm501.c | ||
| 21 | + static void sm501_2d_operation(SM501State *s) | ||
| 22 | + { | ||
| 23 | + /* obtain operation parameters */ | ||
| 24 | + int cmd = (s->twoD_control >> 16) & 0x1F; | ||
| 25 | +- int rtl = s->twoD_control & 0x8000000; | ||
| 26 | ++ int rtl = s->twoD_control & BIT(27); | ||
| 27 | + int src_x = (s->twoD_source >> 16) & 0x01FFF; | ||
| 28 | + int src_y = s->twoD_source & 0xFFFF; | ||
| 29 | + int dst_x = (s->twoD_destination >> 16) & 0x01FFF; | ||
| 30 | + static void sm501_2d_operation(SM501State *s) | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | +- if ((s->twoD_source_base & 0x08000000) || | ||
| 35 | +- (s->twoD_destination_base & 0x08000000)) { | ||
| 36 | ++ if (s->twoD_source_base & BIT(27) || s->twoD_destination_base & BIT(27)) { | ||
| 37 | + qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n"); | ||
| 38 | + return; | ||
| 39 | + } | ||
| 40 | +-- | ||
| 41 | +2.23.0 | ||
| 42 | + | ||