* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
[not found] <4BE32178.2090103@msgid.tls.msk.ru>
@ 2010-05-10 7:41 ` Avi Kivity
2010-05-10 8:15 ` Avi Kivity
0 siblings, 1 reply; 21+ messages in thread
From: Avi Kivity @ 2010-05-10 7:41 UTC (permalink / raw)
To: Michael Tokarev; +Cc: qemu-devel, KVM list
On 05/06/2010 11:07 PM, Michael Tokarev wrote:
> There was a bug recently fixed in vnc code. Apparently
> there's something similar in the cirrus emulation as well.
> Here it triggers _always_ (including old versions of kvm)
> when running windows NT and hitting "test" button in its
> display resolution dialog. Here's what gdb is to say:
>
> Program received signal SIGFPE, Arithmetic exception.
> [Switching to Thread 0xf76cab70 (LWP 580)]
> 0x080c5e45 in cirrus_do_copy (s=0x86134dc, dst=960000, src=0, w=2, h=9)
> at hw/cirrus_vga.c:687
> 687 sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
> (gdb) p depth
> $1 = 2
> (gdb) p s->cirrus_blt_srcpitch
> $2 = 0
>
>
> This qemu-kvm-0.12.3 - actually a debian package of it,
> but there's no patches relevant to video applied.
>
> Anything can be done with it?
Well, it's trivial to check for the condition, but how to handle it?
Need to find the spec for the chip.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-10 7:41 ` [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus Avi Kivity
@ 2010-05-10 8:15 ` Avi Kivity
2010-05-12 12:20 ` Stefano Stabellini
0 siblings, 1 reply; 21+ messages in thread
From: Avi Kivity @ 2010-05-10 8:15 UTC (permalink / raw)
To: Michael Tokarev; +Cc: Brian Kress, qemu-devel, KVM list, Stefano Stabellini
On 05/10/2010 10:41 AM, Avi Kivity wrote:
> On 05/06/2010 11:07 PM, Michael Tokarev wrote:
>> There was a bug recently fixed in vnc code. Apparently
>> there's something similar in the cirrus emulation as well.
>> Here it triggers _always_ (including old versions of kvm)
>> when running windows NT and hitting "test" button in its
>> display resolution dialog. Here's what gdb is to say:
>>
>> Program received signal SIGFPE, Arithmetic exception.
>> [Switching to Thread 0xf76cab70 (LWP 580)]
>> 0x080c5e45 in cirrus_do_copy (s=0x86134dc, dst=960000, src=0, w=2, h=9)
>> at hw/cirrus_vga.c:687
>> 687 sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
>> (gdb) p depth
>> $1 = 2
>> (gdb) p s->cirrus_blt_srcpitch
>> $2 = 0
>>
>>
>> This qemu-kvm-0.12.3 - actually a debian package of it,
>> but there's no patches relevant to video applied.
>>
>> Anything can be done with it?
>
> Well, it's trivial to check for the condition, but how to handle it?
>
That code is wrong. It shouldn't be using the bitblt source pitch, but
the actual display pitch. If the two are different, then the blt
doesn't actually affect a rectangular region, but instead a parallelogram.
Further:
>
> if (notify)
> qemu_console_copy(s->vga.ds,
> sx, sy, dx, dy,
> s->cirrus_blt_width / depth,
> s->cirrus_blt_height);
>
> /* we don't have to notify the display that this portion has
> changed since qemu_console_copy implies this */
>
> cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> s->cirrus_blt_height);
Shouldn't we avoid the invalidate if notify != 0, as the comment says?
31c05501c says this breaks bitblt, but I can't see why this is true.
The copy should update the display. This is probably due to a
miscalculation of the affected region, and now we have two invalidates
instead of one, reducing performance.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-10 8:15 ` Avi Kivity
@ 2010-05-12 12:20 ` Stefano Stabellini
2010-05-12 12:36 ` Avi Kivity
0 siblings, 1 reply; 21+ messages in thread
From: Stefano Stabellini @ 2010-05-12 12:20 UTC (permalink / raw)
To: Avi Kivity
Cc: KVM list, Stabellini, Michael Tokarev, qemu-devel, Stefano,
Brian Kress
On Mon, 10 May 2010, Avi Kivity wrote:
> On 05/10/2010 10:41 AM, Avi Kivity wrote:
> > On 05/06/2010 11:07 PM, Michael Tokarev wrote:
> >> There was a bug recently fixed in vnc code. Apparently
> >> there's something similar in the cirrus emulation as well.
> >> Here it triggers _always_ (including old versions of kvm)
> >> when running windows NT and hitting "test" button in its
> >> display resolution dialog. Here's what gdb is to say:
> >>
> >> Program received signal SIGFPE, Arithmetic exception.
> >> [Switching to Thread 0xf76cab70 (LWP 580)]
> >> 0x080c5e45 in cirrus_do_copy (s=0x86134dc, dst=960000, src=0, w=2, h=9)
> >> at hw/cirrus_vga.c:687
> >> 687 sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
> >> (gdb) p depth
> >> $1 = 2
> >> (gdb) p s->cirrus_blt_srcpitch
> >> $2 = 0
> >>
> >>
> >> This qemu-kvm-0.12.3 - actually a debian package of it,
> >> but there's no patches relevant to video applied.
> >>
> >> Anything can be done with it?
> >
> > Well, it's trivial to check for the condition, but how to handle it?
> >
>
> That code is wrong. It shouldn't be using the bitblt source pitch, but
> the actual display pitch. If the two are different, then the blt
> doesn't actually affect a rectangular region, but instead a parallelogram.
>
Reading some documention about the Cirrus card we are emulating, it
seems that the source pitch is ignored in video to video operations, so
I think you are right here.
The Windows NT driver probably relies on this behaviour and doesn't set
the source pitch properly before the bitblt.
> Further:
>
> >
> > if (notify)
> > qemu_console_copy(s->vga.ds,
> > sx, sy, dx, dy,
> > s->cirrus_blt_width / depth,
> > s->cirrus_blt_height);
> >
> > /* we don't have to notify the display that this portion has
> > changed since qemu_console_copy implies this */
> >
> > cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> > s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> > s->cirrus_blt_height);
>
>
> Shouldn't we avoid the invalidate if notify != 0, as the comment says?
>
> 31c05501c says this breaks bitblt, but I can't see why this is true.
> The copy should update the display. This is probably due to a
> miscalculation of the affected region, and now we have two invalidates
> instead of one, reducing performance.
>
I agree with you: qemu_console_copy does imply that the copied portion
of the screen changed, so there is no reason to invalidate it again if
qemu_console_copy is called.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 12:20 ` Stefano Stabellini
@ 2010-05-12 12:36 ` Avi Kivity
2010-05-12 13:45 ` Stefano Stabellini
0 siblings, 1 reply; 21+ messages in thread
From: Avi Kivity @ 2010-05-12 12:36 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list
On 05/12/2010 03:20 PM, Stefano Stabellini wrote:
> On Mon, 10 May 2010, Avi Kivity wrote:
>
>> On 05/10/2010 10:41 AM, Avi Kivity wrote:
>>
>>> On 05/06/2010 11:07 PM, Michael Tokarev wrote:
>>>
>>>> There was a bug recently fixed in vnc code. Apparently
>>>> there's something similar in the cirrus emulation as well.
>>>> Here it triggers _always_ (including old versions of kvm)
>>>> when running windows NT and hitting "test" button in its
>>>> display resolution dialog. Here's what gdb is to say:
>>>>
>>>> Program received signal SIGFPE, Arithmetic exception.
>>>> [Switching to Thread 0xf76cab70 (LWP 580)]
>>>> 0x080c5e45 in cirrus_do_copy (s=0x86134dc, dst=960000, src=0, w=2, h=9)
>>>> at hw/cirrus_vga.c:687
>>>> 687 sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
>>>> (gdb) p depth
>>>> $1 = 2
>>>> (gdb) p s->cirrus_blt_srcpitch
>>>> $2 = 0
>>>>
>>>>
>>>> This qemu-kvm-0.12.3 - actually a debian package of it,
>>>> but there's no patches relevant to video applied.
>>>>
>>>> Anything can be done with it?
>>>>
>>> Well, it's trivial to check for the condition, but how to handle it?
>>>
>>>
>> That code is wrong. It shouldn't be using the bitblt source pitch, but
>> the actual display pitch. If the two are different, then the blt
>> doesn't actually affect a rectangular region, but instead a parallelogram.
>>
>>
> Reading some documention about the Cirrus card we are emulating, it
> seems that the source pitch is ignored in video to video operations, so
> I think you are right here.
>
From what I've read I don't think it's ignored. Rather there are two
separate pitches, one for bitblt and one for display.
I think the code should be something like
if bitblt destination intersects display memory:
if bitblt pitch == display pitch
use console_copy
else
invalidate entire display
> The Windows NT driver probably relies on this behaviour and doesn't set
> the source pitch properly before the bitblt.
>
Note it's just during mode changes. During normal operation I'm sure
the pitches are equal.
>> 31c05501c says this breaks bitblt, but I can't see why this is true.
>> The copy should update the display. This is probably due to a
>> miscalculation of the affected region, and now we have two invalidates
>> instead of one, reducing performance.
>>
>>
> I agree with you: qemu_console_copy does imply that the copied portion
> of the screen changed, so there is no reason to invalidate it again if
> qemu_console_copy is called.
>
Well, we can't just revert 31c05501c. There's probably another bug
involved.
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 12:36 ` Avi Kivity
@ 2010-05-12 13:45 ` Stefano Stabellini
2010-05-12 14:27 ` Avi Kivity
0 siblings, 1 reply; 21+ messages in thread
From: Stefano Stabellini @ 2010-05-12 13:45 UTC (permalink / raw)
To: Avi Kivity
Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list,
Stefano Stabellini
On Wed, 12 May 2010, Avi Kivity wrote:
> On 05/12/2010 03:20 PM, Stefano Stabellini wrote:
> > On Mon, 10 May 2010, Avi Kivity wrote:
> >
> >> On 05/10/2010 10:41 AM, Avi Kivity wrote:
> >>
> >>> On 05/06/2010 11:07 PM, Michael Tokarev wrote:
> >>>
> >>>> There was a bug recently fixed in vnc code. Apparently
> >>>> there's something similar in the cirrus emulation as well.
> >>>> Here it triggers _always_ (including old versions of kvm)
> >>>> when running windows NT and hitting "test" button in its
> >>>> display resolution dialog. Here's what gdb is to say:
> >>>>
> >>>> Program received signal SIGFPE, Arithmetic exception.
> >>>> [Switching to Thread 0xf76cab70 (LWP 580)]
> >>>> 0x080c5e45 in cirrus_do_copy (s=0x86134dc, dst=960000, src=0, w=2, h=9)
> >>>> at hw/cirrus_vga.c:687
> >>>> 687 sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
> >>>> (gdb) p depth
> >>>> $1 = 2
> >>>> (gdb) p s->cirrus_blt_srcpitch
> >>>> $2 = 0
> >>>>
> >>>>
> >>>> This qemu-kvm-0.12.3 - actually a debian package of it,
> >>>> but there's no patches relevant to video applied.
> >>>>
> >>>> Anything can be done with it?
> >>>>
> >>> Well, it's trivial to check for the condition, but how to handle it?
> >>>
> >>>
> >> That code is wrong. It shouldn't be using the bitblt source pitch, but
> >> the actual display pitch. If the two are different, then the blt
> >> doesn't actually affect a rectangular region, but instead a parallelogram.
> >>
> >>
> > Reading some documention about the Cirrus card we are emulating, it
> > seems that the source pitch is ignored in video to video operations, so
> > I think you are right here.
> >
>
> From what I've read I don't think it's ignored. Rather there are two
> separate pitches, one for bitblt and one for display.
>
> > The Windows NT driver probably relies on this behaviour and doesn't set
> > the source pitch properly before the bitblt.
> >
>
> Note it's just during mode changes. During normal operation I'm sure
> the pitches are equal.
>
The source blt pitch as set by the driver is always equal to the display
pitch (apart from the case reported above).
However cirrus_blt_srcpitch is not always equal to the display pitch
because of CIRRUS_BLTMODE_BACKWARDS: cirrus_blt_srcpitch can also be
negative and equal to -display_pitch.
I suggest to start using the display pitch (with the proper sign)
instead of cirrus_blt_srcpitch in cirrus_do_copy at least when
cirrus_blt_srcpitch doesn't have a proper value.
> I think the code should be something like
>
> if bitblt destination intersects display memory:
> if bitblt pitch == display pitch
> use console_copy
> else
> invalidate entire display
>
I think the following should be enough:
if bitblt destination intersects display memory:
qemu_console_copy
else
invalidate region
why do we need if bitblt pitch == display pitch or to invalidate
everything?
> >> 31c05501c says this breaks bitblt, but I can't see why this is true.
> >> The copy should update the display. This is probably due to a
> >> miscalculation of the affected region, and now we have two invalidates
> >> instead of one, reducing performance.
> >>
> >>
> > I agree with you: qemu_console_copy does imply that the copied portion
> > of the screen changed, so there is no reason to invalidate it again if
> > qemu_console_copy is called.
> >
>
> Well, we can't just revert 31c05501c. There's probably another bug
> involved.
>
Sure, we have to fix the other one first :)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 13:45 ` Stefano Stabellini
@ 2010-05-12 14:27 ` Avi Kivity
2010-05-12 15:57 ` Stefano Stabellini
0 siblings, 1 reply; 21+ messages in thread
From: Avi Kivity @ 2010-05-12 14:27 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list
On 05/12/2010 04:45 PM, Stefano Stabellini wrote:
>
>
>> Note it's just during mode changes. During normal operation I'm sure
>> the pitches are equal.
>>
>>
> The source blt pitch as set by the driver is always equal to the display
> pitch (apart from the case reported above).
> However cirrus_blt_srcpitch is not always equal to the display pitch
> because of CIRRUS_BLTMODE_BACKWARDS: cirrus_blt_srcpitch can also be
> negative and equal to -display_pitch.
>
Yes.
> I suggest to start using the display pitch (with the proper sign)
> instead of cirrus_blt_srcpitch in cirrus_do_copy at least when
> cirrus_blt_srcpitch doesn't have a proper value.
>
Why switch from one bug to the other?
It's perfectly possible to take into account both values. Of course
when abs(blt_pitch) != display pitch we can't use console_copy, but so what.
>> I think the code should be something like
>>
>> if bitblt destination intersects display memory:
>> if bitblt pitch == display pitch
>> use console_copy
>> else
>> invalidate entire display
>>
>>
> I think the following should be enough:
>
> if bitblt destination intersects display memory:
> qemu_console_copy
> else
> invalidate region
>
> why do we need if bitblt pitch == display pitch or to invalidate
> everything?
>
Because the region is not a rectangle anymore. We could compute exactly
what needs to be invalidated, but since it will never happen, there's no
point in optimizing it.
>>>> 31c05501c says this breaks bitblt, but I can't see why this is true.
>>>> The copy should update the display. This is probably due to a
>>>> miscalculation of the affected region, and now we have two invalidates
>>>> instead of one, reducing performance.
>>>>
>>>>
>>>>
>>> I agree with you: qemu_console_copy does imply that the copied portion
>>> of the screen changed, so there is no reason to invalidate it again if
>>> qemu_console_copy is called.
>>>
>>>
>> Well, we can't just revert 31c05501c. There's probably another bug
>> involved.
>>
>>
> Sure, we have to fix the other one first :)
>
And find it.
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 14:27 ` Avi Kivity
@ 2010-05-12 15:57 ` Stefano Stabellini
2010-05-12 16:07 ` Avi Kivity
2010-05-13 7:36 ` Paolo Bonzini
0 siblings, 2 replies; 21+ messages in thread
From: Stefano Stabellini @ 2010-05-12 15:57 UTC (permalink / raw)
To: Avi Kivity
Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list,
Stefano Stabellini
On Wed, 12 May 2010, Avi Kivity wrote:
> > I suggest to start using the display pitch (with the proper sign)
> > instead of cirrus_blt_srcpitch in cirrus_do_copy at least when
> > cirrus_blt_srcpitch doesn't have a proper value.
> >
>
> Why switch from one bug to the other?
>
> It's perfectly possible to take into account both values. Of course
> when abs(blt_pitch) != display pitch we can't use console_copy, but so what.
>
I see: you want to support the case when abs(src_blt_pitch) != display_pitch,
while I though it is some sort of error.
Considering that src_blt_pitch can even be 0 (as in the bug report), we
would still need to calculate sx and sy using display_pitch instead, so
the only place in which it would make a difference is when src_blt_pitch
is passed as an argument to cirrus_rop.
I guess even a src blt pitch of 0 could be useful there, however in
practice I think the only rop function that was written with this case in
mind has:
dstpitch -= bltwidth;
srcpitch -= bltwidth;
if (dstpitch < 0 || srcpitch < 0) {
/* is 0 valid? srcpitch == 0 could be useful */
return;
}
at the beginning and the others probably just don't deal with the case
with possibly buggy consequences.
Also the documentation I have states:
3CEh index 26h W(R/W): BLT Source Pitch (5426 +)
bit 0-11 (5426-28) Number of bytes in a scanline at the source.
0-12 (5429 +) do
if the source BLT is supposed to be the number of bytes in a scanline at
the source, then 0 is not a correct value for it.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 15:57 ` Stefano Stabellini
@ 2010-05-12 16:07 ` Avi Kivity
2010-05-12 16:55 ` Stefano Stabellini
2010-05-13 7:36 ` Paolo Bonzini
1 sibling, 1 reply; 21+ messages in thread
From: Avi Kivity @ 2010-05-12 16:07 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list
On 05/12/2010 06:57 PM, Stefano Stabellini wrote:
> On Wed, 12 May 2010, Avi Kivity wrote:
>
>>> I suggest to start using the display pitch (with the proper sign)
>>> instead of cirrus_blt_srcpitch in cirrus_do_copy at least when
>>> cirrus_blt_srcpitch doesn't have a proper value.
>>>
>>>
>> Why switch from one bug to the other?
>>
>> It's perfectly possible to take into account both values. Of course
>> when abs(blt_pitch) != display pitch we can't use console_copy, but so what.
>>
>>
> I see: you want to support the case when abs(src_blt_pitch) != display_pitch,
> while I though it is some sort of error.
>
When blting withinh the screen, it is an error from the point of view of
writing a sane driver. My guess is that it's a bug in the NT driver.
It's not an error from the point of view of the hardware, or when blting
offscreen bitmaps (which can have different geomeries than the display).
> Considering that src_blt_pitch can even be 0 (as in the bug report), we
> would still need to calculate sx and sy using display_pitch instead, so
> the only place in which it would make a difference is when src_blt_pitch
> is passed as an argument to cirrus_rop.
>
cirrus_rop() and its arguments don't need to change. They're correctly
using the blt pitch.
My point is: x[xy] and d[xy] are only valid if both source and
destination overlap the display, and if both src_pitch and dst_pitch are
absequal to the display pitch. When they aren't valid, there's no point
in calculating them or using them in anything. The raster operation is
still valid though.
> I guess even a src blt pitch of 0 could be useful there, however in
> practice I think the only rop function that was written with this case in
> mind has:
>
> dstpitch -= bltwidth;
> srcpitch -= bltwidth;
>
> if (dstpitch< 0 || srcpitch< 0) {
> /* is 0 valid? srcpitch == 0 could be useful */
> return;
> }
>
> at the beginning and the others probably just don't deal with the case
> with possibly buggy consequences.
> Also the documentation I have states:
>
> 3CEh index 26h W(R/W): BLT Source Pitch (5426 +)
> bit 0-11 (5426-28) Number of bytes in a scanline at the source.
> 0-12 (5429 +) do
>
> if the source BLT is supposed to be the number of bytes in a scanline at
> the source, then 0 is not a correct value for it.
>
It's useful if you have a one-line horizontal pattern you want to
propagate all over.
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 16:07 ` Avi Kivity
@ 2010-05-12 16:55 ` Stefano Stabellini
2010-05-12 16:57 ` Avi Kivity
2010-05-12 17:07 ` Jamie Lokier
0 siblings, 2 replies; 21+ messages in thread
From: Stefano Stabellini @ 2010-05-12 16:55 UTC (permalink / raw)
To: Avi Kivity
Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list,
Stefano Stabellini
On Wed, 12 May 2010, Avi Kivity wrote:
> > I guess even a src blt pitch of 0 could be useful there, however in
> > practice I think the only rop function that was written with this case in
> > mind has:
> >
> > dstpitch -= bltwidth;
> > srcpitch -= bltwidth;
> >
> > if (dstpitch< 0 || srcpitch< 0) {
> > /* is 0 valid? srcpitch == 0 could be useful */
> > return;
> > }
> >
> > at the beginning and the others probably just don't deal with the case
> > with possibly buggy consequences.
> > Also the documentation I have states:
> >
> > 3CEh index 26h W(R/W): BLT Source Pitch (5426 +)
> > bit 0-11 (5426-28) Number of bytes in a scanline at the source.
> > 0-12 (5429 +) do
> >
> > if the source BLT is supposed to be the number of bytes in a scanline at
> > the source, then 0 is not a correct value for it.
> >
>
> It's useful if you have a one-line horizontal pattern you want to
> propagate all over.
>
It might be useful all right, but it is not entirely clear what the
hardware should do in this situation from the documentation we have, and
certainly the current state of the cirrus emulation code doesn't help.
Without any clear indication of what a Cirrus Logic graphic card would
have done here, I would choose the safest answer that is disregard the
"delicate" case (if it doesn't break Windows NT).
However I don't mind if we try to handle this case too, provided
that we handle it well, without SIGFPEs that is :)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 16:55 ` Stefano Stabellini
@ 2010-05-12 16:57 ` Avi Kivity
2010-05-12 17:07 ` Jamie Lokier
1 sibling, 0 replies; 21+ messages in thread
From: Avi Kivity @ 2010-05-12 16:57 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list
On 05/12/2010 07:55 PM, Stefano Stabellini wrote:
>
>>> 3CEh index 26h W(R/W): BLT Source Pitch (5426 +)
>>> bit 0-11 (5426-28) Number of bytes in a scanline at the source.
>>> 0-12 (5429 +) do
>>>
>>> if the source BLT is supposed to be the number of bytes in a scanline at
>>> the source, then 0 is not a correct value for it.
>>>
>>>
>> It's useful if you have a one-line horizontal pattern you want to
>> propagate all over.
>>
>>
>
> It might be useful all right, but it is not entirely clear what the
> hardware should do in this situation from the documentation we have, and
> certainly the current state of the cirrus emulation code doesn't help.
>
> Without any clear indication of what a Cirrus Logic graphic card would
> have done here, I would choose the safest answer that is disregard the
> "delicate" case (if it doesn't break Windows NT).
>
My guess is that the src or dst address simply doesn't increment. I
think it's also fine to ignore the operation completely.
> However I don't mind if we try to handle this case too, provided
> that we handle it well, without SIGFPEs that is :)
>
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 16:55 ` Stefano Stabellini
2010-05-12 16:57 ` Avi Kivity
@ 2010-05-12 17:07 ` Jamie Lokier
2010-05-12 18:11 ` Stefano Stabellini
1 sibling, 1 reply; 21+ messages in thread
From: Jamie Lokier @ 2010-05-12 17:07 UTC (permalink / raw)
To: Stefano Stabellini
Cc: Michael Tokarev, Brian Kress, Avi Kivity, KVM list, qemu-devel
Stefano Stabellini wrote:
> On Wed, 12 May 2010, Avi Kivity wrote:
> > It's useful if you have a one-line horizontal pattern you want to
> > propagate all over.
>
> It might be useful all right, but it is not entirely clear what the
> hardware should do in this situation from the documentation we have, and
> certainly the current state of the cirrus emulation code doesn't help.
It's quite a reasonable thing for hardware to do, even if not documented.
It would be surprising if the hardware didn't copy the one-line pattern.
-- Jamie
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 17:07 ` Jamie Lokier
@ 2010-05-12 18:11 ` Stefano Stabellini
2010-05-12 19:12 ` Michael Tokarev
` (3 more replies)
0 siblings, 4 replies; 21+ messages in thread
From: Stefano Stabellini @ 2010-05-12 18:11 UTC (permalink / raw)
To: Jamie Lokier
Cc: KVM list, Stefano Stabellini, Michael Tokarev, qemu-devel,
Avi Kivity, Brian Kress
On Wed, 12 May 2010, Jamie Lokier wrote:
> Stefano Stabellini wrote:
> > On Wed, 12 May 2010, Avi Kivity wrote:
> > > It's useful if you have a one-line horizontal pattern you want to
> > > propagate all over.
> >
> > It might be useful all right, but it is not entirely clear what the
> > hardware should do in this situation from the documentation we have, and
> > certainly the current state of the cirrus emulation code doesn't help.
>
> It's quite a reasonable thing for hardware to do, even if not documented.
> It would be surprising if the hardware didn't copy the one-line pattern.
All right then, you convinced me :)
This is my proposed solution, however it is untested with Windows NT.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 9f61a01..a7f0d3c 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -676,15 +676,17 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
int sx, sy;
int dx, dy;
int width, height;
+ uint32_t start_addr, line_offset, line_compare;
int depth;
int notify = 0;
depth = s->vga.get_bpp(&s->vga) / 8;
s->vga.get_resolution(&s->vga, &width, &height);
+ s->vga.get_offsets(&s->vga, &line_offset, &start_addr, &line_compare);
/* extra x, y */
- sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
- sy = (src / ABS(s->cirrus_blt_srcpitch));
+ sx = (src % line_offset) / depth;
+ sy = (src / line_offset);
dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
dy = (dst / ABS(s->cirrus_blt_dstpitch));
@@ -725,18 +727,23 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
s->cirrus_blt_width, s->cirrus_blt_height);
- if (notify)
- qemu_console_copy(s->vga.ds,
- sx, sy, dx, dy,
- s->cirrus_blt_width / depth,
- s->cirrus_blt_height);
-
- /* we don't have to notify the display that this portion has
- changed since qemu_console_copy implies this */
-
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
+ if (ABS(s->cirrus_blt_dstpitch) != line_offset ||
+ ABS(s->cirrus_blt_srcpitch) != line_offset) {
+ /* this is not going to happen very often */
+ vga_hw_invalidate();
+ } else {
+ if (notify)
+ /* we don't have to notify the display that this portion has
+ changed since qemu_console_copy implies this */
+ qemu_console_copy(s->vga.ds,
+ sx, sy, dx, dy,
+ s->cirrus_blt_width / depth,
+ s->cirrus_blt_height);
+ else
+ cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+ s->cirrus_blt_dstpitch, s->cirrus_blt_width,
+ s->cirrus_blt_height);
+ }
}
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
index 39a7b72..80f135b 100644
--- a/hw/cirrus_vga_rop.h
+++ b/hw/cirrus_vga_rop.h
@@ -32,10 +32,10 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
dstpitch -= bltwidth;
srcpitch -= bltwidth;
- if (dstpitch < 0 || srcpitch < 0) {
- /* is 0 valid? srcpitch == 0 could be useful */
+ if (dstpitch < 0)
return;
- }
+ if (srcpitch < 0)
+ srcpitch = 0;
for (y = 0; y < bltheight; y++) {
for (x = 0; x < bltwidth; x++) {
@@ -57,6 +57,12 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
int x,y;
dstpitch += bltwidth;
srcpitch += bltwidth;
+
+ if (dstpitch > 0)
+ return;
+ if (srcpitch > 0)
+ srcpitch = 0;
+
for (y = 0; y < bltheight; y++) {
for (x = 0; x < bltwidth; x++) {
ROP_OP(*dst, *src);
@@ -78,6 +84,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
uint8_t p;
dstpitch -= bltwidth;
srcpitch -= bltwidth;
+
+ if (dstpitch < 0)
+ return;
+ if (srcpitch < 0)
+ srcpitch = 0;
+
for (y = 0; y < bltheight; y++) {
for (x = 0; x < bltwidth; x++) {
p = *dst;
@@ -101,6 +113,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
uint8_t p;
dstpitch += bltwidth;
srcpitch += bltwidth;
+
+ if (dstpitch > 0)
+ return;
+ if (srcpitch > 0)
+ srcpitch = 0;
+
for (y = 0; y < bltheight; y++) {
for (x = 0; x < bltwidth; x++) {
p = *dst;
@@ -124,6 +142,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
uint8_t p1, p2;
dstpitch -= bltwidth;
srcpitch -= bltwidth;
+
+ if (dstpitch < 0)
+ return;
+ if (srcpitch < 0)
+ srcpitch = 0;
+
for (y = 0; y < bltheight; y++) {
for (x = 0; x < bltwidth; x+=2) {
p1 = *dst;
@@ -152,6 +176,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
uint8_t p1, p2;
dstpitch += bltwidth;
srcpitch += bltwidth;
+
+ if (dstpitch > 0)
+ return;
+ if (srcpitch > 0)
+ srcpitch = 0;
+
for (y = 0; y < bltheight; y++) {
for (x = 0; x < bltwidth; x+=2) {
p1 = *(dst-1);
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 18:11 ` Stefano Stabellini
@ 2010-05-12 19:12 ` Michael Tokarev
2010-05-13 6:49 ` Avi Kivity
` (2 subsequent siblings)
3 siblings, 0 replies; 21+ messages in thread
From: Michael Tokarev @ 2010-05-12 19:12 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Avi Kivity, KVM list, qemu-devel
12.05.2010 22:11, Stefano Stabellini wrote:
> On Wed, 12 May 2010, Jamie Lokier wrote:
>> Stefano Stabellini wrote:
>>> On Wed, 12 May 2010, Avi Kivity wrote:
>>>> It's useful if you have a one-line horizontal pattern you want to
>>>> propagate all over.
>>>
>>> It might be useful all right, but it is not entirely clear what the
>>> hardware should do in this situation from the documentation we have, and
>>> certainly the current state of the cirrus emulation code doesn't help.
>>
>> It's quite a reasonable thing for hardware to do, even if not documented.
>> It would be surprising if the hardware didn't copy the one-line pattern.
>
> All right then, you convinced me :)
>
> This is my proposed solution, however it is untested with Windows NT.
Well. At least it does not crash anymore.
With this patch applied, when hitting "Test" (of a new video mode)
button on WindowsNT, the guest window gets resized to correct size,
but is painted with yellow and nothing happens. The CPU enters
100%, and on the kvm console the following messages are displayed:
BUG: kvm_dirty_pages_log_enable_slot: invalid parameters
BUG: kvm_dirty_pages_log_enable_slot: invalid parameters
That's not new, it sometimes displays that shit on attempt to
migrate too, as I mentioned in another thread.
Thanks!
/mjt
> diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> index 9f61a01..a7f0d3c 100644
> --- a/hw/cirrus_vga.c
> +++ b/hw/cirrus_vga.c
> @@ -676,15 +676,17 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
> int sx, sy;
> int dx, dy;
> int width, height;
> + uint32_t start_addr, line_offset, line_compare;
> int depth;
> int notify = 0;
[...]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 18:11 ` Stefano Stabellini
2010-05-12 19:12 ` Michael Tokarev
@ 2010-05-13 6:49 ` Avi Kivity
2010-05-13 13:48 ` Stefano Stabellini
2010-05-28 20:51 ` Michael Tokarev
2010-05-30 8:24 ` Avi Kivity
3 siblings, 1 reply; 21+ messages in thread
From: Avi Kivity @ 2010-05-13 6:49 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list
On 05/12/2010 09:11 PM, Stefano Stabellini wrote:
> On Wed, 12 May 2010, Jamie Lokier wrote:
>
>> Stefano Stabellini wrote:
>>
>>> On Wed, 12 May 2010, Avi Kivity wrote:
>>>
>>>> It's useful if you have a one-line horizontal pattern you want to
>>>> propagate all over.
>>>>
>>>
>>> It might be useful all right, but it is not entirely clear what the
>>> hardware should do in this situation from the documentation we have, and
>>> certainly the current state of the cirrus emulation code doesn't help.
>>>
>> It's quite a reasonable thing for hardware to do, even if not documented.
>> It would be surprising if the hardware didn't copy the one-line pattern.
>>
>
> All right then, you convinced me :)
>
> This is my proposed solution, however it is untested with Windows NT.
>
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
>
> ---
>
>
>
> diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> index 9f61a01..a7f0d3c 100644
> --- a/hw/cirrus_vga.c
> +++ b/hw/cirrus_vga.c
> @@ -676,15 +676,17 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
> int sx, sy;
> int dx, dy;
> int width, height;
> + uint32_t start_addr, line_offset, line_compare;
> int depth;
> int notify = 0;
>
> depth = s->vga.get_bpp(&s->vga) / 8;
> s->vga.get_resolution(&s->vga,&width,&height);
> + s->vga.get_offsets(&s->vga,&line_offset,&start_addr,&line_compare);
>
> /* extra x, y */
> - sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
> - sy = (src / ABS(s->cirrus_blt_srcpitch));
> + sx = (src % line_offset) / depth;
> + sy = (src / line_offset);
>
Does anything prevent the guest from programming the CRTC display pitch
to 0?
> dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
> dy = (dst / ABS(s->cirrus_blt_dstpitch));
>
> @@ -725,18 +727,23 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
> s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
> s->cirrus_blt_width, s->cirrus_blt_height);
>
> - if (notify)
> - qemu_console_copy(s->vga.ds,
> - sx, sy, dx, dy,
> - s->cirrus_blt_width / depth,
> - s->cirrus_blt_height);
> -
> - /* we don't have to notify the display that this portion has
> - changed since qemu_console_copy implies this */
> -
> - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> - s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> - s->cirrus_blt_height);
> + if (ABS(s->cirrus_blt_dstpitch) != line_offset ||
> + ABS(s->cirrus_blt_srcpitch) != line_offset) {
> + /* this is not going to happen very often */
> + vga_hw_invalidate();
>
I think we need to consider only dstpitch for a full invalidate. We
might be copying an offscreen bitmap into the screen, and srcpitch is
likely to be the bitmap width instead of the screen pitch.
> + } else {
> + if (notify)
> + /* we don't have to notify the display that this portion has
> + changed since qemu_console_copy implies this */
> + qemu_console_copy(s->vga.ds,
> + sx, sy, dx, dy,
> + s->cirrus_blt_width / depth,
> + s->cirrus_blt_height);
> + else
> + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> + s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> + s->cirrus_blt_height);
> + }
> }
>
> static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
> diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
> index 39a7b72..80f135b 100644
> --- a/hw/cirrus_vga_rop.h
> +++ b/hw/cirrus_vga_rop.h
> @@ -32,10 +32,10 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
> dstpitch -= bltwidth;
> srcpitch -= bltwidth;
>
> - if (dstpitch< 0 || srcpitch< 0) {
> - /* is 0 valid? srcpitch == 0 could be useful */
> + if (dstpitch< 0)
> return;
> - }
> + if (srcpitch< 0)
> + srcpitch = 0;
>
Why?
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 15:57 ` Stefano Stabellini
2010-05-12 16:07 ` Avi Kivity
@ 2010-05-13 7:36 ` Paolo Bonzini
1 sibling, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2010-05-13 7:36 UTC (permalink / raw)
To: Stefano Stabellini
Cc: Brian Kress, Michael Tokarev, Avi Kivity, KVM list, qemu-devel
On 05/12/2010 05:57 PM, Stefano Stabellini wrote:
> I guess even a src blt pitch of 0 could be useful there, however in
> practice I think the only rop function that was written with this case in
> mind has:
>
> dstpitch -= bltwidth;
> srcpitch -= bltwidth;
>
> if (dstpitch< 0 || srcpitch< 0) {
> /* is 0 valid? srcpitch == 0 could be useful */
> return;
> }
Note that here srcpitch == 0 is actually srcpitch == bltwidth, which
_is_ obviously useful.
The "real" srcpitch == 0 case would result in srcpitch == -bltwidth, and
it is actually quite useful if you want to stretch a Nx1 bitmap to NxN.
Paolo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-13 6:49 ` Avi Kivity
@ 2010-05-13 13:48 ` Stefano Stabellini
2010-05-13 14:13 ` Michael Tokarev
2010-05-13 16:04 ` Jamie Lokier
0 siblings, 2 replies; 21+ messages in thread
From: Stefano Stabellini @ 2010-05-13 13:48 UTC (permalink / raw)
To: Avi Kivity
Cc: KVM list, Stefano Stabellini, Michael Tokarev, qemu-devel,
Brian Kress
On Thu, 13 May 2010, Avi Kivity wrote:
> > /* extra x, y */
> > - sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
> > - sy = (src / ABS(s->cirrus_blt_srcpitch));
> > + sx = (src % line_offset) / depth;
> > + sy = (src / line_offset);
> >
>
> Does anything prevent the guest from programming the CRTC display pitch
> to 0?
>
Nope, I'll use line_offset there too to prevent possible divisions by 0.
> > dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
> > dy = (dst / ABS(s->cirrus_blt_dstpitch));
> >
> > @@ -725,18 +727,23 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
> > s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
> > s->cirrus_blt_width, s->cirrus_blt_height);
> >
> > - if (notify)
> > - qemu_console_copy(s->vga.ds,
> > - sx, sy, dx, dy,
> > - s->cirrus_blt_width / depth,
> > - s->cirrus_blt_height);
> > -
> > - /* we don't have to notify the display that this portion has
> > - changed since qemu_console_copy implies this */
> > -
> > - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> > - s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> > - s->cirrus_blt_height);
> > + if (ABS(s->cirrus_blt_dstpitch) != line_offset ||
> > + ABS(s->cirrus_blt_srcpitch) != line_offset) {
> > + /* this is not going to happen very often */
> > + vga_hw_invalidate();
> >
>
> I think we need to consider only dstpitch for a full invalidate. We
> might be copying an offscreen bitmap into the screen, and srcpitch is
> likely to be the bitmap width instead of the screen pitch.
>
Agreed.
>
> > + } else {
> > + if (notify)
> > + /* we don't have to notify the display that this portion has
> > + changed since qemu_console_copy implies this */
> > + qemu_console_copy(s->vga.ds,
> > + sx, sy, dx, dy,
> > + s->cirrus_blt_width / depth,
> > + s->cirrus_blt_height);
> > + else
> > + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> > + s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> > + s->cirrus_blt_height);
> > + }
> > }
> >
> > static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
> > diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
> > index 39a7b72..80f135b 100644
> > --- a/hw/cirrus_vga_rop.h
> > +++ b/hw/cirrus_vga_rop.h
> > @@ -32,10 +32,10 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
> > dstpitch -= bltwidth;
> > srcpitch -= bltwidth;
> >
> > - if (dstpitch< 0 || srcpitch< 0) {
> > - /* is 0 valid? srcpitch == 0 could be useful */
> > + if (dstpitch< 0)
> > return;
> > - }
> > + if (srcpitch< 0)
> > + srcpitch = 0;
> >
>
> Why?
I wouldn't want an operation that is supposed to be a forward copy
to become a backward copy instead.
With the way the code is currently written in cirrus_vga it shouldn't be
possible, but it might be a good idea to have the checks anyway.
Actually the limit I wrote is too strict, I'll fix it.
---
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 9f61a01..81c443b 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -676,17 +676,19 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
int sx, sy;
int dx, dy;
int width, height;
+ uint32_t start_addr, line_offset, line_compare;
int depth;
int notify = 0;
depth = s->vga.get_bpp(&s->vga) / 8;
s->vga.get_resolution(&s->vga, &width, &height);
+ s->vga.get_offsets(&s->vga, &line_offset, &start_addr, &line_compare);
/* extra x, y */
- sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
- sy = (src / ABS(s->cirrus_blt_srcpitch));
- dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
- dy = (dst / ABS(s->cirrus_blt_dstpitch));
+ sx = (src % line_offset) / depth;
+ sy = (src / line_offset);
+ dx = (dst % line_offset) / depth;
+ dy = (dst / line_offset);
/* normalize width */
w /= depth;
@@ -725,18 +727,22 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
s->cirrus_blt_width, s->cirrus_blt_height);
- if (notify)
- qemu_console_copy(s->vga.ds,
- sx, sy, dx, dy,
- s->cirrus_blt_width / depth,
- s->cirrus_blt_height);
-
- /* we don't have to notify the display that this portion has
- changed since qemu_console_copy implies this */
-
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
+ if (ABS(s->cirrus_blt_dstpitch) != line_offset) {
+ /* this is not going to happen very often */
+ vga_hw_invalidate();
+ } else {
+ if (ABS(s->cirrus_blt_srcpitch) == line_offset && notify)
+ /* we don't have to notify the display that this portion has
+ changed since qemu_console_copy implies this */
+ qemu_console_copy(s->vga.ds,
+ sx, sy, dx, dy,
+ s->cirrus_blt_width / depth,
+ s->cirrus_blt_height);
+ else
+ cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+ s->cirrus_blt_dstpitch, s->cirrus_blt_width,
+ s->cirrus_blt_height);
+ }
}
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
index 39a7b72..3d41d41 100644
--- a/hw/cirrus_vga_rop.h
+++ b/hw/cirrus_vga_rop.h
@@ -29,13 +29,11 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
int bltwidth,int bltheight)
{
int x,y;
- dstpitch -= bltwidth;
- srcpitch -= bltwidth;
- if (dstpitch < 0 || srcpitch < 0) {
- /* is 0 valid? srcpitch == 0 could be useful */
+ if (dstpitch < 0 || srcpitch < 0)
return;
- }
+ dstpitch -= bltwidth;
+ srcpitch -= bltwidth;
for (y = 0; y < bltheight; y++) {
for (x = 0; x < bltwidth; x++) {
@@ -55,6 +53,9 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
int bltwidth,int bltheight)
{
int x,y;
+
+ if (dstpitch > 0 || srcpitch > 0)
+ return;
dstpitch += bltwidth;
srcpitch += bltwidth;
for (y = 0; y < bltheight; y++) {
@@ -76,6 +77,9 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
{
int x,y;
uint8_t p;
+
+ if (dstpitch < 0 || srcpitch < 0)
+ return;
dstpitch -= bltwidth;
srcpitch -= bltwidth;
for (y = 0; y < bltheight; y++) {
@@ -99,6 +103,9 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
{
int x,y;
uint8_t p;
+
+ if (dstpitch > 0 || srcpitch > 0)
+ return;
dstpitch += bltwidth;
srcpitch += bltwidth;
for (y = 0; y < bltheight; y++) {
@@ -122,6 +129,9 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
{
int x,y;
uint8_t p1, p2;
+
+ if (dstpitch < 0 || srcpitch < 0)
+ return;
dstpitch -= bltwidth;
srcpitch -= bltwidth;
for (y = 0; y < bltheight; y++) {
@@ -150,6 +160,9 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
{
int x,y;
uint8_t p1, p2;
+
+ if (dstpitch > 0 || srcpitch > 0)
+ return;
dstpitch += bltwidth;
srcpitch += bltwidth;
for (y = 0; y < bltheight; y++) {
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-13 13:48 ` Stefano Stabellini
@ 2010-05-13 14:13 ` Michael Tokarev
2010-05-13 18:03 ` Stefano Stabellini
2010-05-13 16:04 ` Jamie Lokier
1 sibling, 1 reply; 21+ messages in thread
From: Michael Tokarev @ 2010-05-13 14:13 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Avi Kivity, KVM list, qemu-devel
Stefano Stabellini wrote:
[]
> diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> index 9f61a01..81c443b 100644
> --- a/hw/cirrus_vga.c
> +++ b/hw/cirrus_vga.c
The same as with previous patch: Yellow screen
(instead of crashing), and two lines on the
stderr:
BUG: kvm_dirty_pages_log_enable_slot: invalid parameters
BUG: kvm_dirty_pages_log_enable_slot: invalid parameters
Thanks!
/mjt
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-13 13:48 ` Stefano Stabellini
2010-05-13 14:13 ` Michael Tokarev
@ 2010-05-13 16:04 ` Jamie Lokier
1 sibling, 0 replies; 21+ messages in thread
From: Jamie Lokier @ 2010-05-13 16:04 UTC (permalink / raw)
To: Stefano Stabellini
Cc: Michael Tokarev, Brian Kress, Avi Kivity, KVM list, qemu-devel
Stefano Stabellini wrote:
> > I think we need to consider only dstpitch for a full invalidate. We
> > might be copying an offscreen bitmap into the screen, and srcpitch is
> > likely to be the bitmap width instead of the screen pitch.
>
> Agreed.
Even when copying on-screen (or partially on-screen), the srcpitch
does not affect the invalidated area. The source area might be
strange (parallelogram, single line repeated), but srcpitch should
only affect whether qemu_console_copy can be used, not the
invalidation.
-- Jamie
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-13 14:13 ` Michael Tokarev
@ 2010-05-13 18:03 ` Stefano Stabellini
0 siblings, 0 replies; 21+ messages in thread
From: Stefano Stabellini @ 2010-05-13 18:03 UTC (permalink / raw)
To: Michael Tokarev
Cc: KVM list, Stefano Stabellini, qemu-devel, Avi Kivity, Brian Kress
On Thu, 13 May 2010, Michael Tokarev wrote:
> Stefano Stabellini wrote:
> []
> > diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> > index 9f61a01..81c443b 100644
> > --- a/hw/cirrus_vga.c
> > +++ b/hw/cirrus_vga.c
>
> The same as with previous patch: Yellow screen
> (instead of crashing), and two lines on the
> stderr:
>
> BUG: kvm_dirty_pages_log_enable_slot: invalid parameters
> BUG: kvm_dirty_pages_log_enable_slot: invalid parameters
>
I tried to do the same thing on WinNT with qemu (thanks to
Michael for providing me the image) and it works OK with the
patch applied.
I think there must be another bug in the kvm dirty page handling...
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 18:11 ` Stefano Stabellini
2010-05-12 19:12 ` Michael Tokarev
2010-05-13 6:49 ` Avi Kivity
@ 2010-05-28 20:51 ` Michael Tokarev
2010-05-30 8:24 ` Avi Kivity
3 siblings, 0 replies; 21+ messages in thread
From: Michael Tokarev @ 2010-05-28 20:51 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Avi Kivity, KVM list, qemu-devel
12.05.2010 22:11, Stefano Stabellini wrote:
> On Wed, 12 May 2010, Jamie Lokier wrote:
>> Stefano Stabellini wrote:
>>> On Wed, 12 May 2010, Avi Kivity wrote:
>>>> It's useful if you have a one-line horizontal pattern you want to
>>>> propagate all over.
>>>
>>> It might be useful all right, but it is not entirely clear what the
>>> hardware should do in this situation from the documentation we have, and
>>> certainly the current state of the cirrus emulation code doesn't help.
>>
>> It's quite a reasonable thing for hardware to do, even if not documented.
>> It would be surprising if the hardware didn't copy the one-line pattern.
>
> All right then, you convinced me :)
>
> This is my proposed solution, however it is untested with Windows NT.
>
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
So.. what's the status of this, after all? :)
As far as I can tell, it has been agreed that the patch
is good, and verified that it fixes the problem. Should
we just throw it away and start from scratch, or what? :)
Thanks!
> diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> index 9f61a01..a7f0d3c 100644
> --- a/hw/cirrus_vga.c
> +++ b/hw/cirrus_vga.c
> @@ -676,15 +676,17 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
> int sx, sy;
> int dx, dy;
> int width, height;
> + uint32_t start_addr, line_offset, line_compare;
> int depth;
> int notify = 0;
>
> depth = s->vga.get_bpp(&s->vga) / 8;
> s->vga.get_resolution(&s->vga,&width,&height);
> + s->vga.get_offsets(&s->vga,&line_offset,&start_addr,&line_compare);
>
> /* extra x, y */
> - sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
> - sy = (src / ABS(s->cirrus_blt_srcpitch));
> + sx = (src % line_offset) / depth;
> + sy = (src / line_offset);
> dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
> dy = (dst / ABS(s->cirrus_blt_dstpitch));
>
> @@ -725,18 +727,23 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
> s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
> s->cirrus_blt_width, s->cirrus_blt_height);
>
> - if (notify)
> - qemu_console_copy(s->vga.ds,
> - sx, sy, dx, dy,
> - s->cirrus_blt_width / depth,
> - s->cirrus_blt_height);
> -
> - /* we don't have to notify the display that this portion has
> - changed since qemu_console_copy implies this */
> -
> - cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> - s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> - s->cirrus_blt_height);
> + if (ABS(s->cirrus_blt_dstpitch) != line_offset ||
> + ABS(s->cirrus_blt_srcpitch) != line_offset) {
> + /* this is not going to happen very often */
> + vga_hw_invalidate();
> + } else {
> + if (notify)
> + /* we don't have to notify the display that this portion has
> + changed since qemu_console_copy implies this */
> + qemu_console_copy(s->vga.ds,
> + sx, sy, dx, dy,
> + s->cirrus_blt_width / depth,
> + s->cirrus_blt_height);
> + else
> + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
> + s->cirrus_blt_dstpitch, s->cirrus_blt_width,
> + s->cirrus_blt_height);
> + }
> }
>
> static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
> diff --git a/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
> index 39a7b72..80f135b 100644
> --- a/hw/cirrus_vga_rop.h
> +++ b/hw/cirrus_vga_rop.h
> @@ -32,10 +32,10 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
> dstpitch -= bltwidth;
> srcpitch -= bltwidth;
>
> - if (dstpitch< 0 || srcpitch< 0) {
> - /* is 0 valid? srcpitch == 0 could be useful */
> + if (dstpitch< 0)
> return;
> - }
> + if (srcpitch< 0)
> + srcpitch = 0;
>
> for (y = 0; y< bltheight; y++) {
> for (x = 0; x< bltwidth; x++) {
> @@ -57,6 +57,12 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
> int x,y;
> dstpitch += bltwidth;
> srcpitch += bltwidth;
> +
> + if (dstpitch> 0)
> + return;
> + if (srcpitch> 0)
> + srcpitch = 0;
> +
> for (y = 0; y< bltheight; y++) {
> for (x = 0; x< bltwidth; x++) {
> ROP_OP(*dst, *src);
> @@ -78,6 +84,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
> uint8_t p;
> dstpitch -= bltwidth;
> srcpitch -= bltwidth;
> +
> + if (dstpitch< 0)
> + return;
> + if (srcpitch< 0)
> + srcpitch = 0;
> +
> for (y = 0; y< bltheight; y++) {
> for (x = 0; x< bltwidth; x++) {
> p = *dst;
> @@ -101,6 +113,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
> uint8_t p;
> dstpitch += bltwidth;
> srcpitch += bltwidth;
> +
> + if (dstpitch> 0)
> + return;
> + if (srcpitch> 0)
> + srcpitch = 0;
> +
> for (y = 0; y< bltheight; y++) {
> for (x = 0; x< bltwidth; x++) {
> p = *dst;
> @@ -124,6 +142,12 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
> uint8_t p1, p2;
> dstpitch -= bltwidth;
> srcpitch -= bltwidth;
> +
> + if (dstpitch< 0)
> + return;
> + if (srcpitch< 0)
> + srcpitch = 0;
> +
> for (y = 0; y< bltheight; y++) {
> for (x = 0; x< bltwidth; x+=2) {
> p1 = *dst;
> @@ -152,6 +176,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
> uint8_t p1, p2;
> dstpitch += bltwidth;
> srcpitch += bltwidth;
> +
> + if (dstpitch> 0)
> + return;
> + if (srcpitch> 0)
> + srcpitch = 0;
> +
> for (y = 0; y< bltheight; y++) {
> for (x = 0; x< bltwidth; x+=2) {
> p1 = *(dst-1);
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus
2010-05-12 18:11 ` Stefano Stabellini
` (2 preceding siblings ...)
2010-05-28 20:51 ` Michael Tokarev
@ 2010-05-30 8:24 ` Avi Kivity
3 siblings, 0 replies; 21+ messages in thread
From: Avi Kivity @ 2010-05-30 8:24 UTC (permalink / raw)
To: Stefano Stabellini; +Cc: Brian Kress, Michael Tokarev, qemu-devel, KVM list
On 05/12/2010 09:11 PM, Stefano Stabellini wrote:
> On Wed, 12 May 2010, Jamie Lokier wrote:
>
>> Stefano Stabellini wrote:
>>
>>> On Wed, 12 May 2010, Avi Kivity wrote:
>>>
>>>> It's useful if you have a one-line horizontal pattern you want to
>>>> propagate all over.
>>>>
>>>
>>> It might be useful all right, but it is not entirely clear what the
>>> hardware should do in this situation from the documentation we have, and
>>> certainly the current state of the cirrus emulation code doesn't help.
>>>
>> It's quite a reasonable thing for hardware to do, even if not documented.
>> It would be surprising if the hardware didn't copy the one-line pattern.
>>
>
> All right then, you convinced me :)
>
> This is my proposed solution, however it is untested with Windows NT.
>
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
>
> ---
>
>
>
> diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> index 9f61a01..a7f0d3c 100644
> --- a/hw/cirrus_vga.c
> +++ b/hw/cirrus_vga.c
> @@ -676,15 +676,17 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
> int sx, sy;
> int dx, dy;
> int width, height;
> + uint32_t start_addr, line_offset, line_compare;
> int depth;
> int notify = 0;
>
> depth = s->vga.get_bpp(&s->vga) / 8;
> s->vga.get_resolution(&s->vga,&width,&height);
> + s->vga.get_offsets(&s->vga,&line_offset,&start_addr,&line_compare);
>
> /* extra x, y */
> - sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
> - sy = (src / ABS(s->cirrus_blt_srcpitch));
> + sx = (src % line_offset) / depth;
> + sy = (src / line_offset);
> dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
> dy = (dst / ABS(s->cirrus_blt_dstpitch));
>
dx/dy also need to be calculated according to line_offset.
I think the rules are:
if src_byte_range in screen and dst_byte_range in screen
and srcpitch == dstpitch == line_offset:
can use qemu_console_copy
elif dst_byte_range overlaps screen:
if dstpitch == line_offset:
invalidate rectangle
else:
invalidate full screen
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2010-05-30 8:24 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <4BE32178.2090103@msgid.tls.msk.ru>
2010-05-10 7:41 ` [Qemu-devel] Re: Another SIGFPE in display code, now in cirrus Avi Kivity
2010-05-10 8:15 ` Avi Kivity
2010-05-12 12:20 ` Stefano Stabellini
2010-05-12 12:36 ` Avi Kivity
2010-05-12 13:45 ` Stefano Stabellini
2010-05-12 14:27 ` Avi Kivity
2010-05-12 15:57 ` Stefano Stabellini
2010-05-12 16:07 ` Avi Kivity
2010-05-12 16:55 ` Stefano Stabellini
2010-05-12 16:57 ` Avi Kivity
2010-05-12 17:07 ` Jamie Lokier
2010-05-12 18:11 ` Stefano Stabellini
2010-05-12 19:12 ` Michael Tokarev
2010-05-13 6:49 ` Avi Kivity
2010-05-13 13:48 ` Stefano Stabellini
2010-05-13 14:13 ` Michael Tokarev
2010-05-13 18:03 ` Stefano Stabellini
2010-05-13 16:04 ` Jamie Lokier
2010-05-28 20:51 ` Michael Tokarev
2010-05-30 8:24 ` Avi Kivity
2010-05-13 7:36 ` Paolo Bonzini
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).