[Qemu-devel] [Bug 1096712] [NEW] qemu 1.3.0: Windows XP doesn't boot with BSOD STOP 7E in acpi.sys

2013-01-07 Thread Sven
Public bug reported:

I'm running qemu-system-i386 -cdrom /path/to/windows_xp_cd.iso and it will 
yields a BSOD with error code STOP 7E in acpi.sys.
This used to work without problems with qemu 1.2.1 and hence is a regression.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1096712

Title:
  qemu 1.3.0: Windows XP doesn't boot with BSOD STOP 7E in acpi.sys

Status in QEMU:
  New

Bug description:
  I'm running qemu-system-i386 -cdrom /path/to/windows_xp_cd.iso and it will 
yields a BSOD with error code STOP 7E in acpi.sys.
  This used to work without problems with qemu 1.2.1 and hence is a regression.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1096712/+subscriptions



[Qemu-devel] [Bug 1096714] [NEW] qemu 1.3.0: usb devices shouldn't have same vendor/product ID and same serial

2013-01-07 Thread Sven
Public bug reported:

Boot Windows XP with
./qemu-system-i386 -device pci-ohci -device usb-tablet
and then with
./qemu-system-i386 -device pci-ohci -device usb-kbd

and you will notice, that the usb keyboard is not detected. In fact,
Windows XP detects the usb tablet and loads the driver for the tablet
instead of the driver for the keyboard.

The problem seems to be, that vendor and product ID and even the seriel
of both the usb tablet and the usb keyboard are the same as an lsusb
reveiles. Hence, Windows XP doesn't detect when you replace the tablet
by a keyboard and vice versa. I didn't check other USB devices, but it
seems a bad idea to me to have devices with the same vendor/product Id.
I'm not aware, whether it is sufficient to change the seriel numbers of
the devices.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1096714

Title:
  qemu 1.3.0: usb devices shouldn't have same vendor/product ID and same
  serial

Status in QEMU:
  New

Bug description:
  Boot Windows XP with
  ./qemu-system-i386 -device pci-ohci -device usb-tablet
  and then with
  ./qemu-system-i386 -device pci-ohci -device usb-kbd

  and you will notice, that the usb keyboard is not detected. In fact,
  Windows XP detects the usb tablet and loads the driver for the tablet
  instead of the driver for the keyboard.

  The problem seems to be, that vendor and product ID and even the
  seriel of both the usb tablet and the usb keyboard are the same as an
  lsusb reveiles. Hence, Windows XP doesn't detect when you replace the
  tablet by a keyboard and vice versa. I didn't check other USB devices,
  but it seems a bad idea to me to have devices with the same
  vendor/product Id. I'm not aware, whether it is sufficient to change
  the seriel numbers of the devices.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1096714/+subscriptions



[Qemu-devel] [Bug 1096713] [NEW] qemu 1.3.0: Windows XP crashes when reconizing the USB keyboard

2013-01-07 Thread Sven
Public bug reported:

I'm trying to use the usb tablet and the usb keyboard as follows:
./qemu-system-i386  -device pci-ohci -device usb-tablet -device usb-kbd
or
./qemu-system-i386  -device ich9-usb-ehci1 -device ich9-usb-uhci1 -device 
usb-tablet -device ich9-usb-uhci2 -device usb-kbd

While Windows XP works fine if I only use the tablet but not the
keyboard, it crashed with a BSOD when I use both keyboard and tablet. It
crashed during the detection of the keyboard.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1096713

Title:
  qemu 1.3.0: Windows XP crashes when reconizing the USB keyboard

Status in QEMU:
  New

Bug description:
  I'm trying to use the usb tablet and the usb keyboard as follows:
  ./qemu-system-i386  -device pci-ohci -device usb-tablet -device usb-kbd
  or
  ./qemu-system-i386  -device ich9-usb-ehci1 -device ich9-usb-uhci1 -device 
usb-tablet -device ich9-usb-uhci2 -device usb-kbd

  While Windows XP works fine if I only use the tablet but not the
  keyboard, it crashed with a BSOD when I use both keyboard and tablet.
  It crashed during the detection of the keyboard.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1096713/+subscriptions



[Qemu-devel] [Bug 1091115] Re: qemu-1.3.0 crashes when installing windows xp

2013-01-17 Thread Sven
Same as Bug 1096712 I reported

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1091115

Title:
  qemu-1.3.0 crashes when installing windows xp

Status in QEMU:
  New

Bug description:
  These are the commands:
  $git checkout v1.3.0
  $./configure --prefix=/home/user/tmp --target-list=i386-softmmu --enable-sdl 
--disable-curses --disable-vnc --enable-kvm --disable-docs
  $make
  $make install
  In /home/user/tmp directory:
  $./bin/qemu-img create imgs/winxp.img 4G
  $./bin/qemu-system-i386 imgs/winxp.img -cdrom 
~/Downloads/zh-hans_windows_xp_professional_with_service_pack_3_x86_cd_x14-80404.iso

  then it show a bluescreen after a few seconds.
  See the attachment for more information, please.

  It works well when checking out v1.2.0.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1091115/+subscriptions



[Qemu-devel] [Bug 1101210] [NEW] qemu 1.3.0: usb keyboard not fully working

2013-01-18 Thread Sven
Public bug reported:

When using the usb keyboard, I can't type the | character. I'm using
german keyboard layout (de) on the host and inside the guest. As a guest
OS, I use Linux (e.g. a recent KNOPPIX cd). To obtain the | character on
a german keyboard, I need to press AltGr + the < or > key, i.e. the key
right to the left shift.

The qemu command line is something like this:
./qemu-system-i386 -device pci-ohci -device usb-kbd
I also tried
./qemu-system-i386 -usb -usbdevice keyboard
with the same effect.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1101210

Title:
  qemu 1.3.0: usb keyboard not fully working

Status in QEMU:
  New

Bug description:
  When using the usb keyboard, I can't type the | character. I'm using
  german keyboard layout (de) on the host and inside the guest. As a
  guest OS, I use Linux (e.g. a recent KNOPPIX cd). To obtain the |
  character on a german keyboard, I need to press AltGr + the < or >
  key, i.e. the key right to the left shift.

  The qemu command line is something like this:
  ./qemu-system-i386 -device pci-ohci -device usb-kbd
  I also tried
  ./qemu-system-i386 -usb -usbdevice keyboard
  with the same effect.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1101210/+subscriptions



[Qemu-devel] [Bug 1101210] Re: qemu 1.3.0: usb keyboard not fully working

2013-01-18 Thread Sven
Actually, the whole < > | key doesn't work. It's just dead. I can't type
any of those characters.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1101210

Title:
  qemu 1.3.0: usb keyboard not fully working

Status in QEMU:
  New

Bug description:
  When using the usb keyboard, I can't type the | character. I'm using
  german keyboard layout (de) on the host and inside the guest. As a
  guest OS, I use Linux (e.g. a recent KNOPPIX cd). To obtain the |
  character on a german keyboard, I need to press AltGr + the < or >
  key, i.e. the key right to the left shift.

  The qemu command line is something like this:
  ./qemu-system-i386 -device pci-ohci -device usb-kbd
  I also tried
  ./qemu-system-i386 -usb -usbdevice keyboard
  with the same effect.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1101210/+subscriptions



[Qemu-devel] [Bug 1101210] Re: qemu 1.4.2: usb keyboard not fully working

2013-06-25 Thread Sven
Any comment? The <>| key is still not working in qemu 1.4.2.

** Summary changed:

- qemu 1.3.0: usb keyboard not fully working
+ qemu 1.4.2: usb keyboard not fully working

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1101210

Title:
  qemu 1.4.2: usb keyboard not fully working

Status in QEMU:
  New

Bug description:
  When using the usb keyboard, I can't type the | character. I'm using
  german keyboard layout (de) on the host and inside the guest. As a
  guest OS, I use Linux (e.g. a recent KNOPPIX cd). To obtain the |
  character on a german keyboard, I need to press AltGr + the < or >
  key, i.e. the key right to the left shift.

  The qemu command line is something like this:
  ./qemu-system-i386 -device pci-ohci -device usb-kbd
  I also tried
  ./qemu-system-i386 -usb -usbdevice keyboard
  with the same effect.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1101210/+subscriptions



[Qemu-devel] [Bug 1096714] Re: qemu 1.3.0: usb devices shouldn't have same vendor/product ID and same serial

2017-07-26 Thread Sven
This bug is more than 4 years old. Why did I even bother writing it? Is
the problem still there in recent qemu versions?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1096714

Title:
  qemu 1.3.0: usb devices shouldn't have same vendor/product ID and same
  serial

Status in QEMU:
  New

Bug description:
  Boot Windows XP with
  ./qemu-system-i386 -device pci-ohci -device usb-tablet
  and then with
  ./qemu-system-i386 -device pci-ohci -device usb-kbd

  and you will notice, that the usb keyboard is not detected. In fact,
  Windows XP detects the usb tablet and loads the driver for the tablet
  instead of the driver for the keyboard.

  The problem seems to be, that vendor and product ID and even the
  seriel of both the usb tablet and the usb keyboard are the same as an
  lsusb reveiles. Hence, Windows XP doesn't detect when you replace the
  tablet by a keyboard and vice versa. I didn't check other USB devices,
  but it seems a bad idea to me to have devices with the same
  vendor/product Id. I'm not aware, whether it is sufficient to change
  the seriel numbers of the devices.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1096714/+subscriptions



[Bug 1910696] Re: Qemu fails to start with error " There is no option group 'spice'"

2021-02-08 Thread Sven
Due to this bug, I cannot start LXD virtual machines on Arch Linux
anymore.

$ lxc start debian10vm
Error: Failed to run: forklimits limit=memlock:unlimited:unlimited -- 
/usr/bin/qemu-system-x86_64 -S -name debian10vm -uuid 
e265f257-85ca-445f-be5c-0170dca5955d -daemonize -cpu host -nographic -serial 
chardev:console -nodefaults -no-reboot -no-user-config -sandbox 
on,obsolete=deny,elevateprivileges=allow,spawn=deny,resourcecontrol=deny 
-readconfig /var/log/lxd/debian10vm/qemu.conf -pidfile 
/var/log/lxd/debian10vm/qemu.pid -D /var/log/lxd/debian10vm/qemu.log -chroot 
/var/lib/lxd/virtual-machines/debian10vm -smbios type=2,manufacturer=Canonical 
Ltd.,product=LXD -runas nobody: 
qemu-system-x86_64:/var/log/lxd/debian10vm/qemu.conf:27: There is no option 
group 'spice'
qemu-system-x86_64: -readconfig /var/log/lxd/debian10vm/qemu.conf: read config 
/var/log/lxd/debian10vm/qemu.conf: Invalid argument
: Process exited with a non-zero value
Try `lxc info --show-log debian10vm` for more info

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1910696

Title:
  Qemu fails to start with error " There is no option group 'spice'"

Status in QEMU:
  New

Bug description:
  After upgrade from 5.1.0 to 5.2.0, qemu fails on start with error:
  `
  /usr/bin/qemu-system-x86_64 -S -name trinti -uuid 
f8ad2ff6-8808-4f42-8f0b-9e23acd20f84 -daemonize -cpu host -nographic -serial 
chardev:console -nodefaults -no-reboot -no-user-config -sandbox 
on,obsolete=deny,elevateprivileges=allow,spawn=deny,resourcecontrol=deny 
-readconfig /var/log/lxd/trinti/qemu.conf -pidfile /var/log/lxd/trinti/qemu.pid 
-D /var/log/lxd/trinti/qemu.log -chroot /var/lib/lxd/virtual-machines/trinti 
-smbios type=2,manufacturer=Canonical Ltd.,product=LXD -runas nobody: 
  qemu-system-x86_64:/var/log/lxd/trinti/qemu.conf:27: There is no option group 
'spice'
  qemu-system-x86_64: -readconfig /var/log/lxd/trinti/qemu.conf: read config 
/var/log/lxd/trinti/qemu.conf: Invalid argument
  `
  Bisected to first bad commit: 
https://github.com/qemu/qemu/commit/cbe5fa11789035c43fd2108ac6f45848954954b5

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1910696/+subscriptions



[Qemu-devel] [Bug 603872] Re: [Feature request] qemu-img image conversion does not show percentage

2013-05-28 Thread Sven Dowideit
qemu-img convert -p does show a percentage completion (but not avg speed
or compression ratio) so this is at least partially done.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/603872

Title:
  [Feature request] qemu-img image conversion does not show percentage

Status in QEMU:
  New

Bug description:
  It will be nice if qemu-img will be able to show percentage of
  completition and average speed of conversion and compress ratio (if
  converting to compressed qcow or qcow2)

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/603872/+subscriptions



[Qemu-devel] [Bug 501177] Re: qemu i386-softmmu segfaults on i386 while testing kdbg hardware interrupts

2010-11-28 Thread Sven Eckelmann
Seems to be fixed in qemu 0.12.5 (Debian 0.12.5+dfsg-2).

** Changed in: qemu
   Status: New => Fix Released

-- 
qemu i386-softmmu segfaults on i386 while testing kdbg hardware interrupts
https://bugs.launchpad.net/bugs/501177
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: New

Bug description:
I tried to boot a kernel with enabled kgdb and kgdb self checks with qemu 
emulating i386. It works with amd64, but crashes with i386. Tests were done 
with 19e65b47f60c68d7e8c96aa0a36223c5a0d3422b and qemu 0.11.1-1 on Debian sid.

Backtrace of i386-softmmu/qemu (19e65b47f60c68d7e8c96aa0a36223c5a0d3422b)

[   15.398435] kgdbts:RUN singlestep [900/1000]
[   15.683097] kgdbts:RUN hw breakpoint test

Program received signal SIGSEGV, Segmentation fault.
raise_interrupt (intno=1, is_int=0, error_code=0, next_eip_addend=0) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1335
1335env->exception_index = intno;
(gdb) bt
#0  raise_interrupt (intno=1, is_int=0, error_code=0, next_eip_addend=0) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1335
#1  0x08182347 in raise_exception (exception_index=1) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1351
#2  0x08191e9a in breakpoint_handler (env=0x8467fa8) at 
/home/sven/tmp/qemu/target-i386/helper.c:1530
#3  0x08125e84 in cpu_handle_debug_exception (env1=0x8467fa8) at 
/home/sven/tmp/qemu/cpu-exec.c:209
#4  cpu_x86_exec (env1=0x8467fa8) at /home/sven/tmp/qemu/cpu-exec.c:274
#5  0x08052680 in qemu_cpu_exec (argc=0, argv=0x0, envp=0x6461) at 
/home/sven/tmp/qemu/vl.c:4021
#6  tcg_cpu_exec (argc=0, argv=0x0, envp=0x6461) at 
/home/sven/tmp/qemu/vl.c:4052
#7  main_loop (argc=0, argv=0x0, envp=0x6461) at /home/sven/tmp/qemu/vl.c:4167
#8  main (argc=0, argv=0x0, envp=0x6461) at /home/sven/tmp/qemu/vl.c:6124


It was run with `/home/sven/tmp/qemu/i386-softmmu/qemu -m 1024 -kernel 
linux-2.6.32.qemu -drive file=root.cow3,if=virtio -net 
nic,macaddr=02:ca:ff:ee:ba:43,model=virtio,vlan=3 -net 
tap,ifname=tap3,vlan=3,script=no -nographic`





[Qemu-devel] [Bug 501177] Re: qemu i386-softmmu segfaults on i386 while testing kdbg hardware interrupts

2010-11-28 Thread Sven Eckelmann
My fault. it is still their... did my test wrong

** Changed in: qemu
   Status: Fix Released => New

-- 
qemu i386-softmmu segfaults on i386 while testing kdbg hardware interrupts
https://bugs.launchpad.net/bugs/501177
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: New

Bug description:
I tried to boot a kernel with enabled kgdb and kgdb self checks with qemu 
emulating i386. It works with amd64, but crashes with i386. Tests were done 
with 19e65b47f60c68d7e8c96aa0a36223c5a0d3422b and qemu 0.11.1-1 on Debian sid.

Backtrace of i386-softmmu/qemu (19e65b47f60c68d7e8c96aa0a36223c5a0d3422b)

[   15.398435] kgdbts:RUN singlestep [900/1000]
[   15.683097] kgdbts:RUN hw breakpoint test

Program received signal SIGSEGV, Segmentation fault.
raise_interrupt (intno=1, is_int=0, error_code=0, next_eip_addend=0) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1335
1335env->exception_index = intno;
(gdb) bt
#0  raise_interrupt (intno=1, is_int=0, error_code=0, next_eip_addend=0) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1335
#1  0x08182347 in raise_exception (exception_index=1) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1351
#2  0x08191e9a in breakpoint_handler (env=0x8467fa8) at 
/home/sven/tmp/qemu/target-i386/helper.c:1530
#3  0x08125e84 in cpu_handle_debug_exception (env1=0x8467fa8) at 
/home/sven/tmp/qemu/cpu-exec.c:209
#4  cpu_x86_exec (env1=0x8467fa8) at /home/sven/tmp/qemu/cpu-exec.c:274
#5  0x08052680 in qemu_cpu_exec (argc=0, argv=0x0, envp=0x6461) at 
/home/sven/tmp/qemu/vl.c:4021
#6  tcg_cpu_exec (argc=0, argv=0x0, envp=0x6461) at 
/home/sven/tmp/qemu/vl.c:4052
#7  main_loop (argc=0, argv=0x0, envp=0x6461) at /home/sven/tmp/qemu/vl.c:4167
#8  main (argc=0, argv=0x0, envp=0x6461) at /home/sven/tmp/qemu/vl.c:6124


It was run with `/home/sven/tmp/qemu/i386-softmmu/qemu -m 1024 -kernel 
linux-2.6.32.qemu -drive file=root.cow3,if=virtio -net 
nic,macaddr=02:ca:ff:ee:ba:43,model=virtio,vlan=3 -net 
tap,ifname=tap3,vlan=3,script=no -nographic`





[Qemu-devel] [Bug 501177] Re: qemu i386-softmmu segfaults on i386 while testing kdbg hardware interrupts

2010-11-28 Thread Sven Eckelmann
Works with 0.13.0 (Debian 0.13.0+dfsg-2). Probably
63a54736f31f9e11da6fb52319bba26e7d24f571 was the fix

** Changed in: qemu
   Status: New => Fix Released

-- 
qemu i386-softmmu segfaults on i386 while testing kdbg hardware interrupts
https://bugs.launchpad.net/bugs/501177
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: Fix Released

Bug description:
I tried to boot a kernel with enabled kgdb and kgdb self checks with qemu 
emulating i386. It works with amd64, but crashes with i386. Tests were done 
with 19e65b47f60c68d7e8c96aa0a36223c5a0d3422b and qemu 0.11.1-1 on Debian sid.

Backtrace of i386-softmmu/qemu (19e65b47f60c68d7e8c96aa0a36223c5a0d3422b)

[   15.398435] kgdbts:RUN singlestep [900/1000]
[   15.683097] kgdbts:RUN hw breakpoint test

Program received signal SIGSEGV, Segmentation fault.
raise_interrupt (intno=1, is_int=0, error_code=0, next_eip_addend=0) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1335
1335env->exception_index = intno;
(gdb) bt
#0  raise_interrupt (intno=1, is_int=0, error_code=0, next_eip_addend=0) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1335
#1  0x08182347 in raise_exception (exception_index=1) at 
/home/sven/tmp/qemu/target-i386/op_helper.c:1351
#2  0x08191e9a in breakpoint_handler (env=0x8467fa8) at 
/home/sven/tmp/qemu/target-i386/helper.c:1530
#3  0x08125e84 in cpu_handle_debug_exception (env1=0x8467fa8) at 
/home/sven/tmp/qemu/cpu-exec.c:209
#4  cpu_x86_exec (env1=0x8467fa8) at /home/sven/tmp/qemu/cpu-exec.c:274
#5  0x08052680 in qemu_cpu_exec (argc=0, argv=0x0, envp=0x6461) at 
/home/sven/tmp/qemu/vl.c:4021
#6  tcg_cpu_exec (argc=0, argv=0x0, envp=0x6461) at 
/home/sven/tmp/qemu/vl.c:4052
#7  main_loop (argc=0, argv=0x0, envp=0x6461) at /home/sven/tmp/qemu/vl.c:4167
#8  main (argc=0, argv=0x0, envp=0x6461) at /home/sven/tmp/qemu/vl.c:6124


It was run with `/home/sven/tmp/qemu/i386-softmmu/qemu -m 1024 -kernel 
linux-2.6.32.qemu -drive file=root.cow3,if=virtio -net 
nic,macaddr=02:ca:ff:ee:ba:43,model=virtio,vlan=3 -net 
tap,ifname=tap3,vlan=3,script=no -nographic`





[Qemu-devel] [Bug 628082] Re: nl-be keymap is wrong

2010-09-01 Thread Sven Vermeulen

** Attachment added: "nl-be keymap for Qemu (incl. qemu-kvm)"
   https://bugs.launchpad.net/qemu/+bug/628082/+attachment/1534466/+files/nl-be

-- 
nl-be keymap is wrong
https://bugs.launchpad.net/bugs/628082
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: New

Bug description:
As mentioned on https://bugs.launchpad.net/ubuntu/+source/kvm/+bug/429965 as 
well as the kvm mailinglist 
(http://thread.gmane.org/gmane.comp.emulators.kvm.devel/14413), the nl-be 
keymap does not work. The number keys above the regular keys (non-numeric 
keypad numbers) as well as vital keys such as slash, backslash, dash, ... are 
not working.

The nl-be keymap that is presented in the above URLs (and also attached to this 
bug) does work properly.

Would it be possible to include this keymap rather than the current one?





[Qemu-devel] [Bug 628082] [NEW] nl-be keymap is wrong

2010-09-01 Thread Sven Vermeulen
Public bug reported:

As mentioned on
https://bugs.launchpad.net/ubuntu/+source/kvm/+bug/429965 as well as the
kvm mailinglist
(http://thread.gmane.org/gmane.comp.emulators.kvm.devel/14413), the nl-
be keymap does not work. The number keys above the regular keys (non-
numeric keypad numbers) as well as vital keys such as slash, backslash,
dash, ... are not working.

The nl-be keymap that is presented in the above URLs (and also attached
to this bug) does work properly.

Would it be possible to include this keymap rather than the current one?

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
nl-be keymap is wrong
https://bugs.launchpad.net/bugs/628082
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: New

Bug description:
As mentioned on https://bugs.launchpad.net/ubuntu/+source/kvm/+bug/429965 as 
well as the kvm mailinglist 
(http://thread.gmane.org/gmane.comp.emulators.kvm.devel/14413), the nl-be 
keymap does not work. The number keys above the regular keys (non-numeric 
keypad numbers) as well as vital keys such as slash, backslash, dash, ... are 
not working.

The nl-be keymap that is presented in the above URLs (and also attached to this 
bug) does work properly.

Would it be possible to include this keymap rather than the current one?





[Qemu-devel] Re: qemu: async sending in tap causes "NFS not responding" error

2009-10-26 Thread Sven Rudolph
Scott Tsai  writes:

> I recently found that this chageset:
> http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=e19eb22486f258a421108ac22b8380a4e2f16b97
> "net: make use of async packet sending API in tap client"
> causes NFS root Linux guest setups using TAP networking to fail with
> error messages like:
> nfs: server 172.20.0.1 not responding, still trying
> nfs: server 172.20.0.1 OK
> <  repeat infinitely ...>
> This happens on both the "master" and "stable-0.11" branches on qemu.
>
> The attached '0001-net-revert-e19eb22486f258a421108ac22b8380a4e2f16b97.patch'
> makes NFS root on qemu emulated "arm-integrator-cp" boards work for me
> again.

> After finding:
> http://lists.gnu.org/archive/html/qemu-devel/2009-09/msg01173.html
> through Google and reading through the potentially bad commits that
> Sven found through bisection,
> I patched "tap_send()" to not run in a loop ("drain the tap send queue
> in one go"?) and the error goes away.

Thank you for digging into this. I tested your patch in my environment
and can confirm that it solves the problem.

Sven





[Qemu-devel] Re: [et-mgmt-tools] Image Corruption Possible with qemu and qemu-kvm

2007-08-27 Thread Sven Oehme
i thought it might be good to post this on qemu-devel as well, as i see 
this as a general qemu / kvm / xen /whatevercomesnext issue .

are there any plans to implement a default in qemu to prevent accessing 
the same image multiple times ? 
i know that in xen they deal with this problem somehow xen specific.
wouldn't it be good to prevent multiple access to the same image by 
default and add a switch to overwrite it ? 

i am sure other people had the same issue as i had (corrupting images) and 
would be great to prevent people in the future messing around with data 
loss :-)

Sven




Sven Oehme/Germany/[EMAIL PROTECTED] 
Sent by: [EMAIL PROTECTED]
08/27/2007 09:38 PM
Please respond to
Fedora/Linux Management Tools <[EMAIL PROTECTED]>


To
Fedora/Linux Management Tools <[EMAIL PROTECTED]>
cc

Subject
[et-mgmt-tools] Image Corruption Possible with qemu and qemu-kvm







Hi, 

i corrupted a couple of virtual Linux images last week as i accidentally 
started them two times .. 
i opened a bug against qemu (not sure if this was a good idea) -->  
https://bugzilla.redhat.com/show_bug.cgi?id=253533 

are there any plans to ensure that this can't happen in future releases of 
virt-manager with lock files in the image directory or similar ? 

thanks. Sven 
___
et-mgmt-tools mailing list
[EMAIL PROTECTED]
https://www.redhat.com/mailman/listinfo/et-mgmt-tools


Re: [Qemu-devel] Re: [et-mgmt-tools] Image Corruption Possible with qemu and qemu-kvm

2007-08-29 Thread Sven Oehme
[EMAIL PROTECTED] wrote on 08/28/2007 
04:13:02 AM:

> Anthony Liguori wrote:
> >> In the scenario you mention, libvirt should probably do a sanity 
check for
> >> this before letting you start the guest. libvirt already supports the 
idea
> >> of 'shared' disk images where two or more guests can be 
> optionally configured 
> >> to have write access - basically assumes the admin requesting sharing 
knows
> >> what they're doing.
> >> 
> >
> > I think this is the right level myself.  Advisory locks work okay but
> > not all filesystems support them.  It's particularly nasty when you 
have
> > a clustered filesystem in the host.  I think it would do more harm 
than
> > good to have a feature like that was supposed to provide a safe-guard
> > but then frequently didn't work.
> > 
> 
> There's still the unmanaged use case to worry about.  I think qemu can 
> default to advisory locking, and management tools can do their own 
> locking and always override qemu.
> 
> It's too easy to kill an image by starting up another instance right 
now.
> 

i agree default should be advisory locking and a switch to disable it ..
would that be hard to implement ?

thanks. Sven

[Qemu-devel] Re: Unknown PCI Bridge

2006-05-05 Thread Sven Köhler
>> qemu's ACPI PCI device doesn't seem to be _that_ normal/known. At least
>> a recent Knoppix lists it as "Bridge: Intel Corp.: Inknown device 7013".
> 
> Wrong device id, should be 0x7113.

Hmmm, i looked it up, and i think i know why the author "preferred" 7013
instead of 7113.

7113 is 82371AB/EB/MB PIIX4 ACPI, but all the other qemu-hardware is
only PIIX3 - afaik.

So using 7113 would mean, that the PIIX4 stuff gets mixed with PIIX3
stuff. I don't know, how odd that might seem to some OS.

Beside that, a PIIX3-ACPI-device doesn't seem to exist in the
pciid-database.



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: DMA with Knoppix and qemu (cvs-version)

2006-05-05 Thread Sven Köhler
> i just booted a recent knoppix-cd (4.0.2) and i'm trying to enable DMA,
> but it won't work!
> 
> I started qemu with that command:
> 
> qemu -m 256 -cdrom knoppix.iso -boot d
> 
> But inside knoppix, a "hdparm -d1 /dev/hdc" won't work:
>   HDIO_SET_DMA failed: Operation not permitted

Ah ha! DMA mode work for harrdisks, but not for cdroms.

Strange - why?



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: Unknown PCI Bridge

2006-05-05 Thread Sven Köhler
>> So using 7113 would mean, that the PIIX4 stuff gets mixed with PIIX3
>> stuff. I don't know, how odd that might seem to some OS.
> 
> It's irrelevant to any OS that i know of.

;-)

>> Beside that, a PIIX3-ACPI-device doesn't seem to exist in the
>> pciid-database.
> 
> Huh?

# cat /usr/share/misc/pci.ids|grep -i PIIX3
7000  82371SB PIIX3 ISA [Natoma/Triton II]
7010  82371SB PIIX3 IDE [Natoma/Triton II]
7020  82371SB PIIX3 USB [Natoma/Triton II]
# cat /usr/share/misc/pci.ids|grep -i PIIX4
7110  82371AB/EB/MB PIIX4 ISA
7111  82371AB/EB/MB PIIX4 IDE
7112  82371AB/EB/MB PIIX4 USB
7113  82371AB/EB/MB PIIX4 ACPI


See? No PIIX3 ACPI device. That's all i tried to say.




signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: Unknown PCI Bridge

2006-05-06 Thread Sven Köhler
> Win2k and Linux 2.6 (w/o kqemu) seem to work fine.

have you reinstalled Win2k?

Or did you somehow manage, to turn an already installed Win2k from a
"Standard PC" into a "ACPI PC" (as the hardware-manager calls it)?



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: DMA with Knoppix and qemu (cvs-version)

2006-05-07 Thread Sven Köhler
> Just a note: setting DMA through hdparm doesn't work on Linux since
> tens of versions ago, it's been depreceted and you have to trust the
> on-boot autodetection (and it works fine -- unless you didn't compile
> the right driver in). It's the same on real machines.

WHAT!?

i have used it with Knoppix since ages. Knoppix has DMA disabled (for
some reason). Most of the time i boot knoppix with "dma" in the
append-line, but in the other cases, hdparm works and improves
performance dramatically.



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] high CPU load / async IO?

2006-07-23 Thread Sven Köhler
Hi,

sorry for bothering, but the last time i heard something about asyn IO
was on Feb 2nd. Fabrice said:

[quote]
I have at least 5 items on my TODO list :
1) New kqemu which virtualizes both user and kernel code (currently in
alpha stage but not released yet).
2) DMA block I/O (merged)
3) async block I/O (not merged yet)
4) Network adapter using DMA (not merged yet)
5) VGA acceleration (either improve Cirrus VGA or switch back to Bochs
VGA for Win 2000/XP or Linux)
[/quote]

so 1) and 2) are in HEAD. I saw something concerning 5) too, i think.
I'm not sure about 4) - but - well,

I'm very curious about 3)  :-)

It's not in HEAD yet, isn't it?

Why i'm curious? Well, i'm curious about the improvement it causes. You
people once told me, that the boost will not be that significant. On the
other hand, i see my host CPU usage going towards 100% just because the
guest is doing some IO or ... or is it because of somethine else perhaps?

To be concrete: have you guys ever run windows-update inside qemu? Well,
my win2k guest consumes all CPU on the host for some reason. What might
be the reason?
(qemu is started with -kernel-kqemu -m 256 -soundhw es1370)

Also windows-update's green "progress bar" inside the guest is stopping
for let's say 3 or 5 seconds and not moving continuous.

Is anybody experiencing the same or knows the reason?


Thanks,
  Sven



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: high CPU load / async IO?

2006-07-24 Thread Sven Köhler
>> 3) async block I/O (not merged yet)
>> It's not in HEAD yet, isn't it?
> 
> The pthread-based async patch is a band-aid.  No doubt it helps your
> particular case, but it's not the right approach long term.
> 
> IDE only supports one outstanding request, so having a thread that runs
> the synchronous block routines appears reasonable.  However, SATA and SCSI
> both support multiple outstanding requests.  The extension to the existing
> patch would be simple--increase the number of threads.

???

Wasn't there another variant using the async-I/O support of the Host OS
and thereby supporting a larger number of outstanding requests?

> A number of Xen hackers (primarily Andy Warfield and Dan Smith) have been
> doing a lot of work analyzing userspace block device performance.  As
> QEMU's CPU virtualization gets faster (ala kqemu or VT/SVM), it will start
> facing the same bottlenecks that we do today in Xen.
> 
> To achieve near-native performance, you basically have to be able to
> saturate the host's IO scheduler queue.  Using O_DIRECT, you can do
> zero-copy meaning that your ability to queue requests is the only limiting
> factor.
> 
> What's been discovered is that a thread based approach requires a ton of
> threads to achieve saturation.  Just imagine the contention of having a
> very large number of threads trying to get at a single BDRVState.
> 
> The real solution is to modify the block API to be asynchronous and then
> provide support for interacting with the host IO scheduler queue via
> something like linux-aio (or the win32 equiv).

The approch that i mentioned above (using the host's async I/O) is what
you mean with using linux-aio, right?

> So the current thread-based async dma patch is really just the wrong long
> term solution.  A more long term solution is likely in the works.  It
> requires quite a bit of code modification though.

I see. So in other words:

don't ask for simple async I/O now. The more complex and flexible
sollution will follow soon.



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: high CPU load / async IO?

2006-07-25 Thread Sven Köhler
>>> IDE only supports one outstanding request, so having a thread that runs
>>> the synchronous block routines appears reasonable.  However, SATA and SCSI
>>> both support multiple outstanding requests.  The extension to the existing
>>> patch would be simple--increase the number of threads.
>> ???
>>
>> Wasn't there another variant using the async-I/O support of the Host OS
>> and thereby supporting a larger number of outstanding requests?
> 
> Not that I know of.  Do you have a pointer?

Hmm, perhaps i only heard people talking about it ...
But if i find anything, i post the link.

>>> So the current thread-based async dma patch is really just the wrong long
>>> term solution.  A more long term solution is likely in the works.  It
>>> requires quite a bit of code modification though.
>>
>> I see. So in other words:
>>
>> don't ask for simple async I/O now. The more complex and flexible
>> sollution will follow soon.
> 
> Yes, hopefully really soon.

So i will wait patiently :-)



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: high CPU load / async IO?

2006-07-26 Thread Sven Köhler
> Sounds good, so at least it's on its way :-)
> It's on of those big items left on the TODO, so will be good to see go
> in. Then one should implement an ahci host controller for queued
> command support next...
 Or use the scsi emulation :-)
>>> Ah, did not know that queueing was fully implemented there yet!
>> It isn't, but it's nearer than the SATA emulation!
> 
> ahci wouldn't be too much work, but definitely more so than finishing
> the scsi bits!

That sounds great! I feel, like my dreams come true.


BTW: Fabrice said, he will use the POSIX AIO (i guess, he means
http://www.bullopensource.org/posix/ in case of Linux, right?)

Which other OS do also support the POSIX AIO API?



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] qemu (cvs-version) performance?

2006-08-20 Thread Sven Köhler
Hi,

i'd like to know, what the qemu-project aims at.
Do the authers aim at writing (together with kqemu or qv86) an
alternative to VMWare? (At least in the x86 virtualization case)

I first thought that way and i still hope that, but i was disappointed
by qemu 0.8.0 and the latest version from CVS.

I thought, that qemu-0.8.0's problem would be disk-IO. I installed
Windows 2000 and in the task-manager the CPU-Time is 100% during intense
IO. A "dir c:\ /A /S /B >NUL:" on the console causes 100% CPU-time and
most of it being that red-colored "in-kernel-time".

The DMA-mode is active according to the device-manager, since i upgraded
to qemu CVS (version from an hour ago).

So IO still seems to be very expensive. AFAIK, IDE-DMA or BusMastering
should enable the CPU to do other things while waiting for the Interrupt
that signals the finished transfer. (My knowledge about hardware is not
that good though.) But the virtual CPU is not idle and the host's CPU
isn't either.

Of course i'm using kqemu.


So what might be wrong?
Some hints:
- the disk-image(raw format) is on a reiserfs-filesystem
- the host ist kernel 2.6.15


Please don't understand me wrong.
I appreciate your work.


Greetings
  Sven



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] Timing problems

2005-08-28 Thread Sven Zenker
Hi all,
as a new qemu user, let me first of all say that qemu, especially in
combination with kqemu is a great piece of software. Many thanks to the
developer(s).
Since I am using a Laptop with a Pentium M CPU with SpeedStep and am
forced to use XP SP2 as a guest OS (Suse 9.3 is host OS), it wouldn't
work reliably for me,  for reasons mentioned previously in this thread
(system services timing out at startup, networking problems etc.).
Really needing a working emulator bad, I came up with the following ugly
hack, which leads to a stable and network enabled XP SP 2 running in
qemu on my SpeedStep machine, with the side effect of having an accurate
real time clock in the guest OS again. It simply replaces the virtual
timer mechanism based on CPU tick count (which is totally messed up in a
SpeedStep setting) with calls to the realtime clock. It should work even
when emulation is stopped intermittently, I hope, since the  built in
"virtual clock stop" mechanism ist left unchanged. 
I modified only the I386 code, so to make this work on other machines,
more modifications would be necessary:

qemu-0.7.1 # diff vl.c.org vl.c 
503d502
<
505d503
<
508,510c506
< int64_t val;
< asm volatile ("rdtsc" : "=A" (val));
< return val;
---
> return get_clock();
512d507
<
594,605c589
< int64_t usec, ticks;
<
< usec = get_clock();
< ticks = cpu_get_real_ticks();
< #ifdef _WIN32
< Sleep(50);
< #else
< usleep(50 * 1000);
< #endif
< usec = get_clock() - usec;
< ticks = cpu_get_real_ticks() - ticks;
< ticks_per_sec = (ticks * 100LL + (usec >> 1)) / usec;
---
>   ticks_per_sec = 100LL;  /* our real time clock resolution */

+

and 

+

qemu-0.7.1/linux-user # diff main.c.org main.c
113,115c113
< int64_t val;
< asm volatile ("rdtsc" : "=A" (val));
< return val;
---
> return get_clock();
 return get_clock();
---
> return val;

++
This is of course an ugly hack and sure to affect performance, but at
least, it makes XP work for me.
Please let me know your thoughts.
Best regards,
Sven Zenker

-- 
Dr. med. Sven Zenker
Research Associate
Center for Inflammation and Regenerative Modeling
Dpt. of Critical Care Medicine
University of Pittsburgh Medical Center



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: Re: [Qemu-devel] Timing problems

2005-08-30 Thread Sven Zenker
Hi,
> Hm. hard choice.correctness traded for perfomance But 
> anywayIMHO this hack  is needed for every speed-step enabled 
> machine. Perhaps...the other workaround is via cpufreqd? I don't have 
> any Pentium M based PC/laptop around, so this is just a pure guess
Yeah, you can also expect problems with the original versions on
multi-processor machines, I would think. Would be nice to compare
performance of the patched and original version. Unfortunately can't do
that right now because timing of the non-patched version is of course
messed up on my machine.
> 
> BTW, your patch seems reversedif you really mean you want to fetch 
> realtime clock, you should use "rdtsc", right? But the patch seems 
> replaced "rdtsc" with get_clock() 
rdtsc gives you the cpu's clock count, which, if CPU frequency changes,
or your code is run on different processors (multiprocessor machine),
cannot be assumed to be related to real time anymore. Resolutionwise,
the real time clock may be inferior, of course, as Jim mentioned.
Jim: could you point me to this other patch? Thanks!
> 
> Another thing, IMHO it is better to use unified format (diff -u). More 
> readable and i think it is a standart
Here you go:
+++
qemu-0.7.1 # diff -u vl.c.org vl.c
--- vl.c.org2005-08-26 19:03:52.0 -0400
+++ vl.c2005-08-28 14:43:00.0 -0400
@@ -500,16 +500,11 @@
 } while (h != h1);
 return ((int64_t)h << 32) | l;
 }
-
 #elif defined(__i386__)
-
 int64_t cpu_get_real_ticks(void)
 {
-int64_t val;
-asm volatile ("rdtsc" : "=A" (val));
-return val;
+return get_clock();
 }
-
 #elif defined(__x86_64__)

 int64_t cpu_get_real_ticks(void)
@@ -591,18 +586,7 @@

 void cpu_calibrate_ticks(void)
 {
-int64_t usec, ticks;
-
-usec = get_clock();
-ticks = cpu_get_real_ticks();
-#ifdef _WIN32
-Sleep(50);
-#else
-usleep(50 * 1000);
-#endif
-usec = get_clock() - usec;
-ticks = cpu_get_real_ticks() - ticks;
-ticks_per_sec = (ticks * 100LL + (usec >> 1)) / usec;
+   ticks_per_sec = 100LL;  /* our real time clock resolution */
 }

 /* compute with 96 bit intermediate result: (a*b)/c */

+++

qemu-0.7.1/linux-user # diff -u main.c.org main.c
--- main.c.org  2005-08-28 14:40:16.0 -0400
+++ main.c  2005-08-28 15:06:31.0 -0400
@@ -110,9 +110,7 @@

 int64_t cpu_get_real_ticks(void)
 {
-int64_t val;
-asm volatile ("rdtsc" : "=A" (val));
-return val;
+return get_clock();
 }

 #elif defined(__x86_64__)

+++

Best regards,
Sven



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] Timing.. was : kqemu processor feature question

2005-10-19 Thread Sven Zenker
Had the same problem on my SpeedStep machine, am using an ugly patch
currently that replaces the CPU tick based timing with calls to the
realtime clock (see my previous mails on this list). Runs XP as guest
quite reliably under Suse 9.3 (using it every day to run Windows only
software). Performance isn't the best, though, although I'm lacking
comparisons.
-Sven

Am Mittwoch, den 19.10.2005, 10:18 +0400 schrieb Brad Campbell:
> Brad Campbell wrote:
> > John R. Hogerhuis wrote:
> > 
> >> Anyway everything seems to be fitting your theory about Athlon
> >> extensions. It would be nice to catch it in the act of trying to run an
> >> Athlon instruction on a Pentium.
> > 
> > And it was all a bogus trail.. It's *timer* related!
> > I made start_rtc_timer() fail (return -1) unconditionally, and voila it 
> > boots first time every time, and any Image I throw at it..
> > So something in the win2k loader appears to be timing sensitive. I did 
> > try the -win2k-hack for a lark, but that only had random results..
> > So there is an issue with the RTC handler on this machine by the looks..
> > RTC max freq is 1024, so it's not that.. further debugging required
> 
> 
> There is something bogus happening in cpu_calibrate_ticks() on this machine
> 
> When it boots windows ok I get this..
> 
> bklaptop:/tracks>qemu -hda w2k.img -m 512 -user-net -localtime -enable-audio
> timer: min=450 us max=50188 us avg=2424 us avg_freq=412.523 Hz
> timer: min=243 us max=53085 us avg=2435 us avg_freq=410.534 Hz
> timer: min=80 us max=24302 us avg=2416 us avg_freq=413.747 Hz
> timer: min=20 us max=60886 us avg=2837 us avg_freq=352.417 Hz
> 
> When it fails to start I get this..
> 
> bklaptop:/tracks>qemu -hda w2k.img -m 512 -user-net -localtime -enable-audio
> timer: min=194 us max=226993 us avg=21626 us avg_freq=46.239 Hz
> timer: min=646 us max=550679 us avg=21923 us avg_freq=45.613 Hz
> timer: min=939 us max=203745 us avg=21966 us avg_freq=45.525 Hz
> timer: min=171 us max=540720 us avg=28920 us avg_freq=34.577 Hz
> timer: min=4641 us max=80171 us avg=21372 us avg_freq=46.789 Hz
> 
> I might start qemu 30 times, and get 1 boot from 30 starts..
> 
> If the machine is loaded when I start qemu it will start every time. (while 
> true ; do echo -n . ; 
> done) in the shell is enough to load it up..
> It *almost* looks like the tsc is stopping while the machine is in hlt state 
> and cpu_calibrate_ticks 
> is getting bogus figures somewhere..
> 
> This machine has SpeedStep, but according to the info in 
> /sys/devices/system/cpu/cpu0/cpufreq/
> It has not changed state since boot and the governor is set to max_freq..
> 
>  "Some time later.."
> 
> By changing cpu_calibrate_ticks to do something silly and keep busy while 
> waiting instead of 
> sleeping, I get dead reliable results every time.. (Yes, it's horridly ugly, 
> I know it's ugly but it 
> works here)
> 
> void cpu_calibrate_ticks(void)
> {
>  int64_t usec, ticks;
> 
>  usec = get_clock();
>  ticks = cpu_get_real_ticks();
> #ifdef _WIN32
>  Sleep(50);
> #else
>  while (get_clock()-usec < 5) {
>  get_clock();
>  }
> #endif
>  usec = get_clock() - usec;
>  ticks = cpu_get_real_ticks() - ticks;
>  ticks_per_sec = (ticks * 100LL + (usec >> 1)) / usec;
>  printf("Ticks_per_sec = %lld\n",ticks_per_sec);
> }
> 
> bklaptop:/tracks>qemu -hda w2k.img -user-net -m 512 -localtime
> timer: min=90 us max=10628 us avg=994 us avg_freq=1005.900 Hz
> timer: min=33 us max=22670 us avg=1003 us avg_freq=996.085 Hz
> timer: min=305 us max=2995 us avg=980 us avg_freq=1019.897 Hz
> timer: min=220 us max=25093 us avg=1020 us avg_freq=979.883 Hz
> timer: min=27 us max=9872 us avg=701 us avg_freq=1425.036 Hz
> 
> So it appears to give a much more accurate idea of tics_per_sec. (which is 
> where all my timer 
> problems on this laptop are coming from)
> 
> For testing I run cpu_calibrate_tics 8 times in the init sequence..
> This is just changing the above routine only.. no other machine modification 
> or restart...
> 
> Before
> bklaptop:/tracks>qemu -hda w2k.img -user-net -m 512 -localtime
> Ticks_per_sec = 47720193
> Ticks_per_sec = 32508223
> Ticks_per_sec = 34422776
> Ticks_per_sec = 51535607
> Ticks_per_sec = 29776765
> Ticks_per_sec = 29481406
> Ticks_per_sec = 26230393
> Ticks_per_sec = 26133451
> Winner - RTC enabled
> timer: min=2568 us max=850100 us avg=38857 us avg_freq=25.735 Hz
> timer: min=5607 us max=153629 us avg=37663 us avg_freq=26.551 Hz
> 
> After
> bklaptop:/tracks>qemu -hda w2k.img -user

Re: [Qemu-devel] Re: Timing problems

2005-11-08 Thread Sven Zenker
Hi,
people have had this problem with SpeedStep machines, where it is
related to qemu timing being based on CPU cycle count, which is thereby
messed up. 
Since it seems to occur with frequency scaling disabled as well, could
this be related to running on a HyperThreading CPU? Not sure what
happens there with the cycle counts, but to verify, you could try to
apply my previously posted patch that substituted the built-in mechanism
with realtime clock calls (was for 0.7.1, though, I think).
Best,
Sven

Am Montag, den 07.11.2005, 22:46 + schrieb Michael Smith:
> Alexander Toresson  gmail.com> writes:
> 
> > time flies by at 5x the speed it should.
> 
> > PS. I'm susprised nobody has seen this problem before. Is it just me
> > who experience it?
> 
> No, I experience this as well.
> 
> I'm running Qemu 0.7.2 with Linux 2.6.14 (vanilla kernel) as host OS and 
> Windows
> XP Professional as guest OS.  If the VM is running and actively using CPU, 
> time
> runs much faster in the guest than in the host.  On the other hand, if the VM 
> is
> mostly idle, time is slower in the guest than in the host OS.
> 
> This odd clock behavior seems to cause other problems in the guest OS,
> particularly during boot/service initialization.
> 
> I can recreate this behavior with or without KQemu.
> 
> I can recreate this behavior with or without CPU frequency scaling enabled.
> 
> It is frustrating, and I would be very happy if someone could suggest a fix or
> workaround.
> 
> Thanks,
> Mike Smith
> [EMAIL PROTECTED]
> 
> 
> 
> 
> 
> ___
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
> 



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] [FYI] gentoo ebuilds for cvs-version

2006-03-09 Thread Sven Köhler
Hi,

are there any Gentoo-users out there?

Well, here are 2 ebuilds to use newest qemu-version from CVS:

http://bugs.gentoo.org/show_bug.cgi?id=125668


Greetings
  Sven



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] qemu (cvs-version) performance?

2006-03-11 Thread Sven Köhler
Hi,

i'd like to know, what the qemu-project aims at.
Do the authers aim at writing (together with kqemu or qv86) an
alternative to VMWare? (At least in the x86 virtualization case)

I first thought that way and i still hope that, but i was disappointed
by qemu 0.8.0 and the latest version from CVS.

I thought, that qemu-0.8.0's problem would be disk-IO. I installed
Windows 2000 and in the task-manager the CPU-Time is 100% during intense
IO. A "dir c:\ /A /S /B >NUL:" on the console causes 100% CPU-time and
most of it being that red-colored "in-kernel-time".

The DMA-mode is active according to the device-manager, since i upgraded
to qemu CVS (version from an hour ago).

So IO still seems to be very expensive. AFAIK, IDE-DMA or BusMastering
should enable the CPU to do other things while waiting for the Interrupt
that signals the finished transfer. (My knowledge about hardware is not
that good though.) But the virtual CPU is not idle and the host's CPU
isn't either.

Of course i'm using kqemu.


So what might be wrong?
Some hints:
- the disk-image(raw format) is on a reiserfs-filesystem
- the host ist kernel 2.6.15


Please don't understand me wrong.
I appreciate your work.


Greetings
  Sven



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: qemu (cvs-version) performance?

2006-03-11 Thread Sven Köhler
>> I thought, that qemu-0.8.0's problem would be disk-IO. I installed
>> Windows 2000 and in the task-manager the CPU-Time is 100% during intense
>> IO. A "dir c:\ /A /S /B >NUL:" on the console causes 100% CPU-time and
>> most of it being that red-colored "in-kernel-time".
> 
> Qemu host IO is syncrhonous. ie. the guest is paused on the instruction that 
> issues the IO until the IO completes. As for as the guest is concerned it 
> happens instantly. This is all your test shows.

I have seen thoughts about asynchronous IO for qemu. I thought that they
would have been integrated along with the DMA-patches already.

I would really see how qemu performs with asynch IO enabled. Are there
any patches out there?


Greetings
  Sven



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: qemu (cvs-version) performance?

2006-03-11 Thread Sven Köhler
> I have seen thoughts about asynchronous IO for qemu. I thought that they
> would have been integrated along with the DMA-patches already.

I'm sorry, i read a mail by Fabrice that async block I/O is not merged yet.



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] Re: Unknown PCI Bridge

2006-05-04 Thread Sven Köhler
> Yes, ACPI adds a new PCI device so it is normal. I am interested by any
> regression found using the current CVS with ACPI...

I think, this answer is fairly useless for the OP.
So perhaps the OP wanted to ask: how do i tell my Win2k to properly use
the new PCI device?

I'm especially interested in this question: is qemu's current ACPI PCI
device so normal, that it would be recognized and properly used by a
newly installed Win2k?


qemu's ACPI PCI device doesn't seem to be _that_ normal/known. At least
a recent Knoppix lists it as "Bridge: Intel Corp.: Inknown device 7013".


BTW: how can i test ACPI with Linux?
At least "cat /proc/acpi/info" works fine and shows:
version: 20050309

Greetings
  Sven



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] DMA with Knoppix and qemu (cvs-version)

2006-05-04 Thread Sven Köhler
Hi,

i just booted a recent knoppix-cd (4.0.2) and i'm trying to enable DMA,
but it won't work!

I started qemu with that command:

qemu -m 256 -cdrom knoppix.iso -boot d

But inside knoppix, a "hdparm -d1 /dev/hdc" won't work:
  HDIO_SET_DMA failed: Operation not permitted


Are there some issues with qemu's DMA support and Linux?
(qemu does have DMA support, doesn't it?)


Greetings
  Sven



signature.asc
Description: OpenPGP digital signature
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[PATCH 1/4] plugins/execlog: add struct execlog_ctx

2024-02-28 Thread Sven Schnelle
Add a context structure for future enhancements. No functional
change intended.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 24 ++--
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index 82dc2f584e..90da1911b2 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -24,6 +24,10 @@ static GRWLock expand_array_lock;
 static GPtrArray *imatches;
 static GArray *amatches;
 
+struct execlog_ctx {
+GString *s;
+};
+
 /*
  * Expand last_exec array.
  *
@@ -34,8 +38,9 @@ static void expand_last_exec(int cpu_index)
 {
 g_rw_lock_writer_lock(&expand_array_lock);
 while (cpu_index >= last_exec->len) {
-GString *s = g_string_new(NULL);
-g_ptr_array_add(last_exec, s);
+struct execlog_ctx *ctx = g_new(struct execlog_ctx, 1);
+ctx->s = g_string_new(NULL);
+g_ptr_array_add(last_exec, ctx);
 }
 g_rw_lock_writer_unlock(&expand_array_lock);
 }
@@ -46,14 +51,13 @@ static void expand_last_exec(int cpu_index)
 static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info,
  uint64_t vaddr, void *udata)
 {
-GString *s;
-
 /* Find vCPU in array */
 g_rw_lock_reader_lock(&expand_array_lock);
 g_assert(cpu_index < last_exec->len);
-s = g_ptr_array_index(last_exec, cpu_index);
+struct execlog_ctx *ctx = g_ptr_array_index(last_exec, cpu_index);
 g_rw_lock_reader_unlock(&expand_array_lock);
 
+GString *s = ctx->s;
 /* Indicate type of memory access */
 if (qemu_plugin_mem_is_store(info)) {
 g_string_append(s, ", store");
@@ -77,8 +81,6 @@ static void vcpu_mem(unsigned int cpu_index, 
qemu_plugin_meminfo_t info,
  */
 static void vcpu_insn_exec(unsigned int cpu_index, void *udata)
 {
-GString *s;
-
 /* Find or create vCPU in array */
 g_rw_lock_reader_lock(&expand_array_lock);
 if (cpu_index >= last_exec->len) {
@@ -86,8 +88,9 @@ static void vcpu_insn_exec(unsigned int cpu_index, void 
*udata)
 expand_last_exec(cpu_index);
 g_rw_lock_reader_lock(&expand_array_lock);
 }
-s = g_ptr_array_index(last_exec, cpu_index);
+struct execlog_ctx *ctx = g_ptr_array_index(last_exec, cpu_index);
 g_rw_lock_reader_unlock(&expand_array_lock);
+GString *s = ctx->s;
 
 /* Print previous instruction in cache */
 if (s->len) {
@@ -183,9 +186,10 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct 
qemu_plugin_tb *tb)
 static void plugin_exit(qemu_plugin_id_t id, void *p)
 {
 guint i;
-GString *s;
+
 for (i = 0; i < last_exec->len; i++) {
-s = g_ptr_array_index(last_exec, i);
+struct execlog_ctx *ctx = g_ptr_array_index(last_exec, i);
+GString *s = ctx->s;
 if (s->str) {
 qemu_plugin_outs(s->str);
 qemu_plugin_outs("\n");
-- 
2.43.2




[PATCH 2/4] plugins/execlog: pass matches array to parse_vaddr_match

2024-02-28 Thread Sven Schnelle
Pass the matches array to parse_vaddr_match(), so future address
matches can reuse that function.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index 90da1911b2..b4b5ba113c 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -206,14 +206,14 @@ static void parse_insn_match(char *match)
 g_ptr_array_add(imatches, match);
 }
 
-static void parse_vaddr_match(char *match)
+static void parse_vaddr_match(GArray **matches, char *match)
 {
 uint64_t v = g_ascii_strtoull(match, NULL, 16);
 
-if (!amatches) {
-amatches = g_array_new(false, true, sizeof(uint64_t));
+if (!matches) {
+*matches = g_array_new(false, true, sizeof(uint64_t));
 }
-g_array_append_val(amatches, v);
+g_array_append_val(*matches, v);
 }
 
 /**
@@ -239,7 +239,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t 
id,
 if (g_strcmp0(tokens[0], "ifilter") == 0) {
 parse_insn_match(tokens[1]);
 } else if (g_strcmp0(tokens[0], "afilter") == 0) {
-parse_vaddr_match(tokens[1]);
+parse_vaddr_match(&amatches, tokens[1]);
 } else {
 fprintf(stderr, "option parsing failed: %s\n", opt);
 return -1;
-- 
2.43.2




[PATCH 3/4] plugins/execlog: add data address match

2024-02-28 Thread Sven Schnelle
Add a match similar to the afilter address match, but for data
addresses. When an address is specified with '-dfilter=0x12345'
only load/stores to/from address 0x12345 are printed. All other
instructions are hidden.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index b4b5ba113c..33fef9bfc6 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -23,9 +23,11 @@ static GRWLock expand_array_lock;
 
 static GPtrArray *imatches;
 static GArray *amatches;
+static GArray *dmatches;
 
 struct execlog_ctx {
 GString *s;
+bool log;
 };
 
 /*
@@ -45,6 +47,17 @@ static void expand_last_exec(int cpu_index)
 g_rw_lock_writer_unlock(&expand_array_lock);
 }
 
+static bool match_vaddr(struct execlog_ctx *ctx, uint64_t vaddr)
+{
+for (int i = 0; i < dmatches->len; i++) {
+uint64_t v = g_array_index(dmatches, uint64_t, i);
+if (v == vaddr) {
+ctx->log = true;
+return true;
+}
+}
+return false;
+}
 /**
  * Add memory read or write information to current instruction log
  */
@@ -57,6 +70,9 @@ static void vcpu_mem(unsigned int cpu_index, 
qemu_plugin_meminfo_t info,
 struct execlog_ctx *ctx = g_ptr_array_index(last_exec, cpu_index);
 g_rw_lock_reader_unlock(&expand_array_lock);
 
+if (dmatches && !match_vaddr(ctx, vaddr)) {
+return;
+}
 GString *s = ctx->s;
 /* Indicate type of memory access */
 if (qemu_plugin_mem_is_store(info)) {
@@ -93,7 +109,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void 
*udata)
 GString *s = ctx->s;
 
 /* Print previous instruction in cache */
-if (s->len) {
+if (ctx->log && s->len) {
 qemu_plugin_outs(s->str);
 qemu_plugin_outs("\n");
 }
@@ -102,6 +118,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void 
*udata)
 /* vcpu_mem will add memory access information to last_exec */
 g_string_printf(s, "%u, ", cpu_index);
 g_string_append(s, (char *)udata);
+ctx->log = dmatches ? false : true;
 }
 
 /**
@@ -190,7 +207,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
 for (i = 0; i < last_exec->len; i++) {
 struct execlog_ctx *ctx = g_ptr_array_index(last_exec, i);
 GString *s = ctx->s;
-if (s->str) {
+if (ctx->log && s->str) {
 qemu_plugin_outs(s->str);
 qemu_plugin_outs("\n");
 }
@@ -240,6 +257,8 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t 
id,
 parse_insn_match(tokens[1]);
 } else if (g_strcmp0(tokens[0], "afilter") == 0) {
 parse_vaddr_match(&amatches, tokens[1]);
+} else if (g_strcmp0(tokens[0], "dfilter") == 0) {
+parse_vaddr_match(&dmatches, tokens[1]);
 } else {
 fprintf(stderr, "option parsing failed: %s\n", opt);
 return -1;
-- 
2.43.2




[PATCH 4/4] plugins/execlog: add address range matching

2024-02-28 Thread Sven Schnelle
Allow to match memory ranges with the address matches. This
allows to give a range of adresses like '-dfilter=0-0x400'
which would only log memory accesses between 0 and 400.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 65 +++
 1 file changed, 52 insertions(+), 13 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index 33fef9bfc6..a505f98be8 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -30,6 +30,11 @@ struct execlog_ctx {
 bool log;
 };
 
+struct address_match {
+uint64_t low;
+uint64_t high;
+};
+
 /*
  * Expand last_exec array.
  *
@@ -47,17 +52,18 @@ static void expand_last_exec(int cpu_index)
 g_rw_lock_writer_unlock(&expand_array_lock);
 }
 
-static bool match_vaddr(struct execlog_ctx *ctx, uint64_t vaddr)
+static bool match_address_range(GArray *match, uint64_t vaddr)
 {
-for (int i = 0; i < dmatches->len; i++) {
-uint64_t v = g_array_index(dmatches, uint64_t, i);
-if (v == vaddr) {
-ctx->log = true;
+for (int i = 0; i < match->len; i++) {
+struct address_match *m =
+g_array_index(match, struct address_match *, i);
+if (vaddr >= m->low && vaddr <= m->high) {
 return true;
 }
 }
 return false;
 }
+
 /**
  * Add memory read or write information to current instruction log
  */
@@ -70,9 +76,10 @@ static void vcpu_mem(unsigned int cpu_index, 
qemu_plugin_meminfo_t info,
 struct execlog_ctx *ctx = g_ptr_array_index(last_exec, cpu_index);
 g_rw_lock_reader_unlock(&expand_array_lock);
 
-if (dmatches && !match_vaddr(ctx, vaddr)) {
+if (dmatches && !match_address_range(dmatches, vaddr)) {
 return;
 }
+ctx->log = true;
 GString *s = ctx->s;
 /* Indicate type of memory access */
 if (qemu_plugin_mem_is_store(info)) {
@@ -166,8 +173,7 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct 
qemu_plugin_tb *tb)
 if (skip && amatches) {
 int j;
 for (j = 0; j < amatches->len && skip; j++) {
-uint64_t v = g_array_index(amatches, uint64_t, j);
-if (v == insn_vaddr) {
+if (match_address_range(amatches, insn_vaddr)) {
 skip = false;
 }
 }
@@ -197,6 +203,16 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct 
qemu_plugin_tb *tb)
 }
 }
 
+static void free_matches(GArray *matches)
+{
+if (!matches) {
+return;
+}
+
+for (int i = 0; i < matches->len; i++) {
+g_free(g_array_index(matches, struct address_match *, i));
+}
+}
 /**
  * On plugin exit, print last instruction in cache
  */
@@ -212,6 +228,9 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
 qemu_plugin_outs("\n");
 }
 }
+
+free_matches(amatches);
+free_matches(dmatches);
 }
 
 /* Add a match to the array of matches */
@@ -223,14 +242,34 @@ static void parse_insn_match(char *match)
 g_ptr_array_add(imatches, match);
 }
 
-static void parse_vaddr_match(GArray **matches, char *match)
+static void parse_vaddr_match(GArray **matches, char *token)
 {
-uint64_t v = g_ascii_strtoull(match, NULL, 16);
+uint64_t low, high;
+gchar *endp;
 
-if (!matches) {
-*matches = g_array_new(false, true, sizeof(uint64_t));
+low = g_ascii_strtoull(token, &endp, 16);
+if (endp == token) {
+fprintf(stderr, "Invalid address(range) specified: %s\n", token);
+return;
+}
+
+if (*endp != '-') {
+high = low;
+} else {
+high = g_ascii_strtoull(endp + 1, &endp, 16);
+if (endp == token) {
+fprintf(stderr, "Invalid address(range) specified: %s\n", token);
+return;
+}
+}
+
+if (!*matches) {
+*matches = g_array_new(false, true, sizeof(struct address_match));
 }
-g_array_append_val(*matches, v);
+struct address_match *match = g_new(struct address_match, 1);
+match->low = low;
+match->high = high;
+g_array_append_val(*matches, match);
 }
 
 /**
-- 
2.43.2




[PATCH 0/4] plugins/execlog: add data address match and address range support

2024-02-28 Thread Sven Schnelle
Hi List,

this patchset adds a new -dfilter option and address range matching. With this
execlog can match only a certain range of address for both instruction and
data adresses.

Example usage:

qemu-system-xxx  -d plugin -plugin 
libexeclog.so,afilter=0x1000-0x2000,dfilter=0x388

This would only log instruction in the address range 0x1000 to 0x2000
and accessing data at address 0x388.

Sven Schnelle (4):
  plugins/execlog: add struct execlog_ctx
  plugins/execlog: pass matches array to parse_vaddr_match
  plugins/execlog: add data address match
  plugins/execlog: add address range matching

 contrib/plugins/execlog.c | 102 ++
 1 file changed, 82 insertions(+), 20 deletions(-)

-- 
2.43.2




[PATCH 1/3] Revert "target/hppa: Drop attempted gdbstub support for hppa64"

2024-02-28 Thread Sven Schnelle
Despite commit e207b4aa718e ("target/hppa: Drop attempted gdbstub
support for hppa64") saying that hppa-linux-gdb doesn't support 64 bit
mode via remote protocol, it is actually working with a small add-on
patch which enables gdb to guess the size from the g protocol:

$ hppa64-linux-gnu-gdb ~/seabios-hppa/out-64/hppa-firmware64.img
[..]
Reading symbols from /home/svens/seabios-hppa/out-64/hppa-firmware64.img...
(gdb) target remote :1234
Remote debugging using :1234
warning: remote target does not support file transfer, attempting to access 
files from local filesystem.
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
startup () at src/parisc/head.S:144
144 rsm PSW_I, %r0  /* disable local irqs */
(gdb)

Signed-off-by: Sven Schnelle 
---
 target/hppa/gdbstub.c | 32 +++-
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c
index 4a965b38d7..48a514384f 100644
--- a/target/hppa/gdbstub.c
+++ b/target/hppa/gdbstub.c
@@ -21,16 +21,11 @@
 #include "cpu.h"
 #include "gdbstub/helpers.h"
 
-/*
- * GDB 15 only supports PA1.0 via the remote protocol, and ignores
- * any provided xml.  Which means that any attempt to provide more
- * data results in "Remote 'g' packet reply is too long".
- */
-
 int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
-CPUHPPAState *env = cpu_env(cs);
-uint32_t val;
+HPPACPU *cpu = HPPA_CPU(cs);
+CPUHPPAState *env = &cpu->env;
+target_ureg val;
 
 switch (n) {
 case 0:
@@ -144,13 +139,24 @@ int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray 
*mem_buf, int n)
 break;
 }
 
-return gdb_get_reg32(mem_buf, val);
+if (TARGET_REGISTER_BITS == 64) {
+return gdb_get_reg64(mem_buf, val);
+} else {
+return gdb_get_reg32(mem_buf, val);
+}
 }
 
 int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 {
-CPUHPPAState *env = cpu_env(cs);
-uint32_t val = ldl_p(mem_buf);
+HPPACPU *cpu = HPPA_CPU(cs);
+CPUHPPAState *env = &cpu->env;
+target_ureg val;
+
+if (TARGET_REGISTER_BITS == 64) {
+val = ldq_p(mem_buf);
+} else {
+val = ldl_p(mem_buf);
+}
 
 switch (n) {
 case 0:
@@ -160,7 +166,7 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->gr[n] = val;
 break;
 case 32:
-env->cr[CR_SAR] = val & (hppa_is_pa20(env) ? 63 : 31);
+env->cr[CR_SAR] = val;
 break;
 case 33:
 env->iaoq_f = val;
@@ -272,5 +278,5 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 }
 break;
 }
-return 4;
+return sizeof(target_ureg);
 }
-- 
2.43.2




[PATCH 0/3] 64 Bit support for hppa gdbstub

2024-02-28 Thread Sven Schnelle
Hi List,

this patchset allows to debug the hppa target when running in wide (64 bit)
mode. gdb needs a small patch to switch to 64 bit mode. I pushed the
patch to 
https://github.com/bminor/binutils-gdb/commit/fd8662ec282d688d1f8100b4365823e57516857b
With this patch gdb will switch to the appropriate mode when connecting
to qemu/gdbstub.

Sven Schnelle (3):
  Revert "target/hppa: Drop attempted gdbstub support for hppa64"
  target/hppa: add 64 bit support to gdbstub
  target/hppa: mask CR_SAR register writes to 5/6 bit in gdbstub

 target/hppa/gdbstub.c | 66 +--
 1 file changed, 45 insertions(+), 21 deletions(-)

-- 
2.43.2




[PATCH 3/3] target/hppa: mask CR_SAR register writes to 5/6 bit in gdbstub

2024-02-28 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 target/hppa/gdbstub.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c
index a5b2c80c07..049b2d6381 100644
--- a/target/hppa/gdbstub.c
+++ b/target/hppa/gdbstub.c
@@ -184,7 +184,7 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->gr[n] = val;
 break;
 case 32:
-env->cr[CR_SAR] = val;
+env->cr[CR_SAR] = val & (hppa_is_pa20(env) ? 63 : 31);
 break;
 case 33:
 env->iaoq_f = val;
-- 
2.43.2




[PATCH 2/3] target/hppa: add 64 bit support to gdbstub

2024-02-28 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 target/hppa/gdbstub.c | 48 +--
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c
index 48a514384f..a5b2c80c07 100644
--- a/target/hppa/gdbstub.c
+++ b/target/hppa/gdbstub.c
@@ -21,11 +21,25 @@
 #include "cpu.h"
 #include "gdbstub/helpers.h"
 
+static int hppa_num_regs(CPUHPPAState *env)
+{
+return hppa_is_pa20(env) ? 96 : 128;
+}
+
+static int hppa_reg_size(CPUHPPAState *env)
+{
+return hppa_is_pa20(env) ? 8 : 4;
+}
+
 int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
 HPPACPU *cpu = HPPA_CPU(cs);
 CPUHPPAState *env = &cpu->env;
-target_ureg val;
+target_ulong val;
+
+if (n >= hppa_num_regs(env)) {
+return 0;
+}
 
 switch (n) {
 case 0:
@@ -128,18 +142,18 @@ int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray 
*mem_buf, int n)
 val = env->cr[30];
 break;
 case 64 ... 127:
-val = extract64(env->fr[(n - 64) / 2], (n & 1 ? 0 : 32), 32);
-break;
-default:
-if (n < 128) {
-val = 0;
+if (hppa_is_pa20(env)) {
+val = env->fr[n - 64];
 } else {
-return 0;
+val = extract64(env->fr[(n - 64) / 2], (n & 1 ? 0 : 32), 32);
 }
 break;
+default:
+val = 0;
+break;
 }
 
-if (TARGET_REGISTER_BITS == 64) {
+if (hppa_is_pa20(env)) {
 return gdb_get_reg64(mem_buf, val);
 } else {
 return gdb_get_reg32(mem_buf, val);
@@ -150,9 +164,13 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 {
 HPPACPU *cpu = HPPA_CPU(cs);
 CPUHPPAState *env = &cpu->env;
-target_ureg val;
+target_ulong val;
+
+if (n >= hppa_num_regs(env)) {
+return 0;
+}
 
-if (TARGET_REGISTER_BITS == 64) {
+if (hppa_is_pa20(env)) {
 val = ldq_p(mem_buf);
 } else {
 val = ldl_p(mem_buf);
@@ -267,16 +285,16 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 cpu_hppa_loaded_fr0(env);
 break;
 case 65 ... 127:
-{
+if (hppa_is_pa20(env)) {
+env->fr[n - 64] = val;
+} else {
 uint64_t *fr = &env->fr[(n - 64) / 2];
 *fr = deposit64(*fr, (n & 1 ? 0 : 32), 32, val);
 }
 break;
 default:
-if (n >= 128) {
-return 0;
-}
 break;
 }
-return sizeof(target_ureg);
+
+return hppa_reg_size(env);
 }
-- 
2.43.2




[PATCH] hw/scsi/lsi53c895a: add hack to prevent scsi timeouts in HP-UX 10.20

2024-02-28 Thread Sven Schnelle
HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
under certain circumstances. As the SCSI controller and CPU are not
running at the same time this loop will never finish. After some
time, the check loop interrupts with a unexpected device disconnect.
This works, but is slow because the kernel resets the scsi controller.
Instead of signaling UDC, add an option 'hpux-spin-workaround' which
emulates a INTERRUPT 2 script instruction. This instruction tells the
kernel that the request was fulfilled. With this change, SCSI speeds
improves significantly.

The option can be enabled by adding

-global lsi53c895a.hpux-spin-workaround=on

to the qemu commandline.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d607a5f9fb..20c353f594 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -304,6 +304,7 @@ struct LSIState {
 uint32_t adder;
 
 uint8_t script_ram[2048 * sizeof(uint32_t)];
+bool hpux_spin_workaround;
 };
 
 #define TYPE_LSI53C810  "lsi53c810"
@@ -1156,8 +1157,17 @@ again:
 qemu_log_mask(LOG_GUEST_ERROR,
   "lsi_scsi: inf. loop with UDC masked");
 }
-lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
-lsi_disconnect(s);
+if (s->hpux_spin_workaround) {
+/*
+ * Workaround for HP-UX 10.20: Instead of disconnecting, which
+ * causes a long delay, emulate a INTERRUPT 2 instruction.
+ */
+s->dsps = 2;
+lsi_script_dma_interrupt(s, LSI_DSTAT_SIR);
+} else {
+lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
+lsi_disconnect(s);
+}
 trace_lsi_execute_script_stop();
 reentrancy_level--;
 return;
@@ -2339,6 +2349,11 @@ static void lsi_scsi_exit(PCIDevice *dev)
 address_space_destroy(&s->pci_io_as);
 }
 
+static Property lsi_props[] = {
+DEFINE_PROP_BOOL("hpux-spin-workaround", LSIState, hpux_spin_workaround,
+ false),
+};
+
 static void lsi_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -2353,6 +2368,7 @@ static void lsi_class_init(ObjectClass *klass, void *data)
 dc->reset = lsi_scsi_reset;
 dc->vmsd = &vmstate_lsi_scsi;
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+device_class_set_props(dc, lsi_props);
 }
 
 static const TypeInfo lsi_info = {
-- 
2.43.2




[PATCH 0/3] plugins/execlog: add data address match and address range support

2024-02-29 Thread Sven Schnelle
Hi List,

this patchset adds a new -dfilter option and address range matching. With this
execlog can match only a certain range of address for both instruction and
data adresses.

Example usage:

qemu-system-xxx  -d plugin -plugin 
libexeclog.so,afilter=0x1000-0x2000,dfilter=0x388

This would only log instruction in the address range 0x1000 to 0x2000
and accessing data at address 0x388.

Changes in v2:
- rebased on top of latest master

Sven Schnelle (3):
  plugins/execlog: pass matches array to parse_vaddr_match
  plugins/execlog: add data address match
  plugins/execlog: add address range matching

 contrib/plugins/execlog.c | 95 ---
 1 file changed, 79 insertions(+), 16 deletions(-)

-- 
2.43.2




[PATCH 2/3] plugins/execlog: add data address match

2024-02-29 Thread Sven Schnelle
Add a match similar to the afilter address match, but for data
addresses. When an address is specified with '-dfilter=0x12345'
only load/stores to/from address 0x12345 are printed. All other
instructions are hidden.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 32 
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index 934553e83d..c89ebc08b6 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -27,6 +27,8 @@ typedef struct CPU {
 GString *last_exec;
 /* Ptr array of Register */
 GPtrArray *registers;
+/* whether this instruction should be logged */
+bool log;
 } CPU;
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
@@ -36,6 +38,7 @@ static GRWLock expand_array_lock;
 
 static GPtrArray *imatches;
 static GArray *amatches;
+static GArray *dmatches;
 static GPtrArray *rmatches;
 static bool disas_assist;
 static GMutex add_reg_name_lock;
@@ -51,6 +54,17 @@ static CPU *get_cpu(int vcpu_index)
 return c;
 }
 
+static bool match_vaddr(uint64_t vaddr)
+{
+for (int i = 0; i < dmatches->len; i++) {
+uint64_t v = g_array_index(dmatches, uint64_t, i);
+if (v == vaddr) {
+return true;
+}
+}
+return false;
+}
+
 /**
  * Add memory read or write information to current instruction log
  */
@@ -62,6 +76,11 @@ static void vcpu_mem(unsigned int cpu_index, 
qemu_plugin_meminfo_t info,
 
 /* Find vCPU in array */
 
+if (dmatches && !match_vaddr(vaddr)) {
+return;
+}
+c->log = true;
+
 /* Indicate type of memory access */
 if (qemu_plugin_mem_is_store(info)) {
 g_string_append(s, ", store");
@@ -121,15 +140,17 @@ static void vcpu_insn_exec_with_regs(unsigned int 
cpu_index, void *udata)
 if (cpu->registers) {
 insn_check_regs(cpu);
 }
-
-qemu_plugin_outs(cpu->last_exec->str);
-qemu_plugin_outs("\n");
+if (cpu->log) {
+qemu_plugin_outs(cpu->last_exec->str);
+qemu_plugin_outs("\n");
+}
 }
 
 /* Store new instruction in cache */
 /* vcpu_mem will add memory access information to last_exec */
 g_string_printf(cpu->last_exec, "%u, ", cpu_index);
 g_string_append(cpu->last_exec, (char *)udata);
+cpu->log = dmatches ? false : true;
 }
 
 /* Log last instruction while checking registers, ignore next */
@@ -166,6 +187,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void 
*udata)
 /* vcpu_mem will add memory access information to last_exec */
 g_string_printf(cpu->last_exec, "%u, ", cpu_index);
 g_string_append(cpu->last_exec, (char *)udata);
+cpu->log = dmatches ? false : true;
 }
 
 /**
@@ -381,7 +403,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
 g_rw_lock_reader_lock(&expand_array_lock);
 for (i = 0; i < cpus->len; i++) {
 CPU *c = get_cpu(i);
-if (c->last_exec && c->last_exec->str) {
+if (c->log && c->last_exec && c->last_exec->str) {
 qemu_plugin_outs(c->last_exec->str);
 qemu_plugin_outs("\n");
 }
@@ -441,6 +463,8 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t 
id,
 parse_insn_match(tokens[1]);
 } else if (g_strcmp0(tokens[0], "afilter") == 0) {
 parse_vaddr_match(&amatches, tokens[1]);
+} else if (g_strcmp0(tokens[0], "dfilter") == 0) {
+parse_vaddr_match(&dmatches, tokens[1]);
 } else if (g_strcmp0(tokens[0], "reg") == 0) {
 add_regpat(tokens[1]);
 } else if (g_strcmp0(tokens[0], "rdisas") == 0) {
-- 
2.43.2




[PATCH 3/3] plugins/execlog: add address range matching

2024-02-29 Thread Sven Schnelle
Allow to match memory ranges with the address matches. This
allows to give a range of adresses like '-dfilter=0-0x400'
which would only log memory accesses between 0 and 400.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 73 ++-
 1 file changed, 56 insertions(+), 17 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index c89ebc08b6..b1b2a7baf1 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -44,6 +44,11 @@ static bool disas_assist;
 static GMutex add_reg_name_lock;
 static GPtrArray *all_reg_names;
 
+struct address_match {
+uint64_t low;
+uint64_t high;
+};
+
 static CPU *get_cpu(int vcpu_index)
 {
 CPU *c;
@@ -54,11 +59,12 @@ static CPU *get_cpu(int vcpu_index)
 return c;
 }
 
-static bool match_vaddr(uint64_t vaddr)
+static bool match_address_range(GArray *match, uint64_t vaddr)
 {
-for (int i = 0; i < dmatches->len; i++) {
-uint64_t v = g_array_index(dmatches, uint64_t, i);
-if (v == vaddr) {
+for (int i = 0; i < match->len; i++) {
+struct address_match *m =
+g_array_index(match, struct address_match *, i);
+if (vaddr >= m->low && vaddr <= m->high) {
 return true;
 }
 }
@@ -74,9 +80,7 @@ static void vcpu_mem(unsigned int cpu_index, 
qemu_plugin_meminfo_t info,
 CPU *c = get_cpu(cpu_index);
 GString *s = c->last_exec;
 
-/* Find vCPU in array */
-
-if (dmatches && !match_vaddr(vaddr)) {
+if (dmatches && !match_address_range(dmatches, vaddr)) {
 return;
 }
 c->log = true;
@@ -164,8 +168,10 @@ static void vcpu_insn_exec_only_regs(unsigned int 
cpu_index, void *udata)
 insn_check_regs(cpu);
 }
 
-qemu_plugin_outs(cpu->last_exec->str);
-qemu_plugin_outs("\n");
+if (cpu->log) {
+qemu_plugin_outs(cpu->last_exec->str);
+qemu_plugin_outs("\n");
+}
 }
 
 /* reset */
@@ -178,7 +184,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void 
*udata)
 CPU *cpu = get_cpu(cpu_index);
 
 /* Print previous instruction in cache */
-if (cpu->last_exec->len) {
+if (cpu->log && cpu->last_exec->len) {
 qemu_plugin_outs(cpu->last_exec->str);
 qemu_plugin_outs("\n");
 }
@@ -239,8 +245,7 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct 
qemu_plugin_tb *tb)
 if (skip && amatches) {
 int j;
 for (j = 0; j < amatches->len && skip; j++) {
-uint64_t v = g_array_index(amatches, uint64_t, j);
-if (v == insn_vaddr) {
+if (match_address_range(amatches, insn_vaddr)) {
 skip = false;
 }
 }
@@ -394,6 +399,17 @@ static void vcpu_init(qemu_plugin_id_t id, unsigned int 
vcpu_index)
 c->registers = registers_init(vcpu_index);
 }
 
+static void free_matches(GArray *matches)
+{
+if (!matches) {
+return;
+}
+
+for (int i = 0; i < matches->len; i++) {
+g_free(g_array_index(matches, struct address_match *, i));
+}
+}
+
 /**
  * On plugin exit, print last instruction in cache
  */
@@ -409,6 +425,9 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
 }
 }
 g_rw_lock_reader_unlock(&expand_array_lock);
+
+free_matches(amatches);
+free_matches(dmatches);
 }
 
 /* Add a match to the array of matches */
@@ -420,14 +439,34 @@ static void parse_insn_match(char *match)
 g_ptr_array_add(imatches, g_strdup(match));
 }
 
-static void parse_vaddr_match(GArray **matches, char *match)
+static void parse_vaddr_match(GArray **matches, char *token)
 {
-uint64_t v = g_ascii_strtoull(match, NULL, 16);
+uint64_t low, high;
+gchar *endp;
 
-if (!matches) {
-*matches = g_array_new(false, true, sizeof(uint64_t));
+low = g_ascii_strtoull(token, &endp, 16);
+if (endp == token) {
+fprintf(stderr, "Invalid address(range) specified: %s\n", token);
+return;
+}
+
+if (*endp != '-') {
+high = low;
+} else {
+high = g_ascii_strtoull(endp + 1, &endp, 16);
+if (endp == token) {
+fprintf(stderr, "Invalid address(range) specified: %s\n", token);
+return;
+}
+}
+
+if (!*matches) {
+*matches = g_array_new(false, true, sizeof(struct address_match));
 }
-g_array_append_val(*matches, v);
+struct address_match *match = g_new(struct address_match, 1);
+match->low = low;
+match->high = high;
+g_array_append_val(*matches, match);
 }
 
 /*
-- 
2.43.2




Re: [PATCH 0/4] plugins/execlog: add data address match and address range support

2024-02-29 Thread Sven Schnelle
Pierrick Bouvier  writes:

> Hi Sven, thanks for your series.
>
> Yesterday, series for new API to access registers from plugins was
> merged. As part of it, execlog plugin was extended to support this
> [1].
> This conflict with the changes presented here.
>
> Could you please rebase this series on top of master?

I sent out a rebased version. Should have done a git pull before...

Thanks,
Sven



Re: [PATCH] hw/scsi/lsi53c895a: add hack to prevent scsi timeouts in HP-UX 10.20

2024-02-29 Thread Sven Schnelle
Peter Maydell  writes:

> On Wed, 28 Feb 2024 at 21:12, Sven Schnelle  wrote:
>>
>> HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
>> under certain circumstances. As the SCSI controller and CPU are not
>> running at the same time this loop will never finish. After some
>> time, the check loop interrupts with a unexpected device disconnect.
>> This works, but is slow because the kernel resets the scsi controller.
>> Instead of signaling UDC, add an option 'hpux-spin-workaround' which
>> emulates a INTERRUPT 2 script instruction. This instruction tells the
>> kernel that the request was fulfilled. With this change, SCSI speeds
>> improves significantly.
>> [..]
> I see we already have a hacky workaround for other OSes
> that do something similar. The ideal fix for both of these
> I think would be for lsi_execute_script() to, instead of stopping,
> arrange to defer executing more script instructions until
> after the guest has had a chance to run a bit more.
> I think setting a timer that calls lsi_resume_script() after
> a while would have that effect.

Thanks, good idea. So something like this?

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d607a5f9fb..9931799d44 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -188,7 +188,7 @@ static const char *names[] = {
 #define LSI_TAG_VALID (1 << 16)
 
 /* Maximum instructions to process. */
-#define LSI_MAX_INSN1
+#define LSI_MAX_INSN1000
 
 typedef struct lsi_request {
 SCSIRequest *req;
@@ -205,6 +205,7 @@ enum {
 LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
 LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
 LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
+LSI_WAIT_SCRIPTS, /* SCRIPTS where stopped because of instruction count 
limit */
 };
 
 enum {
@@ -224,6 +225,7 @@ struct LSIState {
 MemoryRegion ram_io;
 MemoryRegion io_io;
 AddressSpace pci_io_as;
+QEMUTimer *scripts_timer;
 
 int carry; /* ??? Should this be an a visible register somewhere?  */
 int status;
@@ -1152,13 +1154,9 @@ again:
  * which should be enough for all valid use cases).
  */
 if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
-if (!(s->sien0 & LSI_SIST0_UDC)) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "lsi_scsi: inf. loop with UDC masked");
-}
-lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
-lsi_disconnect(s);
-trace_lsi_execute_script_stop();
+s->waiting = LSI_WAIT_SCRIPTS;
+timer_mod(s->scripts_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 
500);
+trace_lsi_scripts_timer_arm();
 reentrancy_level--;
 return;
 }
@@ -2294,6 +2292,17 @@ static const struct SCSIBusInfo lsi_scsi_info = {
 .cancel = lsi_request_cancelled
 };
 
+static void scripts_timer_cb(void *opaque)
+{
+LSIState *s = opaque;
+
+trace_lsi_scripts_timer_triggered();
+if (s->waiting == LSI_WAIT_SCRIPTS) {
+s->waiting = 0;
+lsi_execute_script(s);
+}
+}
+
 static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
 {
 LSIState *s = LSI53C895A(dev);
@@ -2313,6 +2322,7 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
   "lsi-ram", 0x2000);
 memory_region_init_io(&s->io_io, OBJECT(s), &lsi_io_ops, s,
   "lsi-io", 256);
+s->scripts_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, scripts_timer_cb, s);
 
 /*
  * Since we use the address-space API to interact with ram_io, disable the
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index d72f741ed8..4456a08ab0 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -302,6 +302,8 @@ lsi_execute_script_stop(void) "SCRIPTS execution stopped"
 lsi_awoken(void) "Woken by SIGP"
 lsi_reg_read(const char *name, int offset, uint8_t ret) "Read reg %s 0x%x = 
0x%02x"
 lsi_reg_write(const char *name, int offset, uint8_t val) "Write reg %s 0x%x = 
0x%02x"
+lsi_scripts_timer_triggered(void) "SCRIPTS timer triggered"
+lsi_scripts_timer_arm(void) "SCRIPTS timer armed"
 
 # virtio-scsi.c
 virtio_scsi_cmd_req(int lun, uint32_t tag, uint8_t cmd) "virtio_scsi_cmd_req 
lun=%u tag=0x%x cmd=0x%x"



Re: [PATCH] hw/scsi/lsi53c895a: add hack to prevent scsi timeouts in HP-UX 10.20

2024-02-29 Thread Sven Schnelle
Peter Maydell  writes:

> On Thu, 29 Feb 2024 at 16:54, Sven Schnelle  wrote:
>>
>> Peter Maydell  writes:
>>
>> > On Wed, 28 Feb 2024 at 21:12, Sven Schnelle  wrote:
>> >>
>> >> HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
>> >> under certain circumstances. As the SCSI controller and CPU are not
>> >> running at the same time this loop will never finish. After some
>> >> time, the check loop interrupts with a unexpected device disconnect.
>> >> This works, but is slow because the kernel resets the scsi controller.
>> >> Instead of signaling UDC, add an option 'hpux-spin-workaround' which
>> >> emulates a INTERRUPT 2 script instruction. This instruction tells the
>> >> kernel that the request was fulfilled. With this change, SCSI speeds
>> >> improves significantly.
>> >> [..]
>> > I see we already have a hacky workaround for other OSes
>> > that do something similar. The ideal fix for both of these
>> > I think would be for lsi_execute_script() to, instead of stopping,
>> > arrange to defer executing more script instructions until
>> > after the guest has had a chance to run a bit more.
>> > I think setting a timer that calls lsi_resume_script() after
>> > a while would have that effect.
>>
>> Thanks, good idea. So something like this?
>
> Yeah, something like that I think. (You probably want to delete
> the timer on reset, and you need to handle migration -- you can
> either put the timer state in a new vmstate section, or else
> in post-load if the state is 'LSI_WAIT_SCRIPTS' arm the timer.)

> Does it work? :-)

Yes it does. I only did a quick hack without caring about things like
reset, freeing the timer and migration. I successfully booted HP-UX 10.20
without any scsi errors in the dmesg. So i think this is much better
than the commandline option. I'll prepare a proper patch in the next
days and submit it.

Thanks!
Sven



Re: [PATCH 3/3] plugins/execlog: add address range matching

2024-02-29 Thread Sven Schnelle
Hi Alex,

Alex Bennée  writes:

> Sven Schnelle  writes:
>> +static void parse_vaddr_match(GArray **matches, char *token)
>>  {
>> -uint64_t v = g_ascii_strtoull(match, NULL, 16);
>> +uint64_t low, high;
>> +gchar *endp;
>>  
>> -if (!matches) {
>> -*matches = g_array_new(false, true, sizeof(uint64_t));
>> +low = g_ascii_strtoull(token, &endp, 16);
>> +if (endp == token) {
>> +fprintf(stderr, "Invalid address(range) specified: %s\n", token);
>> +return;
>> +}
>> +
>> +if (*endp != '-') {
>> +high = low;
>> +} else {
>> +high = g_ascii_strtoull(endp + 1, &endp, 16);
>> +if (endp == token) {
>> +fprintf(stderr, "Invalid address(range) specified: %s\n", 
>> token);
>> +return;
>> +}
>> +}
>> +
>> +if (!*matches) {
>> +*matches = g_array_new(false, true, sizeof(struct address_match));
>>  }
>> -g_array_append_val(*matches, v);
>> +struct address_match *match = g_new(struct address_match, 1);
>> +match->low = low;
>> +match->high = high;
>> +g_array_append_val(*matches, match);
>
> This is almost but not quite qemu_set_dfilter_ranges(). I wonder if it
> would be worth a light re-factoring and then exposing the parser as a
> helper function?

Thanks, I'll take a look. I wasn't aware of qemu_set_dfilter_ranges().



[PATCH] hw/scsi/lsi53c895a: add timer to scripts processing

2024-02-29 Thread Sven Schnelle
Some OS's like HP-UX 10.20 are spinn

HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
under certain circumstances. As the SCSI controller and CPU are not
running at the same time this loop will never finish. After some
time, the check loop interrupts with a unexpected device disconnect.
This works, but is slow because the kernel resets the scsi controller.
Instead of signaling UDC, start a timer and exit the loop. Until the
timer fires, the CPU can process instructions until the timer fires.
The limit of instructions is also reduced because scripts running
on the SCSI processor are usually very short. This keeps the time
until the loop-exit short.

Suggested-by: Peter Maydell 
Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 33 +
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d607a5f9fb..0b6f1dc72f 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -188,7 +188,7 @@ static const char *names[] = {
 #define LSI_TAG_VALID (1 << 16)
 
 /* Maximum instructions to process. */
-#define LSI_MAX_INSN1
+#define LSI_MAX_INSN100
 
 typedef struct lsi_request {
 SCSIRequest *req;
@@ -205,6 +205,7 @@ enum {
 LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
 LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
 LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
+LSI_WAIT_SCRIPTS, /* SCRIPTS stopped because of instruction count limit */
 };
 
 enum {
@@ -224,6 +225,7 @@ struct LSIState {
 MemoryRegion ram_io;
 MemoryRegion io_io;
 AddressSpace pci_io_as;
+QEMUTimer *scripts_timer;
 
 int carry; /* ??? Should this be an a visible register somewhere?  */
 int status;
@@ -415,6 +417,7 @@ static void lsi_soft_reset(LSIState *s)
 s->sbr = 0;
 assert(QTAILQ_EMPTY(&s->queue));
 assert(!s->current);
+timer_del(s->scripts_timer);
 }
 
 static int lsi_dma_40bit(LSIState *s)
@@ -1127,6 +1130,12 @@ static void lsi_wait_reselect(LSIState *s)
 }
 }
 
+static void lsi_scripts_timer_start(LSIState *s)
+{
+trace_lsi_scripts_timer_start();
+timer_mod(s->scripts_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);
+}
+
 static void lsi_execute_script(LSIState *s)
 {
 PCIDevice *pci_dev = PCI_DEVICE(s);
@@ -1152,13 +1161,8 @@ again:
  * which should be enough for all valid use cases).
  */
 if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
-if (!(s->sien0 & LSI_SIST0_UDC)) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "lsi_scsi: inf. loop with UDC masked");
-}
-lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
-lsi_disconnect(s);
-trace_lsi_execute_script_stop();
+s->waiting = LSI_WAIT_SCRIPTS;
+lsi_scripts_timer_start(s);
 reentrancy_level--;
 return;
 }
@@ -2197,6 +2201,9 @@ static int lsi_post_load(void *opaque, int version_id)
 return -EINVAL;
 }
 
+if (s->waiting == LSI_WAIT_SCRIPTS) {
+lsi_scripts_timer_start(s);
+}
 return 0;
 }
 
@@ -2294,6 +2301,15 @@ static const struct SCSIBusInfo lsi_scsi_info = {
 .cancel = lsi_request_cancelled
 };
 
+static void scripts_timer_cb(void *opaque)
+{
+LSIState *s = opaque;
+
+trace_lsi_scripts_timer_triggered();
+s->waiting = LSI_NOWAIT;
+lsi_execute_script(s);
+}
+
 static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
 {
 LSIState *s = LSI53C895A(dev);
@@ -2313,6 +2329,7 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
   "lsi-ram", 0x2000);
 memory_region_init_io(&s->io_io, OBJECT(s), &lsi_io_ops, s,
   "lsi-io", 256);
+s->scripts_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, scripts_timer_cb, s);
 
 /*
  * Since we use the address-space API to interact with ram_io, disable the
-- 
2.43.2




Re: [PATCH 0/3] plugins/execlog: add data address match and address range support

2024-02-29 Thread Sven Schnelle
Hi Alex,

Alex Bennée  writes:

> Sven Schnelle  writes:
> I think we've lost a patch in the re-posting. patchew hasn't seen it
> either:
>
>   https://patchew.org/QEMU/20240229150729.1620410-1-sv...@stackframe.org/
>
>>   plugins/execlog: add data address match
>>   plugins/execlog: add address range matching
>>
>>  contrib/plugins/execlog.c | 95 ---
>>  1 file changed, 79 insertions(+), 16 deletions(-)

Yes, i got a 550 mail. But i'll look into the qemu_set_dfilter_ranges()
before resending.



Re: [PATCH] hw/scsi/lsi53c895a: add timer to scripts processing

2024-02-29 Thread Sven Schnelle
BALATON Zoltan  writes:

> On Thu, 29 Feb 2024, Sven Schnelle wrote:
>> Some OS's like HP-UX 10.20 are spinn
>
> I guess the above line is left here by accident.

Yes.

>> HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
>> under certain circumstances. As the SCSI controller and CPU are not
>> running at the same time this loop will never finish. After some
>> time, the check loop interrupts with a unexpected device disconnect.
>> This works, but is slow because the kernel resets the scsi controller.
>> Instead of signaling UDC, start a timer and exit the loop. Until the
>> timer fires, the CPU can process instructions until the timer fires.
>> The limit of instructions is also reduced because scripts running
>> on the SCSI processor are usually very short. This keeps the time
>> until the loop-exit short.
>>
>> Suggested-by: Peter Maydell 
>> Signed-off-by: Sven Schnelle 
>> ---
>> hw/scsi/lsi53c895a.c | 33 +
>> 1 file changed, 25 insertions(+), 8 deletions(-)
>>
>> diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
>> index d607a5f9fb..0b6f1dc72f 100644
>> --- a/hw/scsi/lsi53c895a.c
>> +++ b/hw/scsi/lsi53c895a.c
>> @@ -188,7 +188,7 @@ static const char *names[] = {
>> #define LSI_TAG_VALID (1 << 16)
>>
>> /* Maximum instructions to process. */
>> -#define LSI_MAX_INSN1
>> +#define LSI_MAX_INSN100
>>
>> typedef struct lsi_request {
>> SCSIRequest *req;
>> @@ -205,6 +205,7 @@ enum {
>> LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
>> LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
>> LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
>> +LSI_WAIT_SCRIPTS, /* SCRIPTS stopped because of instruction count limit 
>> */
>> };
>>
>> enum {
>> @@ -224,6 +225,7 @@ struct LSIState {
>> MemoryRegion ram_io;
>> MemoryRegion io_io;
>> AddressSpace pci_io_as;
>> +QEMUTimer *scripts_timer;
>>
>> int carry; /* ??? Should this be an a visible register somewhere?  */
>> int status;
>> @@ -415,6 +417,7 @@ static void lsi_soft_reset(LSIState *s)
>> s->sbr = 0;
>> assert(QTAILQ_EMPTY(&s->queue));
>> assert(!s->current);
>> +timer_del(s->scripts_timer);
>
> Maybe the rimer needs to be deleted in lsi_scsi_exit() too but I'm not
> sure.

I added it, thanks.

>> }
>>
>> static int lsi_dma_40bit(LSIState *s)
>> @@ -1127,6 +1130,12 @@ static void lsi_wait_reselect(LSIState *s)
>> }
>> }
>>
>> +static void lsi_scripts_timer_start(LSIState *s)
>> +{
>> +trace_lsi_scripts_timer_start();
>> +timer_mod(s->scripts_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 
>> 500);
>> +}
>> +
>> static void lsi_execute_script(LSIState *s)
>> {
>> PCIDevice *pci_dev = PCI_DEVICE(s);
>> @@ -1152,13 +1161,8 @@ again:
>>  * which should be enough for all valid use cases).
>>  */
>
> Does tha above comment need updating to say what the code does now?

Yes, i changed it to describe the new method:

/*
 * Some windows drivers make the device spin waiting for a memory location
 * to change. If we have executed more than LSI_MAX_INSN instructions then
 * assume this is the case and start a timer. Until the timer fires, the
 * host CPU has a chance to run and change the memory location.
 *
 * Another issue (CVE-2023-0330) can occur if the script is programmed to
 * trigger itself again and again. Avoid this problem by stopping after
 * being called multiple times in a reentrant way (8 is an arbitrary value
 * which should be enough for all valid use cases).
 */

> Regards,
> BALATON Zoltan
>
>> if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
>> -if (!(s->sien0 & LSI_SIST0_UDC)) {
>> -qemu_log_mask(LOG_GUEST_ERROR,
>> -  "lsi_scsi: inf. loop with UDC masked");
>> -}
>> -lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
>> -lsi_disconnect(s);
>> -trace_lsi_execute_script_stop();
>> +s->waiting = LSI_WAIT_SCRIPTS;
>> +lsi_scripts_timer_start(s);
>> reentrancy_level--;
>> return;
>> }
>> @@ -2197,6 +2201,9 @@ static int lsi_post_load(void *opaque, int version_id)
>> return -EINVAL;
>> }
>>
>> +if (s->waiting == LSI_WAIT_SCRIPTS) {
>

[PATCH v2] hw/scsi/lsi53c895a: add timer to scripts processing

2024-02-29 Thread Sven Schnelle
HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
under certain circumstances. As the SCSI controller and CPU are not
running at the same time this loop will never finish. After some
time, the check loop interrupts with a unexpected device disconnect.
This works, but is slow because the kernel resets the scsi controller.
Instead of signaling UDC, start a timer and exit the loop. Until the
timer fires, the CPU can process instructions which might changes the
memory location.

The limit of instructions is also reduced because scripts running on
the SCSI processor are usually very short. This keeps the time until
the loop is exit short.

Suggested-by: Peter Maydell 
Signed-off-by: Sven Schnelle 
---
Changes in v2:
- update comment in lsi_execute_script()
- reset waiting state and del timer in lsi_execute_script() to
  handle the case where script processing is triggered via
  register write, and not from the pending timer
- delete timer in lsi_scsi_exit()

 hw/scsi/lsi53c895a.c | 43 +--
 hw/scsi/trace-events |  2 ++
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d607a5f9fb..4ff9470381 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -188,7 +188,7 @@ static const char *names[] = {
 #define LSI_TAG_VALID (1 << 16)
 
 /* Maximum instructions to process. */
-#define LSI_MAX_INSN1
+#define LSI_MAX_INSN100
 
 typedef struct lsi_request {
 SCSIRequest *req;
@@ -205,6 +205,7 @@ enum {
 LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
 LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
 LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
+LSI_WAIT_SCRIPTS, /* SCRIPTS stopped because of instruction count limit */
 };
 
 enum {
@@ -224,6 +225,7 @@ struct LSIState {
 MemoryRegion ram_io;
 MemoryRegion io_io;
 AddressSpace pci_io_as;
+QEMUTimer *scripts_timer;
 
 int carry; /* ??? Should this be an a visible register somewhere?  */
 int status;
@@ -415,6 +417,7 @@ static void lsi_soft_reset(LSIState *s)
 s->sbr = 0;
 assert(QTAILQ_EMPTY(&s->queue));
 assert(!s->current);
+timer_del(s->scripts_timer);
 }
 
 static int lsi_dma_40bit(LSIState *s)
@@ -1127,6 +1130,12 @@ static void lsi_wait_reselect(LSIState *s)
 }
 }
 
+static void lsi_scripts_timer_start(LSIState *s)
+{
+trace_lsi_scripts_timer_start();
+timer_mod(s->scripts_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);
+}
+
 static void lsi_execute_script(LSIState *s)
 {
 PCIDevice *pci_dev = PCI_DEVICE(s);
@@ -1136,6 +1145,11 @@ static void lsi_execute_script(LSIState *s)
 int insn_processed = 0;
 static int reentrancy_level;
 
+if (s->waiting == LSI_WAIT_SCRIPTS) {
+timer_del(s->scripts_timer);
+s->waiting = LSI_NOWAIT;
+}
+
 reentrancy_level++;
 
 s->istat1 |= LSI_ISTAT1_SRUN;
@@ -1143,8 +1157,8 @@ again:
 /*
  * Some windows drivers make the device spin waiting for a memory location
  * to change. If we have executed more than LSI_MAX_INSN instructions then
- * assume this is the case and force an unexpected device disconnect. This
- * is apparently sufficient to beat the drivers into submission.
+ * assume this is the case and start a timer. Until the timer fires, the
+ * host CPU has a chance to run and change the memory location.
  *
  * Another issue (CVE-2023-0330) can occur if the script is programmed to
  * trigger itself again and again. Avoid this problem by stopping after
@@ -1152,13 +1166,8 @@ again:
  * which should be enough for all valid use cases).
  */
 if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
-if (!(s->sien0 & LSI_SIST0_UDC)) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "lsi_scsi: inf. loop with UDC masked");
-}
-lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
-lsi_disconnect(s);
-trace_lsi_execute_script_stop();
+s->waiting = LSI_WAIT_SCRIPTS;
+lsi_scripts_timer_start(s);
 reentrancy_level--;
 return;
 }
@@ -2197,6 +2206,9 @@ static int lsi_post_load(void *opaque, int version_id)
 return -EINVAL;
 }
 
+if (s->waiting == LSI_WAIT_SCRIPTS) {
+lsi_scripts_timer_start(s);
+}
 return 0;
 }
 
@@ -2294,6 +2306,15 @@ static const struct SCSIBusInfo lsi_scsi_info = {
 .cancel = lsi_request_cancelled
 };
 
+static void scripts_timer_cb(void *opaque)
+{
+LSIState *s = opaque;
+
+trace_lsi_scripts_timer_triggered();
+s->waiting = LSI_NOWAIT;
+lsi_execute_script(s);
+}
+
 static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
 {
 LSIState *s = LSI53C895A(dev);
@@ -2313,6 +2334,7 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
   

Re: [PATCH] hw/scsi/lsi53c895a: add timer to scripts processing

2024-02-29 Thread Sven Schnelle
BALATON Zoltan  writes:

> On Thu, 29 Feb 2024, Sven Schnelle wrote:
>> BALATON Zoltan  writes:
>> Yes, i changed it to describe the new method:
>>
>>/*
>> * Some windows drivers make the device spin waiting for a memory location
>> * to change. If we have executed more than LSI_MAX_INSN instructions then
>> * assume this is the case and start a timer. Until the timer fires, the
>> * host CPU has a chance to run and change the memory location.
>
> Is that the host or guest CPU? I thought the guest vcpu needs to get a
> chance to do something about this but maybe I did not get the problem
> at all.

Of course it's the guest CPU. I'll wait for other review comments and
fix it in the next version.

Thanks!
Sven



[PATCH v3 07/12] util/range: make range_list_from_string() accept a single number

2024-03-01 Thread Sven Schnelle
To use range_list_from_string() as a replacement in the execlog
plugin, make it accept single numbers instead of a range. This
might also be useful for the already present debug_ranges filtering.

Signed-off-by: Sven Schnelle 
---
 util/range.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/util/range.c b/util/range.c
index 8c463995e7..7784c21b12 100644
--- a/util/range.c
+++ b/util/range.c
@@ -154,6 +154,11 @@ static int parse_single_range(const char *r, Error **errp,
 
 range_op = split_single_range(r, &r2);
 if (!range_op) {
+if (!qemu_strtou64(r, &e, 0, &r1val) && *e == '\0') {
+*lob = r1val;
+*upb = r1val;
+return 0;
+}
 error_setg(errp, "Bad range specifier");
 return 1;
 }
-- 
2.43.2




[PATCH v3 01/12] util/log: convert debug_regions to GList

2024-03-01 Thread Sven Schnelle
In preparation of making the parsing part of qemu_set_dfilter_ranges()
available to other users, convert it to return a GList, so the result
can be used with other functions taking a GList of struct Range.

Signed-off-by: Sven Schnelle 
---
 util/log.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/util/log.c b/util/log.c
index d36c98da0b..779c0689a9 100644
--- a/util/log.c
+++ b/util/log.c
@@ -46,7 +46,7 @@ static __thread Notifier qemu_log_thread_cleanup_notifier;
 
 int qemu_loglevel;
 static bool log_per_thread;
-static GArray *debug_regions;
+static GList *debug_regions;
 
 /* Returns true if qemu_log() will really write somewhere. */
 bool qemu_log_enabled(void)
@@ -368,38 +368,36 @@ bool qemu_set_log_filename_flags(const char *name, int 
flags, Error **errp)
  */
 bool qemu_log_in_addr_range(uint64_t addr)
 {
-if (debug_regions) {
-int i = 0;
-for (i = 0; i < debug_regions->len; i++) {
-Range *range = &g_array_index(debug_regions, Range, i);
-if (range_contains(range, addr)) {
-return true;
-}
-}
-return false;
-} else {
+GList *p;
+
+if (!debug_regions) {
 return true;
 }
-}
 
+for (p = g_list_first(debug_regions); p; p = g_list_next(p)) {
+if (range_contains(p->data, addr)) {
+return true;
+}
+}
+return false;
+}
 
 void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
 {
 gchar **ranges = g_strsplit(filter_spec, ",", 0);
+struct Range *range = NULL;
 int i;
 
 if (debug_regions) {
-g_array_unref(debug_regions);
+g_list_free_full(debug_regions, g_free);
 debug_regions = NULL;
 }
 
-debug_regions = g_array_sized_new(FALSE, FALSE,
-  sizeof(Range), g_strv_length(ranges));
 for (i = 0; ranges[i]; i++) {
 const char *r = ranges[i];
 const char *range_op, *r2, *e;
 uint64_t r1val, r2val, lob, upb;
-struct Range range;
+range = g_new0(struct Range, 1);
 
 range_op = strstr(r, "-");
 r2 = range_op ? range_op + 1 : NULL;
@@ -448,10 +446,12 @@ void qemu_set_dfilter_ranges(const char *filter_spec, 
Error **errp)
 error_setg(errp, "Invalid range");
 goto out;
 }
-range_set_bounds(&range, lob, upb);
-g_array_append_val(debug_regions, range);
+range_set_bounds(range, lob, upb);
+debug_regions = g_list_append(debug_regions, range);
+range = NULL;
 }
 out:
+g_free(range);
 g_strfreev(ranges);
 }
 
-- 
2.43.2




[PATCH v3 00/12] plugins/execlog: add data address match and address range support

2024-03-01 Thread Sven Schnelle
Hi List,

this patchset adds a new -dfilter option and address range matching. With this
execlog can match only a certain range of address for both instruction and
data adresses.

Example usage:

qemu-system-xxx  -d plugin -plugin 
libexeclog.so,afilter=0x1000-0x2000,dfilter=0x388

This would only log instruction in the address range 0x1000 to 0x2000
and accessing data at address 0x388.

Changes in v3:
- extend plugin api to re-use the existing range parsing infrastructure
- export error report api

Changes in v2:
- rebased on top of latest master

Sven Schnelle (12):
  util/log: convert debug_regions to GList
  util/log: make qemu_set_dfilter_ranges() take a GList
  util/range: move range_list_from_string() to range.c
  util/range: add range_list_free()
  util/range: use append_new_range() in range_list_from_string()
  util/range: split up range_list_from_string()
  util/range: make range_list_from_string() accept a single number
  qemu/range: add range_list_contains() function
  plugins: add API to print errors
  plugins: add range list API
  plugins/execlog: use range list api
  plugins/execlog: add data address match

 contrib/plugins/execlog.c|  55 +++
 include/qemu/qemu-plugin.h   |  53 ++
 include/qemu/range.h |  24 +
 plugins/api.c|  25 +
 plugins/qemu-plugins.symbols |   4 ++
 util/log.c   |  84 ++---
 util/range.c | 102 +++
 7 files changed, 244 insertions(+), 103 deletions(-)

--
2.43.2



[PATCH v3 05/12] util/range: use append_new_range() in range_list_from_string()

2024-03-01 Thread Sven Schnelle
Use append_new_ranges() instead of manually allocating and
filling the new range member.

Signed-off-by: Sven Schnelle 
---
 util/range.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/util/range.c b/util/range.c
index 7234ab7a53..db535de9a7 100644
--- a/util/range.c
+++ b/util/range.c
@@ -128,7 +128,6 @@ void range_list_from_string(GList **out_ranges, const char 
*filter_spec,
 Error **errp)
 {
 gchar **ranges = g_strsplit(filter_spec, ",", 0);
-struct Range *range = NULL;
 int i;
 
 if (*out_ranges) {
@@ -140,7 +139,6 @@ void range_list_from_string(GList **out_ranges, const char 
*filter_spec,
 const char *r = ranges[i];
 const char *range_op, *r2, *e;
 uint64_t r1val, r2val, lob, upb;
-range = g_new0(struct Range, 1);
 
 range_op = strstr(r, "-");
 r2 = range_op ? range_op + 1 : NULL;
@@ -189,12 +187,9 @@ void range_list_from_string(GList **out_ranges, const char 
*filter_spec,
 error_setg(errp, "Invalid range");
 goto out;
 }
-range_set_bounds(range, lob, upb);
-*out_ranges = g_list_append(*out_ranges, range);
-range = NULL;
+*out_ranges = append_new_range(*out_ranges, lob, upb);
 }
 out:
-g_free(range);
 g_strfreev(ranges);
 }
 
-- 
2.43.2




[PATCH v3 12/12] plugins/execlog: add data address match

2024-03-01 Thread Sven Schnelle
Add a match similar to the afilter address match, but for data
addresses. When an address is specified with '-dfilter=0x12345'
only load/stores to/from address 0x12345 are printed. All other
instructions are hidden.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 28 +++-
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index c518797893..c44fd0e593 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -27,6 +27,8 @@ typedef struct CPU {
 GString *last_exec;
 /* Ptr array of Register */
 GPtrArray *registers;
+/* whether this instruction should be logged */
+bool log;
 } CPU;
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
@@ -36,6 +38,7 @@ static GRWLock expand_array_lock;
 
 static GPtrArray *imatches;
 static GList *amatches;
+static GList *dmatches;
 static GPtrArray *rmatches;
 static bool disas_assist;
 static GMutex add_reg_name_lock;
@@ -62,6 +65,11 @@ static void vcpu_mem(unsigned int cpu_index, 
qemu_plugin_meminfo_t info,
 
 /* Find vCPU in array */
 
+if (dmatches && !qemu_plugin_range_list_contains(dmatches, vaddr)) {
+return;
+}
+c->log = true;
+
 /* Indicate type of memory access */
 if (qemu_plugin_mem_is_store(info)) {
 g_string_append(s, ", store");
@@ -121,15 +129,17 @@ static void vcpu_insn_exec_with_regs(unsigned int 
cpu_index, void *udata)
 if (cpu->registers) {
 insn_check_regs(cpu);
 }
-
-qemu_plugin_outs(cpu->last_exec->str);
-qemu_plugin_outs("\n");
+if (cpu->log) {
+qemu_plugin_outs(cpu->last_exec->str);
+qemu_plugin_outs("\n");
+}
 }
 
 /* Store new instruction in cache */
 /* vcpu_mem will add memory access information to last_exec */
 g_string_printf(cpu->last_exec, "%u, ", cpu_index);
 g_string_append(cpu->last_exec, (char *)udata);
+cpu->log = dmatches ? false : true;
 }
 
 /* Log last instruction while checking registers, ignore next */
@@ -157,7 +167,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void 
*udata)
 CPU *cpu = get_cpu(cpu_index);
 
 /* Print previous instruction in cache */
-if (cpu->last_exec->len) {
+if (cpu->log && cpu->last_exec->len) {
 qemu_plugin_outs(cpu->last_exec->str);
 qemu_plugin_outs("\n");
 }
@@ -166,6 +176,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void 
*udata)
 /* vcpu_mem will add memory access information to last_exec */
 g_string_printf(cpu->last_exec, "%u, ", cpu_index);
 g_string_append(cpu->last_exec, (char *)udata);
+cpu->log = dmatches ? false : true;
 }
 
 /**
@@ -377,7 +388,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
 g_rw_lock_reader_lock(&expand_array_lock);
 for (i = 0; i < cpus->len; i++) {
 CPU *c = get_cpu(i);
-if (c->last_exec && c->last_exec->str) {
+if (c->log && c->last_exec && c->last_exec->str) {
 qemu_plugin_outs(c->last_exec->str);
 qemu_plugin_outs("\n");
 }
@@ -432,6 +443,13 @@ QEMU_PLUGIN_EXPORT int 
qemu_plugin_install(qemu_plugin_id_t id,
 qemu_plugin_error_print(err);
 return -1;
 }
+} else if (g_strcmp0(tokens[0], "dfilter") == 0) {
+Error *err = NULL;
+qemu_plugin_range_list_from_string(&dmatches, tokens[1], &err);
+if (err) {
+qemu_plugin_error_print(err);
+return -1;
+}
 } else if (g_strcmp0(tokens[0], "reg") == 0) {
 add_regpat(tokens[1]);
 } else if (g_strcmp0(tokens[0], "rdisas") == 0) {
-- 
2.43.2




[PATCH v3 08/12] qemu/range: add range_list_contains() function

2024-03-01 Thread Sven Schnelle
Add a small inline function to match an address against
a list of ranges.

Signed-off-by: Sven Schnelle 
---
 include/qemu/range.h | 12 
 util/log.c   | 10 +-
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/include/qemu/range.h b/include/qemu/range.h
index 4ff9799d89..7ef9b3d5fb 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -57,6 +57,18 @@ static inline bool range_contains(const Range *range, 
uint64_t val)
 return val >= range->lob && val <= range->upb;
 }
 
+static inline bool range_list_contains(GList *ranges, uint64_t val)
+{
+GList *p;
+
+for (p = g_list_first(ranges); p; p = g_list_next(p)) {
+if (range_contains(p->data, val)) {
+return true;
+}
+}
+return false;
+}
+
 /* Initialize @range to the empty range */
 static inline void range_make_empty(Range *range)
 {
diff --git a/util/log.c b/util/log.c
index 90897ef0f9..032110d700 100644
--- a/util/log.c
+++ b/util/log.c
@@ -368,18 +368,10 @@ bool qemu_set_log_filename_flags(const char *name, int 
flags, Error **errp)
  */
 bool qemu_log_in_addr_range(uint64_t addr)
 {
-GList *p;
-
 if (!debug_regions) {
 return true;
 }
-
-for (p = g_list_first(debug_regions); p; p = g_list_next(p)) {
-if (range_contains(p->data, addr)) {
-return true;
-}
-}
-return false;
+return range_list_contains(debug_regions, addr);
 }
 
 void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
-- 
2.43.2




[PATCH v3 04/12] util/range: add range_list_free()

2024-03-01 Thread Sven Schnelle
Introduce range_list_free(), which takes a GList of ranges
and frees the list and each range.

Signed-off-by: Sven Schnelle 
---
 include/qemu/range.h | 5 +
 util/range.c | 5 +
 2 files changed, 10 insertions(+)

diff --git a/include/qemu/range.h b/include/qemu/range.h
index 530b0c7db1..4ff9799d89 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -240,4 +240,9 @@ void range_inverse_array(GList *in_ranges,
 void range_list_from_string(GList **out_ranges, const char *filter_spec,
 Error **errp);
 
+/*
+ * Free a list of ranges.
+ */
+void range_list_free(GList *ranges);
+
 #endif
diff --git a/util/range.c b/util/range.c
index bd2d0961bd..7234ab7a53 100644
--- a/util/range.c
+++ b/util/range.c
@@ -197,3 +197,8 @@ out:
 g_free(range);
 g_strfreev(ranges);
 }
+
+void range_list_free(GList *ranges)
+{
+g_list_free_full(ranges, g_free);
+}
-- 
2.43.2




[PATCH v3 09/12] plugins: add API to print errors

2024-03-01 Thread Sven Schnelle
add qemu_plugin_error_print() which is a wrapper around
error_report_err(). This will be used by
qemu_plugin_parse_filter_ranges() to report parse failures.

Signed-off-by: Sven Schnelle 
---
 include/qemu/qemu-plugin.h   | 12 
 plugins/api.c|  7 +++
 plugins/qemu-plugins.symbols |  1 +
 3 files changed, 20 insertions(+)

diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 45e2ebc8f8..5839feea4d 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -752,5 +752,17 @@ QEMU_PLUGIN_API
 int qemu_plugin_read_register(struct qemu_plugin_register *handle,
   GByteArray *buf);
 
+typedef struct Error Error;
+
+/**
+ * qemu_plugin_error_print() - print and free error
+ *
+ * @err: a @Error handle
+ *
+ * This function shows and and frees the supplied error.
+ */
+
+QEMU_PLUGIN_API
+void qemu_plugin_error_print(Error *err);
 
 #endif /* QEMU_QEMU_PLUGIN_H */
diff --git a/plugins/api.c b/plugins/api.c
index 81f43c9ce8..8fd3a8964a 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -45,6 +45,7 @@
 #include "exec/ram_addr.h"
 #include "disas/disas.h"
 #include "plugin.h"
+#include "qapi/error.h"
 #ifndef CONFIG_USER_ONLY
 #include "qemu/plugin-memory.h"
 #include "hw/boards.h"
@@ -465,3 +466,9 @@ int qemu_plugin_read_register(struct qemu_plugin_register 
*reg, GByteArray *buf)
 
 return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg));
 }
+
+void qemu_plugin_error_print(Error *err)
+{
+error_report_err(err);
+}
+
diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
index 27fe97239b..b142d11e58 100644
--- a/plugins/qemu-plugins.symbols
+++ b/plugins/qemu-plugins.symbols
@@ -2,6 +2,7 @@
   qemu_plugin_bool_parse;
   qemu_plugin_end_code;
   qemu_plugin_entry_code;
+  qemu_plugin_error_print;
   qemu_plugin_get_hwaddr;
   qemu_plugin_get_registers;
   qemu_plugin_hwaddr_device_name;
-- 
2.43.2




[PATCH v3 10/12] plugins: add range list API

2024-03-01 Thread Sven Schnelle
Export range_list_from_string(), range_contains() and range_list_free()
to allow plugins to parse filter ranges and match them to avoid
reimplementing this functionality.

Signed-off-by: Sven Schnelle 
---
 include/qemu/qemu-plugin.h   | 41 
 plugins/api.c| 18 
 plugins/qemu-plugins.symbols |  3 +++
 3 files changed, 62 insertions(+)

diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 5839feea4d..4910a63d70 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -765,4 +765,45 @@ typedef struct Error Error;
 QEMU_PLUGIN_API
 void qemu_plugin_error_print(Error *err);
 
+typedef GList qemu_plugin_range_list;
+
+/**
+ * qemu_plugin_ranges_from_string() - parse a filter range string
+ *
+ * @out_ranges: a pointer to a @qemu_plugin_range_list pointer
+ * @filter_spec: input string
+ * @errp: @Error string on parse failure
+ *
+ * This function parses a filter specification string and stores the
+ * parsed adress ranges found in @out. On parse failure a @Error pointer
+ * is stored in @errp. The function accepts a comma-separated list
+ * of start and end addresses or single addresses.
+ */
+QEMU_PLUGIN_API
+void qemu_plugin_range_list_from_string(qemu_plugin_range_list **out_range,
+const char *filter_spec,
+Error **errp);
+
+/**
+ * qemu_plugin_range_list_contains() - match a value against a list
+ * of ranges
+ *
+ * @ranges: a pointer to a @qemu_plugin_range_list
+ * @val: the value to match
+ *
+ * This function matches @val against the adress range list in @ranges.
+ * On success, true is returned, otherwise false.
+ */
+QEMU_PLUGIN_API
+bool qemu_plugin_range_list_contains(qemu_plugin_range_list *ranges,
+ uint64_t val);
+
+/**
+ * qemu_plugin_range_list_free() - free a list of ranges
+ *
+ * @ranges: a pointer to the list to be freed
+ */
+QEMU_PLUGIN_API
+void qemu_plugin_range_list_free(qemu_plugin_range_list *ranges);
+
 #endif /* QEMU_QEMU_PLUGIN_H */
diff --git a/plugins/api.c b/plugins/api.c
index 8fd3a8964a..8dbd14c648 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -472,3 +472,21 @@ void qemu_plugin_error_print(Error *err)
 error_report_err(err);
 }
 
+void qemu_plugin_range_list_from_string(qemu_plugin_range_list **out,
+const char *filter_spec,
+Error **errp)
+{
+return range_list_from_string(out, filter_spec, errp);
+}
+
+bool qemu_plugin_range_list_contains(qemu_plugin_range_list *ranges,
+ uint64_t val)
+{
+return range_list_contains(ranges, val);
+}
+
+void qemu_plugin_range_list_free(qemu_plugin_range_list *ranges)
+{
+return range_list_free(ranges);
+}
+
diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
index b142d11e58..472b29fc5f 100644
--- a/plugins/qemu-plugins.symbols
+++ b/plugins/qemu-plugins.symbols
@@ -21,6 +21,9 @@
   qemu_plugin_num_vcpus;
   qemu_plugin_outs;
   qemu_plugin_path_to_binary;
+  qemu_plugin_range_list_contains;
+  qemu_plugin_range_list_free;
+  qemu_plugin_range_list_from_string;
   qemu_plugin_read_register;
   qemu_plugin_register_atexit_cb;
   qemu_plugin_register_flush_cb;
-- 
2.43.2




[PATCH v3 02/12] util/log: make qemu_set_dfilter_ranges() take a GList

2024-03-01 Thread Sven Schnelle
In preparation of making qemu_set_dfilter_ranges() available
to other users, move the code to a new function range_list_from_string()
which takes an additional GList argument.

Signed-off-by: Sven Schnelle 
---
 util/log.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/util/log.c b/util/log.c
index 779c0689a9..f183ea4e4d 100644
--- a/util/log.c
+++ b/util/log.c
@@ -382,15 +382,16 @@ bool qemu_log_in_addr_range(uint64_t addr)
 return false;
 }
 
-void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
+static void range_list_from_string(GList **out_ranges, const char *filter_spec,
+   Error **errp)
 {
 gchar **ranges = g_strsplit(filter_spec, ",", 0);
 struct Range *range = NULL;
 int i;
 
-if (debug_regions) {
-g_list_free_full(debug_regions, g_free);
-debug_regions = NULL;
+if (*out_ranges) {
+g_list_free_full(*out_ranges, g_free);
+*out_ranges = NULL;
 }
 
 for (i = 0; ranges[i]; i++) {
@@ -447,7 +448,7 @@ void qemu_set_dfilter_ranges(const char *filter_spec, Error 
**errp)
 goto out;
 }
 range_set_bounds(range, lob, upb);
-debug_regions = g_list_append(debug_regions, range);
+   *out_ranges = g_list_append(*out_ranges, range);
 range = NULL;
 }
 out:
@@ -455,6 +456,11 @@ out:
 g_strfreev(ranges);
 }
 
+void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
+{
+range_list_from_string(&debug_regions, filter_spec, errp);
+}
+
 const QEMULogItem qemu_log_items[] = {
 { CPU_LOG_TB_OUT_ASM, "out_asm",
   "show generated host assembly code for each compiled TB" },
-- 
2.43.2




[PATCH v3 06/12] util/range: split up range_list_from_string()

2024-03-01 Thread Sven Schnelle
Makes the code a bit easier to read and maintain.

Signed-off-by: Sven Schnelle 
---
 util/range.c | 119 ++-
 1 file changed, 70 insertions(+), 49 deletions(-)

diff --git a/util/range.c b/util/range.c
index db535de9a7..8c463995e7 100644
--- a/util/range.c
+++ b/util/range.c
@@ -124,6 +124,74 @@ exit:
 *rev = out;
 }
 
+static const char *split_single_range(const char *r, const char **r2)
+{
+char *range_op;
+
+range_op = strstr(r, "-");
+if (range_op) {
+*r2 = range_op + 1;
+return range_op;
+}
+range_op = strstr(r, "+");
+if (range_op) {
+*r2 = range_op + 1;
+return range_op;
+}
+range_op = strstr(r, "..");
+if (range_op) {
+*r2 = range_op + 2;
+return range_op;
+}
+return NULL;
+}
+
+static int parse_single_range(const char *r, Error **errp,
+  uint64_t *lob, uint64_t *upb)
+{
+const char *range_op, *r2, *e;
+uint64_t r1val, r2val;
+
+range_op = split_single_range(r, &r2);
+if (!range_op) {
+error_setg(errp, "Bad range specifier");
+return 1;
+}
+if (qemu_strtou64(r, &e, 0, &r1val)
+|| e != range_op) {
+error_setg(errp, "Invalid number to the left of %.*s",
+   (int)(r2 - range_op), range_op);
+return 1;
+}
+if (qemu_strtou64(r2, NULL, 0, &r2val)) {
+error_setg(errp, "Invalid number to the right of %.*s",
+   (int)(r2 - range_op), range_op);
+return 1;
+}
+
+switch (*range_op) {
+case '+':
+*lob = r1val;
+*upb = r1val + r2val - 1;
+break;
+case '-':
+*upb = r1val;
+*lob = r1val - (r2val - 1);
+break;
+case '.':
+*lob = r1val;
+*upb = r2val;
+break;
+default:
+g_assert_not_reached();
+}
+if (*lob > *upb) {
+error_setg(errp, "Invalid range");
+return 1;
+}
+return 0;
+}
+
 void range_list_from_string(GList **out_ranges, const char *filter_spec,
 Error **errp)
 {
@@ -136,60 +204,13 @@ void range_list_from_string(GList **out_ranges, const 
char *filter_spec,
 }
 
 for (i = 0; ranges[i]; i++) {
-const char *r = ranges[i];
-const char *range_op, *r2, *e;
-uint64_t r1val, r2val, lob, upb;
-
-range_op = strstr(r, "-");
-r2 = range_op ? range_op + 1 : NULL;
-if (!range_op) {
-range_op = strstr(r, "+");
-r2 = range_op ? range_op + 1 : NULL;
-}
-if (!range_op) {
-range_op = strstr(r, "..");
-r2 = range_op ? range_op + 2 : NULL;
-}
-if (!range_op) {
-error_setg(errp, "Bad range specifier");
-goto out;
-}
-
-if (qemu_strtou64(r, &e, 0, &r1val)
-|| e != range_op) {
-error_setg(errp, "Invalid number to the left of %.*s",
-   (int)(r2 - range_op), range_op);
-goto out;
-}
-if (qemu_strtou64(r2, NULL, 0, &r2val)) {
-error_setg(errp, "Invalid number to the right of %.*s",
-   (int)(r2 - range_op), range_op);
-goto out;
-}
+uint64_t lob, upb;
 
-switch (*range_op) {
-case '+':
-lob = r1val;
-upb = r1val + r2val - 1;
+if (parse_single_range(ranges[i], errp, &lob, &upb)) {
 break;
-case '-':
-upb = r1val;
-lob = r1val - (r2val - 1);
-break;
-case '.':
-lob = r1val;
-upb = r2val;
-break;
-default:
-g_assert_not_reached();
-}
-if (lob > upb) {
-error_setg(errp, "Invalid range");
-goto out;
 }
 *out_ranges = append_new_range(*out_ranges, lob, upb);
 }
-out:
 g_strfreev(ranges);
 }
 
-- 
2.43.2




[PATCH v3 11/12] plugins/execlog: use range list api

2024-03-01 Thread Sven Schnelle
Instead of doing its own implementation, use the new range
list API to parse and match address lists.

Signed-off-by: Sven Schnelle 
---
 contrib/plugins/execlog.c | 27 +--
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index a1dfd59ab7..c518797893 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -35,7 +35,7 @@ static GArray *cpus;
 static GRWLock expand_array_lock;
 
 static GPtrArray *imatches;
-static GArray *amatches;
+static GList *amatches;
 static GPtrArray *rmatches;
 static bool disas_assist;
 static GMutex add_reg_name_lock;
@@ -215,12 +215,8 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct 
qemu_plugin_tb *tb)
 }
 
 if (skip && amatches) {
-int j;
-for (j = 0; j < amatches->len && skip; j++) {
-uint64_t v = g_array_index(amatches, uint64_t, j);
-if (v == insn_vaddr) {
-skip = false;
-}
+if (qemu_plugin_range_list_contains(amatches, insn_vaddr)) {
+skip = false;
 }
 }
 
@@ -398,16 +394,6 @@ static void parse_insn_match(char *match)
 g_ptr_array_add(imatches, g_strdup(match));
 }
 
-static void parse_vaddr_match(char *match)
-{
-uint64_t v = g_ascii_strtoull(match, NULL, 16);
-
-if (!amatches) {
-amatches = g_array_new(false, true, sizeof(uint64_t));
-}
-g_array_append_val(amatches, v);
-}
-
 /*
  * We have to wait until vCPUs are started before we can check the
  * patterns find anything.
@@ -440,7 +426,12 @@ QEMU_PLUGIN_EXPORT int 
qemu_plugin_install(qemu_plugin_id_t id,
 if (g_strcmp0(tokens[0], "ifilter") == 0) {
 parse_insn_match(tokens[1]);
 } else if (g_strcmp0(tokens[0], "afilter") == 0) {
-parse_vaddr_match(tokens[1]);
+Error *err = NULL;
+qemu_plugin_range_list_from_string(&amatches, tokens[1], &err);
+if (err) {
+qemu_plugin_error_print(err);
+return -1;
+}
 } else if (g_strcmp0(tokens[0], "reg") == 0) {
 add_regpat(tokens[1]);
 } else if (g_strcmp0(tokens[0], "rdisas") == 0) {
-- 
2.43.2




[PATCH v3 03/12] util/range: move range_list_from_string() to range.c

2024-03-01 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 include/qemu/range.h |  7 
 util/log.c   | 74 --
 util/range.c | 76 
 3 files changed, 83 insertions(+), 74 deletions(-)

diff --git a/include/qemu/range.h b/include/qemu/range.h
index 205e1da76d..530b0c7db1 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -233,4 +233,11 @@ void range_inverse_array(GList *in_ranges,
  GList **out_ranges,
  uint64_t low, uint64_t high);
 
+/*
+ * Parse a comma separated list of address ranges into a @GArray
+ * of @Range entries. On error @errp is set.
+ */
+void range_list_from_string(GList **out_ranges, const char *filter_spec,
+Error **errp);
+
 #endif
diff --git a/util/log.c b/util/log.c
index f183ea4e4d..90897ef0f9 100644
--- a/util/log.c
+++ b/util/log.c
@@ -382,80 +382,6 @@ bool qemu_log_in_addr_range(uint64_t addr)
 return false;
 }
 
-static void range_list_from_string(GList **out_ranges, const char *filter_spec,
-   Error **errp)
-{
-gchar **ranges = g_strsplit(filter_spec, ",", 0);
-struct Range *range = NULL;
-int i;
-
-if (*out_ranges) {
-g_list_free_full(*out_ranges, g_free);
-*out_ranges = NULL;
-}
-
-for (i = 0; ranges[i]; i++) {
-const char *r = ranges[i];
-const char *range_op, *r2, *e;
-uint64_t r1val, r2val, lob, upb;
-range = g_new0(struct Range, 1);
-
-range_op = strstr(r, "-");
-r2 = range_op ? range_op + 1 : NULL;
-if (!range_op) {
-range_op = strstr(r, "+");
-r2 = range_op ? range_op + 1 : NULL;
-}
-if (!range_op) {
-range_op = strstr(r, "..");
-r2 = range_op ? range_op + 2 : NULL;
-}
-if (!range_op) {
-error_setg(errp, "Bad range specifier");
-goto out;
-}
-
-if (qemu_strtou64(r, &e, 0, &r1val)
-|| e != range_op) {
-error_setg(errp, "Invalid number to the left of %.*s",
-   (int)(r2 - range_op), range_op);
-goto out;
-}
-if (qemu_strtou64(r2, NULL, 0, &r2val)) {
-error_setg(errp, "Invalid number to the right of %.*s",
-   (int)(r2 - range_op), range_op);
-goto out;
-}
-
-switch (*range_op) {
-case '+':
-lob = r1val;
-upb = r1val + r2val - 1;
-break;
-case '-':
-upb = r1val;
-lob = r1val - (r2val - 1);
-break;
-case '.':
-lob = r1val;
-upb = r2val;
-break;
-default:
-g_assert_not_reached();
-}
-if (lob > upb) {
-error_setg(errp, "Invalid range");
-goto out;
-}
-range_set_bounds(range, lob, upb);
-   *out_ranges = g_list_append(*out_ranges, range);
-range = NULL;
-}
-out:
-g_free(range);
-g_strfreev(ranges);
-}
-
 void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
 {
 range_list_from_string(&debug_regions, filter_spec, errp);
diff --git a/util/range.c b/util/range.c
index f3f40098d5..bd2d0961bd 100644
--- a/util/range.c
+++ b/util/range.c
@@ -19,6 +19,8 @@
 
 #include "qemu/osdep.h"
 #include "qemu/range.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
 
 int range_compare(Range *a, Range *b)
 {
@@ -121,3 +123,77 @@ void range_inverse_array(GList *in, GList **rev,
 exit:
 *rev = out;
 }
+
+void range_list_from_string(GList **out_ranges, const char *filter_spec,
+Error **errp)
+{
+gchar **ranges = g_strsplit(filter_spec, ",", 0);
+struct Range *range = NULL;
+int i;
+
+if (*out_ranges) {
+g_list_free_full(*out_ranges, g_free);
+*out_ranges = NULL;
+}
+
+for (i = 0; ranges[i]; i++) {
+const char *r = ranges[i];
+const char *range_op, *r2, *e;
+uint64_t r1val, r2val, lob, upb;
+range = g_new0(struct Range, 1);
+
+range_op = strstr(r, "-");
+r2 = range_op ? range_op + 1 : NULL;
+if (!range_op) {
+range_op = strstr(r, "+");
+r2 = range_op ? range_op + 1 : NULL;
+}
+if (!range_op) {
+range_op = strstr(r, "..");
+r2 = range_op ? range_op + 2 : NULL;
+}
+if (!range_op) {
+error_setg(errp, "Bad range specifier");
+goto out;
+}
+
+if (qemu_strtou64(r, &e, 0, &r1val)
+|| e != range_op) {
+error_setg(errp, "

[PATCH RFC] hppa: assemble_16() in wide mode

2024-03-02 Thread Sven Schnelle
Hi Richard,

while looking into a HPPA tcg issue i noticed that the current
tcg code doesn't do the special wide mode handling described in the
Parisc 2.0 specification, Chapter E -> assemble_16(). In wide mode,
assemble_16() adds two more bits to the immediate value/displacement
of certain instruction like ldo(ldi), st[bhwd] and ld[bhwd] and some
others.

I wonder what the easiest way to implement this is - it has to be xor'd
and is dependend on the W bit, so i don't think it will be possible to
implement this with changing only insn.decode. I came up with the
attached patch, do you think there's a better way?

Thanks!
Sven




[PATCH] target/hppa: add assemble_16()

2024-03-02 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 target/hppa/insns.decode | 99 
 target/hppa/translate.c  | 22 +
 2 files changed, 72 insertions(+), 49 deletions(-)

diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index f5a3f02fd1..8f17e18cd0 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -62,7 +62,7 @@
 
 
 # All insns that need to form a virtual address should use this set.
-&ldst   t b x disp sp m scale size
+&ldst   t b x disp sp m scale size w16
 
 &rr_cf_dt r cf d
 &rrrt r1 r2
@@ -138,7 +138,7 @@ getshadowregs      1101 1110 1010 1101 0010
 
 
 @addrx  .. b:5 x:5 ..  m:1 .\
-&ldst disp=0 scale=0 t=0 sp=0 size=0
+&ldst disp=0 scale=0 t=0 sp=0 size=0 w16=0
 
 nop 01 - - -- 11001010 0 - # fdc, disp
 nop_addrx   01 . . -- 01001010 . -  @addrx # fdc, index
@@ -163,24 +163,24 @@ ixtlbt  01 r2:5 r1:5 000 data:1 10 0 
0# idtlbt
 
 # pdtlb, pitlb
 pxtlb   01 b:5 x:5 sp:2 01001000 m:1 - \
-&ldst disp=0 scale=0 size=0 t=0
+&ldst disp=0 scale=0 size=0 t=0 w16=0
 pxtlb   01 b:5 x:5 ...   0001000 m:1 - \
-&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x
+&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x w16=0
 
 # ... pa20 local
 pxtlb_l 01 b:5 x:5 sp:2 01011000 m:1 - \
-&ldst disp=0 scale=0 size=0 t=0
+&ldst disp=0 scale=0 size=0 t=0 w16=0
 pxtlb_l 01 b:5 x:5 ...   0011000 m:1 - \
-&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x
+&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x w16=0
 
 # pdtlbe, pitlbe
 pxtlbe  01 b:5 x:5 sp:2 01001001 m:1 - \
-&ldst disp=0 scale=0 size=0 t=0
+&ldst disp=0 scale=0 size=0 t=0 w16=0
 pxtlbe  01 b:5 x:5 ...   0001001 m:1 - \
-&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x
+&ldst disp=0 scale=0 size=0 t=0 sp=%assemble_sr3x w16=0
 
 lpa 01 b:5 x:5 sp:2 01001101 m:1 t:5\
-&ldst disp=0 scale=0 size=0
+&ldst disp=0 scale=0 size=0 w16=0
 
 lci 01 - - -- 01001100 0 t:5
 
@@ -221,7 +221,7 @@ sub_b_tsv   10 . .  110100 . .  
@rrr_cf_d
 
 ldil001000 t:5 .i=%assemble_21
 addil   001010 r:5 .i=%assemble_21
-ldo 001101 b:5 t:5 -- ..i=%lowsign_14
+ldo 001101 b:5 t:5 s:2 ..i=%lowsign_14 w16=1
 
 addi101101 . .  0 ...   @rri_cf
 addi_tsv101101 . .  1 ...   @rri_cf
@@ -264,19 +264,19 @@ permh   10 r1:5  r2:5  0 c0:2 0 c1:2 c2:2 
c3:2 0 t:5
 @stim5  .. b:5 t:5 sp:2 . . \
 &ldst disp=%im5_0 x=0 scale=0 m=%ma_to_m
 
-ld  11 . . .. . 1 -- 00 size:2 ..   @ldim5
-ld  11 . . .. . 0 -- 00 size:2 ..   @ldstx
-st  11 . . .. . 1 -- 10 size:2 ..   @stim5
-ldc 11 . . .. . 1 -- 0111  ..   @ldim5 size=2
-ldc 11 . . .. . 0 -- 0111  ..   @ldstx size=2
-ldc 11 . . .. . 1 -- 0101  ..   @ldim5 size=3
-ldc 11 . . .. . 0 -- 0101  ..   @ldstx size=3
-lda 11 . . .. . 1 -- 0110  ..   @ldim5 size=2
-lda 11 . . .. . 0 -- 0110  ..   @ldstx size=2
-lda 11 . . .. . 1 -- 0100  ..   @ldim5 size=3
-lda 11 . . .. . 0 -- 0100  ..   @ldstx size=3
-sta 11 . . .. . 1 -- 1110  ..   @stim5 size=2
-sta 11 . . .. . 1 --   ..   @stim5 size=3
+ld  11 . . .. . 1 -- 00 size:2 ..   @ldim5 w16=0
+ld  11 . . .. . 0 -- 00 size:2 ..   @ldstx w16=0
+st  11 . . .. . 1 -- 10 size:2 ..   @stim5 w16=0
+ldc 11 . . .. . 1 -- 0111  ..   @ldim5 size=2 
w16=0
+ldc 11 . . .. . 0 -- 0111  ..   @ldstx size=2 
w16=0
+ldc 11 . . .. . 1 -- 0101  ..   @ldim5 size=3 
w16=0
+ldc 11 . . .. . 0 -- 0101  ..   @ldstx size=3 
w16=0
+lda 11 . . .. . 1 -- 0110  ..   @ldim5 size=2 
w16=0
+lda 11 . . .. . 0 -- 0110  

[PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch

2024-03-02 Thread Sven Schnelle
Netbsd isn't happy with qemu lsi53c895a emulation:

cd0(esiop0:0:2:0): command with tag id 0 reset
esiop0: autoconfiguration error: phase mismatch without command
esiop0: autoconfiguration error: unhandled scsi interrupt, sist=0x80 sstat1=0x0 
DSA=0x23a64b1 DSP=0x50

This is because lsi_bad_phase() triggers a phase mismatch, which
stops SCRIPT processing. However, after returning to
lsi_command_complete(), SCRIPT is restarted with lsi_resume_script().
Fix this by adding a return value to lsi_bad_phase(), and only resume
script processing when lsi_bad_phase() didn't trigger a host interrupt.

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 4ff9470381..59b88aff3f 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -573,8 +573,9 @@ static inline void lsi_set_phase(LSIState *s, int phase)
 s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
 }
 
-static void lsi_bad_phase(LSIState *s, int out, int new_phase)
+static int lsi_bad_phase(LSIState *s, int out, int new_phase)
 {
+int ret = 0;
 /* Trigger a phase mismatch.  */
 if (s->ccntl0 & LSI_CCNTL0_ENPMJ) {
 if ((s->ccntl0 & LSI_CCNTL0_PMJCTL)) {
@@ -587,8 +588,10 @@ static void lsi_bad_phase(LSIState *s, int out, int 
new_phase)
 trace_lsi_bad_phase_interrupt();
 lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
 lsi_stop_script(s);
+ret = 1;
 }
 lsi_set_phase(s, new_phase);
+return ret;
 }
 
 
@@ -792,7 +795,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, 
uint32_t len)
 static void lsi_command_complete(SCSIRequest *req, size_t resid)
 {
 LSIState *s = LSI53C895A(req->bus->qbus.parent);
-int out;
+int out, stop = 0;
 
 out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
 trace_lsi_command_complete(req->status);
@@ -800,7 +803,10 @@ static void lsi_command_complete(SCSIRequest *req, size_t 
resid)
 s->command_complete = 2;
 if (s->waiting && s->dbc != 0) {
 /* Raise phase mismatch for short transfers.  */
-lsi_bad_phase(s, out, PHASE_ST);
+stop = lsi_bad_phase(s, out, PHASE_ST);
+if (stop) {
+s->waiting = 0;
+}
 } else {
 lsi_set_phase(s, PHASE_ST);
 }
@@ -810,7 +816,9 @@ static void lsi_command_complete(SCSIRequest *req, size_t 
resid)
 lsi_request_free(s, s->current);
 scsi_req_unref(req);
 }
-lsi_resume_script(s);
+if (!stop) {
+lsi_resume_script(s);
+}
 }
 
  /* Callback to indicate that the SCSI layer has completed a transfer.  */
-- 
2.43.2




Re: lsi53c895a assert with AmigaOS

2024-03-02 Thread Sven Schnelle
BALATON Zoltan  writes:

> AmigaOS4 also has a driver for this card so I've tried to test it but
> it trips an assert. Does anybody have an idea why and how it could be
> fixed? Sven's recent patches don't seem to have an effect on this, it
> still happens shortly after it tries to access the SCSI device with
> those patches applied. (Unfortunately AmigaOS is not freely available
> so it's a bit hard to reproduce but I can do tests if needed.) I got
> the following traces:
> [..]
> lsi_do_command Send command len=6
> qemu-system-ppc: ../hw/scsi/lsi53c895a.c:863: lsi_do_command: Assertion 
> `s->current == NULL' failed.
>
> Any idea what could it be and what could be done about it?

I think the Host is resetting the SCSI controller while it still has
some request pending. I made a hack to work around that bug, but so
far i haven't spent the time to verify whether it's correct or whether
there are additional changes required. Here it is:

>From 6a807653679fde5e3e09a7f27576c673f335fef6 Mon Sep 17 00:00:00 2001
From: Sven Schnelle 
Date: Sat, 3 Feb 2024 19:46:07 +0100
Subject: [PATCH] lsi53c895a: free pending requests on reset

Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d607a5f9fb..c6bd801a7e 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -346,6 +346,8 @@ static lsi_request *get_pending_req(LSIState *s)
 
 static void lsi_soft_reset(LSIState *s)
 {
+lsi_request *p, *p_next;
+
 trace_lsi_reset();
 s->carry = 0;
 
@@ -413,8 +415,14 @@ static void lsi_soft_reset(LSIState *s)
 s->sbc = 0;
 s->csbc = 0;
 s->sbr = 0;
-assert(QTAILQ_EMPTY(&s->queue));
-assert(!s->current);
+
+QTAILQ_FOREACH_SAFE(p, &s->queue, next, p_next) {
+scsi_req_cancel(p->req);
+}
+
+if (s->current)
+scsi_req_cancel(s->current->req);
+s->current = NULL;
 }
 
 static int lsi_dma_40bit(LSIState *s)
@@ -860,7 +868,9 @@ static void lsi_do_command(LSIState *s)
 return;
 }
 
-assert(s->current == NULL);
+if (s->current)
+scsi_req_cancel(s->current->req);
+
 s->current = g_new0(lsi_request, 1);
 s->current->tag = s->select_tag;
 s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun, buf,
-- 
2.43.2




Re: lsi53c895a assert with AmigaOS

2024-03-03 Thread Sven Schnelle
BALATON Zoltan  writes:

> Hello,
>
> AmigaOS4 also has a driver for this card so I've tried to test it but
> it trips an assert. Does anybody have an idea why and how it could be
> fixed? Sven's recent patches don't seem to have an effect on this, it
> still happens shortly after it tries to access the SCSI device with
> those patches applied. (Unfortunately AmigaOS is not freely available
> so it's a bit hard to reproduce but I can do tests if needed.) I got
> the following traces:
>
> lsi_reg_write Write reg SIEN0 0x40 = 0x84
> lsi_reg_write Write reg SIEN1 0x41 = 0x04
> lsi_reg_write Write reg DIEN 0x39 = 0xff
> lsi_reg_write Write reg DSP0 0x2c = 0x00
> lsi_reg_write Write reg DSP1 0x2d = 0x80
> lsi_reg_write Write reg DSP2 0x2e = 0x19
> lsi_reg_write Write reg DSP3 0x2f = 0x00
> lsi_execute_script SCRIPTS dsp=0x198000 opcode 0x7c07fe00 arg 0x0
> lsi_execute_script_io_opcode Read-Modify-Write reg 0x7 AND data8=0xfe 
> sfbr=0x01
> lsi_reg_read Read reg GPREG 0x7 = 0x7f
> lsi_reg_write Write reg GPREG 0x7 = 0x7e
> lsi_execute_script SCRIPTS dsp=0x198008 opcode 0x6200 arg 0x0
> lsi_execute_script_io_clear Clear TM
> lsi_execute_script SCRIPTS dsp=0x198010 opcode 0x4000 arg 0x198208
> lsi_execute_script_io_alreadyreselected Already reselected, jumping to
> alternative address
here ---^
> lsi_do_msgout_select Select LUN 0
> lsi_execute_script SCRIPTS dsp=0x198070 opcode 0x820b arg 0x1981f8
> lsi_execute_script_tc_compp Compare phase CMD == CMD
> lsi_execute_script_tc_jump Jump to 0x1981f8
> lsi_execute_script SCRIPTS dsp=0x1981f8 opcode 0xa06 arg 0x199000
> lsi_do_command Send command len=6
> qemu-system-ppc: ../hw/scsi/lsi53c895a.c:863: lsi_do_command: Assertion 
> `s->current == NULL' failed.
>
> Any idea what could it be and what could be done about it?

Wild guess is that this is because of the 'Already reselected' line
above. lsi_reselect() sets s->current, and later when lsi_do_command()
is called it gets confused because s->current is already set. But i
would need the whole logfile to see why this is going wrong, or even
better AmigaOS (which is not free as you already mentioned)

Sven



Re: [PATCH v3 01/12] util/log: convert debug_regions to GList

2024-03-04 Thread Sven Schnelle
Alex Bennée  writes:

> Sven Schnelle  writes:
>
>> In preparation of making the parsing part of qemu_set_dfilter_ranges()
>> available to other users, convert it to return a GList, so the result
>> can be used with other functions taking a GList of struct Range.
>
> Why do we need to convert it to a Glist? When I originally wrote the
> dfilter code I deliberately chose GArray over GList to avoid bouncing
> across cache lines during the tight loop that is checking ranges. It's
> not like we can't pass GArray's to plugins as well?

Good point. I'll change it back to a GArray in the next iteration.



Re: [PATCH v2] hw/scsi/lsi53c895a: add timer to scripts processing

2024-03-04 Thread Sven Schnelle
Peter Maydell  writes:

> On Thu, 29 Feb 2024 at 20:44, Sven Schnelle  wrote:
>>
>> HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
>> under certain circumstances. As the SCSI controller and CPU are not
>> running at the same time this loop will never finish. After some
>> time, the check loop interrupts with a unexpected device disconnect.
>> This works, but is slow because the kernel resets the scsi controller.
>> Instead of signaling UDC, start a timer and exit the loop. Until the
>> timer fires, the CPU can process instructions which might changes the
>> memory location.
>>
>> The limit of instructions is also reduced because scripts running on
>> the SCSI processor are usually very short. This keeps the time until
>> the loop is exit short.
>
> "exited"
>
>>
>> Suggested-by: Peter Maydell 
>> Signed-off-by: Sven Schnelle 
>> ---
>> Changes in v2:
>> - update comment in lsi_execute_script()
>> - reset waiting state and del timer in lsi_execute_script() to
>>   handle the case where script processing is triggered via
>>   register write, and not from the pending timer
>> - delete timer in lsi_scsi_exit()
>
> Other than the s/host/guest/ comment fix,
> Reviewed-by: Peter Maydell 
>
> I don't suppose anybody has a setup with the Windows drivers
> to test this on? (commit ee4d919f30f13 suggests that at least
> Windows XP and 2003 had this problem.)

I have a Windows XP VM with lsi53c895a. I just fired it up and added
a qemu_log() in the timer path, and seen it trigger once while copying
a few files. It looks like Windows XP (or better the SCSI driver) also
works with this patch.



[PATCH v3] hw/scsi/lsi53c895a: add timer to scripts processing

2024-03-04 Thread Sven Schnelle
HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location
under certain circumstances. As the SCSI controller and CPU are not
running at the same time this loop will never finish. After some
time, the check loop interrupts with a unexpected device disconnect.
This works, but is slow because the kernel resets the scsi controller.
Instead of signaling UDC, start a timer and exit the loop. Until the
timer fires, the CPU can process instructions which might change the
memory location.

The limit of instructions is also reduced because scripts running on
the SCSI processor are usually very short. This keeps the time until
the loop is exited short.

Suggested-by: Peter Maydell 
Signed-off-by: Sven Schnelle 
Reviewed-by: Peter Maydell 
---
 hw/scsi/lsi53c895a.c | 43 +--
 hw/scsi/trace-events |  2 ++
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 949b2bbd10..3b5e76bbd9 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -188,7 +188,7 @@ static const char *names[] = {
 #define LSI_TAG_VALID (1 << 16)
 
 /* Maximum instructions to process. */
-#define LSI_MAX_INSN1
+#define LSI_MAX_INSN100
 
 typedef struct lsi_request {
 SCSIRequest *req;
@@ -205,6 +205,7 @@ enum {
 LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
 LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
 LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
+LSI_WAIT_SCRIPTS, /* SCRIPTS stopped because of instruction count limit */
 };
 
 enum {
@@ -224,6 +225,7 @@ struct LSIState {
 MemoryRegion ram_io;
 MemoryRegion io_io;
 AddressSpace pci_io_as;
+QEMUTimer *scripts_timer;
 
 int carry; /* ??? Should this be an a visible register somewhere?  */
 int status;
@@ -415,6 +417,7 @@ static void lsi_soft_reset(LSIState *s)
 s->sbr = 0;
 assert(QTAILQ_EMPTY(&s->queue));
 assert(!s->current);
+timer_del(s->scripts_timer);
 }
 
 static int lsi_dma_40bit(LSIState *s)
@@ -1135,6 +1138,12 @@ static void lsi_wait_reselect(LSIState *s)
 }
 }
 
+static void lsi_scripts_timer_start(LSIState *s)
+{
+trace_lsi_scripts_timer_start();
+timer_mod(s->scripts_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);
+}
+
 static void lsi_execute_script(LSIState *s)
 {
 PCIDevice *pci_dev = PCI_DEVICE(s);
@@ -1144,6 +1153,11 @@ static void lsi_execute_script(LSIState *s)
 int insn_processed = 0;
 static int reentrancy_level;
 
+if (s->waiting == LSI_WAIT_SCRIPTS) {
+timer_del(s->scripts_timer);
+s->waiting = LSI_NOWAIT;
+}
+
 reentrancy_level++;
 
 s->istat1 |= LSI_ISTAT1_SRUN;
@@ -1151,8 +1165,8 @@ again:
 /*
  * Some windows drivers make the device spin waiting for a memory location
  * to change. If we have executed more than LSI_MAX_INSN instructions then
- * assume this is the case and force an unexpected device disconnect. This
- * is apparently sufficient to beat the drivers into submission.
+ * assume this is the case and start a timer. Until the timer fires, the
+ * guest CPU has a chance to run and change the memory location.
  *
  * Another issue (CVE-2023-0330) can occur if the script is programmed to
  * trigger itself again and again. Avoid this problem by stopping after
@@ -1160,13 +1174,8 @@ again:
  * which should be enough for all valid use cases).
  */
 if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
-if (!(s->sien0 & LSI_SIST0_UDC)) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "lsi_scsi: inf. loop with UDC masked");
-}
-lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
-lsi_disconnect(s);
-trace_lsi_execute_script_stop();
+s->waiting = LSI_WAIT_SCRIPTS;
+lsi_scripts_timer_start(s);
 reentrancy_level--;
 return;
 }
@@ -2205,6 +2214,9 @@ static int lsi_post_load(void *opaque, int version_id)
 return -EINVAL;
 }
 
+if (s->waiting == LSI_WAIT_SCRIPTS) {
+lsi_scripts_timer_start(s);
+}
 return 0;
 }
 
@@ -2302,6 +2314,15 @@ static const struct SCSIBusInfo lsi_scsi_info = {
 .cancel = lsi_request_cancelled
 };
 
+static void scripts_timer_cb(void *opaque)
+{
+LSIState *s = opaque;
+
+trace_lsi_scripts_timer_triggered();
+s->waiting = LSI_NOWAIT;
+lsi_execute_script(s);
+}
+
 static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
 {
 LSIState *s = LSI53C895A(dev);
@@ -2321,6 +2342,7 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp)
   "lsi-ram", 0x2000);
 memory_region_init_io(&s->io_io, OBJECT(s), &lsi_io_ops, s,
   "lsi-io", 256);
+s->scripts_timer = timer_new_us(QEMU_CLOCK_VIRT

Re: [PATCH v3 01/12] util/log: convert debug_regions to GList

2024-03-04 Thread Sven Schnelle
Alex Bennée  writes:

> Sven Schnelle  writes:
>
>> In preparation of making the parsing part of qemu_set_dfilter_ranges()
>> available to other users, convert it to return a GList, so the result
>> can be used with other functions taking a GList of struct Range.
>
> Why do we need to convert it to a Glist? When I originally wrote the
> dfilter code I deliberately chose GArray over GList to avoid bouncing
> across cache lines during the tight loop that is checking ranges. It's
> not like we can't pass GArray's to plugins as well?

Looking at the code again, i remember that the reason for choosing GList
was that the other range matching function all take GList's - having
some functions take GArray's, and some not would be odd. So i wonder
whether we should convert all of those functions to GArray? (if
possible, i haven't checked)

What do you think?



Re: [PATCH v3 01/12] util/log: convert debug_regions to GList

2024-03-04 Thread Sven Schnelle
Alex Bennée  writes:

>> So i wonder
>> whether we should convert all of those functions to GArray? (if
>> possible, i haven't checked)
>
> I think that would depend on access patterns and flexibility. For the
> dfilter there is no particular need for sorting and the principle
> operation is a sequence of lookups. For the other use cases keeping a
> sorted list and quick insertion might be more useful.
>
> While its tempting to go on a wider re-factoring I would caution against
> it so close to softfreeze.
>
>> What do you think?
>
> Lets stick to the dfilter case and worry about wider clean-ups later. As
> Richard points out it might be the interval tree makes more sense for
> some of these things.

I think i go with the GArray variant for now. I'd guess that -dfilter is
usually only used with one or a few arguments, so using a Interval Tree
is probably not neccessary.



[PATCH] hw/scsi/lsi53c895a: add missing decrement of reentrancy counter

2024-01-28 Thread Sven Schnelle
When the maximum count of SCRIPTS instructions is reached, the code
stops execution and returns, but fails to decrement the reentrancy
counter. This effectively renders the SCSI controller unusable
because on next entry the reentrancy counter is still above the limit.

This bug was seen on HP-UX 10.20 which seems to trigger SCRIPTS
loops.

Fixes: b987718bbb ("hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI 
controller (CVE-2023-0330)")
Signed-off-by: Sven Schnelle 
---
 hw/scsi/lsi53c895a.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 34e3b89287..d607a5f9fb 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -1159,6 +1159,7 @@ again:
 lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
 lsi_disconnect(s);
 trace_lsi_execute_script_stop();
+reentrancy_level--;
 return;
 }
 insn = read_dword(s, s->dsp);
-- 
2.43.0




Re: [PATCH] hw/scsi/lsi53c895a: add missing decrement of reentrancy counter

2024-01-28 Thread Sven Schnelle
Thomas Huth  writes:

> On 28/01/2024 21.22, Sven Schnelle wrote:
>> When the maximum count of SCRIPTS instructions is reached, the code
>> stops execution and returns, but fails to decrement the reentrancy
>> counter. This effectively renders the SCSI controller unusable
>> because on next entry the reentrancy counter is still above the limit.
>> This bug was seen on HP-UX 10.20 which seems to trigger SCRIPTS
>> loops.
>
> Out of curiosity: What happened there before we introduced the
> reentrancy_level fix? Did it end up in an endless loop, or was it
> finishing at one point? In the latter case, we might need to adjust
> the "reentrancy_level > 8" to allow deeper nesting.

Without the reentrancy counter it was triggering the insn_processed
limit. The HP-UX scsi driver seems to spin on some memory value during
some SCSI writes (CDB with command 0x2a). So it is spinning in an
endless loop until the insn_processed counter will trigger the exit.
In HP-UX you will see a SCSI command timeout error in the kernel log
- at least i'm assuming that's related, but can't say for sure as
there's no kernel source available.



[PATCH] hw/net/tulip: add chip status register values

2024-02-05 Thread Sven Schnelle
Netbsd isn't able to detect a link on the emulated tulip card. That's
because netbsd reads the Chip Status Register of the Phy (address
0x14). The default phy data in the qemu tulip driver is all zero,
which means no link is established and autonegotation isn't complete.

Therefore set the register to 0x3b40, which means:

Link is up, Autonegotation complete, Full Duplex, 100MBit/s Link
speed.

Also clear the mask because this register is read only.

Signed-off-by: Sven Schnelle 
---
 hw/net/tulip.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index 6d4fb06dad..1f2ef20977 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -421,7 +421,7 @@ static uint16_t tulip_mdi_default[] = {
 /* MDI Registers 8 - 15 */
 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 /* MDI Registers 16 - 31 */
-0x0003, 0x, 0x0001, 0x, 0x, 0x, 0x, 0x,
+0x0003, 0x, 0x0001, 0x, 0x3b40, 0x, 0x, 0x,
 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 };
 
@@ -429,7 +429,7 @@ static uint16_t tulip_mdi_default[] = {
 static const uint16_t tulip_mdi_mask[] = {
 0x, 0x, 0x, 0x, 0xc01f, 0x, 0x, 0x,
 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
-0x0fff, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
+0x0fff, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 };
 
-- 
2.43.0




Re: [PULL 0/9] target/hppa fixes for 9.0

2024-03-21 Thread Sven Schnelle
Michael Tokarev  writes:

> 20.03.2024 03:32, Richard Henderson :
>
>> Richard Henderson (3):
>>target/hppa: Fix assemble_16 insns for wide mode
>>target/hppa: Fix assemble_11a insns for wide mode
>>target/hppa: Fix assemble_12a insns for wide mode
>> Sven Schnelle (6):
>>target/hppa: ldcw,s uses static shift of 3
>>target/hppa: fix shrp for wide mode
>>target/hppa: fix access_id check
>>target/hppa: exit tb on flush cache instructions
>>target/hppa: mask privilege bits in mfia
>>target/hppa: fix do_stdby_e()
>
> Is it all -stable material (when appropriate)?

I'd say yes.



[PATCH 2/3] target/hppa: sub: fix trap on overflow for narrow mode

2024-03-21 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index f493e207e1..4d2b96f876 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1213,6 +1213,9 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
TCGv_i64 in1,
 if (is_tsv || cond_need_sv(c)) {
 sv = do_sub_sv(ctx, dest, in1, in2);
 if (is_tsv) {
+if (!d) {
+tcg_gen_ext32s_i64(sv, sv);
+}
 gen_helper_tsv(tcg_env, sv);
 }
 }
-- 
2.43.2




[PATCH 1/3] target/hppa: add unit conditions for wide mode

2024-03-21 Thread Sven Schnelle
Wide mode provides two more conditions, add them.

Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 25 +++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 8a87996fc1..f493e207e1 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -963,11 +963,22 @@ static DisasCond do_unit_cond(unsigned cf, bool d, 
TCGv_i64 res,
 
 switch (cf >> 1) {
 case 0: /* never / TR */
-case 1: /* undefined */
-case 5: /* undefined */
 cond = cond_make_f();
 break;
 
+case 1:
+if (d) {
+tmp = tcg_temp_new_i64();
+tcg_gen_subi_i64(tmp, res, d_repl * 0x0001u);
+tcg_gen_andc_i64(tmp, tmp, res);
+tcg_gen_andi_i64(tmp, tmp, d_repl * 0x8000u);
+cond = cond_make_0(TCG_COND_NE, tmp);
+} else {
+/* undefined */
+cond = cond_make_f();
+}
+break;
+
 case 2: /* SBZ / NBZ */
 /* See hasless(v,1) from
  * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
@@ -992,6 +1003,16 @@ static DisasCond do_unit_cond(unsigned cf, bool d, 
TCGv_i64 res,
 cond = cond_make_0(TCG_COND_NE, cb);
 break;
 
+case 5:
+if (d) {
+tcg_gen_andi_i64(cb, cb, d_repl * 0x8000u);
+cond = cond_make_0(TCG_COND_NE, cb);
+} else {
+/* undefined */
+cond = cond_make_f();
+}
+break;
+
 case 6: /* SBC / NBC */
 tcg_gen_andi_i64(cb, cb, d_repl * 0x80808080u);
 cond = cond_make_0(TCG_COND_NE, cb);
-- 
2.43.2




[PATCH 3/3] target/hppa: add: fix trap on overflow for narrow mode

2024-03-21 Thread Sven Schnelle
Signed-off-by: Sven Schnelle 
---
 target/hppa/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 4d2b96f876..74a9ea0cd8 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1122,6 +1122,9 @@ static void do_add(DisasContext *ctx, unsigned rt, 
TCGv_i64 in1,
 if (is_tsv || cond_need_sv(c)) {
 sv = do_add_sv(ctx, dest, in1, in2);
 if (is_tsv) {
+if (!d) {
+tcg_gen_ext32s_i64(sv, sv);
+}
 /* ??? Need to include overflow from shift.  */
 gen_helper_tsv(tcg_env, sv);
 }
-- 
2.43.2




Re: [PATCH 2/3] target/hppa: sub: fix trap on overflow for narrow mode

2024-03-21 Thread Sven Schnelle
Richard Henderson  writes:

> On 3/21/24 08:42, Sven Schnelle wrote:
>> Signed-off-by: Sven Schnelle 
>> ---
>>   target/hppa/translate.c | 3 +++
>>   1 file changed, 3 insertions(+)
>> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
>> index f493e207e1..4d2b96f876 100644
>> --- a/target/hppa/translate.c
>> +++ b/target/hppa/translate.c
>> @@ -1213,6 +1213,9 @@ static void do_sub(DisasContext *ctx, unsigned rt, 
>> TCGv_i64 in1,
>>   if (is_tsv || cond_need_sv(c)) {
>>   sv = do_sub_sv(ctx, dest, in1, in2);
>>   if (is_tsv) {
>> +if (!d) {
>> +tcg_gen_ext32s_i64(sv, sv);
>> +}
>>   gen_helper_tsv(tcg_env, sv);
>>   }
>>   }
>
> Difficult to pinpoint exactly which patch should have added this.  :-)

Yes, after missing the Fixes: tags on all of my patches in the last
patchset, i tried add one but wasn't sure either. :-)

> Reviewed-by: Richard Henderson 

Thanks!



Re: [PATCH 1/3] target/hppa: add unit conditions for wide mode

2024-03-21 Thread Sven Schnelle
Richard Henderson  writes:

> On 3/21/24 08:42, Sven Schnelle wrote:
>> Wide mode provides two more conditions, add them.
>> Signed-off-by: Sven Schnelle 
>> ---
>>   target/hppa/translate.c | 25 +++--
>>   1 file changed, 23 insertions(+), 2 deletions(-)
>> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
>> index 8a87996fc1..f493e207e1 100644
>> --- a/target/hppa/translate.c
>> +++ b/target/hppa/translate.c
>> @@ -963,11 +963,22 @@ static DisasCond do_unit_cond(unsigned cf, bool d, 
>> TCGv_i64 res,
>> switch (cf >> 1) {
>>   case 0: /* never / TR */
>> -case 1: /* undefined */
>> -case 5: /* undefined */
>>   cond = cond_make_f();
>>   break;
>>   +case 1:
>
> Wants a comment for /* SWZ / NWZ */
>
>> +case 5:
>
> /* SWC / NWC */

Are you going to fix that up, or should i send a v2?



[PATCH 1/3] target/hppa: use gva_offset_mask() everywhere

2024-03-24 Thread Sven Schnelle
move it to cpu.h, so it can also be used in hppa_form_gva_psw()

Signed-off-by: Sven Schnelle 
---
 target/hppa/cpu.h   | 10 --
 target/hppa/translate.c | 12 +++-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a92dc352cb..a072d0bb63 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -285,14 +285,20 @@ void hppa_translate_init(void);
 
 #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
 
+static inline uint64_t gva_offset_mask(target_ulong psw)
+{
+return (psw & PSW_W
+? MAKE_64BIT_MASK(0, 62)
+: MAKE_64BIT_MASK(0, 32));
+}
+
 static inline target_ulong hppa_form_gva_psw(target_ulong psw, uint64_t spc,
  target_ulong off)
 {
 #ifdef CONFIG_USER_ONLY
 return off;
 #else
-off &= psw & PSW_W ? MAKE_64BIT_MASK(0, 62) : MAKE_64BIT_MASK(0, 32);
-return spc | off;
+return spc | (off & gva_offset_mask(psw));
 #endif
 }
 
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 19594f917e..0af125ed74 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -586,17 +586,10 @@ static bool nullify_end(DisasContext *ctx)
 return true;
 }
 
-static uint64_t gva_offset_mask(DisasContext *ctx)
-{
-return (ctx->tb_flags & PSW_W
-? MAKE_64BIT_MASK(0, 62)
-: MAKE_64BIT_MASK(0, 32));
-}
-
 static void copy_iaoq_entry(DisasContext *ctx, TCGv_i64 dest,
 uint64_t ival, TCGv_i64 vval)
 {
-uint64_t mask = gva_offset_mask(ctx);
+uint64_t mask = gva_offset_mask(ctx->tb_flags);
 
 if (ival != -1) {
 tcg_gen_movi_i64(dest, ival & mask);
@@ -1403,7 +1396,8 @@ static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, 
TCGv_i64 *pofs,
 
 *pofs = ofs;
 *pgva = addr = tcg_temp_new_i64();
-tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base, gva_offset_mask(ctx));
+tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base,
+ gva_offset_mask(ctx->tb_flags));
 #ifndef CONFIG_USER_ONLY
 if (!is_phys) {
 tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base));
-- 
2.43.2




[PATCH 3/3] target/hppa: fix building gva for wide mode

2024-03-24 Thread Sven Schnelle
64 Bit hppa no longer has a fixed 32/32 bit split between space and
offset. Instead it uses 42 bits for the offset. The lower 10 bits of
the space are always zero, leaving 22 bits actually used. Simply or
the values together to build the gva.

Signed-off-by: Sven Schnelle 
---
 target/hppa/mem_helper.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 84785b5a5c..6f895fced7 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -523,13 +523,16 @@ void HELPER(itlbp_pa11)(CPUHPPAState *env, target_ulong 
addr, target_ulong reg)
 }
 
 static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
-   target_ulong r2, vaddr va_b)
+   target_ulong r2, uint64_t spc, uint64_t off)
 {
 HPPATLBEntry *ent;
-vaddr va_e;
+vaddr va_b, va_e;
 uint64_t va_size;
 int mask_shift;
 
+va_b = off & gva_offset_mask(env->psw);
+va_b |= spc << 32;
+
 mask_shift = 2 * (r1 & 0xf);
 va_size = (uint64_t)TARGET_PAGE_SIZE << mask_shift;
 va_b &= -va_size;
@@ -569,14 +572,12 @@ static void itlbt_pa20(CPUHPPAState *env, target_ulong r1,
 
 void HELPER(idtlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
 {
-vaddr va_b = deposit64(env->cr[CR_IOR], 32, 32, env->cr[CR_ISR]);
-itlbt_pa20(env, r1, r2, va_b);
+itlbt_pa20(env, r1, r2, env->cr[CR_ISR], env->cr[CR_IOR]);
 }
 
 void HELPER(iitlbt_pa20)(CPUHPPAState *env, target_ulong r1, target_ulong r2)
 {
-vaddr va_b = deposit64(env->cr[CR_IIAOQ], 32, 32, env->cr[CR_IIASQ]);
-itlbt_pa20(env, r1, r2, va_b);
+itlbt_pa20(env, r1, r2, env->cr[CR_IIASQ], env->cr[CR_IIAOQ]);
 }
 
 /* Purge (Insn/Data) TLB. */
-- 
2.43.2




[PATCH 0/3] few hppa fixes for 64bit mode

2024-03-24 Thread Sven Schnelle
Hi,

in preparation of getting 64bit HP-UX running in qemu, here are a few fixes
to make HP-UX progress a bit further.

Sven Schnelle (3):
  target/hppa: use gva_offset_mask() everywhere
  target/hppa: mask offset bits in gva
  target/hppa: fix building gva for wide mode

 target/hppa/cpu.h| 11 +--
 target/hppa/mem_helper.c | 13 +++--
 target/hppa/translate.c  | 12 +++-
 3 files changed, 19 insertions(+), 17 deletions(-)

-- 
2.43.2




[PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Sven Schnelle
The CPU seems to mask a few bits in the offset when running
under HP-UX. ISR/IOR register contents for an address in
the processor HPA (0xfffa) on my C8000 and J6750:

running on Linux: 3fff c000fffa0500
running on HP-UX: 301f c000fffa0500

I haven't found how this is switched (guess some diag in the
firmware), but linux + seabios seems to handle that as well,
so lets mask out the additional bits.

Signed-off-by: Sven Schnelle 
---
 target/hppa/cpu.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index a072d0bb63..9bc4d208fa 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -283,12 +283,13 @@ static inline int HPPA_BTLB_ENTRIES(CPUHPPAState *env)
 
 void hppa_translate_init(void);
 
+#define HPPA_GVA_OFFSET_MASK64 0x301f
 #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
 
 static inline uint64_t gva_offset_mask(target_ulong psw)
 {
 return (psw & PSW_W
-? MAKE_64BIT_MASK(0, 62)
+? HPPA_GVA_OFFSET_MASK64
 : MAKE_64BIT_MASK(0, 32));
 }
 
-- 
2.43.2




Re: [PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Sven Schnelle
Hi Richard,

Richard Henderson  writes:

> In particular Figure 2-14 for "data translation disabled" may be
> instructive.  Suppose the cpu does not implement all of the physical
> address lines (true for all extant pa-risc cpus; qemu implements 40
> bits to match pa-8500 iirc).  Suppose when reporting a trap with
> translation disabled, it is a truncated physical address that is used
> as input to Figure 2-14.
>
> If that is so, then the fix might be in hppa_set_ior_and_isr.  Perhaps
>
> -env->cr[CR_ISR] &= 0x3fff;
> +env->cr[CR_ISR] &= 0x301f;
>
> Though my argument would suggest the mask should be 0xff for the
> 40-bit physical address, which is not what you see at all, so perhaps
> the thing is moot.  I am at a loss to explain why or how HP-UX gets a
> 7-bit hole in the ISR result.
>
> On the other hand, there are some not-well-documented shenanigans (aka
> implementation defined behaviour) between Figure H-8 and Figure H-11,
> where the 62-bit absolute address is expanded to a 64-bit logical
> physical address and then compacted to a 40-bit implementation
> physical address.
>
> We've already got hacks in place for this in hppa_abs_to_phys_pa2_w1,
> which just truncates everything down to 40 bits.  But that's probably
> not what the processor is really doing.
>
> Anyhow, will you please try the hppa_set_ior_and_isr change and see if
> that fixes your HP-UX problems?

The problem occurs with data address translation - it's working without,
which is not suprising because no exception can happen there. But as
soon as the kernel enables address translation it will hit a data tlb
miss exception because it can't find 0xfffb0500 in the page
tables. Trying to truncate the ISR in hppa_set_ior_and_isr() for the
data translation enabled case leads to this loop:

hppa_tlb_fill_excp env=0x55bf06e976e0 addr=0x3ffb0500 size=4 type=0 
mmu_idx=9
hppa_tlb_find_entry env=0x55bf06e976e0 ent=0x55bf06e97b30 valid=1 va_b=0x20 
va_e=0x2f pa=0x20
hppa_tlb_get_physical_address env=0x55bf06e976e0 ret=-1 prot=5 addr=0x26170c 
phys=0x26170c
hppa_tlb_flush_ent env=0x55bf06e976e0 ent=0x55bf06e97bf0 
va_b=0x301b va_e=0x301b0fff pa=0xfffb
hppa_tlb_itlba env=0x55bf06e976e0 ent=0x55bf06e97bf0 va_b=0x301b 
va_e=0x301b0fff pa=0xfffb
hppa_tlb_itlbp env=0x55bf06e976e0 ent=0x55bf06e97bf0 access_id=0 u=1 pl2=0 
pl1=0 type=1 b=0 d=0 t=0

So qemu is looking up 0x3ffb0500 in the TLB, can't find it,
raises an exception, HP-UX says: "ah nice, i have a translation for
you", but that doesn't match because we're only stripping the bits
in the ISR.

As i was a bit puzzled in the beginning what's going on, i dumped the
pagetables and wrote a small dump program:

68: val=000f47ff301f r2=110e0f01 r1=01e8ffe0 
phys=f47ff000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
680020: val=000f47fe301f r2=110e0f01 r1=01e8ffc0 
phys=f47fe000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
680060: val=000f47fc301f r2=110e0f01 r1=01e8ff80 
phys=f47fc000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5860: val=000fed3c301f r2=010e0001 r1=01fda780 
phys=fed3c000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d58e0: val=000fed38301f r2=010e0001 r1=01fda700 
phys=fed38000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d59a0: val=000fed32301f r2=010e0001 r1=01fda640 
phys=fed32000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d59e0: val=000fed30301f r2=110e0f01 r1=01fda600 
phys=fed3 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a00: val=000fed2f301f r2=010e0001 r1=01fda5e0 
phys=fed2f000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a20: val=000fed2e301f r2=010e0001 r1=01fda5c0 
phys=fed2e000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a40: val=000fed2d301f r2=010e0001 r1=01fda5a0 
phys=fed2d000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a60: val=000fed2c301f r2=010e0001 r1=01fda580 
phys=fed2c000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5a80: val=000fed2b301f r2=010e0001 r1=01fda560 
phys=fed2b000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5aa0: val=000fed2a301f r2=010e0001 r1=01fda540 
phys=fed2a000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5ac0: val=000fed29301f r2=010e0001 r1=01fda520 
phys=fed29000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5ae0: val=000fed28301f r2=010e0001 r1=01fda500 
phys=fed28000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5b00: val=000fed27301f r2=010e0001 r1=01fda4e0 
phys=fed27000 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
7d5b20: val=000fed26301f r2=010e0001 r1=01fda4c0 
phys=fed26000 4K aid=1 pl1=0, pl2=0 type=1 (

Re: [PATCH 2/3] target/hppa: mask offset bits in gva

2024-03-24 Thread Sven Schnelle
Richard Henderson  writes:

> On 3/24/24 08:41, Sven Schnelle wrote:
>> 7f09e0: val=000fffb0301f r2=110e0f01 r1=01fff600 
>> phys=fffb 4K aid=1 pl1=0, pl2=0 type=1 (DATA RW)
>> 'val' is the value constructed from IOR/ISR,
>
> Is this byte swapped in some weird way?  I do not see how 'val'
> corresponds to any of the addresses we're talking about.  From here,
> the string "301f" appears to an out-of-context grep hit.

It's just both values combined together, where the 301f is basically
the ISR content. It's not a out of context grep - the real machines i have
are constructing the same value, and the same offset into the pagetable.
I verified that by patching the DTLB miss handler in HPUX to write the
ISR/IOR and calulated pagetable offset/value to PAGE0 and looked with
the kernel debugger at the values.



target/hppa: be,n nullifying first insn at branch target?

2024-03-25 Thread Sven Schnelle
Hi Richard,

one of the last issue i'm seeing with 64bit HP-UX 11.11 is a crash
of ld64 while building (linking) the kernel. The program is killed
due to a unaligned access. I've wrote a logfile, and it looks like
be,n is nullifying the first instruction at the branch target:

IN: 
0x9d4a416d4fc:  cmpiclr,<> c,r31,r0
0x9d4a416d500:  addi,tr 13,r0,ret1
0x9d4a416d504:  ldi 0,ret1
0x9d4a416d508:  ldi 0,ret0
0x9d4a416d50c:  ldsid (rp),r31
0x9d4a416d510:  mtsp r31,sr0
0x9d4a416d514:  be,n 0(sr0,rp)

Trace 0: 0x7efd7f9d75c0 [9d4a404/09d4a416d4fc/00040306/ff00] 
IA_F 09d4a416d4ff IA_B 09d4a416d503 IIR 4afc3ff9
PSW  00ff0004ff1f CB    -C---RQPDI
GR00  GR01 09d4a400 GR02 00107573 GR03 
003c79b8
GR04 00419f50 GR05 00410a30 GR06 7a0005c8 GR07 
00419f50
GR08 004122f8 GR09 000b GR10 001db1b8 GR11 
001c81f8
GR12 001c81f8 GR13 001c81f8 GR14  GR15 
001dbf18
GR16  GR17 0001 GR18 001d5278 GR19 
001c5000
GR20 00416a40 GR21 006a GR22 0016d4e8 GR23 
004a
GR24 029c GR25  GR26 00419f50 GR27 
001e65f8
GR28 0001 GR29 001db1b8 GR30 7a029510 GR31 
000c
SR00 09d4a400 SR01  SR02  SR03 
SR04 09d4a400 SR05 09d4a400 SR06 01eea400 SR07 01eea400


IN: 
0x9d4a4107570:  ldw 0(r4),r19
0x9d4a4107574:  ldw 58(r19),r22
0x9d4a4107578:  ldo 0(ret1),r7
0x9d4a410757c:  ldo 0(r4),r26
0x9d4a4107580:  b,l 0x9d4a41074d8,r31
0x9d4a4107584:  ldo 0(r31),rp

Trace 0: 0x7efd7f9d77c0 [9d4a404/09d4a4107570/00240306/ff00] 
IA_F 09d4a4107573 IA_B 09d4a4107577 IIR 4afc3ff9
PSW  0024001f CB    --N--C---RQPDI
GR00  GR01 09d4a400 GR02 00107573 GR03 
003c79b8
GR04 00419f50 GR05 00410a30 GR06 7a0005c8 GR07 
00419f50
GR08 004122f8 GR09 000b GR10 001db1b8 GR11 
001c81f8
GR12 001c81f8 GR13 001c81f8 GR14  GR15 
001dbf18
GR16  GR17 0001 GR18 001d5278 GR19 
001c5000
GR20 00416a40 GR21 006a GR22 0016d4e8 GR23 
004a
GR24 029c GR25  GR26 00419f50 GR27 
001e65f8
GR28  GR29 0013 GR30 7a029510 GR31 
09d4a400
SR00 09d4a400 SR01  SR02  SR03 
SR04 09d4a400 SR05 09d4a400 SR06 01eea400 SR07 01eea400

Trace 0: 0x7efd7f9adb80 [9d4a404/09d4a41074d8/00040306/ff00] 
IA_F 09d4a41074db IA_B 09d4a41074df IIR 4afc3ff9
PSW  0004001f CB    -C---RQPDI
GR00  GR01 09d4a400 GR02 0010758b GR03 
003c79b8
GR04 00419f50 GR05 00410a30 GR06 7a0005c8 GR07 
0013
GR08 004122f8 GR09 000b GR10 001db1b8 GR11 
001c81f8
GR12 001c81f8 GR13 001c81f8 GR14  GR15 
001dbf18
GR16  GR17 0001 GR18 001d5278 GR19 
001c5000
GR20 00416a40 GR21 006a GR22 2400 GR23 
004a
GR24 029c GR25  GR26 00419f50 GR27 
001e65f8
GR28  GR29 0013 GR30 7a029510 GR31 
0010758b
SR00 09d4a400 SR01  SR02  SR03 
SR04 09d4a400 SR05 09d4a400 SR06 01eea400 SR07 01eea400

The problem is the 0x1c5000 value in r19, which is the value of an old
instruction. At 0x9d4a416d514 is a be,n and at 09d4a4107570 the
N bit is set. First i thought it might be just a display issue with the
log, but the following change to confirm the issue makes the kernel
linking succeed:


diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 7546a5f5a2..56c68a7cbe 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -3847,7 +3849,7 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
 copy_iaoq_entry(ctx, cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
 tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_b);
 }
-if (a->n && use_nullify_skip(ctx)) {
+if (0 && a->n && use_nullify_skip(ctx)) {
 copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
 tcg_gen_addi_i64(tmp, tmp, 4);
 copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);


So i think the problem is caused by this optimization. Does this ring a
bell? Debugging this is rather hard, alone the logfile above is 6GB in
size...

Thanks,
Sven



Re: target/hppa: be,n nullifying first insn at branch target?

2024-03-26 Thread Sven Schnelle
Richard Henderson  writes:

> On 3/25/24 09:33, Sven Schnelle wrote:
>> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
>> index 7546a5f5a2..56c68a7cbe 100644
>> --- a/target/hppa/translate.c
>> +++ b/target/hppa/translate.c
>> @@ -3847,7 +3849,7 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>>   copy_iaoq_entry(ctx, cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
>>   tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_b);
>>   }
>> -if (a->n && use_nullify_skip(ctx)) {
>> +if (0 && a->n && use_nullify_skip(ctx)) {
>>   copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
>>   tcg_gen_addi_i64(tmp, tmp, 4);
>>   copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
>> So i think the problem is caused by this optimization. Does this
>> ring a
>> bell? Debugging this is rather hard, alone the logfile above is 6GB in
>> size...
>
> The problem is a missing
>
> nullify_set(ctx, 0)
>
> within this block.
>
> I have patches queued to reorg the IAQ handling, which I hope will fix
> the problem Sven saw with spaces.  It would fix this as a consequence
> of other unification.  But I think it's a bit too big for 9.0.

Thanks Richard. Let me know if you want me to test patches.



  1   2   3   >