Re: [PATCH v2 2/6] accel: accel_available() function

2020-11-26 Thread Eduardo Habkost
On Thu, Nov 26, 2020 at 10:14:31AM +0100, Claudio Fontana wrote:
> Hi Eduardo,
> 
> On 11/25/20 9:56 PM, Eduardo Habkost wrote:
> > This function will be used to replace the xen_available() and
> > kvm_available() functions from arch_init.c.
> > 
> > Signed-off-by: Eduardo Habkost 
> > ---
> > Cc: Richard Henderson 
> > Cc: Paolo Bonzini 
> > Cc: Claudio Fontana 
> > Cc: Roman Bolshakov 
> > ---
> >  include/sysemu/accel.h | 1 +
> >  accel/accel.c  | 5 +
> >  2 files changed, 6 insertions(+)
> > 
> > diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
> > index e08b8ab8fa..a4a00c75c8 100644
> > --- a/include/sysemu/accel.h
> > +++ b/include/sysemu/accel.h
> > @@ -67,6 +67,7 @@ typedef struct AccelClass {
> >  OBJECT_GET_CLASS(AccelClass, (obj), TYPE_ACCEL)
> >  
> >  AccelClass *accel_find(const char *opt_name);
> > +bool accel_available(const char *name);
> >  int accel_init_machine(AccelState *accel, MachineState *ms);
> >  
> >  /* Called just before os_setup_post (ie just before drop OS privs) */
> > diff --git a/accel/accel.c b/accel/accel.c
> > index cb555e3b06..4a64a2b38a 100644
> > --- a/accel/accel.c
> > +++ b/accel/accel.c
> > @@ -46,6 +46,11 @@ AccelClass *accel_find(const char *opt_name)
> >  return ac;
> >  }
> >  
> > +bool accel_available(const char *name)
> > +{
> > +return accel_find(name) != NULL;
> 
> 
> accel_find() in its implementation allocates and then frees memory to 
> generate the string,
> the user of accel_available() might be unaware and overuse leading to 
> fragmentation/performance issues?

Is that a real issue?  We had only 3 users of kvm_available() and
xen_available() since those functions were added 10 years ago.

Do you have any suggestions on what we should do?

-- 
Eduardo




[PATCH v2 5/6] Remove unnecessary usage of arch_init.h

2020-11-25 Thread Eduardo Habkost
The only declarations in arch_init.h are the `arch_type` variable
and the QEMU_ARCH_* constants.  Stop including arch_init.h from
code that don't use neither.

Patch generated automatically using the command:

 $ sed -i -e '/#include "sysemu.arch_init.h"/d' \
   $(comm -23 \
  <(git grep -l arch_init.h | sort) \
  <((git grep -l -w 'arch_type'; g grep -l QEMU_ARCH;) | sort -u))

Signed-off-by: Eduardo Habkost 
---
Cc: Richard Henderson 
Cc: Paolo Bonzini 
Cc: Eduardo Habkost 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: "Hervé Poussineau" 
Cc: Aleksandar Rikalo 
Cc: "Philippe Mathieu-Daudé" 
Cc: Aurelien Jarno 
Cc: Jiaxun Yang 
Cc: David Gibson 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Markus Armbruster 
Cc: David Hildenbrand 
Cc: Cornelia Huck 
Cc: Thomas Huth 
Cc: Halil Pasic 
Cc: Christian Borntraeger 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: qemu-ri...@nongnu.org
Cc: qemu-s3...@nongnu.org
---
 accel/accel.c   | 1 -
 hw/i386/pc.c| 1 -
 hw/i386/pc_piix.c   | 1 -
 hw/i386/pc_q35.c| 1 -
 hw/mips/jazz.c  | 1 -
 hw/mips/malta.c | 1 -
 hw/ppc/prep.c   | 1 -
 hw/riscv/sifive_e.c | 1 -
 hw/riscv/sifive_u.c | 1 -
 hw/riscv/spike.c| 1 -
 hw/riscv/virt.c | 1 -
 monitor/qmp-cmds.c  | 1 -
 target/i386/cpu.c   | 1 -
 target/s390x/cpu.c  | 1 -
 target/s390x/cpu_models.c   | 1 -
 target/ppc/translate_init.c.inc | 1 -
 16 files changed, 16 deletions(-)

diff --git a/accel/accel.c b/accel/accel.c
index 4a64a2b38a..3e567a001f 100644
--- a/accel/accel.c
+++ b/accel/accel.c
@@ -26,7 +26,6 @@
 #include "qemu/osdep.h"
 #include "sysemu/accel.h"
 #include "hw/boards.h"
-#include "sysemu/arch_init.h"
 #include "sysemu/sysemu.h"
 #include "qom/object.h"
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 17b514d1da..48a5fb0798 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -67,7 +67,6 @@
 #include "ui/qemu-spice.h"
 #include "exec/memory.h"
 #include "exec/address-spaces.h"
-#include "sysemu/arch_init.h"
 #include "qemu/bitmap.h"
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 13d1628f13..95ee1f39d8 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -44,7 +44,6 @@
 #include "hw/kvm/clock.h"
 #include "sysemu/sysemu.h"
 #include "hw/sysbus.h"
-#include "sysemu/arch_init.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/xen/xen-x86.h"
 #include "exec/memory.h"
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index a3f4959c43..cf85b240bc 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -31,7 +31,6 @@
 #include "qemu/osdep.h"
 #include "qemu/units.h"
 #include "hw/loader.h"
-#include "sysemu/arch_init.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "sysemu/kvm.h"
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index 71448f72ac..6fee2a4ec0 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -34,7 +34,6 @@
 #include "hw/isa/isa.h"
 #include "hw/block/fdc.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/arch_init.h"
 #include "hw/boards.h"
 #include "net/net.h"
 #include "hw/scsi/esp.h"
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 9d1a3b50b7..6b4387c179 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -38,7 +38,6 @@
 #include "hw/mips/cpudevs.h"
 #include "hw/pci/pci.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/arch_init.h"
 #include "qemu/log.h"
 #include "hw/mips/bios.h"
 #include "hw/ide.h"
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 4a0cb434a6..5c9ec45749 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -43,7 +43,6 @@
 #include "hw/rtc/mc146818rtc.h"
 #include "hw/isa/pc87312.h"
 #include "hw/qdev-properties.h"
-#include "sysemu/arch_init.h"
 #include "sysemu/kvm.h"
 #include "sysemu/qtest.h"
 #include "sysemu/reset.h"
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 59bac4cc9a..6185872127 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -46,7 +46,6 @@
 #include "hw/intc/sifive_plic.h"
 #include "hw/misc/sifive_e_prci.h"
 #include "chardev/char.h"
-#include "sysemu/arch_init.h"
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sif

[PATCH v2 4/6] xen: Delete xen_available() function

2020-11-25 Thread Eduardo Habkost
The function can be replaced with accel_available("xen").

Signed-off-by: Eduardo Habkost 
---
Cc: Paolo Bonzini 
Cc: qemu-devel@nongnu.org
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paul Durrant 
Cc: xen-de...@lists.xenproject.org
Cc: Richard Henderson 
Cc: Claudio Fontana 
Cc: Roman Bolshakov 
---
 include/sysemu/arch_init.h | 2 --
 softmmu/arch_init.c| 9 -
 softmmu/vl.c   | 6 +++---
 3 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index b32ce1afa9..40ac8052b7 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -32,6 +32,4 @@ enum {
 
 extern const uint32_t arch_type;
 
-int xen_available(void);
-
 #endif
diff --git a/softmmu/arch_init.c b/softmmu/arch_init.c
index 79383c8db8..f4770931f5 100644
--- a/softmmu/arch_init.c
+++ b/softmmu/arch_init.c
@@ -49,12 +49,3 @@ int graphic_depth = 32;
 
 
 const uint32_t arch_type = QEMU_ARCH;
-
-int xen_available(void)
-{
-#ifdef CONFIG_XEN
-return 1;
-#else
-return 0;
-#endif
-}
diff --git a/softmmu/vl.c b/softmmu/vl.c
index e6e0ad5a92..74b6ebf1e4 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -3667,21 +3667,21 @@ void qemu_init(int argc, char **argv, char **envp)
 has_defaults = 0;
 break;
 case QEMU_OPTION_xen_domid:
-if (!(xen_available())) {
+if (!(accel_available("xen"))) {
 error_report("Option not supported for this target");
 exit(1);
 }
 xen_domid = atoi(optarg);
 break;
 case QEMU_OPTION_xen_attach:
-if (!(xen_available())) {
+if (!(accel_available("xen"))) {
 error_report("Option not supported for this target");
 exit(1);
 }
 xen_mode = XEN_ATTACH;
 break;
 case QEMU_OPTION_xen_domid_restrict:
-if (!(xen_available())) {
+if (!(accel_available("xen"))) {
 error_report("Option not supported for this target");
 exit(1);
 }
-- 
2.28.0




[PATCH v2 3/6] kvm: Remove kvm_available() function

2020-11-25 Thread Eduardo Habkost
The only caller can use accel_available("kvm") instead.

Signed-off-by: Eduardo Habkost 
---
Cc: Markus Armbruster 
Cc: qemu-devel@nongnu.org
Cc: Paolo Bonzini 
Cc: k...@vger.kernel.org
Cc: Richard Henderson 
Cc: Paolo Bonzini 
Cc: Claudio Fontana 
Cc: Roman Bolshakov 
---
 include/sysemu/arch_init.h | 1 -
 monitor/qmp-cmds.c | 2 +-
 softmmu/arch_init.c| 9 -
 3 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 54f069d491..b32ce1afa9 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -32,7 +32,6 @@ enum {
 
 extern const uint32_t arch_type;
 
-int kvm_available(void);
 int xen_available(void);
 
 #endif
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index a08143b323..ac5b8a97d7 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -57,7 +57,7 @@ KvmInfo *qmp_query_kvm(Error **errp)
 KvmInfo *info = g_malloc0(sizeof(*info));
 
 info->enabled = kvm_enabled();
-info->present = kvm_available();
+info->present = accel_available("kvm");
 
 return info;
 }
diff --git a/softmmu/arch_init.c b/softmmu/arch_init.c
index 7ef32a98b9..79383c8db8 100644
--- a/softmmu/arch_init.c
+++ b/softmmu/arch_init.c
@@ -50,15 +50,6 @@ int graphic_depth = 32;
 
 const uint32_t arch_type = QEMU_ARCH;
 
-int kvm_available(void)
-{
-#ifdef CONFIG_KVM
-return 1;
-#else
-return 0;
-#endif
-}
-
 int xen_available(void)
 {
 #ifdef CONFIG_XEN
-- 
2.28.0




[PATCH v2 6/6] Rename arch_init.h to arch_type.h

2020-11-25 Thread Eduardo Habkost
The only declarations in arch_init.h are related to the arch_type
variable (which is a useful feature that allows us to simplify
command line option handling).  Rename the header to reflect its
purpose.

Signed-off-by: Eduardo Habkost 
---
Cc: Markus Armbruster 
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
Cc: Eduardo Habkost 
Cc: qemu-bl...@nongnu.org
Cc: qemu-devel@nongnu.org
---
 include/sysemu/{arch_init.h => arch_type.h} | 0
 blockdev.c  | 2 +-
 softmmu/arch_init.c | 2 +-
 softmmu/qdev-monitor.c  | 2 +-
 softmmu/vl.c| 2 +-
 stubs/arch_type.c   | 2 +-
 6 files changed, 5 insertions(+), 5 deletions(-)
 rename include/sysemu/{arch_init.h => arch_type.h} (100%)

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_type.h
similarity index 100%
rename from include/sysemu/arch_init.h
rename to include/sysemu/arch_type.h
diff --git a/blockdev.c b/blockdev.c
index fe6fb5dc1d..46c10b2609 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -56,7 +56,7 @@
 #include "sysemu/iothread.h"
 #include "block/block_int.h"
 #include "block/trace.h"
-#include "sysemu/arch_init.h"
+#include "sysemu/arch_type.h"
 #include "sysemu/qtest.h"
 #include "sysemu/runstate.h"
 #include "sysemu/replay.h"
diff --git a/softmmu/arch_init.c b/softmmu/arch_init.c
index f4770931f5..5a9bc56387 100644
--- a/softmmu/arch_init.c
+++ b/softmmu/arch_init.c
@@ -24,7 +24,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/arch_init.h"
+#include "sysemu/arch_type.h"
 #include "hw/pci/pci.h"
 #include "hw/audio/soundhw.h"
 #include "qapi/error.h"
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index bf79d0bbcd..c8b7fb27dc 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -22,7 +22,7 @@
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 #include "monitor/qdev.h"
-#include "sysemu/arch_init.h"
+#include "sysemu/arch_type.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qdev.h"
 #include "qapi/qmp/qdict.h"
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 74b6ebf1e4..1dd63b2782 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -95,7 +95,7 @@
 #include "trace/control.h"
 #include "qemu/plugin.h"
 #include "qemu/queue.h"
-#include "sysemu/arch_init.h"
+#include "sysemu/arch_type.h"
 
 #include "ui/qemu-spice.h"
 #include "qapi/string-input-visitor.h"
diff --git a/stubs/arch_type.c b/stubs/arch_type.c
index fc5423bc98..603a49deec 100644
--- a/stubs/arch_type.c
+++ b/stubs/arch_type.c
@@ -1,4 +1,4 @@
 #include "qemu/osdep.h"
-#include "sysemu/arch_init.h"
+#include "sysemu/arch_type.h"
 
 const uint32_t arch_type = QEMU_ARCH_NONE;
-- 
2.28.0




[PATCH v2 2/6] accel: accel_available() function

2020-11-25 Thread Eduardo Habkost
This function will be used to replace the xen_available() and
kvm_available() functions from arch_init.c.

Signed-off-by: Eduardo Habkost 
---
Cc: Richard Henderson 
Cc: Paolo Bonzini 
Cc: Claudio Fontana 
Cc: Roman Bolshakov 
---
 include/sysemu/accel.h | 1 +
 accel/accel.c  | 5 +
 2 files changed, 6 insertions(+)

diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
index e08b8ab8fa..a4a00c75c8 100644
--- a/include/sysemu/accel.h
+++ b/include/sysemu/accel.h
@@ -67,6 +67,7 @@ typedef struct AccelClass {
 OBJECT_GET_CLASS(AccelClass, (obj), TYPE_ACCEL)
 
 AccelClass *accel_find(const char *opt_name);
+bool accel_available(const char *name);
 int accel_init_machine(AccelState *accel, MachineState *ms);
 
 /* Called just before os_setup_post (ie just before drop OS privs) */
diff --git a/accel/accel.c b/accel/accel.c
index cb555e3b06..4a64a2b38a 100644
--- a/accel/accel.c
+++ b/accel/accel.c
@@ -46,6 +46,11 @@ AccelClass *accel_find(const char *opt_name)
 return ac;
 }
 
+bool accel_available(const char *name)
+{
+return accel_find(name) != NULL;
+}
+
 int accel_init_machine(AccelState *accel, MachineState *ms)
 {
 AccelClass *acc = ACCEL_GET_CLASS(accel);
-- 
2.28.0




[PATCH v2 0/6] arch_init.c cleanup

2020-11-25 Thread Eduardo Habkost
This series gets rid of most of the code in arch_init.c.  It
moves the QEMU_ARCH macro definitions to corresponding cpu.h
files, and gets rid of kvm_available() and xen_available().

After this series, only two things remain in arch_init.c:
- the arch_type variable, which seems to be a useful feature; and
- the initialization of graphic_width/graphic_height/graphic_depth,
  which is a hack we must eventually get rid of.

Gerd got rid of the graphic_* initialization hack once (in 2017),
but the series was never merged:
https://lore.kernel.org/qemu-devel/1487715299-21102-5-git-send-email-kra...@redhat.com

Eduardo Habkost (6):
  arch_init: Move QEMU_ARCH definitions to cpu.h
  accel: accel_available() function
  kvm: Remove kvm_available() function
  xen: Delete xen_available() function
  Remove unnecessary usage of arch_init.h
  Rename arch_init.h to arch_type.h

 include/sysemu/accel.h  |  1 +
 include/sysemu/{arch_init.h => arch_type.h} |  3 -
 target/alpha/cpu.h  |  1 +
 target/arm/cpu.h|  1 +
 target/avr/cpu.h|  1 +
 target/cris/cpu.h   |  1 +
 target/hppa/cpu.h   |  1 +
 target/i386/cpu.h   |  1 +
 target/lm32/cpu.h   |  1 +
 target/m68k/cpu.h   |  1 +
 target/microblaze/cpu.h |  1 +
 target/mips/cpu.h   |  1 +
 target/moxie/cpu.h  |  1 +
 target/nios2/cpu.h  |  1 +
 target/openrisc/cpu.h   |  1 +
 target/ppc/cpu.h|  1 +
 target/riscv/cpu.h  |  1 +
 target/rx/cpu.h |  1 +
 target/s390x/cpu.h  |  1 +
 target/sh4/cpu.h|  1 +
 target/sparc/cpu.h  |  1 +
 target/tricore/cpu.h|  1 +
 target/unicore32/cpu.h  |  1 +
 target/xtensa/cpu.h |  1 +
 accel/accel.c   |  6 +-
 blockdev.c  |  2 +-
 hw/i386/pc.c|  1 -
 hw/i386/pc_piix.c   |  1 -
 hw/i386/pc_q35.c|  1 -
 hw/mips/jazz.c  |  1 -
 hw/mips/malta.c |  1 -
 hw/ppc/prep.c   |  1 -
 hw/riscv/sifive_e.c |  1 -
 hw/riscv/sifive_u.c |  1 -
 hw/riscv/spike.c|  1 -
 hw/riscv/virt.c |  1 -
 monitor/qmp-cmds.c  |  3 +-
 softmmu/arch_init.c | 66 +
 softmmu/qdev-monitor.c  |  2 +-
 softmmu/vl.c|  8 +--
 stubs/arch_type.c   |  2 +-
 target/i386/cpu.c   |  1 -
 target/s390x/cpu.c  |  1 -
 target/s390x/cpu_models.c   |  1 -
 target/ppc/translate_init.c.inc |  1 -
 45 files changed, 37 insertions(+), 92 deletions(-)
 rename include/sysemu/{arch_init.h => arch_type.h} (94%)

-- 
2.28.0





[PATCH v2 1/6] arch_init: Move QEMU_ARCH definitions to cpu.h

2020-11-25 Thread Eduardo Habkost
Instead of a collection of #ifdefs on arch_init.c, define
QEMU_ARCH inside each cpu.h file.

Signed-off-by: Eduardo Habkost 
---
Cc: Richard Henderson 
Cc: Peter Maydell 
Cc: Michael Rolnik 
Cc: Sarah Harris 
Cc: "Edgar E. Iglesias" 
Cc: Paolo Bonzini 
Cc: Eduardo Habkost 
Cc: Michael Walle 
Cc: Laurent Vivier 
Cc: "Philippe Mathieu-Daudé" 
Cc: Aurelien Jarno 
Cc: Jiaxun Yang 
Cc: Aleksandar Rikalo 
Cc: Anthony Green 
Cc: Chris Wulff 
Cc: Marek Vasut 
Cc: Stafford Horne 
Cc: David Gibson 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Yoshinori Sato 
Cc: David Hildenbrand 
Cc: Cornelia Huck 
Cc: Thomas Huth 
Cc: Mark Cave-Ayland 
Cc: Artyom Tarasenko 
Cc: Guan Xuetao 
Cc: Max Filippov 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: qemu-...@nongnu.org
Cc: qemu-ri...@nongnu.org
Cc: qemu-s3...@nongnu.org
---
 target/alpha/cpu.h  |  1 +
 target/arm/cpu.h|  1 +
 target/avr/cpu.h|  1 +
 target/cris/cpu.h   |  1 +
 target/hppa/cpu.h   |  1 +
 target/i386/cpu.h   |  1 +
 target/lm32/cpu.h   |  1 +
 target/m68k/cpu.h   |  1 +
 target/microblaze/cpu.h |  1 +
 target/mips/cpu.h   |  1 +
 target/moxie/cpu.h  |  1 +
 target/nios2/cpu.h  |  1 +
 target/openrisc/cpu.h   |  1 +
 target/ppc/cpu.h|  1 +
 target/riscv/cpu.h  |  1 +
 target/rx/cpu.h |  1 +
 target/s390x/cpu.h  |  1 +
 target/sh4/cpu.h|  1 +
 target/sparc/cpu.h  |  1 +
 target/tricore/cpu.h|  1 +
 target/unicore32/cpu.h  |  1 +
 target/xtensa/cpu.h |  1 +
 softmmu/arch_init.c | 46 -
 23 files changed, 22 insertions(+), 46 deletions(-)

diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 82df108967..313a4e456e 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -438,6 +438,7 @@ void alpha_translate_init(void);
 #define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU
 #define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
 #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
+#define QEMU_ARCH QEMU_ARCH_ALPHA
 
 void alpha_cpu_list(void);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e5514c8286..3f469a6485 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2822,6 +2822,7 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
 #define ARM_CPU_TYPE_SUFFIX "-" TYPE_ARM_CPU
 #define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
 #define CPU_RESOLVING_TYPE TYPE_ARM_CPU
+#define QEMU_ARCH QEMU_ARCH_ARM
 
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index d148e8c75a..98f5df0ad7 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -31,6 +31,7 @@
 #define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU
 #define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX)
 #define CPU_RESOLVING_TYPE TYPE_AVR_CPU
+#define QEMU_ARCH QEMU_ARCH_AVR
 
 #define TCG_GUEST_DEFAULT_MO 0
 
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index d3b6492909..2482915699 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -249,6 +249,7 @@ enum {
 #define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU
 #define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX)
 #define CPU_RESOLVING_TYPE TYPE_CRIS_CPU
+#define QEMU_ARCH QEMU_ARCH_CRIS
 
 #define cpu_signal_handler cpu_cris_signal_handler
 
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 61178fa6a2..74d813289b 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -242,6 +242,7 @@ static inline int cpu_mmu_index(CPUHPPAState *env, bool 
ifetch)
 void hppa_translate_init(void);
 
 #define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
+#define QEMU_ARCH QEMU_ARCH_HPPA
 
 static inline target_ulong hppa_form_gva_psw(target_ureg psw, uint64_t spc,
  target_ureg off)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 88e8586f8f..03202f610c 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1971,6 +1971,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);
 #define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
 #define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
 #define CPU_RESOLVING_TYPE TYPE_X86_CPU
+#define QEMU_ARCH QEMU_ARCH_I386
 
 #ifdef TARGET_X86_64
 #define TARGET_DEFAULT_CPU_TYPE X86_CPU_TYPE_NAME("qemu64")
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index ea7c01ca8b..169c0ff19d 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -238,6 +238,7 @@ bool lm32_cpu_do_semihosting(CPUState *cs);
 #define LM32_CPU_TYPE_SUFFIX "-" TYPE_LM32_CPU
 #define LM32_CPU_TYPE_NAME(model) model LM32_CPU_TYPE_SUFFIX
 #define CPU_RESOLVING_TYPE TYPE_LM32_CPU
+#define QEMU_ARCH QEMU_ARCH_LM32
 
 #define cpu_list lm32_cpu_list
 #define cpu_signal_handler cpu_lm32_signal_handler
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 521ac67cdd..

Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-25 Thread Eduardo Habkost
On Wed, Nov 25, 2020 at 07:40:48AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Tue, Nov 24, 2020 at 04:20:37PM +0100, Markus Armbruster wrote:
> >> Eduardo Habkost  writes:
> >> 
> >> > On Tue, Nov 24, 2020 at 09:49:30AM +0100, Markus Armbruster wrote:
> >> >> Eduardo Habkost  writes:
> >> >> 
> >> >> > On Mon, Nov 23, 2020 at 08:51:27AM +0100, Markus Armbruster wrote:
> >> >> >> Eduardo Habkost  writes:
> >> >> >> 
> >> >> >> > On Fri, Nov 20, 2020 at 06:29:16AM +0100, Markus Armbruster wrote:
> >> >> >> [...]
> >> >> >> >> When the structure of a data type is to be kept away from its 
> >> >> >> >> users, I
> >> >> >> >> prefer to keep it out of the public header, so the compiler 
> >> >> >> >> enforces the
> >> >> >> >> encapsulation.
> >> >> >> >
> >> >> >> > I prefer that too, except that it is impossible when users of the
> >> >> >> > API need the compiler to know the struct size.
> >> >> >> 
> >> >> >> There are cases where the structure of a data type should be
> >> >> >> encapsulated, yet its size must be made known for performance (avoid
> >> >> >> dynamic memory allocation and pointer chasing).
> >> >> >> 
> >> >> >> Need for encapsulation correlates with complex algorithms and data
> >> >> >> structures.  The cost of dynamic allocation is often in the noise 
> >> >> >> then.
> >> >> >
> >> >> > I don't know what we are talking about anymore.  None of this
> >> >> > applies to the QNum API, right?
> >> >> >
> >> >> > QNum/QNumValue are not complex data structures, and the reason we
> >> >> > need the compiler to know the size of QNumValue is not related to
> >> >> > performance at all.
> >> >> 
> >> >> We started with the question whether to make QNumValue's members
> >> >> private.  We digressed to the question when to make members private.
> >> >> So back to the original question.
> >> >> 
> >> >> > We might still want to discourage users of the QNum API from
> >> >> > accessing QNum.u/QNumValue.u directly.  Documenting the field as
> >> >> > private is a very easy way to do it.
> >> >> 
> >> >> It's a complete non-issue.  QNum has been around for years, and we
> >> >> haven't had any issues that could've been plausibly avoided by asking
> >> >> people to refrain from accessing its members.
> >> >> 
> >> >> If there was an actual need to keep the members private, I'd move the
> >> >> struct out of the header, so the compiler enforces privacy.
> >> >
> >> > Understood.  There's still a question I'd like to answer, to
> >> > decide how the API documentation should look like:
> >> >
> >> >   Is QNum.u/QNumValue.u required to be part of the API
> >> >   documentation?
> >> >
> >> > If accessing that field directly is not necessary for using the
> >> > API, I don't think it should appear in the documentation (because
> >> > it would be just noise).
> >> 
> >> The current patch's comment on QNumValue looks good to me.
> >> 
> >> Does this answer your question?
> >
> > The current patch (v3) doesn't address the question.  It doesn't
> > include documentation for the field, but doesn't hide it.
> > kernel-doc will print a warning on that case.
> 
> Do we care?

Yes.  Peter will reject pull requests if it generates kernel-doc
warnings.

> How many such warnings exist before the patch?

Zero.

> Does this series add just this one, or more?

The current series (v3) doesn't add any, because I dropped the
patch that added QObject and QNum documentation to docs/devel.  I
still want to resubmit that patch later, though.

> 
> Use your judgement, then be ready to explain it :)

OK!

-- 
Eduardo




Re: [RFC v5 12/12] accel: centralize initialization of CpusAccelOps

2020-11-25 Thread Eduardo Habkost
On Wed, Nov 25, 2020 at 12:48:22PM +0100, Claudio Fontana wrote:
> On 11/25/20 10:32 AM, Claudio Fontana wrote:
> > On 11/24/20 9:34 PM, Eduardo Habkost wrote:
> >> On Tue, Nov 24, 2020 at 08:39:33PM +0100, Claudio Fontana wrote:
> >>> On 11/24/20 8:27 PM, Eduardo Habkost wrote:
> >>>> On Tue, Nov 24, 2020 at 07:52:15PM +0100, Claudio Fontana wrote:
> >>>> [...]
> >>>>>>> +}
> >>>>>>
> >>>>>> Additionally, if you call arch_cpu_accel_init() here, you won't
> >>>>>> need MODULE_INIT_ACCEL_CPU anymore.  The
> >>>>>>
> >>>>>>   module_call_init(MODULE_INIT_ACCEL_CPU)
> >>>>>>
> >>>>>> call with implicit dependencies on runtime state inside vl.c and
> >>>>>> *-user/main.c becomes a trivial:
> >>>>>>
> >>>>>>   accel_init(accel)
> >>>>>>
> >>>>>> call in accel_init_machine() and *-user:main().
> 
> 
> On this one I see an issue:
> 
> the *-user_main() would still need an ac->machine_init() call to initialize 
> tcg itself,
> currently the accelerator initialization is put into ac->machine_init
> 
> (tcg_init, kvm_init, xen_init, etc).
> 
> Or are you proposing to move tcg initialization away from the current 
> ->machine_init(),
> into the new ac->init called by accel_init()?

Yes.  Anything that requires MachineState (and is
softmmu-specific) would go to ->machine_init().  Anything that is
not softmmu-specific would go to ->init().

> 
> This would make tcg even more different from the other accelerators.

That's true, but isn't this only because TCG is the only one that
really needs it?

> 
> Or are you proposing for all accelerators to separate the initialization of 
> the accelerator itself
> from the machine state input, leading to, for example, separating kvm-all.c 
> kvm_init() into two
> functions, one which takes the input from MachineState and puts it into the 
> AccelState, and
> another one which actually then initializes kvm proper? And same for all 
> accels?

That would be possible (and maybe a good idea), but not necessary
to make it work.

> 
> In my view we could still do in *-user main.c,
> 
> ac = ACCEL_GET_CLASS(current_accel())
> ac->machine_init(NULL);
> ac->init_cpu_interfaces(ac);

That would work too.  I would implement it as an accel_init(NULL)
call, however, to avoid duplicating the code from
accel_init_machine().

Calling ->machine_init(NULL) is just a bit surprising because of
the name (calling machine_init() when there's no machine), and
because we know most accelerators will crash if getting a NULL
argument.

Anyway, the split between ->machine_init() and ->init() is just a
suggestion.  Keeping a single init method that accepts a NULL
MachineState* as argument is not my favourite option, but it
works.

Whatever you choose, my only ask is to document clearly the
expectations and requirements of the AccelClass methods you are
using.


> 
> to solve this, or something like that, but also the option of fixing all 
> accelerators to separate
> the gathering of the input from the MachineState to the actual accelerator 
> initialization is
> a possibility to me.
> 
> Ciao,
> 
> Claudio

Thank you very much for your patience!  I think we're going on
the right direction.

-- 
Eduardo




Re: [RFC v5 11/12] i386: centralize initialization of cpu accel interfaces

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 09:13:13PM +0100, Paolo Bonzini wrote:
> On 24/11/20 17:22, Claudio Fontana wrote:
> > +static void x86_cpu_accel_init(void)
> >  {
> > -X86CPUAccelClass *acc;
> > +const char *ac_name;
> > +ObjectClass *ac;
> > +char *xac_name;
> > +ObjectClass *xac;
> > -acc = X86_CPU_ACCEL_CLASS(object_class_by_name(accel_name));
> > -g_assert(acc != NULL);
> > +ac = object_get_class(OBJECT(current_accel()));
> > +g_assert(ac != NULL);
> > +ac_name = object_class_get_name(ac);
> > +g_assert(ac_name != NULL);
> > -object_class_foreach(x86_cpu_accel_init_aux, TYPE_X86_CPU, false, 
> > &acc);
> > +xac_name = g_strdup_printf("%s-%s", ac_name, TYPE_X86_CPU);
> > +xac = object_class_by_name(xac_name);
> > +g_free(xac_name);
> > +
> > +if (xac) {
> > +object_class_foreach(x86_cpu_accel_init_aux, TYPE_X86_CPU, false, 
> > xac);
> > +}
> >  }
> > +
> > +accel_cpu_init(x86_cpu_accel_init);
> 
> If this and cpus_accel_ops_init are the only call to accel_cpu_init, I'd
> rather make them functions in CPUClass (which you find and call via
> CPU_RESOLVING_TYPE) and AccelClass respectively.

Making x86_cpu_accel_init() be a CPUClass method sounds like a
good idea.  This way we won't need a arch_cpu_accel_init() stub
for non-x86.

accel.c can't use cpu.h, correct?  We can add a:

  CPUClass *arch_base_cpu_type(void)
  {
  return object_class_by_name(CPU_RESOLVING_TYPE);
  }

function to arch_init.c, to allow target-independent code call
target-specific code.

-- 
Eduardo




Re: [RFC v5 12/12] accel: centralize initialization of CpusAccelOps

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 08:39:33PM +0100, Claudio Fontana wrote:
> On 11/24/20 8:27 PM, Eduardo Habkost wrote:
> > On Tue, Nov 24, 2020 at 07:52:15PM +0100, Claudio Fontana wrote:
> > [...]
> >>>> +}
> >>>
> >>> Additionally, if you call arch_cpu_accel_init() here, you won't
> >>> need MODULE_INIT_ACCEL_CPU anymore.  The
> >>>
> >>>   module_call_init(MODULE_INIT_ACCEL_CPU)
> >>>
> >>> call with implicit dependencies on runtime state inside vl.c and
> >>> *-user/main.c becomes a trivial:
> >>>
> >>>   accel_init(accel)
> >>>
> >>> call in accel_init_machine() and *-user:main().
> >>
> >>
> >>
> >> I do need a separate thing for the arch cpu accel specialization though,
> >> without MODULE_INIT_ACCEL_CPU that link between all operations done at 
> >> accel-chosen time is missing..
> >>
> > 
> > I think this is a key point we need to sort out.
> > 
> > What do you mean by "link between all operations done at
> > accel-chosen time" and why that's important?
> 
> 
> For understanding by a reader that tries to figure this out,
> (see the gid MODULE_INIT_ACCEL_CPU comment elsewhere in the thread).

Right, but how does the module_call_init(MODULE_INIT_ACCEL_CPU)
indirection makes this easier to figure out than just looking at
a accel_init() function that makes regular function calls?


> 
> And it could be that the high level plan to make accelerators fully 
> dynamically loadable plugins in the future
> also conditioned me to want to have a very clear demarcation line around the 
> choice of the accelerator.

We have dynamically loadable modules for other QOM types,
already, and they just use type_init().  I don't see why an extra
module_init() type makes this easier.

> 
> 
> > 
> > accel_init_machine() has 2-3 lines of code with side effects.  It
> > calls AccelClass.init_machine(), which may may have hundreds of
> 
> 
> could we initialize also all arch-dependent stuff in here?

You can, if you use a wrapper + stub, like arch_cpu_accel_init().


> 
> 
> > lines of code.  accel_setup_post() has one additional method
> > call, which is triggered at a slightly different moment.
> > 
> > You are using MODULE_INIT_ACCEL for 2 additional lines of code:
> > - the cpus_register_accel() call
> > - the x86_cpu_accel_init() call
> > 
> > What makes those 2 lines of code so special, to make them deserve
> > a completely new mechanism to trigger them, instead of using
> > trivial function calls inside a accel_init() function?
> > 
> 
> ...can we do also the x86_cpu_accel_init inside accel_init()?
> 
> 
> In any case I'll try also the alternative, it would be nice if I could bring 
> everything together under the same roof,
> and easily discoverable, both the arch-specific steps that we need to do at 
> accel-chosen time and the non-arch-specific steps.

One way to bring everything together under the same roof is to
call everything inside a accel_init() function.


> 
> Hope this helps clarifying where I am coming from,
> but I am open to have my mind changed, also trying the alternatives you 
> propose here could help me see first hand how things play out.

Thanks!

-- 
Eduardo




Re: [RFC v5 12/12] accel: centralize initialization of CpusAccelOps

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 07:52:15PM +0100, Claudio Fontana wrote:
[...]
> >> +}
> > 
> > Additionally, if you call arch_cpu_accel_init() here, you won't
> > need MODULE_INIT_ACCEL_CPU anymore.  The
> > 
> >   module_call_init(MODULE_INIT_ACCEL_CPU)
> > 
> > call with implicit dependencies on runtime state inside vl.c and
> > *-user/main.c becomes a trivial:
> > 
> >   accel_init(accel)
> > 
> > call in accel_init_machine() and *-user:main().
> 
> 
> 
> I do need a separate thing for the arch cpu accel specialization though,
> without MODULE_INIT_ACCEL_CPU that link between all operations done at 
> accel-chosen time is missing..
> 

I think this is a key point we need to sort out.

What do you mean by "link between all operations done at
accel-chosen time" and why that's important?

accel_init_machine() has 2-3 lines of code with side effects.  It
calls AccelClass.init_machine(), which may may have hundreds of
lines of code.  accel_setup_post() has one additional method
call, which is triggered at a slightly different moment.

You are using MODULE_INIT_ACCEL for 2 additional lines of code:
- the cpus_register_accel() call
- the x86_cpu_accel_init() call

What makes those 2 lines of code so special, to make them deserve
a completely new mechanism to trigger them, instead of using
trivial function calls inside a accel_init() function?

-- 
Eduardo




Re: [RFC v5 09/12] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 07:29:50PM +0100, Claudio Fontana wrote:
> On 11/24/20 6:08 PM, Eduardo Habkost wrote:
> > On Tue, Nov 24, 2020 at 05:22:07PM +0100, Claudio Fontana wrote:
> >> apply this to the registration of the cpus accel interfaces,
> >>
> >> but this will be also in preparation for later use of this
> >> new module init step to also register per-accel x86 cpu type
> >> interfaces.
> >>
> >> Signed-off-by: Claudio Fontana 
> >> ---
> > [...]
> >> diff --git a/accel/qtest/qtest.c b/accel/qtest/qtest.c
> >> index b4e731cb2b..482f89729f 100644
> >> --- a/accel/qtest/qtest.c
> >> +++ b/accel/qtest/qtest.c
> >> @@ -32,7 +32,6 @@ const CpusAccel qtest_cpus = {
> >>  
> >>  static int qtest_init_accel(MachineState *ms)
> >>  {
> >> -cpus_register_accel(&qtest_cpus);
> >>  return 0;
> >>  }
> >>  
> >> @@ -58,3 +57,12 @@ static void qtest_type_init(void)
> >>  }
> >>  
> >>  type_init(qtest_type_init);
> >> +
> >> +static void qtest_accel_cpu_init(void)
> >> +{
> >> +if (qtest_enabled()) {
> >> +cpus_register_accel(&qtest_cpus);
> >> +}
> >> +}
> >> +
> >> +accel_cpu_init(qtest_accel_cpu_init);
> > 
> > I don't understand why this (and the similar changes on other
> > accelerators) is an improvement.
> > 
> > You are replacing a trivial AccelClass-specific init method with
> > a module_init() function that has a hidden dependency on runtime
> > state.
> > 
> 
> Not a big advantage I agree,
> I think however there is one, in using the existing framework that exists, 
> for the purposes that it was built for.
> 
> As I understand it, the global module init framework is supposed to mark the 
> major initialization steps,
> and this seems to fit the bill.

That seems to be the main source of disagreement.  I don't agree
that's the purpose of module_init().

The module init framework is used to unconditionally register
module-provided entities like option names, QOM types, block
drivers, trace events, etc.  The entities registered by module
init functions represent a passive dynamically loadable piece of
code.

module_init() was never used for initialization of machines,
devices, CPUs, or other runtime state.  We don't have
MODULE_INIT_MONITOR, MODULE_INIT_OBJECTS, MODULE_INIT_MACHINE,
MODULE_INIT_CPUS, MODULE_INIT_DEVICES, etc.

And I'm not convinced we should, because it would hide
dependencies between initialization steps.  It would force us to
make initialization functions affect and depend on global state.

I believe this:

  int main()
  {
result_of_A = init_A(input_for_A);
result_of_B = init_B(input_for_B);
result_of_C = init_C(input_for_C);
  }

is clearer and more maintainable than:

  int main()
  {
module_init_call(MODULE_INIT_A);  /* result_of_A hidden in global state */
module_init_call(MODULE_INIT_B);  /* result_of_B hidden in global state */
module_init_call(MODULE_INIT_C);  /* result_of_C hidden in global state */
  }

> 
> The "hidden" dependency on the fact that accels need to be initialized at 
> that time, is not hidden at all I think,
> it is what this module init step is all about.
> 
> It is explicitly meaning, "_now that the current accelerator is chosen_, 
> perform these initializations".
> 
> But, as you mentioned elsewhere, I will in the meantime anyway squash these 
> things so they do not start fragmented at all, and centralize immediately.

Agreed.  We still need to sort out the disagreement above, or
we'll spend a lot of energy arguing about code.

-- 
Eduardo




Re: [RFC v5 08/12] accel: extend AccelState and AccelClass to user-mode

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 05:22:06PM +0100, Claudio Fontana wrote:
> Signed-off-by: Claudio Fontana 
> ---
[...]
> @@ -908,8 +909,12 @@ int main(int argc, char **argv)
>  }
>  
>  /* init tcg before creating CPUs and to get qemu_host_page_size */
> -tcg_exec_init(0);
> +{
> +AccelClass *ac = accel_find("tcg");
>  
> +g_assert(ac != NULL);
> +ac->init_machine(NULL);

Most init_machine() methods will crash if you call them with a
NULL argument.

This looks like another reason for having a
  void accel_init(AccelState*)
function and a
  void (*init)(AccelState*)
method in AccelClass.

Then the whole code block above would be as trivial as:

  accel_init(current_accel());


> +}
[...]
> 

-- 
Eduardo




Re: [RFC v5 12/12] accel: centralize initialization of CpusAccelOps

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 05:22:10PM +0100, Claudio Fontana wrote:
> Signed-off-by: Claudio Fontana 
> ---
>  accel/kvm/kvm-all.c  |  9 ---
>  accel/kvm/kvm-cpus.c | 26 +-
>  accel/kvm/kvm-cpus.h |  2 --
>  accel/qtest/qtest.c  | 31 --
>  accel/tcg/tcg-cpus-icount.c  | 11 +---
>  accel/tcg/tcg-cpus-icount.h  |  2 ++
>  accel/tcg/tcg-cpus-mttcg.c   | 12 +++--
>  accel/tcg/tcg-cpus-mttcg.h   | 19 ++
>  accel/tcg/tcg-cpus-rr.c  |  7 -
>  accel/tcg/tcg-cpus.c | 48 ++---
>  accel/tcg/tcg-cpus.h |  4 ---
>  accel/xen/xen-all.c  | 29 ++--
>  include/sysemu/cpus.h| 39 ---
>  softmmu/cpus.c   | 51 +---
>  target/i386/hax/hax-all.c|  9 ---
>  target/i386/hax/hax-cpus.c   | 29 +++-
>  target/i386/hax/hax-cpus.h   |  2 --
>  target/i386/hvf/hvf-cpus.c   | 27 ++-
>  target/i386/hvf/hvf-cpus.h   |  2 --
>  target/i386/hvf/hvf.c|  9 ---
>  target/i386/whpx/whpx-all.c  |  9 ---
>  target/i386/whpx/whpx-cpus.c | 29 +++-
>  target/i386/whpx/whpx-cpus.h |  2 --
>  23 files changed, 251 insertions(+), 157 deletions(-)
>  create mode 100644 accel/tcg/tcg-cpus-mttcg.h
> 
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index 509b249f52..33156cc4c7 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -3234,12 +3234,3 @@ static void kvm_type_init(void)
>  }
>  
>  type_init(kvm_type_init);
> -
> -static void kvm_accel_cpu_init(void)
> -{
> -if (kvm_enabled()) {
> -cpus_register_accel(&kvm_cpus);
> -}
> -}
> -
> -accel_cpu_init(kvm_accel_cpu_init);
> diff --git a/accel/kvm/kvm-cpus.c b/accel/kvm/kvm-cpus.c
> index d809b1e74c..33dc8e737a 100644
> --- a/accel/kvm/kvm-cpus.c
> +++ b/accel/kvm/kvm-cpus.c
> @@ -74,11 +74,25 @@ static void kvm_start_vcpu_thread(CPUState *cpu)
> cpu, QEMU_THREAD_JOINABLE);
>  }
>  
> -const CpusAccel kvm_cpus = {
> -.create_vcpu_thread = kvm_start_vcpu_thread,
> +static void kvm_cpus_class_init(ObjectClass *oc, void *data)
> +{
> +CpusAccelOps *ops = CPUS_ACCEL_OPS_CLASS(oc);

Why do you need a separate QOM type hierarchy instead of just
doing this inside AccelClass methods and/or existing accel
class_init functions?

>  
> -.synchronize_post_reset = kvm_cpu_synchronize_post_reset,
> -.synchronize_post_init = kvm_cpu_synchronize_post_init,
> -.synchronize_state = kvm_cpu_synchronize_state,
> -.synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm,
> +ops->create_vcpu_thread = kvm_start_vcpu_thread;
> +ops->synchronize_post_reset = kvm_cpu_synchronize_post_reset;
> +ops->synchronize_post_init = kvm_cpu_synchronize_post_init;
> +ops->synchronize_state = kvm_cpu_synchronize_state;
> +ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm;

All of these could be AccelClass fields.

TCG makes it a bit more complicated because there's a different
set of methods chosen for TYPE_TCG_ACCEL depending on the
configuration.  This could be solved by patching AccelClass at
init time, or by moving the method pointers to AccelState.

Alternatively, if you still want to keep the
CpusAccel/CpusAccelOps struct, that's OK.  You can just add a
`CpusAccel *cpu_accel_ops` field to AccelClass or AccelState.  No
need for a separate QOM hierarchy, either.

If you _really_ want a separate TYPE_CPU_ACCEL_OPS QOM type, you
can still have it.  But it can be just an interface implemented
by each accel subclass, instead of requiring a separate
CPUS_ACCEL_TYPE_NAME(...) type to be registered for each
accelerator.  (I don't see why you would want it, though.)


>  };
> +static const TypeInfo kvm_cpus_type_info = {
> +.name = CPUS_ACCEL_TYPE_NAME("kvm"),
> +
> +.parent = TYPE_CPUS_ACCEL_OPS,
> +.class_init = kvm_cpus_class_init,
> +.abstract = true,
> +};
> +static void kvm_cpus_register_types(void)
> +{
> +type_register_static(&kvm_cpus_type_info);
> +}
> +type_init(kvm_cpus_register_types);
[...]
> -typedef struct CpusAccel {
> -void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY */
> +typedef struct CpusAccelOps CpusAccelOps;
> +DECLARE_CLASS_CHECKERS(CpusAccelOps, CPUS_ACCEL_OPS, TYPE_CPUS_ACCEL_OPS)
> +
> +struct CpusAccelOps {
> +ObjectClass parent_class;
> +
> +/* initialization function called when accel is chosen */
> +void (*accel_chosen_init)(CpusAccelOps *ops);

This can be an AccelClass method too.  What about just naming it
AccelClass.init?

> +
> +void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY NON-NULL */
>  void (*kick_vcpu_thread)(CPUState *cpu);
>  
>  void (*synchronize_post_reset)(CPUState *cpu);
> @@ -20,13 +45,7 @@ typedef struct CpusAccel {
>  
>  int64_t (*get_virtual_clock)(void);
>  int64_t (*get_elapsed_ticks)(void);
> -}

Re: [RFC v5 09/12] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 05:22:07PM +0100, Claudio Fontana wrote:
> apply this to the registration of the cpus accel interfaces,
> 
> but this will be also in preparation for later use of this
> new module init step to also register per-accel x86 cpu type
> interfaces.
> 
> Signed-off-by: Claudio Fontana 
> ---
[...]
> diff --git a/accel/qtest/qtest.c b/accel/qtest/qtest.c
> index b4e731cb2b..482f89729f 100644
> --- a/accel/qtest/qtest.c
> +++ b/accel/qtest/qtest.c
> @@ -32,7 +32,6 @@ const CpusAccel qtest_cpus = {
>  
>  static int qtest_init_accel(MachineState *ms)
>  {
> -cpus_register_accel(&qtest_cpus);
>  return 0;
>  }
>  
> @@ -58,3 +57,12 @@ static void qtest_type_init(void)
>  }
>  
>  type_init(qtest_type_init);
> +
> +static void qtest_accel_cpu_init(void)
> +{
> +if (qtest_enabled()) {
> +cpus_register_accel(&qtest_cpus);
> +}
> +}
> +
> +accel_cpu_init(qtest_accel_cpu_init);

I don't understand why this (and the similar changes on other
accelerators) is an improvement.

You are replacing a trivial AccelClass-specific init method with
a module_init() function that has a hidden dependency on runtime
state.

-- 
Eduardo




Re: [RFC v5 11/12] i386: centralize initialization of cpu accel interfaces

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 05:22:09PM +0100, Claudio Fontana wrote:
> Signed-off-by: Claudio Fontana 

Probably this can be squashed into patch 10/12.

> ---
>  target/i386/cpu-qom.h |  2 --
>  target/i386/cpu.c | 27 ---
>  target/i386/hvf/cpu.c |  9 -
>  target/i386/kvm/cpu.c |  8 
>  target/i386/tcg/cpu.c |  9 -
>  5 files changed, 20 insertions(+), 35 deletions(-)
> 
> diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h
> index 9316e78e71..2cea5394c6 100644
> --- a/target/i386/cpu-qom.h
> +++ b/target/i386/cpu-qom.h
> @@ -98,6 +98,4 @@ struct X86CPUAccelClass {
>  void (*cpu_realizefn)(X86CPU *cpu, Error **errp);
>  };
>  
> -void x86_cpu_accel_init(const char *accel_name);
> -
>  #endif
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index b799723e53..f6fd055046 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -7066,18 +7066,31 @@ type_init(x86_cpu_register_types)
>  static void x86_cpu_accel_init_aux(ObjectClass *klass, void *opaque)
>  {
>  X86CPUClass *xcc = X86_CPU_CLASS(klass);
> -const X86CPUAccelClass **accel = opaque;
> +X86CPUAccelClass *accel = opaque;
>  
> -xcc->accel = *accel;
> +xcc->accel = accel;
>  xcc->accel->cpu_common_class_init(xcc);
>  }
>  
> -void x86_cpu_accel_init(const char *accel_name)
> +static void x86_cpu_accel_init(void)
>  {
> -X86CPUAccelClass *acc;
> +const char *ac_name;
> +ObjectClass *ac;
> +char *xac_name;
> +ObjectClass *xac;
>  
> -acc = X86_CPU_ACCEL_CLASS(object_class_by_name(accel_name));
> -g_assert(acc != NULL);
> +ac = object_get_class(OBJECT(current_accel()));
> +g_assert(ac != NULL);
> +ac_name = object_class_get_name(ac);
> +g_assert(ac_name != NULL);
>  
> -object_class_foreach(x86_cpu_accel_init_aux, TYPE_X86_CPU, false, &acc);
> +xac_name = g_strdup_printf("%s-%s", ac_name, TYPE_X86_CPU);
> +xac = object_class_by_name(xac_name);
> +g_free(xac_name);
> +
> +if (xac) {
> +object_class_foreach(x86_cpu_accel_init_aux, TYPE_X86_CPU, false, 
> xac);
> +}
>  }
> +
> +accel_cpu_init(x86_cpu_accel_init);

This keeps the hidden initialization ordering dependency between
MODULE_INIT_ACCEL_CPU and current_accel().  I thought we were
going to get rid of module init functions that depend on runtime
state.

This is an improvement to the code in patch 10/12, though.  If
others believe it is an acceptable (temporary) solution, I won't
block it.

I would still prefer to have a
  void arch_accel_cpu_init(AccelState*)
function which would call a
  void x86_cpu_accel_init(AccelState*)
function.  That would make the dependency between
x86_cpu_accel_init() and accelerator creation explicit.


> diff --git a/target/i386/hvf/cpu.c b/target/i386/hvf/cpu.c
> index 7e7dc044d3..70b6dbfc10 100644
> --- a/target/i386/hvf/cpu.c
> +++ b/target/i386/hvf/cpu.c
> @@ -65,12 +65,3 @@ static void hvf_cpu_accel_register_types(void)
>  type_register_static(&hvf_cpu_accel_type_info);
>  }
>  type_init(hvf_cpu_accel_register_types);
> -
> -static void hvf_cpu_accel_init(void)
> -{
> -if (hvf_enabled()) {
> -x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME("hvf"));
> -}
> -}
> -
> -accel_cpu_init(hvf_cpu_accel_init);
> diff --git a/target/i386/kvm/cpu.c b/target/i386/kvm/cpu.c
> index bc5f519479..c17ed5a3f2 100644
> --- a/target/i386/kvm/cpu.c
> +++ b/target/i386/kvm/cpu.c
> @@ -147,11 +147,3 @@ static void kvm_cpu_accel_register_types(void)
>  type_register_static(&kvm_cpu_accel_type_info);
>  }
>  type_init(kvm_cpu_accel_register_types);
> -
> -static void kvm_cpu_accel_init(void)
> -{
> -if (kvm_enabled()) {
> -x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME("kvm"));
> -}
> -}
> -accel_cpu_init(kvm_cpu_accel_init);
> diff --git a/target/i386/tcg/cpu.c b/target/i386/tcg/cpu.c
> index e7d4effdd0..00166c36e9 100644
> --- a/target/i386/tcg/cpu.c
> +++ b/target/i386/tcg/cpu.c
> @@ -170,12 +170,3 @@ static void tcg_cpu_accel_register_types(void)
>  type_register_static(&tcg_cpu_accel_type_info);
>  }
>  type_init(tcg_cpu_accel_register_types);
> -
> -static void tcg_cpu_accel_init(void)
> -{
> -if (tcg_enabled()) {
> -x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME("tcg"));
> -}
> -}
> -
> -accel_cpu_init(tcg_cpu_accel_init);
> -- 
> 2.26.2
> 

-- 
Eduardo




Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 04:20:37PM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Tue, Nov 24, 2020 at 09:49:30AM +0100, Markus Armbruster wrote:
> >> Eduardo Habkost  writes:
> >> 
> >> > On Mon, Nov 23, 2020 at 08:51:27AM +0100, Markus Armbruster wrote:
> >> >> Eduardo Habkost  writes:
> >> >> 
> >> >> > On Fri, Nov 20, 2020 at 06:29:16AM +0100, Markus Armbruster wrote:
> >> >> [...]
> >> >> >> When the structure of a data type is to be kept away from its users, 
> >> >> >> I
> >> >> >> prefer to keep it out of the public header, so the compiler enforces 
> >> >> >> the
> >> >> >> encapsulation.
> >> >> >
> >> >> > I prefer that too, except that it is impossible when users of the
> >> >> > API need the compiler to know the struct size.
> >> >> 
> >> >> There are cases where the structure of a data type should be
> >> >> encapsulated, yet its size must be made known for performance (avoid
> >> >> dynamic memory allocation and pointer chasing).
> >> >> 
> >> >> Need for encapsulation correlates with complex algorithms and data
> >> >> structures.  The cost of dynamic allocation is often in the noise then.
> >> >
> >> > I don't know what we are talking about anymore.  None of this
> >> > applies to the QNum API, right?
> >> >
> >> > QNum/QNumValue are not complex data structures, and the reason we
> >> > need the compiler to know the size of QNumValue is not related to
> >> > performance at all.
> >> 
> >> We started with the question whether to make QNumValue's members
> >> private.  We digressed to the question when to make members private.
> >> So back to the original question.
> >> 
> >> > We might still want to discourage users of the QNum API from
> >> > accessing QNum.u/QNumValue.u directly.  Documenting the field as
> >> > private is a very easy way to do it.
> >> 
> >> It's a complete non-issue.  QNum has been around for years, and we
> >> haven't had any issues that could've been plausibly avoided by asking
> >> people to refrain from accessing its members.
> >> 
> >> If there was an actual need to keep the members private, I'd move the
> >> struct out of the header, so the compiler enforces privacy.
> >
> > Understood.  There's still a question I'd like to answer, to
> > decide how the API documentation should look like:
> >
> >   Is QNum.u/QNumValue.u required to be part of the API
> >   documentation?
> >
> > If accessing that field directly is not necessary for using the
> > API, I don't think it should appear in the documentation (because
> > it would be just noise).
> 
> The current patch's comment on QNumValue looks good to me.
> 
> Does this answer your question?

The current patch (v3) doesn't address the question.  It doesn't
include documentation for the field, but doesn't hide it.
kernel-doc will print a warning on that case.

-- 
Eduardo




[PULL 1/1] Revert "hw/core/qdev-properties: Use qemu_strtoul() in set_pci_host_devaddr()"

2020-11-24 Thread Eduardo Habkost
From: "Michael S. Tsirkin" 

This reverts commit bccb20c49df1bd683248a366021973901c11982f as it
introduced a regression blocking bus addresses > 0x1f or higher.
Legal bus numbers go up to 0xff.

Fixes: bccb20c49df ("Use qemu_strtoul() in set_pci_host_devaddr()")
Reported-by: Klaus Herman 
Reported-by: Geoffrey McRae 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Philippe Mathieu-Daudé 
Cc: "Philippe Mathieu-Daudé" 
Message-Id: <20201120130409.956956-1-...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/core/qdev-properties-system.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index b81a4e8d14..9d80a07d26 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -858,7 +858,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, 
const char *name,
 Property *prop = opaque;
 PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
 char *str, *p;
-const char *e;
+char *e;
 unsigned long val;
 unsigned long dom = 0, bus = 0;
 unsigned int slot = 0, func = 0;
@@ -873,23 +873,23 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, 
const char *name,
 }
 
 p = str;
-if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0x || e == p) {
-goto inval;
-}
-if (*e != ':') {
+val = strtoul(p, &e, 16);
+if (e == p || *e != ':') {
 goto inval;
 }
 bus = val;
 
-p = (char *)e + 1;
-if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0x1f || e == p) {
+p = e + 1;
+val = strtoul(p, &e, 16);
+if (e == p) {
 goto inval;
 }
 if (*e == ':') {
 dom = bus;
 bus = val;
-p = (char *)e + 1;
-if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0x1f || e == p) {
+p = e + 1;
+val = strtoul(p, &e, 16);
+if (e == p) {
 goto inval;
 }
 }
@@ -898,13 +898,14 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, 
const char *name,
 if (*e != '.') {
 goto inval;
 }
-p = (char *)e + 1;
-if (qemu_strtoul(p, &e, 10, &val) < 0 || val > 7 || e == p) {
+p = e + 1;
+val = strtoul(p, &e, 10);
+if (e == p) {
 goto inval;
 }
 func = val;
 
-if (bus > 0xff) {
+if (dom > 0x || bus > 0xff || slot > 0x1f || func > 7) {
 goto inval;
 }
 
-- 
2.28.0




[PULL 0/1] PCI host devaddr property fix for 5.2

2020-11-24 Thread Eduardo Habkost
The following changes since commit d536d9578ec3ac5029a70b8126cb84bb6f2124a4:

  Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into 
staging (2020-11-24 10:59:12 +)

are available in the Git repository at:

  git://github.com/ehabkost/qemu.git tags/machine-next-for-5.2-pull-request

for you to fetch changes up to 28afbc1f11f5ae33b69deb162a551110717eec94:

  Revert "hw/core/qdev-properties: Use qemu_strtoul() in 
set_pci_host_devaddr()" (2020-11-24 10:06:54 -0500)


PCI host devaddr property fix for 5.2



Michael S. Tsirkin (1):
  Revert "hw/core/qdev-properties: Use qemu_strtoul() in
set_pci_host_devaddr()"

 hw/core/qdev-properties-system.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

-- 
2.28.0





Re: [PATCH for-5.2] Revert "hw/core/qdev-properties: Use qemu_strtoul() in set_pci_host_devaddr()"

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 03:13:14PM +0100, Philippe Mathieu-Daudé wrote:
> On 11/20/20 2:10 PM, Paolo Bonzini wrote:
> > On 20/11/20 14:04, Michael S. Tsirkin wrote:
> >> This reverts commit bccb20c49df1bd683248a366021973901c11982f as it
> >> introduced a regression blocking bus addresses > 0x1f or higher.
> >> Legal bus numbers go up to 0xff.
> >>
> >> Cc: "Philippe Mathieu-Daudé" 
> >> Fixes: bccb20c49df ("Use qemu_strtoul() in set_pci_host_devaddr()")
> >> Reported-by: Klaus Herman 
> >> Reported-by: Geoffrey McRae 
> >> Signed-off-by: Michael S. Tsirkin 
> >> ---
> >>
> >> checkpatch will complain since it does not like strtoul but
> >> we had it for years so should be ok for 5.2, right?
> > 
> > Yes, of course.
> > 
> > Paolo
> 
> Which tree is going to merge this patch?

Sorry, I was expecting Michael to merge it, as it's PCI-specific
but it looks like people were waiting for me to merge it.

I'll merge it and submit a pull request ASAP.

-- 
Eduardo




Re: [PATCH v3 10/19] qlit: Support all types of QNums

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 01:22:02PM +0100, Markus Armbruster wrote:
> Paolo Bonzini  writes:
> 
> > On 24/11/20 10:55, Markus Armbruster wrote:
> >>> +/* Larger than UINT64_MAX: */
> >>> +QLIT_QNUM_DOUBLE(18446744073709552e3),
> >>> +/* Smaller than INT64_MIN: */
> >>> +QLIT_QNUM_DOUBLE(-92233720368547758e2),
> >> Why "larger than UINT64_MAX" and "smaller than INT64_MIN"?
> >> 
> >
> > I guess the point is to test values that are only representable as a
> > double, so (double)((uint64_t)INT64_MAX+1) wouldn't be very useful for 
> > that: as the expression shows, it would not be a QNUM_VAL_INT but it
> > would be representable as QNUM_VAL_UINT.
> >
> > So these are the cases that matter the most, even though -1, 0 and
> > INT64_MAX+1 could be nice to have.
> 
> qnum_is_equal()'s contract:
> 
>  * Doubles are never considered equal to integers.

If that's part of the contract, it would be OK to include
0.0, -1.0, 1.0, INT64_MAX+1 in the list.  I incorrectly assumed
  qnum_is_equal(qnum_from_int(0), qnum_from_double(0.0))
was undefined.

However, if we really care about test coverage of
qnum_is_equal(), we probably should be extending check-qnum.c,
not check-qlit.c.

-- 
Eduardo




Re: [PATCH v3 08/19] qlit: Move qlit_equal_qobject() reference values to array

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 10:51:34AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > Add an array of values to qlit_equal_qobject_test(), so we can
> > extend the test case to compare multiple literals, not just the
> > ones at the existing `qlit` and `qlit_foo` variables.
> >
> > Signed-off-by: Eduardo Habkost 
> > ---
> > This is a new patch added in v3 of this series.
> > ---
> >  tests/check-qlit.c | 26 +++---
> >  1 file changed, 19 insertions(+), 7 deletions(-)
> >
> > diff --git a/tests/check-qlit.c b/tests/check-qlit.c
> > index 24ac21395c..b1cfbddb17 100644
> > --- a/tests/check-qlit.c
> > +++ b/tests/check-qlit.c
> > @@ -29,11 +29,6 @@ static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) {
> >  { },
> >  }));
> >  
> > -static QLitObject qlit_foo = QLIT_QDICT(((QLitDictEntry[]) {
> > -{ "foo", QLIT_QNUM_INT(42) },
> > -{ },
> > -}));
> > -
> >  static QObject *make_qobject(void)
> >  {
> >  QDict *qdict = qdict_new();
> > @@ -53,16 +48,33 @@ static QObject *make_qobject(void)
> >  
> >  static void qlit_equal_qobject_test(void)
> >  {
> > +/* Each entry in the values[] array should be different from the 
> > others */
> > +QLitObject values[] = {
> > +qlit,
> > +QLIT_QDICT(((QLitDictEntry[]) {
> > +{ "foo", QLIT_QNUM_INT(42) },
> > +{ },
> > +})),
> > +};
> > +int i;
> >  QObject *qobj = make_qobject();
> >  
> >  g_assert(qlit_equal_qobject(&qlit, qobj));
> >  
> > -g_assert(!qlit_equal_qobject(&qlit_foo, qobj));
> > -
> >  qdict_put(qobject_to(QDict, qobj), "bee", qlist_new());
> >  g_assert(!qlit_equal_qobject(&qlit, qobj));
> >  
> >  qobject_unref(qobj);
> > +
> > +for (i = 0; i < ARRAY_SIZE(values); i++) {
> > +int j;
> 
> I'd prefer to declare this one together with @i.
> 
> > +QObject *o = qobject_from_qlit(&values[i]);
> 
> Blank line, if you don't mind.

I will surely do it if there's a v4, but I hope you don't make me
submit v4 just to change these.

> 
> > +for (j = 0; j < ARRAY_SIZE(values); j++) {
> > +g_assert(qlit_equal_qobject(&values[j], o) == (i == j));
> > +}
> > +qobject_unref(o);
> > +}
> > +
> >  }
> >  
> >  static void qlit_equal_large_qnum_test(void)

-- 
Eduardo




Re: [PATCH v3 11/19] qom: field_prop_set_default_value() helper

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 10:58:27AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > Move code that sets the property default value to a separate
> > function, to reduce duplication and make refactoring easier.
> >
> > Signed-off-by: Eduardo Habkost 
> > ---
> > This is a new patch added in v3 of this series.
> > Hopefully, this will make the series easier to review.
> >
> > The field_prop_set_default_value() was added in v2 at
> > "qom: Use qlit to represent property defaults".
> > ---
> >  qom/field-property.c | 24 
> >  1 file changed, 16 insertions(+), 8 deletions(-)
> >
> > diff --git a/qom/field-property.c b/qom/field-property.c
> > index cb729626ce..6a0df7c6ea 100644
> > --- a/qom/field-property.c
> > +++ b/qom/field-property.c
> > @@ -62,6 +62,17 @@ static void static_prop_release_dynamic_prop(Object 
> > *obj, const char *name,
> >  g_free(prop);
> >  }
> >  
> > +static void field_prop_set_default_value(ObjectProperty *op,
> > + Property *prop)
> > +{
> > +if (!prop->set_default) {
> > +return;
> > +}
> > +
> > +assert(prop->info->set_default_value);
> > +prop->info->set_default_value(op, prop);
> > +}
> > +
> >  ObjectProperty *
> >  object_property_add_field(Object *obj, const char *name,
> >Property *prop,
> > @@ -83,11 +94,9 @@ object_property_add_field(Object *obj, const char *name,
> >  object_property_set_description(obj, name,
> >  newprop->info->description);
> >  
> > -if (newprop->set_default) {
> > -newprop->info->set_default_value(op, newprop);
> > -if (op->init) {
> > -op->init(obj, op);
> > -}
> > +field_prop_set_default_value(op, newprop);
> > +if (op->init) {
> > +op->init(obj, op);
> >  }
> 
> op->init() is now called even when !newprop->set_default.  Why is that
> okay?

op->init() will be NULL if object_property_set_default() was not
called.

It's subtle, and worth mentioning in the commit message.  I think
we should encapsulate op->init() behind a
object_property_reset_to_default_value() function.

> 
> >  
> >  op->allow_set = allow_set;
> > @@ -113,9 +122,8 @@ object_class_property_add_field_static(ObjectClass *oc, 
> > const char *name,
> > prop->info->release,
> > prop);
> >  }
> > -if (prop->set_default) {
> > -prop->info->set_default_value(op, prop);
> > -}
> > +
> > +field_prop_set_default_value(op, prop);
> >  if (prop->info->description) {
> >  object_class_property_set_description(oc, name,
> >prop->info->description);

-- 
Eduardo




Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-24 Thread Eduardo Habkost
On Tue, Nov 24, 2020 at 09:49:30AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Mon, Nov 23, 2020 at 08:51:27AM +0100, Markus Armbruster wrote:
> >> Eduardo Habkost  writes:
> >> 
> >> > On Fri, Nov 20, 2020 at 06:29:16AM +0100, Markus Armbruster wrote:
> >> [...]
> >> >> When the structure of a data type is to be kept away from its users, I
> >> >> prefer to keep it out of the public header, so the compiler enforces the
> >> >> encapsulation.
> >> >
> >> > I prefer that too, except that it is impossible when users of the
> >> > API need the compiler to know the struct size.
> >> 
> >> There are cases where the structure of a data type should be
> >> encapsulated, yet its size must be made known for performance (avoid
> >> dynamic memory allocation and pointer chasing).
> >> 
> >> Need for encapsulation correlates with complex algorithms and data
> >> structures.  The cost of dynamic allocation is often in the noise then.
> >
> > I don't know what we are talking about anymore.  None of this
> > applies to the QNum API, right?
> >
> > QNum/QNumValue are not complex data structures, and the reason we
> > need the compiler to know the size of QNumValue is not related to
> > performance at all.
> 
> We started with the question whether to make QNumValue's members
> private.  We digressed to the question when to make members private.
> So back to the original question.
> 
> > We might still want to discourage users of the QNum API from
> > accessing QNum.u/QNumValue.u directly.  Documenting the field as
> > private is a very easy way to do it.
> 
> It's a complete non-issue.  QNum has been around for years, and we
> haven't had any issues that could've been plausibly avoided by asking
> people to refrain from accessing its members.
> 
> If there was an actual need to keep the members private, I'd move the
> struct out of the header, so the compiler enforces privacy.

Understood.  There's still a question I'd like to answer, to
decide how the API documentation should look like:

  Is QNum.u/QNumValue.u required to be part of the API
  documentation?

If accessing that field directly is not necessary for using the
API, I don't think it should appear in the documentation (because
it would be just noise).

-- 
Eduardo




[PATCH v3 16/19] qom: Make PropertyInfo.set_default_value optional

2020-11-23 Thread Eduardo Habkost
If .set_default_value is not set, call
object_property_set_default().  This will let us delete most of
the .set_default_value functions later.

Signed-off-by: Eduardo Habkost 
---
This is a new patch in v3 of this series.

In v2 of the series, equivalent functionality was implemented by
"qom: Use qlit to represent property defaults".
---
 include/qom/field-property.h |  3 +++
 qom/field-property.c | 12 ++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index 951cec2fb0..00b83ee9ba 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -53,6 +53,9 @@ struct PropertyInfo {
  * @set_default_value: Callback for initializing the default value
  *
  * @defval is a weak reference.
+ *
+ * Optional.  If not set and Property.defval is not QTYPE_NONE,
+ * object_property_set_default() will be called.
  */
 void (*set_default_value)(ObjectProperty *op, const Property *prop,
   const QObject *defval);
diff --git a/qom/field-property.c b/qom/field-property.c
index 593ffb53e9..d21ff98862 100644
--- a/qom/field-property.c
+++ b/qom/field-property.c
@@ -72,8 +72,16 @@ static void field_prop_set_default_value(ObjectProperty *op,
 }
 
 defval = qobject_from_qlit(&prop->defval);
-assert(prop->info->set_default_value);
-prop->info->set_default_value(op, prop, defval);
+if (prop->info->set_default_value) {
+/* .set_default_value() gets a weak reference */
+prop->info->set_default_value(op, prop, defval);
+} else {
+/*
+ * object_property_set_default() takes ownership,
+ * so qobject_ref() is needed.
+ */
+object_property_set_default(op, qobject_ref(defval));
+}
 qobject_unref(defval);
 }
 
-- 
2.28.0




[PATCH v3 15/19] qom: Make object_property_set_default() public

2020-11-23 Thread Eduardo Habkost
The function will be used outside qom/object.c, to simplify the
field property code that sets the property default value.

Reviewed-by: Marc-André Lureau 
Signed-off-by: Eduardo Habkost 
---
 include/qom/object.h | 11 +++
 qom/object.c |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 2ab124b8f0..4234cc9b66 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1090,6 +1090,17 @@ ObjectProperty *object_class_property_add(ObjectClass 
*klass, const char *name,
   ObjectPropertyRelease *release,
   void *opaque);
 
+/**
+ * object_property_set_default:
+ * @prop: the property to set
+ * @value: the value to be written to the property
+ *
+ * Set the property default value.
+ *
+ * Ownership of @value is transferred to the property.
+ */
+void object_property_set_default(ObjectProperty *prop, QObject *value);
+
 /**
  * object_property_set_default_bool:
  * @prop: the property to set
diff --git a/qom/object.c b/qom/object.c
index 7c11bcd3b1..6b0d9d8c79 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1547,7 +1547,7 @@ static void object_property_init_defval(Object *obj, 
ObjectProperty *prop)
 visit_free(v);
 }
 
-static void object_property_set_default(ObjectProperty *prop, QObject *defval)
+void object_property_set_default(ObjectProperty *prop, QObject *defval)
 {
 assert(!prop->defval);
 assert(!prop->init);
-- 
2.28.0




[PATCH v3 13/19] qom: Fix documentation of UUID property type

2020-11-23 Thread Eduardo Habkost
On some cases, the documentation for UUID properties is lying:
properties defined using DEFINE_PROP_UUID_NODEFAULT are not set
to "auto" by default.  It's better to omit this instead of
providing incorrect information.

Signed-off-by: Eduardo Habkost 
---
This is a new patch addeed in v3 of this series.
---
 hw/core/qdev-properties-system.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 217e041152..6071f672a4 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -1089,7 +1089,7 @@ static void set_default_uuid_auto(ObjectProperty *op, 
const Property *prop,
 const PropertyInfo qdev_prop_uuid = {
 .name  = "str",
 .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
-"\" for random value (default)",
+"\" for random value",
 .get   = get_uuid,
 .set   = set_uuid,
 .set_default_value = set_default_uuid_auto,
-- 
2.28.0




[PATCH v3 11/19] qom: field_prop_set_default_value() helper

2020-11-23 Thread Eduardo Habkost
Move code that sets the property default value to a separate
function, to reduce duplication and make refactoring easier.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.
Hopefully, this will make the series easier to review.

The field_prop_set_default_value() was added in v2 at
"qom: Use qlit to represent property defaults".
---
 qom/field-property.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/qom/field-property.c b/qom/field-property.c
index cb729626ce..6a0df7c6ea 100644
--- a/qom/field-property.c
+++ b/qom/field-property.c
@@ -62,6 +62,17 @@ static void static_prop_release_dynamic_prop(Object *obj, 
const char *name,
 g_free(prop);
 }
 
+static void field_prop_set_default_value(ObjectProperty *op,
+ Property *prop)
+{
+if (!prop->set_default) {
+return;
+}
+
+assert(prop->info->set_default_value);
+prop->info->set_default_value(op, prop);
+}
+
 ObjectProperty *
 object_property_add_field(Object *obj, const char *name,
   Property *prop,
@@ -83,11 +94,9 @@ object_property_add_field(Object *obj, const char *name,
 object_property_set_description(obj, name,
 newprop->info->description);
 
-if (newprop->set_default) {
-newprop->info->set_default_value(op, newprop);
-if (op->init) {
-op->init(obj, op);
-}
+field_prop_set_default_value(op, newprop);
+if (op->init) {
+op->init(obj, op);
 }
 
 op->allow_set = allow_set;
@@ -113,9 +122,8 @@ object_class_property_add_field_static(ObjectClass *oc, 
const char *name,
prop->info->release,
prop);
 }
-if (prop->set_default) {
-prop->info->set_default_value(op, prop);
-}
+
+field_prop_set_default_value(op, prop);
 if (prop->info->description) {
 object_class_property_set_description(oc, name,
   prop->info->description);
-- 
2.28.0




[PATCH v3 17/19] qom: Delete field_prop_set_default_value_*int()

2020-11-23 Thread Eduardo Habkost
The field_prop_set_default_value_*int() functions can be
completely replaced by object_propert_set_default(),
we don't need them anymore.

Signed-off-by: Eduardo Habkost 
---
This is a new patch in v3 of this series.

In v2 of the series, equivalent changes were part of "qom: Use
qlit to represent property defaults".
---
 include/qom/field-property-internal.h |  6 --
 hw/core/qdev-properties-system.c  |  2 --
 qom/property-types.c  | 25 -
 3 files changed, 33 deletions(-)

diff --git a/include/qom/field-property-internal.h 
b/include/qom/field-property-internal.h
index 7ed0d8d160..4bcf5b45f3 100644
--- a/include/qom/field-property-internal.h
+++ b/include/qom/field-property-internal.h
@@ -16,12 +16,6 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char 
*name,
 void field_prop_set_default_value_enum(ObjectProperty *op,
const Property *prop,
const QObject *defval);
-void field_prop_set_default_value_int(ObjectProperty *op,
-  const Property *prop,
-   const QObject *defval);
-void field_prop_set_default_value_uint(ObjectProperty *op,
-   const Property *prop,
-   const QObject *defval);
 
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
   void *opaque, Error **errp);
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 117c540254..b2df955f2a 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -571,7 +571,6 @@ const PropertyInfo qdev_prop_blocksize = {
" and " MAX_BLOCK_SIZE_STR,
 .get   = field_prop_get_size32,
 .set   = set_blocksize,
-.set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- Block device error handling policy --- */
@@ -769,7 +768,6 @@ const PropertyInfo qdev_prop_pci_devfn = {
 .print = print_pci_devfn,
 .get   = field_prop_get_int32,
 .set   = set_pci_devfn,
-.set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- pci host address --- */
diff --git a/qom/property-types.c b/qom/property-types.c
index 0fc24b3687..399e36c29e 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -195,27 +195,10 @@ static void set_uint8(Object *obj, Visitor *v, const char 
*name, void *opaque,
 visit_type_uint8(v, name, ptr, errp);
 }
 
-void field_prop_set_default_value_int(ObjectProperty *op,
-  const Property *prop,
-  const QObject *defval)
-{
-QNum *qn = qobject_to(QNum, defval);
-object_property_set_default_int(op, qnum_get_int(qn));
-}
-
-void field_prop_set_default_value_uint(ObjectProperty *op,
-   const Property *prop,
-   const QObject *defval)
-{
-QNum *qn = qobject_to(QNum, defval);
-object_property_set_default_uint(op, qnum_get_uint(qn));
-}
-
 const PropertyInfo prop_info_uint8 = {
 .name  = "uint8",
 .get   = get_uint8,
 .set   = set_uint8,
-.set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 16bit integer --- */
@@ -242,7 +225,6 @@ const PropertyInfo prop_info_uint16 = {
 .name  = "uint16",
 .get   = get_uint16,
 .set   = set_uint16,
-.set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 32bit integer --- */
@@ -287,14 +269,12 @@ const PropertyInfo prop_info_uint32 = {
 .name  = "uint32",
 .get   = get_uint32,
 .set   = set_uint32,
-.set_default_value = field_prop_set_default_value_uint,
 };
 
 const PropertyInfo prop_info_int32 = {
 .name  = "int32",
 .get   = field_prop_get_int32,
 .set   = set_int32,
-.set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- 64bit integer --- */
@@ -339,14 +319,12 @@ const PropertyInfo prop_info_uint64 = {
 .name  = "uint64",
 .get   = get_uint64,
 .set   = set_uint64,
-.set_default_value = field_prop_set_default_value_uint,
 };
 
 const PropertyInfo prop_info_int64 = {
 .name  = "int64",
 .get   = get_int64,
 .set   = set_int64,
-.set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- string --- */
@@ -441,7 +419,6 @@ const PropertyInfo prop_info_size32 = {
 .name  = "size",
 .get = field_prop_get_size32,
 .set = set_size32,
-.set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- support for array properties --- */
@@ -505,7 +482,6 @@ const PropertyInfo prop_info_arraylen = {
 .name = "uint32",
 .get = get_uint32,
 .set = set_prop_arraylen,
-.set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 6

[PATCH v3 14/19] qom: Don't ignore defval on UUID property

2020-11-23 Thread Eduardo Habkost
UUID properties were weird because the value of .defval was
completely ignored.  Fix this by setting the default value to
QLIT_QSTR("auto") on the default case, and actually using .defval
inside .set_default_value.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.

This is similar (but not completely the same) to changes that
were submitted as part of
"[PATCH v2 8/8] qom: Use qlit to represent property defaults".
---
 include/hw/qdev-properties-system.h |  9 +++--
 hw/core/qdev-properties-system.c| 10 +-
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/include/hw/qdev-properties-system.h 
b/include/hw/qdev-properties-system.h
index 6221da704e..834ca84904 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -63,14 +63,11 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \
 PCIExpLinkWidth)
 
+#define UUID_VALUE_AUTO"auto"
+
 #define DEFINE_PROP_UUID(_name, _state, _field) \
 DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID, \
-/*   \
- * Note that set_default_uuid_auto() currently   \
- * ignores the actual value value of .defval,\
- * we just need it to not be not QTYPE_NONE  \
- */  \
-.defval = QLIT_QNULL)
+.defval = QLIT_QSTR(UUID_VALUE_AUTO))
 
 #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 6071f672a4..117c540254 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -15,6 +15,7 @@
 #include "hw/qdev-properties-system.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
+#include "qapi/qmp/qstring.h"
 #include "qapi/qapi-types-block.h"
 #include "qapi/qapi-types-machine.h"
 #include "qapi/qapi-types-migration.h"
@@ -1059,8 +1060,6 @@ static void get_uuid(Object *obj, Visitor *v, const char 
*name, void *opaque,
 visit_type_str(v, name, &p, errp);
 }
 
-#define UUID_VALUE_AUTO"auto"
-
 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 Error **errp)
 {
@@ -1080,10 +1079,11 @@ static void set_uuid(Object *obj, Visitor *v, const 
char *name, void *opaque,
 g_free(str);
 }
 
-static void set_default_uuid_auto(ObjectProperty *op, const Property *prop,
+static void set_default_uuid(ObjectProperty *op, const Property *prop,
   const QObject *defval)
 {
-object_property_set_default_str(op, UUID_VALUE_AUTO);
+QString *qs = qobject_to(QString, defval);
+object_property_set_default_str(op, qstring_get_str(qs));
 }
 
 const PropertyInfo qdev_prop_uuid = {
@@ -1092,5 +1092,5 @@ const PropertyInfo qdev_prop_uuid = {
 "\" for random value",
 .get   = get_uuid,
 .set   = set_uuid,
-.set_default_value = set_default_uuid_auto,
+.set_default_value = set_default_uuid,
 };
-- 
2.28.0




[PATCH v3 03/19] qnum: QNumValue type for QNum value literals

2020-11-23 Thread Eduardo Habkost
Provide a separate QNumValue type that can be used for QNum value
literals without the referencing counting and memory allocation
features provided by QObject.

Signed-off-by: Eduardo Habkost 
---
Changes v2 -> v3:
* Fixed copy-pasta at qnum_from_value() documentation
* Removed qnum_get_value() function
* Moved doc comment of qnum_from_value() to .c file, for
  consistency with other functions.
* Removed "private:" doc comment at QNumValue.
* Removed unnecessary kernel-doc noise (obvious
  parameter descriptions).
* Removed space after type cast in qnum_from_*().
* qnum_is_equal() variable const-ness & renames:
  * Renamed new QNumValue variables to val_x/val_y.
  * Keep existing QNum num_x/num_y variable names.
  * const-ness change of num_x/num_y was moved to a separate
patch.

Changes v1 -> v2:
* Fix "make check" failure, by updating check-qnum unit test to
  use the new struct fields
---
 include/qapi/qmp/qnum.h | 23 ++-
 qobject/qnum.c  | 91 ++---
 tests/check-qnum.c  | 14 +++
 3 files changed, 76 insertions(+), 52 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 3e9ecd324e..03193dca20 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -44,16 +44,35 @@ typedef enum {
  * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
  * convert under the hood.
  */
-struct QNum {
-struct QObjectBase_ base;
+
+/**
+ * struct QNumValue: the value of a QNum
+ *
+ * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
+ * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
+ */
+typedef struct QNumValue {
 QNumKind kind;
 union {
 int64_t i64;
 uint64_t u64;
 double dbl;
 } u;
+} QNumValue;
+
+#define QNUM_VAL_INT(value) \
+{ .kind = QNUM_I64, .u.i64 = value }
+#define QNUM_VAL_UINT(value) \
+{ .kind = QNUM_U64, .u.u64 = value }
+#define QNUM_VAL_DOUBLE(value) \
+{ .kind = QNUM_DOUBLE, .u.dbl = value }
+
+struct QNum {
+struct QObjectBase_ base;
+QNumValue value;
 };
 
+QNum *qnum_from_value(QNumValue value);
 QNum *qnum_from_int(int64_t value);
 QNum *qnum_from_uint(uint64_t value);
 QNum *qnum_from_double(double value);
diff --git a/qobject/qnum.c b/qobject/qnum.c
index e5ea728638..94e668db60 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -16,21 +16,29 @@
 #include "qapi/qmp/qnum.h"
 
 /**
- * qnum_from_int(): Create a new QNum from an int64_t
+ * qnum_from_value(): Create a new QNum from a QNumValue
  *
  * Return strong reference.
  */
-QNum *qnum_from_int(int64_t value)
+QNum *qnum_from_value(QNumValue value)
 {
 QNum *qn = g_new(QNum, 1);
 
 qobject_init(QOBJECT(qn), QTYPE_QNUM);
-qn->kind = QNUM_I64;
-qn->u.i64 = value;
-
+qn->value = value;
 return qn;
 }
 
+/**
+ * qnum_from_int(): Create a new QNum from an int64_t
+ *
+ * Return strong reference.
+ */
+QNum *qnum_from_int(int64_t value)
+{
+return qnum_from_value((QNumValue)QNUM_VAL_INT(value));
+}
+
 /**
  * qnum_from_uint(): Create a new QNum from an uint64_t
  *
@@ -38,13 +46,7 @@ QNum *qnum_from_int(int64_t value)
  */
 QNum *qnum_from_uint(uint64_t value)
 {
-QNum *qn = g_new(QNum, 1);
-
-qobject_init(QOBJECT(qn), QTYPE_QNUM);
-qn->kind = QNUM_U64;
-qn->u.u64 = value;
-
-return qn;
+return qnum_from_value((QNumValue)QNUM_VAL_UINT(value));
 }
 
 /**
@@ -54,13 +56,7 @@ QNum *qnum_from_uint(uint64_t value)
  */
 QNum *qnum_from_double(double value)
 {
-QNum *qn = g_new(QNum, 1);
-
-qobject_init(QOBJECT(qn), QTYPE_QNUM);
-qn->kind = QNUM_DOUBLE;
-qn->u.dbl = value;
-
-return qn;
+return qnum_from_value((QNumValue)QNUM_VAL_DOUBLE(value));
 }
 
 /**
@@ -70,15 +66,17 @@ QNum *qnum_from_double(double value)
  */
 bool qnum_get_try_int(const QNum *qn, int64_t *val)
 {
-switch (qn->kind) {
+const QNumValue *qv = &qn->value;
+
+switch (qv->kind) {
 case QNUM_I64:
-*val = qn->u.i64;
+*val = qv->u.i64;
 return true;
 case QNUM_U64:
-if (qn->u.u64 > INT64_MAX) {
+if (qv->u.u64 > INT64_MAX) {
 return false;
 }
-*val = qn->u.u64;
+*val = qv->u.u64;
 return true;
 case QNUM_DOUBLE:
 return false;
@@ -108,15 +106,17 @@ int64_t qnum_get_int(const QNum *qn)
  */
 bool qnum_get_try_uint(const QNum *qn, uint64_t *val)
 {
-switch (qn->kind) {
+const QNumValue *qv = &qn->value;
+
+switch (qv->kind) {
 case QNUM_I64:
-if (qn->u.i64 < 0) {
+if (qv->u.i64 < 0) {
 return false;
 }
-*val = qn->u.i64;
+*val = qv->u.i64;
 return true;
 case QNUM_U64:
-*val = qn->u.u64;
+*val = qv->u.u64;
 return true;
 case QNUM_DOUBLE:
 return false;
@@ -146,1

[PATCH v3 04/19] qnum: qnum_value_is_equal() function

2020-11-23 Thread Eduardo Habkost
Extract the QNum value comparison logic to a function that takes
QNumValue* as argument.

Signed-off-by: Eduardo Habkost 
---
Changes v2 -> v3:
* Rename function parameters to val_x/val_y
* Insert blank line after variable declarations at
  qnum_is_equal()
---
 include/qapi/qmp/qnum.h |  1 +
 qobject/qnum.c  | 24 
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 03193dca20..3dcb020689 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -87,6 +87,7 @@ double qnum_get_double(const QNum *qn);
 
 char *qnum_to_string(QNum *qn);
 
+bool qnum_value_is_equal(const QNumValue *val_x, const QNumValue *val_y);
 bool qnum_is_equal(const QObject *x, const QObject *y);
 void qnum_destroy_obj(QObject *obj);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 94e668db60..53c637f46d 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -202,7 +202,7 @@ char *qnum_to_string(QNum *qn)
 }
 
 /**
- * qnum_is_equal(): Test whether the two QNums are equal
+ * qnum_value_is_equal(): Test whether two QNumValues are equal
  *
  * Negative integers are never considered equal to unsigned integers,
  * but positive integers in the range [0, INT64_MAX] are considered
@@ -210,13 +210,8 @@ char *qnum_to_string(QNum *qn)
  *
  * Doubles are never considered equal to integers.
  */
-bool qnum_is_equal(const QObject *x, const QObject *y)
+bool qnum_value_is_equal(const QNumValue *val_x, const QNumValue *val_y)
 {
-const QNum *num_x = qobject_to(QNum, x);
-const QNum *num_y = qobject_to(QNum, y);
-const QNumValue *val_x = &num_x->value;
-const QNumValue *val_y = &num_y->value;
-
 switch (val_x->kind) {
 case QNUM_I64:
 switch (val_y->kind) {
@@ -234,7 +229,7 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
 case QNUM_U64:
 switch (val_y->kind) {
 case QNUM_I64:
-return qnum_is_equal(y, x);
+return qnum_value_is_equal(val_y, val_x);
 case QNUM_U64:
 /* Comparison in native uint64_t type */
 return val_x->u.u64 == val_y->u.u64;
@@ -257,6 +252,19 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
 abort();
 }
 
+/**
+ * qnum_is_equal(): Test whether the two QNums are equal
+ *
+ * See qnum_value_is_equal() for details on the comparison rules.
+ */
+bool qnum_is_equal(const QObject *x, const QObject *y)
+{
+const QNum *qnum_x = qobject_to(QNum, x);
+const QNum *qnum_y = qobject_to(QNum, y);
+
+return qnum_value_is_equal(&qnum_x->value, &qnum_y->value);
+}
+
 /**
  * qnum_destroy_obj(): Free all memory allocated by a
  * QNum object
-- 
2.28.0




[PATCH v3 19/19] qom: Delete set_default_value_bool()

2020-11-23 Thread Eduardo Habkost
set_default_value_bool() can be completely replaced by
object_property_set_default(), we don't need that function
anymore.

Signed-off-by: Eduardo Habkost 
---
This is a new patch in v3 of this series.

In v2 of the series, equivalent changes were part of "qom: Use
qlit to represent property defaults".
---
 qom/property-types.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/qom/property-types.c b/qom/property-types.c
index 399e36c29e..cb7ba2a229 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -84,19 +84,11 @@ static void prop_set_bit(Object *obj, Visitor *v, const 
char *name,
 bit_prop_set(obj, prop, value);
 }
 
-static void set_default_value_bool(ObjectProperty *op, const Property *prop,
-   const QObject *defval)
-{
-QBool *qb = qobject_to(QBool, defval);
-object_property_set_default_bool(op, qbool_get_bool(qb));
-}
-
 const PropertyInfo prop_info_bit = {
 .name  = "bool",
 .description = "on/off",
 .get   = prop_get_bit,
 .set   = prop_set_bit,
-.set_default_value = set_default_value_bool,
 };
 
 /* Bit64 */
@@ -145,7 +137,6 @@ const PropertyInfo prop_info_bit64 = {
 .description = "on/off",
 .get   = prop_get_bit64,
 .set   = prop_set_bit64,
-.set_default_value = set_default_value_bool,
 };
 
 /* --- bool --- */
@@ -172,7 +163,6 @@ const PropertyInfo prop_info_bool = {
 .name  = "bool",
 .get   = get_bool,
 .set   = set_bool,
-.set_default_value = set_default_value_bool,
 };
 
 /* --- 8bit integer --- */
-- 
2.28.0




[PATCH v3 12/19] qom: Replace defval value in Property with QLitObject

2020-11-23 Thread Eduardo Habkost
QLitObject is capable of representing a wider range of values,
and it will allow us to simplify a lot of the existing code
setting property defaults, later.  Replace the bool and union
fields with QLitObject.

In short, this is just a direct translation from:
  prop->set_default
to
  prop->defval.type != QTYPE_NONE

from
  prop->defval.i
to
  qnum_get_int(qobject_to(QNum, prop->defval)

and from
  prop->defval.u
to
  qnum_get_uint(qobject_to(QNum, prop->defval)

Note that this doesn't replace any of the default property
setters (yet), but just make them safer.  Now the actual type of
.defval is validated before it is used.

Also note that set_default_uuid_auto() is a bit weird: it ignores
.defval completely.  This patch keeps the existing behavior, and
set_default_uuid_auto() weirdness will be addressed later.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.

I am splitting the changes and making them in smaller steps to
make them easier to understand and review.  With this, I intend
to demonstrate that the conversion from bool+union to QLitObject
is an improvement even if the removal of custom .set_defaul_value
functions isn't 100% finished yet.
---
 include/hw/qdev-properties-system.h   |  7 ++-
 include/qom/field-property-internal.h |  9 ++---
 include/qom/field-property.h  | 27 ++-
 include/qom/property-types.h  | 18 ++
 hw/core/qdev-properties-system.c  |  3 ++-
 qom/field-property.c  |  8 ++--
 qom/property-types.c  | 26 ++
 7 files changed, 54 insertions(+), 44 deletions(-)

diff --git a/include/hw/qdev-properties-system.h 
b/include/hw/qdev-properties-system.h
index 0ac327ae60..6221da704e 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -65,7 +65,12 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 
 #define DEFINE_PROP_UUID(_name, _state, _field) \
 DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID, \
-.set_default = true)
+/*   \
+ * Note that set_default_uuid_auto() currently   \
+ * ignores the actual value value of .defval,\
+ * we just need it to not be not QTYPE_NONE  \
+ */  \
+.defval = QLIT_QNULL)
 
 #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
diff --git a/include/qom/field-property-internal.h 
b/include/qom/field-property-internal.h
index a7b7e2b69d..7ed0d8d160 100644
--- a/include/qom/field-property-internal.h
+++ b/include/qom/field-property-internal.h
@@ -14,11 +14,14 @@ void field_prop_set_enum(Object *obj, Visitor *v, const 
char *name,
  void *opaque, Error **errp);
 
 void field_prop_set_default_value_enum(ObjectProperty *op,
-   const Property *prop);
+   const Property *prop,
+   const QObject *defval);
 void field_prop_set_default_value_int(ObjectProperty *op,
-  const Property *prop);
+  const Property *prop,
+   const QObject *defval);
 void field_prop_set_default_value_uint(ObjectProperty *op,
-   const Property *prop);
+   const Property *prop,
+   const QObject *defval);
 
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
   void *opaque, Error **errp);
diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index 0cb1fe2217..951cec2fb0 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -6,6 +6,7 @@
 
 #include "qom/object.h"
 #include "qapi/util.h"
+#include "qapi/qmp/qlit.h"
 
 /**
  * struct Property: definition of a field property
@@ -27,21 +28,8 @@ struct Property {
 const PropertyInfo *info;
 ptrdiff_toffset;
 uint8_t  bitnr;
-/**
- * @set_default: true if the default value should be set from @defval,
- *in which case @info->set_default_value must not be NULL
- *(if false then no default value is set by the property system
- * and the field retains whatever value it was given by instance_init).
- */
-bool set_default;
-/**
- * @defval: default value for the property. This is used only if 
@set_default
- * is true.
- */
-union {
-int64_t i;
-uint64_t u;
-} defval;
+/** @defval: If not QTYPE_NONE, the default value for the property */
+QLitObject defval;
 /* priva

[PATCH v3 09/19] qlit: Add more test literals to qlit_equal_qobject() test case

2020-11-23 Thread Eduardo Habkost
Add a few examples of each qlit type, to make sure each one
compare as equal to itself, but not equal to the other values.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.
---
 tests/check-qlit.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index b1cfbddb17..5a9260b93f 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -50,11 +50,27 @@ static void qlit_equal_qobject_test(void)
 {
 /* Each entry in the values[] array should be different from the others */
 QLitObject values[] = {
+QLIT_QNULL,
+QLIT_QBOOL(false),
+QLIT_QBOOL(true),
+QLIT_QNUM_INT(-1),
+QLIT_QNUM_INT(0),
+QLIT_QNUM_INT(1),
+QLIT_QNUM_INT(INT64_MIN),
+QLIT_QNUM_INT(INT64_MAX),
+QLIT_QSTR(""),
+QLIT_QSTR("foo"),
 qlit,
 QLIT_QDICT(((QLitDictEntry[]) {
 { "foo", QLIT_QNUM_INT(42) },
 { },
 })),
+QLIT_QLIST(((QLitObject[]){
+QLIT_QNUM_INT(-1),
+QLIT_QNUM_INT(0),
+QLIT_QNUM_INT(1),
+{ },
+})),
 };
 int i;
 QObject *qobj = make_qobject();
-- 
2.28.0




[PATCH v3 02/19] qnum: Make num_x/num_y variables at qnum_is_equal() const

2020-11-23 Thread Eduardo Habkost
qobject_to() drops const-ness by accident, but our function
arguments (x, y) are const.  Make num_x/num_y const too.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of the series.
---
 qobject/qnum.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qobject/qnum.c b/qobject/qnum.c
index d328d91fcb..e5ea728638 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -209,8 +209,8 @@ char *qnum_to_string(QNum *qn)
  */
 bool qnum_is_equal(const QObject *x, const QObject *y)
 {
-QNum *num_x = qobject_to(QNum, x);
-QNum *num_y = qobject_to(QNum, y);
+const QNum *num_x = qobject_to(QNum, x);
+const QNum *num_y = qobject_to(QNum, y);
 
 switch (num_x->kind) {
 case QNUM_I64:
-- 
2.28.0




[PATCH v3 18/19] qom: Delete set_default_uuid()

2020-11-23 Thread Eduardo Habkost
The function can be completely replaced by
object_property_set_default(), we don't need it anymore.

Signed-off-by: Eduardo Habkost 
---
This is a new patch in v3 of this series.

In v2 of the series, equivalent changes were part of "qom: Use
qlit to represent property defaults".
---
 hw/core/qdev-properties-system.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index b2df955f2a..07945ea1c0 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -1077,18 +1077,10 @@ static void set_uuid(Object *obj, Visitor *v, const 
char *name, void *opaque,
 g_free(str);
 }
 
-static void set_default_uuid(ObjectProperty *op, const Property *prop,
-  const QObject *defval)
-{
-QString *qs = qobject_to(QString, defval);
-object_property_set_default_str(op, qstring_get_str(qs));
-}
-
 const PropertyInfo qdev_prop_uuid = {
 .name  = "str",
 .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
 "\" for random value",
 .get   = get_uuid,
 .set   = set_uuid,
-.set_default_value = set_default_uuid,
 };
-- 
2.28.0




[PATCH v3 06/19] qlit: Rename QLIT_QNUM to QLIT_QNUM_INT

2020-11-23 Thread Eduardo Habkost
Rename the existing QLIT_QNUM macro to indicate it only supports
signed int values.  We're going to add support to other types of
QNums later.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.

In v2, the existing QLIT_QNUM() macro was being kept, now it is
replaced by QLIT_QNUM_INT().
---
 include/qapi/qmp/qlit.h |  2 +-
 tests/check-qjson.c | 30 +++---
 tests/check-qlit.c  | 10 +-
 3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index c0676d5daf..2fc2db282e 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -39,7 +39,7 @@ struct QLitDictEntry {
 { .type = QTYPE_QNULL }
 #define QLIT_QBOOL(val) \
 { .type = QTYPE_QBOOL, .value.qbool = (val) }
-#define QLIT_QNUM(val) \
+#define QLIT_QNUM_INT(val) \
 { .type = QTYPE_QNUM, .value.qnum = (val) }
 #define QLIT_QSTR(val) \
 { .type = QTYPE_QSTRING, .value.qstr = (val) }
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 07a773e653..bc5b7ebdf3 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -1062,7 +1062,7 @@ static void simple_dict(void)
 {
 .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
 .decoded = QLIT_QDICT(((QLitDictEntry[]){
-{ "foo", QLIT_QNUM(42) },
+{ "foo", QLIT_QNUM_INT(42) },
 { "bar", QLIT_QSTR("hello world") },
 { }
 })),
@@ -1074,7 +1074,7 @@ static void simple_dict(void)
 }, {
 .encoded = "{\"foo\": 43}",
 .decoded = QLIT_QDICT(((QLitDictEntry[]){
-{ "foo", QLIT_QNUM(43) },
+{ "foo", QLIT_QNUM_INT(43) },
 { }
 })),
 },
@@ -1160,15 +1160,15 @@ static void simple_list(void)
 {
 .encoded = "[43,42]",
 .decoded = QLIT_QLIST(((QLitObject[]){
-QLIT_QNUM(43),
-QLIT_QNUM(42),
+QLIT_QNUM_INT(43),
+QLIT_QNUM_INT(42),
 { }
 })),
 },
 {
 .encoded = "[43]",
 .decoded = QLIT_QLIST(((QLitObject[]){
-QLIT_QNUM(43),
+QLIT_QNUM_INT(43),
 { }
 })),
 },
@@ -1217,35 +1217,35 @@ static void simple_whitespace(void)
 {
 .encoded = " [ 43 , 42 ]",
 .decoded = QLIT_QLIST(((QLitObject[]){
-QLIT_QNUM(43),
-QLIT_QNUM(42),
+QLIT_QNUM_INT(43),
+QLIT_QNUM_INT(42),
 { }
 })),
 },
 {
 .encoded = "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
 .decoded = QLIT_QLIST(((QLitObject[]){
-QLIT_QNUM(43),
+QLIT_QNUM_INT(43),
 QLIT_QDICT(((QLitDictEntry[]){
 { "h", QLIT_QSTR("b") },
 { }})),
 QLIT_QLIST(((QLitObject[]){
 { }})),
-QLIT_QNUM(42),
+QLIT_QNUM_INT(42),
 { }
 })),
 },
 {
 .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
 .decoded = QLIT_QLIST(((QLitObject[]){
-QLIT_QNUM(43),
+QLIT_QNUM_INT(43),
 QLIT_QDICT(((QLitDictEntry[]){
 { "h", QLIT_QSTR("b") },
-{ "a", QLIT_QNUM(32) },
+{ "a", QLIT_QNUM_INT(32) },
 { }})),
 QLIT_QLIST(((QLitObject[]){
 { }})),
-QLIT_QNUM(42),
+QLIT_QNUM_INT(42),
 { }
 })),
 },
@@ -1275,11 +1275,11 @@ static void simple_interpolation(void)
 QObject *embedded_obj;
 QObject *obj;
 QLitObject decoded = QLIT_QLIST(((QLitObject[]){
-QLIT_QNUM(1),
+QLIT_QNUM_INT(1),
 QLIT_QSTR("100%"),
 QLIT_QLIST(((QLitObject[]){
-QLIT_QNUM(32),
-QLIT_QNUM(42),
+

[PATCH v3 08/19] qlit: Move qlit_equal_qobject() reference values to array

2020-11-23 Thread Eduardo Habkost
Add an array of values to qlit_equal_qobject_test(), so we can
extend the test case to compare multiple literals, not just the
ones at the existing `qlit` and `qlit_foo` variables.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.
---
 tests/check-qlit.c | 26 +++---
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index 24ac21395c..b1cfbddb17 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -29,11 +29,6 @@ static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) {
 { },
 }));
 
-static QLitObject qlit_foo = QLIT_QDICT(((QLitDictEntry[]) {
-{ "foo", QLIT_QNUM_INT(42) },
-{ },
-}));
-
 static QObject *make_qobject(void)
 {
 QDict *qdict = qdict_new();
@@ -53,16 +48,33 @@ static QObject *make_qobject(void)
 
 static void qlit_equal_qobject_test(void)
 {
+/* Each entry in the values[] array should be different from the others */
+QLitObject values[] = {
+qlit,
+QLIT_QDICT(((QLitDictEntry[]) {
+{ "foo", QLIT_QNUM_INT(42) },
+{ },
+})),
+};
+int i;
 QObject *qobj = make_qobject();
 
 g_assert(qlit_equal_qobject(&qlit, qobj));
 
-g_assert(!qlit_equal_qobject(&qlit_foo, qobj));
-
 qdict_put(qobject_to(QDict, qobj), "bee", qlist_new());
 g_assert(!qlit_equal_qobject(&qlit, qobj));
 
 qobject_unref(qobj);
+
+for (i = 0; i < ARRAY_SIZE(values); i++) {
+int j;
+QObject *o = qobject_from_qlit(&values[i]);
+for (j = 0; j < ARRAY_SIZE(values); j++) {
+g_assert(qlit_equal_qobject(&values[j], o) == (i == j));
+}
+qobject_unref(o);
+}
+
 }
 
 static void qlit_equal_large_qnum_test(void)
-- 
2.28.0




[PATCH v3 10/19] qlit: Support all types of QNums

2020-11-23 Thread Eduardo Habkost
Add two new macros to support other types of QNums:
QLIT_QNUM_UINT, and QLIT_QNUM_DOUBLE, and include them
in the qlit_equal_qobject_test() test case.

Signed-off-by: Eduardo Habkost 
---
Changes v2 -> v3:
* QLIT_QNUM macro doesn't exist anymore
* Addition of the QNumValue field to QLitObject is
  now in a separate patch ("qlit: Use QNumValue to represent QNums")
* check-qjson test case changes dropped.
  Instead, I'm only extending the qlit_equal_qobject_test() test
  case.

Changes v1 -> v2:
* Coding style fix at qlit_equal_qobject()
---
 include/qapi/qmp/qlit.h | 4 
 tests/check-qlit.c  | 5 +
 2 files changed, 9 insertions(+)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index a240cdd299..a2881b7f42 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -42,6 +42,10 @@ struct QLitDictEntry {
 { .type = QTYPE_QBOOL, .value.qbool = (val) }
 #define QLIT_QNUM_INT(val) \
 { .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_INT(val) }
+#define QLIT_QNUM_UINT(val) \
+{ .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_UINT(val) }
+#define QLIT_QNUM_DOUBLE(val) \
+{ .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_DOUBLE(val) }
 #define QLIT_QSTR(val) \
 { .type = QTYPE_QSTRING, .value.qstr = (val) }
 #define QLIT_QDICT(val) \
diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index 5a9260b93f..31e90f8965 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -58,6 +58,11 @@ static void qlit_equal_qobject_test(void)
 QLIT_QNUM_INT(1),
 QLIT_QNUM_INT(INT64_MIN),
 QLIT_QNUM_INT(INT64_MAX),
+QLIT_QNUM_UINT(UINT64_MAX),
+/* Larger than UINT64_MAX: */
+QLIT_QNUM_DOUBLE(18446744073709552e3),
+/* Smaller than INT64_MIN: */
+QLIT_QNUM_DOUBLE(-92233720368547758e2),
 QLIT_QSTR(""),
 QLIT_QSTR("foo"),
 qlit,
-- 
2.28.0




[PATCH v3 01/19] qnum: Make qnum_get_double() get const pointer

2020-11-23 Thread Eduardo Habkost
qnum_get_double() won't change the object, the argument can be
const.

Reviewed-by: Marc-André Lureau 
Signed-off-by: Eduardo Habkost 
---
 include/qapi/qmp/qnum.h | 2 +-
 qobject/qnum.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index bbae0a5ec8..3e9ecd324e 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -64,7 +64,7 @@ int64_t qnum_get_int(const QNum *qn);
 bool qnum_get_try_uint(const QNum *qn, uint64_t *val);
 uint64_t qnum_get_uint(const QNum *qn);
 
-double qnum_get_double(QNum *qn);
+double qnum_get_double(const QNum *qn);
 
 char *qnum_to_string(QNum *qn);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 7012fc57f2..d328d91fcb 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -144,7 +144,7 @@ uint64_t qnum_get_uint(const QNum *qn)
  *
  * qnum_get_double() loses precision for integers beyond 53 bits.
  */
-double qnum_get_double(QNum *qn)
+double qnum_get_double(const QNum *qn)
 {
 switch (qn->kind) {
 case QNUM_I64:
-- 
2.28.0




[PATCH v3 05/19] qlit: Use qnum_value_is_equal() when comparing QNums

2020-11-23 Thread Eduardo Habkost
Currently, qlit_equal_qobject() crashes if getting a QNum that
can't be represented as int64.  Fix this by using
qnum_value_is_equal().

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of the series.
---
 qobject/qlit.c |  3 ++-
 tests/check-qlit.c | 19 +++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/qobject/qlit.c b/qobject/qlit.c
index be8332136c..67126b25d5 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -71,7 +71,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject 
*rhs)
 case QTYPE_QBOOL:
 return lhs->value.qbool == qbool_get_bool(qobject_to(QBool, rhs));
 case QTYPE_QNUM:
-return lhs->value.qnum ==  qnum_get_int(qobject_to(QNum, rhs));
+return qnum_value_is_equal(&(QNumValue)QNUM_VAL_INT(lhs->value.qnum),
+   &qobject_to(QNum, rhs)->value);
 case QTYPE_QSTRING:
 return (strcmp(lhs->value.qstr,
qstring_get_str(qobject_to(QString, rhs))) == 0);
diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index bd6798d912..58ceaae5a3 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -65,6 +65,24 @@ static void qlit_equal_qobject_test(void)
 qobject_unref(qobj);
 }
 
+static void qlit_equal_large_qnum_test(void)
+{
+/* 2^32-1 */
+QNum *large = qnum_from_uint(9223372036854775807LL);
+/* 2^32 */
+QNum *too_large = qnum_from_uint(9223372036854775808ULL);
+QNum *dbl = qnum_from_double(9223372036854775808.0);
+QLitObject qlit_large = QLIT_QNUM(9223372036854775807LL);
+
+g_assert(qlit_equal_qobject(&qlit_large, QOBJECT(large)));
+g_assert(!qlit_equal_qobject(&qlit_large, QOBJECT(too_large)));
+g_assert(!qlit_equal_qobject(&qlit_large, QOBJECT(dbl)));
+
+qobject_unref(dbl);
+qobject_unref(large);
+qobject_unref(too_large);
+}
+
 static void qobject_from_qlit_test(void)
 {
 QObject *obj, *qobj = qobject_from_qlit(&qlit);
@@ -95,6 +113,7 @@ int main(int argc, char **argv)
 g_test_init(&argc, &argv, NULL);
 
 g_test_add_func("/qlit/equal_qobject", qlit_equal_qobject_test);
+g_test_add_func("/qlit/equal_large_qnum", qlit_equal_large_qnum_test);
 g_test_add_func("/qlit/qobject_from_qlit", qobject_from_qlit_test);
 
 return g_test_run();
-- 
2.28.0




[PATCH v3 07/19] qlit: Use QNumValue to represent QNums

2020-11-23 Thread Eduardo Habkost
Replace the existing int64_t field in QLitObject with QNumValue,
so we can get support for other QNum types for free.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of the series.  It includes
portions of a previous patch from v2:
"qlit: Support all types of QNums".
---
 include/qapi/qmp/qlit.h | 5 +++--
 qobject/qlit.c  | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index 2fc2db282e..a240cdd299 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -15,6 +15,7 @@
 #define QLIT_H
 
 #include "qobject.h"
+#include "qnum.h"
 
 typedef struct QLitDictEntry QLitDictEntry;
 typedef struct QLitObject QLitObject;
@@ -23,7 +24,7 @@ struct QLitObject {
 QType type;
 union {
 bool qbool;
-int64_t qnum;
+QNumValue qnum;
 const char *qstr;
 QLitDictEntry *qdict;
 QLitObject *qlist;
@@ -40,7 +41,7 @@ struct QLitDictEntry {
 #define QLIT_QBOOL(val) \
 { .type = QTYPE_QBOOL, .value.qbool = (val) }
 #define QLIT_QNUM_INT(val) \
-{ .type = QTYPE_QNUM, .value.qnum = (val) }
+{ .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_INT(val) }
 #define QLIT_QSTR(val) \
 { .type = QTYPE_QSTRING, .value.qstr = (val) }
 #define QLIT_QDICT(val) \
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 67126b25d5..b7af81cefb 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -71,7 +71,7 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject 
*rhs)
 case QTYPE_QBOOL:
 return lhs->value.qbool == qbool_get_bool(qobject_to(QBool, rhs));
 case QTYPE_QNUM:
-return qnum_value_is_equal(&(QNumValue)QNUM_VAL_INT(lhs->value.qnum),
+return qnum_value_is_equal(&lhs->value.qnum,
&qobject_to(QNum, rhs)->value);
 case QTYPE_QSTRING:
 return (strcmp(lhs->value.qstr,
@@ -95,7 +95,7 @@ QObject *qobject_from_qlit(const QLitObject *qlit)
 case QTYPE_QNULL:
 return QOBJECT(qnull());
 case QTYPE_QNUM:
-return QOBJECT(qnum_from_int(qlit->value.qnum));
+return QOBJECT(qnum_from_value(qlit->value.qnum));
 case QTYPE_QSTRING:
 return QOBJECT(qstring_from_str(qlit->value.qstr));
 case QTYPE_QDICT: {
-- 
2.28.0




[PATCH v3 00/19] qom: Use qlit to represent property defaults

2020-11-23 Thread Eduardo Habkost
Based-on: 20201104160021.2342108-1-ehabk...@redhat.com
Git branch: https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-qlit-defaults

This extend qlit.h to support all QNum types (signed int,
unsigned int, and double), and use QLitObject to represent field
property defaults.

It allows us to get rid of most type-specific .set_default_value
functions for QOM property types.

The only remaining .set_default_value function in the code is
field_prop_set_default_value_enum().  This will take a bit more
work because the default is currently stored as int, but parsed
as string, so it will be addressed in a separate series.

Changes v2 -> v3:

* qnum/qlit patches:
  * Variable naming in qnum code
  * Coding style changes in qnum code
  * Split "qlit: Support all types of QNums"
in smaller patches
  * Replace QLIT_QNUM with QLIT_QNUM_INT
  * Extend test cases, move most of the new test case code to
check-qlit.c
  * Remove qnum_get_value() and qlit_get_type() function
  * Removed kernel-doc conversion patch, to reduce noise in series review
* qom patches:
  * Split "qom: Use qlit to represent property defaults" in
smaller patches, hopefully making review easier
  * Small changes in UUID property code (See
"qom: Don't ignore defval on UUID property" and
"qom: Fix documentation of UUID property type")

Changes v1 -> v2:
* Rebase to latest version of field properties series
* Fix unit test failure
* Coding style changes

Eduardo Habkost (19):
  qnum: Make qnum_get_double() get const pointer
  qnum: Make num_x/num_y variables at qnum_is_equal() const
  qnum: QNumValue type for QNum value literals
  qnum: qnum_value_is_equal() function
  qlit: Use qnum_value_is_equal() when comparing QNums
  qlit: Rename QLIT_QNUM to QLIT_QNUM_INT
  qlit: Use QNumValue to represent QNums
  qlit: Move qlit_equal_qobject() reference values to array
  qlit: Add more test literals to qlit_equal_qobject() test case
  qlit: Support all types of QNums
  qom: field_prop_set_default_value() helper
  qom: Replace defval value in Property with QLitObject
  qom: Fix documentation of UUID property type
  qom: Don't ignore defval on UUID property
  qom: Make object_property_set_default() public
  qom: Make PropertyInfo.set_default_value optional
  qom: Delete field_prop_set_default_value_*int()
  qom: Delete set_default_uuid()
  qom: Delete set_default_value_bool()

 include/hw/qdev-properties-system.h   |   4 +-
 include/qapi/qmp/qlit.h   |  11 ++-
 include/qapi/qmp/qnum.h   |  26 +-
 include/qom/field-property-internal.h |   7 +-
 include/qom/field-property.h  |  30 +++
 include/qom/object.h  |  11 +++
 include/qom/property-types.h  |  18 ++--
 hw/core/qdev-properties-system.c  |  13 +--
 qobject/qlit.c|   5 +-
 qobject/qnum.c| 113 ++
 qom/field-property.c  |  36 ++--
 qom/object.c  |   2 +-
 qom/property-types.c  |  37 ++---
 tests/check-qjson.c   |  30 +++
 tests/check-qlit.c|  72 +---
 tests/check-qnum.c|  14 ++--
 16 files changed, 253 insertions(+), 176 deletions(-)

-- 
2.28.0





Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-23 Thread Eduardo Habkost
On Mon, Nov 23, 2020 at 08:51:27AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Fri, Nov 20, 2020 at 06:29:16AM +0100, Markus Armbruster wrote:
> [...]
> >> When the structure of a data type is to be kept away from its users, I
> >> prefer to keep it out of the public header, so the compiler enforces the
> >> encapsulation.
> >
> > I prefer that too, except that it is impossible when users of the
> > API need the compiler to know the struct size.
> 
> There are cases where the structure of a data type should be
> encapsulated, yet its size must be made known for performance (avoid
> dynamic memory allocation and pointer chasing).
> 
> Need for encapsulation correlates with complex algorithms and data
> structures.  The cost of dynamic allocation is often in the noise then.

I don't know what we are talking about anymore.  None of this
applies to the QNum API, right?

QNum/QNumValue are not complex data structures, and the reason we
need the compiler to know the size of QNumValue is not related to
performance at all.

We might still want to discourage users of the QNum API from
accessing QNum.u/QNumValue.u directly.  Documenting the field as
private is a very easy way to do it.

-- 
Eduardo




Re: [RFC v3 9/9] i386: split cpu accelerators from cpu.c

2020-11-23 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 10:08:46AM +0100, Claudio Fontana wrote:
> On 11/19/20 8:23 PM, Eduardo Habkost wrote:
> > On Thu, Nov 19, 2020 at 09:53:09AM +0100, Claudio Fontana wrote:
> >> Hi,
> >>
> >> On 11/18/20 7:28 PM, Eduardo Habkost wrote:
> >>> On Wed, Nov 18, 2020 at 11:29:36AM +0100, Claudio Fontana wrote:
> >>>> split cpu.c into:
> >>>>
> >>>> cpu.ccpuid and common x86 cpu functionality
> >>>> host-cpu.c   host x86 cpu functions and "host" cpu type
> >>>> kvm/cpu.cKVM x86 cpu type
> >>>> hvf/cpu.cHVF x86 cpu type
> >>>> tcg/cpu.cTCG x86 cpu type
> >>>>
> >>>> The accel interface of the X86CPUClass is set at MODULE_INIT_ACCEL_CPU
> >>>> time, when the accelerator is known.
> >>>>
> >>>> Signed-off-by: Claudio Fontana 
> >>>> ---
> >>> [...]
> >>>> +/**
> >>>> + * X86CPUAccel:
> >>>> + * @name: string name of the X86 CPU Accelerator
> >>>> + *
> >>>> + * @common_class_init: initializer for the common cpu
> >>>
> >>> So this will be called for every single CPU class.
> >>
> >> Not really, it's called for every TYPE_X86_CPU cpu class (if an accel 
> >> interface is registered).
> > 
> > This means every single non-abstract CPU class in
> > qemu-system-x86_64, correct?
> > 
> >>
> >> This function extends the existing x86_cpu_common_class_init 
> >> (target/i386/cpu.c),
> >> where some methods of the base class CPUClass are set.
> >>
> >>>
> >>>> + * @instance_init: cpu instance initialization
> >>>> + * @realizefn: realize function, called first in x86 cpu realize
> >>>> + *
> >>>> + * X86 CPU accelerator-specific CPU initializations
> >>>> + */
> >>>> +
> >>>> +struct X86CPUAccel {
> >>>> +const char *name;
> >>>> +
> >>>> +void (*common_class_init)(X86CPUClass *xcc);
> >>>> +void (*instance_init)(X86CPU *cpu);
> >>>> +void (*realizefn)(X86CPU *cpu, Error **errp);
> >>>>  };
> >>>>  
> >>>> +void x86_cpu_accel_init(const X86CPUAccel *accel);
> >>> [...]
> >>>> +static void x86_cpu_accel_init_aux(ObjectClass *klass, void *opaque)
> >>>> +{
> >>>> +X86CPUClass *xcc = X86_CPU_CLASS(klass);
> >>>> +const X86CPUAccel **accel = opaque;
> >>>> +
> >>>> +xcc->accel = *accel;
> >>>> +xcc->accel->common_class_init(xcc);
> >>>> +}
> >>>> +
> >>>> +void x86_cpu_accel_init(const X86CPUAccel *accel)
> >>>> +{
> >>>> +object_class_foreach(x86_cpu_accel_init_aux, TYPE_X86_CPU, false, 
> >>>> &accel);
> >>>> +}
> >>>
> >>> This matches the documented behavior.
> >>>
> >>> [...]
> >>>> +void host_cpu_class_init(X86CPUClass *xcc)
> >>>> +{
> >>>> +xcc->host_cpuid_required = true;
> >>>> +xcc->ordering = 8;
> >>>> +xcc->model_description =
> >>>> +g_strdup_printf("%s processor with all supported host features 
> >>>> ",
> >>>> +xcc->accel->name);
> >>>> +}
> >>> [...]
> >>>> +static void hvf_cpu_common_class_init(X86CPUClass *xcc)
> >>>> +{
> >>>> +host_cpu_class_init(xcc);
> >>>
> >>> Why are you calling host_cpu_class_init() for all CPU types?
> >>
> >> I am not..
> > 
> > I don't get it.  You are calling host_cpu_class_init() for every
> > single non-abstract TYPE_X86_CPU subclass (which includes all CPU
> > models in qemu-system-x86_64), and I don't understand why, or if
> > this is really intentional.
> 
> It is really intentional what is done here,
> 
> when HVF accelerator is enabled, and only when the HVF accelerator is enabled,
> 
> all X86 CPU classes and subclasses (cpu models, which have been
> implemented as subclasses of TYPE_X86_CPU), are updated with a
> link to the accelerator-specific HVF interface.

I'm confused.  That (updating the class with a link) is not what
host_cpu_class_init() does.

This is what host_cpu_class_init() does:

void host_cpu_class_init(X86CPUClass *xcc)
{
xcc->host_cpuid_required = true;
xcc->ordering = 8;
xcc->model_description =
g_strdup_printf("%s processor with all supported host features ",
xcc->accel->name);
}

Why do you want to call host_cpu_class_init() for every non-abstract
TYPE_X86_CPU subclass?

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-23 Thread Eduardo Habkost
On Mon, Nov 23, 2020 at 04:02:24PM +0100, Claudio Fontana wrote:
> On 11/23/20 2:18 PM, Paolo Bonzini wrote:
> > On 23/11/20 10:55, Claudio Fontana wrote:
> >> One idea that came to mind is, why not extend accel.h to user mode?
> >>
> >> It already contains
> >>
> >> #ifndef CONFIG_USER_ONLY
> >>
> >> parts, so maybe it was meant to be used by both, and just happened to
> >> end up confined to include/softmmu ?
> >>
> >> Basically I was thinking, we could have an AccelState and an
> >> AccelClass for user mode as well (without bringing in the whole
> >> machine thing), and from there we could use current_accel() to build
> >> up the right name for the chosen accelerator?
> > 
> > Yes, extending the accelerator class to usermode emulation is certainly 
> > a good idea.
> > 
> > Paolo
> > 
> 
> Thanks, I'll work on this option.
> 
> Btw considering that CpusAccel for tcg is actually three different interfaces 
> (for mttcg, for icount, and plain RR),
> it will be tough to, in the stated objective, "remove all conditionals", even 
> after removing the tcg_enabled().

The main issue were the conditionals inside module init function.
They are completely OK inside accel-specific methods.

> 
> I wonder how you see this issue (patches for 3 TCG split are in Richard's 
> queue atm).
> 
> static void tcg_accel_cpu_init(void)
> {
> if (tcg_enabled()) {
> TCGState *s = TCG_STATE(current_accel());
> 
> if (s->mttcg_enabled) {
> cpus_register_accel(&tcg_cpus_mttcg);
> } else if (icount_enabled()) {
> cpus_register_accel(&tcg_cpus_icount);
> } else {
> cpus_register_accel(&tcg_cpus_rr);
> }
> }
> }

Probably what we are missing here is a non-softmmu-specific
AccelClass.init() method?

-- 
Eduardo




Re: [RFC v4 9/9] i386: split cpu accelerators from cpu.c

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 07:47:11PM +0100, Claudio Fontana wrote:
> On 11/20/20 6:44 PM, Eduardo Habkost wrote:
> > On Fri, Nov 20, 2020 at 03:49:09PM +0100, Claudio Fontana wrote:
> >> split cpu.c into:
> >>
> >> cpu.ccpuid and common x86 cpu functionality
> >> host-cpu.c   host x86 cpu functions and "host" cpu type
> >> kvm/cpu.cKVM x86 cpu type
> >> hvf/cpu.cHVF x86 cpu type
> >> tcg/cpu.cTCG x86 cpu type
> >>
> >> The link to the accel class is set in the X86CPUClass classes
> >> at MODULE_INIT_ACCEL_CPU time, when the accelerator is known.
> >>
> >> Signed-off-by: Claudio Fontana 
> > [...]
> >> +static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data)
> >> +{
> >> +X86CPUAccelClass *acc = X86_CPU_ACCEL_CLASS(oc);
> >> +
> >> +acc->cpu_realizefn = host_cpu_realizefn;
> >> +acc->cpu_common_class_init = hvf_cpu_common_class_init;
> >> +acc->cpu_instance_init = hvf_cpu_instance_init;
> >> +};
> >> +static const TypeInfo hvf_cpu_accel_type_info = {
> >> +.name = X86_CPU_ACCEL_TYPE_NAME("hvf"),
> >> +
> >> +.parent = TYPE_X86_CPU_ACCEL,
> >> +.class_init = hvf_cpu_accel_class_init,
> >> +};
> >> +static void hvf_cpu_accel_register_types(void)
> >> +{
> >> +type_register_static(&hvf_cpu_accel_type_info);
> >> +}
> >> +type_init(hvf_cpu_accel_register_types);
> >> +
> >> +static void hvf_cpu_accel_init(void)
> >> +{
> >> +if (hvf_enabled()) {
> >> +x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME("hvf"));
> >> +}
> >> +}
> >> +
> >> +accel_cpu_init(hvf_cpu_accel_init);
> > 
> > The point of my suggestion of using QOM is to not require
> > separate accel_cpu_init() functions and (hvf|tcg|kvm)_enabled()
> > checks.
> > 
> > If we still have separate accel_cpu_init() functions for calling
> > x86_cpu_accel_init() with the right argument, using a pointer to
> > static variables like &hvf_cpu_accel (like you did before) was
> > simpler and required less boilerplate code.
> 
> 
> 
> Yes I agree.
> 
> 
> 
> 
> > 
> > However, the difference is that with the X86_CPU_ACCEL_TYPE_NAME
> > macro + object_class_by_name(), you don't need the separate
> > accel_cpu_init() functions for each accelerator.
> > 
> > All you need is a single:
> > 
> >   x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME(chosen_accel_name));
> > 
> > call somewhere in the initialization path.
> 
> 
> Makes sense. The problem is just determining chosen_accel_name.

Yeah, that was a challenge.  do_configure_accelerator() knows
what's the chosen accel name, though.

We can also do it inside accel_init_machine(), if we can
determine the correct accel name from the AccelState object.

> 
> 
> > 
> > A good place for the x86_cpu_accel_init() call would be
> > do_configure_accelerator(), but the function is arch-specific.
> > That's why I suggested a cpu_accel_arch_init() function at
> > https://lore.kernel.org/qemu-devel/20201118220750.gp1509...@habkost.net
> > 
> 
> 
> Fine by me. I'd use a specific init step for this, but that also works.

A separate module init function has no easy access to the accel
name, but in this case I'd say it's on purpose: the intended use
case for module init functions is to unconditionally register
features provided by a code module.  They shouldn't look at any
runtime configuration or runtime state.

-- 
Eduardo




Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 06:29:16AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Thu, Nov 19, 2020 at 11:24:52AM +0100, Markus Armbruster wrote:
> >> Marc-André Lureau  writes:
> >> 
> >> > On Tue, Nov 17, 2020 at 6:42 PM Eduardo Habkost  
> >> > wrote:
> >> >
> >> >> On Tue, Nov 17, 2020 at 12:37:56PM +0400, Marc-André Lureau wrote:
> >> >> > On Tue, Nov 17, 2020 at 2:43 AM Eduardo Habkost 
> >> >> wrote:
> >> >> >
> >> >> > > Provide a separate QNumValue type that can be used for QNum value
> >> >> > > literals without the referencing counting and memory allocation
> >> >> > > features provided by QObject.
> >> >> > >
> >> >> > > Signed-off-by: Eduardo Habkost 
> >> >> > > ---
> >> >> > > Changes v1 -> v2:
> >> >> > > * Fix "make check" failure, by updating check-qnum unit test to
> >> >> > >   use the new struct fields
> >> >> > > ---
> >> >> > >  include/qapi/qmp/qnum.h | 40 +++--
> >> >> > >  qobject/qnum.c  | 78 
> >> >> > > -
> >> >> > >  tests/check-qnum.c  | 14 
> >> >> > >  3 files changed, 84 insertions(+), 48 deletions(-)
> >> >> > >
> >> >> > > diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
> >> >> > > index 55c27b1c24..62fbdfda68 100644
> >> >> > > --- a/include/qapi/qmp/qnum.h
> >> >> > > +++ b/include/qapi/qmp/qnum.h
> >> >> > > @@ -46,20 +46,56 @@ typedef enum {
> >> >> > >   * in range: qnum_get_try_int() / qnum_get_try_uint() check range 
> >> >> > > and
> >> >> > >   * convert under the hood.
> >> >> > >   */
> >> >> > > -struct QNum {
> >> >> > > -struct QObjectBase_ base;
> >> >> > > +
> >> >> > > +/**
> >> >> > > + * struct QNumValue: the value of a QNum
> >> >> > > + *
> >> >> > > + * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
> >> >> > > + * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
> >> >> > > + */
> >> >> > > +typedef struct QNumValue {
> >> >> > > +/* private: */
> >> 
> >> Do we care?
> >
> > Are you asking if we want to make them private, or if we want to
> > document them as private (assuming they are).
> >
> > The answer to the latter is yes ("private:" is an indication to
> > kernel-doc).  The answer to the former seems to be "no", based on
> > your other comments.
> >
> > Or maybe `kind` should be public and `u` should be private?
> 
> You're factoring out a part of struct QNum into new struct QNumValue.
> struct QNum is not private before the patch.  I see no need to start
> making it or parts of it private now.

I don't want to change the rules, just to document the existing
implicit rules.  If you say QNum.u was never private, I won't
argue.

> 
> When the structure of a data type is to be kept away from its users, I
> prefer to keep it out of the public header, so the compiler enforces the
> encapsulation.

I prefer that too, except that it is impossible when users of the
API need the compiler to know the struct size.

-- 
Eduardo




Re: [PATCH v2 4/8] qnum: qnum_value_is_equal() function

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 07:52:31AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > On Thu, Nov 19, 2020 at 11:27:40AM +0100, Markus Armbruster wrote:
> > [...]
> >> > +bool qnum_is_equal(const QObject *x, const QObject *y)
> >> > +{
> >> > +const QNum *qnum_x = qobject_to(QNum, x);
> >> > +const QNum *qnum_y = qobject_to(QNum, y);
> >> 
> >> Humor me: blank line between declarations and statements, please.
> >
> > I can do it.  But why do you prefer it that way?
> 
> Habit borne out of C lacking other visual cues to distinguish
> declarations and statements.

Why is the distinction important, when many variable declarations
also include initializer expressions that can be as complex as
other statements?

(The qobject_to() calls above are an example).

> 
> Declaration or statement?  Tell me quick, don't analyze!
> 
> mumble(*mutter)();
> 
> This "obviously" declares @mutter as pointer to function returning
> mumble.
> 
> Except when @mumble isn't a typedef name, but a function taking one
> argument and returning a function that takes no argument.  Then it
> passes *mutter to mumble(), and calls its return value.
> 
> The whole point of coding style is to help readers along.  Two stylistic
> conventions that can help here:
> 
> 1. In a function call, no space between the expression denoting the
>called function and the (parenthesized) argument list.  Elsewhere,
>space.
> 
>So, when the example above is indeed a declaration, write it as
> 
> mumble (*mutter)();
> 
>If it's function calls, write it as
> 
> mumble(*mutter)();

This makes lots of sense.  Starting with a word followed by space
is what makes declarations visually distinguishable.

> 
> 2. Separate declarations from statements with a blank line.  Do not mix
>them.

I'm not sure about this one, and I'm actually glad it is not part
of CODING_STYLE.  :)

(I'll still follow your advice as maintainer of that piece of
code, of course)

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 06:41:35PM +0100, Claudio Fontana wrote:
> On 11/20/20 6:19 PM, Eduardo Habkost wrote:
> > On Fri, Nov 20, 2020 at 01:13:33PM +0100, Claudio Fontana wrote:
> >> On 11/18/20 11:07 PM, Eduardo Habkost wrote:
> >>> On Wed, Nov 18, 2020 at 08:13:18PM +0100, Paolo Bonzini wrote:
> >>>> On 18/11/20 18:30, Eduardo Habkost wrote:
> >>>>>> Adding a layer of indirect calls is not very different from monkey 
> >>>>>> patching
> >>>>>> though.
> >>>>>
> >>>>> I'm a little bothered by monkey patching, but I'm more
> >>>>> bothered by having to:
> >>>>>
> >>>>> (1) register (module_init()) a function (kvm_cpu_accel_register()) that
> >>>>>(2) register (accel_register_call()) a function 
> >>>>> (kvm_cpu_accel_init()) that
> >>>>>  (3) register (x86_cpu_accel_init()) a data structure (X86CPUAccel 
> >>>>> kvm_cpu_accel) that
> >>>>>(4) will be saved in multiple QOM classes, so that
> >>>>>  (5) we will call the right X86CPUClass.accel method at the 
> >>>>> right moment
> >>>>>  (common_class_init(), instance_init(), realizefn()),
> >>>>> where:
> >>>>>step 4 must be done before any CPU object is created
> >>>>>  (otherwise X86CPUAccel.instance_init & X86CPUAccel.realizefn
> >>>>>   will be silently ignored), and
> >>>>>step 3 must be done after all QOM types were registered.
> >>>>>
> >>>>>> You also have to consider that accel currently does not exist in 
> >>>>>> usermode
> >>>>>> emulators, so that's an issue too. I would rather get a simple change 
> >>>>>> in
> >>>>>> quickly, instead of designing the perfect class hierarchy.
> >>>>>
> >>>>> It doesn't have to be perfect.  I agree that simple is better.
> >>>>>
> >>>>> To me, registering a QOM type and looking it up when necessary is
> >>>>> simpler than the above.  Even if it's a weird class having no
> >>>>> object instances.  It probably could be an interface type.
> >>>>
> >>>> Registering a QOM type still has quite some boilerplate.  [...]
> >>>
> >>> We're working on that.  :)
> >>>
> >>>>[...]  Also 
> >>>> registering a
> >>>> QOM type has a public side effect (shows up in qom-list-types).  In 
> >>>> general
> >>>> I don't look at QOM unless I want its property mechanism, but maybe 
> >>>> that's
> >>>> just me.
> >>>
> >>> We have lots of internal-use-only types returned by
> >>> qom-list-types, I don't think it's a big deal.
> >>>
> >>>>
> >>>>>> Perhaps another idea would be to allow adding interfaces to classes
> >>>>>> *separately from the registration of the types*. Then we can use it to 
> >>>>>> add
> >>>>>> SOFTMMU_ACCEL and I386_ACCEL interfaces to a bare bones accel class, 
> >>>>>> and
> >>>>>> add the accel object to usermode emulators.
> >>>>>
> >>>>> I'm not sure I follow.  What do you mean by bare bones accel
> >>>>> class, and when exactly would you add the new interfaces to the
> >>>>> classes?
> >>>>
> >>>> A bare bones accel class would not have init_machine and setup_post 
> >>>> methods;
> >>>> those would be in a TYPE_SOFTMMU_ACCEL interface.  It would still have
> >>>> properties (such as tb-size for TCG) and would be able to register compat
> >>>> properties.
> > 
> > [1]
> > 
> >>>
> >>> Oh, I think I see.  This could save us having a lot of parallel type
> >>> hierarchies.
> >>>
> >>>>
> >>>> Where would I add it, I don't know.  It could be a simple public wrapper
> >>>> around type_initialize_interface() if we add a new MODULE_INIT_* phase 
> >>>> after
> >>>> QOM.
> >>>>
> >>>> Or without adding

Re: [RFC v4 9/9] i386: split cpu accelerators from cpu.c

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 03:49:09PM +0100, Claudio Fontana wrote:
> split cpu.c into:
> 
> cpu.ccpuid and common x86 cpu functionality
> host-cpu.c   host x86 cpu functions and "host" cpu type
> kvm/cpu.cKVM x86 cpu type
> hvf/cpu.cHVF x86 cpu type
> tcg/cpu.cTCG x86 cpu type
> 
> The link to the accel class is set in the X86CPUClass classes
> at MODULE_INIT_ACCEL_CPU time, when the accelerator is known.
> 
> Signed-off-by: Claudio Fontana 
[...]
> +static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data)
> +{
> +X86CPUAccelClass *acc = X86_CPU_ACCEL_CLASS(oc);
> +
> +acc->cpu_realizefn = host_cpu_realizefn;
> +acc->cpu_common_class_init = hvf_cpu_common_class_init;
> +acc->cpu_instance_init = hvf_cpu_instance_init;
> +};
> +static const TypeInfo hvf_cpu_accel_type_info = {
> +.name = X86_CPU_ACCEL_TYPE_NAME("hvf"),
> +
> +.parent = TYPE_X86_CPU_ACCEL,
> +.class_init = hvf_cpu_accel_class_init,
> +};
> +static void hvf_cpu_accel_register_types(void)
> +{
> +type_register_static(&hvf_cpu_accel_type_info);
> +}
> +type_init(hvf_cpu_accel_register_types);
> +
> +static void hvf_cpu_accel_init(void)
> +{
> +if (hvf_enabled()) {
> +x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME("hvf"));
> +}
> +}
> +
> +accel_cpu_init(hvf_cpu_accel_init);

The point of my suggestion of using QOM is to not require
separate accel_cpu_init() functions and (hvf|tcg|kvm)_enabled()
checks.

If we still have separate accel_cpu_init() functions for calling
x86_cpu_accel_init() with the right argument, using a pointer to
static variables like &hvf_cpu_accel (like you did before) was
simpler and required less boilerplate code.

However, the difference is that with the X86_CPU_ACCEL_TYPE_NAME
macro + object_class_by_name(), you don't need the separate
accel_cpu_init() functions for each accelerator.

All you need is a single:

  x86_cpu_accel_init(X86_CPU_ACCEL_TYPE_NAME(chosen_accel_name));

call somewhere in the initialization path.

A good place for the x86_cpu_accel_init() call would be
do_configure_accelerator(), but the function is arch-specific.
That's why I suggested a cpu_accel_arch_init() function at
https://lore.kernel.org/qemu-devel/20201118220750.gp1509...@habkost.net

-- 
Eduardo




Re: [RFC v4 9/9] i386: split cpu accelerators from cpu.c

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 04:34:47PM +0100, Claudio Fontana wrote:
> On 11/20/20 3:49 PM, Claudio Fontana wrote:
> > split cpu.c into:
> > 
> > cpu.ccpuid and common x86 cpu functionality
> > host-cpu.c   host x86 cpu functions and "host" cpu type
> > kvm/cpu.cKVM x86 cpu type
> > hvf/cpu.cHVF x86 cpu type
> > tcg/cpu.cTCG x86 cpu type
> > 
> > The link to the accel class is set in the X86CPUClass classes
> > at MODULE_INIT_ACCEL_CPU time, when the accelerator is known.
> > 
> > Signed-off-by: Claudio Fontana 
> > ---
[...]
> > +#define TYPE_X86_CPU_ACCEL TYPE_X86_CPU "-accel"
> > +#define X86_CPU_ACCEL_TYPE_NAME(name) (name "-" TYPE_X86_CPU_ACCEL)
> > +
> > +OBJECT_DECLARE_TYPE(X86CPUAccel, X86CPUAccelClass,
> > +X86_CPU_ACCEL)
> 
> 
> Instead of OBJECT_DECLARE_TYPE, since this is never instantiated, this should 
> probably be:
> 
> +typedef struct X86CPUAccelClass X86CPUAccelClass;
> +DECLARE_CLASS_CHECKERS(X86CPUAccelClass, X86_CPU_ACCEL, TYPE_X86_CPU_ACCEL)

Yes, and this way we get rid of the only difference between
OBJECT_DECLARE_TYPE and OBJECT_DECLARE_INTERFACE: the instance
type cast macro is a bit different (it uses INTERFACE_CHECK).

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-20 Thread Eduardo Habkost
On Fri, Nov 20, 2020 at 01:13:33PM +0100, Claudio Fontana wrote:
> On 11/18/20 11:07 PM, Eduardo Habkost wrote:
> > On Wed, Nov 18, 2020 at 08:13:18PM +0100, Paolo Bonzini wrote:
> >> On 18/11/20 18:30, Eduardo Habkost wrote:
> >>>> Adding a layer of indirect calls is not very different from monkey 
> >>>> patching
> >>>> though.
> >>>
> >>> I'm a little bothered by monkey patching, but I'm more
> >>> bothered by having to:
> >>>
> >>> (1) register (module_init()) a function (kvm_cpu_accel_register()) that
> >>>(2) register (accel_register_call()) a function (kvm_cpu_accel_init()) 
> >>> that
> >>>  (3) register (x86_cpu_accel_init()) a data structure (X86CPUAccel 
> >>> kvm_cpu_accel) that
> >>>(4) will be saved in multiple QOM classes, so that
> >>>  (5) we will call the right X86CPUClass.accel method at the right 
> >>> moment
> >>>  (common_class_init(), instance_init(), realizefn()),
> >>> where:
> >>>step 4 must be done before any CPU object is created
> >>>  (otherwise X86CPUAccel.instance_init & X86CPUAccel.realizefn
> >>>   will be silently ignored), and
> >>>step 3 must be done after all QOM types were registered.
> >>>
> >>>> You also have to consider that accel currently does not exist in usermode
> >>>> emulators, so that's an issue too. I would rather get a simple change in
> >>>> quickly, instead of designing the perfect class hierarchy.
> >>>
> >>> It doesn't have to be perfect.  I agree that simple is better.
> >>>
> >>> To me, registering a QOM type and looking it up when necessary is
> >>> simpler than the above.  Even if it's a weird class having no
> >>> object instances.  It probably could be an interface type.
> >>
> >> Registering a QOM type still has quite some boilerplate.  [...]
> > 
> > We're working on that.  :)
> > 
> >>[...]  Also registering 
> >> a
> >> QOM type has a public side effect (shows up in qom-list-types).  In general
> >> I don't look at QOM unless I want its property mechanism, but maybe that's
> >> just me.
> > 
> > We have lots of internal-use-only types returned by
> > qom-list-types, I don't think it's a big deal.
> > 
> >>
> >>>> Perhaps another idea would be to allow adding interfaces to classes
> >>>> *separately from the registration of the types*. Then we can use it to 
> >>>> add
> >>>> SOFTMMU_ACCEL and I386_ACCEL interfaces to a bare bones accel class, and
> >>>> add the accel object to usermode emulators.
> >>>
> >>> I'm not sure I follow.  What do you mean by bare bones accel
> >>> class, and when exactly would you add the new interfaces to the
> >>> classes?
> >>
> >> A bare bones accel class would not have init_machine and setup_post 
> >> methods;
> >> those would be in a TYPE_SOFTMMU_ACCEL interface.  It would still have
> >> properties (such as tb-size for TCG) and would be able to register compat
> >> properties.

[1]

> > 
> > Oh, I think I see.  This could save us having a lot of parallel type
> > hierarchies.
> > 
> >>
> >> Where would I add it, I don't know.  It could be a simple public wrapper
> >> around type_initialize_interface() if we add a new MODULE_INIT_* phase 
> >> after
> >> QOM.
> >>
> >> Or without adding a new phase, it could be a class_type->array of
> >> (interface_type, init_fn) hash table.  type_initialize would look up the
> >> class_type by name, add the interfaces would to the class with
> >> type_initialize_interface, and then call the init_fn to fill in the vtable.
> > 
> > That sounds nice.  I don't think Claudio's cleanup should be
> > blocked until this new mechanism is ready, though.
> > 
> > We don't really need the type representing X86CPUAccel to be a
> > subtype of TYPE_ACCEL or an interface implemented by
> > current_machine->accelerator, in the first version.  We just need
> > a simple way for the CPU initialization code to find the correct
> > X86CPUAccel struct.
> > 
> > While we don't have the new mechanism, it can be just a:
> &

Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 01:21:58PM -0500, Eduardo Habkost wrote:
> On Thu, Nov 19, 2020 at 11:24:52AM +0100, Markus Armbruster wrote:
[...]
> > >> > > +return qnum_from_value((QNumValue) QNUM_VAL_INT(value));
> > 
> > No space between between (type) and its operand, please.
> > 
> > Could we lift the cast into the macro somehow?
> 
> I think we can.  I had thought the cast in the macro would break
> usage as static variable initializers.  I was wrong.

Actually, including the cast in the macro breaks QLIT_QDICT
initializers (which use (QLitDictEntry[]) compound literals), and
I don't know why.

Compound literals in initializers of static variables is a GCC
extension.  I don't understand why it doesn't work inside array
compound literals, though.

Any language lawyers around?

This works:

  typedef struct QLit {
  int x, y;
  } QLit;
  
  typedef struct Entry {
  int key;
  QLit value;
  } Entry;
  
  Entry e = { .key = 0, .value = (QLit) { 1,   2 } };

This works:

  Entry *es1 = (Entry[]) {
  { .key = 0, .value = { 1,   2 } },
  };

But this doesn't:

  Entry *es2 = (Entry[]) {
  { .key = 0, .value = (QLit) { 1,   2 } },
  };

dict.c:16:24: error: initializer element is not constant
   16 | Entry *es2 = (Entry[]) {
  |^
dict.c:16:24: note: (near initialization for ‘es2’)

(gcc (GCC) 10.2.1 20201005 (Red Hat 10.2.1-5))

-- 
Eduardo




Re: [RFC v3 9/9] i386: split cpu accelerators from cpu.c

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 09:53:09AM +0100, Claudio Fontana wrote:
> Hi,
> 
> On 11/18/20 7:28 PM, Eduardo Habkost wrote:
> > On Wed, Nov 18, 2020 at 11:29:36AM +0100, Claudio Fontana wrote:
> >> split cpu.c into:
> >>
> >> cpu.ccpuid and common x86 cpu functionality
> >> host-cpu.c   host x86 cpu functions and "host" cpu type
> >> kvm/cpu.cKVM x86 cpu type
> >> hvf/cpu.cHVF x86 cpu type
> >> tcg/cpu.cTCG x86 cpu type
> >>
> >> The accel interface of the X86CPUClass is set at MODULE_INIT_ACCEL_CPU
> >> time, when the accelerator is known.
> >>
> >> Signed-off-by: Claudio Fontana 
> >> ---
> > [...]
> >> +/**
> >> + * X86CPUAccel:
> >> + * @name: string name of the X86 CPU Accelerator
> >> + *
> >> + * @common_class_init: initializer for the common cpu
> > 
> > So this will be called for every single CPU class.
> 
> Not really, it's called for every TYPE_X86_CPU cpu class (if an accel 
> interface is registered).

This means every single non-abstract CPU class in
qemu-system-x86_64, correct?

> 
> This function extends the existing x86_cpu_common_class_init 
> (target/i386/cpu.c),
> where some methods of the base class CPUClass are set.
> 
> > 
> >> + * @instance_init: cpu instance initialization
> >> + * @realizefn: realize function, called first in x86 cpu realize
> >> + *
> >> + * X86 CPU accelerator-specific CPU initializations
> >> + */
> >> +
> >> +struct X86CPUAccel {
> >> +const char *name;
> >> +
> >> +void (*common_class_init)(X86CPUClass *xcc);
> >> +void (*instance_init)(X86CPU *cpu);
> >> +void (*realizefn)(X86CPU *cpu, Error **errp);
> >>  };
> >>  
> >> +void x86_cpu_accel_init(const X86CPUAccel *accel);
> > [...]
> >> +static void x86_cpu_accel_init_aux(ObjectClass *klass, void *opaque)
> >> +{
> >> +X86CPUClass *xcc = X86_CPU_CLASS(klass);
> >> +const X86CPUAccel **accel = opaque;
> >> +
> >> +xcc->accel = *accel;
> >> +xcc->accel->common_class_init(xcc);
> >> +}
> >> +
> >> +void x86_cpu_accel_init(const X86CPUAccel *accel)
> >> +{
> >> +object_class_foreach(x86_cpu_accel_init_aux, TYPE_X86_CPU, false, 
> >> &accel);
> >> +}
> > 
> > This matches the documented behavior.
> > 
> > [...]
> >> +void host_cpu_class_init(X86CPUClass *xcc)
> >> +{
> >> +xcc->host_cpuid_required = true;
> >> +xcc->ordering = 8;
> >> +xcc->model_description =
> >> +g_strdup_printf("%s processor with all supported host features ",
> >> +xcc->accel->name);
> >> +}
> > [...]
> >> +static void hvf_cpu_common_class_init(X86CPUClass *xcc)
> >> +{
> >> +host_cpu_class_init(xcc);
> > 
> > Why are you calling host_cpu_class_init() for all CPU types?
> 
> I am not..

I don't get it.  You are calling host_cpu_class_init() for every
single non-abstract TYPE_X86_CPU subclass (which includes all CPU
models in qemu-system-x86_64), and I don't understand why, or if
this is really intentional.

> 
> > 
> >> +}
> > [...]
> >> +static void kvm_cpu_common_class_init(X86CPUClass *xcc)
> >> +{
> >> +host_cpu_class_init(xcc);
> >> +}
> > 
> > Same question as above.
> > 
> 
> Ciao,
> 
> Claudio
> 

-- 
Eduardo




Re: [PATCH v2 0/8] qom: Use qlit to represent property defaults

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 07:25:15PM +0100, Paolo Bonzini wrote:
> On 19/11/20 18:55, Eduardo Habkost wrote:
> > On Thu, Nov 19, 2020 at 06:23:30PM +0100, Paolo Bonzini wrote:
> > > On 19/11/20 18:13, Eduardo Habkost wrote:
> > > > > What's left?
> > > > Enums.  Enums properties are a mess to implement, and I plan to
> > > > tackle them later.
> > > > 
> > > > On all other cases, the external representation of the property
> > > > value is similar to the internal representation.  In the case of
> > > > enums, the external representation is a string, but the internal
> > > > representation is an integer.
> > > > 
> > > 
> > > I would have expected a string QLit to work with enums, is there a reason
> > > why it doesn't?
> > 
> > It would work, but it would be more inconvenient for callers.
> > Right now they use the C enum constant instead of a string.
> 
> It matches what you have to do already for compat props, so it's not a big
> deal.  I would say just use strings.

No problem to me.  I'll do.

-- 
Eduardo




Re: [PATCH v2 5/8] qlit: Support all types of QNums

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 11:39:14AM +0100, Markus Armbruster wrote:
> Marc-André Lureau  writes:
> 
> > On Tue, Nov 17, 2020 at 2:48 AM Eduardo Habkost  wrote:
> >
> >> Use QNumValue to represent QNums, so we can also support uint64_t
> >> and double QNum values.  Add new QLIT_QNUM_(INT|UINT|DOUBLE)
> >> macros for each case.
> >>
> >> The QLIT_QNUM() macro is being kept for compatibility with
> >> existing code, but becomes just a wrapper for QLIT_QNUM_INT().
> >>
> >
> > I am not sure it's worth to keep. (furthermore, it's only used in tests
> > afaics)
> 
> Seconded.

Understood, I will remove it.  I thought the QAPI code generator
was using it.

[...]
> >> diff --git a/qobject/qlit.c b/qobject/qlit.c
> >> index be8332136c..b23cdc4532 100644
> >> --- a/qobject/qlit.c
> >> +++ b/qobject/qlit.c
> >> @@ -71,7 +71,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const
> >> QObject *rhs)
> >>  case QTYPE_QBOOL:
> >>  return lhs->value.qbool == qbool_get_bool(qobject_to(QBool, rhs));
> >>  case QTYPE_QNUM:
> >> -return lhs->value.qnum ==  qnum_get_int(qobject_to(QNum, rhs));
> >> +return qnum_value_is_equal(&lhs->value.qnum,
> >> +   qnum_get_value(qobject_to(QNum, rhs)));
> 
> Before the patch, we crash when @rhs can't be represented as int64_t.

I thought it was expected behavior?  QLit never supported
QNUM_U64 or QNUM_DOUBLE as input.

> 
> Afterwards, we return false (I think).
> 
> Please note this in the commit message.  A separate fix preceding this
> patch would be even better, but may not be worth the trouble.  Up to
> you.

The fix would be 3 or 4 extra lines of code that would be
immediately deleted.  I'll just mention it as a side effect of
the new feature.

> 
> >>  case QTYPE_QSTRING:
> >>  return (strcmp(lhs->value.qstr,
> >> qstring_get_str(qobject_to(QString, rhs))) == 0);
> >> @@ -94,7 +95,7 @@ QObject *qobject_from_qlit(const QLitObject *qlit)
> >>  case QTYPE_QNULL:
> >>  return QOBJECT(qnull());
> >>  case QTYPE_QNUM:
> >> -return QOBJECT(qnum_from_int(qlit->value.qnum));
> >> +return QOBJECT(qnum_from_value(qlit->value.qnum));
> >>  case QTYPE_QSTRING:
> >>  return QOBJECT(qstring_from_str(qlit->value.qstr));
> >>  case QTYPE_QDICT: {
> >> diff --git a/tests/check-qjson.c b/tests/check-qjson.c
> >> index 07a773e653..711030cffd 100644
> >> --- a/tests/check-qjson.c
> >> +++ b/tests/check-qjson.c
> >> @@ -796,20 +796,23 @@ static void simple_number(void)
> >>  int i;
> >>  struct {
> >>  const char *encoded;
> >> +QLitObject qlit;
> >>  int64_t decoded;
> >>  int skip;
> >>  } test_cases[] = {
> >> -{ "0", 0 },
> >> -{ "1234", 1234 },
> >> -{ "1", 1 },
> >> -{ "-32", -32 },
> >> -{ "-0", 0, .skip = 1 },
> >> +{ "0",QLIT_QNUM(0),0, },
> >> +{ "1234", QLIT_QNUM(1234), 1234, },
> >> +{ "1",QLIT_QNUM(1),1, },
> >> +{ "-32",  QLIT_QNUM(-32),  -32, },
> >> +{ "-0",   QLIT_QNUM(0),0, .skip = 1 },
> 
> Note .qlit is always QLIT_QNUM(.decoded).  Would doing without .qlit
> result in a simpler patch?

Good point.  When I wrote this, I mistakenly thought we would end
up having different types of qlits in the array.

I still want to test multiple types of QNums here, not just
QNUM_I64.  I will try to get something that is simple but also
gets us more coverage.  Maybe as a separate test function and/or
a separate patch.

> 
> >>  { },
> >>  };
> >>
> >>  for (i = 0; test_cases[i].encoded; i++) {
> >>  QNum *qnum;
> >>  int64_t val;
> >> +QNum *qlit_num;
> >> +int64_t qlit_val;
> >>
> >>  qnum = qobject_to(QNum,
> >>qobject_from_json(test_cases[i].encoded,
> >> @@ -817,6 +820,7 @@ static void simple_number(void)
> >>  g_assert(qnum);
> >>  g_assert(qnum_get_try_int(qnum, &val));
> >>  g_assert_cmpint(val, ==, test_cases[i].decoded);
> >> +
> >>  if (test_cases[i].skip == 0) {
> >>  QString *str;
> >>
> >> @@ -826,9 +830,66 @@ static void simple_number(void)
> >>  }
> >>
> >>  qobject_unref(qnum);
> >> +
> >> +qlit_num = qobject_to(QNum,
> >> +  qobject_from_qlit(&test_cases[i].qlit));
> >> +g_assert(qlit_num);
> >> +g_assert(qnum_get_try_int(qlit_num, &qlit_val));
> >> +g_assert_cmpint(qlit_val, ==, test_cases[i].decoded);
> >> +
> >> +qobject_unref(qlit_num);
> >>  }
> >>  }
> >>
[...]

-- 
Eduardo




Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 11:24:52AM +0100, Markus Armbruster wrote:
> Marc-André Lureau  writes:
> 
> > On Tue, Nov 17, 2020 at 6:42 PM Eduardo Habkost  wrote:
> >
> >> On Tue, Nov 17, 2020 at 12:37:56PM +0400, Marc-André Lureau wrote:
> >> > On Tue, Nov 17, 2020 at 2:43 AM Eduardo Habkost 
> >> wrote:
> >> >
> >> > > Provide a separate QNumValue type that can be used for QNum value
> >> > > literals without the referencing counting and memory allocation
> >> > > features provided by QObject.
> >> > >
> >> > > Signed-off-by: Eduardo Habkost 
> >> > > ---
> >> > > Changes v1 -> v2:
> >> > > * Fix "make check" failure, by updating check-qnum unit test to
> >> > >   use the new struct fields
> >> > > ---
> >> > >  include/qapi/qmp/qnum.h | 40 +++--
> >> > >  qobject/qnum.c  | 78 -
> >> > >  tests/check-qnum.c  | 14 
> >> > >  3 files changed, 84 insertions(+), 48 deletions(-)
> >> > >
> >> > > diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
> >> > > index 55c27b1c24..62fbdfda68 100644
> >> > > --- a/include/qapi/qmp/qnum.h
> >> > > +++ b/include/qapi/qmp/qnum.h
> >> > > @@ -46,20 +46,56 @@ typedef enum {
> >> > >   * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
> >> > >   * convert under the hood.
> >> > >   */
> >> > > -struct QNum {
> >> > > -struct QObjectBase_ base;
> >> > > +
> >> > > +/**
> >> > > + * struct QNumValue: the value of a QNum
> >> > > + *
> >> > > + * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
> >> > > + * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
> >> > > + */
> >> > > +typedef struct QNumValue {
> >> > > +/* private: */
> 
> Do we care?

Are you asking if we want to make them private, or if we want to
document them as private (assuming they are).

The answer to the latter is yes ("private:" is an indication to
kernel-doc).  The answer to the former seems to be "no", based on
your other comments.

Or maybe `kind` should be public and `u` should be private?

> 
> >> > >  QNumKind kind;
> >> > >  union {
> >> > >  int64_t i64;
> >> > >  uint64_t u64;
> >> > >  double dbl;
> >> > >  } u;
> >> > > +} QNumValue;
> >> > > +
> >> > > +#define QNUM_VAL_INT(value) \
> >> > > +{ .kind = QNUM_I64, .u.i64 = value }
> >> > > +#define QNUM_VAL_UINT(value) \
> >> > > +{ .kind = QNUM_U64, .u.u64 = value }
> >> > > +#define QNUM_VAL_DOUBLE(value) \
> >> > > +{ .kind = QNUM_DOUBLE, .u.dbl = value }
> >> > > +
> >> > > +struct QNum {
> >> > > +struct QObjectBase_ base;
> >> > > +QNumValue value;
> >> > >  };
> >> > >
> >> > > +/**
> >> > > + * qnum_from_int(): Create a new QNum from a QNumValue
> >> > >
> >> >
> >> > Copy-pasta qnum_from_int() -> qnum_from_value()
> >>
> >> Oops!  I will fix it in v3, or submit a fixup patch if that's the
> >> only needed change.
> >>
> >> >
> >> > I wonder if there is a check for that kind of mistake, as it may be
> >> common.
> >>
> >> It looks like kernel-doc ignores what's before the colon in the
> >> summary line.  It probably shouldn't.
> >>
> >> >
> >> > + * @value: QNumValue
> >> > > + *
> >> > > + * Return strong reference.
> >> > > + */
> >> > > +QNum *qnum_from_value(QNumValue value);
> >> > >
> >> > +
> >> > >  QNum *qnum_from_int(int64_t value);
> >> > >  QNum *qnum_from_uint(uint64_t value);
> >> > >  QNum *qnum_from_double(double value);
> >> > >
> >> > > +/**
> >> > > + * qnum_get_value(): Get QNumValue from QNum
> >> > > + * @qn: QNum object
> >> > > + */
> >> > > +static inline const QNumValue *qnum_get_value(const QNum *qn)
&

Re: [PATCH v2 4/8] qnum: qnum_value_is_equal() function

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 11:27:40AM +0100, Markus Armbruster wrote:
[...]
> > +bool qnum_is_equal(const QObject *x, const QObject *y)
> > +{
> > +const QNum *qnum_x = qobject_to(QNum, x);
> > +const QNum *qnum_y = qobject_to(QNum, y);
> 
> Humor me: blank line between declarations and statements, please.

I can do it.  But why do you prefer it that way?

> 
> > +return qnum_value_is_equal(&qnum_x->value, &qnum_y->value);
> > +}
> > +
> >  /**
> >   * qnum_destroy_obj(): Free all memory allocated by a QNum object
> >   *

-- 
Eduardo




Re: [PATCH v2 1/8] qobject: Include API docs in docs/devel/qobject.html

2020-11-19 Thread Eduardo Habkost
CCing Peter, Sphinx documentation machinery maintainer.

On Thu, Nov 19, 2020 at 10:37:22AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > Render existing doc comments at docs/devel/qobject.html.
> >
> > Signed-off-by: Eduardo Habkost 
> > ---
[...]
> >  /**
> > - * qnum_destroy_obj(): Free all memory allocated by a
> > - * QNum object
> > + * qnum_destroy_obj(): Free all memory allocated by a QNum object
> > + *
> > + * @obj: QNum object to be destroyed
> >   */
> >  void qnum_destroy_obj(QObject *obj)
> >  {
> 
> Many lines of the form
> 
>   + * @foo: a foo

I hate them too.

> 
> One of my reasons to dislike GTK-Doc.  Oh well, it's what we're using.

It's not gtk-doc.  It's kernel-doc who generates warnings
if some parameters are not documented, and maybe we should
silence them.

-- 
Eduardo




Re: [PATCH v2 6/8] qlit: qlit_type() function

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 11:41:05AM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > Useful function where we need to check for the qlit type before
> > converting it to an actual QObject.
> >
> > Signed-off-by: Eduardo Habkost 
> > ---
> >  include/qapi/qmp/qlit.h | 5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> > index f9e356d31e..acddb80831 100644
> > --- a/include/qapi/qmp/qlit.h
> > +++ b/include/qapi/qmp/qlit.h
> > @@ -59,4 +59,9 @@ bool qlit_equal_qobject(const QLitObject *lhs, const 
> > QObject *rhs);
> >  
> >  QObject *qobject_from_qlit(const QLitObject *qlit);
> >  
> > +static inline QType qlit_type(const QLitObject *qlit)
> > +{
> > +return qlit->type;
> > +}
> > +
> >  #endif /* QLIT_H */
> 
> Hiding qlit->type behind a function makes sense only when the structure
> of QLitObject is an implementation secret.  It don't think it is.

I thought all QLitObject fields were considered private.  If they
are not, I can happily get rid of that function.

-- 
Eduardo




Re: [PATCH v2 0/8] qom: Use qlit to represent property defaults

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 06:23:30PM +0100, Paolo Bonzini wrote:
> On 19/11/20 18:13, Eduardo Habkost wrote:
> > > What's left?
> > Enums.  Enums properties are a mess to implement, and I plan to
> > tackle them later.
> > 
> > On all other cases, the external representation of the property
> > value is similar to the internal representation.  In the case of
> > enums, the external representation is a string, but the internal
> > representation is an integer.
> > 
> 
> I would have expected a string QLit to work with enums, is there a reason
> why it doesn't?

It would work, but it would be more inconvenient for callers.
Right now they use the C enum constant instead of a string.

-- 
Eduardo




Re: [PATCH v2 0/8] qom: Use qlit to represent property defaults

2020-11-19 Thread Eduardo Habkost
On Thu, Nov 19, 2020 at 01:39:50PM +0100, Markus Armbruster wrote:
> Eduardo Habkost  writes:
> 
> > Based-on: 20201104160021.2342108-1-ehabk...@redhat.com
> > Git branch: 
> > https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-qlit-defaults
> >
> > This extend qlit.h to support all QNum types (signed int,
> > unsigned int, and double), and use QLitObject to represent field
> > property defaults.
> >
> > It allows us to get rid of most type-specific .set_default_value
> > functions for QOM property types.
> 
> What's left?

Enums.  Enums properties are a mess to implement, and I plan to
tackle them later.

On all other cases, the external representation of the property
value is similar to the internal representation.  In the case of
enums, the external representation is a string, but the internal
representation is an integer.

> 
> I'm asking because if you create a new way to get rid of most of an old
> way, you're still left with two ways, which may or may not be an
> improvement.

I don't think this is an accurate description.  We had five
different ways of doing this[1].  I replaced four of them with
the new qlit-based mechanism, and now we have two.


[1] The five different ways were:
qdev_propinfo_set_default_value_enum,
qdev_propinfo_set_default_value_int,
qdev_propinfo_set_default_value_uint,
set_default_uuid_auto, and
set_default_value_bool.

> 
> Moving defaults from code to data sounds attractive to me.  Data is
> easier to reason about than code.  For QAPI, we've been talking about
> defining defaults in the schema for a long time, but nobody has gotten
> around to finish an implementation.

-- 
Eduardo




Re: [PATCH RFC v3 23/23] i386: provide simple 'hyperv=on' option to x86 machine types

2020-11-18 Thread Eduardo Habkost
On Fri, Oct 09, 2020 at 02:18:42PM +0200, Vitaly Kuznetsov wrote:
> Enabling Hyper-V emulation for a Windows VM is a tiring experience as it
> requires listing all currently supported enlightenments ("hv_*" CPU
> features) explicitly. We do have a 'hv_passthrough' mode enabling
> everything but it can't be used in production as it prevents migration.
> 
> Introduce a simple 'hyperv=on' option for all x86 machine types enabling
> all currently supported Hyper-V enlightenments. Later, when new
> enlightenments get implemented, we will be adding them to newer machine
> types only (by disabling them for legacy machine types) thus preserving
> migration.
> 
> Signed-off-by: Vitaly Kuznetsov 

This patch seems to be especially useful, and I wonder if we
could make sure this is included before all the rest of the
series.  Especially considering that the KVM changes might take a
while to be merged.

Would you be able to submit this independently from the rest of
the series?  You can add my:

Reviewed-by: Eduardo Habkost 

My only (minor) suggestion is to rename
X86MachineClass.hyperv_features to
X86MachineClass.default_hyperv_features.

> ---
>  docs/hyperv.txt   |  8 
>  hw/i386/x86.c | 30 ++
>  include/hw/i386/x86.h |  7 +++
>  target/i386/cpu.c | 14 ++
>  4 files changed, 59 insertions(+)
> 
> diff --git a/docs/hyperv.txt b/docs/hyperv.txt
> index 5df00da54fc4..1a76a07f8417 100644
> --- a/docs/hyperv.txt
> +++ b/docs/hyperv.txt
> @@ -29,6 +29,14 @@ When any set of the Hyper-V enlightenments is enabled, 
> QEMU changes hypervisor
>  identification (CPUID 0x4000..0x400A) to Hyper-V. KVM identification
>  and features are kept in leaves 0x4100..0x4101.
>  
> +Hyper-V enlightenments can be enabled in bulk by specifying 'hyperv=on' to an
> +x86 machine type:
> +
> +  qemu-system-x86_64 -machine q35,accel=kvm,kernel-irqchip=split,hyperv=on 
> ...
> +
> +Note, new enlightenments are only added to the latest (in-develompent) 
> machine
> +type, older machine types keep the list of the supported features intact to
> +safeguard migration.
>  
>  3. Existing enlightenments
>  ===
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index 3137a2008588..eeecd4e3322f 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -1171,6 +1171,20 @@ static void x86_machine_set_acpi(Object *obj, Visitor 
> *v, const char *name,
>  visit_type_OnOffAuto(v, name, &x86ms->acpi, errp);
>  }
>  
> +static bool x86_machine_get_hyperv(Object *obj, Error **errp)
> +{
> +X86MachineState *x86ms = X86_MACHINE(obj);
> +
> +return x86ms->hyperv_enabled;
> +}
> +
> +static void x86_machine_set_hyperv(Object *obj, bool value, Error **errp)
> +{
> +X86MachineState *x86ms = X86_MACHINE(obj);
> +
> +x86ms->hyperv_enabled = value;
> +}
> +
>  static void x86_machine_initfn(Object *obj)
>  {
>  X86MachineState *x86ms = X86_MACHINE(obj);
> @@ -1193,6 +1207,16 @@ static void x86_machine_class_init(ObjectClass *oc, 
> void *data)
>  x86mc->save_tsc_khz = true;
>  nc->nmi_monitor_handler = x86_nmi;
>  
> +/* Hyper-V features enabled with 'hyperv=on' */
> +x86mc->hyperv_features = BIT(HYPERV_FEAT_RELAXED) | 
> BIT(HYPERV_FEAT_VAPIC) |
> +BIT(HYPERV_FEAT_TIME) | BIT(HYPERV_FEAT_CRASH) |
> +BIT(HYPERV_FEAT_RESET) | BIT(HYPERV_FEAT_VPINDEX) |
> +BIT(HYPERV_FEAT_RUNTIME) | BIT(HYPERV_FEAT_SYNIC) |
> +BIT(HYPERV_FEAT_STIMER) | BIT(HYPERV_FEAT_FREQUENCIES) |
> +BIT(HYPERV_FEAT_REENLIGHTENMENT) | BIT(HYPERV_FEAT_TLBFLUSH) |
> +BIT(HYPERV_FEAT_EVMCS) | BIT(HYPERV_FEAT_IPI) |
> +BIT(HYPERV_FEAT_STIMER_DIRECT);
> +
>  object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
>  x86_machine_get_smm, x86_machine_set_smm,
>  NULL, NULL);
> @@ -1204,6 +1228,12 @@ static void x86_machine_class_init(ObjectClass *oc, 
> void *data)
>  NULL, NULL);
>  object_class_property_set_description(oc, X86_MACHINE_ACPI,
>  "Enable ACPI");
> +
> +object_class_property_add_bool(oc, X86_MACHINE_HYPERV,
> +x86_machine_get_hyperv, x86_machine_set_hyperv);
> +
> +object_class_property_set_description(oc, X86_MACHINE_HYPERV,
> +"Enable Hyper-V enlightenments");
>  }
>  
>  static const TypeInfo x86_machine_info = {
> diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
> index d5dcf7a07fdc..2b989e5fc49d 100644
> --- a/include/hw/i386/x86.h
> +++ b/include/hw/i386/x86.h
> @@ -38,6 +38,9 @@ struct X86MachineClass {

Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 08:13:18PM +0100, Paolo Bonzini wrote:
> On 18/11/20 18:30, Eduardo Habkost wrote:
> > > Adding a layer of indirect calls is not very different from monkey 
> > > patching
> > > though.
> > 
> > I'm a little bothered by monkey patching, but I'm more
> > bothered by having to:
> > 
> > (1) register (module_init()) a function (kvm_cpu_accel_register()) that
> >(2) register (accel_register_call()) a function (kvm_cpu_accel_init()) 
> > that
> >  (3) register (x86_cpu_accel_init()) a data structure (X86CPUAccel 
> > kvm_cpu_accel) that
> >(4) will be saved in multiple QOM classes, so that
> >  (5) we will call the right X86CPUClass.accel method at the right 
> > moment
> >  (common_class_init(), instance_init(), realizefn()),
> > where:
> >step 4 must be done before any CPU object is created
> >  (otherwise X86CPUAccel.instance_init & X86CPUAccel.realizefn
> >   will be silently ignored), and
> >step 3 must be done after all QOM types were registered.
> > 
> > > You also have to consider that accel currently does not exist in usermode
> > > emulators, so that's an issue too. I would rather get a simple change in
> > > quickly, instead of designing the perfect class hierarchy.
> > 
> > It doesn't have to be perfect.  I agree that simple is better.
> > 
> > To me, registering a QOM type and looking it up when necessary is
> > simpler than the above.  Even if it's a weird class having no
> > object instances.  It probably could be an interface type.
> 
> Registering a QOM type still has quite some boilerplate.  [...]

We're working on that.  :)

>[...]  Also registering a
> QOM type has a public side effect (shows up in qom-list-types).  In general
> I don't look at QOM unless I want its property mechanism, but maybe that's
> just me.

We have lots of internal-use-only types returned by
qom-list-types, I don't think it's a big deal.

> 
> > > Perhaps another idea would be to allow adding interfaces to classes
> > > *separately from the registration of the types*. Then we can use it to add
> > > SOFTMMU_ACCEL and I386_ACCEL interfaces to a bare bones accel class, and
> > > add the accel object to usermode emulators.
> > 
> > I'm not sure I follow.  What do you mean by bare bones accel
> > class, and when exactly would you add the new interfaces to the
> > classes?
> 
> A bare bones accel class would not have init_machine and setup_post methods;
> those would be in a TYPE_SOFTMMU_ACCEL interface.  It would still have
> properties (such as tb-size for TCG) and would be able to register compat
> properties.

Oh, I think I see.  This could save us having a lot of parallel type
hierarchies.

> 
> Where would I add it, I don't know.  It could be a simple public wrapper
> around type_initialize_interface() if we add a new MODULE_INIT_* phase after
> QOM.
> 
> Or without adding a new phase, it could be a class_type->array of
> (interface_type, init_fn) hash table.  type_initialize would look up the
> class_type by name, add the interfaces would to the class with
> type_initialize_interface, and then call the init_fn to fill in the vtable.

That sounds nice.  I don't think Claudio's cleanup should be
blocked until this new mechanism is ready, though.

We don't really need the type representing X86CPUAccel to be a
subtype of TYPE_ACCEL or an interface implemented by
current_machine->accelerator, in the first version.  We just need
a simple way for the CPU initialization code to find the correct
X86CPUAccel struct.

While we don't have the new mechanism, it can be just a:
  object_class_by_name("%s-x86-cpu-accel" % (accel->name))
call.

Below is a rough draft of what I mean.  There's still lots of
room for cleaning it up (especially getting rid of the
X86CPUClass.common_class_init and X86CPUClass.accel fields).

git tree at 
https://gitlab.com/ehabkost/qemu/-/commits/work/qom-based-x86-cpu-accel

Signed-off-by: Eduardo Habkost 
---
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 485eda986a..944d403cbd 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -44,7 +44,6 @@ typedef enum {
 MODULE_INIT_BLOCK,
 MODULE_INIT_OPTS,
 MODULE_INIT_QOM,
-MODULE_INIT_ACCEL_CPU,
 MODULE_INIT_TRACE,
 MODULE_INIT_XEN_BACKEND,
 MODULE_INIT_LIBQOS,
@@ -55,7 +54,6 @@ typedef enum {
 #define block_init(function) module_init(function, MODULE_INIT_BLOCK)
 #define opts_init(function) module_init(function, MODULE_INIT_OPTS)
 #define type

Re: [RFC v3 9/9] i386: split cpu accelerators from cpu.c

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 11:29:36AM +0100, Claudio Fontana wrote:
> split cpu.c into:
> 
> cpu.ccpuid and common x86 cpu functionality
> host-cpu.c   host x86 cpu functions and "host" cpu type
> kvm/cpu.cKVM x86 cpu type
> hvf/cpu.cHVF x86 cpu type
> tcg/cpu.cTCG x86 cpu type
> 
> The accel interface of the X86CPUClass is set at MODULE_INIT_ACCEL_CPU
> time, when the accelerator is known.
> 
> Signed-off-by: Claudio Fontana 
> ---
[...]
> +/**
> + * X86CPUAccel:
> + * @name: string name of the X86 CPU Accelerator
> + *
> + * @common_class_init: initializer for the common cpu

So this will be called for every single CPU class.

> + * @instance_init: cpu instance initialization
> + * @realizefn: realize function, called first in x86 cpu realize
> + *
> + * X86 CPU accelerator-specific CPU initializations
> + */
> +
> +struct X86CPUAccel {
> +const char *name;
> +
> +void (*common_class_init)(X86CPUClass *xcc);
> +void (*instance_init)(X86CPU *cpu);
> +void (*realizefn)(X86CPU *cpu, Error **errp);
>  };
>  
> +void x86_cpu_accel_init(const X86CPUAccel *accel);
[...]
> +static void x86_cpu_accel_init_aux(ObjectClass *klass, void *opaque)
> +{
> +X86CPUClass *xcc = X86_CPU_CLASS(klass);
> +const X86CPUAccel **accel = opaque;
> +
> +xcc->accel = *accel;
> +xcc->accel->common_class_init(xcc);
> +}
> +
> +void x86_cpu_accel_init(const X86CPUAccel *accel)
> +{
> +object_class_foreach(x86_cpu_accel_init_aux, TYPE_X86_CPU, false, 
> &accel);
> +}

This matches the documented behavior.

[...]
> +void host_cpu_class_init(X86CPUClass *xcc)
> +{
> +xcc->host_cpuid_required = true;
> +xcc->ordering = 8;
> +xcc->model_description =
> +g_strdup_printf("%s processor with all supported host features ",
> +xcc->accel->name);
> +}
[...]
> +static void hvf_cpu_common_class_init(X86CPUClass *xcc)
> +{
> +host_cpu_class_init(xcc);

Why are you calling host_cpu_class_init() for all CPU types?

> +}
[...]
> +static void kvm_cpu_common_class_init(X86CPUClass *xcc)
> +{
> +host_cpu_class_init(xcc);
> +}

Same question as above.

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 05:22:46PM +0100, Paolo Bonzini wrote:
> Il mer 18 nov 2020, 17:11 Eduardo Habkost  ha scritto:
> 
> > On Wed, Nov 18, 2020 at 04:43:19PM +0100, Paolo Bonzini wrote:
> > > Il mer 18 nov 2020, 16:26 Eduardo Habkost  ha
> > scritto:
> > >
> > > >
> > > > > The alternative is to store the (type, function) tuple directly,
> > with the
> > > > > type as a string.  Then you can just use type_init.
> > > >
> > > > Right.  Let's build on top of that:
> > > >
> > > > Another alternative would be to store a (type, X86CPUAccel) tuple
> > > > directly, with the type as string.  This would save the extra
> > > > indirection of the x86_cpu_accel_init() call.
> > > >
> > > > It turns out we already have a mechanism to register and store
> > > > (type, StructContainingFunctionPointers) tuples at initialization
> > > > time: QOM.
> > > >
> > > > X86CPUAccel can become X86CPUAccelClass, and be registered as a
> > > > QOM type.  It could be a subtype of TYPE_ACCEL or not, it
> > > > shouldn't matter.
> > > >
> > >
> > > It would be a weird type that isn't instantiated, and/or that does
> > nothing
> > > but monkey patching other classes. I don't think it's a good fit.
> >
> > The whole point of this would be to avoid monkey patching other
> > classes.
> >
> 
> Adding a layer of indirect calls is not very different from monkey patching
> though.

I'm a little bothered by monkey patching, but I'm more
bothered by having to:

(1) register (module_init()) a function (kvm_cpu_accel_register()) that
  (2) register (accel_register_call()) a function (kvm_cpu_accel_init()) that
(3) register (x86_cpu_accel_init()) a data structure (X86CPUAccel 
kvm_cpu_accel) that
  (4) will be saved in multiple QOM classes, so that
(5) we will call the right X86CPUClass.accel method at the right moment
(common_class_init(), instance_init(), realizefn()),
where:
  step 4 must be done before any CPU object is created
(otherwise X86CPUAccel.instance_init & X86CPUAccel.realizefn
 will be silently ignored), and
  step 3 must be done after all QOM types were registered.



> 
> You also have to consider that accel currently does not exist in usermode
> emulators, so that's an issue too. I would rather get a simple change in
> quickly, instead of designing the perfect class hierarchy.

It doesn't have to be perfect.  I agree that simple is better.

To me, registering a QOM type and looking it up when necessary is
simpler than the above.  Even if it's a weird class having no
object instances.  It probably could be an interface type.

> 
> Perhaps another idea would be to allow adding interfaces to classes
> *separately from the registration of the types*. Then we can use it to add
> SOFTMMU_ACCEL and I386_ACCEL interfaces to a bare bones accel class, and
> add the accel object to usermode emulators.

I'm not sure I follow.  What do you mean by bare bones accel
class, and when exactly would you add the new interfaces to the
classes?

> 
> Why wouldn't we instantiate it?  There's a huge number of static
> > variables in target/i386/kvm.c that could be moved to that
> > object.  Sounds like a perfect fit for me.
> >
> 
> Most of those are properties of the running kernel so there's no need to
> move them inside an object.

There's no need, correct.  Some consistency would be nice,
though.  All kernel capabilities in kvm-all.c are saved in
KVMState.

> 
> Paolo
> 
> I won't try to stop you if you really want to invent a brand new
> > (name => CollectionOfFunctionPointers) registry, but it seems
> > unnecessary.
> >
> > >
> > > Yet another possibility is to use GHashTable. It is limited to one value
> > > per key, but it's enough if everything is kept local to {hw,target}/i386.
> > > If needed a new function pointer can be added to MachineClass,
> > implemented
> > > in X86MachineState (where the GHashTable would also be) and called in
> > > accel.c.
> > >
> > > Paolo
> > >
> > > Paolo
> > >
> > >
> > > > I remember this was suggested in a previous thread, but I don't
> > > > remember if there were any objections.
> > > >
> > > > >
> > > > > > Making sure module_call_init() is called at the correct moment is
> > > > > > not easier or safer than just making sure accel_init_machine()
>

Re: [PATCH for-6.0 1/6] qapi: Add query-accel command

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 09:56:28AM -0600, Eric Blake wrote:
> On 11/18/20 9:45 AM, Eduardo Habkost wrote:
> > On Wed, Nov 18, 2020 at 02:53:26PM +0100, Markus Armbruster wrote:
> > [...]
> >> Another way to skin this cat:
> >>
> >>   {"available": {"kvm": { extra properties... },
> >>  "tcg": ...,
> >>  "xen": ...},
> >>"active": "kvm"}
> > 
> > How would this structure be represented in the QAPI schema?
> > 
> > In other words, how do I say "Dict[str, AccelInfo]" in QAPIese?
> 
> {'type':'AvailAccel', 'data': {
>   '*kvm': 'KvmExtraProps',
>   '*tcg': 'TcgExtraProps',
>   '*xen': 'XenExtraProps',
>   '*hax': 'HaxExtraProps' } }
> {'command':'query-accel', 'returns': {
>'available': 'AvailAccel', 'active': 'strOrEnum' } }
> 
> where adding a new accelerator then adds a new optional member to
> AvailAccel as well as possibly a new enum member if 'active' is driving
> by an enum instead of 'str'.

Is it possible to represent this if we don't enumerate all
possible dictionary keys in advance?  (I'm not suggesting we
should/shouldn't do that, just wondering if it's possible)

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 04:43:19PM +0100, Paolo Bonzini wrote:
> Il mer 18 nov 2020, 16:26 Eduardo Habkost  ha scritto:
> 
> >
> > > The alternative is to store the (type, function) tuple directly, with the
> > > type as a string.  Then you can just use type_init.
> >
> > Right.  Let's build on top of that:
> >
> > Another alternative would be to store a (type, X86CPUAccel) tuple
> > directly, with the type as string.  This would save the extra
> > indirection of the x86_cpu_accel_init() call.
> >
> > It turns out we already have a mechanism to register and store
> > (type, StructContainingFunctionPointers) tuples at initialization
> > time: QOM.
> >
> > X86CPUAccel can become X86CPUAccelClass, and be registered as a
> > QOM type.  It could be a subtype of TYPE_ACCEL or not, it
> > shouldn't matter.
> >
> 
> It would be a weird type that isn't instantiated, and/or that does nothing
> but monkey patching other classes. I don't think it's a good fit.

The whole point of this would be to avoid monkey patching other
classes.

Why wouldn't we instantiate it?  There's a huge number of static
variables in target/i386/kvm.c that could be moved to that
object.  Sounds like a perfect fit for me.

I won't try to stop you if you really want to invent a brand new
(name => CollectionOfFunctionPointers) registry, but it seems
unnecessary.

> 
> Yet another possibility is to use GHashTable. It is limited to one value
> per key, but it's enough if everything is kept local to {hw,target}/i386.
> If needed a new function pointer can be added to MachineClass, implemented
> in X86MachineState (where the GHashTable would also be) and called in
> accel.c.
> 
> Paolo
> 
> Paolo
> 
> 
> > I remember this was suggested in a previous thread, but I don't
> > remember if there were any objections.
> >
> > >
> > > > Making sure module_call_init() is called at the correct moment is
> > > > not easier or safer than just making sure accel_init_machine()
> > > > (or another init function you create) is called at the correct
> > > > moment.
> > >
> > > Since there is a way to do it without a new level, that would of course
> > be
> > > fine for me too.  Let me explain however why I think Claudio's design had
> > > module_call_init() misplaced and what the fundamental difference is.  The
> > > basic phases in qemu_init() are:
> > >
> > > - initialize stuff
> > > - parse command line
> > > - create machine
> > > - create accelerator
> > > - initialize machine
> > > - create devices
> > > - start
> > >
> > > with a mess of other object creation sprinkled between the various phases
> > > (but we don't care about those).
> > >
> > > What I object to, is calling module_call_init() after the "initialize
> > stuff"
> > > phase.  Claudio was using it to call the function directly, so it had to
> > be
> > > exactly at "create accelerator".  This is different from all other
> > > module_call_init() calls, which are done very early.
> >
> > I agree.
> >
> > >
> > > With the implementation I sketched, accel_register_call must still be
> > done
> > > after type_init, so there's still an ordering constraint, but all it's
> > doing
> > > is registering a callback in the "initialize stuff" phase.
> >
> > Makes sense, if we really want to introduce a new accel_register_call()
> > abstraction.  I don't think we need it, though.
> >
> > --
> > Eduardo
> >
> >

-- 
Eduardo




Re: [PATCH for-6.0 1/6] qapi: Add query-accel command

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 02:53:26PM +0100, Markus Armbruster wrote:
[...]
> Another way to skin this cat:
> 
>   {"available": {"kvm": { extra properties... },
>  "tcg": ...,
>  "xen": ...},
>"active": "kvm"}

How would this structure be represented in the QAPI schema?

In other words, how do I say "Dict[str, AccelInfo]" in QAPIese?

> 
> No need for unions then.  "No dupes" is enforced.
> 
> We could inline "available":
> 
>   {"kvm": { extra properties... },
>"tcg": ...,
>"xen": ...,
>"active": "kvm"}
> 
> Future accelerators can't be named "active" then.
> 
> > I guess this can be extended with a union to report extra props for the
> > accelerator, discriminated on the 'active' field eg
> >
> >  { 'available': [ 'kvm', 'tcg', 'xen' ],
> >'active': 'kvm',
> >'data': {
> >"allow-nested": true,
> >}
> > }
> 
> Correct.

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 03:51:44PM +0100, Paolo Bonzini wrote:
> On 18/11/20 15:36, Eduardo Habkost wrote:
> > On Wed, Nov 18, 2020 at 03:05:42PM +0100, Paolo Bonzini wrote:
> > > On 18/11/20 14:48, Claudio Fontana wrote:
> > > > On 11/18/20 1:48 PM, Eduardo Habkost wrote:
> > > > > I don't get why we would use a new module initialization level
> > > > 
> > > > To have a clear point in time after which all accelerator interface 
> > > > initialization is done.
> > > > It avoids to have to hunt down the registration points spread around 
> > > > the code base.
> > > > I'd turn it around, why not?
> > > 
> > > I see two disadvantages:
> > > 
> > > 1) you have to hunt down accel_cpu_inits instead of looking at accelerator
> > > classes. :)
> > > 
> > > 2) all callbacks have an "if (*_enabled())" around the actual meat. 
> > > Another
> > > related issue is that usually the module_call_init are unconditional.
> > > 
> > > I think the idea of using module_call_init is good however.  What about:
> > > 
> > > static void kvm_cpu_accel_init(void)
> > > {
> > >  x86_cpu_accel_init(&kvm_cpu_accel);
> > 
> > What do you expect x86_cpu_accel_init() to do?
> 
> I don't know, the same that it was doing in Claudio's patches. :)
> 
> He had
> 
>   if (kvm_enabled()) {
>   x86_cpu_accel_init(&kvm_cpu_accel);
>   }
> 
> and I'm calling only the function that is registered on the enabled
> accelerator.
> 
> > I don't understand why a separate module init level is necessary
> > here.
> 
> Because you must call accel_register_call after the TYPE_KVM type has been
> registered, or object_class_by_name fails:
> 
> void
> accel_register_call(const char *qom_type, void (*fn)(void))
> {
> AccelClass *acc = ACCEL_CLASS(object_class_by_name(qom_type));
> 
> acc->setup_calls = g_slist_append(acc->setup_calls, (void *)fn);
> }
> 
> The alternative is to store the (type, function) tuple directly, with the
> type as a string.  Then you can just use type_init.

Right.  Let's build on top of that:

Another alternative would be to store a (type, X86CPUAccel) tuple
directly, with the type as string.  This would save the extra
indirection of the x86_cpu_accel_init() call.

It turns out we already have a mechanism to register and store
(type, StructContainingFunctionPointers) tuples at initialization
time: QOM.

X86CPUAccel can become X86CPUAccelClass, and be registered as a
QOM type.  It could be a subtype of TYPE_ACCEL or not, it
shouldn't matter.

I remember this was suggested in a previous thread, but I don't
remember if there were any objections.

> 
> > Making sure module_call_init() is called at the correct moment is
> > not easier or safer than just making sure accel_init_machine()
> > (or another init function you create) is called at the correct
> > moment.
> 
> Since there is a way to do it without a new level, that would of course be
> fine for me too.  Let me explain however why I think Claudio's design had
> module_call_init() misplaced and what the fundamental difference is.  The
> basic phases in qemu_init() are:
> 
> - initialize stuff
> - parse command line
> - create machine
> - create accelerator
> - initialize machine
> - create devices
> - start
> 
> with a mess of other object creation sprinkled between the various phases
> (but we don't care about those).
> 
> What I object to, is calling module_call_init() after the "initialize stuff"
> phase.  Claudio was using it to call the function directly, so it had to be
> exactly at "create accelerator".  This is different from all other
> module_call_init() calls, which are done very early.

I agree.

> 
> With the implementation I sketched, accel_register_call must still be done
> after type_init, so there's still an ordering constraint, but all it's doing
> is registering a callback in the "initialize stuff" phase.

Makes sense, if we really want to introduce a new accel_register_call()
abstraction.  I don't think we need it, though.

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 03:05:42PM +0100, Paolo Bonzini wrote:
> On 18/11/20 14:48, Claudio Fontana wrote:
> > On 11/18/20 1:48 PM, Eduardo Habkost wrote:
> > > On Wed, Nov 18, 2020 at 11:29:35AM +0100, Claudio Fontana wrote:
> > > > apply this to the registration of the cpus accel interfaces,
> > > > 
> > > > but this will be also in preparation for later use of this
> > > > new module init step to also defer the registration of the cpu models,
> > > > in order to make them subclasses of a per-accel cpu type.
> > > > 
> > > > Signed-off-by: Claudio Fontana 
> > > > ---
> > > [...]
> > > > +/*
> > > > + * accelerator has been chosen and initialized, now it is time to
> > > > + * register the cpu accel interface.
> > > > + */
> > > > +module_call_init(MODULE_INIT_ACCEL_CPU);
> > > 
> > > I don't get why we would use a new module initialization level
> > 
> > To have a clear point in time after which all accelerator interface 
> > initialization is done.
> > It avoids to have to hunt down the registration points spread around the 
> > code base.
> > I'd turn it around, why not?
> 
> I see two disadvantages:
> 
> 1) you have to hunt down accel_cpu_inits instead of looking at accelerator
> classes. :)
> 
> 2) all callbacks have an "if (*_enabled())" around the actual meat. Another
> related issue is that usually the module_call_init are unconditional.
> 
> I think the idea of using module_call_init is good however.  What about:
> 
> static void kvm_cpu_accel_init(void)
> {
> x86_cpu_accel_init(&kvm_cpu_accel);

What do you expect x86_cpu_accel_init() to do?

> }
> 
> static void kvm_cpu_accel_register(void)
> {
> accel_register_call(TYPE_KVM, kvm_cpu_accel_init);
> }
> accel_cpu_init(kvm_cpu_accel_register);
> 
> ...
> 
> void
> accel_register_call(const char *qom_type, void (*fn)(void))
> {
> AccelClass *acc = ACCEL_CLASS(object_class_by_name(qom_type));
> 
> acc->setup_calls = g_slist_append(acc->setup_calls, (void *)fn);
> }
> 
> void
> accel_do_call(void *data, void *unused)
> {
> void (*fn)(void) = data;
> 
> data();
> }
> 
> int accel_init_machine(AccelState *accel, MachineState *ms)
> {
> ...
> if (ret < 0) {
> ms->accelerator = NULL;
> *(acc->allowed) = false;
> object_unref(OBJECT(accel));
> } else {
> object_set_accelerator_compat_props(acc->compat_props);
> g_slist_foreach(acc->setup_calls, accel_do_call, NULL);

Why all this extra complexity if you can simply do:

  ACCEL_GET_CLASS(acc)->finish_arch_specific_init();

?


> }
> return ret;
> }
> 
> where the module_call_init would be right after MODULE_INIT_QOM
> 
> Paolo
> 
> > > for this.  If the accelerator object was already created, we can
> > > just ask the existing accel object to do whatever initialization
> > > step is necessary.
> > > 
> > > e.g. we can add a AccelClass.cpu_accel_ops field, and call:
> > > 
> > > cpus_register_accel(current_machine->accelerator->cpu_accel_ops);
> > > 
> > 
> > _When_ this is done is the question, in my view, where the call to the 
> > registration is placed.
> > 
> > After adding additonal operations that have to be done at
> > "accelerator-chosen" time, it becomes more and more difficult
> > to trace them around the codebase.

I don't understand why a separate module init level is necessary
here.

Making sure module_call_init() is called at the correct moment is
not easier or safer than just making sure accel_init_machine()
(or another init function you create) is called at the correct
moment.

-- 
Eduardo




Re: [RFC v3 8/9] module: introduce MODULE_INIT_ACCEL_CPU

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 11:29:35AM +0100, Claudio Fontana wrote:
> apply this to the registration of the cpus accel interfaces,
> 
> but this will be also in preparation for later use of this
> new module init step to also defer the registration of the cpu models,
> in order to make them subclasses of a per-accel cpu type.
> 
> Signed-off-by: Claudio Fontana 
> ---
[...]
> +/*
> + * accelerator has been chosen and initialized, now it is time to
> + * register the cpu accel interface.
> + */
> +module_call_init(MODULE_INIT_ACCEL_CPU);

I don't get why we would use a new module initialization level
for this.  If the accelerator object was already created, we can
just ask the existing accel object to do whatever initialization
step is necessary.

e.g. we can add a AccelClass.cpu_accel_ops field, and call:

   cpus_register_accel(current_machine->accelerator->cpu_accel_ops);

-- 
Eduardo




Re: Property '.hmat' not found

2020-11-18 Thread Eduardo Habkost
On Wed, Nov 18, 2020 at 06:16:36PM +0800, 郭俊甫 (Jack Kuo) wrote:
> >
> > Could you check what happens if you use
> > "-machine pc-i440fx-5.2,hmat=on" instead of "-machine hmat=on"?
> 
> 
> It failed, but `-machine pc-i440fx-4.2` worked without `hmat` option.
> So, the problem could be that I didn't fully compile QEMU, which specified
> `--target-list=x86_64-softmmu` in the configure command.
> 
> Thus, I re-compile QEMU without any additional arg, then the problem is
> solved!
> It's strange that `-machine pc,help` showed me `pc-i440fx-5.2` but actually
> loaded the `pc-i440fx-4.2`.

Yeah, it is strange.  Were the "-version" and "-machine pc,help"
commands executed on a different shell process?  If you have
installed a new qemu-system-x86_64 binary in a separate location
in $PATH (e.g. /usr/local/bin), existing shell processes might
still run the old binary if the old path was already in their
hash table.

> 
> BTW, originally, I thought that `-hmat-cache` is the arg for customizing
> CPU cache, and now I find that I'm wrong... It's for memory side cache.

Correct.  Unfortunately, there are not many CPU cache
configuration options in qemu-system-x86_64 today, except for
"l3-cache" and "host-cache-info" -cpu options.

> 
> Thank you very much, really help me a lot.

No problem!

> 
> Sincerely,
> Jack
> 
> Eduardo Habkost  於 2020年11月17日 週二 下午11:09寫道:
> 
> > On Tue, Nov 17, 2020 at 11:49:38AM +0800, 郭俊甫 (Jack Kuo) wrote:
> > > >
> > > > Do you have the output of `qemu-system-x86_64 -version`, and more
> > > > information on how your binary was built?
> > >
> > >
> > > I have 2 machines, both of them encounter the .hmat problem.
> > >
> > > (1) *5.1.90 (v5.2.0-rc0*)
> > > - follow this wiki [1], and configure cmd: `./configure
> > > --target-list=x86_64-softmmu`
> > > - i5-8400, Ubuntu 20.04.1 LTS, kernel: 5.4.0-53-generic
> >
> > This one is supposed to work, and I see the pc-i440fx-5.2.hmat
> > property below.
> >
> >
> > >
> > > (2) *4.2.1 (Debian 1:4.2-3ubuntu6.8)*
> >
> > This one isn't expect to have "hmat", as the feature was
> > introduced in v5.0.0.
> >
> > > - use apt install qemu
> > > - E5-2670 * 2, Ubuntu 20.04.1 LTS, kernel: 5.4.0-53-generic, Dell
> > > PowerEdge-R720
> > >
> > > I can't reproduce it here.  I've tested both qemu.git master
> > >
> > >
> > > That’s strange, also I try the command you (Eduardo) provided, '.hmat'
> > not
> > > found, too.
> > > Does the kernel module matter? or PC architecture?
> >
> > Kernel or host architecture shouldn't matter.  The choice of
> > machine type matters, but the default is supposed to be "pc".
> > The output of "-machine help" might be useful to debug it.
> >
> > Could you check what happens if you use
> > "-machine pc-i440fx-5.2,hmat=on" instead of "-machine hmat=on"?
> >
> >
> > >
> > > Output of `-machine help` and `-machine pc,help` would be useful
> > > > to debug it, too.
> > >
> > >
> > >  (1) *5.1.90 (i5-8400)*
> > > *```*
> > > $ qemu-system-x86_64 -machine pc,help
> > > pc-i440fx-5.2.nvdimm-persistence=string (Set NVDIMM persistenceValid
> > values
> > > are cpu, mem-ctrl)
> > > pc-i440fx-5.2.hmat=bool (Set on/off to enable/disable ACPI Heterogeneous
> > > Memory Attribute Table (HMAT))
> > > pc-i440fx-5.2.nvdimm=bool (Set on/off to enable/disable NVDIMM
> > > instantiation)
> > > pc-i440fx-5.2.pcspk-audiodev=str (ID of an audiodev to use as a backend)
> > > pc-i440fx-5.2.pflash1=str (Node name or ID of a block device to use as a
> > > backend)
> > > pc-i440fx-5.2.pflash0=str (Node name or ID of a block device to use as a
> > > backend)
> > > pc-i440fx-5.2.hpet=bool
> > > pc-i440fx-5.2.vmport=OnOffAuto (Enable vmport (pc & q35))
> > > pc-i440fx-5.2.sata=bool
> > > pc-i440fx-5.2.pit=bool
> > > pc-i440fx-5.2.max-ram-below-4g=size (Maximum ram below the 4G boundary
> > > (32bit boundary))
> > > pc-i440fx-5.2.smbus=bool
> > > pc-i440fx-5.2.acpi=OnOffAuto (Enable ACPI)
> > > pc-i440fx-5.2.smm=OnOffAuto (Enable SMM)
> > > pc-i440fx-5.2.memory-backend=string (Set RAM backendValid value is ID of
> > > hostmem based backend)
> > > pc-i440fx-5.2.firmware=string (Firmware image)
&g

Re: [PATCH v2 02/16] qapi/expr.py: Check for dict instead of OrderedDict

2020-11-17 Thread Eduardo Habkost
On Tue, Nov 17, 2020 at 05:30:04PM +0100, Markus Armbruster wrote:
> John Snow  writes:
> 
> > OrderedDict is a subtype of dict, so we can check for a more general form.
> >
> > Signed-off-by: John Snow 
> > Reviewed-by: Eduardo Habkost 
> > Reviewed-by: Cleber Rosa 
> > ---
> >  scripts/qapi/expr.py | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
> > index 35695c4c653b..5694c501fa38 100644
> > --- a/scripts/qapi/expr.py
> > +++ b/scripts/qapi/expr.py
> > @@ -14,7 +14,6 @@
> >  # This work is licensed under the terms of the GNU GPL, version 2.
> >  # See the COPYING file in the top-level directory.
> >  
> > -from collections import OrderedDict
> >  import re
> >  
> >  from .common import c_name
> > @@ -131,7 +130,7 @@ def check_if_str(ifcond):
> >  
> >  
> >  def normalize_members(members):
> > -if isinstance(members, OrderedDict):
> > +if isinstance(members, dict):
> >  for key, arg in members.items():
> >  if isinstance(arg, dict):
> >  continue
> > @@ -162,7 +161,7 @@ def check_type(value, info, source,
> >  if not allow_dict:
> >  raise QAPISemError(info, "%s should be a type name" % source)
> >  
> > -if not isinstance(value, OrderedDict):
> > +if not isinstance(value, dict):
> >  raise QAPISemError(info,
> > "%s should be an object or type name" % source)
> 
> Plain dict remembers insertion order since Python 3.6, but it wasn't
> formally promised until 3.7.  
> 
> Can we simply ditch OrderedDict entirely?

In theory, our build requirement is "Python >= 3.6", not
"CPython >= 3.6".  In practice, I don't expect anybody to ever
use any other Python implementation except CPython to build QEMU.

I think we can get rid of OrderedDict if you really want to.

-- 
Eduardo




Re: [PATCH v2 4/8] qnum: qnum_value_is_equal() function

2020-11-17 Thread Eduardo Habkost
On Tue, Nov 17, 2020 at 08:53:19PM +0400, Marc-André Lureau wrote:
> On Tue, Nov 17, 2020 at 7:49 PM Eduardo Habkost  wrote:
> 
> > On Tue, Nov 17, 2020 at 12:42:47PM +0400, Marc-André Lureau wrote:
> > > On Tue, Nov 17, 2020 at 2:42 AM Eduardo Habkost 
> > wrote:
> > >
> > > > Extract the QNum value comparison logic to a function that takes
> > > > QNumValue* as argument.
> > > >
> > > > Signed-off-by: Eduardo Habkost 
> > > > ---
> > > >  include/qapi/qmp/qnum.h |  1 +
> > > >  qobject/qnum.c  | 29 +++--
> > > >  2 files changed, 20 insertions(+), 10 deletions(-)
> > > >
> > > > diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
> > > > index 62fbdfda68..0327ecd0f0 100644
> > > > --- a/include/qapi/qmp/qnum.h
> > > > +++ b/include/qapi/qmp/qnum.h
> > > > @@ -106,6 +106,7 @@ double qnum_get_double(const QNum *qn);
> > > >
> > > >  char *qnum_to_string(QNum *qn);
> > > >
> > > > +bool qnum_value_is_equal(const QNumValue *num_x, const QNumValue
> > *num_y);
> > > >  bool qnum_is_equal(const QObject *x, const QObject *y);
> > > >  void qnum_destroy_obj(QObject *obj);
> > > >
> > > > diff --git a/qobject/qnum.c b/qobject/qnum.c
> > > > index f80d4efd76..6a0f948b16 100644
> > > > --- a/qobject/qnum.c
> > > > +++ b/qobject/qnum.c
> > > > @@ -207,9 +207,9 @@ char *qnum_to_string(QNum *qn)
> > > >  }
> > > >
> > > >  /**
> > > > - * qnum_is_equal(): Test whether the two QNums are equal
> > > > - * @x: QNum object
> > > > - * @y: QNum object
> > > > + * qnum_value_is_equal(): Test whether two QNumValues are equal
> > > > + * @num_x: QNum value
> > > > + * @num_y: QNum value
> > > >
> > >
> > > val_x: a QNumValue ?
> >
> > Do you mean:
> >   @num_x: a QNumValue
> >
> ?
> >
> > I was not planning to rename the existing num_x/num_y variables.
> >
> >
> Not renaming because that would make some churn? But this is already quite
> confusing, so it's better to use "val" for QNumVal and "num" for QNum I
> guess.
> 
> If you don't want to rename it in the code, may I suggest doing it at the
> declaration side? Not sure it's a better idea.

Yeah, I was not renaming them just to avoid churn.

However, I'm already replacing `qn` variables with `qv` at patch
3/8.  Replacing num_x/num_y with val_x/val_y at qnum_is_equal()
(at patch 3/8 as well) wouldn't hurt too much.

-- 
Eduardo




Re: [PATCH v2 4/8] qnum: qnum_value_is_equal() function

2020-11-17 Thread Eduardo Habkost
On Tue, Nov 17, 2020 at 12:42:47PM +0400, Marc-André Lureau wrote:
> On Tue, Nov 17, 2020 at 2:42 AM Eduardo Habkost  wrote:
> 
> > Extract the QNum value comparison logic to a function that takes
> > QNumValue* as argument.
> >
> > Signed-off-by: Eduardo Habkost 
> > ---
> >  include/qapi/qmp/qnum.h |  1 +
> >  qobject/qnum.c  | 29 +++--
> >  2 files changed, 20 insertions(+), 10 deletions(-)
> >
> > diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
> > index 62fbdfda68..0327ecd0f0 100644
> > --- a/include/qapi/qmp/qnum.h
> > +++ b/include/qapi/qmp/qnum.h
> > @@ -106,6 +106,7 @@ double qnum_get_double(const QNum *qn);
> >
> >  char *qnum_to_string(QNum *qn);
> >
> > +bool qnum_value_is_equal(const QNumValue *num_x, const QNumValue *num_y);
> >  bool qnum_is_equal(const QObject *x, const QObject *y);
> >  void qnum_destroy_obj(QObject *obj);
> >
> > diff --git a/qobject/qnum.c b/qobject/qnum.c
> > index f80d4efd76..6a0f948b16 100644
> > --- a/qobject/qnum.c
> > +++ b/qobject/qnum.c
> > @@ -207,9 +207,9 @@ char *qnum_to_string(QNum *qn)
> >  }
> >
> >  /**
> > - * qnum_is_equal(): Test whether the two QNums are equal
> > - * @x: QNum object
> > - * @y: QNum object
> > + * qnum_value_is_equal(): Test whether two QNumValues are equal
> > + * @num_x: QNum value
> > + * @num_y: QNum value
> >
> 
> val_x: a QNumValue ?

Do you mean:
  @num_x: a QNumValue
?

I was not planning to rename the existing num_x/num_y variables.

> 
>   *
> >   * Negative integers are never considered equal to unsigned integers,
> >   * but positive integers in the range [0, INT64_MAX] are considered
> > @@ -217,13 +217,8 @@ char *qnum_to_string(QNum *qn)
> >   *
> >   * Doubles are never considered equal to integers.
> >   */
> > -bool qnum_is_equal(const QObject *x, const QObject *y)
> > +bool qnum_value_is_equal(const QNumValue *num_x, const QNumValue *num_y)
> >  {
> > -const QNum *qnum_x = qobject_to(QNum, x);
> > -const QNum *qnum_y = qobject_to(QNum, y);
> > -const QNumValue *num_x = &qnum_x->value;
> > -const QNumValue *num_y = &qnum_y->value;
> > -
> >  switch (num_x->kind) {
> >  case QNUM_I64:
> >  switch (num_y->kind) {
> > @@ -241,7 +236,7 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
> >  case QNUM_U64:
> >  switch (num_y->kind) {
> >  case QNUM_I64:
> > -return qnum_is_equal(y, x);
> > +return qnum_value_is_equal(num_y, num_x);
> >  case QNUM_U64:
> >  /* Comparison in native uint64_t type */
> >  return num_x->u.u64 == num_y->u.u64;
> > @@ -264,6 +259,20 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
> >  abort();
> >  }
> >
> > +/**
> > + * qnum_is_equal(): Test whether the two QNums are equal
> > + * @x: QNum object
> > + * @y: QNum object
> > + *
> > + * See qnum_value_is_equal() for details on the comparison rules.
> > + */
> > +bool qnum_is_equal(const QObject *x, const QObject *y)
> > +{
> > +const QNum *qnum_x = qobject_to(QNum, x);
> > +const QNum *qnum_y = qobject_to(QNum, y);
> > +return qnum_value_is_equal(&qnum_x->value, &qnum_y->value);
> > +}
> > +
> >  /**
> >   * qnum_destroy_obj(): Free all memory allocated by a QNum object
> >   *
> > --
> > 2.28.0
> >
> >
> >
> beside that,
> Reviewed-by: Marc-André Lureau 

Thanks!

-- 
Eduardo




Re: Property '.hmat' not found

2020-11-17 Thread Eduardo Habkost
te
> dynamically)
> pc-i440fx-4.2.igd-passthru=bool (Set on/off to enable/disable igd passthrou)
> pc-i440fx-4.2.kvm-shadow-mem=int (KVM shadow MMU size)
> pc-i440fx-4.2.dump-guest-core=bool (Include guest memory in a core dump)
> pc-i440fx-4.2.memory-encryption=string (Set memory encryption object to use)
> pc-i440fx-4.2.firmware=string (Firmware image)
> pc-i440fx-4.2.usb=bool (Set on/off to enable/disable usb)
> pc-i440fx-4.2.kernel-irqchip=on|off|split (Configure KVM in-kernel irqchip)
> pc-i440fx-4.2.graphics=bool (Set on/off to enable/disable graphics
> emulation)
> pc-i440fx-4.2.initrd=string (Linux initial ramdisk file)
> pc-i440fx-4.2.dt-compatible=string (Overrides the "compatible" property of
> the dt root node)
> pc-i440fx-4.2.kernel=string (Linux kernel image file)
> pc-i440fx-4.2.enforce-config-section=bool (Set on to enforce configuration
> section migration)
> ```
> 
> [1] https://wiki.qemu.org/Hosts/Linux#Building_QEMU_for_Linux
> 
> Sincerely,
> Jack
> 
> Eduardo Habkost  於 2020年11月17日 週二 上午3:02寫道:
> 
> > On Mon, Nov 16, 2020 at 01:51:37PM +0100, Philippe Mathieu-Daudé wrote:
> > > Cc'ing Igor & Eduardo.
> >
> > Thanks!
> >
> > >
> > > On 11/13/20 10:17 AM, Jack wrote:
> > > > Hi all,
> > > >
> > > > As I follow the document[1] to enable hmat, it fails and shows the
> > message:
> > > >   qemu-system-x86_64: Property '.hmat' not found
> > > >
> > > > My QEMU version is 5.1.90
> >
> > Do you have the output of `qemu-system-x86_64 -version`, and more
> > information on how your binary was built?
> >
> > Output of `-machine help` and `-machine pc,help` would be useful
> > to debug it, too.
> >
> > I can't reproduce it here.  I've tested both qemu.git master
> > (commit cb5ed407a1dd) and v5.2.0-rc (commit 3d6e32347a3b).
> >
> >   [build/(cb5ed407a1...)]$ ./qemu-system-x86_64 -version
> >   QEMU emulator version 5.1.91 (v5.2.0-rc1-107-gcb5ed407a1)
> >   Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers
> >   [build/(cb5ed407a1...)]$ ./qemu-system-x86_64 -machine hmat=on -m 2G
> > -object memory-backend-ram,size=1G,id=m0 -object
> > memory-backend-ram,size=1G,id=m1 -smp 2 -numa node,nodeid=0,memdev=m0 -numa
> > node,nodeid=1,memdev=m1,initiator=0 -numa cpu ,node-id=0,socket-id=0 -numa
> > cpu,node-id=0,socket-id=1 -numa
> > hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5
> > -numa
> > hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M
> > -numa
> > hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10
> > -numa
> > hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M
> > -numa
> > hmat-cache,node-id=0,size=10K,level=1,associativity=direct,policy=write-back,line=8
> > -numa
> > hmat-cache,node-id=1,size=10K,level=1,associativity=direct,policy=write-back,line=8
> > -cpu host -vga virtio -accel kvm
> >   [VM boots]
> >
> >
> > > >
> > > > Does anyone know why?
> > > >
> > > > Here is my command:
> > > >
> > > > ```
> > > > $ sudo qemu-system-x86_64 \
> > > > -machine hmat=on \
> > > > -m 2G \
> > > > -object memory-backend-ram,size=1G,id=m0 \
> > > > -object memory-backend-ram,size=1G,id=m1 \
> > > > -smp 2 \
> > > > -numa node,nodeid=0,memdev=m0 \
> > > > -numa node,nodeid=1,memdev=m1,initiator=0 \
> > > > -numa cpu,node-id=0,socket-id=0 \
> > > > -numa cpu,node-id=0,socket-id=1 \
> > > > -numa
> > > >
> > hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5
> > > > \
> > > > -numa
> > > >
> > hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M
> > > > \
> > > > -numa
> > > >
> > hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10
> > > > \
> > > > -numa
> > > >
> > hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M
> > > > \
> > > > -numa
> > > >
> > hmat-cache,node-id=0,size=10K,level=1,associativity=direct,policy=write-back,line=8
> > > > \
> > > > -numa
> > > >
> > hmat-cache,node-id=1,size=10K,level=1,associativity=direct,policy=write-back,line=8
> > > > \
> > > > -cpu host \
> > > > -m 4g -vga virtio -hda ubuntu20.04.qcow2 \
> > > > -nic user,model=virtio \
> > > > -nic tap,model=e1000 \
> > > > -nic tap,model=e1000 \
> > > > -accel kvm
> > > > ```
> > > >
> > > > Thanks.
> > > >
> > > > [1]
> > > >
> > https://www.qemu.org/docs/master/system/qemu-manpage.html?highlight=numa
> > > >
> > > >
> > > > Sincerely,
> > > > Jack
> > > >
> > >
> >
> > --
> > Eduardo
> >
> >

-- 
Eduardo




Re: [PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-17 Thread Eduardo Habkost
On Tue, Nov 17, 2020 at 12:37:56PM +0400, Marc-André Lureau wrote:
> On Tue, Nov 17, 2020 at 2:43 AM Eduardo Habkost  wrote:
> 
> > Provide a separate QNumValue type that can be used for QNum value
> > literals without the referencing counting and memory allocation
> > features provided by QObject.
> >
> > Signed-off-by: Eduardo Habkost 
> > ---
> > Changes v1 -> v2:
> > * Fix "make check" failure, by updating check-qnum unit test to
> >   use the new struct fields
> > ---
> >  include/qapi/qmp/qnum.h | 40 +++--
> >  qobject/qnum.c  | 78 -
> >  tests/check-qnum.c  | 14 
> >  3 files changed, 84 insertions(+), 48 deletions(-)
> >
> > diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
> > index 55c27b1c24..62fbdfda68 100644
> > --- a/include/qapi/qmp/qnum.h
> > +++ b/include/qapi/qmp/qnum.h
> > @@ -46,20 +46,56 @@ typedef enum {
> >   * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
> >   * convert under the hood.
> >   */
> > -struct QNum {
> > -struct QObjectBase_ base;
> > +
> > +/**
> > + * struct QNumValue: the value of a QNum
> > + *
> > + * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
> > + * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
> > + */
> > +typedef struct QNumValue {
> > +/* private: */
> >  QNumKind kind;
> >  union {
> >  int64_t i64;
> >  uint64_t u64;
> >  double dbl;
> >  } u;
> > +} QNumValue;
> > +
> > +#define QNUM_VAL_INT(value) \
> > +{ .kind = QNUM_I64, .u.i64 = value }
> > +#define QNUM_VAL_UINT(value) \
> > +{ .kind = QNUM_U64, .u.u64 = value }
> > +#define QNUM_VAL_DOUBLE(value) \
> > +{ .kind = QNUM_DOUBLE, .u.dbl = value }
> > +
> > +struct QNum {
> > +struct QObjectBase_ base;
> > +QNumValue value;
> >  };
> >
> > +/**
> > + * qnum_from_int(): Create a new QNum from a QNumValue
> >
> 
> Copy-pasta qnum_from_int() -> qnum_from_value()

Oops!  I will fix it in v3, or submit a fixup patch if that's the
only needed change.

> 
> I wonder if there is a check for that kind of mistake, as it may be common.

It looks like kernel-doc ignores what's before the colon in the
summary line.  It probably shouldn't.

> 
> + * @value: QNumValue
> > + *
> > + * Return strong reference.
> > + */
> > +QNum *qnum_from_value(QNumValue value);
> >
> +
> >  QNum *qnum_from_int(int64_t value);
> >  QNum *qnum_from_uint(uint64_t value);
> >  QNum *qnum_from_double(double value);
> >
> > +/**
> > + * qnum_get_value(): Get QNumValue from QNum
> > + * @qn: QNum object
> > + */
> > +static inline const QNumValue *qnum_get_value(const QNum *qn)
> > +{
> > +return &qn->value;
> > +}
> > +
> >
> 
> Nothing uses that function in this patch. Should be put into use.

It is used in patch 5/8.  Why do you think it's necessary to use
it in internal code too?

> 
>  bool qnum_get_try_int(const QNum *qn, int64_t *val);
> >  int64_t qnum_get_int(const QNum *qn);
> >
> > diff --git a/qobject/qnum.c b/qobject/qnum.c
> > index 69fd9a82d9..f80d4efd76 100644
> > --- a/qobject/qnum.c
> > +++ b/qobject/qnum.c
> > @@ -15,6 +15,15 @@
> >  #include "qemu/osdep.h"
> >  #include "qapi/qmp/qnum.h"
> >
> > +QNum *qnum_from_value(QNumValue value)
> >
> 
> I wonder if it shouldn't be made "inline" in header too (if that can help
> avoid argument copy).

I'm unsure.  I would make it inline (in a separate patch) if
there's evidence it's worth it.  I expect the g_new() call to be
more expensive than any argument copying, though.

> 
> +{
> > +QNum *qn = g_new(QNum, 1);
> > +
> > +qobject_init(QOBJECT(qn), QTYPE_QNUM);
> > +qn->value = value;
> > +return qn;
> > +}
> > +
> >  /**
> >   * qnum_from_int(): Create a new QNum from an int64_t
> >   * @value: int64_t value
> > @@ -23,13 +32,7 @@
> >   */
> >  QNum *qnum_from_int(int64_t value)
> >  {
> > -QNum *qn = g_new(QNum, 1);
> > -
> > -qobject_init(QOBJECT(qn), QTYPE_QNUM);
> > -qn->kind = QNUM_I64;
> > -qn->u.i64 = value;
> > -
> > -return qn;
> > +return qnum_from_value((QNumValue) QNUM_VAL_INT(value));
> >  }
> >
> >  /**
> &

[PATCH v2 6/8] qlit: qlit_type() function

2020-11-16 Thread Eduardo Habkost
Useful function where we need to check for the qlit type before
converting it to an actual QObject.

Signed-off-by: Eduardo Habkost 
---
 include/qapi/qmp/qlit.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index f9e356d31e..acddb80831 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -59,4 +59,9 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject 
*rhs);
 
 QObject *qobject_from_qlit(const QLitObject *qlit);
 
+static inline QType qlit_type(const QLitObject *qlit)
+{
+return qlit->type;
+}
+
 #endif /* QLIT_H */
-- 
2.28.0




[PATCH v2 5/8] qlit: Support all types of QNums

2020-11-16 Thread Eduardo Habkost
Use QNumValue to represent QNums, so we can also support uint64_t
and double QNum values.  Add new QLIT_QNUM_(INT|UINT|DOUBLE)
macros for each case.

The QLIT_QNUM() macro is being kept for compatibility with
existing code, but becomes just a wrapper for QLIT_QNUM_INT().

Signed-off-by: Eduardo Habkost 
---
Changes v1 -> v2:
* Coding style fix at qlit_equal_qobject()
---
 include/qapi/qmp/qlit.h | 11 +--
 qobject/qlit.c  |  5 +--
 tests/check-qjson.c | 72 ++---
 3 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index c0676d5daf..f9e356d31e 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -15,6 +15,7 @@
 #define QLIT_H
 
 #include "qobject.h"
+#include "qnum.h"
 
 typedef struct QLitDictEntry QLitDictEntry;
 typedef struct QLitObject QLitObject;
@@ -23,7 +24,7 @@ struct QLitObject {
 QType type;
 union {
 bool qbool;
-int64_t qnum;
+QNumValue qnum;
 const char *qstr;
 QLitDictEntry *qdict;
 QLitObject *qlist;
@@ -39,8 +40,14 @@ struct QLitDictEntry {
 { .type = QTYPE_QNULL }
 #define QLIT_QBOOL(val) \
 { .type = QTYPE_QBOOL, .value.qbool = (val) }
+#define QLIT_QNUM_INT(val) \
+{ .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_INT(val) }
+#define QLIT_QNUM_UINT(val) \
+{ .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_UINT(val) }
+#define QLIT_QNUM_DOUBLE(val) \
+{ .type = QTYPE_QNUM, .value.qnum = QNUM_VAL_DOUBLE(val) }
 #define QLIT_QNUM(val) \
-{ .type = QTYPE_QNUM, .value.qnum = (val) }
+QLIT_QNUM_INT(val)
 #define QLIT_QSTR(val) \
 { .type = QTYPE_QSTRING, .value.qstr = (val) }
 #define QLIT_QDICT(val) \
diff --git a/qobject/qlit.c b/qobject/qlit.c
index be8332136c..b23cdc4532 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -71,7 +71,8 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject 
*rhs)
 case QTYPE_QBOOL:
 return lhs->value.qbool == qbool_get_bool(qobject_to(QBool, rhs));
 case QTYPE_QNUM:
-return lhs->value.qnum ==  qnum_get_int(qobject_to(QNum, rhs));
+return qnum_value_is_equal(&lhs->value.qnum,
+   qnum_get_value(qobject_to(QNum, rhs)));
 case QTYPE_QSTRING:
 return (strcmp(lhs->value.qstr,
qstring_get_str(qobject_to(QString, rhs))) == 0);
@@ -94,7 +95,7 @@ QObject *qobject_from_qlit(const QLitObject *qlit)
 case QTYPE_QNULL:
 return QOBJECT(qnull());
 case QTYPE_QNUM:
-return QOBJECT(qnum_from_int(qlit->value.qnum));
+return QOBJECT(qnum_from_value(qlit->value.qnum));
 case QTYPE_QSTRING:
 return QOBJECT(qstring_from_str(qlit->value.qstr));
 case QTYPE_QDICT: {
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 07a773e653..711030cffd 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -796,20 +796,23 @@ static void simple_number(void)
 int i;
 struct {
 const char *encoded;
+QLitObject qlit;
 int64_t decoded;
 int skip;
 } test_cases[] = {
-{ "0", 0 },
-{ "1234", 1234 },
-{ "1", 1 },
-{ "-32", -32 },
-{ "-0", 0, .skip = 1 },
+{ "0",QLIT_QNUM(0),0, },
+{ "1234", QLIT_QNUM(1234), 1234, },
+{ "1",QLIT_QNUM(1),1, },
+{ "-32",  QLIT_QNUM(-32),  -32, },
+{ "-0",   QLIT_QNUM(0),0, .skip = 1 },
 { },
 };
 
 for (i = 0; test_cases[i].encoded; i++) {
 QNum *qnum;
 int64_t val;
+QNum *qlit_num;
+int64_t qlit_val;
 
 qnum = qobject_to(QNum,
   qobject_from_json(test_cases[i].encoded,
@@ -817,6 +820,7 @@ static void simple_number(void)
 g_assert(qnum);
 g_assert(qnum_get_try_int(qnum, &val));
 g_assert_cmpint(val, ==, test_cases[i].decoded);
+
 if (test_cases[i].skip == 0) {
 QString *str;
 
@@ -826,9 +830,66 @@ static void simple_number(void)
 }
 
 qobject_unref(qnum);
+
+qlit_num = qobject_to(QNum,
+  qobject_from_qlit(&test_cases[i].qlit));
+g_assert(qlit_num);
+g_assert(qnum_get_try_int(qlit_num, &qlit_val));
+g_assert_cmpint(qlit_val, ==, test_cases[i].decoded);
+
+qobject_unref(qlit_num);
 }
 }
 
+static void qlit_large_number(void)
+{
+QLitObject maxu64 = QLIT_QNUM_UINT(UINT64_MAX);
+QLitObject maxi64 = QLIT_QNUM(INT64_MAX);
+QLitObject mini64 = QLIT_QNUM(INT64_MIN);
+QLitObject gtu64  = QLIT_QNUM_DOUBLE(18446744073709552e3);
+QLitObject lti64  = QLIT_QNUM_DOUBLE(-92233720368547758e2);
+QNum *qnum;
+uint64_t val;
+int64_t ival;
+
+qnum = qobject_to

[PATCH v2 8/8] qom: Use qlit to represent property defaults

2020-11-16 Thread Eduardo Habkost
Using QLitObject lets us get rid of most of the
.set_default_value functions, and just use
object_property_set_default() directly.

Signed-off-by: Eduardo Habkost 
---
Changes v1 -> v2:
* Instead of initializing defval to QLIT_QNULL
  by default, just check for QTYPE_NONE, to find out if .defval
  was explicitly set.  This avoids extra complexity at
  set_prop_arraylen().
---
 include/hw/qdev-properties-system.h   |  2 +-
 include/qom/field-property-internal.h |  4 ---
 include/qom/field-property.h  | 26 ---
 include/qom/property-types.h  | 19 ++
 hw/core/qdev-properties-system.c  |  8 --
 qom/field-property.c  | 27 ++--
 qom/property-types.c  | 36 ---
 7 files changed, 42 insertions(+), 80 deletions(-)

diff --git a/include/hw/qdev-properties-system.h 
b/include/hw/qdev-properties-system.h
index 0ac327ae60..a586424a33 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -65,7 +65,7 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 
 #define DEFINE_PROP_UUID(_name, _state, _field) \
 DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID, \
-.set_default = true)
+.defval = QLIT_QSTR("auto"))
 
 #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
 DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
diff --git a/include/qom/field-property-internal.h 
b/include/qom/field-property-internal.h
index a7b7e2b69d..9bc29e9b67 100644
--- a/include/qom/field-property-internal.h
+++ b/include/qom/field-property-internal.h
@@ -15,10 +15,6 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char 
*name,
 
 void field_prop_set_default_value_enum(ObjectProperty *op,
const Property *prop);
-void field_prop_set_default_value_int(ObjectProperty *op,
-  const Property *prop);
-void field_prop_set_default_value_uint(ObjectProperty *op,
-   const Property *prop);
 
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
   void *opaque, Error **errp);
diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index 0cb1fe2217..3cfd19cc14 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -6,6 +6,7 @@
 
 #include "qom/object.h"
 #include "qapi/util.h"
+#include "qapi/qmp/qlit.h"
 
 /**
  * struct Property: definition of a field property
@@ -27,21 +28,8 @@ struct Property {
 const PropertyInfo *info;
 ptrdiff_toffset;
 uint8_t  bitnr;
-/**
- * @set_default: true if the default value should be set from @defval,
- *in which case @info->set_default_value must not be NULL
- *(if false then no default value is set by the property system
- * and the field retains whatever value it was given by instance_init).
- */
-bool set_default;
-/**
- * @defval: default value for the property. This is used only if 
@set_default
- * is true.
- */
-union {
-int64_t i;
-uint64_t u;
-} defval;
+/** @defval: If not QTYPE_NONE, the default value for the property */
+QLitObject defval;
 /* private: */
 int  arrayoffset;
 const PropertyInfo *arrayinfo;
@@ -61,7 +49,13 @@ struct PropertyInfo {
 const QEnumLookup *enum_table;
 /** @print: String formatting function, for the human monitor */
 int (*print)(Object *obj, Property *prop, char *dest, size_t len);
-/** @set_default_value: Callback for initializing the default value */
+/**
+ * @set_default_value: Optional callback for initializing the default value
+ *
+ * Most property types don't need to set this, as by default
+ * object_property_set_default() is called with the value at
+ * Property.defval.
+ */
 void (*set_default_value)(ObjectProperty *op, const Property *prop);
 /** @create: Optional callback for creation of property */
 ObjectProperty *(*create)(ObjectClass *oc, const char *name,
diff --git a/include/qom/property-types.h b/include/qom/property-types.h
index 3132ddafd9..869d1a993a 100644
--- a/include/qom/property-types.h
+++ b/include/qom/property-types.h
@@ -5,6 +5,7 @@
 #define QOM_PROPERTY_TYPES_H
 
 #include "qom/field-property.h"
+#include "qapi/qmp/qlit.h"
 
 extern const PropertyInfo prop_info_bit;
 extern const PropertyInfo prop_info_bit64;
@@ -25,34 +26,29 @@ extern const PropertyInfo prop_info_link;
 
 #define PROP_SIGNED(_state, _field, _defval, _prop, _type, ...) \
 FIELD_PROP(_state, _field, _prop, _type,\
-   .set_default = true, \
-   .defval.i= (_type)_defval,   \
+   .defval = QLIT_QNUM_INT((_

[PATCH v2 0/8] qom: Use qlit to represent property defaults

2020-11-16 Thread Eduardo Habkost
Based-on: 20201104160021.2342108-1-ehabk...@redhat.com
Git branch: https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-qlit-defaults

This extend qlit.h to support all QNum types (signed int,
unsigned int, and double), and use QLitObject to represent field
property defaults.

It allows us to get rid of most type-specific .set_default_value
functions for QOM property types.

Changes v1 -> v2:
* Rebase to latest version of field properties series
* Fix unit test failure
* Coding style changes

Eduardo Habkost (8):
  qobject: Include API docs in docs/devel/qobject.html
  qnum: Make qnum_get_double() get const pointer
  qnum: QNumValue type for QNum value literals
  qnum: qnum_value_is_equal() function
  qlit: Support all types of QNums
  qlit: qlit_type() function
  qom: Make object_property_set_default() public
  qom: Use qlit to represent property defaults

 docs/devel/index.rst  |   1 +
 docs/devel/qobject.rst|  11 +++
 include/hw/qdev-properties-system.h   |   2 +-
 include/qapi/qmp/qlit.h   |  16 +++-
 include/qapi/qmp/qnum.h   |  47 ++-
 include/qapi/qmp/qobject.h|  48 +++
 include/qom/field-property-internal.h |   4 -
 include/qom/field-property.h  |  26 +++---
 include/qom/object.h  |  11 +++
 include/qom/property-types.h  |  19 ++---
 hw/core/qdev-properties-system.c  |   8 --
 qobject/qlit.c|   5 +-
 qobject/qnum.c| 116 +++---
 qom/field-property.c  |  27 --
 qom/object.c  |   2 +-
 qom/property-types.c  |  36 ++--
 tests/check-qjson.c   |  72 ++--
 tests/check-qnum.c|  14 ++--
 18 files changed, 301 insertions(+), 164 deletions(-)
 create mode 100644 docs/devel/qobject.rst

-- 
2.28.0





[PATCH v2 7/8] qom: Make object_property_set_default() public

2020-11-16 Thread Eduardo Habkost
The function will be used outside qom/object.c, to simplify the
field property code that sets the property default value.

Signed-off-by: Eduardo Habkost 
---
 include/qom/object.h | 11 +++
 qom/object.c |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 2ab124b8f0..4234cc9b66 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1090,6 +1090,17 @@ ObjectProperty *object_class_property_add(ObjectClass 
*klass, const char *name,
   ObjectPropertyRelease *release,
   void *opaque);
 
+/**
+ * object_property_set_default:
+ * @prop: the property to set
+ * @value: the value to be written to the property
+ *
+ * Set the property default value.
+ *
+ * Ownership of @value is transferred to the property.
+ */
+void object_property_set_default(ObjectProperty *prop, QObject *value);
+
 /**
  * object_property_set_default_bool:
  * @prop: the property to set
diff --git a/qom/object.c b/qom/object.c
index 7c11bcd3b1..6b0d9d8c79 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1547,7 +1547,7 @@ static void object_property_init_defval(Object *obj, 
ObjectProperty *prop)
 visit_free(v);
 }
 
-static void object_property_set_default(ObjectProperty *prop, QObject *defval)
+void object_property_set_default(ObjectProperty *prop, QObject *defval)
 {
 assert(!prop->defval);
 assert(!prop->init);
-- 
2.28.0




[PATCH v2 1/8] qobject: Include API docs in docs/devel/qobject.html

2020-11-16 Thread Eduardo Habkost
Render existing doc comments at docs/devel/qobject.html.

Signed-off-by: Eduardo Habkost 
---
 docs/devel/index.rst   |  1 +
 docs/devel/qobject.rst | 11 +
 include/qapi/qmp/qnum.h|  4 +++-
 include/qapi/qmp/qobject.h | 48 +-
 qobject/qnum.c | 19 ---
 5 files changed, 63 insertions(+), 20 deletions(-)
 create mode 100644 docs/devel/qobject.rst

diff --git a/docs/devel/index.rst b/docs/devel/index.rst
index f10ed77e4c..1cb39a9384 100644
--- a/docs/devel/index.rst
+++ b/docs/devel/index.rst
@@ -35,3 +35,4 @@ Contents:
clocks
qom
block-coroutine-wrapper
+   qobject
diff --git a/docs/devel/qobject.rst b/docs/devel/qobject.rst
new file mode 100644
index 00..4f192ced7c
--- /dev/null
+++ b/docs/devel/qobject.rst
@@ -0,0 +1,11 @@
+QObject API
+===
+
+.. kernel-doc:: include/qapi/qmp/qobject.h
+
+QNum module
+---
+
+.. kernel-doc:: include/qapi/qmp/qnum.h
+
+.. kernel-doc:: qobject/qnum.c
diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index bbae0a5ec8..25f4733efc 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -23,7 +23,9 @@ typedef enum {
 QNUM_DOUBLE
 } QNumKind;
 
-/*
+/**
+ * DOC:
+ *
  * QNum encapsulates how our dialect of JSON fills in the blanks left
  * by the JSON specification (RFC 8259) regarding numbers.
  *
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index fcfd549220..bdc33bdb65 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -1,5 +1,5 @@
 /*
- * QEMU Object Model.
+ * QObject API
  *
  * Based on ideas by Avi Kivity 
  *
@@ -10,24 +10,31 @@
  *
  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  * See the COPYING.LIB file in the top-level directory.
+ */
+
+/**
+ * DOC: QObject Reference Counts Terminology
  *
- * QObject Reference Counts Terminology
- * 
+ * Returning references
+ * 
  *
- *  - Returning references: A function that returns an object may
- *  return it as either a weak or a strong reference.  If the
- *  reference is strong, you are responsible for calling
- *  qobject_unref() on the reference when you are done.
+ * A function that returns an object may return it as either a
+ * weak or a strong reference.  If the reference is strong, you
+ * are responsible for calling qobject_unref() on the reference
+ * when you are done.
  *
- *  If the reference is weak, the owner of the reference may free it at
- *  any time in the future.  Before storing the reference anywhere, you
- *  should call qobject_ref() to make the reference strong.
+ * If the reference is weak, the owner of the reference may free it at
+ * any time in the future.  Before storing the reference anywhere, you
+ * should call qobject_ref() to make the reference strong.
  *
- *  - Transferring ownership: when you transfer ownership of a reference
- *  by calling a function, you are no longer responsible for calling
- *  qobject_unref() when the reference is no longer needed.  In other words,
- *  when the function returns you must behave as if the reference to the
- *  passed object was weak.
+ * Transferring ownership
+ * --
+ *
+ * When you transfer ownership of a reference by calling a
+ * function, you are no longer responsible for calling
+ * qobject_unref() when the reference is no longer needed.  In
+ * other words, when the function returns you must behave as if
+ * the reference to the passed object was weak.
  */
 #ifndef QOBJECT_H
 #define QOBJECT_H
@@ -81,6 +88,8 @@ static inline void qobject_ref_impl(QObject *obj)
 
 /**
  * qobject_is_equal(): Return whether the two objects are equal.
+ * @x: QObject pointer
+ * @y: QObject pointer
  *
  * Any of the pointers may be NULL; return true if both are.  Always
  * return false if only one is (therefore a QNull object is not
@@ -90,6 +99,7 @@ bool qobject_is_equal(const QObject *x, const QObject *y);
 
 /**
  * qobject_destroy(): Free resources used by the object
+ * @obj: QObject pointer
  */
 void qobject_destroy(QObject *obj);
 
@@ -103,6 +113,7 @@ static inline void qobject_unref_impl(QObject *obj)
 
 /**
  * qobject_ref(): Increment QObject's reference count
+ * @obj: QObject pointer
  *
  * Returns: the same @obj. The type of @obj will be propagated to the
  * return type.
@@ -115,12 +126,14 @@ static inline void qobject_unref_impl(QObject *obj)
 
 /**
  * qobject_unref(): Decrement QObject's reference count, deallocate
- * when it reaches zero
+ *  when it reaches zero
+ * @obj: QObject pointer
  */
 #define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))
 
 /**
  * qobject_type(): Return the QObject's type
+ * @obj: QObject pointer
  */
 static inline QType qobject_type(const QObject *obj)
 {
@@ -130,6 +143,9 @@ static inline QType qobject_type(const QObject *obj)
 
 /**
  * qobject_check_type(): Helper f

[PATCH v2 2/8] qnum: Make qnum_get_double() get const pointer

2020-11-16 Thread Eduardo Habkost
qnum_get_double() won't change the object, the argument can be
const.

Signed-off-by: Eduardo Habkost 
---
 include/qapi/qmp/qnum.h | 2 +-
 qobject/qnum.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 25f4733efc..55c27b1c24 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -66,7 +66,7 @@ int64_t qnum_get_int(const QNum *qn);
 bool qnum_get_try_uint(const QNum *qn, uint64_t *val);
 uint64_t qnum_get_uint(const QNum *qn);
 
-double qnum_get_double(QNum *qn);
+double qnum_get_double(const QNum *qn);
 
 char *qnum_to_string(QNum *qn);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 017c8aa739..69fd9a82d9 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -154,7 +154,7 @@ uint64_t qnum_get_uint(const QNum *qn)
  *
  * qnum_get_double() loses precision for integers beyond 53 bits.
  */
-double qnum_get_double(QNum *qn)
+double qnum_get_double(const QNum *qn)
 {
 switch (qn->kind) {
 case QNUM_I64:
-- 
2.28.0




[PATCH v2 3/8] qnum: QNumValue type for QNum value literals

2020-11-16 Thread Eduardo Habkost
Provide a separate QNumValue type that can be used for QNum value
literals without the referencing counting and memory allocation
features provided by QObject.

Signed-off-by: Eduardo Habkost 
---
Changes v1 -> v2:
* Fix "make check" failure, by updating check-qnum unit test to
  use the new struct fields
---
 include/qapi/qmp/qnum.h | 40 +++--
 qobject/qnum.c  | 78 -
 tests/check-qnum.c  | 14 
 3 files changed, 84 insertions(+), 48 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 55c27b1c24..62fbdfda68 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -46,20 +46,56 @@ typedef enum {
  * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
  * convert under the hood.
  */
-struct QNum {
-struct QObjectBase_ base;
+
+/**
+ * struct QNumValue: the value of a QNum
+ *
+ * QNumValue literals can be constructed using the `QNUM_VAL_INT`,
+ * `QNUM_VAL_UINT`, and `QNUM_VAL_DOUBLE` macros.
+ */
+typedef struct QNumValue {
+/* private: */
 QNumKind kind;
 union {
 int64_t i64;
 uint64_t u64;
 double dbl;
 } u;
+} QNumValue;
+
+#define QNUM_VAL_INT(value) \
+{ .kind = QNUM_I64, .u.i64 = value }
+#define QNUM_VAL_UINT(value) \
+{ .kind = QNUM_U64, .u.u64 = value }
+#define QNUM_VAL_DOUBLE(value) \
+{ .kind = QNUM_DOUBLE, .u.dbl = value }
+
+struct QNum {
+struct QObjectBase_ base;
+QNumValue value;
 };
 
+/**
+ * qnum_from_int(): Create a new QNum from a QNumValue
+ * @value: QNumValue
+ *
+ * Return strong reference.
+ */
+QNum *qnum_from_value(QNumValue value);
+
 QNum *qnum_from_int(int64_t value);
 QNum *qnum_from_uint(uint64_t value);
 QNum *qnum_from_double(double value);
 
+/**
+ * qnum_get_value(): Get QNumValue from QNum
+ * @qn: QNum object
+ */
+static inline const QNumValue *qnum_get_value(const QNum *qn)
+{
+return &qn->value;
+}
+
 bool qnum_get_try_int(const QNum *qn, int64_t *val);
 int64_t qnum_get_int(const QNum *qn);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 69fd9a82d9..f80d4efd76 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -15,6 +15,15 @@
 #include "qemu/osdep.h"
 #include "qapi/qmp/qnum.h"
 
+QNum *qnum_from_value(QNumValue value)
+{
+QNum *qn = g_new(QNum, 1);
+
+qobject_init(QOBJECT(qn), QTYPE_QNUM);
+qn->value = value;
+return qn;
+}
+
 /**
  * qnum_from_int(): Create a new QNum from an int64_t
  * @value: int64_t value
@@ -23,13 +32,7 @@
  */
 QNum *qnum_from_int(int64_t value)
 {
-QNum *qn = g_new(QNum, 1);
-
-qobject_init(QOBJECT(qn), QTYPE_QNUM);
-qn->kind = QNUM_I64;
-qn->u.i64 = value;
-
-return qn;
+return qnum_from_value((QNumValue) QNUM_VAL_INT(value));
 }
 
 /**
@@ -40,13 +43,7 @@ QNum *qnum_from_int(int64_t value)
  */
 QNum *qnum_from_uint(uint64_t value)
 {
-QNum *qn = g_new(QNum, 1);
-
-qobject_init(QOBJECT(qn), QTYPE_QNUM);
-qn->kind = QNUM_U64;
-qn->u.u64 = value;
-
-return qn;
+return qnum_from_value((QNumValue) QNUM_VAL_UINT(value));
 }
 
 /**
@@ -57,13 +54,7 @@ QNum *qnum_from_uint(uint64_t value)
  */
 QNum *qnum_from_double(double value)
 {
-QNum *qn = g_new(QNum, 1);
-
-qobject_init(QOBJECT(qn), QTYPE_QNUM);
-qn->kind = QNUM_DOUBLE;
-qn->u.dbl = value;
-
-return qn;
+return qnum_from_value((QNumValue) QNUM_VAL_DOUBLE(value));
 }
 
 /**
@@ -75,15 +66,17 @@ QNum *qnum_from_double(double value)
  */
 bool qnum_get_try_int(const QNum *qn, int64_t *val)
 {
-switch (qn->kind) {
+const QNumValue *qv = &qn->value;
+
+switch (qv->kind) {
 case QNUM_I64:
-*val = qn->u.i64;
+*val = qv->u.i64;
 return true;
 case QNUM_U64:
-if (qn->u.u64 > INT64_MAX) {
+if (qv->u.u64 > INT64_MAX) {
 return false;
 }
-*val = qn->u.u64;
+*val = qv->u.u64;
 return true;
 case QNUM_DOUBLE:
 return false;
@@ -116,15 +109,17 @@ int64_t qnum_get_int(const QNum *qn)
  */
 bool qnum_get_try_uint(const QNum *qn, uint64_t *val)
 {
-switch (qn->kind) {
+const QNumValue *qv = &qn->value;
+
+switch (qv->kind) {
 case QNUM_I64:
-if (qn->u.i64 < 0) {
+if (qv->u.i64 < 0) {
 return false;
 }
-*val = qn->u.i64;
+*val = qv->u.i64;
 return true;
 case QNUM_U64:
-*val = qn->u.u64;
+*val = qv->u.u64;
 return true;
 case QNUM_DOUBLE:
 return false;
@@ -156,13 +151,15 @@ uint64_t qnum_get_uint(const QNum *qn)
  */
 double qnum_get_double(const QNum *qn)
 {
-switch (qn->kind) {
+const QNumValue *qv = &qn->value;
+
+switch (qv->kind) {
 case QNUM_I64:
-return qn->u.i64;
+return qv->u.

[PATCH v2 4/8] qnum: qnum_value_is_equal() function

2020-11-16 Thread Eduardo Habkost
Extract the QNum value comparison logic to a function that takes
QNumValue* as argument.

Signed-off-by: Eduardo Habkost 
---
 include/qapi/qmp/qnum.h |  1 +
 qobject/qnum.c  | 29 +++--
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index 62fbdfda68..0327ecd0f0 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -106,6 +106,7 @@ double qnum_get_double(const QNum *qn);
 
 char *qnum_to_string(QNum *qn);
 
+bool qnum_value_is_equal(const QNumValue *num_x, const QNumValue *num_y);
 bool qnum_is_equal(const QObject *x, const QObject *y);
 void qnum_destroy_obj(QObject *obj);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
index f80d4efd76..6a0f948b16 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -207,9 +207,9 @@ char *qnum_to_string(QNum *qn)
 }
 
 /**
- * qnum_is_equal(): Test whether the two QNums are equal
- * @x: QNum object
- * @y: QNum object
+ * qnum_value_is_equal(): Test whether two QNumValues are equal
+ * @num_x: QNum value
+ * @num_y: QNum value
  *
  * Negative integers are never considered equal to unsigned integers,
  * but positive integers in the range [0, INT64_MAX] are considered
@@ -217,13 +217,8 @@ char *qnum_to_string(QNum *qn)
  *
  * Doubles are never considered equal to integers.
  */
-bool qnum_is_equal(const QObject *x, const QObject *y)
+bool qnum_value_is_equal(const QNumValue *num_x, const QNumValue *num_y)
 {
-const QNum *qnum_x = qobject_to(QNum, x);
-const QNum *qnum_y = qobject_to(QNum, y);
-const QNumValue *num_x = &qnum_x->value;
-const QNumValue *num_y = &qnum_y->value;
-
 switch (num_x->kind) {
 case QNUM_I64:
 switch (num_y->kind) {
@@ -241,7 +236,7 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
 case QNUM_U64:
 switch (num_y->kind) {
 case QNUM_I64:
-return qnum_is_equal(y, x);
+return qnum_value_is_equal(num_y, num_x);
 case QNUM_U64:
 /* Comparison in native uint64_t type */
 return num_x->u.u64 == num_y->u.u64;
@@ -264,6 +259,20 @@ bool qnum_is_equal(const QObject *x, const QObject *y)
 abort();
 }
 
+/**
+ * qnum_is_equal(): Test whether the two QNums are equal
+ * @x: QNum object
+ * @y: QNum object
+ *
+ * See qnum_value_is_equal() for details on the comparison rules.
+ */
+bool qnum_is_equal(const QObject *x, const QObject *y)
+{
+const QNum *qnum_x = qobject_to(QNum, x);
+const QNum *qnum_y = qobject_to(QNum, y);
+return qnum_value_is_equal(&qnum_x->value, &qnum_y->value);
+}
+
 /**
  * qnum_destroy_obj(): Free all memory allocated by a QNum object
  *
-- 
2.28.0




Re: [PATCH for-6.0 1/6] qapi: Add query-accel command

2020-11-16 Thread Eduardo Habkost
On Mon, Nov 16, 2020 at 10:20:04AM -0600, Eric Blake wrote:
> On 11/16/20 7:10 AM, Roman Bolshakov wrote:
> > There's a problem for management applications to determine if certain
> > accelerators available. Generic QMP command should help with that.
> > 
> > Signed-off-by: Roman Bolshakov 
> > ---
> >  monitor/qmp-cmds.c | 15 +++
> >  qapi/machine.json  | 19 +++
> >  2 files changed, 34 insertions(+)
> > 
> 
> > +++ b/qapi/machine.json
> > @@ -591,6 +591,25 @@
> >  ##
> >  { 'command': 'query-kvm', 'returns': 'KvmInfo' }
> >  
> > +##
> > +# @query-accel:
> > +#
> > +# Returns information about an accelerator
> > +#
> > +# Returns: @KvmInfo
> > +#
> > +# Since: 6.0.0
> 
> We're inconsistent on whether we have 'Since: x.y' or 'Since: x.y.z',
> although I prefer the shorter form.  Maybe Markus has an opnion on that.
> 
> > +#
> > +# Example:
> > +#
> > +# -> { "execute": "query-accel", "arguments": { "name": "kvm" } }
> > +# <- { "return": { "enabled": true, "present": true } }
> > +#
> > +##
> > +{ 'command': 'query-accel',
> > +  'data': { 'name': 'str' },
> > +  'returns': 'KvmInfo' }
> 
> '@name' is undocumented and an open-coded string.  Better would be
> requiring 'name' to be one of an enum type.  [...]

This seem similar to CPU models, machine types, device types, and
backend object types: the set of valid values is derived from the
list of subtypes of a QOM type.  We don't duplicate lists of QOM
types in the QAPI schema, today.

Do we want to duplicate the list of accelerators in the QAPI
schema, or should we wait for a generic solution that works for
any QOM type?

>   [...]  Even better would be
> returning an array of KvmInfo with information on all supported
> accelerators at once, rather than making the user call this command once
> per name.

Maybe.  It would save us the work of answering the question
above, but is this (querying information for all accelerators at
once) going to be a common use case?

-- 
Eduardo




Re: Property '.hmat' not found

2020-11-16 Thread Eduardo Habkost
On Mon, Nov 16, 2020 at 01:51:37PM +0100, Philippe Mathieu-Daudé wrote:
> Cc'ing Igor & Eduardo.

Thanks!

> 
> On 11/13/20 10:17 AM, Jack wrote:
> > Hi all,
> > 
> > As I follow the document[1] to enable hmat, it fails and shows the message:
> >   qemu-system-x86_64: Property '.hmat' not found
> > 
> > My QEMU version is 5.1.90

Do you have the output of `qemu-system-x86_64 -version`, and more
information on how your binary was built?

Output of `-machine help` and `-machine pc,help` would be useful
to debug it, too.

I can't reproduce it here.  I've tested both qemu.git master
(commit cb5ed407a1dd) and v5.2.0-rc (commit 3d6e32347a3b).

  [build/(cb5ed407a1...)]$ ./qemu-system-x86_64 -version
  QEMU emulator version 5.1.91 (v5.2.0-rc1-107-gcb5ed407a1)
  Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers
  [build/(cb5ed407a1...)]$ ./qemu-system-x86_64 -machine hmat=on -m 2G -object 
memory-backend-ram,size=1G,id=m0 -object memory-backend-ram,size=1G,id=m1 -smp 
2 -numa node,nodeid=0,memdev=m0 -numa node,nodeid=1,memdev=m1,initiator=0 -numa 
cpu ,node-id=0,socket-id=0 -numa cpu,node-id=0,socket-id=1 -numa 
hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5
 -numa 
hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M
 -numa 
hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10
 -numa 
hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M
 -numa 
hmat-cache,node-id=0,size=10K,level=1,associativity=direct,policy=write-back,line=8
 -numa 
hmat-cache,node-id=1,size=10K,level=1,associativity=direct,policy=write-back,line=8
 -cpu host -vga virtio -accel kvm
  [VM boots]


> > 
> > Does anyone know why?
> > 
> > Here is my command:
> > 
> > ```
> > $ sudo qemu-system-x86_64 \
> > -machine hmat=on \
> > -m 2G \
> > -object memory-backend-ram,size=1G,id=m0 \
> > -object memory-backend-ram,size=1G,id=m1 \
> > -smp 2 \
> > -numa node,nodeid=0,memdev=m0 \
> > -numa node,nodeid=1,memdev=m1,initiator=0 \
> > -numa cpu,node-id=0,socket-id=0 \
> > -numa cpu,node-id=0,socket-id=1 \
> > -numa
> > hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=5
> > \
> > -numa
> > hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=200M
> > \
> > -numa
> > hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=10
> > \
> > -numa
> > hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=100M
> > \
> > -numa
> > hmat-cache,node-id=0,size=10K,level=1,associativity=direct,policy=write-back,line=8
> > \
> > -numa
> > hmat-cache,node-id=1,size=10K,level=1,associativity=direct,policy=write-back,line=8
> > \
> > -cpu host \
> > -m 4g -vga virtio -hda ubuntu20.04.qcow2 \
> > -nic user,model=virtio \
> > -nic tap,model=e1000 \
> > -nic tap,model=e1000 \
> > -accel kvm
> > ```
> > 
> > Thanks.
> > 
> > [1]
> > https://www.qemu.org/docs/master/system/qemu-manpage.html?highlight=numa
> > 
> > 
> > Sincerely,
> > Jack
> > 
> 

-- 
Eduardo




[PATCH v3 53/53] sev: Use class properties

2020-11-12 Thread Eduardo Habkost
Instance properties make introspection hard and are not shown by
"-object ...,help".  Convert them to class properties.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.

There was another version of this patch inside series:
  Subject: [PATCH 00/12] qom: Make all -object types use only class properties
  Message-Id: <20201009160122.1662082-1-ehabk...@redhat.com>
  
https://lore.kernel.org/qemu-devel/20201009160122.1662082-1-ehabk...@redhat.com

Changes from v1 of the patch:
* Use new object_class_property_add_field() API
  to replace object_property_add_uint32_ptr().
  (v1 used object_class_property_add_uint32_ptr(), which won't
  exist anymore)
---
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: qemu-devel@nongnu.org
---
 target/i386/sev.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index 93c4d60b82..264ea5a7fb 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -28,7 +28,7 @@
 #include "sysemu/runstate.h"
 #include "trace.h"
 #include "migration/blocker.h"
-#include "qom/object.h"
+#include "qom/qom.h"
 
 #define TYPE_SEV_GUEST "sev-guest"
 OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST)
@@ -298,6 +298,19 @@ sev_guest_class_init(ObjectClass *oc, void *data)
   sev_guest_set_session_file);
 object_class_property_set_description(oc, "session-file",
 "guest owners session parameters (encoded with base64)");
+
+object_class_property_add_field(oc, "policy",
+PROP_UINT32(SevGuestState, policy, DEFAULT_GUEST_POLICY),
+prop_allow_set_always);
+object_class_property_add_field(oc, "handle",
+PROP_UINT32(SevGuestState, handle, 0),
+prop_allow_set_always);
+object_class_property_add_field(oc, "cbitpos",
+PROP_UINT32(SevGuestState, cbitpos, 0),
+prop_allow_set_always);
+object_class_property_add_field(oc, "reduced-phys-bits",
+PROP_UINT32(SevGuestState, reduced_phys_bits, 0),
+prop_allow_set_always);
 }
 
 static void
@@ -306,16 +319,6 @@ sev_guest_instance_init(Object *obj)
 SevGuestState *sev = SEV_GUEST(obj);
 
 sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
-sev->policy = DEFAULT_GUEST_POLICY;
-object_property_add_uint32_ptr(obj, "policy", &sev->policy,
-   OBJ_PROP_FLAG_READWRITE);
-object_property_add_uint32_ptr(obj, "handle", &sev->handle,
-   OBJ_PROP_FLAG_READWRITE);
-object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos,
-   OBJ_PROP_FLAG_READWRITE);
-object_property_add_uint32_ptr(obj, "reduced-phys-bits",
-   &sev->reduced_phys_bits,
-   OBJ_PROP_FLAG_READWRITE);
 }
 
 /* sev guest info */
-- 
2.28.0




[PATCH v3 51/53] qom: PROP_* macros

2020-11-12 Thread Eduardo Habkost
The new helper macros are similar to the old DEFINE_PROP_* macros, but
don't take a name argument.  They can be used directly as argument to
object_class_property_add_field().

The DEFINE_PROP_* macros were redefined to just be wrappers to PROP_*.

Signed-off-by: Eduardo Habkost 
---
Changes v2 -> v3:
* Now the DEFINE_PROP_* macros are defined using PROP_*,
  not the other way around
* Remove unused macros (PROP_UNSIGNED*, PROP_SIGNED*, PROP_UUID)
* Removed PROP_ARRAY because it isn't as trivial as the others
* Now PROP_* won't return a pointer to a static variable anymore,
  but just a compound literal for a Property struct.

This is a new patch added in v2 of the series

---
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
Cc: Eduardo Habkost 
Cc: qemu-devel@nongnu.org
---
 include/qom/property-types.h | 141 ++-
 1 file changed, 90 insertions(+), 51 deletions(-)

diff --git a/include/qom/property-types.h b/include/qom/property-types.h
index 91b166badf..3132ddafd9 100644
--- a/include/qom/property-types.h
+++ b/include/qom/property-types.h
@@ -23,6 +23,64 @@ extern const PropertyInfo prop_info_size32;
 extern const PropertyInfo prop_info_arraylen;
 extern const PropertyInfo prop_info_link;
 
+#define PROP_SIGNED(_state, _field, _defval, _prop, _type, ...) \
+FIELD_PROP(_state, _field, _prop, _type,\
+   .set_default = true, \
+   .defval.i= (_type)_defval,   \
+   __VA_ARGS__)
+
+#define PROP_UNSIGNED(_state, _field, _defval, _prop, _type, ...) \
+FIELD_PROP(_state, _field, _prop, _type,\
+   .set_default = true, \
+   .defval.u  = (_type)_defval, \
+   __VA_ARGS__)
+
+#define PROP_BIT(_state, _field, _bit, _defval, ...) \
+FIELD_PROP(_state, _field, prop_info_bit, uint32_t, \
+   .bitnr   = (_bit),   \
+   .set_default = true, \
+   .defval.u= (bool)_defval,\
+   __VA_ARGS__)
+
+#define PROP_BIT64(_state, _field, _bit, _defval, ...) \
+FIELD_PROP(_state, _field, prop_info_bit64, uint64_t,   \
+   .bitnr= (_bit),  \
+   .set_default = true, \
+   .defval.u  = (bool)_defval,  \
+   __VA_ARGS__)
+
+#define PROP_BOOL(_state, _field, _defval, ...) \
+FIELD_PROP(_state, _field, prop_info_bool, bool,\
+   .set_default = true, \
+   .defval.u= (bool)_defval,\
+   __VA_ARGS__)
+
+#define PROP_LINK(_state, _field, _type, _ptr_type, ...) \
+FIELD_PROP(_state, _field, prop_info_link, _ptr_type,   \
+   .link_type  = _type, \
+   __VA_ARGS__)
+
+#define PROP_UINT8(_s, _f, _d, ...) \
+PROP_UNSIGNED(_s, _f, _d, prop_info_uint8, uint8_t, __VA_ARGS__)
+#define PROP_UINT16(_s, _f, _d, ...) \
+PROP_UNSIGNED(_s, _f, _d, prop_info_uint16, uint16_t, __VA_ARGS__)
+#define PROP_UINT32(_s, _f, _d, ...) \
+PROP_UNSIGNED(_s, _f, _d, prop_info_uint32, uint32_t, __VA_ARGS__)
+#define PROP_INT32(_s, _f, _d, ...) \
+PROP_SIGNED(_s, _f, _d, prop_info_int32, int32_t, __VA_ARGS__)
+#define PROP_UINT64(_s, _f, _d, ...) \
+PROP_UNSIGNED(_s, _f, _d, prop_info_uint64, uint64_t, __VA_ARGS__)
+#define PROP_INT64(_s, _f, _d, ...) \
+PROP_SIGNED(_s, _f, _d, prop_info_int64, int64_t, __VA_ARGS__)
+#define PROP_SIZE(_s, _f, _d, ...) \
+PROP_UNSIGNED(_s, _f, _d, prop_info_size, uint64_t, __VA_ARGS__)
+#define PROP_STRING(_s, _f, ...) \
+FIELD_PROP(_s, _f, prop_info_string, char*, __VA_ARGS__)
+#define PROP_ON_OFF_AUTO(_s, _f, _d, ...) \
+PROP_SIGNED(_s, _f, _d, prop_info_on_off_auto, OnOffAuto, __VA_ARGS__)
+#define PROP_SIZE32(_s, _f, _d, ...) \
+PROP_UNSIGNED(_s, _f, _d, prop_info_size32, uint32_t, __VA_ARGS__)
+
 /**
  * DEFINE_PROP: Define a #Property struct, including a property name
  *
@@ -43,33 +101,6 @@ extern const PropertyInfo prop_info_link;
.name_template = (_name),  \
__VA_ARGS__)
 
-#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
-DEFINE_PROP(_name, _state, _field, _prop, _type, \
-.set_default = true, \
-.defval.i= (_type)_defval)
-
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
-DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
-.bitnr   = (_bit),  \
-.set_default = true,\
-

[PATCH v3 50/53] qom: Delete DEFINE_PROP_*SIGNED_NODEFAULT macro

2020-11-12 Thread Eduardo Habkost
Those macros are exactly the same as DEFINE_PROP, we can use
DEFINE_PROP directly.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of this series.
---
Cc: Alex Williamson 
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
Cc: Eduardo Habkost 
Cc: Peter Maydell 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
---
 include/qom/property-types.h | 6 --
 hw/vfio/pci.c| 6 +++---
 target/arm/cpu.c | 6 +++---
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/include/qom/property-types.h b/include/qom/property-types.h
index 62551c77e0..91b166badf 100644
--- a/include/qom/property-types.h
+++ b/include/qom/property-types.h
@@ -48,9 +48,6 @@ extern const PropertyInfo prop_info_link;
 .set_default = true, \
 .defval.i= (_type)_defval)
 
-#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
-DEFINE_PROP(_name, _state, _field, _prop, _type)
-
 #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
 DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
 .bitnr   = (_bit),  \
@@ -62,9 +59,6 @@ extern const PropertyInfo prop_info_link;
 .set_default = true,   \
 .defval.u  = (_type)_defval)
 
-#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
-DEFINE_PROP(_name, _state, _field, _prop, _type)
-
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
 DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
 .bitnr= (_bit),   \
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index edfaed8c9a..f15abacbdf 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3214,9 +3214,9 @@ static Property vfio_pci_dev_properties[] = {
 DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
sub_device_id, PCI_ANY_ID),
 DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
-DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
-   nv_gpudirect_clique,
-   qdev_prop_nv_gpudirect_clique, uint8_t),
+DEFINE_PROP("x-nv-gpudirect-clique", VFIOPCIDevice,
+nv_gpudirect_clique,
+qdev_prop_nv_gpudirect_clique, uint8_t),
 DEFINE_PROP_OFF_AUTO_PCIBAR("x-msix-relocation", VFIOPCIDevice, msix_relo,
 OFF_AUTOPCIBAR_OFF),
 /*
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index cef92879b0..7cf2078622 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1106,9 +1106,9 @@ static Property arm_cpu_has_mpu_property =
  * to override that with an incorrect constant value.
  */
 static Property arm_cpu_pmsav7_dregion_property =
-DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU,
-   pmsav7_dregion,
-   prop_info_uint32, uint32_t);
+DEFINE_PROP("pmsav7-dregion", ARMCPU,
+pmsav7_dregion,
+prop_info_uint32, uint32_t);
 
 static bool arm_get_pmu(Object *obj, Error **errp)
 {
-- 
2.28.0




[PATCH v3 46/53] qdev: Move base property types to qom/property-types.c

2020-11-12 Thread Eduardo Habkost
Move all property types from qdev-properties.c to
qom/property-types.c.  Declarations are moved from
hw/qdev-properties.h to qom/property-types.h.

Signed-off-by: Eduardo Habkost 
---
Changes v2 -> v3:
* Redone after changes in previous patches in this series
* Reordered patch, tried to put it a bit earlier in the series

Changes v1 -> v2:
* Rebased after changes in previous patches in the series
---
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
Cc: Eduardo Habkost 
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h | 125 +---
 include/qom/property-types.h | 131 +
 include/qom/qom.h|   1 +
 hw/core/qdev-properties.c| 538 --
 qom/property-types.c | 546 +++
 qom/meson.build  |   1 +
 6 files changed, 680 insertions(+), 662 deletions(-)
 create mode 100644 include/qom/property-types.h
 create mode 100644 qom/property-types.c

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 6585a8e693..939b6dbf4e 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -3,130 +3,7 @@
 
 #include "hw/qdev-core.h"
 #include "qom/field-property.h"
-
-/*** qdev-properties.c ***/
-
-extern const PropertyInfo prop_info_bit;
-extern const PropertyInfo prop_info_bit64;
-extern const PropertyInfo prop_info_bool;
-extern const PropertyInfo prop_info_enum;
-extern const PropertyInfo prop_info_uint8;
-extern const PropertyInfo prop_info_uint16;
-extern const PropertyInfo prop_info_uint32;
-extern const PropertyInfo prop_info_int32;
-extern const PropertyInfo prop_info_uint64;
-extern const PropertyInfo prop_info_int64;
-extern const PropertyInfo prop_info_size;
-extern const PropertyInfo prop_info_string;
-extern const PropertyInfo prop_info_on_off_auto;
-extern const PropertyInfo prop_info_size32;
-extern const PropertyInfo prop_info_arraylen;
-extern const PropertyInfo prop_info_link;
-
-#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
-.name_template = (_name),   \
-.info  = &(_prop),   \
-.offset= offsetof(_state, _field)\
-+ type_check(_type, typeof_field(_state, _field)),   \
-__VA_ARGS__  \
-}
-
-#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
-DEFINE_PROP(_name, _state, _field, _prop, _type, \
-.set_default = true, \
-.defval.i= (_type)_defval)
-
-#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
-DEFINE_PROP(_name, _state, _field, _prop, _type)
-
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
-DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
-.bitnr   = (_bit),  \
-.set_default = true,\
-.defval.u= (bool)_defval)
-
-#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
-DEFINE_PROP(_name, _state, _field, _prop, _type,   \
-.set_default = true,   \
-.defval.u  = (_type)_defval)
-
-#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
-DEFINE_PROP(_name, _state, _field, _prop, _type)
-
-#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
-DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
-.bitnr= (_bit),   \
-.set_default = true,  \
-.defval.u  = (bool)_defval)
-
-#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \
-DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
-.set_default = true, \
-.defval.u= (bool)_defval)
-
-#define PROP_ARRAY_LEN_PREFIX "len-"
-
-/**
- * DEFINE_PROP_ARRAY:
- * @_name: name of the array
- * @_state: name of the device state structure type
- * @_field: uint32_t field in @_state to hold the array length
- * @_arrayfield: field in @_state (of type '@_arraytype *') which
- *   will point to the array
- * @_arrayprop: PropertyInfo defining what property the array elements have
- * @_arraytype: C type of the array elements
- *
- * Define device properties for a variable-length array _name.  A
- * static property "len-arrayname" is defined. When the device creator
- * sets this property to the desired length of array, further dynamic
- * properties "arrayname[0]", "arrayname[1]", ...  are defined so the
- * device creator can set the array element values. Setting the
- * "len-arrayname

[PATCH v3 52/53] tests: Use field property at check-qom-proplist test case

2020-11-12 Thread Eduardo Habkost
Use the field property system for the "sv" property used at
check-qom-proplist.

Signed-off-by: Eduardo Habkost 
---
Changes v2 -> v3:
* Don't register a instance field property, as
  object_property_add_field() is an internal API

Changes v1 -> v2:
* Use PROP_* and object_class_property_add_field() interface

---
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
Cc: Eduardo Habkost 
Cc: qemu-devel@nongnu.org
---
 tests/check-qom-proplist.c | 39 --
 1 file changed, 4 insertions(+), 35 deletions(-)

diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c
index 1b76581980..2ded6203fb 100644
--- a/tests/check-qom-proplist.c
+++ b/tests/check-qom-proplist.c
@@ -25,7 +25,7 @@
 #include "qemu/module.h"
 #include "qemu/option.h"
 #include "qemu/config-file.h"
-#include "qom/object_interfaces.h"
+#include "qom/qom.h"
 
 
 #define TYPE_DUMMY "qemu-dummy"
@@ -103,26 +103,6 @@ static int dummy_get_av(Object *obj,
 return dobj->av;
 }
 
-
-static void dummy_set_sv(Object *obj,
- const char *value,
- Error **errp)
-{
-DummyObject *dobj = DUMMY_OBJECT(obj);
-
-g_free(dobj->sv);
-dobj->sv = g_strdup(value);
-}
-
-static char *dummy_get_sv(Object *obj,
-  Error **errp)
-{
-DummyObject *dobj = DUMMY_OBJECT(obj);
-
-return g_strdup(dobj->sv);
-}
-
-
 static void dummy_init(Object *obj)
 {
 object_property_add_bool(obj, "bv",
@@ -130,12 +110,11 @@ static void dummy_init(Object *obj)
  dummy_set_bv);
 }
 
-
 static void dummy_class_init(ObjectClass *cls, void *data)
 {
-object_class_property_add_str(cls, "sv",
-  dummy_get_sv,
-  dummy_set_sv);
+object_class_property_add_field(cls, "sv",
+PROP_STRING(DummyObject, sv),
+prop_allow_set_always);
 object_class_property_add_enum(cls, "av",
"DummyAnimal",
&dummy_animal_map,
@@ -143,21 +122,11 @@ static void dummy_class_init(ObjectClass *cls, void *data)
dummy_set_av);
 }
 
-
-static void dummy_finalize(Object *obj)
-{
-DummyObject *dobj = DUMMY_OBJECT(obj);
-
-g_free(dobj->sv);
-}
-
-
 static const TypeInfo dummy_info = {
 .name  = TYPE_DUMMY,
 .parent= TYPE_OBJECT,
 .instance_size = sizeof(DummyObject),
 .instance_init = dummy_init,
-.instance_finalize = dummy_finalize,
 .class_size = sizeof(DummyObjectClass),
 .class_init = dummy_class_init,
 .interfaces = (InterfaceInfo[]) {
-- 
2.28.0




[PATCH v3 44/53] qom: Add new qom.h header

2020-11-12 Thread Eduardo Habkost
Multiple QOM features will be provided by different headers.  Add a
qom/qom.h header to make it easier to include all of them at once.

Signed-off-by: Eduardo Habkost 
---
This is a new patch added in v3 of the series.
---
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
Cc: Eduardo Habkost 
Cc: qemu-devel@nongnu.org
---
 include/qom/qom.h | 10 ++
 1 file changed, 10 insertions(+)
 create mode 100644 include/qom/qom.h

diff --git a/include/qom/qom.h b/include/qom/qom.h
new file mode 100644
index 00..3286605083
--- /dev/null
+++ b/include/qom/qom.h
@@ -0,0 +1,10 @@
+/*
+ * QEMU Object Model convenience header
+ *
+ * This header is not supposed to be included by other headers
+ * but by .c files that use QOM.
+ */
+
+#include "qom/object.h"
+#include "qom/object_interfaces.h"
+#include "qom/qom-qobject.h"
-- 
2.28.0




[PATCH v3 42/53] qdev: Reuse object_property_add_field() when adding array elements

2020-11-12 Thread Eduardo Habkost
Now that we call object_property_add() with exactly the same
arguments as object_property_add_field() does, we can just reuse
the function.  We can now use a stack variable for the new
Property struct, because object_property_add_field() will copy
the struct.

Signed-off-by: Eduardo Habkost 
---
Changes v2 -> v3:
* Fix memory leak from v2, after making
  object_property_add_field() copy the Property struct

Changes v1 -> v2:
* Now we don't need to hack ObjectProperty.release anymore,
  patch became trivial
---
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
Cc: Eduardo Habkost 
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 451bb54cf6..83fd45add0 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -576,23 +576,17 @@ static void set_prop_arraylen(Object *obj, Visitor *v, 
const char *name,
 *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
 for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
 g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
-Property *arrayprop = g_new0(Property, 1);
-ObjectProperty *elmop;
-arrayprop->info = prop->arrayinfo;
+Property arrayprop = { };
+arrayprop.info = prop->arrayinfo;
 /* This ugly piece of pointer arithmetic sets up the offset so
  * that when the underlying get/set hooks call qdev_get_prop_ptr
  * they get the right answer despite the array element not actually
  * being inside the device struct.
  */
-arrayprop->offset = eltptr - (void *)obj;
-assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
-elmop = object_property_add(obj, propname,
-arrayprop->info->name,
-field_prop_getter(arrayprop->info),
-field_prop_setter(arrayprop->info),
-static_prop_release_dynamic_prop,
-arrayprop);
-elmop->allow_set = op->allow_set;
+arrayprop.offset = eltptr - (void *)obj;
+assert(object_field_prop_ptr(obj, &arrayprop) == eltptr);
+object_property_add_field(obj, propname, &arrayprop,
+  op->allow_set);
 }
 }
 
-- 
2.28.0




<    2   3   4   5   6   7   8   9   10   11   >