已合并
Automatically generate code patches with openeuler #132
zhendongchen创建于 2020年9月24日
Automatically generate code patches with openeuler #132
已合并
zhendongchen创建于 2020年9月24日
从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+@@ -379,7 +379,10 @@ 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+@@ -217,21 +217,31 @@ 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+ 
Mqemu.spec+17-1
@@ -1,6 +1,6 @@
1Name: qemu1Name: qemu
2Version: 4.1.02Version: 4.1.0
3-Release: 213+Release: 22
4Epoch: 24Epoch: 2
5Summary: QEMU is a generic and open source machine emulator and virtualizer5Summary: QEMU is a generic and open source machine emulator and virtualizer
6License: GPLv2 and BSD and MIT and CC-BY6License: GPLv2 and BSD and MIT and CC-BY
@@ -187,6 +187,13 @@ Patch0174: hw-usb-core-fix-buffer-overflow.patch
187Patch0175: slirp-drop-bogus-IPv6-messages.patch187Patch0175: slirp-drop-bogus-IPv6-messages.patch
188Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch188Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch
189Patch0177: hw-xhci-check-return-value-of-usb_packet_map.patch189Patch0177: 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 
191BuildRequires: flex198BuildRequires: flex
192BuildRequires: bison199BuildRequires: bison
@@ -532,6 +539,15 @@ getent passwd qemu >/dev/null || \
532%endif539%endif
533 540 
534%changelog541%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 patches552- enrich commit info for some patches
537- rename some patches for slirp553- 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+@@ -699,28 +699,19 @@ 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+@@ -758,6 +749,13 @@ 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+@@ -793,8 +791,11 @@ 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+@@ -819,7 +820,7 @@ 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+@@ -727,8 +727,8 @@ 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+@@ -754,8 +754,8 @@ 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+@@ -823,9 +823,9 @@ 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+@@ -892,9 +892,8 @@ 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+@@ -948,15 +947,15 @@ 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+@@ -1207,9 +1206,8 @@ 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+@@ -1345,9 +1343,9 @@ 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+@@ -1433,9 +1431,8 @@ 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+@@ -1520,9 +1517,9 @@ 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+@@ -1670,9 +1667,9 @@ 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+@@ -706,13 +706,12 @@ 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+@@ -721,104 +720,136 @@ 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+@@ -700,17 +700,16 @@ 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+@@ -721,12 +720,12 @@ 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+@@ -758,20 +757,20 @@ 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+@@ -783,7 +782,7 @@ 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+@@ -799,15 +798,15 @@ 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+@@ -824,14 +823,14 @@ 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+@@ -701,7 +701,7 @@ 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+@@ -751,8 +751,7 @@ 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+