Re: [PATCH] hw/riscv: virt: pass random seed to fdt

2022-06-28 Thread Alistair Francis
On Mon, Jun 13, 2022 at 10:10 PM Jason A. Donenfeld  wrote:
>
> If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to
> initialize early. Set this using the usual guest random number
> generation function. This is confirmed to successfully initialize the
> RNG on Linux 5.19-rc2.

I have a Linux 5.8 test case that is failing due to this patch.

The command line is:

qemu-system-riscv64 \
-machine virt -m 64M \
-cpu rv64,mmu=false \
-serial mon:stdio -serial null -nographic \
-append "root=/dev/vda rw highres=off  console=ttyS0 mem=1G ip=dhcp
earlycon=sbi" \
-device virtio-net-device,netdev=net0,mac=52:54:00:12:34:02 \
-netdev user,id=net0 \
-object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-rng-device,rng=rng0 \
-smp 1  \
-d guest_errors \
-kernel ./images/qemuriscv64/nommu-Image \
-drive id=disk0,file=./images/qemuriscv64/nommu-rootfs.ext2,if=none,format=raw \
-device virtio -blk-device,drive=disk0 \
-bios none

The working log (before this commit) is:

[0.00] Linux version 5.8.0 (alistair@risc6-mainframe)
(riscv64-elf-gcc (Arch Linux Repositories) 10.1.0, GNU ld (GNU
Binutils) 2.34) #2 SMP Wed Sep
30 12:02:11 PDT 2020
[0.00] earlycon: uart8250 at MMIO 0x1000 (options
'115200n8')
[0.00] printk: bootconsole [uart8250] enabled
[0.00] Zone ranges:
[0.00]   DMA32[mem 0x8000-0x83ff]
[0.00]   Normal   empty
[0.00] Movable zone start for each node
[0.00] Early memory node ranges
[0.00]   node   0: [mem 0x8000-0x83ff]
[0.00] Initmem setup node 0 [mem 0x8000-0x83ff]
[0.00] riscv: ISA extensions abcdefhimnrs
[0.00] riscv: ELF capabilities acdfim
[0.00] percpu: max_distance=0xc000 too large for vmalloc space 0x0
[0.00] percpu: Embedded 12 pages/cpu s18528 r0 d30624 u49152
[0.00] Built 1 zonelists, mobility grouping on.  Total pages: 16160
[0.00] Kernel command line: root=/dev/vda rw
earlycon=uart8250,mmio,0x1000,115200n8 console=ttyS0
[0.00] Dentry cache hash table entries: 8192 (order: 4, 65536
bytes, linear)
[0.00] Inode-cache hash table entries: 4096 (order: 3, 32768
bytes, linear)
[0.00] Sorting __ex_table...
[0.00] mem auto-init: stack:off, heap alloc:off, heap free:off
[0.00] Memory: 62472K/65536K available (1369K kernel code,
144K rwdata, 238K rodata, 106K init, 134K bss, 3064K reserved, 0K
cma-reserved)
[0.00] rcu: Hierarchical RCU implementation.
[0.00] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[0.00] rcu: RCU calculated value of scheduler-enlistment delay
is 25 jiffies.
[0.00] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[0.00] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[0.00] riscv-intc: 64 local interrupts mapped
sifive_plic_read: Invalid register read 0x200c
sifive_plic_write: Invalid enable write 0x200c
[0.00] plic: plic@c00: mapped 96 interrupts with 1
handlers for 2 contexts.
[0.00] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0]
[0.00] clocksource: riscv_clocksource: mask:
0x max_cycles: 0x24e6a1710, max_idle_ns: 440795202120
ns
[0.000106] sched_clock: 64 bits at 10MHz, resolution 100ns, wraps
every 4398046511100ns
[0.002649] Console: colour dummy device 80x25
[0.003599] Calibrating delay loop (skipped), value calculated
using timer frequency.. 20.00 BogoMIPS (lpj=4)
[0.003960] pid_max: default: 4096 minimum: 301
[0.004718] Mount-cache hash table entries: 512 (order: 0, 4096
bytes, linear)
[0.004922] Mountpoint-cache hash table entries: 512 (order: 0,
4096 bytes, linear)
[0.022781] rcu: Hierarchical SRCU implementation.
[0.024374] smp: Bringing up secondary CPUs ...
[0.024583] smp: Brought up 1 node, 1 CPU
[0.030450] devtmpfs: initialized
[0.035183] clocksource: jiffies: mask: 0x max_cycles:
0x, max_idle_ns: 764504178510 ns
[0.035600] futex hash table entries: 16 (order: -2, 1024 bytes, linear)
[0.055175] clocksource: Switched to clocksource riscv_clocksource
[0.073226] workingset: timestamp_bits=62 max_order=14 bucket_order=0
[0.078326] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
[0.082509] printk: console [ttyS0] disabled
[0.083408] 1000.uart: ttyS0 at MMIO 0x1000 (irq = 2,
base_baud = 230400) is a 16550A
[0.084805] printk: console [ttyS0] enabled
[0.084805] printk: console [ttyS0] enabled
[0.085242] printk: bootconsole [uart8250] disabled
[0.085242] printk: bootconsole [uart8250] disabled
virtio_mmio_write: attempt to write guest features with
guest_features_sel > 0 in legacy mode
[0.095810] virtio_blk virtio2: [vda] 122880 512-byte logical
blocks (62.9 MB/60.0 MiB)
[0.096155] vda: detected capacity change from 0 to 62914560
[  

[PATCH v2 05/13] hw/i2c: add asynchronous send

2022-06-28 Thread Peter Delevoryas
From: Klaus Jensen 

Add an asynchronous version of i2c_send() that requires the slave to
explicitly acknowledge on the bus with i2c_ack().

The current master must use the new i2c_start_send_async() to indicate
that it wants to do an asynchronous transfer. This allows the i2c core
to check if the target slave supports this or not. This approach relies
on adding a new enum i2c_event member, which is why a bunch of other
devices needs changes in their event handling switches.

Signed-off-by: Klaus Jensen 
Message-Id: <20220601210831.67259-5-...@irrelevant.dk>
Signed-off-by: Cédric Le Goater 
---
 hw/arm/pxa2xx.c|  2 ++
 hw/display/sii9022.c   |  2 ++
 hw/display/ssd0303.c   |  2 ++
 hw/i2c/core.c  | 36 +++-
 hw/i2c/smbus_slave.c   |  4 
 hw/i2c/trace-events|  2 ++
 hw/nvram/eeprom_at24c.c|  2 ++
 hw/sensor/lsm303dlhc_mag.c |  2 ++
 include/hw/i2c/i2c.h   | 16 
 9 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index f4f687df68..93dda83d7a 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1305,6 +1305,8 @@ static int pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event 
event)
 case I2C_NACK:
 s->status |= 1 << 1;   /* set ACKNAK */
 break;
+default:
+return -1;
 }
 pxa2xx_i2c_update(s);
 
diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c
index b591a58789..664fd4046d 100644
--- a/hw/display/sii9022.c
+++ b/hw/display/sii9022.c
@@ -76,6 +76,8 @@ static int sii9022_event(I2CSlave *i2c, enum i2c_event event)
 break;
 case I2C_NACK:
 break;
+default:
+return -1;
 }
 
 return 0;
diff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c
index aeae22da9c..d67b0ad7b5 100644
--- a/hw/display/ssd0303.c
+++ b/hw/display/ssd0303.c
@@ -196,6 +196,8 @@ static int ssd0303_event(I2CSlave *i2c, enum i2c_event 
event)
 case I2C_NACK:
 /* Nothing to do.  */
 break;
+default:
+return -1;
 }
 
 return 0;
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 145dce6078..d4ba8146bf 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -161,7 +161,8 @@ static int i2c_do_start_transfer(I2CBus *bus, uint8_t 
address,
start condition.  */
 
 if (sc->event) {
-trace_i2c_event("start", s->address);
+trace_i2c_event(event == I2C_START_SEND ? "start" : "start_async",
+s->address);
 rv = sc->event(s, event);
 if (rv && !bus->broadcast) {
 if (bus_scanned) {
@@ -212,6 +213,11 @@ int i2c_start_send(I2CBus *bus, uint8_t address)
 return i2c_do_start_transfer(bus, address, I2C_START_SEND);
 }
 
+int i2c_start_send_async(I2CBus *bus, uint8_t address)
+{
+return i2c_do_start_transfer(bus, address, I2C_START_SEND_ASYNC);
+}
+
 void i2c_end_transfer(I2CBus *bus)
 {
 I2CSlaveClass *sc;
@@ -261,6 +267,23 @@ int i2c_send(I2CBus *bus, uint8_t data)
 return ret ? -1 : 0;
 }
 
+int i2c_send_async(I2CBus *bus, uint8_t data)
+{
+I2CNode *node = QLIST_FIRST(>current_devs);
+I2CSlave *slave = node->elt;
+I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(slave);
+
+if (!sc->send_async) {
+return -1;
+}
+
+trace_i2c_send_async(slave->address, data);
+
+sc->send_async(slave, data);
+
+return 0;
+}
+
 uint8_t i2c_recv(I2CBus *bus)
 {
 uint8_t data = 0xff;
@@ -297,6 +320,17 @@ void i2c_nack(I2CBus *bus)
 }
 }
 
+void i2c_ack(I2CBus *bus)
+{
+if (!bus->bh) {
+return;
+}
+
+trace_i2c_ack();
+
+qemu_bh_schedule(bus->bh);
+}
+
 static int i2c_slave_post_load(void *opaque, int version_id)
 {
 I2CSlave *dev = opaque;
diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
index 5d10e27664..feb3ec6333 100644
--- a/hw/i2c/smbus_slave.c
+++ b/hw/i2c/smbus_slave.c
@@ -143,6 +143,10 @@ static int smbus_i2c_event(I2CSlave *s, enum i2c_event 
event)
 dev->mode = SMBUS_CONFUSED;
 break;
 }
+break;
+
+default:
+return -1;
 }
 
 return 0;
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
index 209275ed2d..af181d43ee 100644
--- a/hw/i2c/trace-events
+++ b/hw/i2c/trace-events
@@ -4,7 +4,9 @@
 
 i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
 i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
+i2c_send_async(uint8_t address, uint8_t data) "send_async(addr:0x%02x) 
data:0x%02x"
 i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
+i2c_ack(void) ""
 
 # aspeed_i2c.c
 
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 01a3093600..d695f6ae89 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -75,6 +75,8 @@ int at24c_eeprom_event(I2CSlave *s, enum i2c_event event)
 break;
 case I2C_NACK:
 break;
+default:
+return -1;
  

[PATCH v2 00/13] hw/i2c/aspeed: Add new-registers DMA slave mode RX support

2022-06-28 Thread Peter Delevoryas
Hey Cedric,

I've gone over the patch series and reordered it a little better.

Changes since v1:
- Replaced printf's with qemu_log_mask or trace events.
- Added more detailed commit messages to several commits.
- Removed one unnecessary patch through reordering intel-me before oby35-cl.
- Replaced PECI register #define's with registerfields.h API.
- Renamed fby35-cpld to fby35-sb-cpld to be more specific.
- Moved the I2C patches to the start of the series, and the
  optional device/machine stuff to the end of the series.

If you'd like, I can separate this into separate patch series.

However, as I mentioned in the previous series, I was using oby35-cl to test
the I2C master and slave mode support in QEMU against Zephyr, and this patch
series includes everything put together.

Hopefully my patch series actually arrives in one piece this time.

Thanks,
Peter

v1: https://lore.kernel.org/qemu-devel/20220627195506.403715-1-p...@fb.com/

Klaus Jensen (3):
  hw/i2c: support multiple masters
  hw/i2c: add asynchronous send
  hw/i2c/aspeed: add slave device in old register mode

Peter Delevoryas (10):
  hw/i2c/aspeed: Fix R_I2CD_FUN_CTRL reference
  hw/i2c/aspeed: Fix DMA len write-enable bit handling
  hw/i2c/aspeed: Fix MASTER_EN missing error message
  hw/i2c/aspeed: Add new-registers DMA slave mode RX support
  hw/i2c/pmbus: Reset out buf after switching pages
  hw/i2c/pmbus: Add read-only IC_DEVICE_ID support
  hw/misc/aspeed: Add PECI controller
  hw/misc/aspeed: Add fby35-sb-cpld
  hw/misc/aspeed: Add intel-me
  hw/arm/aspeed: Add oby35-cl machine

 MAINTAINERS  |   2 +
 hw/arm/aspeed.c  |  48 +++
 hw/arm/aspeed_ast10x0.c  |  12 ++
 hw/arm/aspeed_ast2600.c  |  12 ++
 hw/arm/aspeed_soc.c  |  13 ++
 hw/arm/pxa2xx.c  |   2 +
 hw/display/sii9022.c |   2 +
 hw/display/ssd0303.c |   2 +
 hw/i2c/aspeed_i2c.c  | 234 +++
 hw/i2c/core.c|  70 -
 hw/i2c/pmbus_device.c|   6 +
 hw/i2c/smbus_slave.c |   4 +
 hw/i2c/trace-events  |   2 +
 hw/misc/aspeed_peci.c| 136 ++
 hw/misc/fby35_sb_cpld.c  | 128 +
 hw/misc/intel_me.c   | 162 +
 hw/misc/meson.build  |   5 +-
 hw/misc/trace-events |  12 ++
 hw/nvram/eeprom_at24c.c  |   2 +
 hw/sensor/isl_pmbus_vr.c |  31 
 hw/sensor/lsm303dlhc_mag.c   |   2 +
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/i2c/aspeed_i2c.h  |  11 ++
 include/hw/i2c/i2c.h |  30 
 include/hw/i2c/pmbus_device.h|   1 +
 include/hw/misc/aspeed_peci.h|  47 +++
 include/hw/sensor/isl_pmbus_vr.h |   1 +
 27 files changed, 950 insertions(+), 30 deletions(-)
 create mode 100644 hw/misc/aspeed_peci.c
 create mode 100644 hw/misc/fby35_sb_cpld.c
 create mode 100644 hw/misc/intel_me.c
 create mode 100644 include/hw/misc/aspeed_peci.h

-- 
2.30.2




[PATCH v2 08/13] hw/i2c/pmbus: Reset out buf after switching pages

2022-06-28 Thread Peter Delevoryas
When a pmbus device switches pages, it should clears its output buffer so
that the next transaction doesn't emit data from the previous page.

Fixes: 3746d5c15e70570b ("hw/i2c: add support for PMBus”)
Signed-off-by: Peter Delevoryas 
---
 hw/i2c/pmbus_device.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index 62885fa6a1..efddc36fd9 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -1088,6 +1088,7 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t 
*buf, uint8_t len)
 
 if (pmdev->code == PMBUS_PAGE) {
 pmdev->page = pmbus_receive8(pmdev);
+pmdev->out_buf_len = 0;
 return 0;
 }
 
-- 
2.30.2




Re: [PATCH 2/2] hw/i386/xen/xen-hvm: Inline xen_piix_pci_write_config_client() and remove it

2022-06-28 Thread Laurent Vivier

Le 26/06/2022 à 11:46, Bernhard Beschow a écrit :

xen_piix_pci_write_config_client() is implemented in the xen sub tree and
uses PIIX constants internally, thus creating a direct dependency on
PIIX. Now that xen_set_pci_link_route() is stubbable, the logic of
xen_piix_pci_write_config_client() can be moved to PIIX which resolves
the dependency.

Signed-off-by: Bernhard Beschow 
---
  hw/i386/xen/xen-hvm.c | 18 --
  hw/isa/piix3.c| 15 ++-
  include/hw/xen/xen.h  |  1 -
  stubs/xen-hw-stub.c   |  4 
  4 files changed, 14 insertions(+), 24 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 204fda7949..e4293d6d66 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -15,7 +15,6 @@
  #include "hw/pci/pci.h"
  #include "hw/pci/pci_host.h"
  #include "hw/i386/pc.h"
-#include "hw/southbridge/piix.h"
  #include "hw/irq.h"
  #include "hw/hw.h"
  #include "hw/i386/apic-msidef.h"
@@ -149,23 +148,6 @@ void xen_piix3_set_irq(void *opaque, int irq_num, int 
level)
 irq_num & 3, level);
  }
  
-void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)

-{
-int i;
-
-/* Scan for updates to PCI link routes (0x60-0x63). */
-for (i = 0; i < len; i++) {
-uint8_t v = (val >> (8 * i)) & 0xff;
-if (v & 0x80) {
-v = 0;
-}
-v &= 0xf;
-if (((address + i) >= PIIX_PIRQCA) && ((address + i) <= PIIX_PIRQCD)) {
-xen_set_pci_link_route(address + i - PIIX_PIRQCA, v);
-}
-}
-}
-
  int xen_set_pci_link_route(uint8_t link, uint8_t irq)
  {
  return xendevicemodel_set_pci_link_route(xen_dmod, xen_domid, link, irq);
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 6388558f92..48f9ab1096 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -138,7 +138,20 @@ static void piix3_write_config(PCIDevice *dev,
  static void piix3_write_config_xen(PCIDevice *dev,
 uint32_t address, uint32_t val, int len)
  {
-xen_piix_pci_write_config_client(address, val, len);
+int i;
+
+/* Scan for updates to PCI link routes (0x60-0x63). */
+for (i = 0; i < len; i++) {
+uint8_t v = (val >> (8 * i)) & 0xff;
+if (v & 0x80) {
+v = 0;
+}
+v &= 0xf;
+if (((address + i) >= PIIX_PIRQCA) && ((address + i) <= PIIX_PIRQCD)) {
+xen_set_pci_link_route(address + i - PIIX_PIRQCA, v);
+}
+}
+
  piix3_write_config(dev, address, val, len);
  }
  
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h

index 13bffaef53..afdf9c436a 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -23,7 +23,6 @@ extern bool xen_domid_restrict;
  int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
  int xen_set_pci_link_route(uint8_t link, uint8_t irq);
  void xen_piix3_set_irq(void *opaque, int irq_num, int level);
-void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
  void xen_hvm_inject_msi(uint64_t addr, uint32_t data);
  int xen_is_pirq_msi(uint32_t msi_data);
  
diff --git a/stubs/xen-hw-stub.c b/stubs/xen-hw-stub.c

index 743967623f..34a22f2ad7 100644
--- a/stubs/xen-hw-stub.c
+++ b/stubs/xen-hw-stub.c
@@ -19,10 +19,6 @@ void xen_piix3_set_irq(void *opaque, int irq_num, int level)
  {
  }
  
-void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)

-{
-}
-
  int xen_set_pci_link_route(uint8_t link, uint8_t irq)
  {
  return -1;


Applied to my trivial-patches branch.

Thanks,
Laurent




Re: [PATCH v2] target/riscv: fix user-mode build issue because mhartid

2022-06-28 Thread Rahul Pathak
Hi Alistair

My fix patch needs to be dropped since Anup took care of this issue
in his yesterdays series update in this patch -
[PATCH v8 4/4] target/riscv: Force disable extensions if priv spec
version does not match

Thanks
Rahul

On Wed, Jun 29, 2022 at 7:32 AM Alistair Francis  wrote:
>
> On Tue, Jun 28, 2022 at 3:03 AM Rahul Pathak  wrote:
> >
> > mhartid csr is not available in user-mode code path and
> > user-mode build fails because of its reference in
> > riscv_cpu_realize function
> >
> > Commit causing the issue is currently in Alistair's
> > riscv-to-apply.next branch and need to be squashed there.
> >
> > Fixes: 7ecee770d40 ("target/riscv: Force disable extensions if priv spec 
> > version does not match")
>
> Can you please re-send the original patch with the fix? I have removed
> this patch from my tree
>
> Alistair
>
> >
> > Signed-off-by: Rahul Pathak 
> > ---
> >
> > Changes in V2:
> > - remove the stray format specifier
> > - add the Fixes tag and reference to external tree
> > ---
> >  target/riscv/cpu.c | 6 ++
> >  1 file changed, 6 insertions(+)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index e4ec05abf4..509923f15e 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -636,9 +636,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> > **errp)
> >  if (isa_ext_is_enabled(cpu, _edata_arr[i]) &&
> >  (env->priv_ver < isa_edata_arr[i].min_version)) {
> >  isa_ext_update_enabled(cpu, _edata_arr[i], false);
> > +#ifndef CONFIG_USER_ONLY
> >  warn_report("disabling %s extension for hart 0x%lx because "
> >  "privilege spec version does not match",
> >  isa_edata_arr[i].name, (unsigned 
> > long)env->mhartid);
> > +#else
> > +warn_report("disabling %s extension for hart because "
> > +"privilege spec version does not match",
> > +isa_edata_arr[i].name);
> > +#endif
> >  }
> >  }
> >
> > --
> > 2.34.1
> >
> >



-- 

Thanks
Rahul Pathak



[PATCH 2/2] vhost-user: Support vhost_dev_start

2022-06-28 Thread Yajun Wu
The motivation of adding vhost-user vhost_dev_start support is to
improve backend configuration speed and reduce live migration VM
downtime.

Today VQ configuration is issued one by one. For virtio net with
multi-queue support, backend needs to update RSS (Receive side
scaling) on every rx queue enable. Updating RSS is time-consuming
(typical time like 7ms).

Implement already defined vhost status and message in the vhost
specification [1].
(a) VHOST_USER_PROTOCOL_F_STATUS
(b) VHOST_USER_SET_STATUS
(c) VHOST_USER_GET_STATUS

Send message VHOST_USER_SET_STATUS with VIRTIO_CONFIG_S_DRIVER_OK for
device start and reset(0) for device stop.

On reception of the DRIVER_OK message, backend can apply the needed setting
only once (instead of incremental) and also utilize parallelism on enabling
queues.

This improves QEMU's live migration downtime with vhost user backend
implementation by great margin, specially for the large number of VQs of 64
from 800 msec to 250 msec.

[1] https://qemu-project.gitlab.io/qemu/interop/vhost-user.html

Signed-off-by: Yajun Wu 
Acked-by: Parav Pandit 
---
 hw/virtio/vhost-user.c | 58 ++
 1 file changed, 58 insertions(+)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 4b9be26e84..9f75c51dc2 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -81,6 +81,7 @@ enum VhostUserProtocolFeature {
 VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
 /* Feature 14 reserved for VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS. */
 VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
+VHOST_USER_PROTOCOL_F_STATUS = 16,
 VHOST_USER_PROTOCOL_F_MAX
 };
 
@@ -126,6 +127,8 @@ typedef enum VhostUserRequest {
 VHOST_USER_GET_MAX_MEM_SLOTS = 36,
 VHOST_USER_ADD_MEM_REG = 37,
 VHOST_USER_REM_MEM_REG = 38,
+VHOST_USER_SET_STATUS = 39,
+VHOST_USER_GET_STATUS = 40,
 VHOST_USER_MAX
 } VhostUserRequest;
 
@@ -1446,6 +1449,39 @@ static int vhost_user_set_u64(struct vhost_dev *dev, int 
request, uint64_t u64,
 return 0;
 }
 
+static int vhost_user_set_status(struct vhost_dev *dev, uint8_t status)
+{
+return vhost_user_set_u64(dev, VHOST_USER_SET_STATUS, status, false);
+}
+
+static int vhost_user_get_status(struct vhost_dev *dev, uint8_t *status)
+{
+uint64_t value;
+int ret;
+
+ret = vhost_user_get_u64(dev, VHOST_USER_GET_STATUS, );
+if (ret < 0) {
+return ret;
+}
+*status = value;
+
+return 0;
+}
+
+static int vhost_user_add_status(struct vhost_dev *dev, uint8_t status)
+{
+uint8_t s;
+int ret;
+
+ret = vhost_user_get_status(dev, );
+if (ret < 0) {
+return ret;
+}
+s |= status;
+
+return vhost_user_set_status(dev, s);
+}
+
 static int vhost_user_set_features(struct vhost_dev *dev,
uint64_t features)
 {
@@ -2602,6 +2638,27 @@ void vhost_user_cleanup(VhostUserState *user)
 user->chr = NULL;
 }
 
+static int vhost_user_dev_start(struct vhost_dev *dev, bool started)
+{
+if (!virtio_has_feature(dev->protocol_features,
+VHOST_USER_PROTOCOL_F_STATUS)) {
+return 0;
+}
+
+/* Set device status only for last queue pair */
+if (dev->vq_index + dev->nvqs != dev->vq_index_end) {
+return 0;
+}
+
+if (started) {
+return vhost_user_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+  VIRTIO_CONFIG_S_DRIVER |
+  VIRTIO_CONFIG_S_DRIVER_OK);
+} else {
+return vhost_user_set_status(dev, 0);
+}
+}
+
 const VhostOps user_ops = {
 .backend_type = VHOST_BACKEND_TYPE_USER,
 .vhost_backend_init = vhost_user_backend_init,
@@ -2635,4 +2692,5 @@ const VhostOps user_ops = {
 .vhost_backend_mem_section_filter = vhost_user_mem_section_filter,
 .vhost_get_inflight_fd = vhost_user_get_inflight_fd,
 .vhost_set_inflight_fd = vhost_user_set_inflight_fd,
+.vhost_dev_start = vhost_user_dev_start,
 };
-- 
2.27.0




[PATCH 1/2] vhost: Change the sequence of device start

2022-06-28 Thread Yajun Wu
This patch is part of adding vhost-user vhost_dev_start support. The
motivation is to improve backend configuration speed and reduce live
migration VM downtime.

Moving the device start routines after finishing all the necessary device
and VQ configuration, further aligning to the virtio specification for
"device initialization sequence".

Following patch will add vhost-user vhost_dev_start support.

Signed-off-by: Yajun Wu 
Acked-by: Parav Pandit 

---
 hw/block/vhost-user-blk.c | 18 +++---
 hw/net/vhost_net.c| 12 ++--
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 9117222456..972ef46365 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -163,13 +163,6 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error 
**errp)
 goto err_guest_notifiers;
 }
 
-ret = vhost_dev_start(>dev, vdev);
-if (ret < 0) {
-error_setg_errno(errp, -ret, "Error starting vhost");
-goto err_guest_notifiers;
-}
-s->started_vu = true;
-
 /* guest_notifier_mask/pending not used yet, so just unmask
  * everything here. virtio-pci will do the right thing by
  * enabling/disabling irqfd.
@@ -178,9 +171,20 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error 
**errp)
 vhost_virtqueue_mask(>dev, vdev, i, false);
 }
 
+s->dev.vq_index_end = s->dev.nvqs;
+ret = vhost_dev_start(>dev, vdev);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Error starting vhost");
+goto err_guest_notifiers;
+}
+s->started_vu = true;
+
 return ret;
 
 err_guest_notifiers:
+for (i = 0; i < s->dev.nvqs; i++) {
+vhost_virtqueue_mask(>dev, vdev, i, true);
+}
 k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
 err_host_notifiers:
 vhost_dev_disable_notifiers(>dev, vdev);
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index ccac5b7a64..6a8a6082a2 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -370,21 +370,21 @@ int vhost_net_start(VirtIODevice *dev, NetClientState 
*ncs,
 } else {
 peer = qemu_get_peer(ncs, n->max_queue_pairs);
 }
-r = vhost_net_start_one(get_vhost_net(peer), dev);
-
-if (r < 0) {
-goto err_start;
-}
 
 if (peer->vring_enable) {
 /* restore vring enable state */
 r = vhost_set_vring_enable(peer, peer->vring_enable);
 
 if (r < 0) {
-vhost_net_stop_one(get_vhost_net(peer), dev);
 goto err_start;
 }
 }
+
+r = vhost_net_start_one(get_vhost_net(peer), dev);
+if (r < 0) {
+vhost_net_stop_one(get_vhost_net(peer), dev);
+goto err_start;
+}
 }
 
 return 0;
-- 
2.27.0




Re: [RFC v3 1/5] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-06-28 Thread Sam Li
Damien Le Moal  于2022年6月29日周三 10:32写道:
>
> On 6/29/22 10:50, Sam Li wrote:
> >>> +rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct 
> >>> blk_zone);
> >>> +g_autofree struct blk_zone_report *rep = g_new(struct 
> >>> blk_zone_report, nrz);
> >>
> >> g_new() looks incorrect. There should be 1 struct blk_zone_report
> >> followed by nrz struct blk_zone structs. Please use g_malloc(rep_size)
> >> instead.
> >
> > Yes! However, it still has a memory leak error when using g_autofree
> > && g_malloc.
> 
>  That may be because you are changing the value of the rep pointer while
>  parsing the report ?
> >>>
> >>> I am not sure it is the case. Can you show me some way to find the 
> >>> problem?
> >>
> >> Not sure. I never used this g_malloc()/g_autofree() before so not sure how
> >> it works. It may be that g_autofree() work only with g_new() ?
> >> Could you try separating the declaration and allocation ? e.g.
> >>
> >> Declare at the beginning of the function:
> >> g_autofree struct blk_zone_report *rep = NULL;
> >>
> >> And then when needed do:
> >>
> >> rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct blk_zone);
> >> rep = g_malloc(rep_size);
> >
> > Actually, the memory leak occurs in that way. When using zone_mgmt,
> > memory leak still occurs. Asan gives the error information not much so
> > I haven't tracked down the problem yet.
>
> See this:
>
> https://blog.fishsoup.net/2015/11/05/attributecleanup-mixed-declarations-and-code-and-goto/
>
> Maybe you can find some hints.

Thanks!

>
> --
> Damien Le Moal
> Western Digital Research



Re: [RFC v3 1/5] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-06-28 Thread Damien Le Moal
On 6/29/22 10:50, Sam Li wrote:
>>> +rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct 
>>> blk_zone);
>>> +g_autofree struct blk_zone_report *rep = g_new(struct 
>>> blk_zone_report, nrz);
>>
>> g_new() looks incorrect. There should be 1 struct blk_zone_report
>> followed by nrz struct blk_zone structs. Please use g_malloc(rep_size)
>> instead.
>
> Yes! However, it still has a memory leak error when using g_autofree
> && g_malloc.

 That may be because you are changing the value of the rep pointer while
 parsing the report ?
>>>
>>> I am not sure it is the case. Can you show me some way to find the problem?
>>
>> Not sure. I never used this g_malloc()/g_autofree() before so not sure how
>> it works. It may be that g_autofree() work only with g_new() ?
>> Could you try separating the declaration and allocation ? e.g.
>>
>> Declare at the beginning of the function:
>> g_autofree struct blk_zone_report *rep = NULL;
>>
>> And then when needed do:
>>
>> rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct blk_zone);
>> rep = g_malloc(rep_size);
> 
> Actually, the memory leak occurs in that way. When using zone_mgmt,
> memory leak still occurs. Asan gives the error information not much so
> I haven't tracked down the problem yet.

See this:

https://blog.fishsoup.net/2015/11/05/attributecleanup-mixed-declarations-and-code-and-goto/

Maybe you can find some hints.

-- 
Damien Le Moal
Western Digital Research



[PATCH v2 10/13] hw/misc/aspeed: Add PECI controller

2022-06-28 Thread Peter Delevoryas
This introduces a really basic PECI controller that responses to
commands by always setting the response code to success and then raising
an interrupt to indicate the command is done. This helps avoid getting
hit with constant errors if the driver continuously attempts to send a
command and keeps timing out.

The AST2400 and AST2500 only included registers up to 0x5C, not 0xFC.
They supported PECI 1.1, 2.0, and 3.0. The AST2600 and AST1030 support
PECI 4.0, which includes more read/write buffer registers from 0x80 to
0xFC to support 64-byte mode.

This patch doesn't attempt to handle that, or to create a different
version of the controller for the different generations, since it's only
implementing functionality that is common to all generations.

The basic sequence of events is that the firmware will read and write to
various registers and then trigger a command by setting the FIRE bit in
the command register (similar to the I2C controller).

Then the firmware waits for an interrupt from the PECI controller,
expecting the interrupt status register to be filled in with info on
what happened. If the command was transmitted and received successfully,
then response codes from the host CPU will be found in the data buffer
registers.

Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed_ast10x0.c   |  12 +++
 hw/arm/aspeed_ast2600.c   |  12 +++
 hw/arm/aspeed_soc.c   |  13 
 hw/misc/aspeed_peci.c | 136 ++
 hw/misc/meson.build   |   3 +-
 hw/misc/trace-events  |   4 +
 include/hw/arm/aspeed_soc.h   |   3 +
 include/hw/misc/aspeed_peci.h |  47 
 8 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/aspeed_peci.c
 create mode 100644 include/hw/misc/aspeed_peci.h

diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
index 5df480a21f..56e8de3d89 100644
--- a/hw/arm/aspeed_ast10x0.c
+++ b/hw/arm/aspeed_ast10x0.c
@@ -47,6 +47,7 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
 [ASPEED_DEV_UART13]= 0x7E790700,
 [ASPEED_DEV_WDT]   = 0x7E785000,
 [ASPEED_DEV_LPC]   = 0x7E789000,
+[ASPEED_DEV_PECI]  = 0x7E78B000,
 [ASPEED_DEV_I2C]   = 0x7E7B,
 };
 
@@ -75,6 +76,7 @@ static const int aspeed_soc_ast1030_irqmap[] = {
 [ASPEED_DEV_TIMER8]= 23,
 [ASPEED_DEV_WDT]   = 24,
 [ASPEED_DEV_LPC]   = 35,
+[ASPEED_DEV_PECI]  = 38,
 [ASPEED_DEV_FMC]   = 39,
 [ASPEED_DEV_PWM]   = 44,
 [ASPEED_DEV_ADC]   = 46,
@@ -133,6 +135,8 @@ static void aspeed_soc_ast1030_init(Object *obj)
 
 object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
 
+object_initialize_child(obj, "peci", >peci, TYPE_ASPEED_PECI);
+
 object_initialize_child(obj, "sbc", >sbc, TYPE_ASPEED_SBC);
 
 for (i = 0; i < sc->wdts_num; i++) {
@@ -206,6 +210,14 @@ static void aspeed_soc_ast1030_realize(DeviceState 
*dev_soc, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>i2c.busses[i]), 0, irq);
 }
 
+/* PECI */
+if (!sysbus_realize(SYS_BUS_DEVICE(>peci), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>peci), 0, sc->memmap[ASPEED_DEV_PECI]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>peci), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_PECI));
+
 /* LPC */
 if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
 return;
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index b0a4199b69..85178fabea 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -59,6 +59,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 [ASPEED_DEV_LPC]   = 0x1E789000,
 [ASPEED_DEV_IBT]   = 0x1E789140,
 [ASPEED_DEV_I2C]   = 0x1E78A000,
+[ASPEED_DEV_PECI]  = 0x1E78B000,
 [ASPEED_DEV_UART1] = 0x1E783000,
 [ASPEED_DEV_UART2] = 0x1E78D000,
 [ASPEED_DEV_UART3] = 0x1E78E000,
@@ -122,6 +123,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_LPC]   = 35,
 [ASPEED_DEV_IBT]   = 143,
 [ASPEED_DEV_I2C]   = 110,   /* 110 -> 125 */
+[ASPEED_DEV_PECI]  = 38,
 [ASPEED_DEV_ETH1]  = 2,
 [ASPEED_DEV_ETH2]  = 3,
 [ASPEED_DEV_HACE]  = 4,
@@ -180,6 +182,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
 snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
 object_initialize_child(obj, "i2c", >i2c, typename);
 
+object_initialize_child(obj, "peci", >peci, TYPE_ASPEED_PECI);
+
 snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
 object_initialize_child(obj, "fmc", >fmc, typename);
 
@@ -388,6 +392,14 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>i2c.busses[i]), 0, irq);
 }
 
+/* PECI */
+if (!sysbus_realize(SYS_BUS_DEVICE(>peci), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>peci), 0, 

[PATCH v2 11/13] hw/misc/aspeed: Add fby35-sb-cpld

2022-06-28 Thread Peter Delevoryas
fby35 machines have 1 BMC on a baseboard and 2-4 server boards with BIC's.
There are also CPLD's on each of the boards, one type of CPLD on the
baseboard and another type on each of the server boards. This commit adds an
implementation of some of the logic performed by the server board CPLD,
which is connected to the server board BIC.

fby35 machines have 1 baseboard with a BMC (AST2600) and 4 server boards
with bridge interconnects (BIC's, AST1030's). Each server board has a CPLD
on it which provides FRU information and some synchronization functionality
with the BMC. The baseboard also has one CPLD, but it does other stuff.

This commit just adds some of the FRU functionality to allow the BIC to
startup without any errors.

Signed-off-by: Peter Delevoryas 
---
 MAINTAINERS |   1 +
 hw/misc/fby35_sb_cpld.c | 128 
 hw/misc/meson.build |   3 +-
 3 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/fby35_sb_cpld.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 05cf84b58c..3ffd473db1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1067,6 +1067,7 @@ F: hw/net/ftgmac100.c
 F: include/hw/net/ftgmac100.h
 F: docs/system/arm/aspeed.rst
 F: tests/qtest/*aspeed*
+F: hw/misc/fby35_sb_cpld.c
 
 NRF51
 M: Joel Stanley 
diff --git a/hw/misc/fby35_sb_cpld.c b/hw/misc/fby35_sb_cpld.c
new file mode 100644
index 00..f170a6c781
--- /dev/null
+++ b/hw/misc/fby35_sb_cpld.c
@@ -0,0 +1,128 @@
+/*
+ * fby35 Server Board CPLD
+ *
+ * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
+ *
+ * This code is licensed under the GPL version 2 or later. See the COPYING
+ * file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/i2c/i2c.h"
+#include "hw/registerfields.h"
+
+#define BOARD_ID_CLASS1 0b
+#define BOARD_ID_CLASS2 0b0001
+
+#define TYPE_FBY35_SB_CPLD "fby35-sb-cpld"
+OBJECT_DECLARE_SIMPLE_TYPE(Fby35SbCpldState, FBY35_SB_CPLD);
+
+REG8(CLASS_TYPE, 0x5);
+FIELD(CLASS_TYPE, RESERVED, 0, 2);
+FIELD(CLASS_TYPE, 1OU_EXPANSION_NOT_PRESENT, 2, 1);
+FIELD(CLASS_TYPE, 2OU_EXPANSION_NOT_PRESENT, 3, 1);
+FIELD(CLASS_TYPE, BOARD_ID, 4, 4);
+REG8(BOARD_REVISION, 0x8);
+FIELD(BOARD_REVISION, VALUE, 0, 4);
+FIELD(BOARD_REVISION, RESERVED, 4, 4);
+
+struct Fby35SbCpldState {
+I2CSlave parent_obj;
+
+uint8_t target_reg;
+uint32_t regs[10];
+};
+
+static void fby35_sb_cpld_realize(DeviceState *dev, Error **errp)
+{
+Fby35SbCpldState *s = FBY35_SB_CPLD(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+s->target_reg = 0;
+
+ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, BOARD_ID, 0b);
+ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, 1OU_EXPANSION_NOT_PRESENT, 1);
+ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, 2OU_EXPANSION_NOT_PRESENT, 1);
+ARRAY_FIELD_DP32(s->regs, BOARD_REVISION, VALUE, 0x1);
+}
+
+static int fby35_sb_cpld_i2c_event(I2CSlave *i2c, enum i2c_event event)
+{
+Fby35SbCpldState *s = FBY35_SB_CPLD(i2c);
+
+switch (event) {
+case I2C_START_RECV:
+break;
+case I2C_START_SEND:
+s->target_reg = 0;
+break;
+case I2C_START_SEND_ASYNC:
+case I2C_FINISH:
+case I2C_NACK:
+break;
+}
+
+return 0;
+}
+
+static uint8_t fby35_sb_cpld_i2c_recv(I2CSlave *i2c)
+{
+Fby35SbCpldState *s = FBY35_SB_CPLD(i2c);
+
+switch (s->target_reg) {
+case R_CLASS_TYPE:
+case R_BOARD_REVISION:
+return s->regs[s->target_reg];
+default:
+qemu_log_mask(LOG_UNIMP, "%s: Register read unimplemented: 0x%02x\n",
+  __func__, s->target_reg);
+return 0xff;
+}
+}
+
+static int fby35_sb_cpld_i2c_send(I2CSlave *i2c, uint8_t data)
+{
+Fby35SbCpldState *s = FBY35_SB_CPLD(i2c);
+
+if (s->target_reg == 0) {
+s->target_reg = data;
+return 0;
+}
+
+switch (s->target_reg) {
+case R_CLASS_TYPE:
+case R_BOARD_REVISION:
+s->regs[s->target_reg] = data;
+break;
+default:
+qemu_log_mask(LOG_UNIMP,
+  "%s: Register write unimplemented: 0x%02x 0x%02x\n",
+  __func__, s->target_reg, data);
+break;
+}
+
+return 0;
+}
+
+static void fby35_sb_cpld_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+I2CSlaveClass *i2c = I2C_SLAVE_CLASS(oc);
+
+dc->realize = fby35_sb_cpld_realize;
+i2c->event = fby35_sb_cpld_i2c_event;
+i2c->recv = fby35_sb_cpld_i2c_recv;
+i2c->send = fby35_sb_cpld_i2c_send;
+}
+
+static const TypeInfo types[] = {
+{
+.name = TYPE_FBY35_SB_CPLD,
+.parent = TYPE_I2C_SLAVE,
+.instance_size = sizeof(Fby35SbCpldState),
+.class_init = fby35_sb_cpld_class_init,
+},
+};
+
+DEFINE_TYPES(types);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 95268eddc0..948e25c440 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -117,7 +117,8 @@ 

[PATCH v2] target/ppc: Return default CPU for max CPU

2022-06-28 Thread Murilo Opsfelder Araujo
All ppc CPUs represent hardware that exists in the real world, i.e.: we
do not have a "max" CPU with all possible emulated features enabled.
Return the default CPU type for the machine because that has greater
chance of being useful as the "max" CPU.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1038
Cc: Cédric Le Goater 
Cc: Daniel Henrique Barboza 
Cc: Daniel P. Berrangé 
Cc: Greg Kurz 
Cc: Matheus K. Ferst 
Cc: Thomas Huth 
Signed-off-by: Murilo Opsfelder Araujo 
Signed-off-by: Fabiano Rosas 
---
v2:
- Return the default CPU of the machine instead of hard-coded alias.

v1: 
https://lore.kernel.org/qemu-devel/20220531172711.94564-1-muri...@linux.ibm.com/

 target/ppc/cpu-models.c |  1 -
 target/ppc/cpu_init.c   | 19 +++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index 976be5e0d1..05589eb21d 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -879,7 +879,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
 { "755", "755_v2.8" },
 { "goldfinger", "755_v2.8" },
 { "7400", "7400_v2.9" },
-{ "max", "7400_v2.9" },
 { "g4",  "7400_v2.9" },
 { "7410", "7410_v1.4" },
 { "nitro", "7410_v1.4" },
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index c16cb8dbe7..8ee0b7c785 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -47,6 +47,10 @@
 #include "spr_common.h"
 #include "power8-pmu.h"
 
+#ifndef CONFIG_USER_ONLY
+#include "hw/boards.h"
+#endif
+
 /* #define PPC_DEBUG_SPR */
 /* #define USE_APPLE_GDB */
 
@@ -6963,6 +6967,21 @@ static ObjectClass *ppc_cpu_class_by_name(const char 
*name)
 }
 }
 
+/*
+ * All ppc CPUs represent hardware that exists in the real world, i.e.: we
+ * do not have a "max" CPU with all possible emulated features enabled.
+ * Return the default CPU type for the machine because that has greater
+ * chance of being useful as the "max" CPU.
+ */
+#if !defined(CONFIG_USER_ONLY)
+if (strcmp(name, "max") == 0) {
+MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
+if (mc) {
+return object_class_by_name(mc->default_cpu_type);
+}
+}
+#endif
+
 cpu_model = g_ascii_strdown(name, -1);
 p = ppc_cpu_lookup_alias(cpu_model);
 if (p) {
-- 
2.36.1




Re: [PATCH v2] target/riscv: fix user-mode build issue because mhartid

2022-06-28 Thread Alistair Francis
On Tue, Jun 28, 2022 at 3:03 AM Rahul Pathak  wrote:
>
> mhartid csr is not available in user-mode code path and
> user-mode build fails because of its reference in
> riscv_cpu_realize function
>
> Commit causing the issue is currently in Alistair's
> riscv-to-apply.next branch and need to be squashed there.
>
> Fixes: 7ecee770d40 ("target/riscv: Force disable extensions if priv spec 
> version does not match")

Can you please re-send the original patch with the fix? I have removed
this patch from my tree

Alistair

>
> Signed-off-by: Rahul Pathak 
> ---
>
> Changes in V2:
> - remove the stray format specifier
> - add the Fixes tag and reference to external tree
> ---
>  target/riscv/cpu.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index e4ec05abf4..509923f15e 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -636,9 +636,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>  if (isa_ext_is_enabled(cpu, _edata_arr[i]) &&
>  (env->priv_ver < isa_edata_arr[i].min_version)) {
>  isa_ext_update_enabled(cpu, _edata_arr[i], false);
> +#ifndef CONFIG_USER_ONLY
>  warn_report("disabling %s extension for hart 0x%lx because "
>  "privilege spec version does not match",
>  isa_edata_arr[i].name, (unsigned long)env->mhartid);
> +#else
> +warn_report("disabling %s extension for hart because "
> +"privilege spec version does not match",
> +isa_edata_arr[i].name);
> +#endif
>  }
>  }
>
> --
> 2.34.1
>
>



Re: [PATCH] aspeed/smc: Fix potential overflow

2022-06-28 Thread Joel Stanley
On Tue, 28 Jun 2022 at 16:55, Cédric Le Goater  wrote:
>
> Coverity warns that "ssi_transfer(s->spi, 0U) << 8 * i" might overflow
> because the expression is evaluated using 32-bit arithmetic and then
> used in a context expecting a uint64_t.

Would it make sense to also place a limit on "size"?

assert(size < something)

>
> Fixes: Coverity CID 1487244
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/ssi/aspeed_smc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index d2b1dde604e3..26640539ae64 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -490,7 +490,7 @@ static uint64_t aspeed_smc_flash_read(void *opaque, 
> hwaddr addr, unsigned size)
>  switch (aspeed_smc_flash_mode(fl)) {
>  case CTRL_USERMODE:
>  for (i = 0; i < size; i++) {
> -ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
> +ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
>  }
>  break;
>  case CTRL_READMODE:
> @@ -499,7 +499,7 @@ static uint64_t aspeed_smc_flash_read(void *opaque, 
> hwaddr addr, unsigned size)
>  aspeed_smc_flash_setup(fl, addr);
>
>  for (i = 0; i < size; i++) {
> -ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
> +ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
>  }
>
>  aspeed_smc_flash_unselect(fl);
> --
> 2.35.3
>



Re: [PATCH v8 2/4] target/riscv: Set minumum priv spec version for mcountinhibit

2022-06-28 Thread Alistair Francis
On Tue, Jun 28, 2022 at 8:23 PM Anup Patel  wrote:
>
> The minimum priv spec versino for mcountinhibit to v1.11 so that it
> is not available for v1.10 (or lower).
>
> Fixes: eab4776b2bad ("target/riscv: Add support for hpmcounters/hpmevents")
> Signed-off-by: Anup Patel 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d65318dcc6..f7bfd2eab5 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3944,7 +3944,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> write_mhpmcounter },
>
>  [CSR_MCOUNTINHIBIT]  = { "mcountinhibit",  any, read_mcountinhibit,
> -write_mcountinhibit },
> +   write_mcountinhibit, .min_priv_ver = PRIV_VERSION_1_11_0  },
>
>  [CSR_MHPMEVENT3] = { "mhpmevent3", any,read_mhpmevent,
> write_mhpmevent },
> --
> 2.34.1
>
>



[PATCH v2 07/13] hw/i2c/aspeed: Add new-registers DMA slave mode RX support

2022-06-28 Thread Peter Delevoryas
This commit adds support for DMA RX in slave mode while using the new
register set in the AST2600 and AST1030. This patch also pretty much
assumes packet mode is enabled, I'm not sure if this will work in DMA
step mode.

This is particularly useful for testing IPMB exchanges between Zephyr
and external devices, which requires multi-master I2C support and DMA in
the new register mode, because the Zephyr drivers from Aspeed use DMA in
the new mode by default. The Zephyr drivers are also using packet mode.

The typical sequence of events for receiving data in DMA slave + packet
mode is that the Zephyr firmware will configure the slave address
register with an address to receive on and configure the bus's function
control register to enable master mode and slave mode simultaneously at
startup, before any transfers are initiated.

RX DMA is enabled in the slave mode command register, and the slave RX
DMA buffer address and slave RX DMA buffer length are set. TX DMA is not
covered in this patch.

When the Aspeed I2C controller receives data from some other I2C master,
it will reset the I2CS_DMA_LEN RX_LEN value to zero, then buffer
incoming data in the RX DMA buffer while incrementing the I2CC_DMA_ADDR
address counter and decrementing the I2CC_DMA_LEN counter. It will also
update the I2CS_DMA_LEN RX_LEN value along the way.

Once all the data has been received, the bus controller will raise an
interrupt indicating a packet command was completed, the slave address
matched, a normal stop condition was seen, and the transfer was an RX
operation.

If the master sent a NACK instead of a normal stop condition, or the
transfer timed out, then a slightly different set of interrupt status
values would be set. Those conditions are not handled in this commit.

The Zephyr firmware then collects data from the RX DMA buffer and clears
the status register by writing the PKT_MODE_EN bit to the status
register. In packet mode, clearing the packet mode interrupt enable bit
also clears most of the other interrupt bits automatically (except for a
few bits above it).

Note: if the master transmit or receive functions were in use
simultaneously with the slave mode receive functionality, then the
master mode functions may have raised the interrupt line for the bus
before the DMA slave transfer is complete. It's important to have the
slave's interrupt status register clear throughout the receive
operation, and if the slave attempts to raise the interrupt before the
master interrupt status is cleared, then it needs to re-raise the
interrupt once the master interrupt status is cleared. (And vice-versa).
That's why in this commit, when the master interrupt status is cleared
and the interrupt line is lowered, we call the slave interrupt _raise_
function, to see if the interrupt was pending. (And again, vice-versa).

Signed-off-by: Peter Delevoryas 
---
 hw/i2c/aspeed_i2c.c | 133 
 include/hw/i2c/aspeed_i2c.h |   3 +
 2 files changed, 124 insertions(+), 12 deletions(-)

diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index 8a8514586f..fc8b6b62cf 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -78,6 +78,18 @@ static inline void 
aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
 }
 }
 
+static inline void aspeed_i2c_bus_raise_slave_interrupt(AspeedI2CBus *bus)
+{
+AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
+
+if (!bus->regs[R_I2CS_INTR_STS]) {
+return;
+}
+
+bus->controller->intr_status |= 1 << bus->id;
+qemu_irq_raise(aic->bus_get_irq(bus));
+}
+
 static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
 unsigned size)
 {
@@ -140,8 +152,17 @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, 
hwaddr offset,
 case A_I2CM_DMA_LEN_STS:
 case A_I2CC_DMA_ADDR:
 case A_I2CC_DMA_LEN:
+
+case A_I2CS_DEV_ADDR:
+case A_I2CS_DMA_RX_ADDR:
+case A_I2CS_DMA_LEN:
+case A_I2CS_CMD:
+case A_I2CS_INTR_CTRL:
+case A_I2CS_DMA_LEN_STS:
 /* Value is already set, don't do anything. */
 break;
+case A_I2CS_INTR_STS:
+break;
 case A_I2CM_CMD:
 value = SHARED_FIELD_DP32(value, BUS_BUSY_STS, i2c_bus_busy(bus->bus));
 break;
@@ -547,12 +568,7 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, 
hwaddr offset,
 
 switch (offset) {
 case A_I2CC_FUN_CTRL:
-if (SHARED_FIELD_EX32(value, SLAVE_EN)) {
-qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
-  __func__);
-break;
-}
-bus->regs[R_I2CC_FUN_CTRL] = value & 0x007dc3ff;
+bus->regs[R_I2CC_FUN_CTRL] = value;
 break;
 case A_I2CC_AC_TIMING:
 bus->regs[R_I2CC_AC_TIMING] = value & 0x10ff;
@@ -580,6 +596,7 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, 
hwaddr offset,
 bus->controller->intr_status &= ~(1 << 

Re: [PATCH v2] target/riscv: fix user-mode build issue because mhartid

2022-06-28 Thread Bin Meng
Hi Rahul,

On Wed, Jun 29, 2022 at 10:07 AM Rahul Pathak  wrote:
>
> Hi Alistair
>
> My fix patch needs to be dropped since Anup took care of this issue
> in his yesterdays series update in this patch -
> [PATCH v8 4/4] target/riscv: Force disable extensions if priv spec
> version does not match

I don't understand. Each patch should keep bisectability.

This sounds like to me, that
[PATCH v8 4/4] target/riscv: Force disable extensions if priv spec
version does not match

has an issue that it does 2 things: one is to fix this bug, and the
other one is to force disable extensions.

Which is not right.

Regards,
Bin



[PATCH v2 13/13] hw/arm/aspeed: Add oby35-cl machine

2022-06-28 Thread Peter Delevoryas
The fby35 machine includes 4 server boards, each of which has a "bridge
interconnect" (BIC). This chip abstracts the pinout for the server board
into a single endpoint that the baseboard management controller (BMC)
can talk to using IPMB.

The codename for this board is oby35-cl, which means "OpenBIC
Yosemite3.5 CraterLake". There is also a variant of the BIC called
"OpenBIC Yosemite3.5 Baseboard", which is an image built to run from the
baseboard as a replacement for the BMC, that's not included here, but
that's why the "-cl" suffix is included.

A test image can be built from https://github.com/facebook/openbic using
the instructions in the README.md to build the meta-facebook/yv35-cl
recipe, or retrieved from my Github:

wget 
https://github.com/peterdelevoryas/OpenBIC/releases/download/oby35-cl-2022.17.01/Y35BCL.elf

And you can run this machine with the following command:

qemu-system-arm -machine oby35-cl -nographic -kernel Y35BCL.elf

It should produce output like the following:

[00:00:00.008,000]  usb_dc_aspeed: select ep[0x81] as IN endpoint
[00:00:00.009,000]  usb_dc_aspeed: select ep[0x82] as IN endpoint
[00:00:00.009,000]  usb_dc_aspeed: pre-selected ep[0x1] as IN endpoint
[00:00:00.009,000]  usb_dc_aspeed: pre-selected ep[0x2] as IN endpoint
[00:00:00.009,000]  usb_dc_aspeed: select ep[0x3] as OUT endpoint
*** Booting Zephyr OS build v00.01.05  ***
Hello, welcome to yv35 craterlake 2022.25.1
BIC class type(class-1), 1ou present status(0), 2ou present status(0), 
board revision(0x1)
[init_drive_type] sensor 0x14 post sensor read failed!
[init_drive_type] sensor 0x30 post sensor read failed!
[init_drive_type] sensor 0x39 post sensor read failed!
ipmi_init
[set_DC_status] gpio number(15) status(0)
[set_post_status] gpio number(1) status(1)

uart:~$ [00:00:00.249,000]  kcs_aspeed: KCS3: addr=0xca2, idr=0x2c, 
odr=0x38, str=0x44

[00:00:00.255,000]  spi_nor_multi_dev: [1216][spi1_cs0]SFDP magic 
 invalid
[00:00:00.255,000]  spi_nor_multi_dev: [1456]SFDP read failed: -22
[00:00:00.249,000]  kcs_aspeed: KCS3: addr=0xca2, idr=0x2c, odr=0x38, 
str=0x44

[00:00:00.255,000]  spi_nor_multi_dev: [1216][spi1_cs0]SFDP magic 
 invalid
[00:00:00.255,000]  spi_nor_multi_dev: [1456]SFDP read failed: -22
uart:~$ BIC Ready

Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed.c | 48 
 1 file changed, 48 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index a06f7c1b62..75971ef2ca 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -1429,6 +1429,50 @@ static void 
aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
 amc->macs_mask = 0;
 }
 
+static void oby35_cl_i2c_init(AspeedMachineState *bmc)
+{
+AspeedSoCState *soc = >soc;
+I2CBus *i2c[14];
+I2CBus *ssd[8];
+int i;
+
+for (i = 0; i < 14; i++) {
+i2c[i] = aspeed_i2c_get_bus(>i2c, i);
+}
+get_pca9548_channels(i2c[1], 0x71, ssd);
+
+i2c_slave_create_simple(i2c[0], "fby35-sb-cpld", 0x21);
+i2c_slave_create_simple(i2c[1], "tmp105", 0x48);
+i2c_slave_create_simple(i2c[1], "tmp105", 0x49);
+i2c_slave_create_simple(i2c[1], "tmp105", 0x4a);
+i2c_slave_create_simple(i2c[1], "adm1272", 0x40);
+i2c_slave_create_simple(i2c[1], "tmp421", 0x4c);
+i2c_slave_create_simple(i2c[2], "intel-me", 0x16);
+i2c_slave_create_simple(i2c[4], "isl69259", 0x76);
+i2c_slave_create_simple(i2c[4], "isl69259", 0x62);
+i2c_slave_create_simple(i2c[4], "isl69259", 0x60);
+
+for (int i = 0; i < 8; i++) {
+i2c_slave_create_simple(ssd[i], "tmp105", 0x6a);
+}
+
+/*
+ * FIXME: This should actually be the BMC, but both the ME and the BMC
+ * are IPMB endpoints, and the current ME implementation is generic
+ * enough to respond normally to some things.
+ */
+i2c_slave_create_simple(i2c[6], "intel-me", 0x10);
+}
+
+static void aspeed_machine_oby35_cl_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+mc->desc = "Meta Platforms fby35 CraterLake BIC (Cortex-M4)";
+amc->i2c_init = oby35_cl_i2c_init;
+}
+
 static const TypeInfo aspeed_machine_types[] = {
 {
 .name  = MACHINE_TYPE_NAME("palmetto-bmc"),
@@ -1494,6 +1538,10 @@ static const TypeInfo aspeed_machine_types[] = {
 .name   = MACHINE_TYPE_NAME("ast1030-evb"),
 .parent = TYPE_ASPEED_MACHINE,
 .class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
+}, {
+.name  = MACHINE_TYPE_NAME("oby35-cl"),
+.parent= MACHINE_TYPE_NAME("ast1030-evb"),
+.class_init= aspeed_machine_oby35_cl_class_init,
 }, {
 .name  = TYPE_ASPEED_MACHINE,
 .parent= TYPE_MACHINE,
-- 
2.30.2




Re: [PATCH 0/2] Decouple Xen-HVM from PIIX

2022-06-28 Thread B



Am 26. Juni 2022 09:46:54 UTC schrieb Bernhard Beschow :
>hw/i386/xen/xen-hvm.c contains logic which is PIIX-specific. This makes 
>xen-hvm.c depend on PIIX which can be avoided if PIIX logic was isolated in 
>PIIX itself.
>
>
>
>Bernhard Beschow (2):
>
>  hw/i386/xen/xen-hvm: Allow for stubbing xen_set_pci_link_route()
>
>  hw/i386/xen/xen-hvm: Inline xen_piix_pci_write_config_client() and
>
>remove it
>
>
>
> hw/i386/xen/xen-hvm.c   | 17 ++---
>
> hw/isa/piix3.c  | 15 ++-
>
> include/hw/xen/xen.h|  2 +-
>
> include/hw/xen/xen_common.h |  6 --
>
> stubs/xen-hw-stub.c |  3 ++-
>
> 5 files changed, 19 insertions(+), 24 deletions(-)
>
>
>
>-- >
>2.36.1
>
>
>

Hi Laurent,

would you like to queue this as well? Both patches have been reviewed at least 
once, piix twice. Or would you rather keep the review period open for longer?

Best regards,
Bernhard



Re: Slowness with multi-thread TCG?

2022-06-28 Thread Alex Bennée


Frederic Barrat  writes:

> On 28/06/2022 17:12, Alex Bennée wrote:
>> Frederic Barrat  writes:
>> 
>>> On 28/06/2022 13:25, Matheus K. Ferst wrote:
 On 27/06/2022 15:25, Frederic Barrat wrote:
> [ Resending as it was meant for the qemu-ppc list ]
>
> Hello,
>
> I've been looking at why our qemu powernv model is so slow when booting
> a compressed linux kernel, using multiple vcpus and multi-thread tcg.
> With only one vcpu, the decompression time of the kernel is what it is,
> but when using multiple vcpus, the decompression is actually slower. And
> worse: it degrades very fast with the number of vcpus!
>
> Rough measurement of the decompression time on a x86 laptop with
> multi-thread tcg and using the qemu powernv10 machine:
> 1 vcpu => 15 seconds
> 2 vcpus => 45 seconds
> 4 vcpus => 1 min 30 seconds
>
> Looking in details, when the firmware (skiboot) hands over execution to
> the linux kernel, there's one main thread entering some bootstrap code
> and running the kernel decompression algorithm. All the other secondary
> threads are left spinning in skiboot (1 thread per vpcu). So on paper,
> with multi-thread tcg and assuming the system has enough available
> physical cpus, I would expect the decompression to hog one physical cpu
> and the time needed to be constant, no matter the number of vpcus.
>> 
>
> Ironically, the behavior seen with single thread tcg is what I would
> expect: 1 thread decompressing in 15 seconds, all the other threads
> spinning for that same amount of time, all sharing the same physical
> cpu, so it all adds up nicely: I see 60 seconds decompression time with
> 4 vcpus (4x15). Which means multi-thread tcg is slower by quite a bit.
> And single thread tcg hogs one physical cpu of the laptop vs. 4 physical
> cpus for the slower multi-thread tcg.
>
> Does anybody have an idea of what might happen or have suggestion to
> keep investigating?
> Thanks for your help!
>
>     Fred
>
>
 Hi Frederic,
 I did some boot time tests recently and didn't notice this behavior.
 Could you share your QEMU command line with us? Did you build QEMU
 with any debug option or sanitizer enabled?
>>>
>>>
>>> You should be able to see it with:
>>>
>>> qemu-system-ppc64 -machine powernv10 -smp 4 -m 4G -nographic -bios
>>>  -kernel-initrd
>>>   -serial mon:stdio
>>>
>>>
>>> -smp is what matters.
>>>
>>> When simplifying the command line above, I noticed something
>>> interesting: the problem doesn't show using the skiboot.lid shipped
>>> with qemu! I'm using something closer to the current upstream head and
>>> the idle code (the for loop in my initial mail) had been reworked in
>>> between. So, clearly, the way the guest code is written matters. But
>>> that doesn't explain it.
>>>
>>> I'm using a kernel in debug mode, so it's pretty big and that's why I
>>> was using a compressed image. The compressed image is about 8 MB.

You can use split debug to avoid keeping the symbol in the final
vmimage. Or are there other debugging options turned on?

>> If the debug mode on PPC enables live patching of kernel functions
>> for
>> instrumentation that can certainly slow things down. You would see that
>> in tcg_optimize appearing in the perf log and "info jit" showing
>> constantly growing translation buffers.
>
>
> The part where I'm seeing the huge slowdown is not quite in kernel
> yet. Only one thread is in bootstrap code decompressing the real
> kernel. All the other threads are still spinning in firmware.
>
> Anyway, I've run perf. I couldn't figure out how to trigger the
> recording only around the decompression part with the slowdown. So I
> booted with 4 cpus to make it really slow, expecting the initial steps
> of the boot, which happen quickly enough, would be dwarfed by the time
> spent while one thread is decompressing the kernel (the part where I
> see the huge slowdown). I'd say the recording was taken with ~80% of
> the time in the interesting part. Here is what I got:
>
>
>   12,62%  qemu-system-ppc  [kernel.kallsyms]  [k]
>   syscall_exit_to_user_mode
>6,93%  qemu-system-ppc  [kernel.kallsyms]  [k]
>syscall_return_via_sysret
>5,64%  qemu-system-ppc  [kernel.kallsyms]  [k]
>__entry_text_start
>3,93%  qemu-system-ppc  libc.so.6  [.]
>pthread_mutex_lock@@GLIBC_2.2.5
>3,21%  qemu-system-ppc  libc.so.6  [.]
>__GI___pthread_mutex_unlock_usercnt
>3,12%  qemu-system-ppc  libc.so.6  [.]
>__GI___lll_lock_wait
>2,60%  qemu-system-ppc  qemu-system-ppc64  [.]
>cpu_handle_interrupt
>2,55%  qemu-system-ppc  [kernel.kallsyms]  [k] futex_wake
>2,43%  qemu-system-ppc  [kernel.kallsyms]  [k]
>native_queued_spin_lock_slowpath
>1,97%  qemu-system-ppc  [kernel.kallsyms]  

Re: [PATCH 1/2] hw/i386/xen/xen-hvm: Allow for stubbing xen_set_pci_link_route()

2022-06-28 Thread Laurent Vivier

Le 26/06/2022 à 11:46, Bernhard Beschow a écrit :

The only user of xen_set_pci_link_route() is
xen_piix_pci_write_config_client() which implements PIIX-specific logic in
the xen namespace. This makes xen-hvm depend on PIIX which could be
avoided if xen_piix_pci_write_config_client() was implemented in PIIX. In
order to do this, xen_set_pci_link_route() needs to be stubbable which
this patch addresses.

Signed-off-by: Bernhard Beschow 
---
  hw/i386/xen/xen-hvm.c   | 7 ++-
  include/hw/xen/xen.h| 1 +
  include/hw/xen/xen_common.h | 6 --
  stubs/xen-hw-stub.c | 5 +
  4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 0731f70410..204fda7949 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -161,11 +161,16 @@ void xen_piix_pci_write_config_client(uint32_t address, 
uint32_t val, int len)
  }
  v &= 0xf;
  if (((address + i) >= PIIX_PIRQCA) && ((address + i) <= PIIX_PIRQCD)) 
{
-xen_set_pci_link_route(xen_domid, address + i - PIIX_PIRQCA, v);
+xen_set_pci_link_route(address + i - PIIX_PIRQCA, v);
  }
  }
  }
  
+int xen_set_pci_link_route(uint8_t link, uint8_t irq)

+{
+return xendevicemodel_set_pci_link_route(xen_dmod, xen_domid, link, irq);
+}
+
  int xen_is_pirq_msi(uint32_t msi_data)
  {
  /* If vector is 0, the msi is remapped into a pirq, passed as
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 0f9962b1c1..13bffaef53 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -21,6 +21,7 @@ extern enum xen_mode xen_mode;
  extern bool xen_domid_restrict;
  
  int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);

+int xen_set_pci_link_route(uint8_t link, uint8_t irq);
  void xen_piix3_set_irq(void *opaque, int irq_num, int level);
  void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int 
len);
  void xen_hvm_inject_msi(uint64_t addr, uint32_t data);
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 179741ff79..77ce17d8a4 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -316,12 +316,6 @@ static inline int xen_set_pci_intx_level(domid_t domid, 
uint16_t segment,
   device, intx, level);
  }
  
-static inline int xen_set_pci_link_route(domid_t domid, uint8_t link,

- uint8_t irq)
-{
-return xendevicemodel_set_pci_link_route(xen_dmod, domid, link, irq);
-}
-
  static inline int xen_inject_msi(domid_t domid, uint64_t msi_addr,
   uint32_t msi_data)
  {
diff --git a/stubs/xen-hw-stub.c b/stubs/xen-hw-stub.c
index 15f3921a76..743967623f 100644
--- a/stubs/xen-hw-stub.c
+++ b/stubs/xen-hw-stub.c
@@ -23,6 +23,11 @@ void xen_piix_pci_write_config_client(uint32_t address, 
uint32_t val, int len)
  {
  }
  
+int xen_set_pci_link_route(uint8_t link, uint8_t irq)

+{
+return -1;
+}
+
  void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
  {
  }


Applied to my trivial-patches branch.

Thanks,
Laurent



[PATCH v2 01/13] hw/i2c/aspeed: Fix R_I2CD_FUN_CTRL reference

2022-06-28 Thread Peter Delevoryas
Very minor, doesn't effect functionality, but this is supposed to be
R_I2CC_FUN_CTRL (new-mode, not old-mode).

Fixes: ba2cccd64e9 ("aspeed: i2c: Add new mode support")
Signed-off-by: Peter Delevoryas 
---
 hw/i2c/aspeed_i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index 37ae1f2e04..ff33571954 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -552,7 +552,7 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, 
hwaddr offset,
   __func__);
 break;
 }
-bus->regs[R_I2CD_FUN_CTRL] = value & 0x007dc3ff;
+bus->regs[R_I2CC_FUN_CTRL] = value & 0x007dc3ff;
 break;
 case A_I2CC_AC_TIMING:
 bus->regs[R_I2CC_AC_TIMING] = value & 0x10ff;
-- 
2.30.2




[PATCH v2 12/13] hw/misc/aspeed: Add intel-me

2022-06-28 Thread Peter Delevoryas
The Intel Management Engine is an IPMI endpoint that responds to various
IPMI commands. In this commit, I've added some very basic functionality that
will respond back with a respond code of zero (success), while also setting
an appropriate response NetFN (request NetFN + 1), a matching command ID and
sequence number, and the 2 standard checksums. Other data is not provided,
but the model here could be extended to respond to more kinds of requests.

Signed-off-by: Peter Delevoryas 
---
 MAINTAINERS  |   1 +
 hw/misc/intel_me.c   | 162 +++
 hw/misc/meson.build  |   3 +-
 hw/misc/trace-events |   8 +++
 4 files changed, 173 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/intel_me.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3ffd473db1..3220644bb5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1068,6 +1068,7 @@ F: include/hw/net/ftgmac100.h
 F: docs/system/arm/aspeed.rst
 F: tests/qtest/*aspeed*
 F: hw/misc/fby35_sb_cpld.c
+F: hw/misc/intel_me.c
 
 NRF51
 M: Joel Stanley 
diff --git a/hw/misc/intel_me.c b/hw/misc/intel_me.c
new file mode 100644
index 00..933ae45101
--- /dev/null
+++ b/hw/misc/intel_me.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
+ *
+ * This code is licensed under the GPL version 2 or later. See the COPYING
+ * file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "hw/i2c/i2c.h"
+#include "trace.h"
+
+#define TYPE_INTEL_ME "intel-me"
+OBJECT_DECLARE_SIMPLE_TYPE(IntelMEState, INTEL_ME);
+
+struct IntelMEState {
+I2CSlave parent_obj;
+
+I2CBus *bus;
+QEMUBH *bh;
+int rx_len;
+int tx_len;
+int tx_pos;
+uint8_t rx_buf[512];
+uint8_t tx_buf[512];
+};
+
+static void intel_me_bh(void *opaque)
+{
+IntelMEState *s = opaque;
+I2CSlave *i2c = I2C_SLAVE(s);
+uint8_t target_addr;
+
+assert(s->bus->bh == s->bh);
+
+switch (s->tx_pos) {
+case 0:
+target_addr = s->tx_buf[s->tx_pos++];
+trace_intel_me_tx_start(i2c->address, target_addr);
+if (i2c_start_send_async(s->bus, target_addr) != 0) {
+break;
+}
+return;
+default:
+if (s->tx_pos >= s->tx_len) {
+break;
+}
+trace_intel_me_tx_data(i2c->address, s->tx_buf[s->tx_pos]);
+if (i2c_send_async(s->bus, s->tx_buf[s->tx_pos++]) != 0) {
+break;
+}
+return;
+}
+
+trace_intel_me_tx_end(i2c->address);
+i2c_end_transfer(s->bus);
+i2c_bus_release(s->bus);
+s->tx_len = 0;
+s->tx_pos = 0;
+memset(s->tx_buf, 0, sizeof(s->tx_buf));
+}
+
+static void intel_me_realize(DeviceState *dev, Error **errp)
+{
+IntelMEState *s = INTEL_ME(dev);
+
+s->bus = I2C_BUS(qdev_get_parent_bus(dev));
+s->bh = qemu_bh_new(intel_me_bh, s);
+s->rx_len = 0;
+s->tx_len = 0;
+s->tx_pos = 0;
+memset(s->rx_buf, 0, sizeof(s->rx_buf));
+memset(s->tx_buf, 0, sizeof(s->tx_buf));
+}
+
+static uint8_t checksum(const uint8_t *ptr, int len)
+{
+int sum = 0;
+
+for (int i = 0; i < len; i++) {
+sum += ptr[i];
+}
+
+return 256 - sum;
+}
+
+static int intel_me_i2c_event(I2CSlave *i2c, enum i2c_event event)
+{
+IntelMEState *s = INTEL_ME(i2c);
+
+switch (event) {
+case I2C_START_RECV:
+break;
+case I2C_START_SEND:
+trace_intel_me_rx_start(i2c->address);
+s->rx_len = 0;
+memset(s->rx_buf, 0, sizeof(s->rx_buf));
+break;
+case I2C_START_SEND_ASYNC:
+break;
+case I2C_FINISH:
+trace_intel_me_rx_end(i2c->address);
+s->tx_len = 10;
+s->tx_pos = 0;
+s->tx_buf[0] = s->rx_buf[2];
+s->tx_buf[1] = ((s->rx_buf[0] >> 2) + 1) << 2;
+s->tx_buf[2] = checksum(s->tx_buf, 2);
+s->tx_buf[3] = i2c->address;
+s->tx_buf[4] = (s->rx_buf[3] >> 2) << 2;
+s->tx_buf[5] = s->rx_buf[4];
+s->tx_buf[6] = 0x00;
+s->tx_buf[7] = 0x55;
+s->tx_buf[8] = 0x00;
+s->tx_buf[9] = checksum(s->tx_buf, s->tx_len - 1);
+s->tx_buf[0] >>= 1;
+i2c_bus_master(s->bus, s->bh);
+break;
+case I2C_NACK:
+break;
+}
+
+return 0;
+}
+
+static uint8_t intel_me_i2c_recv(I2CSlave *i2c)
+{
+return 0xff;
+}
+
+static int intel_me_i2c_send(I2CSlave *i2c, uint8_t data)
+{
+IntelMEState *s = INTEL_ME(i2c);
+
+trace_intel_me_rx_data(i2c->address, data);
+
+assert(s->rx_len < sizeof(s->rx_buf));
+s->rx_buf[s->rx_len++] = data;
+
+return 0;
+}
+
+static void intel_me_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+I2CSlaveClass *i2c = I2C_SLAVE_CLASS(oc);
+
+dc->realize = intel_me_realize;
+i2c->event = intel_me_i2c_event;
+i2c->recv = intel_me_i2c_recv;
+i2c->send = intel_me_i2c_send;
+}
+
+static const TypeInfo types[] = {
+{
+.name = 

Re: [PATCH v2] target/riscv: fix user-mode build issue because mhartid

2022-06-28 Thread Anup Patel
On Wed, Jun 29, 2022 at 9:27 AM Bin Meng  wrote:
>
> Hi Rahul,
>
> On Wed, Jun 29, 2022 at 10:07 AM Rahul Pathak  
> wrote:
> >
> > Hi Alistair
> >
> > My fix patch needs to be dropped since Anup took care of this issue
> > in his yesterdays series update in this patch -
> > [PATCH v8 4/4] target/riscv: Force disable extensions if priv spec
> > version does not match
>
> I don't understand. Each patch should keep bisectability.

The patches are already bisectable. There was a compile error until
v6 which was fixed in v7 by squashing this patch into PATCH4.

>
> This sounds like to me, that
> [PATCH v8 4/4] target/riscv: Force disable extensions if priv spec
> version does not match
>
> has an issue that it does 2 things: one is to fix this bug, and the
> other one is to force disable extensions.
>
> Which is not right.

The bug is fixed as a result of force disabling extensions which
don't match the priv spec version.

Regards,
Anup



Re: [RESEND PATCH] hw/dma: fix crash caused by race condition

2022-06-28 Thread Laurent Vivier

Le 06/05/2022 à 18:31, Tong Zhang a écrit :

assert(dbs->acb) is meant to check the return value of io_func per
documented in commit 6bee44ea34 ("dma: the passed io_func does not
return NULL"). However, there is a chance that after calling
aio_context_release(dbs->ctx); the dma_blk_cb function is called before
the assertion and dbs->acb is set to NULL again at line 121. Thus when
we run assert at line 181 it will fail.

   softmmu/dma-helpers.c:181: dma_blk_cb: Assertion `dbs->acb' failed.

Reported-by: Francisco Londono 
Signed-off-by: Tong Zhang 
---
  softmmu/dma-helpers.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
index 7820fec54c..cb81017928 100644
--- a/softmmu/dma-helpers.c
+++ b/softmmu/dma-helpers.c
@@ -177,8 +177,8 @@ static void dma_blk_cb(void *opaque, int ret)
  aio_context_acquire(dbs->ctx);
  dbs->acb = dbs->io_func(dbs->offset, >iov,
  dma_blk_cb, dbs, dbs->io_func_opaque);
-aio_context_release(dbs->ctx);
  assert(dbs->acb);
+aio_context_release(dbs->ctx);
  }
  
  static void dma_aio_cancel(BlockAIOCB *acb)


Fixes: 1919631e6b55 ("block: explicitly acquire aiocontext in bottom halves that 
need it")
Reviewed-by: Laurent Vivier 




Re: [PATCH v5 2/2] target/xtensa: Use semihosting/syscalls.h

2022-06-28 Thread Richard Henderson

On 6/28/22 19:08, Max Filippov wrote:

On Tue, Jun 28, 2022 at 4:43 AM Richard Henderson
 wrote:


This separates guest file descriptors from host file descriptors,
and utilizes shared infrastructure for integration with gdbstub.
Remove the xtensa custom console handing and rely on the
generic -semihosting-config handling of chardevs.

Signed-off-by: Richard Henderson 
---
  target/xtensa/cpu.h |   1 -
  hw/xtensa/sim.c |   3 -
  target/xtensa/xtensa-semi.c | 226 
  3 files changed, 50 insertions(+), 180 deletions(-)

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index ea66895e7f..99ac3efd71 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -612,7 +612,6 @@ void xtensa_translate_init(void);
  void **xtensa_get_regfile_by_name(const char *name, int entries, int bits);
  void xtensa_breakpoint_handler(CPUState *cs);
  void xtensa_register_core(XtensaConfigList *node);
-void xtensa_sim_open_console(Chardev *chr);
  void check_interrupts(CPUXtensaState *s);
  void xtensa_irq_init(CPUXtensaState *env);
  qemu_irq *xtensa_get_extints(CPUXtensaState *env);
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index 946c71cb5b..5cca6a170e 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -87,9 +87,6 @@ XtensaCPU *xtensa_sim_common_init(MachineState *machine)
  xtensa_create_memory_regions(, "xtensa.sysram",
   get_system_memory());
  }
-if (serial_hd(0)) {
-xtensa_sim_open_console(serial_hd(0));
-}


I've noticed that with this change '-serial stdio' and its variants are still
accepted in the command line, but now they do nothing.


Pardon?  They certainly will do something, via writes to the serial hardware.



This quiet
change of behavior is unfortunate. I wonder if it would be acceptable
to map the '-serial stdio' option in the presence of '-semihosting' to
something like '-chardev stdio,id=id1 -semihosting-config chardev=id1'?


I dunno.  I'm wary of having xtensa be unique here.  Alex, thoughts?


+if (get_user_u32(tv_sec, regs[5]) ||
+get_user_u32(tv_usec, regs[5])) {


get_user_u32(tv_usec, regs[5] + 4)?


Oops, yes.


-regs[2] = select(fd + 1,
- rq == SELECT_ONE_READ   ?  : NULL,
- rq == SELECT_ONE_WRITE  ?  : NULL,
- rq == SELECT_ONE_EXCEPT ?  : NULL,
- target_tv ?  : NULL);
-regs[3] = errno_h2g(errno);
+/* Poll timeout is in milliseconds; overflow to infinity. */
+msec = tv_sec * 1000ull + DIV_ROUND_UP(tv_usec, 1000ull);
+timeout = msec <= INT32_MAX ? msec : -1;
+} else {
+timeout = -1;
  }
+
+switch (regs[4]) {
+case SELECT_ONE_READ:
+events = G_IO_IN;
+break;
+case SELECT_ONE_WRITE:
+events = G_IO_OUT;
+break;
+case SELECT_ONE_EXCEPT:
+events = G_IO_PRI;
+break;
+default:
+xtensa_cb(cs, -1, EINVAL);


This doesn't match what there used to be: it was possible to call
select_one with rq other than SELECT_ONE_* and that would've
passed NULL for all fd sets in the select invocation turning it into
a sleep. It would return 0 after the timeout.


Hmm.  Is there any documentation of what it was *supposed* to do?  Passing rq == 
0xdeadbeef and expecting a specific behaviour seems odd.



r~




Re: [RFC v3 1/5] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-06-28 Thread Damien Le Moal
On 6/28/22 19:23, Sam Li wrote:
> Damien Le Moal  于2022年6月28日周二 17:05写道:
>>
>> On 6/28/22 17:05, Sam Li wrote:
>>> Stefan Hajnoczi  于2022年6月28日周二 14:52写道:

 On Mon, Jun 27, 2022 at 08:19:13AM +0800, Sam Li wrote:
> diff --git a/block/block-backend.c b/block/block-backend.c
> index e0e1aff4b1..786f964d02 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -1810,6 +1810,62 @@ int blk_flush(BlockBackend *blk)
>  return ret;
>  }
>
> +/*
> + * Return zone_report from BlockDriver. Offset can be any number within
> + * the zone size. No alignment for offset and len.

 What is the purpose of len? Is it the maximum number of zones to return
 in nr_zones[]?
>>>
>>> len is actually not used in bdrv_co_zone_report. It is needed by
>>> blk_check_byte_request.
>>
>> There is no IO buffer being passed. Only an array of zone descriptors and
>> an in-out number of zones. len is definitely not needed. Not sure what
>> blk_check_byte_request() is intended to check though.
> 
> Can I just remove len argument and blk_check_byte_request() if it's not used?

If it is unused, yes, you must remove it.

> 
>>
>>>
 How does the caller know how many zones were returned?
>>>
>>> nr_zones represents IN maximum and OUT actual. The caller will know by
>>> nr_zones which is changed in bdrv_co_zone_report. I'll add it in the
>>> comments.
>>>

> + */
> +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> +   int64_t len, int64_t *nr_zones,
> +   BlockZoneDescriptor *zones)
> +{
> +int ret;
> +BlockDriverState *bs;
> +IO_CODE();
> +
> +blk_inc_in_flight(blk); /* increase before waiting */
> +blk_wait_while_drained(blk);
> +bs = blk_bs(blk);
> +
> +ret = blk_check_byte_request(blk, offset, len);
> +if (ret < 0) {
> +return ret;
> +}
> +
> +bdrv_inc_in_flight(bs);

 The bdrv_inc/dec_in_flight() call should be inside
 bdrv_co_zone_report(). See bdrv_co_ioctl() for an example.

> +ret = bdrv_co_zone_report(blk->root->bs, offset, len,
> +  nr_zones, zones);
> +bdrv_dec_in_flight(bs);
> +blk_dec_in_flight(blk);
> +return ret;
> +}
> +
> +/*
> + * Return zone_mgmt from BlockDriver.

 Maybe this should be:

   Send a zone management command.
>>>
>>> Yes, it's more accurate.
>>>

> @@ -216,6 +217,11 @@ typedef struct RawPosixAIOData {
>  PreallocMode prealloc;
>  Error **errp;
>  } truncate;
> +struct {
> +int64_t *nr_zones;
> +BlockZoneDescriptor *zones;
> +} zone_report;
> +zone_op op;

 It's cleaner to put op inside a struct zone_mgmt so its purpose is
 self-explanatory:

   struct {
   zone_op op;
   } zone_mgmt;

> +static int handle_aiocb_zone_report(void *opaque) {
> +RawPosixAIOData *aiocb = opaque;
> +int fd = aiocb->aio_fildes;
> +int64_t *nr_zones = aiocb->zone_report.nr_zones;
> +BlockZoneDescriptor *zones = aiocb->zone_report.zones;
> +int64_t offset = aiocb->aio_offset;
> +int64_t len = aiocb->aio_nbytes;
>>
>> Since you have the zone array and number of zones (size of that array) I
>> really do not see why you need len.
>>
> +
> +struct blk_zone *blkz;
> +int64_t rep_size, nrz;
> +int ret, n = 0, i = 0;
> +
> +nrz = *nr_zones;
> +if (len == -1) {
> +return -errno;

 Where is errno set? Should this be an errno constant instead like
 -EINVAL?
>>>
>>> That's right! Noted.
>>>

> +}
> +rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct 
> blk_zone);
> +g_autofree struct blk_zone_report *rep = g_new(struct 
> blk_zone_report, nrz);

 g_new() looks incorrect. There should be 1 struct blk_zone_report
 followed by nrz struct blk_zone structs. Please use g_malloc(rep_size)
 instead.
>>>
>>> Yes! However, it still has a memory leak error when using g_autofree
>>> && g_malloc.
>>
>> That may be because you are changing the value of the rep pointer while
>> parsing the report ?
> 
> I am not sure it is the case. Can you show me some way to find the problem?

Not sure. I never used this g_malloc()/g_autofree() before so not sure how
it works. It may be that g_autofree() work only with g_new() ?
Could you try separating the declaration and allocation ? e.g.

Declare at the beginning of the function:
g_autofree struct blk_zone_report *rep = NULL;

And then when needed do:

rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct blk_zone);
rep = g_malloc(rep_size);

> 
> Thanks for reviewing!
> 
> 
>>
>>>

> 

[PATCH 0/2] vhost-user: Support vhost_dev_start

2022-06-28 Thread Yajun Wu
The motivation of adding vhost-user vhost_dev_start support is to
improve backend configuration speed and reduce live migration VM
downtime.

Today VQ configuration is issued one by one. For virtio net with
multi-queue support, backend needs to update RSS (Receive side
scaling) on every rx queue enable. Updating RSS is time-consuming
(typical time like 7ms).

Implement already defined vhost status and message in the vhost
specification [1].
(a) VHOST_USER_PROTOCOL_F_STATUS
(b) VHOST_USER_SET_STATUS
(c) VHOST_USER_GET_STATUS

Send message VHOST_USER_SET_STATUS with VIRTIO_CONFIG_S_DRIVER_OK for
device start and reset(0) for device stop.

On reception of the DRIVER_OK message, backend can apply the needed setting
only once (instead of incremental) and also utilize parallelism on enabling
queues.

This improves QEMU's live migration downtime with vhost user backend
implementation by great margin, specially for the large number of VQs of 64
from 800 msec to 250 msec.

Another change is to move the device start routines after finishing all the
necessary device and VQ configuration, further aligning to the virtio
specification for "device initialization sequence".

[1] https://qemu-project.gitlab.io/qemu/interop/vhost-user.html#introduction

Yajun Wu (2):
  vhost: Change the sequence of device start
  vhost-user: Support vhost_dev_start

 hw/block/vhost-user-blk.c | 18 +++-
 hw/net/vhost_net.c| 12 
 hw/virtio/vhost-user.c| 58 +++
 3 files changed, 75 insertions(+), 13 deletions(-)

-- 
2.30.2




[PATCH v2 09/13] hw/i2c/pmbus: Add read-only IC_DEVICE_ID support

2022-06-28 Thread Peter Delevoryas
Signed-off-by: Peter Delevoryas 
---
 hw/i2c/pmbus_device.c|  5 +
 hw/sensor/isl_pmbus_vr.c | 31 +++
 include/hw/i2c/pmbus_device.h|  1 +
 include/hw/sensor/isl_pmbus_vr.h |  1 +
 4 files changed, 38 insertions(+)

diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index efddc36fd9..82131fff85 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -984,6 +984,11 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
 }
 break;
 
+case PMBUS_IC_DEVICE_ID:
+pmbus_send(pmdev, pmdev->pages[index].ic_device_id,
+   sizeof(pmdev->pages[index].ic_device_id));
+break;
+
 case PMBUS_CLEAR_FAULTS:  /* Send Byte */
 case PMBUS_PAGE_PLUS_WRITE:   /* Block Write-only */
 case PMBUS_STORE_DEFAULT_ALL: /* Send Byte */
diff --git a/hw/sensor/isl_pmbus_vr.c b/hw/sensor/isl_pmbus_vr.c
index e11e028884..b12c46ab6d 100644
--- a/hw/sensor/isl_pmbus_vr.c
+++ b/hw/sensor/isl_pmbus_vr.c
@@ -218,6 +218,28 @@ static void isl_pmbus_vr_class_init(ObjectClass *klass, 
void *data,
 k->device_num_pages = pages;
 }
 
+static void isl69259_init(Object *obj)
+{
+static const uint8_t ic_device_id[] = {0x04, 0x00, 0x81, 0xD2, 0x49};
+PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+int i;
+
+raa22xx_init(obj);
+for (i = 0; i < pmdev->num_pages; i++) {
+memcpy(pmdev->pages[i].ic_device_id, ic_device_id,
+   sizeof(ic_device_id));
+}
+}
+
+static void isl69259_class_init(ObjectClass *klass, void *data)
+{
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+DeviceClass *dc = DEVICE_CLASS(klass);
+dc->desc = "Renesas ISL69259 Digital Multiphase Voltage Regulator";
+rc->phases.exit = isl_pmbus_vr_exit_reset;
+isl_pmbus_vr_class_init(klass, data, 2);
+}
+
 static void isl69260_class_init(ObjectClass *klass, void *data)
 {
 ResettableClass *rc = RESETTABLE_CLASS(klass);
@@ -245,6 +267,14 @@ static void raa229004_class_init(ObjectClass *klass, void 
*data)
 isl_pmbus_vr_class_init(klass, data, 2);
 }
 
+static const TypeInfo isl69259_info = {
+.name = TYPE_ISL69259,
+.parent = TYPE_PMBUS_DEVICE,
+.instance_size = sizeof(ISLState),
+.instance_init = isl69259_init,
+.class_init = isl69259_class_init,
+};
+
 static const TypeInfo isl69260_info = {
 .name = TYPE_ISL69260,
 .parent = TYPE_PMBUS_DEVICE,
@@ -271,6 +301,7 @@ static const TypeInfo raa228000_info = {
 
 static void isl_pmbus_vr_register_types(void)
 {
+type_register_static(_info);
 type_register_static(_info);
 type_register_static(_info);
 type_register_static(_info);
diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
index 0f4d6b3fad..aed7809841 100644
--- a/include/hw/i2c/pmbus_device.h
+++ b/include/hw/i2c/pmbus_device.h
@@ -407,6 +407,7 @@ typedef struct PMBusPage {
 uint16_t mfr_max_temp_1;   /* R/W word */
 uint16_t mfr_max_temp_2;   /* R/W word */
 uint16_t mfr_max_temp_3;   /* R/W word */
+uint8_t ic_device_id[16];  /* Read-Only block-read */
 } PMBusPage;
 
 /* State */
diff --git a/include/hw/sensor/isl_pmbus_vr.h b/include/hw/sensor/isl_pmbus_vr.h
index 3e47ff7e48..d501b3bc82 100644
--- a/include/hw/sensor/isl_pmbus_vr.h
+++ b/include/hw/sensor/isl_pmbus_vr.h
@@ -12,6 +12,7 @@
 #include "hw/i2c/pmbus_device.h"
 #include "qom/object.h"
 
+#define TYPE_ISL69259   "isl69259"
 #define TYPE_ISL69260   "isl69260"
 #define TYPE_RAA228000  "raa228000"
 #define TYPE_RAA229004  "raa229004"
-- 
2.30.2




[PATCH v2 04/13] hw/i2c: support multiple masters

2022-06-28 Thread Peter Delevoryas
From: Klaus Jensen 

Allow slaves to master the bus by registering a bottom halve. If the bus
is busy, the bottom half is queued up. When a slave has succesfully
mastered the bus, the bottom half is scheduled.

Signed-off-by: Klaus Jensen 
[ clg : - fixed typos in commit log ]
Message-Id: <20220601210831.67259-4-...@irrelevant.dk>
Signed-off-by: Cédric Le Goater 
---
 hw/i2c/core.c| 34 +-
 include/hw/i2c/i2c.h | 14 ++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index d0cb2d32fa..145dce6078 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -13,6 +13,7 @@
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
+#include "qemu/main-loop.h"
 #include "trace.h"
 
 #define I2C_BROADCAST 0x00
@@ -62,6 +63,7 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
 
 bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
 QLIST_INIT(>current_devs);
+QSIMPLEQ_INIT(>pending_masters);
 vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, _i2c_bus, bus);
 return bus;
 }
@@ -74,7 +76,7 @@ void i2c_slave_set_address(I2CSlave *dev, uint8_t address)
 /* Return nonzero if bus is busy.  */
 int i2c_bus_busy(I2CBus *bus)
 {
-return !QLIST_EMPTY(>current_devs);
+return !QLIST_EMPTY(>current_devs) || bus->bh;
 }
 
 bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
@@ -180,6 +182,26 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, bool 
is_recv)
: I2C_START_SEND);
 }
 
+void i2c_bus_master(I2CBus *bus, QEMUBH *bh)
+{
+if (i2c_bus_busy(bus)) {
+I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
+node->bh = bh;
+
+QSIMPLEQ_INSERT_TAIL(>pending_masters, node, entry);
+
+return;
+}
+
+bus->bh = bh;
+qemu_bh_schedule(bus->bh);
+}
+
+void i2c_bus_release(I2CBus *bus)
+{
+bus->bh = NULL;
+}
+
 int i2c_start_recv(I2CBus *bus, uint8_t address)
 {
 return i2c_do_start_transfer(bus, address, I2C_START_RECV);
@@ -206,6 +228,16 @@ void i2c_end_transfer(I2CBus *bus)
 g_free(node);
 }
 bus->broadcast = false;
+
+if (!QSIMPLEQ_EMPTY(>pending_masters)) {
+I2CPendingMaster *node = QSIMPLEQ_FIRST(>pending_masters);
+bus->bh = node->bh;
+
+QSIMPLEQ_REMOVE_HEAD(>pending_masters, entry);
+g_free(node);
+
+qemu_bh_schedule(bus->bh);
+}
 }
 
 int i2c_send(I2CBus *bus, uint8_t data)
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 5ca3b708c0..be8bb8b78a 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -69,13 +69,25 @@ struct I2CNode {
 QLIST_ENTRY(I2CNode) next;
 };
 
+typedef struct I2CPendingMaster I2CPendingMaster;
+
+struct I2CPendingMaster {
+QEMUBH *bh;
+QSIMPLEQ_ENTRY(I2CPendingMaster) entry;
+};
+
 typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList;
+typedef QSIMPLEQ_HEAD(I2CPendingMasters, I2CPendingMaster) I2CPendingMasters;
 
 struct I2CBus {
 BusState qbus;
 I2CNodeList current_devs;
+I2CPendingMasters pending_masters;
 uint8_t saved_address;
 bool broadcast;
+
+/* Set from slave currently mastering the bus. */
+QEMUBH *bh;
 };
 
 I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
@@ -117,6 +129,8 @@ int i2c_start_send(I2CBus *bus, uint8_t address);
 
 void i2c_end_transfer(I2CBus *bus);
 void i2c_nack(I2CBus *bus);
+void i2c_bus_master(I2CBus *bus, QEMUBH *bh);
+void i2c_bus_release(I2CBus *bus);
 int i2c_send(I2CBus *bus, uint8_t data);
 uint8_t i2c_recv(I2CBus *bus);
 bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
-- 
2.30.2




Re: [PATCH] target/ppc: Add error reporting when opening file fails

2022-06-28 Thread Markus Armbruster
jianchunfu  writes:

> Add error reporting before return when opening file fails.
>
> Signed-off-by: jianchunfu 
> ---
>  target/ppc/kvm.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index dc93b99189..ef9a871411 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -1798,6 +1798,7 @@ static int read_cpuinfo(const char *field, char *value, 
> int len)
>  
   static int read_cpuinfo(const char *field, char *value, int len)
   {
   FILE *f;
   int ret = -1;
   int field_len = strlen(field);
   char line[512];

>  f = fopen("/proc/cpuinfo", "r");
>  if (!f) {
> +fprintf(stderr, "Error opening /proc/cpuinfo: %s\n", 
> strerror(errno));
>  return -1;
>  }

   do {
   if (!fgets(line, sizeof(line), f)) {
   break;
   }
   if (!strncmp(line, field, field_len)) {
   pstrcpy(value, len, line);
   ret = 0;
   break;
   }
   } while (*line);

   fclose(f);

   return ret;
   }

This function now reports an error on one out of two failures.  The
caller can't tell whether it reported or not.

Please use error_report() for errors, warn_report() for warnings, and
info_report() for informational messages.

But is it an error?  Here's the only caller:

static uint32_t kvmppc_get_tbfreq_procfs(void)
{
char line[512];
char *ns;
uint32_t tbfreq_fallback = NANOSECONDS_PER_SECOND;
uint32_t tbfreq_procfs;

if (read_cpuinfo("timebase", line, sizeof(line))) {
--->return tbfreq_fallback;
}

ns = strchr(line, ':');
if (!ns) {
--->return tbfreq_fallback;
}

tbfreq_procfs = atoi(++ns);

/* 0 is certainly not acceptable by the guest, return fallback value */
--->return tbfreq_procfs ? tbfreq_procfs : tbfreq_fallback;
}

I marked the three spots that handle errors.  All quietly return
NANOSECONDS_PER_SECOND.  The caller can't tell whether that happened.

Reporting an error when we don't actually fail is confusing.  Better
would be something like "Can't open /proc/cpuinfo, assuming timebase X",
where X is the value you assume.

Reporting this only in one out of several cases where we assume feels
wrong.  If it's worth reporting in one case, why isn't it worth
reporting in the other cases?  Is it worth reporting?

Aside: the use of atoi() silently maps a timebase of 0 to
NANOSECONDS_PER_SECOND.  Not fond of this function.  Not your patch's
problem, of course.

>  
> @@ -1906,6 +1907,7 @@ static uint64_t kvmppc_read_int_dt(const char *filename)
>  
>  f = fopen(filename, "rb");
>  if (!f) {
> +fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno));
>  return -1;
>  }

Preexisting: this function returns -1 when fopen() fails, 0 when fread()
fails or read less data than expected.  Its caller
kvmppc_read_int_cpu_dt() passes on the return value.  However, it is
documented to return "0 if anything goes wrong".  Bug.  Not your patch's
fault, but it needs fixing.

Similar issue as above: you make the function emit an error message on
some, but not all failures.  If it's worth reporting in one case, why
isn't it worth reporting in the other cases?  Is it worth reporting?




Re: [RFC v3 1/5] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-06-28 Thread Sam Li
Damien Le Moal  于2022年6月29日周三 09:43写道:
>
> On 6/28/22 19:23, Sam Li wrote:
> > Damien Le Moal  于2022年6月28日周二 17:05写道:
> >>
> >> On 6/28/22 17:05, Sam Li wrote:
> >>> Stefan Hajnoczi  于2022年6月28日周二 14:52写道:
> 
>  On Mon, Jun 27, 2022 at 08:19:13AM +0800, Sam Li wrote:
> > diff --git a/block/block-backend.c b/block/block-backend.c
> > index e0e1aff4b1..786f964d02 100644
> > --- a/block/block-backend.c
> > +++ b/block/block-backend.c
> > @@ -1810,6 +1810,62 @@ int blk_flush(BlockBackend *blk)
> >  return ret;
> >  }
> >
> > +/*
> > + * Return zone_report from BlockDriver. Offset can be any number within
> > + * the zone size. No alignment for offset and len.
> 
>  What is the purpose of len? Is it the maximum number of zones to return
>  in nr_zones[]?
> >>>
> >>> len is actually not used in bdrv_co_zone_report. It is needed by
> >>> blk_check_byte_request.
> >>
> >> There is no IO buffer being passed. Only an array of zone descriptors and
> >> an in-out number of zones. len is definitely not needed. Not sure what
> >> blk_check_byte_request() is intended to check though.
> >
> > Can I just remove len argument and blk_check_byte_request() if it's not 
> > used?
>
> If it is unused, yes, you must remove it.
>
> >
> >>
> >>>
>  How does the caller know how many zones were returned?
> >>>
> >>> nr_zones represents IN maximum and OUT actual. The caller will know by
> >>> nr_zones which is changed in bdrv_co_zone_report. I'll add it in the
> >>> comments.
> >>>
> 
> > + */
> > +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> > +   int64_t len, int64_t *nr_zones,
> > +   BlockZoneDescriptor *zones)
> > +{
> > +int ret;
> > +BlockDriverState *bs;
> > +IO_CODE();
> > +
> > +blk_inc_in_flight(blk); /* increase before waiting */
> > +blk_wait_while_drained(blk);
> > +bs = blk_bs(blk);
> > +
> > +ret = blk_check_byte_request(blk, offset, len);
> > +if (ret < 0) {
> > +return ret;
> > +}
> > +
> > +bdrv_inc_in_flight(bs);
> 
>  The bdrv_inc/dec_in_flight() call should be inside
>  bdrv_co_zone_report(). See bdrv_co_ioctl() for an example.
> 
> > +ret = bdrv_co_zone_report(blk->root->bs, offset, len,
> > +  nr_zones, zones);
> > +bdrv_dec_in_flight(bs);
> > +blk_dec_in_flight(blk);
> > +return ret;
> > +}
> > +
> > +/*
> > + * Return zone_mgmt from BlockDriver.
> 
>  Maybe this should be:
> 
>    Send a zone management command.
> >>>
> >>> Yes, it's more accurate.
> >>>
> 
> > @@ -216,6 +217,11 @@ typedef struct RawPosixAIOData {
> >  PreallocMode prealloc;
> >  Error **errp;
> >  } truncate;
> > +struct {
> > +int64_t *nr_zones;
> > +BlockZoneDescriptor *zones;
> > +} zone_report;
> > +zone_op op;
> 
>  It's cleaner to put op inside a struct zone_mgmt so its purpose is
>  self-explanatory:
> 
>    struct {
>    zone_op op;
>    } zone_mgmt;
> 
> > +static int handle_aiocb_zone_report(void *opaque) {
> > +RawPosixAIOData *aiocb = opaque;
> > +int fd = aiocb->aio_fildes;
> > +int64_t *nr_zones = aiocb->zone_report.nr_zones;
> > +BlockZoneDescriptor *zones = aiocb->zone_report.zones;
> > +int64_t offset = aiocb->aio_offset;
> > +int64_t len = aiocb->aio_nbytes;
> >>
> >> Since you have the zone array and number of zones (size of that array) I
> >> really do not see why you need len.
> >>
> > +
> > +struct blk_zone *blkz;
> > +int64_t rep_size, nrz;
> > +int ret, n = 0, i = 0;
> > +
> > +nrz = *nr_zones;
> > +if (len == -1) {
> > +return -errno;
> 
>  Where is errno set? Should this be an errno constant instead like
>  -EINVAL?
> >>>
> >>> That's right! Noted.
> >>>
> 
> > +}
> > +rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct 
> > blk_zone);
> > +g_autofree struct blk_zone_report *rep = g_new(struct 
> > blk_zone_report, nrz);
> 
>  g_new() looks incorrect. There should be 1 struct blk_zone_report
>  followed by nrz struct blk_zone structs. Please use g_malloc(rep_size)
>  instead.
> >>>
> >>> Yes! However, it still has a memory leak error when using g_autofree
> >>> && g_malloc.
> >>
> >> That may be because you are changing the value of the rep pointer while
> >> parsing the report ?
> >
> > I am not sure it is the case. Can you show me some way to find the problem?
>
> Not sure. I never used this g_malloc()/g_autofree() before so not sure how
> it works. It may be that g_autofree() work only with g_new() ?
> 

[PATCH] target/ppc: Add error reporting when opening file fails

2022-06-28 Thread jianchunfu
Add error reporting before return when opening file fails.

Signed-off-by: jianchunfu 
---
 target/ppc/kvm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index dc93b99189..ef9a871411 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1798,6 +1798,7 @@ static int read_cpuinfo(const char *field, char *value, 
int len)
 
 f = fopen("/proc/cpuinfo", "r");
 if (!f) {
+fprintf(stderr, "Error opening /proc/cpuinfo: %s\n", strerror(errno));
 return -1;
 }
 
@@ -1906,6 +1907,7 @@ static uint64_t kvmppc_read_int_dt(const char *filename)
 
 f = fopen(filename, "rb");
 if (!f) {
+fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno));
 return -1;
 }
 
-- 
2.18.4






[PULL 30/60] semihosting: Split out semihost_sys_write

2022-06-28 Thread Richard Henderson
Split out the non-ARM specific portions of SYS_WRITE to a
reusable function.  This handles all GuestFD.  This removes
the last use of common_semi_syscall_len.

Note that gdb_do_syscall %x reads target_ulong, not int.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/syscalls.h |  6 
 semihosting/arm-compat-semi.c  | 52 +---
 semihosting/syscalls.c | 54 ++
 3 files changed, 61 insertions(+), 51 deletions(-)

diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 20da8138b0..2464467579 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -33,4 +33,10 @@ void semihost_sys_read(CPUState *cs, gdb_syscall_complete_cb 
complete,
 void semihost_sys_read_gf(CPUState *cs, gdb_syscall_complete_cb complete,
   GuestFD *gf, target_ulong buf, target_ulong len);
 
+void semihost_sys_write(CPUState *cs, gdb_syscall_complete_cb complete,
+int fd, target_ulong buf, target_ulong len);
+
+void semihost_sys_write_gf(CPUState *cs, gdb_syscall_complete_cb complete,
+   GuestFD *gf, target_ulong buf, target_ulong len);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 8da31d8507..d591fcd7c2 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -215,8 +215,6 @@ static inline uint32_t get_swi_errno(CPUState *cs)
 #endif
 }
 
-static target_ulong common_semi_syscall_len;
-
 static void common_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
 {
 if (err) {
@@ -230,9 +228,6 @@ static void common_semi_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
 /* Fixup syscalls that use nonstardard return conventions.  */
 target_ulong reg0 = common_semi_arg(cs, 0);
 switch (reg0) {
-case TARGET_SYS_WRITE:
-ret = common_semi_syscall_len - ret;
-break;
 case TARGET_SYS_SEEK:
 ret = 0;
 break;
@@ -294,30 +289,10 @@ common_semi_flen_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
  * do the work and return the required return value to the guest
  * via common_semi_cb.
  */
-typedef void sys_writefn(CPUState *cs, GuestFD *gf,
- target_ulong buf, uint32_t len);
 typedef void sys_isattyfn(CPUState *cs, GuestFD *gf);
 typedef void sys_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset);
 typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
 
-static void host_writefn(CPUState *cs, GuestFD *gf,
- target_ulong buf, uint32_t len)
-{
-CPUArchState *env = cs->env_ptr;
-uint32_t ret = 0;
-char *s = lock_user(VERIFY_READ, buf, len, 1);
-(void) env; /* Used in arm softmmu lock_user implicitly */
-if (s) {
-ret = write(gf->hostfd, s, len);
-unlock_user(s, buf, 0);
-if (ret == (uint32_t)-1) {
-ret = 0;
-}
-}
-/* Return bytes not written, on error as well. */
-common_semi_cb(cs, len - ret, 0);
-}
-
 static void host_isattyfn(CPUState *cs, GuestFD *gf)
 {
 common_semi_cb(cs, isatty(gf->hostfd), 0);
@@ -340,13 +315,6 @@ static void host_flenfn(CPUState *cs, GuestFD *gf)
 }
 }
 
-static void gdb_writefn(CPUState *cs, GuestFD *gf,
-target_ulong buf, uint32_t len)
-{
-common_semi_syscall_len = len;
-gdb_do_syscall(common_semi_cb, "write,%x,%x,%x", gf->hostfd, buf, len);
-}
-
 static void gdb_isattyfn(CPUState *cs, GuestFD *gf)
 {
 gdb_do_syscall(common_semi_cb, "isatty,%x", gf->hostfd);
@@ -380,13 +348,6 @@ static const uint8_t featurefile_data[] = {
 SH_EXT_EXIT_EXTENDED | SH_EXT_STDOUT_STDERR, /* Feature byte 0 */
 };
 
-static void staticfile_writefn(CPUState *cs, GuestFD *gf,
-   target_ulong buf, uint32_t len)
-{
-/* This fd can never be open for writing */
-common_semi_cb(cs, -1, EBADF);
-}
-
 static void staticfile_isattyfn(CPUState *cs, GuestFD *gf)
 {
 common_semi_cb(cs, 0, 0);
@@ -404,7 +365,6 @@ static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
 }
 
 typedef struct GuestFDFunctions {
-sys_writefn *writefn;
 sys_isattyfn *isattyfn;
 sys_seekfn *seekfn;
 sys_flenfn *flenfn;
@@ -412,19 +372,16 @@ typedef struct GuestFDFunctions {
 
 static const GuestFDFunctions guestfd_fns[] = {
 [GuestFDHost] = {
-.writefn = host_writefn,
 .isattyfn = host_isattyfn,
 .seekfn = host_seekfn,
 .flenfn = host_flenfn,
 },
 [GuestFDGDB] = {
-.writefn = gdb_writefn,
 .isattyfn = gdb_isattyfn,
 .seekfn = gdb_seekfn,
 .flenfn = gdb_flenfn,
 },
 [GuestFDStatic] = {
-.writefn = staticfile_writefn,
 .isattyfn = staticfile_isattyfn,
 .seekfn = staticfile_seekfn,
 .flenfn = staticfile_flenfn,
@@ -449,7 

Re: [PATCH 11/12] acpi/tests/bits: add README file for bits qtests

2022-06-28 Thread Ani Sinha
On Tue, Jun 28, 2022 at 3:56 AM Michael S. Tsirkin  wrote:
>
> On Mon, Jun 27, 2022 at 12:58:55PM +0530, Ani Sinha wrote:
> > The README file is added describing the directory structure and the purpose
> > of every file it contains. It also describes how to add new tests, make 
> > changes
> > to existing tests or bits config files or regenerate the bits software.
> >
> > Signed-off-by: Ani Sinha 
> > ---
> >  tests/qtest/acpi-bits/README | 168 +++
> >  1 file changed, 168 insertions(+)
> >  create mode 100644 tests/qtest/acpi-bits/README
> >
> > diff --git a/tests/qtest/acpi-bits/README b/tests/qtest/acpi-bits/README
> > new file mode 100644
> > index 00..97b15f1665
> > --- /dev/null
> > +++ b/tests/qtest/acpi-bits/README
> > @@ -0,0 +1,168 @@
> > +=
> > +ACPI/SMBIOS QTESTS USING BIOSBITS
> > +=
> > +
> > +Biosbits is a software written by Josh Triplett that can be downloaded by
> > +visiting https://biosbits.org/. The github codebase can be found here:
> > +https://github.com/biosbits/bits/tree/master. It is a software that 
> > exercizes
> > +the bios components such as acpi and smbios tables directly through acpica
> > +bios interpreter (a freely available C based library written by Intel,
> > +downloadable from https://acpica.org/ and is included with biosbits) 
> > without an
> > +operating system getting involved in between.
> > +There are several advantages to directly testing the bios in a real 
> > physical
> > +machine or VM as opposed to indirectly discovering bios issues through the
> > +operating system. For one thing, the OSes tend to hide bios problems from 
> > the
> > +end user. The other is that we have more control of what we wanted to test
> > +and how by directly using acpica interpreter on top of the bios on a 
> > running
> > +system. More details on the inspiration for developing biosbits and its 
> > real
> > +life uses can be found in (a) and (b).
> > +This directory contains QEMU qtests written in python that exercizes the 
> > QEMU
> > +bios components using biosbits and reports test failures.
> > +
> > +These tests use python virtual environment. In debian/ubuntu system, the 
> > tests
> > +would require python3.8-venv and python3-pip packages to be installed.
>
> Why do we mess with venv and pip? Certainly possible but
> what's wrong with using distro provided packages?

There are two things:
(a) We are already using pip and venv for our avocado based
integration tests. Look for TESTS_VENV_DIR in Makefile.include under
tests.
(b) the venv is primarily needed because I wanted to take advantage of
our rich python library that handles QEMU based machines. There are
python qtest libraries as well. These are well tested and used with
integration tests and I wanted to keep the test part of the code
simple by simply reusing them. however, in order to use them, we need
a venv environment within which these qemu python libraries are
installed. Integration tests does the same thing.

A note about my language of choice - python. I gave a lot of thoughts
on this. We do not do a lot of stuff here. All we do is:
(a) generate bits iso.
(b) spawn a QEMU vm with the iso which then runs a bunch of tests within the vm.
(c) collect and analyze logs.

We are not inspecting guest memory or manipulating devices or pci
buses. We do not need the power of C here. We need something that is
simple to write, easy to maintain and understand and can deal with
things like manipulating text files and configs easily. Python seems a
better fit for the role.

>
> > +
> > +A brief description of the contents of this directory follows:
> > +
> > +├── acpi-bits-test.py
> > +├── acpi-bits-test-venv.sh
> > +├── bits-config
> > +│   ├── bits-cfg.txt
> > +│   └── meson.build
> > +├── bits-tests
> > +│   ├── meson.build
> > +│   ├── smbios.py
> > +│   ├── smilatency.py
> > +│   ├── testacpi.py
> > +│   └── testcpuid.py
> > +├── meson.build
> > +├── prebuilt
> > +│   ├── bits-2095-grub.tar.gz
> > +│   ├── bits-2095.zip
> > +│   └── meson.build
> > +├── README
> > +└── requirements.txt
> > +
> > +acpi-bits:
> > + - acpi-bits-test-venv.sh: This is a shell script that sets up the virtual
> > +   environment necessary for the actual python test script to run. Amongst
> > +   other things, it makes sure that QEMU python library is available within
> > +   that venv so that QEMU machines can be forked. QEMU python library can 
> > be
> > +   found within python/ directory in QEMU source.
> > +   After setting up the virtual environment, it runs the python test script
> > +   from within that environment.
> > +   If you want to enable verbose mode only for bits test and run make 
> > check,
> > +   one trick is to add V=1 before the call to execute the python script in
> > +   this file.
> > + - acpi-bits-test.py: This is the main python 

[PULL 17/60] include/exec: Move gdb_stat and gdb_timeval to gdbstub.h

2022-06-28 Thread Richard Henderson
We have two copies of these structures, and require them
in semihosting/ going forward.

Reviewed-by: Alex Bennée 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 include/exec/gdbstub.h| 25 +
 target/m68k/m68k-semi.c   | 32 +---
 target/nios2/nios2-semi.c | 30 +++---
 3 files changed, 33 insertions(+), 54 deletions(-)

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 603e22ae80..7413ffeba2 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -19,6 +19,31 @@
 #define GDB_O_TRUNC   0x400
 #define GDB_O_EXCL0x800
 
+/* For gdb file i/o stat/fstat. */
+typedef uint32_t gdb_mode_t;
+typedef uint32_t gdb_time_t;
+
+struct gdb_stat {
+  uint32_tgdb_st_dev; /* device */
+  uint32_tgdb_st_ino; /* inode */
+  gdb_mode_t  gdb_st_mode;/* protection */
+  uint32_tgdb_st_nlink;   /* number of hard links */
+  uint32_tgdb_st_uid; /* user ID of owner */
+  uint32_tgdb_st_gid; /* group ID of owner */
+  uint32_tgdb_st_rdev;/* device type (if inode device) */
+  uint64_tgdb_st_size;/* total size, in bytes */
+  uint64_tgdb_st_blksize; /* blocksize for filesystem I/O */
+  uint64_tgdb_st_blocks;  /* number of blocks allocated */
+  gdb_time_t  gdb_st_atime;   /* time of last access */
+  gdb_time_t  gdb_st_mtime;   /* time of last modification */
+  gdb_time_t  gdb_st_ctime;   /* time of last change */
+} QEMU_PACKED;
+
+struct gdb_timeval {
+  gdb_time_t tv_sec;  /* second */
+  uint64_t tv_usec;   /* microsecond */
+} QEMU_PACKED;
+
 #ifdef NEED_CPU_H
 #include "cpu.h"
 
diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index 475a6b13b7..b886ebf714 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -45,30 +45,6 @@
 #define HOSTED_ISATTY 12
 #define HOSTED_SYSTEM 13
 
-typedef uint32_t gdb_mode_t;
-typedef uint32_t gdb_time_t;
-
-struct m68k_gdb_stat {
-  uint32_tgdb_st_dev; /* device */
-  uint32_tgdb_st_ino; /* inode */
-  gdb_mode_t  gdb_st_mode;/* protection */
-  uint32_tgdb_st_nlink;   /* number of hard links */
-  uint32_tgdb_st_uid; /* user ID of owner */
-  uint32_tgdb_st_gid; /* group ID of owner */
-  uint32_tgdb_st_rdev;/* device type (if inode device) */
-  uint64_tgdb_st_size;/* total size, in bytes */
-  uint64_tgdb_st_blksize; /* blocksize for filesystem I/O */
-  uint64_tgdb_st_blocks;  /* number of blocks allocated */
-  gdb_time_t  gdb_st_atime;   /* time of last access */
-  gdb_time_t  gdb_st_mtime;   /* time of last modification */
-  gdb_time_t  gdb_st_ctime;   /* time of last change */
-} QEMU_PACKED;
-
-struct gdb_timeval {
-  gdb_time_t tv_sec;  /* second */
-  uint64_t tv_usec;   /* microsecond */
-} QEMU_PACKED;
-
 static int translate_openflags(int flags)
 {
 int hf;
@@ -90,11 +66,13 @@ static int translate_openflags(int flags)
 
 static void translate_stat(CPUM68KState *env, target_ulong addr, struct stat 
*s)
 {
-struct m68k_gdb_stat *p;
+struct gdb_stat *p;
 
-if (!(p = lock_user(VERIFY_WRITE, addr, sizeof(struct m68k_gdb_stat), 0)))
+p = lock_user(VERIFY_WRITE, addr, sizeof(struct gdb_stat), 0);
+if (!p) {
 /* FIXME - should this return an error code? */
 return;
+}
 p->gdb_st_dev = cpu_to_be32(s->st_dev);
 p->gdb_st_ino = cpu_to_be32(s->st_ino);
 p->gdb_st_mode = cpu_to_be32(s->st_mode);
@@ -114,7 +92,7 @@ static void translate_stat(CPUM68KState *env, target_ulong 
addr, struct stat *s)
 p->gdb_st_atime = cpu_to_be32(s->st_atime);
 p->gdb_st_mtime = cpu_to_be32(s->st_mtime);
 p->gdb_st_ctime = cpu_to_be32(s->st_ctime);
-unlock_user(p, addr, sizeof(struct m68k_gdb_stat));
+unlock_user(p, addr, sizeof(struct gdb_stat));
 }
 
 static void m68k_semi_return_u32(CPUM68KState *env, uint32_t ret, uint32_t err)
diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
index 0eec1f9a1c..3e504a6c5f 100644
--- a/target/nios2/nios2-semi.c
+++ b/target/nios2/nios2-semi.c
@@ -47,30 +47,6 @@
 #define HOSTED_ISATTY 12
 #define HOSTED_SYSTEM 13
 
-typedef uint32_t gdb_mode_t;
-typedef uint32_t gdb_time_t;
-
-struct nios2_gdb_stat {
-  uint32_tgdb_st_dev; /* device */
-  uint32_tgdb_st_ino; /* inode */
-  gdb_mode_t  gdb_st_mode;/* protection */
-  uint32_tgdb_st_nlink;   /* number of hard links */
-  uint32_tgdb_st_uid; /* user ID of owner */
-  uint32_tgdb_st_gid; /* group ID of owner */
-  uint32_tgdb_st_rdev;/* device type (if inode device) */
-  uint64_tgdb_st_size;/* total size, in bytes */
-  uint64_tgdb_st_blksize; /* blocksize for filesystem I/O */
-  uint64_tgdb_st_blocks;  /* number of blocks allocated */
-  gdb_time_t  gdb_st_atime;   /* time of last access */
-  gdb_time_t  gdb_st_mtime;   /* time of last modification */
-  gdb_time_t  gdb_st_ctime;   /* time 

[PULL 28/60] semihosting: Split out semihost_sys_close

2022-06-28 Thread Richard Henderson
Split out the non-ARM specific portions of SYS_CLOSE to a
reusable function.  This handles all GuestFD.

Note that gdb_do_syscall %x reads target_ulong, not int.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/syscalls.h |  3 +++
 semihosting/arm-compat-semi.c  | 41 +
 semihosting/guestfd.c  |  7 -
 semihosting/syscalls.c | 47 ++
 4 files changed, 57 insertions(+), 41 deletions(-)

diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 991658bf79..00e718f11d 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -22,4 +22,7 @@ void semihost_sys_open(CPUState *cs, gdb_syscall_complete_cb 
complete,
target_ulong fname, target_ulong fname_len,
int gdb_flags, int mode);
 
+void semihost_sys_close(CPUState *cs, gdb_syscall_complete_cb complete,
+int fd);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 07960658d8..0cb3db2a1a 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -276,7 +276,6 @@ common_semi_flen_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
  * do the work and return the required return value to the guest
  * via common_semi_cb.
  */
-typedef void sys_closefn(CPUState *cs, GuestFD *gf);
 typedef void sys_writefn(CPUState *cs, GuestFD *gf,
  target_ulong buf, uint32_t len);
 typedef void sys_readfn(CPUState *cs, GuestFD *gf,
@@ -285,23 +284,6 @@ typedef void sys_isattyfn(CPUState *cs, GuestFD *gf);
 typedef void sys_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset);
 typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
 
-static void host_closefn(CPUState *cs, GuestFD *gf)
-{
-int ret;
-/*
- * Only close the underlying host fd if it's one we opened on behalf
- * of the guest in SYS_OPEN.
- */
-if (gf->hostfd == STDIN_FILENO ||
-gf->hostfd == STDOUT_FILENO ||
-gf->hostfd == STDERR_FILENO) {
-ret = 0;
-} else {
-ret = close(gf->hostfd);
-}
-common_semi_cb(cs, ret, ret ? errno : 0);
-}
-
 static void host_writefn(CPUState *cs, GuestFD *gf,
  target_ulong buf, uint32_t len)
 {
@@ -362,11 +344,6 @@ static void host_flenfn(CPUState *cs, GuestFD *gf)
 }
 }
 
-static void gdb_closefn(CPUState *cs, GuestFD *gf)
-{
-gdb_do_syscall(common_semi_cb, "close,%x", gf->hostfd);
-}
-
 static void gdb_writefn(CPUState *cs, GuestFD *gf,
 target_ulong buf, uint32_t len)
 {
@@ -414,12 +391,6 @@ static const uint8_t featurefile_data[] = {
 SH_EXT_EXIT_EXTENDED | SH_EXT_STDOUT_STDERR, /* Feature byte 0 */
 };
 
-static void staticfile_closefn(CPUState *cs, GuestFD *gf)
-{
-/* Nothing to do */
-common_semi_cb(cs, 0, 0);
-}
-
 static void staticfile_writefn(CPUState *cs, GuestFD *gf,
target_ulong buf, uint32_t len)
 {
@@ -468,7 +439,6 @@ static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
 }
 
 typedef struct GuestFDFunctions {
-sys_closefn *closefn;
 sys_writefn *writefn;
 sys_readfn *readfn;
 sys_isattyfn *isattyfn;
@@ -478,7 +448,6 @@ typedef struct GuestFDFunctions {
 
 static const GuestFDFunctions guestfd_fns[] = {
 [GuestFDHost] = {
-.closefn = host_closefn,
 .writefn = host_writefn,
 .readfn = host_readfn,
 .isattyfn = host_isattyfn,
@@ -486,7 +455,6 @@ static const GuestFDFunctions guestfd_fns[] = {
 .flenfn = host_flenfn,
 },
 [GuestFDGDB] = {
-.closefn = gdb_closefn,
 .writefn = gdb_writefn,
 .readfn = gdb_readfn,
 .isattyfn = gdb_isattyfn,
@@ -494,7 +462,6 @@ static const GuestFDFunctions guestfd_fns[] = {
 .flenfn = gdb_flenfn,
 },
 [GuestFDStatic] = {
-.closefn = staticfile_closefn,
 .writefn = staticfile_writefn,
 .readfn = staticfile_readfn,
 .isattyfn = staticfile_isattyfn,
@@ -586,13 +553,7 @@ void do_common_semihosting(CPUState *cs)
 
 case TARGET_SYS_CLOSE:
 GET_ARG(0);
-
-gf = get_guestfd(arg0);
-if (!gf) {
-goto do_badf;
-}
-guestfd_fns[gf->type].closefn(cs, gf);
-dealloc_guestfd(arg0);
+semihost_sys_close(cs, common_semi_cb, arg0);
 break;
 
 case TARGET_SYS_WRITEC:
diff --git a/semihosting/guestfd.c b/semihosting/guestfd.c
index 7ac2e147a8..e3122ebba9 100644
--- a/semihosting/guestfd.c
+++ b/semihosting/guestfd.c
@@ -49,6 +49,11 @@ int alloc_guestfd(void)
 return i;
 }
 
+static void do_dealloc_guestfd(GuestFD *gf)
+{
+gf->type = GuestFDUnused;
+}
+
 /*
  * Look up the guestfd in the data structure; return NULL
  * for out of bounds, but don't check whether the slot is unused.
@@ -119,5 +124,5 @@ void 

[PULL 31/60] semihosting: Bound length for semihost_sys_{read,write}

2022-06-28 Thread Richard Henderson
Fixes a minor bug in which a 64-bit guest on a 32-bit host could
truncate the length.  This would only ever cause a problem if
there were no bits set in the low 32, so that it truncates to 0.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 semihosting/syscalls.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 5cb12d6adc..eefbae74f1 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -283,6 +283,14 @@ void semihost_sys_close(CPUState *cs, 
gdb_syscall_complete_cb complete, int fd)
 void semihost_sys_read_gf(CPUState *cs, gdb_syscall_complete_cb complete,
   GuestFD *gf, target_ulong buf, target_ulong len)
 {
+/*
+ * Bound length for 64-bit guests on 32-bit hosts, not overlowing ssize_t.
+ * Note the Linux kernel does this with MAX_RW_COUNT, so it's not a bad
+ * idea to do this unconditionally.
+ */
+if (len > INT32_MAX) {
+len = INT32_MAX;
+}
 switch (gf->type) {
 case GuestFDGDB:
 gdb_read(cs, complete, gf, buf, len);
@@ -313,6 +321,14 @@ void semihost_sys_read(CPUState *cs, 
gdb_syscall_complete_cb complete,
 void semihost_sys_write_gf(CPUState *cs, gdb_syscall_complete_cb complete,
GuestFD *gf, target_ulong buf, target_ulong len)
 {
+/*
+ * Bound length for 64-bit guests on 32-bit hosts, not overlowing ssize_t.
+ * Note the Linux kernel does this with MAX_RW_COUNT, so it's not a bad
+ * idea to do this unconditionally.
+ */
+if (len > INT32_MAX) {
+len = INT32_MAX;
+}
 switch (gf->type) {
 case GuestFDGDB:
 gdb_write(cs, complete, gf, buf, len);
-- 
2.34.1




[PULL 03/12] vhost: add method vhost_set_vring_err

2022-06-28 Thread Michael S. Tsirkin
From: Konstantin Khlebnikov 

Kernel and user vhost may report virtqueue errors via eventfd.
This is only reliable way to get notification about protocol error.

Signed-off-by: Konstantin Khlebnikov 
Message-Id: <20220623161325.18813-2-vsement...@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Roman Kagan 
---
 include/hw/virtio/vhost-backend.h | 3 +++
 hw/virtio/vhost-backend.c | 7 +++
 hw/virtio/vhost-user.c| 6 ++
 3 files changed, 16 insertions(+)

diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index 81bf3109f8..eab46d7f0b 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -69,6 +69,8 @@ typedef int (*vhost_set_vring_kick_op)(struct vhost_dev *dev,
struct vhost_vring_file *file);
 typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev,
struct vhost_vring_file *file);
+typedef int (*vhost_set_vring_err_op)(struct vhost_dev *dev,
+  struct vhost_vring_file *file);
 typedef int (*vhost_set_vring_busyloop_timeout_op)(struct vhost_dev *dev,
struct vhost_vring_state 
*r);
 typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
@@ -145,6 +147,7 @@ typedef struct VhostOps {
 vhost_get_vring_base_op vhost_get_vring_base;
 vhost_set_vring_kick_op vhost_set_vring_kick;
 vhost_set_vring_call_op vhost_set_vring_call;
+vhost_set_vring_err_op vhost_set_vring_err;
 vhost_set_vring_busyloop_timeout_op vhost_set_vring_busyloop_timeout;
 vhost_set_features_op vhost_set_features;
 vhost_get_features_op vhost_get_features;
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 4de8b6b3b0..8e581575c9 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -146,6 +146,12 @@ static int vhost_kernel_set_vring_call(struct vhost_dev 
*dev,
 return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
 }
 
+static int vhost_kernel_set_vring_err(struct vhost_dev *dev,
+  struct vhost_vring_file *file)
+{
+return vhost_kernel_call(dev, VHOST_SET_VRING_ERR, file);
+}
+
 static int vhost_kernel_set_vring_busyloop_timeout(struct vhost_dev *dev,
struct vhost_vring_state *s)
 {
@@ -309,6 +315,7 @@ const VhostOps kernel_ops = {
 .vhost_get_vring_base = vhost_kernel_get_vring_base,
 .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
 .vhost_set_vring_call = vhost_kernel_set_vring_call,
+.vhost_set_vring_err = vhost_kernel_set_vring_err,
 .vhost_set_vring_busyloop_timeout =
 vhost_kernel_set_vring_busyloop_timeout,
 .vhost_set_features = vhost_kernel_set_features,
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 4b9be26e84..75b8df21a4 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1313,6 +1313,11 @@ static int vhost_user_set_vring_call(struct vhost_dev 
*dev,
 return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
 }
 
+static int vhost_user_set_vring_err(struct vhost_dev *dev,
+struct vhost_vring_file *file)
+{
+return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_ERR, file);
+}
 
 static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t 
*u64)
 {
@@ -2616,6 +2621,7 @@ const VhostOps user_ops = {
 .vhost_get_vring_base = vhost_user_get_vring_base,
 .vhost_set_vring_kick = vhost_user_set_vring_kick,
 .vhost_set_vring_call = vhost_user_set_vring_call,
+.vhost_set_vring_err = vhost_user_set_vring_err,
 .vhost_set_features = vhost_user_set_features,
 .vhost_get_features = vhost_user_get_features,
 .vhost_set_owner = vhost_user_set_owner,
-- 
MST




[PULL 51/60] semihosting: Use console_out_gf for SYS_WRITE0

2022-06-28 Thread Richard Henderson
Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index d61b773f98..1a1e2a6960 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -437,8 +437,15 @@ void do_common_semihosting(CPUState *cs)
 break;
 
 case TARGET_SYS_WRITE0:
-ret = qemu_semihosting_console_outs(env, args);
-common_semi_set_ret(cs, ret);
+{
+ssize_t len = target_strlen(args);
+if (len < 0) {
+common_semi_dead_cb(cs, -1, EFAULT);
+} else {
+semihost_sys_write_gf(cs, common_semi_dead_cb,
+  _out_gf, args, len);
+}
+}
 break;
 
 case TARGET_SYS_WRITE:
-- 
2.34.1




[PULL 35/60] semihosting: Split out semihost_sys_remove

2022-06-28 Thread Richard Henderson
Split out the non-ARM specific portions of SYS_REMOVE to a
reusable function.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/syscalls.h |  3 +++
 semihosting/arm-compat-semi.c  | 13 +--
 semihosting/syscalls.c | 40 ++
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 1ae5ba6716..748a4b5e47 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -49,4 +49,7 @@ void semihost_sys_flen(CPUState *cs, gdb_syscall_complete_cb 
fstat_cb,
gdb_syscall_complete_cb flen_cb,
int fd, target_ulong fstat_addr);
 
+void semihost_sys_remove(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong fname, target_ulong fname_len);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 68e13d9077..f4ce3851a4 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -484,18 +484,7 @@ void do_common_semihosting(CPUState *cs)
 case TARGET_SYS_REMOVE:
 GET_ARG(0);
 GET_ARG(1);
-if (use_gdb_syscalls()) {
-gdb_do_syscall(common_semi_cb, "unlink,%s",
-   arg0, (int)arg1 + 1);
-break;
-}
-s = lock_user_string(arg0);
-if (!s) {
-goto do_fault;
-}
-ret = remove(s);
-unlock_user(s, arg0, 0);
-common_semi_cb(cs, ret, ret ? errno : 0);
+semihost_sys_remove(cs, common_semi_cb, arg0, arg1 + 1);
 break;
 
 case TARGET_SYS_RENAME:
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index fff9550c89..5ec4e8f827 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -133,6 +133,18 @@ static void gdb_fstat(CPUState *cs, 
gdb_syscall_complete_cb complete,
 gdb_do_syscall(complete, "fstat,%x,%x", (target_ulong)gf->hostfd, addr);
 }
 
+static void gdb_remove(CPUState *cs, gdb_syscall_complete_cb complete,
+   target_ulong fname, target_ulong fname_len)
+{
+int len = validate_strlen(cs, fname, fname_len);
+if (len < 0) {
+complete(cs, -1, -len);
+return;
+}
+
+gdb_do_syscall(complete, "unlink,%s", fname, len);
+}
+
 /*
  * Host semihosting syscall implementations.
  */
@@ -277,6 +289,24 @@ static void host_flen(CPUState *cs, 
gdb_syscall_complete_cb complete,
 }
 }
 
+static void host_remove(CPUState *cs, gdb_syscall_complete_cb complete,
+target_ulong fname, target_ulong fname_len)
+{
+CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
+char *p;
+int ret;
+
+ret = validate_lock_user_string(, cs, fname, fname_len);
+if (ret < 0) {
+complete(cs, -1, -ret);
+return;
+}
+
+ret = remove(p);
+complete(cs, ret, ret ? errno : 0);
+unlock_user(p, fname, 0);
+}
+
 /*
  * Static file semihosting syscall implementations.
  */
@@ -522,3 +552,13 @@ void semihost_sys_flen(CPUState *cs, 
gdb_syscall_complete_cb fstat_cb,
 g_assert_not_reached();
 }
 }
+
+void semihost_sys_remove(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong fname, target_ulong fname_len)
+{
+if (use_gdb_syscalls()) {
+gdb_remove(cs, complete, fname, fname_len);
+} else {
+host_remove(cs, complete, fname, fname_len);
+}
+}
-- 
2.34.1




[PULL 07/60] semihosting: Simplify softmmu_lock_user_string

2022-06-28 Thread Richard Henderson
We are not currently bounding the search to the 1024 bytes
that we allocated, possibly overrunning the buffer.
Use softmmu_strlen_user to find the length and allocate the
correct size from the beginning.

Reviewed-by: Alex Bennée 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 semihosting/uaccess.c | 15 +++
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/semihosting/uaccess.c b/semihosting/uaccess.c
index d6997e3c65..8018828069 100644
--- a/semihosting/uaccess.c
+++ b/semihosting/uaccess.c
@@ -74,20 +74,11 @@ ssize_t softmmu_strlen_user(CPUArchState *env, target_ulong 
addr)
 
 char *softmmu_lock_user_string(CPUArchState *env, target_ulong addr)
 {
-/* TODO: Make this something that isn't fixed size.  */
-char *s = malloc(1024);
-size_t len = 0;
-
-if (!s) {
+ssize_t len = softmmu_strlen_user(env, addr);
+if (len < 0) {
 return NULL;
 }
-do {
-if (cpu_memory_rw_debug(env_cpu(env), addr++, s + len, 1, 0)) {
-free(s);
-return NULL;
-}
-} while (s[len++]);
-return s;
+return softmmu_lock_user(env, addr, len + 1, true);
 }
 
 void softmmu_unlock_user(CPUArchState *env, void *p,
-- 
2.34.1




[PULL 46/60] semihosting: Add GuestFDConsole

2022-06-28 Thread Richard Henderson
Add a GuestFDType for connecting to the semihosting console.
Hook up to read, write, isatty, and fstat syscalls.

Note that the arm-specific syscall flen cannot be applied
to the console, because the console is not a descriptor
exposed to the guest.

Reviewed-by: Luc Michel 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 include/semihosting/guestfd.h |  7 ++--
 semihosting/syscalls.c| 68 +++
 2 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/include/semihosting/guestfd.h b/include/semihosting/guestfd.h
index ef268abe85..a7ea1041ea 100644
--- a/include/semihosting/guestfd.h
+++ b/include/semihosting/guestfd.h
@@ -13,9 +13,10 @@
 
 typedef enum GuestFDType {
 GuestFDUnused = 0,
-GuestFDHost = 1,
-GuestFDGDB = 2,
-GuestFDStatic = 3,
+GuestFDHost,
+GuestFDGDB,
+GuestFDStatic,
+GuestFDConsole,
 } GuestFDType;
 
 /*
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 13a9bdeda6..9e499b1751 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -10,6 +10,7 @@
 #include "exec/gdbstub.h"
 #include "semihosting/guestfd.h"
 #include "semihosting/syscalls.h"
+#include "semihosting/console.h"
 #ifdef CONFIG_USER_ONLY
 #include "qemu.h"
 #else
@@ -577,6 +578,56 @@ static void staticfile_flen(CPUState *cs, 
gdb_syscall_complete_cb complete,
 complete(cs, gf->staticfile.len, 0);
 }
 
+/*
+ * Console semihosting syscall implementations.
+ */
+
+static void console_read(CPUState *cs, gdb_syscall_complete_cb complete,
+ GuestFD *gf, target_ulong buf, target_ulong len)
+{
+CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
+char *ptr;
+int ret;
+
+ptr = lock_user(VERIFY_WRITE, buf, len, 0);
+if (!ptr) {
+complete(cs, -1, EFAULT);
+return;
+}
+ret = qemu_semihosting_console_read(cs, ptr, len);
+complete(cs, ret, 0);
+unlock_user(ptr, buf, ret);
+}
+
+static void console_write(CPUState *cs, gdb_syscall_complete_cb complete,
+  GuestFD *gf, target_ulong buf, target_ulong len)
+{
+CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
+char *ptr = lock_user(VERIFY_READ, buf, len, 1);
+int ret;
+
+if (!ptr) {
+complete(cs, -1, EFAULT);
+return;
+}
+ret = qemu_semihosting_console_write(ptr, len);
+complete(cs, ret ? ret : -1, ret ? 0 : EIO);
+unlock_user(ptr, buf, ret);
+}
+
+static void console_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
+  GuestFD *gf, target_ulong addr)
+{
+static const struct stat tty_buf = {
+.st_mode = 020666,  /* S_IFCHR, ugo+rw */
+.st_rdev = 5,   /* makedev(5, 0) -- linux /dev/tty */
+};
+int ret;
+
+ret = copy_stat_to_user(cs, addr, _buf);
+complete(cs, ret ? -1 : 0, ret ? -ret : 0);
+}
+
 /*
  * Syscall entry points.
  */
@@ -608,6 +659,7 @@ void semihost_sys_close(CPUState *cs, 
gdb_syscall_complete_cb complete, int fd)
 host_close(cs, complete, gf);
 break;
 case GuestFDStatic:
+case GuestFDConsole:
 complete(cs, 0, 0);
 break;
 default:
@@ -637,6 +689,9 @@ void semihost_sys_read_gf(CPUState *cs, 
gdb_syscall_complete_cb complete,
 case GuestFDStatic:
 staticfile_read(cs, complete, gf, buf, len);
 break;
+case GuestFDConsole:
+console_read(cs, complete, gf, buf, len);
+break;
 default:
 g_assert_not_reached();
 }
@@ -672,6 +727,9 @@ void semihost_sys_write_gf(CPUState *cs, 
gdb_syscall_complete_cb complete,
 case GuestFDHost:
 host_write(cs, complete, gf, buf, len);
 break;
+case GuestFDConsole:
+console_write(cs, complete, gf, buf, len);
+break;
 case GuestFDStatic:
 /* Static files are never open for writing: EBADF. */
 complete(cs, -1, EBADF);
@@ -712,6 +770,9 @@ void semihost_sys_lseek(CPUState *cs, 
gdb_syscall_complete_cb complete,
 case GuestFDStatic:
 staticfile_lseek(cs, complete, gf, off, gdb_whence);
 break;
+case GuestFDConsole:
+complete(cs, -1, ESPIPE);
+break;
 default:
 g_assert_not_reached();
 }
@@ -735,6 +796,9 @@ void semihost_sys_isatty(CPUState *cs, 
gdb_syscall_complete_cb complete, int fd)
 case GuestFDStatic:
 complete(cs, 0, ENOTTY);
 break;
+case GuestFDConsole:
+complete(cs, 1, 0);
+break;
 default:
 g_assert_not_reached();
 }
@@ -760,6 +824,7 @@ void semihost_sys_flen(CPUState *cs, 
gdb_syscall_complete_cb fstat_cb,
 case GuestFDStatic:
 staticfile_flen(cs, flen_cb, gf);
 break;
+case GuestFDConsole:
 default:
 g_assert_not_reached();
 }
@@ -781,6 +846,9 @@ void semihost_sys_fstat(CPUState *cs, 
gdb_syscall_complete_cb complete,
 case GuestFDHost:
 host_fstat(cs, complete, gf, addr);
 break;
+case 

[PULL 57/60] target/mips: Add UHI errno values

2022-06-28 Thread Richard Henderson
>From the Unified Hosting Interface, MD01069 Reference Manual,
version 1.1.6, 06 July 2015.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/mips/tcg/sysemu/mips-semi.c | 40 ++
 1 file changed, 40 insertions(+)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index ac12c802a3..2a039baf4c 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -74,6 +74,46 @@ enum UHIOpenFlags {
 UHIOpen_EXCL   = 0x800
 };
 
+enum UHIErrno {
+UHI_EACCESS = 13,
+UHI_EAGAIN  = 11,
+UHI_EBADF   = 9,
+UHI_EBADMSG = 77,
+UHI_EBUSY   = 16,
+UHI_ECONNRESET  = 104,
+UHI_EEXIST  = 17,
+UHI_EFBIG   = 27,
+UHI_EINTR   = 4,
+UHI_EINVAL  = 22,
+UHI_EIO = 5,
+UHI_EISDIR  = 21,
+UHI_ELOOP   = 92,
+UHI_EMFILE  = 24,
+UHI_EMLINK  = 31,
+UHI_ENAMETOOLONG= 91,
+UHI_ENETDOWN= 115,
+UHI_ENETUNREACH = 114,
+UHI_ENFILE  = 23,
+UHI_ENOBUFS = 105,
+UHI_ENOENT  = 2,
+UHI_ENOMEM  = 12,
+UHI_ENOSPC  = 28,
+UHI_ENOSR   = 63,
+UHI_ENOTCONN= 128,
+UHI_ENOTDIR = 20,
+UHI_ENXIO   = 6,
+UHI_EOVERFLOW   = 139,
+UHI_EPERM   = 1,
+UHI_EPIPE   = 32,
+UHI_ERANGE  = 34,
+UHI_EROFS   = 30,
+UHI_ESPIPE  = 29,
+UHI_ETIMEDOUT   = 116,
+UHI_ETXTBSY = 26,
+UHI_EWOULDBLOCK = 11,
+UHI_EXDEV   = 18,
+};
+
 static int errno_mips(int host_errno)
 {
 /* Errno values taken from asm-mips/errno.h */
-- 
2.34.1




[PULL 60/60] target/nios2: Move nios2-semi.c to nios2_softmmu_ss

2022-06-28 Thread Richard Henderson
Semihosting is not enabled for nios2-linux-user.

Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/nios2/nios2-semi.c | 5 -
 target/nios2/meson.build  | 4 ++--
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
index bdf8849689..55061bb2dc 100644
--- a/target/nios2/nios2-semi.c
+++ b/target/nios2/nios2-semi.c
@@ -22,14 +22,9 @@
  */
 
 #include "qemu/osdep.h"
-
 #include "cpu.h"
 #include "exec/gdbstub.h"
-#if defined(CONFIG_USER_ONLY)
-#include "qemu.h"
-#else
 #include "semihosting/softmmu-uaccess.h"
-#endif
 #include "qemu/log.h"
 
 #define HOSTED_EXIT  0
diff --git a/target/nios2/meson.build b/target/nios2/meson.build
index 2bd60ba306..c6e2243cc3 100644
--- a/target/nios2/meson.build
+++ b/target/nios2/meson.build
@@ -1,7 +1,6 @@
 nios2_ss = ss.source_set()
 nios2_ss.add(files(
   'cpu.c',
-  'nios2-semi.c',
   'op_helper.c',
   'translate.c',
 ))
@@ -10,7 +9,8 @@ nios2_softmmu_ss = ss.source_set()
 nios2_softmmu_ss.add(files(
   'helper.c',
   'monitor.c',
-  'mmu.c'
+  'mmu.c',
+  'nios2-semi.c',
 ))
 
 target_arch += {'nios2': nios2_ss}
-- 
2.34.1




[PULL 11/60] semihosting: Clean up common_semi_flen_cb

2022-06-28 Thread Richard Henderson
Do not read from the gdb struct stat buffer if the callback is
reporting an error. Use common_semi_cb to finish returning results.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 88d6bdeaf2..cc13fcb0ef 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -346,15 +346,17 @@ static target_ulong common_semi_flen_buf(CPUState *cs)
 static void
 common_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
 {
-/* The size is always stored in big-endian order, extract
-   the value. We assume the size always fit in 32 bits.  */
-uint32_t size;
-cpu_memory_rw_debug(cs, common_semi_flen_buf(cs) + 32,
-(uint8_t *), 4, 0);
-size = be32_to_cpu(size);
-common_semi_set_ret(cs, size);
-errno = err;
-set_swi_errno(cs, -1);
+if (!err) {
+/*
+ * The size is always stored in big-endian order, extract
+ * the value. We assume the size always fit in 32 bits.
+ */
+uint32_t size;
+cpu_memory_rw_debug(cs, common_semi_flen_buf(cs) + 32,
+(uint8_t *), 4, 0);
+ret = be32_to_cpu(size);
+}
+common_semi_cb(cs, ret, err);
 }
 
 static int common_semi_open_guestfd;
-- 
2.34.1




[PULL 15/60] semihosting: Remove GDB_O_BINARY

2022-06-28 Thread Richard Henderson
The value is zero, and gdb always opens files in binary mode.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index cebbad2355..92c1375b15 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -92,21 +92,20 @@
 #define GDB_O_APPEND  0x008
 #define GDB_O_CREAT   0x200
 #define GDB_O_TRUNC   0x400
-#define GDB_O_BINARY  0
 
 static int gdb_open_modeflags[12] = {
 GDB_O_RDONLY,
-GDB_O_RDONLY | GDB_O_BINARY,
+GDB_O_RDONLY,
+GDB_O_RDWR,
 GDB_O_RDWR,
-GDB_O_RDWR | GDB_O_BINARY,
 GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC,
-GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
+GDB_O_WRONLY | GDB_O_CREAT | GDB_O_TRUNC,
+GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC,
 GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC,
-GDB_O_RDWR | GDB_O_CREAT | GDB_O_TRUNC | GDB_O_BINARY,
 GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND,
-GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY,
+GDB_O_WRONLY | GDB_O_CREAT | GDB_O_APPEND,
+GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND,
 GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND,
-GDB_O_RDWR | GDB_O_CREAT | GDB_O_APPEND | GDB_O_BINARY
 };
 
 static int open_modeflags[12] = {
-- 
2.34.1




[PULL 22/60] semihosting: Split common_semi_flen_buf per target

2022-06-28 Thread Richard Henderson
We already have some larger ifdef blocks for ARM and RISCV;
split out common_semi_stack_bottom per target.

Reviewed-by: Peter Maydell 
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 44 +--
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index d2ce214078..7550dce622 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -217,6 +217,13 @@ static inline bool is_64bit_semihosting(CPUArchState *env)
 {
 return is_a64(env);
 }
+
+static inline target_ulong common_semi_stack_bottom(CPUState *cs)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = >env;
+return is_a64(env) ? env->xregs[31] : env->regs[13];
+}
 #endif /* TARGET_ARM */
 
 #ifdef TARGET_RISCV
@@ -246,6 +253,13 @@ static inline bool is_64bit_semihosting(CPUArchState *env)
 {
 return riscv_cpu_mxl(env) != MXL_RV32;
 }
+
+static inline target_ulong common_semi_stack_bottom(CPUState *cs)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+return env->gpr[xSP];
+}
 #endif
 
 /*
@@ -301,31 +315,15 @@ static void common_semi_cb(CPUState *cs, target_ulong 
ret, target_ulong err)
 common_semi_set_ret(cs, ret);
 }
 
+/*
+ * Return an address in target memory of 64 bytes where the remote
+ * gdb should write its stat struct. (The format of this structure
+ * is defined by GDB's remote protocol and is not target-specific.)
+ * We put this on the guest's stack just below SP.
+ */
 static target_ulong common_semi_flen_buf(CPUState *cs)
 {
-target_ulong sp;
-#ifdef TARGET_ARM
-/* Return an address in target memory of 64 bytes where the remote
- * gdb should write its stat struct. (The format of this structure
- * is defined by GDB's remote protocol and is not target-specific.)
- * We put this on the guest's stack just below SP.
- */
-ARMCPU *cpu = ARM_CPU(cs);
-CPUARMState *env = >env;
-
-if (is_a64(env)) {
-sp = env->xregs[31];
-} else {
-sp = env->regs[13];
-}
-#endif
-#ifdef TARGET_RISCV
-RISCVCPU *cpu = RISCV_CPU(cs);
-CPURISCVState *env = >env;
-
-sp = env->gpr[xSP];
-#endif
-
+target_ulong sp = common_semi_stack_bottom(cs);
 return sp - 64;
 }
 
-- 
2.34.1




Re: [PATCH v2 4/4] hw/nvme: add new never_ready parameter to test the DNR bit

2022-06-28 Thread Klaus Jensen
On Jun 27 13:47, Niklas Cassel wrote:
> Since we verify that "ready_delay" parameter has to be smaller than CRWMT,
> we know that the namespace will always become ready.
> Therefore the "Namespace Not Ready" status code will never have the DNR
> bit set.
> 
> Add a new parameter "never_ready" that can be used to emulate a namespace
> that never gets ready, such that the DNR bit gets set after CRWMT amount
> of time.
> 
> Signed-off-by: Niklas Cassel 
> ---
>  hw/nvme/ctrl.c | 28 +++-
>  hw/nvme/ns.c   |  1 +
>  hw/nvme/nvme.h |  2 ++
>  3 files changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
> index 5404f67480..5f98d4778d 100644
> --- a/hw/nvme/ctrl.c
> +++ b/hw/nvme/ctrl.c
> @@ -6389,6 +6412,8 @@ static void nvme_ctrl_shutdown(NvmeCtrl *n)
>  
>  nvme_ns_shutdown(ns);
>  }
> +
> +n->cc_enable_timestamp = 0;

A shutdown does not disable the controller (in the case of QEMU), so
isn't this wrong?


signature.asc
Description: PGP signature


[PULL 25/60] semihosting: Use env more often in do_common_semihosting

2022-06-28 Thread Richard Henderson
We've already loaded cs->env_ptr into a local variable; use it.
Since env is unconditionally used, we don't need a dummy use.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 5e442e549d..adb4e5b581 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -553,7 +553,6 @@ void do_common_semihosting(CPUState *cs)
 GuestFD *gf;
 int64_t elapsed;
 
-(void) env; /* Used implicitly by arm lock_user macro */
 nr = common_semi_arg(cs, 0) & 0xU;
 args = common_semi_arg(cs, 1);
 
@@ -636,12 +635,12 @@ void do_common_semihosting(CPUState *cs)
 break;
 
 case TARGET_SYS_WRITEC:
-qemu_semihosting_console_outc(cs->env_ptr, args);
+qemu_semihosting_console_outc(env, args);
 common_semi_set_ret(cs, 0xdeadbeef);
 break;
 
 case TARGET_SYS_WRITE0:
-ret = qemu_semihosting_console_outs(cs->env_ptr, args);
+ret = qemu_semihosting_console_outs(env, args);
 common_semi_set_ret(cs, ret);
 break;
 
@@ -672,7 +671,7 @@ void do_common_semihosting(CPUState *cs)
 break;
 
 case TARGET_SYS_READC:
-ret = qemu_semihosting_console_inc(cs->env_ptr);
+ret = qemu_semihosting_console_inc(env);
 common_semi_set_ret(cs, ret);
 break;
 
-- 
2.34.1




Re: [PATCH 09/14] pmbus: Reset out buf after switching pages

2022-06-28 Thread Cédric Le Goater

On 6/27/22 21:55, Peter Delevoryas wrote:

Signed-off-by: Peter Delevoryas 


is that a bug ?



---
  hw/i2c/pmbus_device.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index 62885fa6a1..efddc36fd9 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -1088,6 +1088,7 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t 
*buf, uint8_t len)
  
  if (pmdev->code == PMBUS_PAGE) {

  pmdev->page = pmbus_receive8(pmdev);
+pmdev->out_buf_len = 0;
  return 0;
  }
  





Re: [PATCH 14/14] aspeed: Add I2C new register DMA slave mode support

2022-06-28 Thread Cédric Le Goater

On 6/28/22 00:27, Peter Delevoryas wrote:

Signed-off-by: Peter Delevoryas 


Some Intro would be welcome. Please move the patch after Klaus patches.

Thanks,

C.




---
  hw/i2c/aspeed_i2c.c | 133 
  include/hw/i2c/aspeed_i2c.h |   3 +
  2 files changed, 124 insertions(+), 12 deletions(-)

diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index 8a8514586f..fc8b6b62cf 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -78,6 +78,18 @@ static inline void 
aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
  }
  }
  
+static inline void aspeed_i2c_bus_raise_slave_interrupt(AspeedI2CBus *bus)

+{
+AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
+
+if (!bus->regs[R_I2CS_INTR_STS]) {
+return;
+}
+
+bus->controller->intr_status |= 1 << bus->id;
+qemu_irq_raise(aic->bus_get_irq(bus));
+}
+
  static uint64_t aspeed_i2c_bus_old_read(AspeedI2CBus *bus, hwaddr offset,
  unsigned size)
  {
@@ -140,8 +152,17 @@ static uint64_t aspeed_i2c_bus_new_read(AspeedI2CBus *bus, 
hwaddr offset,
  case A_I2CM_DMA_LEN_STS:
  case A_I2CC_DMA_ADDR:
  case A_I2CC_DMA_LEN:
+
+case A_I2CS_DEV_ADDR:
+case A_I2CS_DMA_RX_ADDR:
+case A_I2CS_DMA_LEN:
+case A_I2CS_CMD:
+case A_I2CS_INTR_CTRL:
+case A_I2CS_DMA_LEN_STS:
  /* Value is already set, don't do anything. */
  break;
+case A_I2CS_INTR_STS:
+break;
  case A_I2CM_CMD:
  value = SHARED_FIELD_DP32(value, BUS_BUSY_STS, 
i2c_bus_busy(bus->bus));
  break;
@@ -547,12 +568,7 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, 
hwaddr offset,
  
  switch (offset) {

  case A_I2CC_FUN_CTRL:
-if (SHARED_FIELD_EX32(value, SLAVE_EN)) {
-qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
-  __func__);
-break;
-}
-bus->regs[R_I2CC_FUN_CTRL] = value & 0x007dc3ff;
+bus->regs[R_I2CC_FUN_CTRL] = value;
  break;
  case A_I2CC_AC_TIMING:
  bus->regs[R_I2CC_AC_TIMING] = value & 0x10ff;
@@ -580,6 +596,7 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, 
hwaddr offset,
  bus->controller->intr_status &= ~(1 << bus->id);
  qemu_irq_lower(aic->bus_get_irq(bus));
  }
+aspeed_i2c_bus_raise_slave_interrupt(bus);
  break;
  }
  bus->regs[R_I2CM_INTR_STS] &= ~(value & 0xf007f07f);
@@ -668,15 +685,53 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, 
hwaddr offset,
  case A_I2CC_DMA_LEN:
  /* RO */
  break;
-case A_I2CS_DMA_LEN_STS:
-case A_I2CS_DMA_TX_ADDR:
-case A_I2CS_DMA_RX_ADDR:
  case A_I2CS_DEV_ADDR:
+bus->regs[R_I2CS_DEV_ADDR] = value;
+break;
+case A_I2CS_DMA_RX_ADDR:
+bus->regs[R_I2CS_DMA_RX_ADDR] = value;
+break;
+case A_I2CS_DMA_LEN:
+assert(FIELD_EX32(value, I2CS_DMA_LEN, TX_BUF_LEN) == 0);
+if (FIELD_EX32(value, I2CS_DMA_LEN, RX_BUF_LEN_W1T)) {
+ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN, RX_BUF_LEN,
+ FIELD_EX32(value, I2CS_DMA_LEN, RX_BUF_LEN));
+} else {
+bus->regs[R_I2CS_DMA_LEN] = value;
+}
+break;
+case A_I2CS_CMD:
+if (FIELD_EX32(value, I2CS_CMD, W1_CTRL)) {
+bus->regs[R_I2CS_CMD] |= value;
+} else {
+bus->regs[R_I2CS_CMD] = value;
+}
+i2c_slave_set_address(bus->slave, bus->regs[R_I2CS_DEV_ADDR]);
+break;
  case A_I2CS_INTR_CTRL:
+bus->regs[R_I2CS_INTR_CTRL] = value;
+break;
+
  case A_I2CS_INTR_STS:
-case A_I2CS_CMD:
-case A_I2CS_DMA_LEN:
-qemu_log_mask(LOG_UNIMP, "%s: Slave mode is not implemented\n",
+if (ARRAY_FIELD_EX32(bus->regs, I2CS_INTR_CTRL, PKT_CMD_DONE)) {
+if (ARRAY_FIELD_EX32(bus->regs, I2CS_INTR_STS, PKT_CMD_DONE) &&
+FIELD_EX32(value, I2CS_INTR_STS, PKT_CMD_DONE)) {
+bus->regs[R_I2CS_INTR_STS] &= 0xfffc;
+}
+} else {
+bus->regs[R_I2CS_INTR_STS] &= ~value;
+}
+if (!bus->regs[R_I2CS_INTR_STS]) {
+bus->controller->intr_status &= ~(1 << bus->id);
+qemu_irq_lower(aic->bus_get_irq(bus));
+}
+aspeed_i2c_bus_raise_interrupt(bus);
+break;
+case A_I2CS_DMA_LEN_STS:
+bus->regs[R_I2CS_DMA_LEN_STS] = 0;
+break;
+case A_I2CS_DMA_TX_ADDR:
+qemu_log_mask(LOG_UNIMP, "%s: Slave mode DMA TX is not implemented\n",
__func__);
  break;
  default:
@@ -1037,6 +1092,39 @@ static const TypeInfo aspeed_i2c_info = {
  .abstract   = true,
  };
  
+static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,

+  enum i2c_event 

[PULL 33/60] semihosting: Split out semihost_sys_isatty

2022-06-28 Thread Richard Henderson
Split out the non-ARM specific portions of SYS_ISTTY to a
reusable function.  This handles all GuestFD.

Add a common_semi_istty_cb helper to translate the Posix
error return, 0+ENOTTY, to the Arm semihosting not-a-file
success result.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/syscalls.h |  3 +++
 semihosting/arm-compat-semi.c  | 40 --
 semihosting/syscalls.c | 36 ++
 3 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 841a93d25b..c60ebafb85 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -42,4 +42,7 @@ void semihost_sys_write_gf(CPUState *cs, 
gdb_syscall_complete_cb complete,
 void semihost_sys_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
 int fd, int64_t off, int gdb_whence);
 
+void semihost_sys_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
+ int fd);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index a117d180bc..3cdc2b6efc 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -247,6 +247,19 @@ static void common_semi_rw_cb(CPUState *cs, target_ulong 
ret, target_ulong err)
 common_semi_set_ret(cs, arg2 - ret);
 }
 
+/*
+ * Convert from Posix ret+errno to Arm SYS_ISTTY return values.
+ * With gdbstub, err is only ever set for protocol errors to EIO.
+ */
+static void common_semi_istty_cb(CPUState *cs, target_ulong ret,
+ target_ulong err)
+{
+if (err) {
+ret = (err == ENOTTY ? 0 : -1);
+}
+common_semi_cb(cs, ret, err);
+}
+
 /*
  * SYS_SEEK returns 0 on success, not the resulting offset.
  */
@@ -291,14 +304,8 @@ common_semi_flen_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
  * do the work and return the required return value to the guest
  * via common_semi_cb.
  */
-typedef void sys_isattyfn(CPUState *cs, GuestFD *gf);
 typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
 
-static void host_isattyfn(CPUState *cs, GuestFD *gf)
-{
-common_semi_cb(cs, isatty(gf->hostfd), 0);
-}
-
 static void host_flenfn(CPUState *cs, GuestFD *gf)
 {
 struct stat buf;
@@ -310,11 +317,6 @@ static void host_flenfn(CPUState *cs, GuestFD *gf)
 }
 }
 
-static void gdb_isattyfn(CPUState *cs, GuestFD *gf)
-{
-gdb_do_syscall(common_semi_cb, "isatty,%x", gf->hostfd);
-}
-
 static void gdb_flenfn(CPUState *cs, GuestFD *gf)
 {
 gdb_do_syscall(common_semi_flen_cb, "fstat,%x,%x",
@@ -338,32 +340,23 @@ static const uint8_t featurefile_data[] = {
 SH_EXT_EXIT_EXTENDED | SH_EXT_STDOUT_STDERR, /* Feature byte 0 */
 };
 
-static void staticfile_isattyfn(CPUState *cs, GuestFD *gf)
-{
-common_semi_cb(cs, 0, 0);
-}
-
 static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
 {
 common_semi_cb(cs, gf->staticfile.len, 0);
 }
 
 typedef struct GuestFDFunctions {
-sys_isattyfn *isattyfn;
 sys_flenfn *flenfn;
 } GuestFDFunctions;
 
 static const GuestFDFunctions guestfd_fns[] = {
 [GuestFDHost] = {
-.isattyfn = host_isattyfn,
 .flenfn = host_flenfn,
 },
 [GuestFDGDB] = {
-.isattyfn = gdb_isattyfn,
 .flenfn = gdb_flenfn,
 },
 [GuestFDStatic] = {
-.isattyfn = staticfile_isattyfn,
 .flenfn = staticfile_flenfn,
 },
 };
@@ -489,12 +482,7 @@ void do_common_semihosting(CPUState *cs)
 
 case TARGET_SYS_ISTTY:
 GET_ARG(0);
-
-gf = get_guestfd(arg0);
-if (!gf) {
-goto do_badf;
-}
-guestfd_fns[gf->type].isattyfn(cs, gf);
+semihost_sys_isatty(cs, common_semi_istty_cb, arg0);
 break;
 
 case TARGET_SYS_SEEK:
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 9e3eb464b5..1f1baf7e2d 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -121,6 +121,12 @@ static void gdb_lseek(CPUState *cs, 
gdb_syscall_complete_cb complete,
(target_ulong)gf->hostfd, off, (target_ulong)gdb_whence);
 }
 
+static void gdb_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
+   GuestFD *gf)
+{
+gdb_do_syscall(complete, "isatty,%x", (target_ulong)gf->hostfd);
+}
+
 /*
  * Host semihosting syscall implementations.
  */
@@ -246,6 +252,13 @@ static void host_lseek(CPUState *cs, 
gdb_syscall_complete_cb complete,
 complete(cs, ret, err);
 }
 
+static void host_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
+GuestFD *gf)
+{
+int ret = isatty(gf->hostfd);
+complete(cs, ret, ret ? 0 : errno);
+}
+
 /*
  * Static file semihosting syscall implementations.
  */
@@ -437,3 +450,26 @@ void semihost_sys_lseek(CPUState *cs, 
gdb_syscall_complete_cb complete,
 g_assert_not_reached();
 }
 }
+
+void semihost_sys_isatty(CPUState *cs, 

Re: [PATCH 12/14] hw/misc: Add intel-me

2022-06-28 Thread Peter Delevoryas


> On Jun 27, 2022, at 11:58 PM, Cédric Le Goater  wrote:
> 
> On 6/28/22 00:27, Peter Delevoryas wrote:
>> Signed-off-by: Peter Delevoryas 
> 
> Intro ?

Yep, will do

> 
> I would rather have 2 patches, one for the slave model and one adding
> a device to the machine.

Got it, I’ll split it.

> 
> Please replace the printf with trace events.

Yeah sorry about that

> 
> Thanks,
> 
> C.
> 
>> ---
>>  hw/arm/aspeed.c |   1 +
>>  hw/misc/intel_me.c  | 176 
>>  hw/misc/meson.build |   3 +-
>>  3 files changed, 179 insertions(+), 1 deletion(-)
>>  create mode 100644 hw/misc/intel_me.c
>> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
>> index 2b9c1600c6..88e9a47dc2 100644
>> --- a/hw/arm/aspeed.c
>> +++ b/hw/arm/aspeed.c
>> @@ -1447,6 +1447,7 @@ static void oby35_cl_i2c_init(AspeedMachineState *bmc)
>>  i2c_slave_create_simple(i2c[1], "tmp105", 0x4a);
>>  i2c_slave_create_simple(i2c[1], "adm1272", 0x40);
>>  i2c_slave_create_simple(i2c[1], "tmp421", 0x4c);
>> +i2c_slave_create_simple(i2c[2], "intel-me", 0x16);
>>  i2c_slave_create_simple(i2c[4], "isl69259", 0x76);
>>  i2c_slave_create_simple(i2c[4], "isl69259", 0x62);
>>  i2c_slave_create_simple(i2c[4], "isl69259", 0x60);
>> diff --git a/hw/misc/intel_me.c b/hw/misc/intel_me.c
>> new file mode 100644
>> index 00..fdc9180c26
>> --- /dev/null
>> +++ b/hw/misc/intel_me.c
>> @@ -0,0 +1,176 @@
>> +/*
>> + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a 
>> copy
>> + * of this software and associated documentation files (the "Software"), to 
>> deal
>> + * in the Software without restriction, including without limitation the 
>> rights
>> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
>> + * copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included 
>> in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
>> OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
>> OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
>> FROM,
>> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
>> + * THE SOFTWARE.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qemu/main-loop.h"
>> +#include "hw/i2c/i2c.h"
>> +
>> +#define TYPE_INTEL_ME "intel-me"
>> +OBJECT_DECLARE_SIMPLE_TYPE(IntelMEState, INTEL_ME);
>> +
>> +#define printf(...)
>> +
>> +struct IntelMEState {
>> +I2CSlave parent_obj;
>> +
>> +I2CBus *bus;
>> +QEMUBH *bh;
>> +int rx_len;
>> +int tx_len;
>> +int tx_pos;
>> +uint8_t rx_buf[512];
>> +uint8_t tx_buf[512];
>> +};
>> +
>> +static void intel_me_bh(void *opaque)
>> +{
>> +IntelMEState *s = opaque;
>> +
>> +assert(s->bus->bh == s->bh);
>> +
>> +if (s->tx_pos == 0) {
>> +if (i2c_start_send_async(s->bus, s->tx_buf[s->tx_pos++]) != 0) {
>> +goto done;
>> +}
>> +return;
>> +}
>> +
>> +if (s->tx_pos < s->tx_len) {
>> +if (i2c_send_async(s->bus, s->tx_buf[s->tx_pos++]) != 0) {
>> +goto done;
>> +}
>> +return;
>> +}
>> +
>> +done:
>> +i2c_end_transfer(s->bus);
>> +i2c_bus_release(s->bus);
>> +s->tx_len = 0;
>> +s->tx_pos = 0;
>> +memset(s->tx_buf, 0, sizeof(s->tx_buf));
>> +}
>> +
>> +static void intel_me_realize(DeviceState *dev, Error **errp)
>> +{
>> +IntelMEState *s = INTEL_ME(dev);
>> +
>> +s->bus = I2C_BUS(qdev_get_parent_bus(dev));
>> +s->bh = qemu_bh_new(intel_me_bh, s);
>> +s->rx_len = 0;
>> +s->tx_len = 0;
>> +s->tx_pos = 0;
>> +memset(s->rx_buf, 0, sizeof(s->rx_buf));
>> +memset(s->tx_buf, 0, sizeof(s->tx_buf));
>> +}
>> +
>> +static uint8_t checksum(const uint8_t *ptr, int len)
>> +{
>> +int sum = 0;
>> +
>> +for (int i = 0; i < len; i++) {
>> +sum += ptr[i];
>> +}
>> +
>> +return 256 - sum;
>> +}
>> +
>> +static int intel_me_i2c_event(I2CSlave *i2c, enum i2c_event event)
>> +{
>> +IntelMEState *s = INTEL_ME(i2c);
>> +
>> +switch (event) {
>> +case I2C_START_RECV:
>> +break;
>> +case I2C_START_SEND:
>> +s->rx_len = 0;
>> +memset(s->rx_buf, 0, sizeof(s->rx_buf));
>> +break;
>> +case I2C_START_SEND_ASYNC:
>> +break;
>> +case I2C_FINISH:
>> +printf("IntelME rx: [");
>> +for (int i = 0; i < s->rx_len; i++) {
>> +if (i) {
>> +printf(", ");

Re: [RFC v3 1/5] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-06-28 Thread Sam Li
Stefan Hajnoczi  于2022年6月28日周二 14:52写道:
>
> On Mon, Jun 27, 2022 at 08:19:13AM +0800, Sam Li wrote:
> > diff --git a/block/block-backend.c b/block/block-backend.c
> > index e0e1aff4b1..786f964d02 100644
> > --- a/block/block-backend.c
> > +++ b/block/block-backend.c
> > @@ -1810,6 +1810,62 @@ int blk_flush(BlockBackend *blk)
> >  return ret;
> >  }
> >
> > +/*
> > + * Return zone_report from BlockDriver. Offset can be any number within
> > + * the zone size. No alignment for offset and len.
>
> What is the purpose of len? Is it the maximum number of zones to return
> in nr_zones[]?

len is actually not used in bdrv_co_zone_report. It is needed by
blk_check_byte_request.

> How does the caller know how many zones were returned?

nr_zones represents IN maximum and OUT actual. The caller will know by
nr_zones which is changed in bdrv_co_zone_report. I'll add it in the
comments.

>
> > + */
> > +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> > +   int64_t len, int64_t *nr_zones,
> > +   BlockZoneDescriptor *zones)
> > +{
> > +int ret;
> > +BlockDriverState *bs;
> > +IO_CODE();
> > +
> > +blk_inc_in_flight(blk); /* increase before waiting */
> > +blk_wait_while_drained(blk);
> > +bs = blk_bs(blk);
> > +
> > +ret = blk_check_byte_request(blk, offset, len);
> > +if (ret < 0) {
> > +return ret;
> > +}
> > +
> > +bdrv_inc_in_flight(bs);
>
> The bdrv_inc/dec_in_flight() call should be inside
> bdrv_co_zone_report(). See bdrv_co_ioctl() for an example.
>
> > +ret = bdrv_co_zone_report(blk->root->bs, offset, len,
> > +  nr_zones, zones);
> > +bdrv_dec_in_flight(bs);
> > +blk_dec_in_flight(blk);
> > +return ret;
> > +}
> > +
> > +/*
> > + * Return zone_mgmt from BlockDriver.
>
> Maybe this should be:
>
>   Send a zone management command.

Yes, it's more accurate.

>
> > @@ -216,6 +217,11 @@ typedef struct RawPosixAIOData {
> >  PreallocMode prealloc;
> >  Error **errp;
> >  } truncate;
> > +struct {
> > +int64_t *nr_zones;
> > +BlockZoneDescriptor *zones;
> > +} zone_report;
> > +zone_op op;
>
> It's cleaner to put op inside a struct zone_mgmt so its purpose is
> self-explanatory:
>
>   struct {
>   zone_op op;
>   } zone_mgmt;
>
> > +static int handle_aiocb_zone_report(void *opaque) {
> > +RawPosixAIOData *aiocb = opaque;
> > +int fd = aiocb->aio_fildes;
> > +int64_t *nr_zones = aiocb->zone_report.nr_zones;
> > +BlockZoneDescriptor *zones = aiocb->zone_report.zones;
> > +int64_t offset = aiocb->aio_offset;
> > +int64_t len = aiocb->aio_nbytes;
> > +
> > +struct blk_zone *blkz;
> > +int64_t rep_size, nrz;
> > +int ret, n = 0, i = 0;
> > +
> > +nrz = *nr_zones;
> > +if (len == -1) {
> > +return -errno;
>
> Where is errno set? Should this be an errno constant instead like
> -EINVAL?

That's right! Noted.

>
> > +}
> > +rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct 
> > blk_zone);
> > +g_autofree struct blk_zone_report *rep = g_new(struct blk_zone_report, 
> > nrz);
>
> g_new() looks incorrect. There should be 1 struct blk_zone_report
> followed by nrz struct blk_zone structs. Please use g_malloc(rep_size)
> instead.

Yes! However, it still has a memory leak error when using g_autofree
&& g_malloc.

>
> > +offset = offset / 512; /* get the unit of the start sector: sector 
> > size is 512 bytes. */
> > +printf("start to report zone with offset: 0x%lx\n", offset);
> > +
> > +blkz = (struct blk_zone *)(rep + 1);
> > +while (n < nrz) {
> > +memset(rep, 0, rep_size);
> > +rep->sector = offset;
> > +rep->nr_zones = nrz;
>
> What prevents zones[] overflowing? nrz isn't being reduced in the loop,
> so maybe the rep->nr_zones return value will eventually exceed the
> number of elements still available in zones[n..]?

I suppose the number of zones[] is restricted in the subsequent for
loop where zones[] copy one zone at a time as n increases. Even if
rep->zones exceeds the available room in zones[], the extra zone will
not be copied.

>
> > +static int handle_aiocb_zone_mgmt(void *opaque) {
> > +RawPosixAIOData *aiocb = opaque;
> > +int fd = aiocb->aio_fildes;
> > +int64_t offset = aiocb->aio_offset;
> > +int64_t len = aiocb->aio_nbytes;
> > +zone_op op = aiocb->op;
> > +
> > +struct blk_zone_range range;
> > +const char *ioctl_name;
> > +unsigned long ioctl_op;
> > +int64_t zone_size;
> > +int64_t zone_size_mask;
> > +int ret;
> > +
> > +ret = ioctl(fd, BLKGETZONESZ, _size);
>
> Can this value be stored in bs (maybe in BlockLimits) to avoid calling
> ioctl(BLKGETZONESZ) each time?

Yes, zone_size is in the zbd_dev field. I'll update BlockLimits after
I think through the configurations. In addition, it's a temporary

[PULL 50/60] semihosting: Remove qemu_semihosting_console_outc

2022-06-28 Thread Richard Henderson
This function has been replaced by *_write.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/console.h | 13 -
 linux-user/semihost.c | 16 
 semihosting/console.c | 18 --
 3 files changed, 47 deletions(-)

diff --git a/include/semihosting/console.h b/include/semihosting/console.h
index 6994f23c82..d6c1cc58ab 100644
--- a/include/semihosting/console.h
+++ b/include/semihosting/console.h
@@ -24,19 +24,6 @@
  */
 int qemu_semihosting_console_outs(CPUArchState *env, target_ulong s);
 
-/**
- * qemu_semihosting_console_outc:
- * @env: CPUArchState
- * @s: host address of null terminated guest string
- *
- * Send single character from guest memory to the debug console. This
- * may be the remote gdb session if a softmmu guest is currently being
- * debugged.
- *
- * Returns: nothing
- */
-void qemu_semihosting_console_outc(CPUArchState *env, target_ulong c);
-
 /**
  * qemu_semihosting_console_read:
  * @cs: CPUState
diff --git a/linux-user/semihost.c b/linux-user/semihost.c
index 871edf993a..f8bc8889f3 100644
--- a/linux-user/semihost.c
+++ b/linux-user/semihost.c
@@ -33,22 +33,6 @@ int qemu_semihosting_console_outs(CPUArchState *env, 
target_ulong addr)
 return len;
 }
 
-void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
-{
-char c;
-
-if (get_user_u8(c, addr)) {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "%s: passed inaccessible address " TARGET_FMT_lx,
-  __func__, addr);
-} else {
-if (write(STDERR_FILENO, , 1) != 1) {
-qemu_log_mask(LOG_UNIMP, "%s: unexpected write to stdout failure",
-  __func__);
-}
-}
-}
-
 /*
  * For linux-user we can safely block. However as we want to return as
  * soon as a character is read we need to tweak the termio to disable
diff --git a/semihosting/console.c b/semihosting/console.c
index 955880514e..fe7ee85137 100644
--- a/semihosting/console.c
+++ b/semihosting/console.c
@@ -96,24 +96,6 @@ int qemu_semihosting_console_outs(CPUArchState *env, 
target_ulong addr)
 return out;
 }
 
-void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
-{
-CPUState *cpu = env_cpu(env);
-uint8_t c;
-
-if (cpu_memory_rw_debug(cpu, addr, , 1, 0) == 0) {
-if (use_gdb_syscalls()) {
-gdb_do_syscall(semihosting_cb, "write,2,%x,%x", addr, 1);
-} else {
-qemu_semihosting_log_out((const char *) , 1);
-}
-} else {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "%s: passed inaccessible address " TARGET_FMT_lx,
-  __func__, addr);
-}
-}
-
 #define FIFO_SIZE   1024
 
 static int console_can_read(void *opaque)
-- 
2.34.1




[PULL 55/60] target/m68k: Make semihosting system only

2022-06-28 Thread Richard Henderson
While we had a call to do_m68k_semihosting in linux-user, it
wasn't actually reachable.  We don't include DISAS_INSN(halt)
as an instruction unless system mode.

Reviewed-by: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
 linux-user/m68k/cpu_loop.c |  5 -
 target/m68k/m68k-semi.c| 36 
 target/m68k/meson.build|  6 --
 3 files changed, 4 insertions(+), 43 deletions(-)

diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index 3d3033155f..caead1cb74 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -36,11 +36,6 @@ void cpu_loop(CPUM68KState *env)
 process_queued_cpu_work(cs);
 
 switch(trapnr) {
-case EXCP_HALT_INSN:
-/* Semihosing syscall.  */
-env->pc += 4;
-do_m68k_semihosting(env, env->dregs[0]);
-break;
 case EXCP_ILLEGAL:
 case EXCP_LINEA:
 case EXCP_LINEF:
diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index 37b409b0b9..d0697ddbd1 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -21,13 +21,8 @@
 
 #include "cpu.h"
 #include "exec/gdbstub.h"
-#if defined(CONFIG_USER_ONLY)
-#include "qemu.h"
-#define SEMIHOSTING_HEAP_SIZE (128 * 1024 * 1024)
-#else
 #include "semihosting/softmmu-uaccess.h"
 #include "hw/boards.h"
-#endif
 #include "qemu/log.h"
 
 #define HOSTED_EXIT  0
@@ -377,43 +372,12 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 }
 break;
 case HOSTED_INIT_SIM:
-#if defined(CONFIG_USER_ONLY)
-{
-CPUState *cs = env_cpu(env);
-TaskState *ts = cs->opaque;
-/* Allocate the heap using sbrk.  */
-if (!ts->heap_limit) {
-abi_ulong ret;
-uint32_t size;
-uint32_t base;
-
-base = do_brk(0);
-size = SEMIHOSTING_HEAP_SIZE;
-/* Try a big heap, and reduce the size if that fails.  */
-for (;;) {
-ret = do_brk(base + size);
-if (ret >= (base + size)) {
-break;
-}
-size >>= 1;
-}
-ts->heap_limit = base + size;
-}
-/*
- * This call may happen before we have writable memory, so return
- * values directly in registers.
- */
-env->dregs[1] = ts->heap_limit;
-env->aregs[7] = ts->stack_base;
-}
-#else
 /*
  * FIXME: This is wrong for boards where RAM does not start at
  * address zero.
  */
 env->dregs[1] = current_machine->ram_size;
 env->aregs[7] = current_machine->ram_size;
-#endif
 return;
 default:
 cpu_abort(env_cpu(env), "Unsupported semihosting syscall %d\n", nr);
diff --git a/target/m68k/meson.build b/target/m68k/meson.build
index 05cd9fbd1e..27d2d7ba87 100644
--- a/target/m68k/meson.build
+++ b/target/m68k/meson.build
@@ -4,14 +4,16 @@ m68k_ss.add(files(
   'fpu_helper.c',
   'gdbstub.c',
   'helper.c',
-  'm68k-semi.c',
   'op_helper.c',
   'softfloat.c',
   'translate.c',
 ))
 
 m68k_softmmu_ss = ss.source_set()
-m68k_softmmu_ss.add(files('monitor.c'))
+m68k_softmmu_ss.add(files(
+  'm68k-semi.c',
+  'monitor.c'
+))
 
 target_arch += {'m68k': m68k_ss}
 target_softmmu_arch += {'m68k': m68k_softmmu_ss}
-- 
2.34.1




Re: [PULL 22/33] migration: remove the QEMUFileOps 'get_buffer' callback

2022-06-28 Thread Daniel P . Berrangé
On Mon, Jun 27, 2022 at 04:32:00PM -0400, Peter Xu wrote:
> On Mon, Jun 27, 2022 at 04:03:09PM +0100, Daniel P. Berrangé wrote:
> > On Wed, Jun 22, 2022 at 03:34:52PM -0400, Peter Xu wrote:
> > > On Wed, Jun 22, 2022 at 07:39:06PM +0100, Dr. David Alan Gilbert (git) 
> > > wrote:
> > > > diff --git a/migration/qemu-file.c b/migration/qemu-file.c
> > > > index 74f919de67..e206b05550 100644
> > > > --- a/migration/qemu-file.c
> > > > +++ b/migration/qemu-file.c
> > > > @@ -377,8 +377,22 @@ static ssize_t qemu_fill_buffer(QEMUFile *f)
> > > >  return 0;
> > > >  }
> > > >  
> > > > -len = f->ops->get_buffer(f->ioc, f->buf + pending, 
> > > > f->total_transferred,
> > > > - IO_BUF_SIZE - pending, _error);
> > > > +do {
> > > > +len = qio_channel_read(f->ioc,
> > > > +   (char *)f->buf + pending,
> > > > +   IO_BUF_SIZE - pending,
> > > > +   _error);
> > > > +if (len == QIO_CHANNEL_ERR_BLOCK) {
> > > > +if (qemu_in_coroutine()) {
> > > > +qio_channel_yield(f->ioc, G_IO_IN);
> > > > +} else {
> > > > +qio_channel_wait(f->ioc, G_IO_IN);
> > > > +}
> > > > +} else if (len < 0) {
> > > > +len = EIO;
> > > 
> > > This should be -EIO.
> > > 
> > > > +}
> > > > +} while (len == QIO_CHANNEL_ERR_BLOCK);
> > > 
> > > It's failing only with the new TLS test I added for postcopy somehow (at
> > > least /x86_64/migration/postcopy/recovery/tls).. I also verified after the
> > > change it'll work again.
> > 
> > Assuming you can still reproduce the pre-existing flaw, can you capture
> > a stack trace when it hangs.   I'm wondering if it is a sign that the
> > migration is not converging when using TLS under certain load conditions,
> > because the test waits forever for converge.
> 
> Yes it is, and it reproduces here every time.  It hangs at:
> 
>  if (!got_stop) {
>  qtest_qmp_eventwait(from, "STOP");
>  }
> 
> > 
> > Also what scenario are you running in ? Bare metal or a VM, and what
> > host arch ? Wondering if the machine is at all slow, or for example
> > missing AES hardware acceleration or some such thing.
> 
> It's Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz, 40 cores.
> 
> It'll pass after I modify the downtime:
> 
>   migrate_set_parameter_int(from, "downtime-limit", 10);
> 
> And with QTEST_LOG=1 I found that the bw is indeed low, ~700mbps.

Good, this all makes sense, and I've got pending patchues I'm testing
that will fix this.

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH v4 6/7] block/copy-before-write: implement cbw-timeout option

2022-06-28 Thread Vladimir Sementsov-Ogievskiy

While debugging my "[PULL 00/10] Block jobs & NBD patches", I found that we 
have bdrv_dec_in_flight() and bdrv_inc_in_flight().

So, this should be fixed:

On 4/7/22 16:27, Vladimir Sementsov-Ogievskiy wrote:

In some scenarios, when copy-before-write operations lasts too long
time, it's better to cancel it.

Most useful would be to use the new option together with
on-cbw-error=break-snapshot: this way if cbw operation takes too long
time we'll just cancel backup process but do not disturb the guest too
much.



[..]

  
+static void block_copy_cb(void *opaque)

+{
+BlockDriverState *bs = opaque;
+
+bs->in_flight--;
+aio_wait_kick();


Just bdrv_dec_in_flight(bs), which includes aio_wait_kick().


+}
+
  /*
   * Do copy-before-write operation.
   *
@@ -111,7 +120,16 @@ static coroutine_fn int 
cbw_do_copy_before_write(BlockDriverState *bs,
  off = QEMU_ALIGN_DOWN(offset, cluster_size);
  end = QEMU_ALIGN_UP(offset + bytes, cluster_size);
  
-ret = block_copy(s->bcs, off, end - off, true, 0, NULL, NULL);

+/*
+ * Increase in_flight, so that in case of timed-out block-copy, the
+ * remaining background block_copy() request (which can't be immediately
+ * cancelled by timeout) is presented in bs->in_flight. This way we are
+ * sure that on bs close() we'll previously wait for all timed-out but yet
+ * running block_copy calls.
+ */
+bs->in_flight++;


bdrv_inc_in_flight(bs)


+ret = block_copy(s->bcs, off, end - off, true, s->cbw_timeout_ns,
+ block_copy_cb, bs);
  if (ret < 0 && s->on_cbw_error == ON_CBW_ERROR_BREAK_GUEST_WRITE) {
  return ret;
  }
@@ -377,6 +395,7 @@ static BlockdevOptions *cbw_parse_options(QDict *options, 
Error **errp)
   */
  qdict_extract_subqdict(options, NULL, "bitmap");
  qdict_del(options, "on-cbw-error");
+qdict_del(options, "cbw-timeout");
  


I'm going to resend "[PULL 00/10] Block jobs & NBD patches" with this fix and 
with fix in 03, if no objections.

--
Best regards,
Vladimir



Re: venv for python qtest bits? (was: Re: [PATCH 11/12] acpi/tests/bits: add README file for bits qtests)

2022-06-28 Thread Ani Sinha
On Tue, Jun 28, 2022 at 12:55 PM Thomas Huth  wrote:
>
> On 28/06/2022 09.10, Michael S. Tsirkin wrote:
> > On Tue, Jun 28, 2022 at 09:03:33AM +0200, Thomas Huth wrote:
>  No problem with that. So that's venv. But do we need pip and pulling
>  packages from the net during testing?
> >>>
> >>> We do that too. See requirements.txt in tests/
> >>> Following two are downloaded:
> >>> avocado-framework==88.1
> >>> pycdlib==1.11.0
> >>>
> >>> Also see this line in Makefie.include:
> >>>
> >>> $(call quiet-venv-pip,install -r $(TESTS_VENV_REQ))
> >>
> >> Right but that's avocado since it pulls lots of stuff from
> >> the net anyway.
> >> Are the libraries in question not packaged on major distros?
> >
> > Currently I only need this:
> > https://github.com/python-tap/tappy
> > which is the basic TAP processing library for python.
> >
> > It seems its only installed through pip:
> > https://tappy.readthedocs.io/en/latest/
> >
> > I do not think this is packaged by default. It's such a basic library
> > for parsing test output that maybe we can keep this somewhere within
> > the python src tree? Not sure ...
> 
>  It's pretty small for sure. Another submodule?
> >>>
> >>> Unlike BITS, this one is likely going to be maintained for a while and
> >>> will receive new releases through
> >>> https://pypi.org/project/tap.py/
> >>> so forking is OK but someone has to keep this updated.
> >>>
> >>> I am open to anything. Whatever feels right is fine to me.
> >>
> >> John Snow is currently working on the "Pythonification" of various QEMU
> >> bits, I think you should loop him into this discussion, too.
> >>
> >>   Thomas
> >
> > submodule does not mean we fork necessarily. We could have
> > all options: check for the module and use it if there, if not
> > use one from system if not there install with pip ..
> > But yea, I'm not sure what's best either.
>
> submodules create a dependency on an internet connection, too. So before you
> add yet another submodule (which have a couple of other disadvantages), I
> think you could also directly use the venv here.

Not sure what you mean by directly using the venv.

>
>   Thomas
>



Re: venv for python qtest bits? (was: Re: [PATCH 11/12] acpi/tests/bits: add README file for bits qtests)

2022-06-28 Thread Thomas Huth

On 28/06/2022 09.49, Ani Sinha wrote:

On Tue, Jun 28, 2022 at 12:55 PM Thomas Huth  wrote:


On 28/06/2022 09.10, Michael S. Tsirkin wrote:

On Tue, Jun 28, 2022 at 09:03:33AM +0200, Thomas Huth wrote:

No problem with that. So that's venv. But do we need pip and pulling
packages from the net during testing?


We do that too. See requirements.txt in tests/
Following two are downloaded:
avocado-framework==88.1
pycdlib==1.11.0

Also see this line in Makefie.include:

$(call quiet-venv-pip,install -r $(TESTS_VENV_REQ))


Right but that's avocado since it pulls lots of stuff from
the net anyway.
Are the libraries in question not packaged on major distros?


Currently I only need this:
https://github.com/python-tap/tappy
which is the basic TAP processing library for python.

It seems its only installed through pip:
https://tappy.readthedocs.io/en/latest/

I do not think this is packaged by default. It's such a basic library
for parsing test output that maybe we can keep this somewhere within
the python src tree? Not sure ...


It's pretty small for sure. Another submodule?


Unlike BITS, this one is likely going to be maintained for a while and
will receive new releases through
https://pypi.org/project/tap.py/
so forking is OK but someone has to keep this updated.

I am open to anything. Whatever feels right is fine to me.


John Snow is currently working on the "Pythonification" of various QEMU
bits, I think you should loop him into this discussion, too.

   Thomas


submodule does not mean we fork necessarily. We could have
all options: check for the module and use it if there, if not
use one from system if not there install with pip ..
But yea, I'm not sure what's best either.


submodules create a dependency on an internet connection, too. So before you
add yet another submodule (which have a couple of other disadvantages), I
think you could also directly use the venv here.


Not sure what you mean by directly using the venv.


I meant installing the dependency via pip in a venv, as you are currently 
doing it via the acpi-bits-test-venv.sh script.


 Thomas




Re: [PATCH 0/9] Preliminary patches for subproject split

2022-06-28 Thread Marc-André Lureau
Hi Markus

On Thu, Jun 16, 2022 at 4:48 PM  wrote:

> From: Marc-André Lureau 
>
> Hi,
>
> Here is another subset of the large "subproject(qga)"" series I intend to
> send
> soon after (https://gitlab.com/marcandre.lureau/qemu/-/commits/qga).
>
> Thanks
>
> Marc-André Lureau (9):
>   monitor: make error_vprintf_unless_qmp() static
>   error-report: misc comment fix
>   error-report: introduce "detailed" variable
>   error-report: simplify print_loc()
>   error-report: introduce ErrorReportDetailedFunc
>   error-report: add a callback to overwrite error_vprintf
>   qapi: move QEMU-specific dispatch code in monitor
>   scripts/qapi-gen: add -i option
>   scripts/qapi: add required system includes to visitor
>

This is mostly your area of maintenance. Do you have time for the remaining
reviews? (The progress feels very slow, compared to what is left in the
queue, I'd like to flush this before next year!)

thanks

-- 
Marc-André Lureau


Re: venv for python qtest bits? (was: Re: [PATCH 11/12] acpi/tests/bits: add README file for bits qtests)

2022-06-28 Thread Daniel P . Berrangé
On Tue, Jun 28, 2022 at 01:21:35PM +0530, Ani Sinha wrote:
> On Tue, Jun 28, 2022 at 1:19 PM Daniel P. Berrangé  
> wrote:
> >
> > On Tue, Jun 28, 2022 at 09:25:35AM +0200, Thomas Huth wrote:
> > > On 28/06/2022 09.10, Michael S. Tsirkin wrote:
> > > > On Tue, Jun 28, 2022 at 09:03:33AM +0200, Thomas Huth wrote:
> > > > > > > > > > > No problem with that. So that's venv. But do we need pip 
> > > > > > > > > > > and pulling
> > > > > > > > > > > packages from the net during testing?
> > > > > > > > > >
> > > > > > > > > > We do that too. See requirements.txt in tests/
> > > > > > > > > > Following two are downloaded:
> > > > > > > > > > avocado-framework==88.1
> > > > > > > > > > pycdlib==1.11.0
> > > > > > > > > >
> > > > > > > > > > Also see this line in Makefie.include:
> > > > > > > > > >
> > > > > > > > > > $(call quiet-venv-pip,install -r $(TESTS_VENV_REQ))
> > > > > > > > >
> > > > > > > > > Right but that's avocado since it pulls lots of stuff from
> > > > > > > > > the net anyway.
> > > > > > > > > Are the libraries in question not packaged on major distros?
> > > > > > > >
> > > > > > > > Currently I only need this:
> > > > > > > > https://github.com/python-tap/tappy
> > > > > > > > which is the basic TAP processing library for python.
> > > > > > > >
> > > > > > > > It seems its only installed through pip:
> > > > > > > > https://tappy.readthedocs.io/en/latest/
> > > > > > > >
> > > > > > > > I do not think this is packaged by default. It's such a basic 
> > > > > > > > library
> > > > > > > > for parsing test output that maybe we can keep this somewhere 
> > > > > > > > within
> > > > > > > > the python src tree? Not sure ...
> > > > > > >
> > > > > > > It's pretty small for sure. Another submodule?
> > > > > >
> > > > > > Unlike BITS, this one is likely going to be maintained for a while 
> > > > > > and
> > > > > > will receive new releases through
> > > > > > https://pypi.org/project/tap.py/
> > > > > > so forking is OK but someone has to keep this updated.
> > > > > >
> > > > > > I am open to anything. Whatever feels right is fine to me.
> > > > >
> > > > > John Snow is currently working on the "Pythonification" of various 
> > > > > QEMU
> > > > > bits, I think you should loop him into this discussion, too.
> > > > >
> > > > >   Thomas
> > > >
> > > > submodule does not mean we fork necessarily. We could have
> > > > all options: check for the module and use it if there, if not
> > > > use one from system if not there install with pip ..
> > > > But yea, I'm not sure what's best either.
> > >
> > > submodules create a dependency on an internet connection, too. So before 
> > > you
> > > add yet another submodule (which have a couple of other disadvantages), I
> > > think you could also directly use the venv here.
> >
> > Definitely not submodules.
> >
> > We need to get out of the mindset that submodules are needed for every new
> > dependancy we add. Submodules are only appropriate if the external project
> > is designed to be used as a copylib (eg the keycodemapdb tool), or if we
> > need to bundle in order to prevent a regression for previously deployed
> > QEMU installs where the dependancy is known not to exist on all our
> > supported platforms.
> >
> > This does not apply in this case, because the proposed use of tappy is
> > merely for a test case. Meson just needs to check if tappy exists and if
> > it does, then use it, otherwise skip the tests that need it. The user can
> > arrange to install tappy, as they do with the majority of other deps.
> >
> > If John's venv stuff is relevant, then we don't even need the meson checks,
> > just delegate to the venv setup.
> >
> > Regardless, no submodules are needed or desirable.
> 
> What about keeping biosbits stuff? Source or pre-built.

Shipping them as pre-built binaries in QEMU is not a viable option
IMHO, especially for grub as a GPL'd project we need to be extremely
clear about the exact corresponding source and build process for any
binary.

For this kind of thing I would generally expect the distro to provide
packages that we consume. Looking at biosbits I see it is itself
bundling a bunch more 3rd party projects, libffi, grub2, and including
even an ancient version of python as a submodule.

So bundling a pre-built biosbits in QEMU appears to mean that we're in
turn going to unexpectedly bundle a bunch of other 3rd party projects
too, all with dubious license compliance. I don't think this looks like
something we should have in qemu.git or qemu tarballs. It will also
make it challenging for the distro to take biosbits at all, unless
those 3rd party bundles can be eliminated in favour of using existing
builds their have packaged for grub, python, libffi, etc.

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [RFC v3 3/5] file-posix: introduce get_sysfs_long_val for zoned device information.

2022-06-28 Thread Stefan Hajnoczi
On Mon, Jun 27, 2022 at 08:19:15AM +0800, Sam Li wrote:
> Use sysfs attribute files to get the zoned device information in case
> that ioctl() commands of zone management interface won't work. It can
> return long type of value like chunk_sectors, zoned_append_max_bytes,
> max_open_zones, max_active_zones.
> ---
>  block/file-posix.c | 37 +
>  1 file changed, 25 insertions(+), 12 deletions(-)
> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 1b8b0d351f..73c2cdfbca 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1216,15 +1216,19 @@ static int hdev_get_max_hw_transfer(int fd, struct 
> stat *st)
>  #endif
>  }
>  
> -static int hdev_get_max_segments(int fd, struct stat *st)
> -{
> +/*
> + * Get zoned device information (chunk_sectors, zoned_append_max_bytes,
> + * max_open_zones, max_active_zones) through sysfs attribute files.

This function is also used to get max_segments, which is not related to
zoned devices. How about:

  Get a block queue sysfs attribute value.

> + */
> +static long get_sysfs_long_val(int fd, struct stat *st,
> +   const char *attribute) {
>  #ifdef CONFIG_LINUX
>  char buf[32];
>  const char *end;
>  char *sysfspath = NULL;
>  int ret;
>  int sysfd = -1;
> -long max_segments;
> +long val;
>  
>  if (S_ISCHR(st->st_mode)) {
>  if (ioctl(fd, SG_GET_SG_TABLESIZE, ) == 0) {
> @@ -1237,8 +1241,9 @@ static int hdev_get_max_segments(int fd, struct stat 
> *st)
>  return -ENOTSUP;
>  }
>  
> -sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
> -major(st->st_rdev), minor(st->st_rdev));
> +sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
> +major(st->st_rdev), minor(st->st_rdev),
> +attribute);
>  sysfd = open(sysfspath, O_RDONLY);
>  if (sysfd == -1) {
>  ret = -errno;
> @@ -1256,9 +1261,9 @@ static int hdev_get_max_segments(int fd, struct stat 
> *st)
>  }
>  buf[ret] = 0;
>  /* The file is ended with '\n', pass 'end' to accept that. */
> -ret = qemu_strtol(buf, , 10, _segments);
> +ret = qemu_strtol(buf, , 10, );
>  if (ret == 0 && end && *end == '\n') {
> -ret = max_segments;
> +ret = val;
>  }
>  
>  out:
> @@ -1272,6 +1277,15 @@ out:
>  #endif
>  }
>  
> +static int hdev_get_max_segments(int fd, struct stat *st) {
> +int ret;
> +ret = get_sysfs_long_val(fd, st, "max_segments");
> +if (ret < 0) {
> +return -1;

This hides the actual error number. The if statement can be dropped and
the function can be simplified to:

  static int hdev_get_max_segments(int fd, struct stat *st) {
  return get_sysfs_long_val(fd, st, "max_segments");
  }

Whether you want to keep the tiny helper function or inline
get_sysfs_long_val(fd, st, "max_segments") into the caller is up to you.

> +}
> +return ret;
> +}
> +
>  static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
>  {
>  BDRVRawState *s = bs->opaque;
> @@ -1872,6 +1886,7 @@ static int handle_aiocb_zone_report(void *opaque) {
>  
>  static int handle_aiocb_zone_mgmt(void *opaque) {
>  RawPosixAIOData *aiocb = opaque;
> +BlockDriverState *s = aiocb->bs;
>  int fd = aiocb->aio_fildes;
>  int64_t offset = aiocb->aio_offset;
>  int64_t len = aiocb->aio_nbytes;
> @@ -1884,11 +1899,9 @@ static int handle_aiocb_zone_mgmt(void *opaque) {
>  int64_t zone_size_mask;
>  int ret;
>  
> -ret = ioctl(fd, BLKGETZONESZ, _size);
> -if (ret) {
> -return -1;
> -}
> -
> +g_autofree struct stat *file = g_new(struct stat, 1);
> +stat(s->filename, file);

There is no need to allocate struct stat using g_new(). It's a small
struct that can be on the stack.

Also, fstat(fd, ) is preferred when the file descriptor is already
open because it avoids race conditions due to file renaming/path
traversal.

Here is how this could be written:

  struct stat st;
  if (fstat(fd, ) < 0) {
  return -errno;
  }

> +zone_size = get_sysfs_long_val(fd, file, "chunk_sectors");
>  zone_size_mask = zone_size - 1;
>  if (offset & zone_size_mask) {
>  error_report("offset is not the start of a zone");
> -- 
> 2.35.3
> 


signature.asc
Description: PGP signature


Re: venv for python qtest bits? (was: Re: [PATCH 11/12] acpi/tests/bits: add README file for bits qtests)

2022-06-28 Thread Thomas Huth

On 28/06/2022 10.23, Daniel P. Berrangé wrote:

On Tue, Jun 28, 2022 at 01:21:35PM +0530, Ani Sinha wrote:

On Tue, Jun 28, 2022 at 1:19 PM Daniel P. Berrangé  wrote:


On Tue, Jun 28, 2022 at 09:25:35AM +0200, Thomas Huth wrote:

On 28/06/2022 09.10, Michael S. Tsirkin wrote:

On Tue, Jun 28, 2022 at 09:03:33AM +0200, Thomas Huth wrote:

No problem with that. So that's venv. But do we need pip and pulling
packages from the net during testing?


We do that too. See requirements.txt in tests/
Following two are downloaded:
avocado-framework==88.1
pycdlib==1.11.0

Also see this line in Makefie.include:

$(call quiet-venv-pip,install -r $(TESTS_VENV_REQ))


Right but that's avocado since it pulls lots of stuff from
the net anyway.
Are the libraries in question not packaged on major distros?


Currently I only need this:
https://github.com/python-tap/tappy
which is the basic TAP processing library for python.

It seems its only installed through pip:
https://tappy.readthedocs.io/en/latest/

I do not think this is packaged by default. It's such a basic library
for parsing test output that maybe we can keep this somewhere within
the python src tree? Not sure ...


It's pretty small for sure. Another submodule?


Unlike BITS, this one is likely going to be maintained for a while and
will receive new releases through
https://pypi.org/project/tap.py/
so forking is OK but someone has to keep this updated.

I am open to anything. Whatever feels right is fine to me.


John Snow is currently working on the "Pythonification" of various QEMU
bits, I think you should loop him into this discussion, too.

   Thomas


submodule does not mean we fork necessarily. We could have
all options: check for the module and use it if there, if not
use one from system if not there install with pip ..
But yea, I'm not sure what's best either.


submodules create a dependency on an internet connection, too. So before you
add yet another submodule (which have a couple of other disadvantages), I
think you could also directly use the venv here.


Definitely not submodules.

We need to get out of the mindset that submodules are needed for every new
dependancy we add. Submodules are only appropriate if the external project
is designed to be used as a copylib (eg the keycodemapdb tool), or if we
need to bundle in order to prevent a regression for previously deployed
QEMU installs where the dependancy is known not to exist on all our
supported platforms.

This does not apply in this case, because the proposed use of tappy is
merely for a test case. Meson just needs to check if tappy exists and if
it does, then use it, otherwise skip the tests that need it. The user can
arrange to install tappy, as they do with the majority of other deps.

If John's venv stuff is relevant, then we don't even need the meson checks,
just delegate to the venv setup.

Regardless, no submodules are needed or desirable.


What about keeping biosbits stuff? Source or pre-built.


Shipping them as pre-built binaries in QEMU is not a viable option
IMHO, especially for grub as a GPL'd project we need to be extremely
clear about the exact corresponding source and build process for any
binary.

For this kind of thing I would generally expect the distro to provide
packages that we consume. Looking at biosbits I see it is itself
bundling a bunch more 3rd party projects, libffi, grub2, and including
even an ancient version of python as a submodule.

So bundling a pre-built biosbits in QEMU appears to mean that we're in
turn going to unexpectedly bundle a bunch of other 3rd party projects
too, all with dubious license compliance. I don't think this looks like
something we should have in qemu.git or qemu tarballs. It will also
make it challenging for the distro to take biosbits at all, unless
those 3rd party bundles can be eliminated in favour of using existing
builds their have packaged for grub, python, libffi, etc.


So if this depends on some third party binary bits, I think this is pretty 
similar to the tests in the avocado directory ... there we download third 
party binaries, too... Wouldn't it make sense to adapt your tests to that 
framework?


 Thomas




Re: [PATCH] util: Return void on iova_tree_remove

2022-06-28 Thread Laurent Vivier

Le 27/04/2022 à 17:49, Eugenio Pérez a écrit :

It always returns IOVA_OK so nobody uses it.

Acked-by: Jason Wang 
Reviewed-by: Peter Xu 
Signed-off-by: Eugenio Pérez 
---
  include/qemu/iova-tree.h | 4 +---
  util/iova-tree.c | 4 +---
  2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
index c938fb0793..16bbfdf5f8 100644
--- a/include/qemu/iova-tree.h
+++ b/include/qemu/iova-tree.h
@@ -72,10 +72,8 @@ int iova_tree_insert(IOVATree *tree, const DMAMap *map);
   * provided.  The range does not need to be exactly what has inserted,
   * all the mappings that are included in the provided range will be
   * removed from the tree.  Here map->translated_addr is meaningless.
- *
- * Return: 0 if succeeded, or <0 if error.
   */
-int iova_tree_remove(IOVATree *tree, const DMAMap *map);
+void iova_tree_remove(IOVATree *tree, const DMAMap *map);

  /**
   * iova_tree_find:
diff --git a/util/iova-tree.c b/util/iova-tree.c
index 6dff29c1f6..fee530a579 100644
--- a/util/iova-tree.c
+++ b/util/iova-tree.c
@@ -164,15 +164,13 @@ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator 
iterator)
  g_tree_foreach(tree->tree, iova_tree_traverse, iterator);
  }

-int iova_tree_remove(IOVATree *tree, const DMAMap *map)
+void iova_tree_remove(IOVATree *tree, const DMAMap *map)
  {
  const DMAMap *overlap;

  while ((overlap = iova_tree_find(tree, map))) {
  g_tree_remove(tree->tree, overlap);
  }
-
-return IOVA_OK;
  }

  /**
--
2.27.0




Applied to my trivial-patches branch.

Thanks,
Laurent




Re: [PATCH 12/14] hw/misc: Add intel-me

2022-06-28 Thread Cédric Le Goater

On 6/28/22 00:27, Peter Delevoryas wrote:

Signed-off-by: Peter Delevoryas 


Intro ?

I would rather have 2 patches, one for the slave model and one adding
a device to the machine.

Please replace the printf with trace events.

Thanks,

C.
 


---
  hw/arm/aspeed.c |   1 +
  hw/misc/intel_me.c  | 176 
  hw/misc/meson.build |   3 +-
  3 files changed, 179 insertions(+), 1 deletion(-)
  create mode 100644 hw/misc/intel_me.c

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 2b9c1600c6..88e9a47dc2 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -1447,6 +1447,7 @@ static void oby35_cl_i2c_init(AspeedMachineState *bmc)
  i2c_slave_create_simple(i2c[1], "tmp105", 0x4a);
  i2c_slave_create_simple(i2c[1], "adm1272", 0x40);
  i2c_slave_create_simple(i2c[1], "tmp421", 0x4c);
+i2c_slave_create_simple(i2c[2], "intel-me", 0x16);
  i2c_slave_create_simple(i2c[4], "isl69259", 0x76);
  i2c_slave_create_simple(i2c[4], "isl69259", 0x62);
  i2c_slave_create_simple(i2c[4], "isl69259", 0x60);
diff --git a/hw/misc/intel_me.c b/hw/misc/intel_me.c
new file mode 100644
index 00..fdc9180c26
--- /dev/null
+++ b/hw/misc/intel_me.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "hw/i2c/i2c.h"
+
+#define TYPE_INTEL_ME "intel-me"
+OBJECT_DECLARE_SIMPLE_TYPE(IntelMEState, INTEL_ME);
+
+#define printf(...)
+
+struct IntelMEState {
+I2CSlave parent_obj;
+
+I2CBus *bus;
+QEMUBH *bh;
+int rx_len;
+int tx_len;
+int tx_pos;
+uint8_t rx_buf[512];
+uint8_t tx_buf[512];
+};
+
+static void intel_me_bh(void *opaque)
+{
+IntelMEState *s = opaque;
+
+assert(s->bus->bh == s->bh);
+
+if (s->tx_pos == 0) {
+if (i2c_start_send_async(s->bus, s->tx_buf[s->tx_pos++]) != 0) {
+goto done;
+}
+return;
+}
+
+if (s->tx_pos < s->tx_len) {
+if (i2c_send_async(s->bus, s->tx_buf[s->tx_pos++]) != 0) {
+goto done;
+}
+return;
+}
+
+done:
+i2c_end_transfer(s->bus);
+i2c_bus_release(s->bus);
+s->tx_len = 0;
+s->tx_pos = 0;
+memset(s->tx_buf, 0, sizeof(s->tx_buf));
+}
+
+static void intel_me_realize(DeviceState *dev, Error **errp)
+{
+IntelMEState *s = INTEL_ME(dev);
+
+s->bus = I2C_BUS(qdev_get_parent_bus(dev));
+s->bh = qemu_bh_new(intel_me_bh, s);
+s->rx_len = 0;
+s->tx_len = 0;
+s->tx_pos = 0;
+memset(s->rx_buf, 0, sizeof(s->rx_buf));
+memset(s->tx_buf, 0, sizeof(s->tx_buf));
+}
+
+static uint8_t checksum(const uint8_t *ptr, int len)
+{
+int sum = 0;
+
+for (int i = 0; i < len; i++) {
+sum += ptr[i];
+}
+
+return 256 - sum;
+}
+
+static int intel_me_i2c_event(I2CSlave *i2c, enum i2c_event event)
+{
+IntelMEState *s = INTEL_ME(i2c);
+
+switch (event) {
+case I2C_START_RECV:
+break;
+case I2C_START_SEND:
+s->rx_len = 0;
+memset(s->rx_buf, 0, sizeof(s->rx_buf));
+break;
+case I2C_START_SEND_ASYNC:
+break;
+case I2C_FINISH:
+printf("IntelME rx: [");
+for (int i = 0; i < s->rx_len; i++) {
+if (i) {
+printf(", ");
+}
+printf("0x%02x", s->rx_buf[i]);
+}
+printf("]\n");
+
+s->tx_len = 10;
+s->tx_pos = 0;
+s->tx_buf[0] = s->rx_buf[2];
+s->tx_buf[1] = ((s->rx_buf[0] >> 2) + 1) << 2;
+s->tx_buf[2] = 256 - s->tx_buf[0] - s->tx_buf[1];
+s->tx_buf[3] = i2c->address; // rsSA response Slave Address
+s->tx_buf[4] = (s->rx_buf[3] >> 2) << 2; // sequence number
+s->tx_buf[5] = s->rx_buf[4]; // Same command code
+s->tx_buf[6] = 0x00; // OK
+s->tx_buf[7] = 0x55; // NO_ERROR
+ 

Re: [PATCH 00/12] Introduce new acpi/smbios qtests using biosbits

2022-06-28 Thread Ani Sinha
On Tue, Jun 28, 2022 at 1:39 PM Daniel P. Berrangé  wrote:
>
> On Mon, Jun 27, 2022 at 12:58:44PM +0530, Ani Sinha wrote:
> > Biosbits is a software written by Josh Triplett that can be downloaded by
> > visiting https://biosbits.org/. The github codebase can be found here:
> > https://github.com/biosbits/bits/tree/master. It is a software that 
> > exercizes
> > the bios components such as acpi and smbios tables directly through acpica
> > bios interpreter (a freely available C based library written by Intel,
> > downloadable from https://acpica.org/ and is included with biosbits) 
> > without an
> > operating system getting involved in between.
> > There are several advantages to directly testing the bios in a real physical
> > machine or VM as opposed to indirectly discovering bios issues through the
> > operating system. For one thing, the OSes tend to hide bios problems from 
> > the
> > end user. The other is that we have more control of what we wanted to test
> > and how by directly using acpica interpreter on top of the bios on a running
> > system. More details on the inspiration for developing biosbits and its real
> > life uses can be found in (a) and (b).
> > This patchset contains QEMU qtests written in python that exercizes the QEMU
> > bios components using biosbits and reports test failures.
> >
> > Details of each of the files added by this patchset are provided in the 
> > README
> > file which is part of Patch 11. Every effort to contact Josh, through 
> > various
> > means including email, twitter, linkedIn etc has failed. Hence, the changes 
> > to
> > build biosbits with the newer compiler, upgrade acpica and other changes are
> > currently maintained in a forked project in my personal github. We may want 
> > to
> > maintain bits in a separate fork in a stable repository that is accessible 
> > by
> > QEMU developers.
> >
> > The newly introduced qtest currently only run for x86_64 platform. They pass
> > both when running make check on a baremetal box as well as from inside a vm.
> >
> > Thanks to Igor M for pointing me to this work.
> >
> > (a) 
> > https://blog.linuxplumbersconf.org/2011/ocw/system/presentations/867/original/bits.pdf
> > (b) https://www.youtube.com/watch?v=36QIepyUuhg
> >
> > Ani Sinha (12):
> >   qtest: meson.build changes required to integrate python based qtests
> >   acpi/tests/bits: add prebuilt bios bits zip archive
> >   acpi/tests/bits: add prebuilt bits generated grub modules and scripts
>
> These two files didn't arrive on the mailing list, presumaby because
> pre-built binaries made the patches way too large.

Yes they are over 25 MB and my gmail account does not support
attachments more than that size.

>
>
> With regards,
> Daniel
> --
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
>



[PATCH v4 45/45] linux-user/aarch64: Add SME related hwcap entries

2022-06-28 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 163fc8a1ee..a496c37855 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -605,6 +605,18 @@ enum {
 ARM_HWCAP2_A64_RNG  = 1 << 16,
 ARM_HWCAP2_A64_BTI  = 1 << 17,
 ARM_HWCAP2_A64_MTE  = 1 << 18,
+ARM_HWCAP2_A64_ECV  = 1 << 19,
+ARM_HWCAP2_A64_AFP  = 1 << 20,
+ARM_HWCAP2_A64_RPRES= 1 << 21,
+ARM_HWCAP2_A64_MTE3 = 1 << 22,
+ARM_HWCAP2_A64_SME  = 1 << 23,
+ARM_HWCAP2_A64_SME_I16I64   = 1 << 24,
+ARM_HWCAP2_A64_SME_F64F64   = 1 << 25,
+ARM_HWCAP2_A64_SME_I8I32= 1 << 26,
+ARM_HWCAP2_A64_SME_F16F32   = 1 << 27,
+ARM_HWCAP2_A64_SME_B16F32   = 1 << 28,
+ARM_HWCAP2_A64_SME_F32F32   = 1 << 29,
+ARM_HWCAP2_A64_SME_FA64 = 1 << 30,
 };
 
 #define ELF_HWCAP   get_elf_hwcap()
@@ -674,6 +686,14 @@ static uint32_t get_elf_hwcap2(void)
 GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
 GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
 GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
+GET_FEATURE_ID(aa64_sme, (ARM_HWCAP2_A64_SME |
+  ARM_HWCAP2_A64_SME_F32F32 |
+  ARM_HWCAP2_A64_SME_B16F32 |
+  ARM_HWCAP2_A64_SME_F16F32 |
+  ARM_HWCAP2_A64_SME_I8I32));
+GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64);
+GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64);
+GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64);
 
 return hwcaps;
 }
-- 
2.34.1




[PULL 12/60] semihosting: Clean up common_semi_open_cb

2022-06-28 Thread Richard Henderson
Use common_semi_cb to return results instead of calling
set_swi_errno and common_semi_set_ret directly.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index cc13fcb0ef..6414caa749 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -364,15 +364,13 @@ static int common_semi_open_guestfd;
 static void
 common_semi_open_cb(CPUState *cs, target_ulong ret, target_ulong err)
 {
-if (ret == (target_ulong)-1) {
-errno = err;
-set_swi_errno(cs, -1);
+if (err) {
 dealloc_guestfd(common_semi_open_guestfd);
 } else {
 associate_guestfd(common_semi_open_guestfd, ret);
 ret = common_semi_open_guestfd;
 }
-common_semi_set_ret(cs, ret);
+common_semi_cb(cs, ret, err);
 }
 
 static target_ulong
-- 
2.34.1




[PULL 13/60] semihosting: Return void from do_common_semihosting

2022-06-28 Thread Richard Henderson
Perform the cleanup in the FIXME comment in common_semi_gdb_syscall.
Do not modify guest registers until the syscall is complete,
which in the gdbstub case is asynchronous.

In the synchronous non-gdbstub case, use common_semi_set_ret
to set the result.  Merge set_swi_errno into common_semi_cb.
Rely on the latter for combined return value / errno setting.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 semihosting/common-semi.h |   2 +-
 linux-user/aarch64/cpu_loop.c |   2 +-
 linux-user/arm/cpu_loop.c |   2 +-
 linux-user/riscv/cpu_loop.c   |   2 +-
 semihosting/arm-compat-semi.c | 543 --
 target/arm/helper.c   |   4 +-
 target/arm/m_helper.c |   2 +-
 target/riscv/cpu_helper.c |   2 +-
 8 files changed, 264 insertions(+), 295 deletions(-)

diff --git a/semihosting/common-semi.h b/semihosting/common-semi.h
index 0bfab1c669..0a91db7c41 100644
--- a/semihosting/common-semi.h
+++ b/semihosting/common-semi.h
@@ -34,6 +34,6 @@
 #ifndef COMMON_SEMI_H
 #define COMMON_SEMI_H
 
-target_ulong do_common_semihosting(CPUState *cs);
+void do_common_semihosting(CPUState *cs);
 
 #endif /* COMMON_SEMI_H */
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 3b273f6299..f7ef36cd9f 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -154,7 +154,7 @@ void cpu_loop(CPUARMState *env)
 force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
 break;
 case EXCP_SEMIHOST:
-env->xregs[0] = do_common_semihosting(cs);
+do_common_semihosting(cs);
 env->pc += 4;
 break;
 case EXCP_YIELD:
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index d950409d5b..c0790f3246 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -449,7 +449,7 @@ void cpu_loop(CPUARMState *env)
 }
 break;
 case EXCP_SEMIHOST:
-env->regs[0] = do_common_semihosting(cs);
+do_common_semihosting(cs);
 env->regs[15] += env->thumb ? 2 : 4;
 break;
 case EXCP_INTERRUPT:
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 29084c1421..bffca7db12 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -81,7 +81,7 @@ void cpu_loop(CPURISCVState *env)
 force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
 break;
 case RISCV_EXCP_SEMIHOST:
-env->gpr[xA0] = do_common_semihosting(cs);
+do_common_semihosting(cs);
 env->pc += 4;
 break;
 default:
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 6414caa749..cebbad2355 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -261,20 +261,6 @@ static target_ulong syscall_err;
 #include "semihosting/softmmu-uaccess.h"
 #endif
 
-static inline uint32_t set_swi_errno(CPUState *cs, uint32_t code)
-{
-if (code == (uint32_t)-1) {
-#ifdef CONFIG_USER_ONLY
-TaskState *ts = cs->opaque;
-
-ts->swi_errno = errno;
-#else
-syscall_err = errno;
-#endif
-}
-return code;
-}
-
 static inline uint32_t get_swi_errno(CPUState *cs)
 {
 #ifdef CONFIG_USER_ONLY
@@ -373,54 +359,24 @@ common_semi_open_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
 common_semi_cb(cs, ret, err);
 }
 
-static target_ulong
-common_semi_gdb_syscall(CPUState *cs, gdb_syscall_complete_cb cb,
-const char *fmt, ...)
-{
-va_list va;
-
-va_start(va, fmt);
-gdb_do_syscallv(cb, fmt, va);
-va_end(va);
-
-/*
- * FIXME: in softmmu mode, the gdbstub will schedule our callback
- * to occur, but will not actually call it to complete the syscall
- * until after this function has returned and we are back in the
- * CPU main loop. Therefore callers to this function must not
- * do anything with its return value, because it is not necessarily
- * the result of the syscall, but could just be the old value of X0.
- * The only thing safe to do with this is that the callers of
- * do_common_semihosting() will write it straight back into X0.
- * (In linux-user mode, the callback will have happened before
- * gdb_do_syscallv() returns.)
- *
- * We should tidy this up so neither this function nor
- * do_common_semihosting() return a value, so the mistake of
- * doing something with the return value is not possible to make.
- */
-
-return common_semi_arg(cs, 0);
-}
-
 /*
  * Types for functions implementing various semihosting calls
  * for specific types of guest file descriptor. These must all
- * do the work and return the required return value for the guest,
- * setting the guest errno if appropriate.
+ * do the work and return the required return value to the guest
+ * via common_semi_cb.
  */
-typedef 

[PULL 40/60] gdbstub: Adjust gdb_syscall_complete_cb declaration

2022-06-28 Thread Richard Henderson
Change 'ret' to uint64_t.  This resolves a FIXME in the
m68k and nios2 semihosting that we've lost data.
Change 'err' to int.  There is nothing target-specific
about the width of the errno value.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/exec/gdbstub.h|  3 +--
 gdbstub.c |  7 ---
 semihosting/arm-compat-semi.c | 12 +---
 semihosting/console.c |  7 +++
 semihosting/syscalls.c|  2 +-
 target/m68k/m68k-semi.c   | 10 +++---
 target/nios2/nios2-semi.c |  8 +++-
 7 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index b588c306cc..f667014888 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -74,8 +74,7 @@ struct gdb_timeval {
 #ifdef NEED_CPU_H
 #include "cpu.h"
 
-typedef void (*gdb_syscall_complete_cb)(CPUState *cpu,
-target_ulong ret, target_ulong err);
+typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, uint64_t ret, int err);
 
 /**
  * gdb_do_syscall:
diff --git a/gdbstub.c b/gdbstub.c
index f3a4664453..cf869b10e3 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1878,11 +1878,12 @@ static void handle_read_all_regs(GArray *params, void 
*user_ctx)
 static void handle_file_io(GArray *params, void *user_ctx)
 {
 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
-target_ulong ret, err;
+uint64_t ret;
+int err;
 
-ret = (target_ulong)get_param(params, 0)->val_ull;
+ret = get_param(params, 0)->val_ull;
 if (params->len >= 2) {
-err = (target_ulong)get_param(params, 1)->val_ull;
+err = get_param(params, 1)->val_ull;
 } else {
 err = 0;
 }
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 7ab6afd7fc..1b0505987a 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -215,7 +215,7 @@ static inline uint32_t get_swi_errno(CPUState *cs)
 #endif
 }
 
-static void common_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
+static void common_semi_cb(CPUState *cs, uint64_t ret, int err)
 {
 if (err) {
 #ifdef CONFIG_USER_ONLY
@@ -232,7 +232,7 @@ static void common_semi_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
  * SYS_READ and SYS_WRITE always return the number of bytes not read/written.
  * There is no error condition, other than returning the original length.
  */
-static void common_semi_rw_cb(CPUState *cs, target_ulong ret, target_ulong err)
+static void common_semi_rw_cb(CPUState *cs, uint64_t ret, int err)
 {
 /* Recover the original length from the third argument. */
 CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
@@ -251,8 +251,7 @@ static void common_semi_rw_cb(CPUState *cs, target_ulong 
ret, target_ulong err)
  * Convert from Posix ret+errno to Arm SYS_ISTTY return values.
  * With gdbstub, err is only ever set for protocol errors to EIO.
  */
-static void common_semi_istty_cb(CPUState *cs, target_ulong ret,
- target_ulong err)
+static void common_semi_istty_cb(CPUState *cs, uint64_t ret, int err)
 {
 if (err) {
 ret = (err == ENOTTY ? 0 : -1);
@@ -263,8 +262,7 @@ static void common_semi_istty_cb(CPUState *cs, target_ulong 
ret,
 /*
  * SYS_SEEK returns 0 on success, not the resulting offset.
  */
-static void common_semi_seek_cb(CPUState *cs, target_ulong ret,
-target_ulong err)
+static void common_semi_seek_cb(CPUState *cs, uint64_t ret, int err)
 {
 if (!err) {
 ret = 0;
@@ -285,7 +283,7 @@ static target_ulong common_semi_flen_buf(CPUState *cs)
 }
 
 static void
-common_semi_flen_fstat_cb(CPUState *cs, target_ulong ret, target_ulong err)
+common_semi_flen_fstat_cb(CPUState *cs, uint64_t ret, int err)
 {
 if (!err) {
 /* The size is always stored in big-endian order, extract the value. */
diff --git a/semihosting/console.c b/semihosting/console.c
index ef6958d844..4e49202b2a 100644
--- a/semihosting/console.c
+++ b/semihosting/console.c
@@ -64,11 +64,10 @@ static GString *copy_user_string(CPUArchState *env, 
target_ulong addr)
 return s;
 }
 
-static void semihosting_cb(CPUState *cs, target_ulong ret, target_ulong err)
+static void semihosting_cb(CPUState *cs, uint64_t ret, int err)
 {
-if (ret == (target_ulong) -1) {
-qemu_log("%s: gdb console output failed ("TARGET_FMT_ld")",
- __func__, err);
+if (err) {
+qemu_log("%s: gdb console output failed (%d)\n", __func__, err);
 }
 }
 
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index db1e9f6cc9..13a9bdeda6 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -115,7 +115,7 @@ static int copy_stat_to_user(CPUState *cs, target_ulong 
addr,
 
 static gdb_syscall_complete_cb gdb_open_complete;
 
-static void gdb_open_cb(CPUState *cs, target_ulong ret, target_ulong err)

[PULL 34/60] semihosting: Split out semihost_sys_flen

2022-06-28 Thread Richard Henderson
The ARM-specific SYS_FLEN isn't really something that can be
reused by other semihosting apis, but there are parts that can
reused for the implementation of semihost_sys_fstat.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/syscalls.h |  4 ++
 semihosting/arm-compat-semi.c  | 74 ++
 semihosting/syscalls.c | 49 ++
 3 files changed, 66 insertions(+), 61 deletions(-)

diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index c60ebafb85..1ae5ba6716 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -45,4 +45,8 @@ void semihost_sys_lseek(CPUState *cs, gdb_syscall_complete_cb 
complete,
 void semihost_sys_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
  int fd);
 
+void semihost_sys_flen(CPUState *cs, gdb_syscall_complete_cb fstat_cb,
+   gdb_syscall_complete_cb flen_cb,
+   int fd, target_ulong fstat_addr);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 3cdc2b6efc..68e13d9077 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -285,44 +285,25 @@ static target_ulong common_semi_flen_buf(CPUState *cs)
 }
 
 static void
-common_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
+common_semi_flen_fstat_cb(CPUState *cs, target_ulong ret, target_ulong err)
 {
 if (!err) {
 /* The size is always stored in big-endian order, extract the value. */
 uint64_t size;
-cpu_memory_rw_debug(cs, common_semi_flen_buf(cs) +
-offsetof(struct gdb_stat, gdb_st_size),
-, 8, 0);
-ret = be64_to_cpu(size);
+if (cpu_memory_rw_debug(cs, common_semi_flen_buf(cs) +
+offsetof(struct gdb_stat, gdb_st_size),
+, 8, 0)) {
+ret = -1, err = EFAULT;
+} else {
+size = be64_to_cpu(size);
+if (ret != size) {
+ret = -1, err = EOVERFLOW;
+}
+}
 }
 common_semi_cb(cs, ret, err);
 }
 
-/*
- * Types for functions implementing various semihosting calls
- * for specific types of guest file descriptor. These must all
- * do the work and return the required return value to the guest
- * via common_semi_cb.
- */
-typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
-
-static void host_flenfn(CPUState *cs, GuestFD *gf)
-{
-struct stat buf;
-
-if (fstat(gf->hostfd, )) {
-common_semi_cb(cs, -1, errno);
-} else {
-common_semi_cb(cs, buf.st_size, 0);
-}
-}
-
-static void gdb_flenfn(CPUState *cs, GuestFD *gf)
-{
-gdb_do_syscall(common_semi_flen_cb, "fstat,%x,%x",
-   gf->hostfd, common_semi_flen_buf(cs));
-}
-
 #define SHFB_MAGIC_0 0x53
 #define SHFB_MAGIC_1 0x48
 #define SHFB_MAGIC_2 0x46
@@ -340,27 +321,6 @@ static const uint8_t featurefile_data[] = {
 SH_EXT_EXIT_EXTENDED | SH_EXT_STDOUT_STDERR, /* Feature byte 0 */
 };
 
-static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
-{
-common_semi_cb(cs, gf->staticfile.len, 0);
-}
-
-typedef struct GuestFDFunctions {
-sys_flenfn *flenfn;
-} GuestFDFunctions;
-
-static const GuestFDFunctions guestfd_fns[] = {
-[GuestFDHost] = {
-.flenfn = host_flenfn,
-},
-[GuestFDGDB] = {
-.flenfn = gdb_flenfn,
-},
-[GuestFDStatic] = {
-.flenfn = staticfile_flenfn,
-},
-};
-
 /*
  * Do a semihosting call.
  *
@@ -379,7 +339,6 @@ void do_common_semihosting(CPUState *cs)
 char * s;
 int nr;
 uint32_t ret;
-GuestFD *gf;
 int64_t elapsed;
 
 nr = common_semi_arg(cs, 0) & 0xU;
@@ -493,12 +452,8 @@ void do_common_semihosting(CPUState *cs)
 
 case TARGET_SYS_FLEN:
 GET_ARG(0);
-
-gf = get_guestfd(arg0);
-if (!gf) {
-goto do_badf;
-}
-guestfd_fns[gf->type].flenfn(cs, gf);
+semihost_sys_flen(cs, common_semi_flen_fstat_cb, common_semi_cb,
+  arg0, common_semi_flen_buf(cs));
 break;
 
 case TARGET_SYS_TMPNAM:
@@ -820,9 +775,6 @@ void do_common_semihosting(CPUState *cs)
 cpu_dump_state(cs, stderr, 0);
 abort();
 
-do_badf:
-common_semi_cb(cs, -1, EBADF);
-break;
 do_fault:
 common_semi_cb(cs, -1, EFAULT);
 break;
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 1f1baf7e2d..fff9550c89 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -127,6 +127,12 @@ static void gdb_isatty(CPUState *cs, 
gdb_syscall_complete_cb complete,
 gdb_do_syscall(complete, "isatty,%x", (target_ulong)gf->hostfd);
 }
 
+static void gdb_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
+  GuestFD *gf, target_ulong addr)
+{
+

[PULL 53/60] semihosting: Create semihost_sys_poll_one

2022-06-28 Thread Richard Henderson
This will be used for implementing the xtensa select_one
system call.  Choose "poll" over "select" so that we can
reuse Glib's g_poll constants and to avoid struct timeval.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/console.h  | 16 
 include/semihosting/syscalls.h |  3 ++
 semihosting/console.c  | 19 -
 semihosting/syscalls.c | 70 ++
 4 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/include/semihosting/console.h b/include/semihosting/console.h
index 20c31d89d4..61b0cb3a94 100644
--- a/include/semihosting/console.h
+++ b/include/semihosting/console.h
@@ -53,4 +53,20 @@ int qemu_semihosting_console_write(void *buf, int len);
  */
 int qemu_semihosting_log_out(const char *s, int len);
 
+/*
+ * qemu_semihosting_console_block_until_ready:
+ * @cs: CPUState
+ *
+ * If no data is available we suspend the CPU and will re-execute the
+ * instruction when data is available.
+ */
+void qemu_semihosting_console_block_until_ready(CPUState *cs);
+
+/**
+ * qemu_semihosting_console_ready:
+ *
+ * Return true if characters are available for read; does not block.
+ */
+bool qemu_semihosting_console_ready(void);
+
 #endif /* SEMIHOST_CONSOLE_H */
diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 347200cb9f..3a5ec229eb 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -69,4 +69,7 @@ void semihost_sys_system(CPUState *cs, 
gdb_syscall_complete_cb complete,
 void semihost_sys_gettimeofday(CPUState *cs, gdb_syscall_complete_cb complete,
target_ulong tv_addr, target_ulong tz_addr);
 
+void semihost_sys_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
+   int fd, GIOCondition cond, int timeout);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/console.c b/semihosting/console.c
index c84ab97ab6..cda7cf1905 100644
--- a/semihosting/console.c
+++ b/semihosting/console.c
@@ -77,10 +77,17 @@ static void console_read(void *opaque, const uint8_t *buf, 
int size)
 c->sleeping_cpus = NULL;
 }
 
-int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
+bool qemu_semihosting_console_ready(void)
+{
+SemihostingConsole *c = 
+
+g_assert(qemu_mutex_iothread_locked());
+return !fifo8_is_empty(>fifo);
+}
+
+void qemu_semihosting_console_block_until_ready(CPUState *cs)
 {
 SemihostingConsole *c = 
-int ret = 0;
 
 g_assert(qemu_mutex_iothread_locked());
 
@@ -92,6 +99,14 @@ int qemu_semihosting_console_read(CPUState *cs, void *buf, 
int len)
 cpu_loop_exit(cs);
 /* never returns */
 }
+}
+
+int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
+{
+SemihostingConsole *c = 
+int ret = 0;
+
+qemu_semihosting_console_block_until_ready(cs);
 
 /* Read until buffer full or fifo exhausted. */
 do {
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 9e499b1751..4847f66c02 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -520,6 +520,21 @@ static void host_gettimeofday(CPUState *cs, 
gdb_syscall_complete_cb complete,
 unlock_user(p, tv_addr, sizeof(struct gdb_timeval));
 }
 
+#ifndef CONFIG_USER_ONLY
+static void host_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
+  GuestFD *gf, GIOCondition cond, int timeout)
+{
+/*
+ * Since this is only used by xtensa in system mode, and stdio is
+ * handled through GuestFDConsole, and there are no semihosting
+ * system calls for sockets and the like, that means this descriptor
+ * must be a normal file.  Normal files never block and are thus
+ * always ready.
+ */
+complete(cs, cond & (G_IO_IN | G_IO_OUT), 0);
+}
+#endif
+
 /*
  * Static file semihosting syscall implementations.
  */
@@ -628,6 +643,34 @@ static void console_fstat(CPUState *cs, 
gdb_syscall_complete_cb complete,
 complete(cs, ret ? -1 : 0, ret ? -ret : 0);
 }
 
+#ifndef CONFIG_USER_ONLY
+static void console_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
+ GuestFD *gf, GIOCondition cond, int timeout)
+{
+/* The semihosting console does not support urgent data or errors. */
+cond &= G_IO_IN | G_IO_OUT;
+
+/*
+ * Since qemu_semihosting_console_write never blocks, we can
+ * consider output always ready -- leave G_IO_OUT alone.
+ * All that remains is to conditionally signal input ready.
+ * Since output ready causes an immediate return, only block
+ * for G_IO_IN alone.
+ *
+ * TODO: Implement proper timeout.  For now, only support
+ * indefinite wait or immediate poll.
+ */
+if (cond == G_IO_IN && timeout < 0) {
+qemu_semihosting_console_block_until_ready(cs);
+/* We returned -- input must be ready. */
+} else if ((cond & G_IO_IN) && !qemu_semihosting_console_ready()) {
+

Re: [PATCH v2 7/8] aspeed: Make aspeed_board_init_flashes public

2022-06-28 Thread Cédric Le Goater

On 6/24/22 02:37, Peter Delevoryas wrote:

Signed-off-by: Peter Delevoryas 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/arm/aspeed.c | 25 -
  hw/arm/aspeed_soc.c | 26 ++
  include/hw/arm/aspeed_soc.h |  2 ++
  3 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index b43dc0fda8..a7352ca837 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -257,31 +257,6 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, 
size_t rom_size,
  rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
  }
  
-static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,

-  unsigned int count, int unit0)
-{
-int i;
-
-if (!flashtype) {
-return;
-}
-
-for (i = 0; i < count; ++i) {
-DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
-qemu_irq cs_line;
-DeviceState *dev;
-
-dev = qdev_new(flashtype);
-if (dinfo) {
-qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
-}
-qdev_realize_and_unref(dev, BUS(s->spi), _fatal);
-
-cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
-sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
-}
-}
-
  static void sdhci_attach_drive(SDHCIState *sdhci, DriveInfo *dinfo)
  {
  DeviceState *card;
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 16394c8e0b..4183f5ffbf 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -21,6 +21,7 @@
  #include "hw/i2c/aspeed_i2c.h"
  #include "net/net.h"
  #include "sysemu/sysemu.h"
+#include "sysemu/blockdev.h"
  
  #define ASPEED_SOC_IOMEM_SIZE   0x0020
  
@@ -626,3 +627,28 @@ void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,

  memory_region_add_subregion_overlap(s->memory, addr,
  sysbus_mmio_get_region(dev, 0), 
-1000);
  }
+
+void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
+   unsigned int count, int unit0)
+{
+int i;
+
+if (!flashtype) {
+return;
+}
+
+for (i = 0; i < count; ++i) {
+DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
+qemu_irq cs_line;
+DeviceState *dev;
+
+dev = qdev_new(flashtype);
+if (dinfo) {
+qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
+}
+qdev_realize_and_unref(dev, BUS(s->spi), _fatal);
+
+cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
+sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
+}
+}
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 6cfc063985..5cd31c1306 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -178,5 +178,7 @@ void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, 
int n, hwaddr addr);
  void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
 const char *name, hwaddr addr,
 uint64_t size);
+void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
+   unsigned int count, int unit0);
  
  #endif /* ASPEED_SOC_H */





[PULL 54/60] target/m68k: Eliminate m68k_semi_is_fseek

2022-06-28 Thread Richard Henderson
Reorg m68k_semi_return_* to gdb_syscall_complete_cb.
Use the 32-bit version normally, and the 64-bit version
for HOSTED_LSEEK.

Reviewed-by: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
 target/m68k/m68k-semi.c | 55 +
 1 file changed, 23 insertions(+), 32 deletions(-)

diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index 8c186c0e9f..37b409b0b9 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -95,8 +95,11 @@ static void translate_stat(CPUM68KState *env, target_ulong 
addr, struct stat *s)
 unlock_user(p, addr, sizeof(struct gdb_stat));
 }
 
-static void m68k_semi_return_u32(CPUM68KState *env, uint32_t ret, int err)
+static void m68k_semi_u32_cb(CPUState *cs, uint64_t ret, int err)
 {
+M68kCPU *cpu = M68K_CPU(cs);
+CPUM68KState *env = >env;
+
 target_ulong args = env->dregs[1];
 if (put_user_u32(ret, args) ||
 put_user_u32(err, args + 4)) {
@@ -110,8 +113,11 @@ static void m68k_semi_return_u32(CPUM68KState *env, 
uint32_t ret, int err)
 }
 }
 
-static void m68k_semi_return_u64(CPUM68KState *env, uint64_t ret, int err)
+static void m68k_semi_u64_cb(CPUState *cs, uint64_t ret, int err)
 {
+M68kCPU *cpu = M68K_CPU(cs);
+CPUM68KState *env = >env;
+
 target_ulong args = env->dregs[1];
 if (put_user_u32(ret >> 32, args) ||
 put_user_u32(ret, args + 4) ||
@@ -122,21 +128,6 @@ static void m68k_semi_return_u64(CPUM68KState *env, 
uint64_t ret, int err)
 }
 }
 
-static int m68k_semi_is_fseek;
-
-static void m68k_semi_cb(CPUState *cs, uint64_t ret, int err)
-{
-M68kCPU *cpu = M68K_CPU(cs);
-CPUM68KState *env = >env;
-
-if (m68k_semi_is_fseek) {
-m68k_semi_return_u64(env, ret, err);
-m68k_semi_is_fseek = 0;
-} else {
-m68k_semi_return_u32(env, ret, err);
-}
-}
-
 /*
  * Read the input value from the argument block; fail the semihosting
  * call if the memory read fails.
@@ -151,6 +142,7 @@ static void m68k_semi_cb(CPUState *cs, uint64_t ret, int 
err)
 
 void do_m68k_semihosting(CPUM68KState *env, int nr)
 {
+CPUState *cs = env_cpu(env);
 uint32_t args;
 target_ulong arg0, arg1, arg2, arg3;
 void *p;
@@ -169,7 +161,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 GET_ARG(2);
 GET_ARG(3);
 if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_cb, "open,%s,%x,%x", arg0, (int)arg1,
+gdb_do_syscall(m68k_semi_u32_cb, "open,%s,%x,%x", arg0, (int)arg1,
arg2, arg3);
 return;
 } else {
@@ -190,7 +182,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 int fd = arg0;
 if (fd > 2) {
 if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_cb, "close,%x", arg0);
+gdb_do_syscall(m68k_semi_u32_cb, "close,%x", arg0);
 return;
 } else {
 result = close(fd);
@@ -206,7 +198,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 GET_ARG(2);
 len = arg2;
 if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_cb, "read,%x,%x,%x",
+gdb_do_syscall(m68k_semi_u32_cb, "read,%x,%x,%x",
arg0, arg1, len);
 return;
 } else {
@@ -226,7 +218,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 GET_ARG(2);
 len = arg2;
 if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_cb, "write,%x,%x,%x",
+gdb_do_syscall(m68k_semi_u32_cb, "write,%x,%x,%x",
arg0, arg1, len);
 return;
 } else {
@@ -249,12 +241,11 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 GET_ARG(3);
 off = (uint32_t)arg2 | ((uint64_t)arg1 << 32);
 if (use_gdb_syscalls()) {
-m68k_semi_is_fseek = 1;
-gdb_do_syscall(m68k_semi_cb, "fseek,%x,%lx,%x",
+gdb_do_syscall(m68k_semi_u64_cb, "fseek,%x,%lx,%x",
arg0, off, arg3);
 } else {
 off = lseek(arg0, off, arg3);
-m68k_semi_return_u64(env, off, errno);
+m68k_semi_u64_cb(cs, off, errno);
 }
 return;
 }
@@ -264,7 +255,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 GET_ARG(2);
 GET_ARG(3);
 if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_cb, "rename,%s,%s",
+gdb_do_syscall(m68k_semi_u32_cb, "rename,%s,%s",
arg0, (int)arg1, arg2, (int)arg3);
 return;
 } else {
@@ -284,7 +275,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
 GET_ARG(0);
 GET_ARG(1);
 if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_cb, "unlink,%s",
+

Re: [PATCH v2 3/4] hw/nvme: add support for ratified TP4084

2022-06-28 Thread Klaus Jensen
On Jun 27 13:47, Niklas Cassel wrote:
> TP4084 adds a new mode, CC.CRIME, that can be used to mark a namespace
> as ready independently from the controller.
> 
> When CC.CRIME is 0 (default), things behave as before, all namespaces
> are ready when CSTS.RDY gets set to 1.
> 
> When CC.CRIME is 1, the controller will become ready when CSTS.RDY gets
> set to 1, but commands accessing a namespace are allowed to return
> "Namespace Not Ready" or "Admin Command Media Not Ready".
> After CRTO.CRWMT amount of time, if the namespace has not yet been
> marked ready, the status codes also need to have the DNR bit set.
> 
> Add a new "ready_delay" namespace device parameter, in order to emulate
> different ready latencies for namespaces.
> 
> Once a namespace is ready, it will set the NRDY bit in the I/O Command
> Set Independent Identify Namespace Data Structure, and then send out a
> Namespace Attribute Changed event.
> 
> This new "ready_delay" is supported on controllers not part of a NVMe
> subsystem. The reasons are many. One problem is that multiple controllers
> can have different CC.CRIME modes running. Another problem is the extra
> locking needed. The third problem is when to actually clear NRDY. If we
> assume that a namespace clears NRDY when it no longer has any controller
> online for that namespace. The problem then is that Linux will reset the
> controllers one by one during probe time. The reset goes so fast so that
> there is no time when all controllers are in reset at the same time, so
> NRDY will never get cleared. (The controllers are enabled by SeaBIOS by
> default.) We could introduce a reset_time param, but this would only
> increase the chances that all controllers are in reset at the same time.
> 
> Signed-off-by: Niklas Cassel 
> ---
>  hw/nvme/ctrl.c   | 123 +--
>  hw/nvme/ns.c |  18 +++
>  hw/nvme/nvme.h   |   6 +++
>  hw/nvme/trace-events |   1 +
>  include/block/nvme.h |  60 -
>  5 files changed, 204 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
> index 8ca824ea14..5404f67480 100644
> --- a/hw/nvme/ctrl.c
> +++ b/hw/nvme/ctrl.c
> @@ -88,6 +88,12 @@
>   *   completion when there are no outstanding AERs. When the maximum number 
> of
>   *   enqueued events are reached, subsequent events will be dropped.
>   *
> + * - `crwmt`
> + *   This is the Controller Ready With Media Timeout (CRWMT) field that is
> + *   defined in the CRTO register. This specifies the worst-case time that 
> host
> + *   software should wait for the controller and all attached namespaces to
> + *   become ready. The value is in units of 500 milliseconds.
> + *
>   * - `mdts`
>   *   Indicates the maximum data transfer size for a command that transfers 
> data
>   *   between host-accessible memory and the controller. The value is 
> specified
> @@ -157,6 +163,11 @@
>   *   namespace will be available in the subsystem but not attached to any
>   *   controllers.
>   *
> + * - `ready_delay`
> + *   This parameter specifies the amount of time that the namespace should 
> wait
> + *   before being marked ready. Only applicable if CC.CRIME is set by the 
> user.
> + *   The value is in units of 500 milliseconds (to be consistent with 
> `crwmt`).
> + *
>   * Setting `zoned` to true selects Zoned Command Set at the namespace.
>   * In this case, the following namespace properties are available to 
> configure
>   * zoned operation:
> @@ -216,6 +227,8 @@
>  #define NVME_VF_RES_GRANULARITY 1
>  #define NVME_VF_OFFSET 0x1
>  #define NVME_VF_STRIDE 1
> +#define NVME_DEFAULT_CRIMT 0xa
> +#define NVME_DEFAULT_CRWMT 0xf
>  
>  #define NVME_GUEST_ERR(trace, fmt, ...) \
>  do { \
> @@ -4188,6 +4201,10 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest 
> *req)
>  return NVME_INVALID_OPCODE | NVME_DNR;
>  }
>  
> +if (!(ns->id_indep_ns.nstat & NVME_NSTAT_NRDY)) {
> +return NVME_NS_NOT_READY;
> +}
> +

I'd add a ns->ready bool instead. See below for my previously posted
patch.

>  if (ns->status) {
>  return ns->status;
>  }
> @@ -4791,6 +4808,27 @@ static uint16_t nvme_identify_ns(NvmeCtrl *n, 
> NvmeRequest *req, bool active)
>  return NVME_INVALID_CMD_SET | NVME_DNR;
>  }
>  
> +static uint16_t nvme_identify_cs_indep_ns(NvmeCtrl *n, NvmeRequest *req)
> +{
> +NvmeNamespace *ns;
> +NvmeIdentify *c = (NvmeIdentify *)>cmd;
> +uint32_t nsid = le32_to_cpu(c->nsid);
> +
> +trace_pci_nvme_identify_cs_indep_ns(nsid);
> +
> +if (!nvme_nsid_valid(n, nsid) || nsid == NVME_NSID_BROADCAST) {
> +return NVME_INVALID_NSID | NVME_DNR;
> +}
> +
> +ns = nvme_ns(n, nsid);
> +if (unlikely(!ns)) {
> +return nvme_rpt_empty_id_struct(n, req);
> +}
> +
> +return nvme_c2h(n, (uint8_t *)>id_indep_ns, sizeof(NvmeIdNsCsIndep),
> +req);
> +}
> +

I posted a patch for this some time ago


[PULL 16/60] include/exec: Move gdb open flags to gdbstub.h

2022-06-28 Thread Richard Henderson
There were 3 copies of these flags.  Place them in the
file with gdb_do_syscall, with which they belong.

Reviewed-by: Alex Bennée 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 include/exec/gdbstub.h| 9 +
 semihosting/arm-compat-semi.c | 7 ---
 target/m68k/m68k-semi.c   | 8 
 target/nios2/nios2-semi.c | 8 
 4 files changed, 9 insertions(+), 23 deletions(-)

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index c35d7334b4..603e22ae80 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -10,6 +10,15 @@
 #define GDB_WATCHPOINT_READ  3
 #define GDB_WATCHPOINT_ACCESS4
 
+/* For gdb file i/o remote protocol open flags. */
+#define GDB_O_RDONLY  0
+#define GDB_O_WRONLY  1
+#define GDB_O_RDWR2
+#define GDB_O_APPEND  8
+#define GDB_O_CREAT   0x200
+#define GDB_O_TRUNC   0x400
+#define GDB_O_EXCL0x800
+
 #ifdef NEED_CPU_H
 #include "cpu.h"
 
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 92c1375b15..abf543ce91 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -86,13 +86,6 @@
 #define O_BINARY 0
 #endif
 
-#define GDB_O_RDONLY  0x000
-#define GDB_O_WRONLY  0x001
-#define GDB_O_RDWR0x002
-#define GDB_O_APPEND  0x008
-#define GDB_O_CREAT   0x200
-#define GDB_O_TRUNC   0x400
-
 static int gdb_open_modeflags[12] = {
 GDB_O_RDONLY,
 GDB_O_RDONLY,
diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index a31db38fc3..475a6b13b7 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -69,14 +69,6 @@ struct gdb_timeval {
   uint64_t tv_usec;   /* microsecond */
 } QEMU_PACKED;
 
-#define GDB_O_RDONLY   0x0
-#define GDB_O_WRONLY   0x1
-#define GDB_O_RDWR 0x2
-#define GDB_O_APPEND   0x8
-#define GDB_O_CREAT  0x200
-#define GDB_O_TRUNC  0x400
-#define GDB_O_EXCL   0x800
-
 static int translate_openflags(int flags)
 {
 int hf;
diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
index 373e6b9436..0eec1f9a1c 100644
--- a/target/nios2/nios2-semi.c
+++ b/target/nios2/nios2-semi.c
@@ -71,14 +71,6 @@ struct gdb_timeval {
   uint64_t tv_usec;   /* microsecond */
 } QEMU_PACKED;
 
-#define GDB_O_RDONLY   0x0
-#define GDB_O_WRONLY   0x1
-#define GDB_O_RDWR 0x2
-#define GDB_O_APPEND   0x8
-#define GDB_O_CREAT  0x200
-#define GDB_O_TRUNC  0x400
-#define GDB_O_EXCL   0x800
-
 static int translate_openflags(int flags)
 {
 int hf;
-- 
2.34.1




Re: [PATCH 07/14] aspeed: Add PECI controller

2022-06-28 Thread Cédric Le Goater

On 6/27/22 21:54, Peter Delevoryas wrote:

Could we have some short intro ? :)


Signed-off-by: Peter Delevoryas 
---
  hw/arm/aspeed_ast10x0.c   |  11 ++
  hw/misc/aspeed_peci.c | 225 ++
  hw/misc/meson.build   |   3 +-
  include/hw/arm/aspeed_soc.h   |   3 +
  include/hw/misc/aspeed_peci.h |  34 +
  5 files changed, 275 insertions(+), 1 deletion(-)
  create mode 100644 hw/misc/aspeed_peci.c
  create mode 100644 include/hw/misc/aspeed_peci.h

diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
index 5df480a21f..780841ea84 100644
--- a/hw/arm/aspeed_ast10x0.c
+++ b/hw/arm/aspeed_ast10x0.c
@@ -47,6 +47,7 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
  [ASPEED_DEV_UART13]= 0x7E790700,
  [ASPEED_DEV_WDT]   = 0x7E785000,
  [ASPEED_DEV_LPC]   = 0x7E789000,
+[ASPEED_DEV_PECI]  = 0x7E78B000,
  [ASPEED_DEV_I2C]   = 0x7E7B,
  };
  
@@ -75,6 +76,7 @@ static const int aspeed_soc_ast1030_irqmap[] = {

  [ASPEED_DEV_TIMER8]= 23,
  [ASPEED_DEV_WDT]   = 24,
  [ASPEED_DEV_LPC]   = 35,
+[ASPEED_DEV_PECI]  = 38,
  [ASPEED_DEV_FMC]   = 39,
  [ASPEED_DEV_PWM]   = 44,
  [ASPEED_DEV_ADC]   = 46,
@@ -133,6 +135,8 @@ static void aspeed_soc_ast1030_init(Object *obj)
  
  object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
  
+object_initialize_child(obj, "peci", >peci, TYPE_ASPEED_PECI);

+
  object_initialize_child(obj, "sbc", >sbc, TYPE_ASPEED_SBC);
  
  for (i = 0; i < sc->wdts_num; i++) {

@@ -238,6 +242,13 @@ static void aspeed_soc_ast1030_realize(DeviceState 
*dev_soc, Error **errp)
  /* UART */
  aspeed_soc_uart_init(s);
  
+/* PECI */

+if (!sysbus_realize(SYS_BUS_DEVICE(>peci), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>peci), 0, sc->memmap[ASPEED_DEV_PECI]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>peci), 0, aspeed_soc_get_irq(s, 
ASPEED_DEV_PECI));
+
  /* Timer */
  object_property_set_link(OBJECT(>timerctrl), "scu", OBJECT(>scu),
   _abort);
diff --git a/hw/misc/aspeed_peci.c b/hw/misc/aspeed_peci.c
new file mode 100644
index 00..670e532fc0
--- /dev/null
+++ b/hw/misc/aspeed_peci.c
@@ -0,0 +1,225 @@
+/*
+ * Aspeed PECI Controller
+ *
+ * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
+ *
+ * This code is licensed under the GPL version 2 or later. See the COPYING
+ * file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/misc/aspeed_peci.h"
+
+#define U(x) (x##U)
+#define GENMASK(h, l) \
+   (((~U(0)) - (U(1) << (l)) + 1) & \
+(~U(0) >> (32 - 1 - (h


I beleive QEMU has similar macros to generate masks.



+/* ASPEED PECI Registers */
+/* Control Register */
+#define ASPEED_PECI_CTRL (0x00 / 4)
+#define   ASPEED_PECI_CTRL_SAMPLING_MASK   GENMASK(19, 16)
+#define   ASPEED_PECI_CTRL_RD_MODE_MASKGENMASK(13, 12)
+#define ASPEED_PECI_CTRL_RD_MODE_DBG BIT(13)
+#define ASPEED_PECI_CTRL_RD_MODE_COUNT BIT(12)
+#define   ASPEED_PECI_CTRL_CLK_SRC_HCLK BIT(11)
+#define   ASPEED_PECI_CTRL_CLK_DIV_MASK GENMASK(10, 8)
+#define   ASPEED_PECI_CTRL_INVERT_OUT BIT(7)
+#define   ASPEED_PECI_CTRL_INVERT_IN BIT(6)
+#define   ASPEED_PECI_CTRL_BUS_CONTENTION_EN BIT(5)
+#define   ASPEED_PECI_CTRL_PECI_EN  BIT(4)
+#define   ASPEED_PECI_CTRL_PECI_CLK_EN  BIT(0)
+
+/* Timing Negotiation Register */
+#define ASPEED_PECI_TIMING_NEGOTIATION (0x04 / 4)
+#define   ASPEED_PECI_T_NEGO_MSG_MASK  GENMASK(15, 8)
+#define   ASPEED_PECI_T_NEGO_ADDR_MASK  GENMASK(7, 0)
+
+/* Command Register */
+#define ASPEED_PECI_CMD (0x08 / 4)
+#define   ASPEED_PECI_CMD_PIN_MONITORING BIT(31)
+#define   ASPEED_PECI_CMD_STS_MASK  GENMASK(27, 24)
+#define ASPEED_PECI_CMD_STS_ADDR_T_NEGO 0x3
+#define   ASPEED_PECI_CMD_IDLE_MASK  \
+   (ASPEED_PECI_CMD_STS_MASK | ASPEED_PECI_CMD_PIN_MONITORING)
+#define   ASPEED_PECI_CMD_FIRE   BIT(0)
+
+/* Read/Write Length Register */
+#define ASPEED_PECI_RW_LENGTH (0x0c / 4)
+#define   ASPEED_PECI_AW_FCS_EN   BIT(31)
+#define   ASPEED_PECI_RD_LEN_MASK  GENMASK(23, 16)
+#define   ASPEED_PECI_WR_LEN_MASK  GENMASK(15, 8)
+#define   ASPEED_PECI_TARGET_ADDR_MASK  GENMASK(7, 0)
+
+/* Expected FCS Data Register */
+#define ASPEED_PECI_EXPECTED_FCS (0x10 / 4)
+#define   ASPEED_PECI_EXPECTED_RD_FCS_MASK GENMASK(23, 16)
+#define   ASPEED_PECI_EXPECTED_AW_FCS_AUTO_MASK GENMASK(15, 8)
+#define   ASPEED_PECI_EXPECTED_WR_FCS_MASK GENMASK(7, 0)
+
+/* Captured FCS Data Register */
+#define ASPEED_PECI_CAPTURED_FCS (0x14 / 4)
+#define   ASPEED_PECI_CAPTURED_RD_FCS_MASK GENMASK(23, 16)
+#define   ASPEED_PECI_CAPTURED_WR_FCS_MASK GENMASK(7, 0)
+
+/* Interrupt Register */
+#define ASPEED_PECI_INT_CTRL (0x18 / 4)
+#define   ASPEED_PECI_TIMING_NEGO_SEL_MASK GENMASK(31, 30)
+#define ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO 0
+#define 

Re: [RFC PATCH] qemu-options: bring the kernel and image options together

2022-06-28 Thread Cédric Le Goater

On 6/23/22 12:21, Alex Bennée wrote:


Cédric Le Goater  writes:


On 6/22/22 16:50, Alex Bennée wrote:

How to control the booting of QEMU is often a source of confusion for
users. Bring the options that control this together in the manual
pages and add some verbiage to describe when each option is
appropriate.
Signed-off-by: Alex Bennée 
Cc: Cédric Le Goater 
---
   qemu-options.hx | 80 ++---
   1 file changed, 62 insertions(+), 18 deletions(-)
diff --git a/qemu-options.hx b/qemu-options.hx
index 377d22fbd8..9b0242f0ef 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1585,13 +1585,6 @@ SRST
   Use file as SecureDigital card image.
   ERST
   -DEF("pflash", HAS_ARG, QEMU_OPTION_pflash,
-"-pflash fileuse 'file' as a parallel flash image\n", QEMU_ARCH_ALL)
-SRST
-``-pflash file``
-Use file as a parallel flash image.
-ERST
->   DEF("snapshot", 0, QEMU_OPTION_snapshot,
   "-snapshot   write to temporary files instead of disk image files\n",
   QEMU_ARCH_ALL)
@@ -3680,12 +3673,51 @@ DEFHEADING()
 #endif
   -DEFHEADING(Linux/Multiboot boot specific:)
+DEFHEADING(Boot Image or Kernel specific:)
+SRST
+There are broadly 4 ways you can boot a system with QEMU.
+
+ - specify a firmware and let it control finding a kernel
+ - specify a firmware and pass a hint to the kernel to boot
+ - direct kernel image boot
+ - manually load files into the guests address space
+
+The last method is useful for quickly testing kernels but as there is
+no firmware to pass configuration information to the kernel it must
+either be built for the exact configuration or be handed a DTB blob
+which tells the kernel what drivers it needs.


The last method can also load any FW blob with the correct executable
layout (reset vector).


Heh - actually I wrote that paragraph for the direct kernel image boot
and then added the manual option after the fact. I'll try and clean that
up to make it clearer.




+
+ERST
+
+SRST
+
+For x86 machines ``-bios`` will generally do the right thing with
+whatever it is given. For non-x86 machines the more strict ``-pflash``
+option needs an image that is sized for the flash device for the given
+machine type.


Some ppc machine use -bios also, mac, pseries, PowerNV (let's not restrict
to x86).


Ahh the magic some ;-) Does it essentially rely on if the correct
plumbing has been done for the machine? 


They rely on finding a reset vector. So yes, the FW should be mapped
where it is expected and have vectors. The machines also know how to
expose kernel/initrd to the FW and the FWs have runtime services.
It's more than a kernel loader.


Anything I can look for to audit other machine types?


Good question. There are some many ways to start a machine.

The avocado tests should be a good reference and here is a little
tool I use to verify that the PPC machines supported in QEMU boot
correctly :

  https://github.com/legoater/qemu-ppc-boot/blob/main/ppc-boot.sh

Sometime ago, I did a model for a MicroWatt SoC, a POWER9 FPGA
implementation, and I found quite a few ways to boot from some blob.
See :

  https://github.com/qemu/qemu/commit/2f43989f87332c226358c1f3ef7b96d94ba342ca

I guess when FW runtime services are required so is -bios. Else all
these options  :

 -kernel
 -bios
 -device loader
 -drive 

can be used more or less in the same way.

Thanks,

C.







LGTM.

Thanks,

C.



+
+ERST
+
+DEF("bios", HAS_ARG, QEMU_OPTION_bios, \
+"-bios file  set the filename for the BIOS\n", QEMU_ARCH_ALL)
+SRST
+``-bios file``
+Set the filename for the BIOS.
+ERST
+
+DEF("pflash", HAS_ARG, QEMU_OPTION_pflash,
+"-pflash fileuse 'file' as a parallel flash image\n", QEMU_ARCH_ALL)
+SRST
+``-pflash file``
+Use file as a parallel flash image.
+ERST
+
   SRST
-When using these options, you can use a given Linux or Multiboot kernel
-without installing it in the disk image. It can be useful for easier
-testing of various kernels.
   +The kernel options were designed to work with Linux kernels
although
+other things (like hypervisors) can be packaged up as a kernel
+executable image. The exact format of a executable image is usually
+architecture specific.
   ERST
   @@ -3725,6 +3757,25 @@ SRST
   kernel on boot.
   ERST
   +SRST
+
+Finally you can also manually load images directly into the address
+space of the guest. This is most useful for developers who already
+know the layout of their guest and take care to ensure something sane
+will happen when the reset vector executes.
+
+The generic loader can be invoked by using the loader device:
+
+``-device 
loader,addr=,data=,data-len=[,data-be=][,cpu-num=]``
+
+there is also the guest loader which operates in a similar way but
+tweaks the DTB so a hypervisor loaded via ``-kernel`` can find where
+the guest image is:
+
+``-device 
guest-loader,addr=[,kernel=,[bootargs=]][,initrd=]``
+ERST
+
   DEFHEADING()
 DEFHEADING(Debug/Expert options:)
@@ -4175,13 +4226,6 @@ 

[PULL 26/60] semihosting: Move GET_ARG/SET_ARG earlier in the file

2022-06-28 Thread Richard Henderson
Moving this to be useful for another function
besides do_common_semihosting.

Reviewed-by: Alex Bennée 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 48 +--
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index adb4e5b581..72a1350512 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -181,6 +181,30 @@ static LayoutInfo common_semi_find_bases(CPUState *cs)
 
 #include "common-semi-target.h"
 
+/*
+ * Read the input value from the argument block; fail the semihosting
+ * call if the memory read fails. Eventually we could use a generic
+ * CPUState helper function here.
+ */
+
+#define GET_ARG(n) do { \
+if (is_64bit_semihosting(env)) {\
+if (get_user_u64(arg ## n, args + (n) * 8)) {   \
+goto do_fault;  \
+}   \
+} else {\
+if (get_user_u32(arg ## n, args + (n) * 4)) {   \
+goto do_fault;  \
+}   \
+}   \
+} while (0)
+
+#define SET_ARG(n, val) \
+(is_64bit_semihosting(env) ?\
+ put_user_u64(val, args + (n) * 8) :\
+ put_user_u32(val, args + (n) * 4))
+
+
 /*
  * The semihosting API has no concept of its errno being thread-safe,
  * as the API design predates SMP CPUs and was intended as a simple
@@ -507,30 +531,6 @@ static const GuestFDFunctions guestfd_fns[] = {
 },
 };
 
-/*
- * Read the input value from the argument block; fail the semihosting
- * call if the memory read fails. Eventually we could use a generic
- * CPUState helper function here.
- */
-
-#define GET_ARG(n) do { \
-if (is_64bit_semihosting(env)) {\
-if (get_user_u64(arg ## n, args + (n) * 8)) {   \
-goto do_fault;  \
-}   \
-} else {\
-if (get_user_u32(arg ## n, args + (n) * 4)) {   \
-goto do_fault;  \
-}   \
-}   \
-} while (0)
-
-#define SET_ARG(n, val) \
-(is_64bit_semihosting(env) ?\
- put_user_u64(val, args + (n) * 8) :\
- put_user_u32(val, args + (n) * 4))
-
-
 /*
  * Do a semihosting call.
  *
-- 
2.34.1




Re: [PATCH 09/14] pmbus: Reset out buf after switching pages

2022-06-28 Thread Peter Delevoryas


> On Jun 27, 2022, at 11:51 PM, Cédric Le Goater  wrote:
> 
> On 6/27/22 21:55, Peter Delevoryas wrote:
>> Signed-off-by: Peter Delevoryas 
> 
> is that a bug ?

I believe so yes, although I don’t really have any experience with
real pmbus devices. But, I would assume that when you’re switching
pages, you wouldn’t retain any remaining data from the transfer
buffer of the previous page, because that would return data
from the previous page.

Here’s the tag I should have included:

Fixes: 3746d5c15e70570b ("hw/i2c: add support for PMBus”)

> 
> 
>> ---
>>  hw/i2c/pmbus_device.c | 1 +
>>  1 file changed, 1 insertion(+)
>> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
>> index 62885fa6a1..efddc36fd9 100644
>> --- a/hw/i2c/pmbus_device.c
>> +++ b/hw/i2c/pmbus_device.c
>> @@ -1088,6 +1088,7 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t 
>> *buf, uint8_t len)
>>if (pmdev->code == PMBUS_PAGE) {
>>  pmdev->page = pmbus_receive8(pmdev);
>> +pmdev->out_buf_len = 0;
>>  return 0;
>>  }
>>  
> 



[PULL 43/60] semihosting: Expand qemu_semihosting_console_inc to read

2022-06-28 Thread Richard Henderson
Allow more than one character to be read at one time.
Will be used by m68k and nios2 semihosting for stdio.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/console.h | 12 +++-
 linux-user/semihost.c | 10 ++
 semihosting/arm-compat-semi.c | 11 +--
 semihosting/console.c | 16 
 4 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/include/semihosting/console.h b/include/semihosting/console.h
index 27f8e9ae2e..39dbf1b062 100644
--- a/include/semihosting/console.h
+++ b/include/semihosting/console.h
@@ -38,19 +38,21 @@ int qemu_semihosting_console_outs(CPUArchState *env, 
target_ulong s);
 void qemu_semihosting_console_outc(CPUArchState *env, target_ulong c);
 
 /**
- * qemu_semihosting_console_inc:
+ * qemu_semihosting_console_read:
  * @cs: CPUState
+ * @buf: host buffer
+ * @len: buffer size
  *
- * Receive single character from debug console.  As this call may block
- * if no data is available we suspend the CPU and will re-execute the
+ * Receive at least one character from debug console.  As this call may
+ * block if no data is available we suspend the CPU and will re-execute the
  * instruction when data is there. Therefore two conditions must be met:
  *
  *   - CPUState is synchronized before calling this function
  *   - pc is only updated once the character is successfully returned
  *
- * Returns: character read OR cpu_loop_exit!
+ * Returns: number of characters read, OR cpu_loop_exit!
  */
-target_ulong qemu_semihosting_console_inc(CPUState *cs);
+int qemu_semihosting_console_read(CPUState *cs, void *buf, int len);
 
 /**
  * qemu_semihosting_log_out:
diff --git a/linux-user/semihost.c b/linux-user/semihost.c
index f14c6ae21d..2029fb674c 100644
--- a/linux-user/semihost.c
+++ b/linux-user/semihost.c
@@ -56,21 +56,23 @@ void qemu_semihosting_console_outc(CPUArchState *env, 
target_ulong addr)
  * program is expecting more normal behaviour. This is slow but
  * nothing using semihosting console reading is expecting to be fast.
  */
-target_ulong qemu_semihosting_console_inc(CPUState *cs)
+int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
 {
-uint8_t c;
+int ret;
 struct termios old_tio, new_tio;
 
 /* Disable line-buffering and echo */
 tcgetattr(STDIN_FILENO, _tio);
 new_tio = old_tio;
 new_tio.c_lflag &= (~ICANON & ~ECHO);
+new_tio.c_cc[VMIN] = 1;
+new_tio.c_cc[VTIME] = 0;
 tcsetattr(STDIN_FILENO, TCSANOW, _tio);
 
-c = getchar();
+ret = fread(buf, 1, len, stdin);
 
 /* restore config */
 tcsetattr(STDIN_FILENO, TCSANOW, _tio);
 
-return (target_ulong) c;
+return ret;
 }
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 40f3730778..fdb143ace8 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -428,8 +428,15 @@ void do_common_semihosting(CPUState *cs)
 break;
 
 case TARGET_SYS_READC:
-ret = qemu_semihosting_console_inc(cs);
-common_semi_set_ret(cs, ret);
+{
+uint8_t ch;
+int ret = qemu_semihosting_console_read(cs, , 1);
+if (ret == 1) {
+common_semi_cb(cs, ch, 0);
+} else {
+common_semi_cb(cs, -1, EIO);
+}
+}
 break;
 
 case TARGET_SYS_ISERROR:
diff --git a/semihosting/console.c b/semihosting/console.c
index 17ece6bdca..e5ac3f20ba 100644
--- a/semihosting/console.c
+++ b/semihosting/console.c
@@ -144,12 +144,14 @@ static void console_read(void *opaque, const uint8_t 
*buf, int size)
 c->sleeping_cpus = NULL;
 }
 
-target_ulong qemu_semihosting_console_inc(CPUState *cs)
+int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
 {
-uint8_t ch;
 SemihostingConsole *c = 
+int ret = 0;
 
 g_assert(qemu_mutex_iothread_locked());
+
+/* Block if the fifo is completely empty. */
 if (fifo8_is_empty(>fifo)) {
 c->sleeping_cpus = g_slist_prepend(c->sleeping_cpus, cs);
 cs->halted = 1;
@@ -157,8 +159,14 @@ target_ulong qemu_semihosting_console_inc(CPUState *cs)
 cpu_loop_exit(cs);
 /* never returns */
 }
-ch = fifo8_pop(>fifo);
-return (target_ulong) ch;
+
+/* Read until buffer full or fifo exhausted. */
+do {
+*(char *)(buf + ret) = fifo8_pop(>fifo);
+ret++;
+} while (ret < len && !fifo8_is_empty(>fifo));
+
+return ret;
 }
 
 void qemu_semihosting_console_init(void)
-- 
2.34.1




Re: [PATCH 09/12] acpi/tests/bits: add acpi and smbios python tests that uses biosbits

2022-06-28 Thread Thomas Huth

On 28/06/2022 09.26, Ani Sinha wrote:

On Tue, Jun 28, 2022 at 12:50 PM Thomas Huth  wrote:


On 27/06/2022 09.28, Ani Sinha wrote:

This change adds python based qtest framework that can be used to run
qtests from within a virtual environment. A bash script creates the virtual
environment and then runs the python based tests from within that environment.
All dependent python packages are installed in the virtual environment using
pip module. QEMU python test modules are also available in the environment for
spawning the QEMU based VMs.

It also introduces QEMU acpi/smbios biosbits python test script which is run
from within the python virtual environment.

Signed-off-by: Ani Sinha 
---
   tests/qtest/acpi-bits/acpi-bits-test-venv.sh |  59 
   tests/qtest/acpi-bits/acpi-bits-test.py  | 327 +++
   tests/qtest/acpi-bits/meson.build|  39 +++
   tests/qtest/acpi-bits/requirements.txt   |   1 +
   4 files changed, 426 insertions(+)
   create mode 100644 tests/qtest/acpi-bits/acpi-bits-test-venv.sh
   create mode 100644 tests/qtest/acpi-bits/acpi-bits-test.py
   create mode 100644 tests/qtest/acpi-bits/meson.build
   create mode 100644 tests/qtest/acpi-bits/requirements.txt

diff --git a/tests/qtest/acpi-bits/acpi-bits-test-venv.sh 
b/tests/qtest/acpi-bits/acpi-bits-test-venv.sh
new file mode 100644
index 00..124e03ce18
--- /dev/null
+++ b/tests/qtest/acpi-bits/acpi-bits-test-venv.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+# Generates a python virtual environment for the test to run.
+# Then runs python test scripts from within that virtual environment.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+# Author: Ani Sinha 
+
+set -e
+
+MYPATH=$(realpath ${BASH_SOURCE:-$0})
+MYDIR=$(dirname $MYPATH)
+
+if [ -z "$QTEST_SOURCE_ROOT" ]; then
+echo -n "Please set QTEST_SOURCE_ROOT env pointing"
+echo " to the root of the qemu source tree."
+echo -n "This is required so that the test can find the "
+echo "python modules that it needs for execution."
+exit 1
+fi
+SRCDIR=$QTEST_SOURCE_ROOT
+TESTSCRIPTS=("acpi-bits-test.py")
+PIPCMD="-m pip -q --disable-pip-version-check"
+# we need to save the old value of PWD before we do a change-dir later
+QTEST_PWD=$PWD
+
+TESTS_PYTHON=/usr/bin/python3
+TESTS_VENV_REQ=requirements.txt
+
+# sadly for pip -e and -t options do not work together.
+# please see https://github.com/pypa/pip/issues/562
+cd $MYDIR
+
+$TESTS_PYTHON -m venv .
+$TESTS_PYTHON $PIPCMD install -e $SRCDIR/python/
+[ -f $TESTS_VENV_REQ ] && \
+$TESTS_PYTHON $PIPCMD install -r $TESTS_VENV_REQ
+
+# venv is activated at this point.
+
+# run the test
+for testscript in ${TESTSCRIPTS[@]} ; do
+export QTEST_PWD; python3 $testscript
+done
+
+cd $QTEST_PWD
+
+exit 0
diff --git a/tests/qtest/acpi-bits/acpi-bits-test.py 
b/tests/qtest/acpi-bits/acpi-bits-test.py
new file mode 100644
index 00..673567bf8e
--- /dev/null
+++ b/tests/qtest/acpi-bits/acpi-bits-test.py
@@ -0,0 +1,327 @@
+#!/usr/bin/env python3
+# group: rw quick
+# Exercize QEMU generated ACPI/SMBIOS tables using biosbits,
+# https://biosbits.org/
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+# Some parts are slightly taken from qtest.py and iotests.py
+#
+# Authors:
+#  Ani Sinha 
+
+# pylint: disable=invalid-name
+
+"""
+QEMU bios tests using biosbits available at
+https://biosbits.org/.
+"""
+
+import logging
+import os
+import re
+import shutil
+import subprocess
+import sys
+import tarfile
+import tempfile
+import time
+import unittest
+import zipfile
+from typing import (
+List,
+Optional,
+Sequence,
+)
+from tap import TAPTestRunner
+from qemu.machine import QEMUMachine
+
+QTESTQEMUPROG = os.getenv('QTEST_QEMU_BINARY')
+QTEST_PWD = os.getenv('QTEST_PWD')
+
+def get_arch():
+

Re: venv for python qtest bits? (was: Re: [PATCH 11/12] acpi/tests/bits: add README file for bits qtests)

2022-06-28 Thread Daniel P . Berrangé
On Tue, Jun 28, 2022 at 09:25:35AM +0200, Thomas Huth wrote:
> On 28/06/2022 09.10, Michael S. Tsirkin wrote:
> > On Tue, Jun 28, 2022 at 09:03:33AM +0200, Thomas Huth wrote:
> > > > > > > > > No problem with that. So that's venv. But do we need pip and 
> > > > > > > > > pulling
> > > > > > > > > packages from the net during testing?
> > > > > > > > 
> > > > > > > > We do that too. See requirements.txt in tests/
> > > > > > > > Following two are downloaded:
> > > > > > > > avocado-framework==88.1
> > > > > > > > pycdlib==1.11.0
> > > > > > > > 
> > > > > > > > Also see this line in Makefie.include:
> > > > > > > > 
> > > > > > > > $(call quiet-venv-pip,install -r $(TESTS_VENV_REQ))
> > > > > > > 
> > > > > > > Right but that's avocado since it pulls lots of stuff from
> > > > > > > the net anyway.
> > > > > > > Are the libraries in question not packaged on major distros?
> > > > > > 
> > > > > > Currently I only need this:
> > > > > > https://github.com/python-tap/tappy
> > > > > > which is the basic TAP processing library for python.
> > > > > > 
> > > > > > It seems its only installed through pip:
> > > > > > https://tappy.readthedocs.io/en/latest/
> > > > > > 
> > > > > > I do not think this is packaged by default. It's such a basic 
> > > > > > library
> > > > > > for parsing test output that maybe we can keep this somewhere within
> > > > > > the python src tree? Not sure ...
> > > > > 
> > > > > It's pretty small for sure. Another submodule?
> > > > 
> > > > Unlike BITS, this one is likely going to be maintained for a while and
> > > > will receive new releases through
> > > > https://pypi.org/project/tap.py/
> > > > so forking is OK but someone has to keep this updated.
> > > > 
> > > > I am open to anything. Whatever feels right is fine to me.
> > > 
> > > John Snow is currently working on the "Pythonification" of various QEMU
> > > bits, I think you should loop him into this discussion, too.
> > > 
> > >   Thomas
> > 
> > submodule does not mean we fork necessarily. We could have
> > all options: check for the module and use it if there, if not
> > use one from system if not there install with pip ..
> > But yea, I'm not sure what's best either.
> 
> submodules create a dependency on an internet connection, too. So before you
> add yet another submodule (which have a couple of other disadvantages), I
> think you could also directly use the venv here.

Definitely not submodules.

We need to get out of the mindset that submodules are needed for every new
dependancy we add. Submodules are only appropriate if the external project
is designed to be used as a copylib (eg the keycodemapdb tool), or if we
need to bundle in order to prevent a regression for previously deployed
QEMU installs where the dependancy is known not to exist on all our
supported platforms.

This does not apply in this case, because the proposed use of tappy is
merely for a test case. Meson just needs to check if tappy exists and if
it does, then use it, otherwise skip the tests that need it. The user can
arrange to install tappy, as they do with the majority of other deps.

If John's venv stuff is relevant, then we don't even need the meson checks,
just delegate to the venv setup.

Regardless, no submodules are needed or desirable.

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




[PULL 49/60] semihosting: Use console_out_gf for SYS_WRITEC

2022-06-28 Thread Richard Henderson
Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 9d4d6d2812..d61b773f98 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -228,6 +228,15 @@ static void common_semi_cb(CPUState *cs, uint64_t ret, int 
err)
 common_semi_set_ret(cs, ret);
 }
 
+/*
+ * Use 0xdeadbeef as the return value when there isn't a defined
+ * return value for the call.
+ */
+static void common_semi_dead_cb(CPUState *cs, uint64_t ret, int err)
+{
+common_semi_set_ret(cs, 0xdeadbeef);
+}
+
 /*
  * SYS_READ and SYS_WRITE always return the number of bytes not read/written.
  * There is no error condition, other than returning the original length.
@@ -341,8 +350,7 @@ static const uint8_t featurefile_data[] = {
  * The specification always says that the "return register" either
  * returns a specific value or is corrupted, so we don't need to
  * report to our caller whether we are returning a value or trying to
- * leave the register unchanged. We use 0xdeadbeef as the return value
- * when there isn't a defined return value for the call.
+ * leave the register unchanged.
  */
 void do_common_semihosting(CPUState *cs)
 {
@@ -420,8 +428,12 @@ void do_common_semihosting(CPUState *cs)
 break;
 
 case TARGET_SYS_WRITEC:
-qemu_semihosting_console_outc(env, args);
-common_semi_set_ret(cs, 0xdeadbeef);
+/*
+ * FIXME: the byte to be written is in a target_ulong slot,
+ * which means this is wrong for a big-endian guest.
+ */
+semihost_sys_write_gf(cs, common_semi_dead_cb,
+  _out_gf, args, 1);
 break;
 
 case TARGET_SYS_WRITE0:
-- 
2.34.1




Re: [PATCH v1 2/2] migration/multifd: Warn user when zerocopy not working

2022-06-28 Thread Daniel P . Berrangé
On Mon, Jun 27, 2022 at 10:09:09PM -0300, Leonardo Bras wrote:
> Some errors, like the lack of Scatter-Gather support by the network
> interface(NETIF_F_SG) may cause sendmsg(...,MSG_ZEROCOPY) to fail on using
> zero-copy, which causes it to fall back to the default copying mechanism.

How common is this lack of SG support ? What NICs did you have that
were affected ?

> After each full dirty-bitmap scan there should be a zero-copy flush
> happening, which checks for errors each of the previous calls to
> sendmsg(...,MSG_ZEROCOPY). If all of them failed to use zero-copy, then
> warn the user about it.
> 
> Since it happens once each full dirty-bitmap scan, even in worst case
> scenario it should not print a lot of warnings, and will allow tracking
> how many dirty-bitmap iterations were not able to use zero-copy send.

For long running migrations which are not converging, or converging
very slowly there could be 100's of passes.



> Signed-off-by: Leonardo Bras 
> ---
>  migration/multifd.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/migration/multifd.c b/migration/multifd.c
> index 684c014c86..9c62aec84e 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -624,6 +624,9 @@ int multifd_send_sync_main(QEMUFile *f)
>  if (ret < 0) {
>  error_report_err(err);
>  return -1;
> +} else if (ret == 1) {
> +warn_report("The network device is not able to use "
> +"zero-copy-send: copying is being used");
>  }
>  }
>  }
> -- 
> 2.36.1
> 

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




[PATCH qemu v3] ppc: Define SETFIELD for the ppc target

2022-06-28 Thread Alexey Kardashevskiy
It keeps repeating, move it to the header. This uses __builtin_ffsll() to
allow using the macros in #define.

This is not using the QEMU's FIELD macros as this would require changing
all such macros found in skiboot (the PPC PowerNV firmware).

Signed-off-by: Alexey Kardashevskiy 
---
Changes:
v3:
* __builtin_ffsl -> __builtin_ffsll

v2:
* preserved the comment about skiboot
* copied the actual macros from skiboot:
https://github.com/open-power/skiboot/blob/master/include/bitutils.h#L31
---
 include/hw/pci-host/pnv_phb3_regs.h | 16 
 target/ppc/cpu.h| 12 
 hw/intc/pnv_xive.c  | 20 
 hw/intc/pnv_xive2.c | 20 
 hw/pci-host/pnv_phb4.c  | 16 
 5 files changed, 12 insertions(+), 72 deletions(-)

diff --git a/include/hw/pci-host/pnv_phb3_regs.h 
b/include/hw/pci-host/pnv_phb3_regs.h
index a174ef1f7045..38f8ce9d7406 100644
--- a/include/hw/pci-host/pnv_phb3_regs.h
+++ b/include/hw/pci-host/pnv_phb3_regs.h
@@ -12,22 +12,6 @@
 
 #include "qemu/host-utils.h"
 
-/*
- * QEMU version of the GETFIELD/SETFIELD macros
- *
- * These are common with the PnvXive model.
- */
-static inline uint64_t GETFIELD(uint64_t mask, uint64_t word)
-{
-return (word & mask) >> ctz64(mask);
-}
-
-static inline uint64_t SETFIELD(uint64_t mask, uint64_t word,
-uint64_t value)
-{
-return (word & ~mask) | ((value << ctz64(mask)) & mask);
-}
-
 /*
  * PBCQ XSCOM registers
  */
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 6d78078f379d..50cea032c853 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -47,6 +47,18 @@
  PPC_BIT32(bs))
 #define PPC_BITMASK8(bs, be)((PPC_BIT8(bs) - PPC_BIT8(be)) | PPC_BIT8(bs))
 
+/*
+ * QEMU version of the GETFIELD/SETFIELD macros from skiboot
+ *
+ * It might be better to use the existing extract64() and
+ * deposit64() but this means that all the register definitions will
+ * change and become incompatible with the ones found in skiboot.
+ */
+#define MASK_TO_LSH(m)  (__builtin_ffsll(m) - 1)
+#define GETFIELD(m, v)  (((v) & (m)) >> MASK_TO_LSH(m))
+#define SETFIELD(m, v, val) \
+(((v) & ~(m)) | typeof(v))(val)) << MASK_TO_LSH(m)) & (m)))
+
 /*/
 /* Exception vectors definitions */
 enum {
diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index 1ce1d7b07d63..c7b75ed12ee0 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -66,26 +66,6 @@ static const XiveVstInfo vst_infos[] = {
 qemu_log_mask(LOG_GUEST_ERROR, "XIVE[%x] - " fmt "\n",  \
   (xive)->chip->chip_id, ## __VA_ARGS__);
 
-/*
- * QEMU version of the GETFIELD/SETFIELD macros
- *
- * TODO: It might be better to use the existing extract64() and
- * deposit64() but this means that all the register definitions will
- * change and become incompatible with the ones found in skiboot.
- *
- * Keep it as it is for now until we find a common ground.
- */
-static inline uint64_t GETFIELD(uint64_t mask, uint64_t word)
-{
-return (word & mask) >> ctz64(mask);
-}
-
-static inline uint64_t SETFIELD(uint64_t mask, uint64_t word,
-uint64_t value)
-{
-return (word & ~mask) | ((value << ctz64(mask)) & mask);
-}
-
 /*
  * When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID
  * field overrides the hardwired chip ID in the Powerbus operations
diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
index f31c53c28dd2..f22ce5ca59ae 100644
--- a/hw/intc/pnv_xive2.c
+++ b/hw/intc/pnv_xive2.c
@@ -75,26 +75,6 @@ static const XiveVstInfo vst_infos[] = {
 qemu_log_mask(LOG_GUEST_ERROR, "XIVE[%x] - " fmt "\n",  \
   (xive)->chip->chip_id, ## __VA_ARGS__);
 
-/*
- * QEMU version of the GETFIELD/SETFIELD macros
- *
- * TODO: It might be better to use the existing extract64() and
- * deposit64() but this means that all the register definitions will
- * change and become incompatible with the ones found in skiboot.
- *
- * Keep it as it is for now until we find a common ground.
- */
-static inline uint64_t GETFIELD(uint64_t mask, uint64_t word)
-{
-return (word & mask) >> ctz64(mask);
-}
-
-static inline uint64_t SETFIELD(uint64_t mask, uint64_t word,
-uint64_t value)
-{
-return (word & ~mask) | ((value << ctz64(mask)) & mask);
-}
-
 /*
  * TODO: Document block id override
  */
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 6594016121a3..5d72c0c432b2 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -31,22 +31,6 @@
 qemu_log_mask(LOG_GUEST_ERROR, "phb4_pec[%d:%d]: " fmt "\n",\
   (pec)->chip_id, (pec)->index, ## __VA_ARGS__)
 
-/*
- * QEMU version of the GETFIELD/SETFIELD macros
- *
- 

Re: [RFC v3 1/5] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-06-28 Thread Damien Le Moal
On 6/28/22 17:05, Sam Li wrote:
> Stefan Hajnoczi  于2022年6月28日周二 14:52写道:
>>
>> On Mon, Jun 27, 2022 at 08:19:13AM +0800, Sam Li wrote:
>>> diff --git a/block/block-backend.c b/block/block-backend.c
>>> index e0e1aff4b1..786f964d02 100644
>>> --- a/block/block-backend.c
>>> +++ b/block/block-backend.c
>>> @@ -1810,6 +1810,62 @@ int blk_flush(BlockBackend *blk)
>>>  return ret;
>>>  }
>>>
>>> +/*
>>> + * Return zone_report from BlockDriver. Offset can be any number within
>>> + * the zone size. No alignment for offset and len.
>>
>> What is the purpose of len? Is it the maximum number of zones to return
>> in nr_zones[]?
> 
> len is actually not used in bdrv_co_zone_report. It is needed by
> blk_check_byte_request.

There is no IO buffer being passed. Only an array of zone descriptors and
an in-out number of zones. len is definitely not needed. Not sure what
blk_check_byte_request() is intended to check though.

> 
>> How does the caller know how many zones were returned?
> 
> nr_zones represents IN maximum and OUT actual. The caller will know by
> nr_zones which is changed in bdrv_co_zone_report. I'll add it in the
> comments.
> 
>>
>>> + */
>>> +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
>>> +   int64_t len, int64_t *nr_zones,
>>> +   BlockZoneDescriptor *zones)
>>> +{
>>> +int ret;
>>> +BlockDriverState *bs;
>>> +IO_CODE();
>>> +
>>> +blk_inc_in_flight(blk); /* increase before waiting */
>>> +blk_wait_while_drained(blk);
>>> +bs = blk_bs(blk);
>>> +
>>> +ret = blk_check_byte_request(blk, offset, len);
>>> +if (ret < 0) {
>>> +return ret;
>>> +}
>>> +
>>> +bdrv_inc_in_flight(bs);
>>
>> The bdrv_inc/dec_in_flight() call should be inside
>> bdrv_co_zone_report(). See bdrv_co_ioctl() for an example.
>>
>>> +ret = bdrv_co_zone_report(blk->root->bs, offset, len,
>>> +  nr_zones, zones);
>>> +bdrv_dec_in_flight(bs);
>>> +blk_dec_in_flight(blk);
>>> +return ret;
>>> +}
>>> +
>>> +/*
>>> + * Return zone_mgmt from BlockDriver.
>>
>> Maybe this should be:
>>
>>   Send a zone management command.
> 
> Yes, it's more accurate.
> 
>>
>>> @@ -216,6 +217,11 @@ typedef struct RawPosixAIOData {
>>>  PreallocMode prealloc;
>>>  Error **errp;
>>>  } truncate;
>>> +struct {
>>> +int64_t *nr_zones;
>>> +BlockZoneDescriptor *zones;
>>> +} zone_report;
>>> +zone_op op;
>>
>> It's cleaner to put op inside a struct zone_mgmt so its purpose is
>> self-explanatory:
>>
>>   struct {
>>   zone_op op;
>>   } zone_mgmt;
>>
>>> +static int handle_aiocb_zone_report(void *opaque) {
>>> +RawPosixAIOData *aiocb = opaque;
>>> +int fd = aiocb->aio_fildes;
>>> +int64_t *nr_zones = aiocb->zone_report.nr_zones;
>>> +BlockZoneDescriptor *zones = aiocb->zone_report.zones;
>>> +int64_t offset = aiocb->aio_offset;
>>> +int64_t len = aiocb->aio_nbytes;

Since you have the zone array and number of zones (size of that array) I
really do not see why you need len.

>>> +
>>> +struct blk_zone *blkz;
>>> +int64_t rep_size, nrz;
>>> +int ret, n = 0, i = 0;
>>> +
>>> +nrz = *nr_zones;
>>> +if (len == -1) {
>>> +return -errno;
>>
>> Where is errno set? Should this be an errno constant instead like
>> -EINVAL?
> 
> That's right! Noted.
> 
>>
>>> +}
>>> +rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct 
>>> blk_zone);
>>> +g_autofree struct blk_zone_report *rep = g_new(struct blk_zone_report, 
>>> nrz);
>>
>> g_new() looks incorrect. There should be 1 struct blk_zone_report
>> followed by nrz struct blk_zone structs. Please use g_malloc(rep_size)
>> instead.
> 
> Yes! However, it still has a memory leak error when using g_autofree
> && g_malloc.

That may be because you are changing the value of the rep pointer while
parsing the report ?

> 
>>
>>> +offset = offset / 512; /* get the unit of the start sector: sector 
>>> size is 512 bytes. */
>>> +printf("start to report zone with offset: 0x%lx\n", offset);
>>> +
>>> +blkz = (struct blk_zone *)(rep + 1);
>>> +while (n < nrz) {
>>> +memset(rep, 0, rep_size);
>>> +rep->sector = offset;
>>> +rep->nr_zones = nrz;
>>
>> What prevents zones[] overflowing? nrz isn't being reduced in the loop,
>> so maybe the rep->nr_zones return value will eventually exceed the
>> number of elements still available in zones[n..]?
> 
> I suppose the number of zones[] is restricted in the subsequent for
> loop where zones[] copy one zone at a time as n increases. Even if
> rep->zones exceeds the available room in zones[], the extra zone will
> not be copied.
> 
>>
>>> +static int handle_aiocb_zone_mgmt(void *opaque) {
>>> +RawPosixAIOData *aiocb = opaque;
>>> +int fd = aiocb->aio_fildes;
>>> +int64_t offset = aiocb->aio_offset;
>>> +int64_t len = 

Re: [PATCH 04/14] aspeed: i2c: Fix DMA len write-enable bit handling

2022-06-28 Thread Peter Delevoryas


> On Jun 28, 2022, at 12:01 AM, Cédric Le Goater  wrote:
> 
> On 6/27/22 21:54, Peter Delevoryas wrote:
>> I noticed i2c rx transfers were getting shortened to "1" on Zephyr. It
>> seems to be because the Zephyr i2c driver sets the RX DMA len with the
>> RX field write-enable bit set (bit 31) to avoid a read-modify-write. [1]
>> /* 0x1C : I2CM Master DMA Transfer Length Register   */
>> I think we should be checking the write-enable bits on the incoming
>> value, not checking the register array. I'm not sure we're even writing
>> the write-enable bits to the register array, actually.
>> [1] 
>> https://github.com/AspeedTech-BMC/zephyr/blob/db3dbcc9c52e67a47180890ac938ed380b33f91c/drivers/i2c/i2c_aspeed.c#L145-L148
>> Fixes: ba2cccd64e90f34 ("aspeed: i2c: Add new mode support")
>> Signed-off-by: Peter Delevoryas 
>> ---
> 
> Nice. Can you move this patch at beginning of the series ?

Yeah sure! I’ll do that on v2.

> 
> Reviewed-by: Cédric Le Goater 
> 
> Thanks,
> 
> C.
> 
> 
>>  hw/i2c/aspeed_i2c.c | 8 
>>  1 file changed, 4 insertions(+), 4 deletions(-)
>> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
>> index 2cfd05cb6c..6c8222717f 100644
>> --- a/hw/i2c/aspeed_i2c.c
>> +++ b/hw/i2c/aspeed_i2c.c
>> @@ -644,18 +644,18 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus 
>> *bus, hwaddr offset,
>>   RX_BUF_LEN) + 1;
>>  break;
>>  case A_I2CM_DMA_LEN:
>> -w1t = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN_W1T) ||
>> -   ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, 
>> TX_BUF_LEN_W1T);
>> +w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) ||
>> +  FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN_W1T);
>>  /* If none of the w1t bits are set, just write to the reg as 
>> normal. */
>>  if (!w1t) {
>>  bus->regs[R_I2CM_DMA_LEN] = value;
>>  break;
>>  }
>> -if (ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN_W1T)) {
>> +if (FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T)) {
>>  ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN,
>>   FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN));
>>  }
>> -if (ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, TX_BUF_LEN_W1T)) {
>> +if (FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN_W1T)) {
>>  ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, TX_BUF_LEN,
>>   FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN));
>>  }
> 



[PULL 29/60] semihosting: Split out semihost_sys_read

2022-06-28 Thread Richard Henderson
Split out the non-ARM specific portions of SYS_READ to a
reusable function.  This handles all GuestFD.  Isolate the
curious ARM-specific return value processing to a new
callback, common_semi_rw_cb.

Note that gdb_do_syscall %x reads target_ulong, not int.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/syscalls.h |  8 
 semihosting/arm-compat-semi.c  | 85 --
 semihosting/syscalls.c | 85 ++
 3 files changed, 113 insertions(+), 65 deletions(-)

diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 00e718f11d..20da8138b0 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -18,6 +18,8 @@
  * or non-zero (where it should include the terminating zero).
  */
 
+typedef struct GuestFD GuestFD;
+
 void semihost_sys_open(CPUState *cs, gdb_syscall_complete_cb complete,
target_ulong fname, target_ulong fname_len,
int gdb_flags, int mode);
@@ -25,4 +27,10 @@ void semihost_sys_open(CPUState *cs, gdb_syscall_complete_cb 
complete,
 void semihost_sys_close(CPUState *cs, gdb_syscall_complete_cb complete,
 int fd);
 
+void semihost_sys_read(CPUState *cs, gdb_syscall_complete_cb complete,
+   int fd, target_ulong buf, target_ulong len);
+
+void semihost_sys_read_gf(CPUState *cs, gdb_syscall_complete_cb complete,
+  GuestFD *gf, target_ulong buf, target_ulong len);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 0cb3db2a1a..8da31d8507 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -231,7 +231,6 @@ static void common_semi_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
 target_ulong reg0 = common_semi_arg(cs, 0);
 switch (reg0) {
 case TARGET_SYS_WRITE:
-case TARGET_SYS_READ:
 ret = common_semi_syscall_len - ret;
 break;
 case TARGET_SYS_SEEK:
@@ -244,6 +243,25 @@ static void common_semi_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
 common_semi_set_ret(cs, ret);
 }
 
+/*
+ * SYS_READ and SYS_WRITE always return the number of bytes not read/written.
+ * There is no error condition, other than returning the original length.
+ */
+static void common_semi_rw_cb(CPUState *cs, target_ulong ret, target_ulong err)
+{
+/* Recover the original length from the third argument. */
+CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
+target_ulong args = common_semi_arg(cs, 1);
+target_ulong arg2;
+GET_ARG(2);
+
+if (err) {
+ do_fault:
+ret = 0; /* error: no bytes transmitted */
+}
+common_semi_set_ret(cs, arg2 - ret);
+}
+
 /*
  * Return an address in target memory of 64 bytes where the remote
  * gdb should write its stat struct. (The format of this structure
@@ -278,8 +296,6 @@ common_semi_flen_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
  */
 typedef void sys_writefn(CPUState *cs, GuestFD *gf,
  target_ulong buf, uint32_t len);
-typedef void sys_readfn(CPUState *cs, GuestFD *gf,
-target_ulong buf, uint32_t len);
 typedef void sys_isattyfn(CPUState *cs, GuestFD *gf);
 typedef void sys_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset);
 typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
@@ -302,26 +318,6 @@ static void host_writefn(CPUState *cs, GuestFD *gf,
 common_semi_cb(cs, len - ret, 0);
 }
 
-static void host_readfn(CPUState *cs, GuestFD *gf,
-target_ulong buf, uint32_t len)
-{
-CPUArchState *env = cs->env_ptr;
-uint32_t ret = 0;
-char *s = lock_user(VERIFY_WRITE, buf, len, 0);
-(void) env; /* Used in arm softmmu lock_user implicitly */
-if (s) {
-do {
-ret = read(gf->hostfd, s, len);
-} while (ret == -1 && errno == EINTR);
-unlock_user(s, buf, len);
-if (ret == (uint32_t)-1) {
-ret = 0;
-}
-}
-/* Return bytes not read, on error as well. */
-common_semi_cb(cs, len - ret, 0);
-}
-
 static void host_isattyfn(CPUState *cs, GuestFD *gf)
 {
 common_semi_cb(cs, isatty(gf->hostfd), 0);
@@ -351,13 +347,6 @@ static void gdb_writefn(CPUState *cs, GuestFD *gf,
 gdb_do_syscall(common_semi_cb, "write,%x,%x,%x", gf->hostfd, buf, len);
 }
 
-static void gdb_readfn(CPUState *cs, GuestFD *gf,
-   target_ulong buf, uint32_t len)
-{
-common_semi_syscall_len = len;
-gdb_do_syscall(common_semi_cb, "read,%x,%x,%x", gf->hostfd, buf, len);
-}
-
 static void gdb_isattyfn(CPUState *cs, GuestFD *gf)
 {
 gdb_do_syscall(common_semi_cb, "isatty,%x", gf->hostfd);
@@ -398,30 +387,6 @@ static void staticfile_writefn(CPUState *cs, GuestFD *gf,
 common_semi_cb(cs, -1, EBADF);
 }
 
-static void staticfile_readfn(CPUState *cs, GuestFD 

[PATCH v7 1/4] Revert "target/riscv: Add dummy mcountinhibit CSR for priv spec v1.11 or higher"

2022-06-28 Thread Anup Patel
This reverts commit 33cc1c0b69e457f5c526f64297353cba6f7bfdb4 because
commit eab4776b2badd4088a4f807c9bb3dc453c53dc23 already implements
proper mcountinhibit CSR emulation.

Signed-off-by: Anup Patel 
---
 target/riscv/cpu_bits.h | 3 ---
 target/riscv/csr.c  | 2 --
 2 files changed, 5 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8724b45c08..b3f7fa7130 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -159,9 +159,6 @@
 #define CSR_MTVEC   0x305
 #define CSR_MCOUNTEREN  0x306
 
-/* Machine Counter Setup */
-#define CSR_MCOUNTINHIBIT   0x320
-
 /* 32-bit only */
 #define CSR_MSTATUSH0x310
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b5734957cf..d65318dcc6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3642,8 +3642,6 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_MIE] = { "mie",any,   NULL,NULL,rmw_mie   
},
 [CSR_MTVEC]   = { "mtvec",  any,   read_mtvec,   write_mtvec   
},
 [CSR_MCOUNTEREN]  = { "mcounteren", any,   read_mcounteren,  
write_mcounteren  },
-[CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_zero, write_ignore,
- .min_priv_ver = 
PRIV_VERSION_1_11_0 },
 
 [CSR_MSTATUSH]= { "mstatush",   any32, read_mstatush,
write_mstatush},
 
-- 
2.34.1




[PULL 23/60] semihosting: Split out common_semi_has_synccache

2022-06-28 Thread Richard Henderson
We already have some larger ifdef blocks for ARM and RISCV;
split out a boolean test for SYS_SYNCCACHE.

Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 semihosting/arm-compat-semi.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 7550dce622..50f40a2a1a 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -224,6 +224,12 @@ static inline target_ulong 
common_semi_stack_bottom(CPUState *cs)
 CPUARMState *env = >env;
 return is_a64(env) ? env->xregs[31] : env->regs[13];
 }
+
+static inline bool common_semi_has_synccache(CPUArchState *env)
+{
+/* Ok for A64, invalid for A32/T32. */
+return is_a64(env);
+}
 #endif /* TARGET_ARM */
 
 #ifdef TARGET_RISCV
@@ -260,6 +266,11 @@ static inline target_ulong 
common_semi_stack_bottom(CPUState *cs)
 CPURISCVState *env = >env;
 return env->gpr[xSP];
 }
+
+static inline bool common_semi_has_synccache(CPUArchState *env)
+{
+return true;
+}
 #endif
 
 /*
@@ -1102,16 +1113,11 @@ void do_common_semihosting(CPUState *cs)
  * virtual address range. This is a nop for us since we don't
  * implement caches. This is only present on A64.
  */
-#ifdef TARGET_ARM
-if (is_a64(cs->env_ptr)) {
+if (common_semi_has_synccache(env)) {
 common_semi_set_ret(cs, 0);
 break;
 }
-#endif
-#ifdef TARGET_RISCV
-common_semi_set_ret(cs, 0);
-#endif
-/* fall through -- invalid for A32/T32 */
+/* fall through */
 default:
 fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
 cpu_dump_state(cs, stderr, 0);
-- 
2.34.1




[PULL 24/60] semihosting: Split out common-semi-target.h

2022-06-28 Thread Richard Henderson
Move the ARM and RISCV specific helpers into
their own header file.

Reviewed-by: Alex Bennée 
Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 target/arm/common-semi-target.h   | 62 
 target/riscv/common-semi-target.h | 50 
 semihosting/arm-compat-semi.c | 94 +--
 3 files changed, 113 insertions(+), 93 deletions(-)
 create mode 100644 target/arm/common-semi-target.h
 create mode 100644 target/riscv/common-semi-target.h

diff --git a/target/arm/common-semi-target.h b/target/arm/common-semi-target.h
new file mode 100644
index 00..629d75ca5a
--- /dev/null
+++ b/target/arm/common-semi-target.h
@@ -0,0 +1,62 @@
+/*
+ * Target-specific parts of semihosting/arm-compat-semi.c.
+ *
+ * Copyright (c) 2005, 2007 CodeSourcery.
+ * Copyright (c) 2019, 2022 Linaro
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef TARGET_ARM_COMMON_SEMI_TARGET_H
+#define TARGET_ARM_COMMON_SEMI_TARGET_H
+
+#ifndef CONFIG_USER_ONLY
+#include "hw/arm/boot.h"
+#endif
+
+static inline target_ulong common_semi_arg(CPUState *cs, int argno)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = >env;
+if (is_a64(env)) {
+return env->xregs[argno];
+} else {
+return env->regs[argno];
+}
+}
+
+static inline void common_semi_set_ret(CPUState *cs, target_ulong ret)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = >env;
+if (is_a64(env)) {
+env->xregs[0] = ret;
+} else {
+env->regs[0] = ret;
+}
+}
+
+static inline bool common_semi_sys_exit_extended(CPUState *cs, int nr)
+{
+return (nr == TARGET_SYS_EXIT_EXTENDED || is_a64(cs->env_ptr));
+}
+
+static inline bool is_64bit_semihosting(CPUArchState *env)
+{
+return is_a64(env);
+}
+
+static inline target_ulong common_semi_stack_bottom(CPUState *cs)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = >env;
+return is_a64(env) ? env->xregs[31] : env->regs[13];
+}
+
+static inline bool common_semi_has_synccache(CPUArchState *env)
+{
+/* Ok for A64, invalid for A32/T32 */
+return is_a64(env);
+}
+
+#endif
diff --git a/target/riscv/common-semi-target.h 
b/target/riscv/common-semi-target.h
new file mode 100644
index 00..7c8a59e0cc
--- /dev/null
+++ b/target/riscv/common-semi-target.h
@@ -0,0 +1,50 @@
+/*
+ * Target-specific parts of semihosting/arm-compat-semi.c.
+ *
+ * Copyright (c) 2005, 2007 CodeSourcery.
+ * Copyright (c) 2019, 2022 Linaro
+ * Copyright © 2020 by Keith Packard 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef TARGET_RISCV_COMMON_SEMI_TARGET_H
+#define TARGET_RISCV_COMMON_SEMI_TARGET_H
+
+static inline target_ulong common_semi_arg(CPUState *cs, int argno)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+return env->gpr[xA0 + argno];
+}
+
+static inline void common_semi_set_ret(CPUState *cs, target_ulong ret)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+env->gpr[xA0] = ret;
+}
+
+static inline bool common_semi_sys_exit_extended(CPUState *cs, int nr)
+{
+return (nr == TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) == 8);
+}
+
+static inline bool is_64bit_semihosting(CPUArchState *env)
+{
+return riscv_cpu_mxl(env) != MXL_RV32;
+}
+
+static inline target_ulong common_semi_stack_bottom(CPUState *cs)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = >env;
+return env->gpr[xSP];
+}
+
+static inline bool common_semi_has_synccache(CPUArchState *env)
+{
+return true;
+}
+
+#endif
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 50f40a2a1a..5e442e549d 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -46,9 +46,6 @@
 #else
 #include "qemu/cutils.h"
 #include "hw/loader.h"
-#ifdef TARGET_ARM
-#include "hw/arm/boot.h"
-#endif
 #include "hw/boards.h"
 #endif
 
@@ -182,96 +179,7 @@ static LayoutInfo common_semi_find_bases(CPUState *cs)
 
 #endif
 
-#ifdef TARGET_ARM
-static inline target_ulong
-common_semi_arg(CPUState *cs, int argno)
-{
-ARMCPU *cpu = ARM_CPU(cs);
-CPUARMState *env = >env;
-if (is_a64(env)) {
-return env->xregs[argno];
-} else {
-return env->regs[argno];
-}
-}
-
-static inline void
-common_semi_set_ret(CPUState *cs, target_ulong ret)
-{
-ARMCPU *cpu = ARM_CPU(cs);
-CPUARMState *env = >env;
-if (is_a64(env)) {
-env->xregs[0] = ret;
-} else {
-env->regs[0] = ret;
-}
-}
-
-static inline bool
-common_semi_sys_exit_extended(CPUState *cs, int nr)
-{
-return (nr == TARGET_SYS_EXIT_EXTENDED || is_a64(cs->env_ptr));
-}
-
-static inline bool is_64bit_semihosting(CPUArchState *env)
-{
-return is_a64(env);
-}
-
-static inline target_ulong common_semi_stack_bottom(CPUState *cs)
-{
-ARMCPU *cpu = ARM_CPU(cs);
-CPUARMState *env = >env;
-return is_a64(env) ? env->xregs[31] : env->regs[13];
-}
-
-static inline bool 

[PULL 36/60] semihosting: Split out semihost_sys_rename

2022-06-28 Thread Richard Henderson
Split out the non-ARM specific portions of SYS_RENAME to a
reusable function.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/semihosting/syscalls.h |  4 +++
 semihosting/arm-compat-semi.c  | 21 +
 semihosting/syscalls.c | 57 ++
 3 files changed, 62 insertions(+), 20 deletions(-)

diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 748a4b5e47..21430aa0ef 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -52,4 +52,8 @@ void semihost_sys_flen(CPUState *cs, gdb_syscall_complete_cb 
fstat_cb,
 void semihost_sys_remove(CPUState *cs, gdb_syscall_complete_cb complete,
  target_ulong fname, target_ulong fname_len);
 
+void semihost_sys_rename(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong oname, target_ulong oname_len,
+ target_ulong nname, target_ulong nname_len);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index f4ce3851a4..14d37ac9da 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -492,26 +492,7 @@ void do_common_semihosting(CPUState *cs)
 GET_ARG(1);
 GET_ARG(2);
 GET_ARG(3);
-if (use_gdb_syscalls()) {
-gdb_do_syscall(common_semi_cb, "rename,%s,%s",
-   arg0, (int)arg1 + 1, arg2, (int)arg3 + 1);
-} else {
-char *s2;
-
-s = lock_user_string(arg0);
-if (!s) {
-goto do_fault;
-}
-s2 = lock_user_string(arg2);
-if (!s2) {
-unlock_user(s, arg0, 0);
-goto do_fault;
-}
-ret = rename(s, s2);
-unlock_user(s2, arg2, 0);
-unlock_user(s, arg0, 0);
-common_semi_cb(cs, ret, ret ? errno : 0);
-}
+semihost_sys_rename(cs, common_semi_cb, arg0, arg1 + 1, arg2, arg3 + 
1);
 break;
 
 case TARGET_SYS_CLOCK:
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 5ec4e8f827..223916b110 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -145,6 +145,26 @@ static void gdb_remove(CPUState *cs, 
gdb_syscall_complete_cb complete,
 gdb_do_syscall(complete, "unlink,%s", fname, len);
 }
 
+static void gdb_rename(CPUState *cs, gdb_syscall_complete_cb complete,
+   target_ulong oname, target_ulong oname_len,
+   target_ulong nname, target_ulong nname_len)
+{
+int olen, nlen;
+
+olen = validate_strlen(cs, oname, oname_len);
+if (olen < 0) {
+complete(cs, -1, -olen);
+return;
+}
+nlen = validate_strlen(cs, nname, nname_len);
+if (nlen < 0) {
+complete(cs, -1, -nlen);
+return;
+}
+
+gdb_do_syscall(complete, "rename,%s,%s", oname, olen, nname, nlen);
+}
+
 /*
  * Host semihosting syscall implementations.
  */
@@ -307,6 +327,32 @@ static void host_remove(CPUState *cs, 
gdb_syscall_complete_cb complete,
 unlock_user(p, fname, 0);
 }
 
+static void host_rename(CPUState *cs, gdb_syscall_complete_cb complete,
+target_ulong oname, target_ulong oname_len,
+target_ulong nname, target_ulong nname_len)
+{
+CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
+char *ostr, *nstr;
+int ret;
+
+ret = validate_lock_user_string(, cs, oname, oname_len);
+if (ret < 0) {
+complete(cs, -1, -ret);
+return;
+}
+ret = validate_lock_user_string(, cs, nname, nname_len);
+if (ret < 0) {
+unlock_user(ostr, oname, 0);
+complete(cs, -1, -ret);
+return;
+}
+
+ret = rename(ostr, nstr);
+complete(cs, ret, ret ? errno : 0);
+unlock_user(ostr, oname, 0);
+unlock_user(nstr, nname, 0);
+}
+
 /*
  * Static file semihosting syscall implementations.
  */
@@ -562,3 +608,14 @@ void semihost_sys_remove(CPUState *cs, 
gdb_syscall_complete_cb complete,
 host_remove(cs, complete, fname, fname_len);
 }
 }
+
+void semihost_sys_rename(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong oname, target_ulong oname_len,
+ target_ulong nname, target_ulong nname_len)
+{
+if (use_gdb_syscalls()) {
+gdb_rename(cs, complete, oname, oname_len, nname, nname_len);
+} else {
+host_rename(cs, complete, oname, oname_len, nname, nname_len);
+}
+}
-- 
2.34.1




[PULL 32/60] semihosting: Split out semihost_sys_lseek

2022-06-28 Thread Richard Henderson
Split out the non-ARM specific portions of SYS_SEEK to a
reusable function.  This handles all GuestFD.  Isolate the
curious ARM-specific return value processing to a new
callback, common_semi_seek_cb.

Expand the internal type of the offset to int64_t, and
provide the whence argument, which will be required by
m68k and nios2 semihosting.

Note that gdb_do_syscall %x reads target_ulong, not int.

Reviewed-by: Luc Michel 
Signed-off-by: Richard Henderson 
---
 include/exec/gdbstub.h |  5 +++
 include/semihosting/syscalls.h |  3 ++
 semihosting/arm-compat-semi.c  | 51 ++---
 semihosting/syscalls.c | 81 ++
 4 files changed, 102 insertions(+), 38 deletions(-)

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 95a8b7b056..b588c306cc 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -41,6 +41,11 @@
 #define GDB_ENAMETOOLONG   91
 #define GDB_EUNKNOWN   
 
+/* For gdb file i/o remote protocol lseek whence. */
+#define GDB_SEEK_SET  0
+#define GDB_SEEK_CUR  1
+#define GDB_SEEK_END  2
+
 /* For gdb file i/o stat/fstat. */
 typedef uint32_t gdb_mode_t;
 typedef uint32_t gdb_time_t;
diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 2464467579..841a93d25b 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -39,4 +39,7 @@ void semihost_sys_write(CPUState *cs, gdb_syscall_complete_cb 
complete,
 void semihost_sys_write_gf(CPUState *cs, gdb_syscall_complete_cb complete,
GuestFD *gf, target_ulong buf, target_ulong len);
 
+void semihost_sys_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
+int fd, int64_t off, int gdb_whence);
+
 #endif /* SEMIHOSTING_SYSCALLS_H */
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index d591fcd7c2..a117d180bc 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -224,16 +224,6 @@ static void common_semi_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
 #else
 syscall_err = err;
 #endif
-} else {
-/* Fixup syscalls that use nonstardard return conventions.  */
-target_ulong reg0 = common_semi_arg(cs, 0);
-switch (reg0) {
-case TARGET_SYS_SEEK:
-ret = 0;
-break;
-default:
-break;
-}
 }
 common_semi_set_ret(cs, ret);
 }
@@ -257,6 +247,18 @@ static void common_semi_rw_cb(CPUState *cs, target_ulong 
ret, target_ulong err)
 common_semi_set_ret(cs, arg2 - ret);
 }
 
+/*
+ * SYS_SEEK returns 0 on success, not the resulting offset.
+ */
+static void common_semi_seek_cb(CPUState *cs, target_ulong ret,
+target_ulong err)
+{
+if (!err) {
+ret = 0;
+}
+common_semi_cb(cs, ret, err);
+}
+
 /*
  * Return an address in target memory of 64 bytes where the remote
  * gdb should write its stat struct. (The format of this structure
@@ -290,7 +292,6 @@ common_semi_flen_cb(CPUState *cs, target_ulong ret, 
target_ulong err)
  * via common_semi_cb.
  */
 typedef void sys_isattyfn(CPUState *cs, GuestFD *gf);
-typedef void sys_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset);
 typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
 
 static void host_isattyfn(CPUState *cs, GuestFD *gf)
@@ -298,12 +299,6 @@ static void host_isattyfn(CPUState *cs, GuestFD *gf)
 common_semi_cb(cs, isatty(gf->hostfd), 0);
 }
 
-static void host_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
-{
-off_t ret = lseek(gf->hostfd, offset, SEEK_SET);
-common_semi_cb(cs, ret, ret == -1 ? errno : 0);
-}
-
 static void host_flenfn(CPUState *cs, GuestFD *gf)
 {
 struct stat buf;
@@ -320,11 +315,6 @@ static void gdb_isattyfn(CPUState *cs, GuestFD *gf)
 gdb_do_syscall(common_semi_cb, "isatty,%x", gf->hostfd);
 }
 
-static void gdb_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
-{
-gdb_do_syscall(common_semi_cb, "lseek,%x,%x,0", gf->hostfd, offset);
-}
-
 static void gdb_flenfn(CPUState *cs, GuestFD *gf)
 {
 gdb_do_syscall(common_semi_flen_cb, "fstat,%x,%x",
@@ -353,12 +343,6 @@ static void staticfile_isattyfn(CPUState *cs, GuestFD *gf)
 common_semi_cb(cs, 0, 0);
 }
 
-static void staticfile_seekfn(CPUState *cs, GuestFD *gf, target_ulong offset)
-{
-gf->staticfile.off = offset;
-common_semi_cb(cs, 0, 0);
-}
-
 static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
 {
 common_semi_cb(cs, gf->staticfile.len, 0);
@@ -366,24 +350,20 @@ static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
 
 typedef struct GuestFDFunctions {
 sys_isattyfn *isattyfn;
-sys_seekfn *seekfn;
 sys_flenfn *flenfn;
 } GuestFDFunctions;
 
 static const GuestFDFunctions guestfd_fns[] = {
 [GuestFDHost] = {
 .isattyfn = host_isattyfn,
-.seekfn = host_seekfn,
 .flenfn = host_flenfn,
 },
 [GuestFDGDB] = {
 .isattyfn = 

[PULL 00/60] semihosting patch queue

2022-06-28 Thread Richard Henderson
The following changes since commit 29f6db75667f44f3f01ba5037dacaf9ebd9328da:

  Merge tag 'pull-target-arm-20220627' of 
https://git.linaro.org/people/pmaydell/qemu-arm into staging (2022-06-27 
16:47:39 +0530)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-semi-20220628

for you to fetch changes up to ca97e0ef99045ce650b842f3bc8c89d76daaafae:

  target/nios2: Move nios2-semi.c to nios2_softmmu_ss (2022-06-28 10:18:57 
+0530)


Semihosting syscall reorg:
  * Split out semihosting/syscalls.c with common implementations.
  * Reorg arm-compat-semi.c to use syscalls.c.
  * Minor prep cleanups to m68k, mips, nios2.


Richard Henderson (60):
  semihosting: Move exec/softmmu-semi.h to semihosting/softmmu-uaccess.h
  semihosting: Return failure from softmmu-uaccess.h functions
  semihosting: Improve condition for config.c and console.c
  semihosting: Move softmmu-uaccess.h functions out of line
  accel/stubs: Add tcg stub for probe_access_flags
  semihosting: Add target_strlen for softmmu-uaccess.h
  semihosting: Simplify softmmu_lock_user_string
  semihosting: Split out guestfd.c
  semihosting: Inline set_swi_errno into common_semi_cb
  semihosting: Adjust error checking in common_semi_cb
  semihosting: Clean up common_semi_flen_cb
  semihosting: Clean up common_semi_open_cb
  semihosting: Return void from do_common_semihosting
  semihosting: Move common-semi.h to include/semihosting/
  semihosting: Remove GDB_O_BINARY
  include/exec: Move gdb open flags to gdbstub.h
  include/exec: Move gdb_stat and gdb_timeval to gdbstub.h
  include/exec: Define errno values in gdbstub.h
  gdbstub: Convert GDB error numbers to host error numbers
  semihosting: Use struct gdb_stat in common_semi_flen_cb
  semihosting: Split is_64bit_semihosting per target
  semihosting: Split common_semi_flen_buf per target
  semihosting: Split out common_semi_has_synccache
  semihosting: Split out common-semi-target.h
  semihosting: Use env more often in do_common_semihosting
  semihosting: Move GET_ARG/SET_ARG earlier in the file
  semihosting: Split out semihost_sys_open
  semihosting: Split out semihost_sys_close
  semihosting: Split out semihost_sys_read
  semihosting: Split out semihost_sys_write
  semihosting: Bound length for semihost_sys_{read,write}
  semihosting: Split out semihost_sys_lseek
  semihosting: Split out semihost_sys_isatty
  semihosting: Split out semihost_sys_flen
  semihosting: Split out semihost_sys_remove
  semihosting: Split out semihost_sys_rename
  semihosting: Split out semihost_sys_system
  semihosting: Create semihost_sys_{stat,fstat}
  semihosting: Create semihost_sys_gettimeofday
  gdbstub: Adjust gdb_syscall_complete_cb declaration
  semihosting: Fix docs comment for qemu_semihosting_console_inc
  semihosting: Pass CPUState to qemu_semihosting_console_inc
  semihosting: Expand qemu_semihosting_console_inc to read
  semihosting: Cleanup chardev init
  semihosting: Create qemu_semihosting_console_write
  semihosting: Add GuestFDConsole
  semihosting: Create qemu_semihosting_guestfd_init
  semihosting: Use console_in_gf for SYS_READC
  semihosting: Use console_out_gf for SYS_WRITEC
  semihosting: Remove qemu_semihosting_console_outc
  semihosting: Use console_out_gf for SYS_WRITE0
  semihosting: Remove qemu_semihosting_console_outs
  semihosting: Create semihost_sys_poll_one
  target/m68k: Eliminate m68k_semi_is_fseek
  target/m68k: Make semihosting system only
  target/mips: Use an exception for semihosting
  target/mips: Add UHI errno values
  target/mips: Drop pread and pwrite syscalls from semihosting
  target/nios2: Eliminate nios2_semi_is_lseek
  target/nios2: Move nios2-semi.c to nios2_softmmu_ss

 configs/targets/aarch64-linux-user.mak |1 +
 configs/targets/aarch64_be-linux-user.mak  |1 +
 configs/targets/arm-linux-user.mak |1 +
 configs/targets/armeb-linux-user.mak   |1 +
 configs/targets/riscv32-linux-user.mak |1 +
 configs/targets/riscv64-linux-user.mak |1 +
 include/exec/gdbstub.h |   64 +-
 include/exec/softmmu-semi.h|  101 --
 {semihosting => include/semihosting}/common-semi.h |2 +-
 include/semihosting/console.h  |   71 +-
 include/semihosting/guestfd.h  |   91 ++
 include/semihosting/semihost.h |   14 +-
 include/semihosting/softmmu-uaccess.h  |   59 ++
 include/semihosting/syscalls.h |   75 ++
 target/arm/common-semi-target.h|  

[PULL 52/60] semihosting: Remove qemu_semihosting_console_outs

2022-06-28 Thread Richard Henderson
This function has been replaced by *_write.

Reviewed-by: Luc Michel 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 include/semihosting/console.h | 13 --
 linux-user/semihost.c | 17 
 semihosting/console.c | 49 ---
 3 files changed, 79 deletions(-)

diff --git a/include/semihosting/console.h b/include/semihosting/console.h
index d6c1cc58ab..20c31d89d4 100644
--- a/include/semihosting/console.h
+++ b/include/semihosting/console.h
@@ -11,19 +11,6 @@
 
 #include "cpu.h"
 
-/**
- * qemu_semihosting_console_outs:
- * @env: CPUArchState
- * @s: host address of null terminated guest string
- *
- * Send a null terminated guest string to the debug console. This may
- * be the remote gdb session if a softmmu guest is currently being
- * debugged.
- *
- * Returns: number of bytes written.
- */
-int qemu_semihosting_console_outs(CPUArchState *env, target_ulong s);
-
 /**
  * qemu_semihosting_console_read:
  * @cs: CPUState
diff --git a/linux-user/semihost.c b/linux-user/semihost.c
index f8bc8889f3..cee62a365c 100644
--- a/linux-user/semihost.c
+++ b/linux-user/semihost.c
@@ -16,23 +16,6 @@
 #include "user-internals.h"
 #include 
 
-int qemu_semihosting_console_outs(CPUArchState *env, target_ulong addr)
-{
-int len = target_strlen(addr);
-void *s;
-if (len < 0){
-   qemu_log_mask(LOG_GUEST_ERROR,
- "%s: passed inaccessible address " TARGET_FMT_lx,
- __func__, addr);
-   return 0;
-}
-s = lock_user(VERIFY_READ, addr, (long)(len + 1), 1);
-g_assert(s);  /* target_strlen has already verified this will work */
-len = write(STDERR_FILENO, s, len);
-unlock_user(s, addr, 0);
-return len;
-}
-
 /*
  * For linux-user we can safely block. However as we want to return as
  * soon as a character is read we need to tweak the termio to disable
diff --git a/semihosting/console.c b/semihosting/console.c
index fe7ee85137..c84ab97ab6 100644
--- a/semihosting/console.c
+++ b/semihosting/console.c
@@ -47,55 +47,6 @@ int qemu_semihosting_log_out(const char *s, int len)
 }
 }
 
-/*
- * A re-implementation of lock_user_string that we can use locally
- * instead of relying on softmmu-semi. Hopefully we can deprecate that
- * in time. Copy string until we find a 0 or address error.
- */
-static GString *copy_user_string(CPUArchState *env, target_ulong addr)
-{
-CPUState *cpu = env_cpu(env);
-GString *s = g_string_sized_new(128);
-uint8_t c;
-
-do {
-if (cpu_memory_rw_debug(cpu, addr++, , 1, 0) == 0) {
-if (c) {
-s = g_string_append_c(s, c);
-}
-} else {
-qemu_log_mask(LOG_GUEST_ERROR,
-  "%s: passed inaccessible address " TARGET_FMT_lx,
-  __func__, addr);
-break;
-}
-} while (c!=0);
-
-return s;
-}
-
-static void semihosting_cb(CPUState *cs, uint64_t ret, int err)
-{
-if (err) {
-qemu_log("%s: gdb console output failed (%d)\n", __func__, err);
-}
-}
-
-int qemu_semihosting_console_outs(CPUArchState *env, target_ulong addr)
-{
-GString *s = copy_user_string(env, addr);
-int out = s->len;
-
-if (use_gdb_syscalls()) {
-gdb_do_syscall(semihosting_cb, "write,2,%x,%x", addr, s->len);
-} else {
-out = qemu_semihosting_log_out(s->str, s->len);
-}
-
-g_string_free(s, true);
-return out;
-}
-
 #define FIFO_SIZE   1024
 
 static int console_can_read(void *opaque)
-- 
2.34.1




[PULL 58/60] target/mips: Drop pread and pwrite syscalls from semihosting

2022-06-28 Thread Richard Henderson
We don't implement it with _WIN32 hosts, and the syscalls
are missing from the gdb remote file i/o interface.
Since we can't implement them universally, drop them.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/mips/tcg/sysemu/mips-semi.c | 39 ++
 1 file changed, 7 insertions(+), 32 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index 2a039baf4c..67c35fe7f9 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -182,8 +182,8 @@ static int get_open_flags(target_ulong target_flags)
 return open_flags;
 }
 
-static int write_to_file(CPUMIPSState *env, target_ulong fd, target_ulong 
vaddr,
- target_ulong len, target_ulong offset)
+static int write_to_file(CPUMIPSState *env, target_ulong fd,
+ target_ulong vaddr, target_ulong len)
 {
 int num_of_bytes;
 void *dst = lock_user(VERIFY_READ, vaddr, len, 1);
@@ -192,23 +192,14 @@ static int write_to_file(CPUMIPSState *env, target_ulong 
fd, target_ulong vaddr,
 return -1;
 }
 
-if (offset) {
-#ifdef _WIN32
-num_of_bytes = 0;
-#else
-num_of_bytes = pwrite(fd, dst, len, offset);
-#endif
-} else {
-num_of_bytes = write(fd, dst, len);
-}
+num_of_bytes = write(fd, dst, len);
 
 unlock_user(dst, vaddr, 0);
 return num_of_bytes;
 }
 
 static int read_from_file(CPUMIPSState *env, target_ulong fd,
-  target_ulong vaddr, target_ulong len,
-  target_ulong offset)
+  target_ulong vaddr, target_ulong len)
 {
 int num_of_bytes;
 void *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
@@ -217,15 +208,7 @@ static int read_from_file(CPUMIPSState *env, target_ulong 
fd,
 return -1;
 }
 
-if (offset) {
-#ifdef _WIN32
-num_of_bytes = 0;
-#else
-num_of_bytes = pread(fd, dst, len, offset);
-#endif
-} else {
-num_of_bytes = read(fd, dst, len);
-}
+num_of_bytes = read(fd, dst, len);
 
 unlock_user(dst, vaddr, len);
 return num_of_bytes;
@@ -312,11 +295,11 @@ void mips_semihosting(CPUMIPSState *env)
 gpr[3] = errno_mips(errno);
 break;
 case UHI_read:
-gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], 0);
+gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6]);
 gpr[3] = errno_mips(errno);
 break;
 case UHI_write:
-gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], 0);
+gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6]);
 gpr[3] = errno_mips(errno);
 break;
 case UHI_lseek:
@@ -382,14 +365,6 @@ void mips_semihosting(CPUMIPSState *env)
 FREE_TARGET_STRING(p, gpr[4]);
 abort();
 break;
-case UHI_pread:
-gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
-gpr[3] = errno_mips(errno);
-break;
-case UHI_pwrite:
-gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
-gpr[3] = errno_mips(errno);
-break;
 #ifndef _WIN32
 case UHI_link:
 GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
-- 
2.34.1




  1   2   3   4   >