qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: BALATON Zoltan <balaton@eik.bme.hu>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Sebastian Bauer <mail@sebastianbauer.info>,
	Magnus Damm <magnus.damm@gmail.com>,
	qemu-devel@nongnu.org, Aurelien Jarno <aurelien@aurel32.net>
Subject: Re: [PATCH v2 5/7] sm501: Replace hand written implementation with pixman where possible
Date: Tue, 26 May 2020 12:43:18 +0200	[thread overview]
Message-ID: <20200526104318.wmsqqtia3h52l454@sirius.home.kraxel.org> (raw)
In-Reply-To: <58666389b6cae256e4e972a32c05cf8aa51bffc0.1590089984.git.balaton@eik.bme.hu>

On Thu, May 21, 2020 at 09:39:44PM +0200, BALATON Zoltan wrote:
> Besides being faster this should also prevent malicious guests to
> abuse 2D engine to overwrite data or cause a crash.

>          uint32_t src_base = s->twoD_source_base & 0x03FFFFFF;
> -        uint8_t *src = s->local_mem + src_base;

> -                    val = *(_pixel_type *)&src[index_s];                      \

Well, the advantage of *not* using pixman is that you can easily switch
the code to use offsets instead of pointers, then apply the mask to the
*final* offset to avoid oob data access:

    val = *(_pixel_type*)(&s->local_mem[(s->twoD_source_base + index_s) & 0x03FFFFFF]);

> +        if ((rop_mode && rop == 0x5) || (!rop_mode && rop == 0x55)) {
> +            /* Invert dest, is there a way to do this with pixman? */

PIXMAN_OP_XOR maybe?

> +            if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) {
> +                /* regions may overlap: copy via temporary */

The usual way for a hardware blitter is to have a direction bit, i.e.
the guest os can ask to blit in top->bottom or bottom->top scanline
ordering.  The guest can use that to make sure the blit does not
overwrite things.  But note the guest can also intentionally use
overlapping regions, i.e. memset(0) the first scanline, then use a blit
with overlap to clear the whole screen.  The later will surely break if
you blit via temporary image ...

> +                pixman_blt((uint32_t *)&s->local_mem[src_base],
> +                           (uint32_t *)&s->local_mem[dst_base],
> +                           src_pitch * (1 << format) / sizeof(uint32_t),
> +                           dst_pitch * (1 << format) / sizeof(uint32_t),
> +                           8 * (1 << format), 8 * (1 << format),
> +                           src_x, src_y, dst_x, dst_y, width, height);

See above, i'm not convinced pixman is the best way here.
When using pixman I'd suggest:

  (1) src = pixman_image_create_bits_no_clear(...);
  (2) dst = pixman_image_create_bits_no_clear(...);
  (3) pixman_image_composite(PIXMAN_OP_SRC, src, NULL, dst, ...);
  (4) pixman_image_unref(src);
  (5) pixman_image_unref(dst);

pixman_blt() is probably doing basically the same.  The advantage of not
using pixman_blt() is that

  (a) you can also use pixman ops other than PIXMAN_OP_SRC, and
  (b) you can have a helper function for (1)+(2) which very carefully
      applies sanity checks to make sure the pixman image created stays
      completely inside s->local_mem.
  (c) you have the option to completely rearrange the code flow, for
      example update the src pixman image whenever the guest touches
      src_base or src_pitch or format instead of having a
      create/op/unref cycle on every blitter op.

> +        pixman_fill((uint32_t *)&s->local_mem[dst_base],
> +                    dst_pitch * (1 << format) / sizeof(uint32_t),
> +                    8 * (1 << format), dst_x, dst_y, width, height, color);

  (1) src = pixman_image_create_solid(...), otherwise same as above ;)

take care,
  Gerd



  reply	other threads:[~2020-05-26 10:44 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-21 19:39 [PATCH v2 0/7] Misc display/sm501 clean ups and fixes BALATON Zoltan
2020-05-21 19:39 ` [PATCH v2 4/7] sm501: Clean up local variables in sm501_2d_operation BALATON Zoltan
2020-05-21 19:39 ` [PATCH v2 6/7] sm501: Optimize small overlapping blits BALATON Zoltan
2020-05-21 19:39 ` [PATCH v2 1/7] sm501: Convert printf + abort to qemu_log_mask BALATON Zoltan
2020-05-21 19:39 ` [PATCH v2 2/7] sm501: Shorten long variable names in sm501_2d_operation BALATON Zoltan
2020-05-21 19:39 ` [PATCH v2 3/7] sm501: Use BIT(x) macro to shorten constant BALATON Zoltan
2020-05-21 19:39 ` [PATCH v2 7/7] sm501: Remove obsolete changelog and todo comment BALATON Zoltan
2020-05-21 19:39 ` [PATCH v2 5/7] sm501: Replace hand written implementation with pixman where possible BALATON Zoltan
2020-05-26 10:43   ` Gerd Hoffmann [this message]
2020-05-26 13:35     ` BALATON Zoltan
2020-05-27  9:15       ` Gerd Hoffmann
2020-05-27 11:05         ` BALATON Zoltan
2020-05-22  1:50 ` [PATCH v2 0/7] Misc display/sm501 clean ups and fixes no-reply
2020-05-28  7:21 ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200526104318.wmsqqtia3h52l454@sirius.home.kraxel.org \
    --to=kraxel@redhat.com \
    --cc=aurelien@aurel32.net \
    --cc=balaton@eik.bme.hu \
    --cc=magnus.damm@gmail.com \
    --cc=mail@sebastianbauer.info \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).