qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20170213-1' into staging

vga: bugfixes for cirrus and virtio-gpu

# gpg: Signature made Mon 13 Feb 2017 08:14:47 GMT
# gpg: using RSA key 0x4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/pull-vga-20170213-1:
Revert "cirrus: allow zero source pitch in pattern fill rops"
cirrus: fix patterncopy checks
cirrus: replace debug printf with trace points
vga: replace debug printf with trace points
virtio-gpu: fix resource leak in virgl_cmd_resource_unref
virtio-gpu: fix memory leak in set scanout

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+67 -52
+42 -29
hw/display/cirrus_vga.c
··· 28 28 */ 29 29 #include "qemu/osdep.h" 30 30 #include "qapi/error.h" 31 + #include "trace.h" 31 32 #include "hw/hw.h" 32 33 #include "hw/pci/pci.h" 33 34 #include "ui/console.h" ··· 272 273 static bool blit_region_is_unsafe(struct CirrusVGAState *s, 273 274 int32_t pitch, int32_t addr) 274 275 { 276 + if (!pitch) { 277 + return true; 278 + } 275 279 if (pitch < 0) { 276 280 int64_t min = addr 277 281 + ((int64_t)s->cirrus_blt_height - 1) * pitch ··· 290 294 return false; 291 295 } 292 296 293 - static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only, 294 - bool zero_src_pitch_ok) 297 + static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) 295 298 { 296 - int32_t check_pitch; 297 - 298 299 /* should be the case, see cirrus_bitblt_start */ 299 300 assert(s->cirrus_blt_width > 0); 300 301 assert(s->cirrus_blt_height > 0); ··· 303 304 return true; 304 305 } 305 306 306 - if (!s->cirrus_blt_dstpitch) { 307 - return true; 308 - } 309 - 310 307 if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, 311 308 s->cirrus_blt_dstaddr)) { 312 309 return true; ··· 314 311 if (dst_only) { 315 312 return false; 316 313 } 317 - 318 - check_pitch = s->cirrus_blt_srcpitch; 319 - if (!zero_src_pitch_ok && !check_pitch) { 320 - check_pitch = s->cirrus_blt_width; 321 - } 322 - 323 - if (blit_region_is_unsafe(s, check_pitch, 314 + if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, 324 315 s->cirrus_blt_srcaddr)) { 325 316 return true; 326 317 } ··· 683 674 } 684 675 } 685 676 686 - static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, 687 - const uint8_t * src) 677 + static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc) 688 678 { 679 + uint32_t patternsize; 689 680 uint8_t *dst; 681 + uint8_t *src; 690 682 691 683 dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr; 692 684 693 - if (blit_is_unsafe(s, false, true)) { 685 + if (videosrc) { 686 + switch (s->vga.get_bpp(&s->vga)) { 687 + case 8: 688 + patternsize = 64; 689 + break; 690 + case 15: 691 + case 16: 692 + patternsize = 128; 693 + break; 694 + case 24: 695 + case 32: 696 + default: 697 + patternsize = 256; 698 + break; 699 + } 700 + s->cirrus_blt_srcaddr &= ~(patternsize - 1); 701 + if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) { 702 + return 0; 703 + } 704 + src = s->vga.vram_ptr + s->cirrus_blt_srcaddr; 705 + } else { 706 + src = s->cirrus_bltbuf; 707 + } 708 + 709 + if (blit_is_unsafe(s, true)) { 694 710 return 0; 695 711 } 696 712 ··· 709 725 { 710 726 cirrus_fill_t rop_func; 711 727 712 - if (blit_is_unsafe(s, true, true)) { 728 + if (blit_is_unsafe(s, true)) { 713 729 return 0; 714 730 } 715 731 rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; ··· 731 747 732 748 static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) 733 749 { 734 - return cirrus_bitblt_common_patterncopy(s, s->vga.vram_ptr + 735 - (s->cirrus_blt_srcaddr & ~7)); 750 + return cirrus_bitblt_common_patterncopy(s, true); 736 751 } 737 752 738 753 static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) ··· 810 825 811 826 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) 812 827 { 813 - if (blit_is_unsafe(s, false, false)) 828 + if (blit_is_unsafe(s, false)) 814 829 return 0; 815 830 816 831 return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, ··· 831 846 832 847 if (s->cirrus_srccounter > 0) { 833 848 if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { 834 - cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf); 849 + cirrus_bitblt_common_patterncopy(s, false); 835 850 the_end: 836 851 s->cirrus_srccounter = 0; 837 852 cirrus_bitblt_reset(s); ··· 1852 1867 break; 1853 1868 } 1854 1869 1870 + trace_vga_cirrus_write_blt(address, value); 1855 1871 return (uint8_t) value; 1856 1872 } 1857 1873 1858 1874 static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address, 1859 1875 uint8_t value) 1860 1876 { 1877 + trace_vga_cirrus_write_blt(address, value); 1861 1878 switch (address) { 1862 1879 case (CIRRUS_MMIO_BLTBGCOLOR + 0): 1863 1880 cirrus_vga_write_gr(s, 0x00, value); ··· 2607 2624 break; 2608 2625 } 2609 2626 } 2610 - #if defined(DEBUG_VGA) 2611 - printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val); 2612 - #endif 2627 + trace_vga_cirrus_read_io(addr, val); 2613 2628 return val; 2614 2629 } 2615 2630 ··· 2626 2641 if (vga_ioport_invalid(s, addr)) { 2627 2642 return; 2628 2643 } 2629 - #ifdef DEBUG_VGA 2630 - printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val); 2631 - #endif 2644 + trace_vga_cirrus_write_io(addr, val); 2632 2645 2633 2646 switch (addr) { 2634 2647 case 0x3c0:
+12
hw/display/trace-events
··· 119 119 qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom) "stride=%d [%d, %d, %d, %d]" 120 120 qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp) "%dx%d, stride %d, bpp %d, depth %d" 121 121 qxl_render_update_area_done(void *cookie) "%p" 122 + 123 + # hw/display/vga.c 124 + vga_std_read_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x" 125 + vga_std_write_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x" 126 + vga_vbe_read(uint32_t index, uint32_t val) "index 0x%x, val 0x%x" 127 + vga_vbe_write(uint32_t index, uint32_t val) "index 0x%x, val 0x%x" 128 + 129 + # hw/display/cirrus_vga.c 130 + vga_cirrus_read_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x" 131 + vga_cirrus_write_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x" 132 + vga_cirrus_read_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x" 133 + vga_cirrus_write_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
+4 -23
hw/display/vga.c
··· 34 34 #include "hw/xen/xen.h" 35 35 #include "trace.h" 36 36 37 - //#define DEBUG_VGA 38 37 //#define DEBUG_VGA_MEM 39 38 //#define DEBUG_VGA_REG 40 - 41 - //#define DEBUG_BOCHS_VBE 42 39 43 40 /* 16 state changes per vertical frame @60 Hz */ 44 41 #define VGA_TEXT_CURSOR_PERIOD_MS (1000 * 2 * 16 / 60) ··· 428 425 break; 429 426 } 430 427 } 431 - #if defined(DEBUG_VGA) 432 - printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val); 433 - #endif 428 + trace_vga_std_read_io(addr, val); 434 429 return val; 435 430 } 436 431 ··· 443 438 if (vga_ioport_invalid(s, addr)) { 444 439 return; 445 440 } 446 - #ifdef DEBUG_VGA 447 - printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val); 448 - #endif 441 + trace_vga_std_write_io(addr, val); 449 442 450 443 switch(addr) { 451 444 case VGA_ATT_W: ··· 733 726 } else { 734 727 val = 0; 735 728 } 736 - #ifdef DEBUG_BOCHS_VBE 737 - printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val); 738 - #endif 729 + trace_vga_vbe_read(s->vbe_index, val); 739 730 return val; 740 731 } 741 732 ··· 750 741 VGACommonState *s = opaque; 751 742 752 743 if (s->vbe_index <= VBE_DISPI_INDEX_NB) { 753 - #ifdef DEBUG_BOCHS_VBE 754 - printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val); 755 - #endif 744 + trace_vga_vbe_write(s->vbe_index, val); 756 745 switch(s->vbe_index) { 757 746 case VBE_DISPI_INDEX_ID: 758 747 if (val == VBE_DISPI_ID0 || ··· 1543 1532 height, format, s->line_offset, 1544 1533 s->vram_ptr + (s->start_addr * 4)); 1545 1534 dpy_gfx_replace_surface(s->con, surface); 1546 - #ifdef DEBUG_VGA 1547 - printf("VGA: Using shared surface for depth=%d swap=%d\n", 1548 - depth, byteswap); 1549 - #endif 1550 1535 } else { 1551 1536 qemu_console_resize(s->con, disp_width, height); 1552 1537 surface = qemu_console_surface(s->con); 1553 - #ifdef DEBUG_VGA 1554 - printf("VGA: Using shadow surface for depth=%d swap=%d\n", 1555 - depth, byteswap); 1556 - #endif 1557 1538 } 1558 1539 s->last_scr_width = disp_width; 1559 1540 s->last_scr_height = height;
+8
hw/display/virtio-gpu-3d.c
··· 77 77 struct virtio_gpu_ctrl_command *cmd) 78 78 { 79 79 struct virtio_gpu_resource_unref unref; 80 + struct iovec *res_iovs = NULL; 81 + int num_iovs = 0; 80 82 81 83 VIRTIO_GPU_FILL_CMD(unref); 82 84 trace_virtio_gpu_cmd_res_unref(unref.resource_id); 83 85 86 + virgl_renderer_resource_detach_iov(unref.resource_id, 87 + &res_iovs, 88 + &num_iovs); 89 + if (res_iovs != NULL && num_iovs != 0) { 90 + virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs); 91 + } 84 92 virgl_renderer_resource_unref(unref.resource_id); 85 93 } 86 94
+1
hw/display/virtio-gpu.c
··· 608 608 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; 609 609 return; 610 610 } 611 + pixman_image_unref(rect); 611 612 dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, scanout->ds); 612 613 } 613 614