Re: [Qemu-devel] [PATCH v3] hw: net: cadence_gem: Fix build errors in DB_PRINT()

2019-08-18 Thread Jason Wang


On 2019/8/19 下午1:24, Bin Meng wrote:
> On Sat, Aug 10, 2019 at 9:58 AM Alistair Francis  wrote:
>> On Fri, Aug 9, 2019 at 12:26 AM Bin Meng  wrote:
>>> When CADENCE_GEM_ERR_DEBUG is turned on, there are several
>>> compilation errors in DB_PRINT(). Fix them.
>>>
>>> While we are here, update to use appropriate modifiers in
>>> the same DB_PRINT() call.
>>>
>>> Signed-off-by: Bin Meng 
>> Reviewed-by: Alistair Francis 
>>
> Ping?
>
> What's the status of this patch?
>
> Regards,
> Bin


Applied.

Thanks




[Qemu-devel] [PATCH v4 23/28] riscv: roms: Update default bios for sifive_u machine

2019-08-18 Thread Bin Meng
With the support of heterogeneous harts and PRCI model, it's now
possible to use the OpenSBI image (PLATFORM=sifive/fu540) built
for the real hardware.

Signed-off-by: Bin Meng 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin 40968 -> 45064 bytes
 roms/Makefile|   4 ++--
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin 
b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
index 
5d7a1ef6818994bac4a36818ad36043b592ce309..eb22aefdfb468cfe2804cb4b0bc422d8ebcae93b
 100644
GIT binary patch
delta 10830
zcmcI~eOOf0_WwTTaAp|5zy=s$G)G2;B$Y8xQwsqZMktj?Fen8a(7-p07sHnZ7-n!l
zMBCydW6I@gkn_7)_3KlO(VPJ-_F<-9NtbxZHEj
z{_M5aUTf{O*51R;dU|IYeF9VCYY-ChyTdf=_$;$t$%-!FBh)PF2YiLnP#RtlO4
zf`7%(Y^=BI*)uVqWvTi1HA8ri}M#lXXVj799nsK;XrsM6yhpfDIJrX~XyC
z2!|6CowN*ZcY7WO@m?9<2q^Y_gGC}=pjE1PeV*?)24lA+F1Veyny!q&5qy)IT**
z9rPutBL0(>5I47X9AAARDRjwiGOa}(Juz}vMdK*G692<-3vK0Nnc&)lwu}o}=nauO
zcZ?TY@G#q+qP_71r*$d=x5^cU{Rm;*npek1)(iPIr(~VJW~mN-36_!SG&$4uS~~N
zonLU~df7CKT(SnQcb*l>JuB8)tVcB(J|0hh;{4>3FrF7NUbBFQV#_`kT`g;OzrM@A#ALL{
zFTU_?J|jALA1rVijEu5Z$42A<$HLllzdOpW)s4KC2e>p^Za^`^qUJBC{Py4!EA
zutuzHbf2QIpb(0@8y_(H6QcRl+ZIXQ6a)AlE~>f3d6UUogxm|
z*kzH_OU(7-Ptx?B#rQ4vb~<{#`E`#i4*hXk`_T9gC`6$aZcQh)
zV{dOMfP%ff7aUy+I6J_`D7soZ)`!j_sahQuzb>@g*xD?yR~LRZ00n1kc|r)?_U(B6Tyr^792v7v?!|R
zf-X*H>-Ak>>vO=8IlS+h~Y>Fke_l-#wN!wf;{Zxr>5mD#b1Oqq6nuJjfiZDAe
z9+1=DnQRAk$Jl_kV#a`T?ZBk~oPtk`As5?`i^q`D?Z`!d^u$S$QJ%qeWbhbriXHhJ
zAf2(>lu=}m9T_x+^t2;q021N)F{Hm8=|6^awj+HkZq{s^;WNrpVn<5GkjRb{0Wuv+
zq@zerJJNFu*=I+(05TC@97DR;kuGD%yLKc6$mKY1>L^dzj-IBGR@o5jR~9$w0|D(-07zoZw)HjrO(kIKH(9^=JO?UhKu_4FYHvMB-U9Ol5;Tb}yi`Px~pI?{-$hQJQaxrTZ@pusP*TeGUMh6zDgaSIhCttB64
zLcHG{g7y88>$M?kY`UHRT@UV5Dc67>GK61lF|?rnXMP
zS~hy~8X=D-nafgcAga@-Ahnk(7C>)hYpvH!N>PxPz1im`ud8~frT;?jCF_-*Yqx*y
zY;RjLl-|Fw7YY9Dhk}?!5ydp~DNUo=k7AnUQko_u<-=+kR#5S!pR-K!TIzi1Y97f
zbiRV)XkFOKPU~<>8)TZo5!1XJX_~T-ra1+PJ#~~=#HZqSt7CT?4Mk|>ZZVJNR!#Ci
zv_z~@uslOHNT_8Khyd34{(2ES3t4SEOns6}*`hUY{yKdr*CHy{B-^+yxVgj4h;RA
zzZQn^o5RdQp^GV6jd8@HIQn=cKD1~TeWMId4}ZyFVcu__;F;mU_*A$Hy=)MF8Gesm
z)`S14*h)`s#nrKMaC(F%?Rpv)L`(ex{FqhxaI3XiF1*eQ_LJ_67cU@tgFr
z&+yZc-2rK^X8qAGM9>NaM|XljU<~BJfrF~O%|0o?<{Em*3VS4gI6(N~BEJVXXIY
zOWUTyB6tr4?;UrQR%tdE(B(3lr=;G-3DJ|L+01*((zeWKLw0wLB60JBkv=<`?ZlPQ
zVljvAx@l>1HQ45>X|r*AzYSlBe(+*0$e@q>#*hVVVfZ)Tac#@Anpy#pY0ce!6q!Lf
z|H0Rmwr{kVDBA7c{vkmG?=N`1+2{9kKa{L7KBG`>WXXiTek1?JU9ngub
zuN)A{qbI8-v2J)E7l~GoH7X_e;PTf%XEX7`<-K%31GdIy^PvlzmBs7h-k`tv#C#>L
zfTqhzaYFngkGTj18@lPWlD*J3eaQ
zjKSXH*Nxp@*96+1);^NTk37_W5+B=l2BIV}2e>FMDv}*sqbZh3v0
zhwZx$^bQR;7*dG33MJTarAo#1bbJ4KT=Rs3D%vAAKe#+!Iq{s%A(vd$;Gi
zs!3mofQOJ@<2hjwDI_U{>QOf*f$hDYJHD`TN<3hsAJ#lc#z{Y|apT&5)Vlq_rEIc{
z+o^I){_~9LkI4vJ#2xTIu0aB_s7PV^*1P^9tvre%YcXr3
z!JX?}AK;LT8H{Alvp6HegOMX=yfb4KQ|~$SU>c1Jr_cHvL`m&$!gw4|c_ZAM{
zEQK}~r*D3bsSmh~o!-2|)E_@X%g-;b0}?Hw=p)
zga~=n?c5o`s%{_O$oMr3?^UYk2M!``MCwhzzxPMHtPM}h-oZ#N?@0~txi9DFHz
z79a3ftGI-na$*@t(kpm%|1#u7I_MF9Z;vk;BWjd|y#|c|rU?gn|amAKb
zKzMg--4a8qhjI8@DtJ8;o8DT$NZeR_`>h-BJQ26#PMIR9%rX_KUSrXnx@s*IK@M_x
znWn;y2zF?x)^Z}T6}xQpp>K3y`PM0nB*Yyr-wM*TrQ_nQbAm?B83k~fEcQaGi$M(g
z0gOJ8cq35Y8#)|xx^QZ!SF2FqfmB}yQBa-fAPb*3d=>X@okJ&{#?!YwOW!z!leWb?
zb>kzuE(T?gmVt?NS>KHFrb0;9CnkT0FK+XZ9R84`Q0dIhhvuSAq}nt@w9Rsm^tR2NC}O@*eSju7_Ij)Ym2P$bU7RXY@n+lh7f?v9nh
zd0-yBAWFy!AH2pL36q34;q5on{zV$42gN8@idhV`QiLBR_RvyB1D`ryX71)w#{D{o
z`}uxCHiK5}=%Y0eMTl8!K$^w1h*8ua=%>UJ94YfH9vO+uw>+uyyYppd-h)%nYXbWPLYZ0I+ak(QAlH;+>EZQc13jNSmr(f0^WnJ16b33jx5A2~)!ZuUDcKb32~r1!`PH=
z+iFA$SIds+ak-jL=kKj97i#si*hxp9EVi6*{RxgvPfI@-026{an~6EWjLk>Dn_!p1
zHo97Rxzx6O3Ow@n#_6id1GSNq<;12RjYUpKc%=v|Rg7Zv;>+NDuNG5cVr|c2idc!*
z=A1^D;Kc1?*p)05Stj=6QNpbcUGakluC2RYE)#nflO2Zw??zBp%cMslDQVRJt!ZpP
z4DqTa2QZPl%{1Ututr+bJeB6w2;v#{^Wfk`PA9RPy+?QZ)zZK5AA`0IpD}T9+;0XWNGC-@r4${g2x;-N-t164m
zZBGkJuS%Z+R*m0WWv%YH(0QpXZfLbt*V}SCp?_8Hnx6FA8$0tRm>H|za(4M^zL7tzz1*mqhpNke
ztB{^Jg+7!~Bxw
zVhOhmx?U|4i%U@8FKa2`4|-US9@MI*q(|0pczjjx7#tgPuMk3r}-MxLR<@6P16Lf2ChYH%QW^v
zpyPqfJCX6=F3Q~VHRL0(H)ze=viW;V`!4O%Mu38~z9j>~AN3H3^ho%f
zp24r`8KD8_ih#l*c#acrsY6X-63Mq=6G(>r+=Ij?vQtT}_3;#cr>BHJ3h36dDo^99
zdJ4x1=$FebmkF=vX(7o!1rtWOtajwaUllNfTRTfQ!ERy*w=f=Y%GR>adBWTQ
z*O$wx1eeQv)B2zCk_vt5*oi`-wCDA>hEf4wYkLfkx
zETxHp2p{E3F)z-hAOqj@I{(KwLa!r{1kBTRyhnBQC~WdV%2)xRw<{JXl@fcai;=lY
zK^1tsBgo%-0S+K+L`ylb=Sbelx*f4g>Q-*9YLg8`^)Ky>vFbYGdh#6o^)rj1e6-%U
zW-9bLU!BB*+nTW4_N=O0dTV=nGE8_$E95l{l4%2a{EH`@hoZT%?j|E^7(}=(mdT
zvdtBy;(Qq;yQJny+mRwup<-C9^F|kl^(qhlYeTJOYQtb`?WE0Bx2rps4#o7x^(I(X
z_2_z9+Vb2?`eVh!jB#Lp
zs35?G5ZAdt1h#`fSd*DuI1~j(0!w9L+n@U$H&$Fv!fjnAF*oZ?f%Os`YV`;cK~0YEaT3
zk&;;KhEDqYk%zMzK}mx|D^c17f;kjXl}%GbOBU<#9#f&1FF=Zc-$Rq03e^Y)?z=+3
z_JYj?S|hh9woJ&(EgS^B3@+8Z{sri4@RIgJesH;^^2T>(YK3Zk;ot>MO~mmQ?ll!o
z8-`T^_>y)O3*PYUQKBllrg%f7zTr+V*25oBk9j=N4(2rsErok;a$ytj&;xAUFl5r^
zM~nlPlWAvx=<^-y@tpebo&^e|$Bn#u#f{kFIlRZ^G?7M{dgEIpA=K|Ig<2?O9>D
zHlGh$mrT4Kemk;H+@gwOoxskM`i96(;NH6BJ+F;qrZo(bH!^JtX_Wvad
zYI5itJ#g0D!(Rt^Lxl`ydF$Z=UX71OblaMew!oqI(O;_tTFMvjd_zh8%a4H5Y}4c1

Re: [Qemu-devel] [PATCH v2 1/2] memory-device: not necessary to use goto for the last check

2019-08-18 Thread Zeng, Star



> -Original Message-
> From: Wei Yang [mailto:richardw.y...@linux.intel.com]
> Sent: Monday, August 19, 2019 10:39 AM
> To: David Hildenbrand 
> Cc: Wei Yang ; Zeng, Star
> ; imamm...@redhat.com; qemu-devel@nongnu.org;
> m...@redhat.com
> Subject: Re: [Qemu-devel] [PATCH v2 1/2] memory-device: not necessary to
> use goto for the last check
> 
> On Thu, Aug 08, 2019 at 09:06:21AM +0200, David Hildenbrand wrote:
> >On 08.08.19 04:38, Wei Yang wrote:
> >> On Thu, Aug 08, 2019 at 02:30:02AM +, Zeng, Star wrote:
>  -Original Message-
>  From: Wei Yang [mailto:richardw.y...@linux.intel.com]
>  Sent: Thursday, August 8, 2019 10:13 AM
>  To: Zeng, Star 
>  Cc: Wei Yang ;
>  qemu-devel@nongnu.org; imamm...@redhat.com;
> da...@redhat.com;
>  m...@redhat.com
>  Subject: Re: [Qemu-devel] [PATCH v2 1/2] memory-device: not
>  necessary to use goto for the last check
> 
>  On Thu, Aug 08, 2019 at 01:42:14AM +, Zeng, Star wrote:
> >> -Original Message-
> >> From: Qemu-devel [mailto:qemu-devel-
> >> bounces+star.zeng=intel@nongnu.org] On Behalf Of Wei Yang
> >> Sent: Tuesday, July 30, 2019 8:38 AM
> >> To: qemu-devel@nongnu.org
> >> Cc: imamm...@redhat.com; da...@redhat.com; Wei Yang
> >> ; m...@redhat.com
> >> Subject: [Qemu-devel] [PATCH v2 1/2] memory-device: not
> necessary
> >> to use goto for the last check
> >>
> >> We are already at the last condition check.
> >>
> >> Signed-off-by: Wei Yang 
> >> Reviewed-by: Igor Mammedov 
> >> Reviewed-by: David Hildenbrand 
> >> ---
> >>  hw/mem/memory-device.c | 1 -
> >>  1 file changed, 1 deletion(-)
> >>
> >> diff --git a/hw/mem/memory-device.c b/hw/mem/memory-
> device.c
>  index
> >> 5f2c408036..df3261b32a 100644
> >> --- a/hw/mem/memory-device.c
> >> +++ b/hw/mem/memory-device.c
> >> @@ -186,7 +186,6 @@ static uint64_t
> >> memory_device_get_free_addr(MachineState *ms,
> >>  if (!range_contains_range(, )) {
> >>  error_setg(errp, "could not find position in guest address 
> >> space
> for "
> >> "memory device - memory fragmented due to
> alignments");
> >> -goto out;
> >
> > Is it better to return 0 (or set new_addr to 0) for this error
> > path and another
>  remaining "goto out" path?
> >
> 
>  I may not get your point.
> 
>  We set errp which is handled in its caller. By doing so, the error is
> propagated.
> 
>  Do I miss something?
> >>>
> >>> Yes, you are right. Currently, the caller is checking errp, but not the
> returned address, so there should be no issue.
> >>> But when you see other error paths, you will find they all return 0.
> >>> To be aligned (return 0 when error), so just suggest also returning
> >>> 0 for these two "goto out" error path. :)
> >>>
> >>
> >> You may have some point.
> >>
> >> Let's see whether others have the same taste, or we can refine it
> separately.
> >>
> >
> >I don't think that's necessary (callers really should check for errors
> >before using the return values), but I would also not object to that change.
> >
> 
> In case there is no strong requirement to refactor the code. I would leave it
> here.

It was just my suggestion. I am fine with any preference you and other experts 
have.

Thanks,
Star

> 
> >--
> >
> >Thanks,
> >
> >David / dhildenb
> 
> --
> Wei Yang
> Help you, Help me



[Qemu-devel] [PATCH v4 26/28] riscv: sifive_u: Fix broken GEM support

2019-08-18 Thread Bin Meng
At present the GEM support in sifive_u machine is seriously broken.
The GEM block register base was set to a weird number (0x100900FC),
which for no way could work with the cadence_gem model in QEMU.

Not like other GEM variants, the FU540-specific GEM has a management
block to control 10/100/1000Mbps link speed changes, that is mapped
to 0x100a. We can simply map it into MMIO space without special
handling using create_unimplemented_device().

Update the GEM node compatible string to use the official name used
by the upstream Linux kernel, and add the management block reg base
& size to the  property encoding.

Tested with upstream U-Boot and Linux kernel MACB drivers.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v4: None
Changes in v3: None
Changes in v2:
- use create_unimplemented_device() to create the GEM management
  block instead of sifive_mmio_emulate()
- add "phy-handle" property to the ethernet node

 hw/riscv/sifive_u.c | 21 +
 include/hw/riscv/sifive_u.h |  3 ++-
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index d66a7e8..7a370e9 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
  * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Bin Meng 
  *
  * Provides a board compatible with the SiFive Freedom U SDK:
  *
@@ -11,6 +12,7 @@
  * 2) PLIC (Platform Level Interrupt Controller)
  * 3) PRCI (Power, Reset, Clock, Interrupt)
  * 4) OTP (One-Time Programmable) memory with stored serial number
+ * 5) GEM (Gigabit Ethernet Controller) and management block
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -39,6 +41,7 @@
 #include "hw/sysbus.h"
 #include "hw/char/serial.h"
 #include "hw/cpu/cluster.h"
+#include "hw/misc/unimp.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
@@ -70,7 +73,8 @@ static const struct MemmapEntry {
 [SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_OTP] =  { 0x1007, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
-[SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
+[SIFIVE_U_GEM] =  { 0x1009, 0x2000 },
+[SIFIVE_U_GEM_MGMT] = { 0x100a, 0x1000 },
 };
 
 #define SIFIVE_OTP_SERIAL   1
@@ -87,7 +91,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char ethclk_names[] = "pclk\0hclk";
 uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
-uint32_t hfclk_phandle, rtcclk_phandle;
+uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
 if (!fdt) {
@@ -257,15 +261,20 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
+phy_phandle = phandle++;
 nodename = g_strdup_printf("/soc/ethernet@%lx",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "cdns,macb");
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"sifive,fu540-c000-gem");
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_GEM].base,
-0x0, memmap[SIFIVE_U_GEM].size);
+0x0, memmap[SIFIVE_U_GEM].size,
+0x0, memmap[SIFIVE_U_GEM_MGMT].base,
+0x0, memmap[SIFIVE_U_GEM_MGMT].size);
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
+qemu_fdt_setprop_cell(fdt, nodename, "phy-handle", phy_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
@@ -279,6 +288,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", phy_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
@@ -527,6 +537,9 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>gem), 0, memmap[SIFIVE_U_GEM].base);
 sysbus_connect_irq(SYS_BUS_DEVICE(>gem), 0,
plic_gpios[SIFIVE_U_GEM_IRQ]);
+
+create_unimplemented_device("riscv.sifive.u.gem-mgmt",
+memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
 }
 
 static void riscv_sifive_u_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_u.h 

[Qemu-devel] [Bug 1772165] Re: arm raspi2/raspi3 emulation has no USB support

2019-08-18 Thread Weber Kai via Qemu-devel
Hi!

I've googled: "usb" "designware" "otg" "datasheet"

I think this is the kernel driver for this device:
https://github.com/torvalds/linux/tree/master/drivers/usb/dwc3

Maybe it should be possible to use this as a reference? Maybe try to
redirect the proprietary drivers system calls? I don't know...

I've also found theses docs, which explains the device a little bit:
http://www.infradead.org/~mchehab/kernel_docs_pdf/driver-api.pdf
https://media.digikey.com/pdf/Data%20Sheets/Austriamicrosystems%20PDFs/AS3524.pdf
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/arria-10/a10_54018.pdf

Thanks.

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

Title:
  arm raspi2/raspi3 emulation has no USB support

Status in QEMU:
  Confirmed

Bug description:
  Using Qemu 2.12.0 on ArchLinux.

  Trying to emulate arm device with `qemu-system-arm` and attach usb
  device for unput using

  ` -usb -device usb-host,bus=001,vendorid=0x1d6b,productid=0x0002 `

  # lsusb returns

  Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
  Bus 001 Device 014: ID 13d3:3487 IMC Networks 
  Bus 001 Device 004: ID 0457:11af Silicon Integrated Systems Corp. 
  Bus 001 Device 003: ID 0bda:57e6 Realtek Semiconductor Corp. 
  Bus 001 Device 002: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card 
Reader Controller
  Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

  # qemu returns
  qemu-system-arm: -device usb-host,bus=001,vendorid=0x1d6b,productid=0x0002: 
Bus '001' not found

  
  Tried with connecting external usb keyboard but that didn't seem to work 
either.

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



[Qemu-devel] [PATCH v4 21/28] riscv: sifive_u: Update UART base addresses and IRQs

2019-08-18 Thread Bin Meng
This updates the UART base address and IRQs to match the hardware.

Signed-off-by: Bin Meng 
Reviewed-by: Jonathan Behrens 
Acked-by: Alistair Francis 
Reviewed-by: Chih-Min Chao 

---

Changes in v4: None
Changes in v3:
- update IRQ numbers of both UARTs to match hardware as well

Changes in v2: None

 hw/riscv/sifive_u.c | 4 ++--
 include/hw/riscv/sifive_u.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 8818fd6..a85db77 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -64,8 +64,8 @@ static const struct MemmapEntry {
 [SIFIVE_U_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
 [SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
-[SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
-[SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
+[SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
+[SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
 [SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
 };
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 0ec04df..9acb69e 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -62,8 +62,8 @@ enum {
 };
 
 enum {
-SIFIVE_U_UART0_IRQ = 3,
-SIFIVE_U_UART1_IRQ = 4,
+SIFIVE_U_UART0_IRQ = 4,
+SIFIVE_U_UART1_IRQ = 5,
 SIFIVE_U_GEM_IRQ = 0x35
 };
 
-- 
2.7.4




[Qemu-devel] [PATCH v4 27/28] riscv: sifive_u: Remove handcrafted clock nodes for UART and ethernet

2019-08-18 Thread Bin Meng
In the past we did not have a model for PRCI, hence two handcrafted
clock nodes ("/soc/ethclk" and "/soc/uartclk") were created for the
purpose of supplying hard-coded clock frequencies. But now since we
have added the PRCI support in QEMU, we don't need them any more.

Signed-off-by: Bin Meng 

---

Changes in v4:
- new patch to remove handcrafted clock nodes for UART and ethernet

Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 24 +---
 include/hw/riscv/sifive_u.h |  3 +--
 2 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 7a370e9..7d9fb3a 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -89,8 +89,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 uint32_t *cells;
 char *nodename;
 char ethclk_names[] = "pclk\0hclk";
-uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
-uint32_t uartclk_phandle;
+uint32_t plic_phandle, prci_phandle, phandle = 1;
 uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
@@ -250,17 +249,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(cells);
 g_free(nodename);
 
-ethclk_phandle = phandle++;
-nodename = g_strdup_printf("/soc/ethclk");
-qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
-qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
-SIFIVE_U_GEM_CLOCK_FREQ);
-qemu_fdt_setprop_cell(fdt, nodename, "phandle", ethclk_phandle);
-ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
-g_free(nodename);
-
 phy_phandle = phandle++;
 nodename = g_strdup_printf("/soc/ethernet@%lx",
 (long)memmap[SIFIVE_U_GEM].base);
@@ -292,16 +280,6 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
-uartclk_phandle = phandle++;
-nodename = g_strdup_printf("/soc/uartclk");
-qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
-qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 3686400);
-qemu_fdt_setprop_cell(fdt, nodename, "phandle", uartclk_phandle);
-uartclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
-g_free(nodename);
-
 nodename = g_strdup_printf("/soc/serial@%lx",
 (long)memmap[SIFIVE_U_UART0].base);
 qemu_fdt_add_subnode(fdt, nodename);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index cba29e1..8880f9c 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -72,8 +72,7 @@ enum {
 enum {
 SIFIVE_U_CLOCK_FREQ = 10,
 SIFIVE_U_HFCLK_FREQ = ,
-SIFIVE_U_RTCCLK_FREQ = 100,
-SIFIVE_U_GEM_CLOCK_FREQ = 12500
+SIFIVE_U_RTCCLK_FREQ = 100
 };
 
 #define SIFIVE_U_MANAGEMENT_CPU_COUNT   1
-- 
2.7.4




[Qemu-devel] [PATCH v4 28/28] riscv: sifive_u: Update model and compatible strings in device tree

2019-08-18 Thread Bin Meng
This updates model and compatible strings to use the same strings
as used in the Linux kernel device tree (hifive-unleashed-a00.dts).

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 7d9fb3a..c5cc4bd 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -98,8 +98,9 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 exit(1);
 }
 
-qemu_fdt_setprop_string(fdt, "/", "model", "ucbbar,spike-bare,qemu");
-qemu_fdt_setprop_string(fdt, "/", "compatible", "ucbbar,spike-bare-dev");
+qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed A00");
+qemu_fdt_setprop_string(fdt, "/", "compatible",
+"sifive,hifive-unleashed-a00");
 qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
 qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
 
-- 
2.7.4




[Qemu-devel] [PATCH v4 17/28] riscv: sifive: Implement PRCI model for FU540

2019-08-18 Thread Bin Meng
This adds a simple PRCI model for FU540 (sifive_u). It has different
register layout from the existing PRCI model for FE310 (sifive_e).

Signed-off-by: Bin Meng 

---

Changes in v4:
- prefix all macros/variables/functions with SIFIVE_U/sifive_u
  in the sifive_u_prci driver

Changes in v3: None
Changes in v2: None

 hw/riscv/Makefile.objs   |   1 +
 hw/riscv/sifive_u_prci.c | 165 +++
 include/hw/riscv/sifive_u_prci.h |  90 +
 3 files changed, 256 insertions(+)
 create mode 100644 hw/riscv/sifive_u_prci.c
 create mode 100644 include/hw/riscv/sifive_u_prci.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index c859697..b95bbd5 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
+obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_uart.o
 obj-$(CONFIG_SPIKE) += spike.o
 obj-$(CONFIG_RISCV_VIRT) += virt.o
diff --git a/hw/riscv/sifive_u_prci.c b/hw/riscv/sifive_u_prci.c
new file mode 100644
index 000..578c643
--- /dev/null
+++ b/hw/riscv/sifive_u_prci.c
@@ -0,0 +1,165 @@
+/*
+ * QEMU SiFive U PRCI (Power, Reset, Clock, Interrupt)
+ *
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * Simple model of the PRCI to emulate register reads made by the SDK BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qemu/module.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_u_prci.h"
+
+static uint64_t sifive_u_prci_read(void *opaque, hwaddr addr, unsigned int 
size)
+{
+SiFiveUPRCIState *s = opaque;
+
+switch (addr) {
+case SIFIVE_U_PRCI_HFXOSCCFG:
+return s->hfxosccfg;
+case SIFIVE_U_PRCI_COREPLLCFG0:
+return s->corepllcfg0;
+case SIFIVE_U_PRCI_DDRPLLCFG0:
+return s->ddrpllcfg0;
+case SIFIVE_U_PRCI_DDRPLLCFG1:
+return s->ddrpllcfg1;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG0:
+return s->gemgxlpllcfg0;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG1:
+return s->gemgxlpllcfg1;
+case SIFIVE_U_PRCI_CORECLKSEL:
+return s->coreclksel;
+case SIFIVE_U_PRCI_DEVICESRESET:
+return s->devicesreset;
+case SIFIVE_U_PRCI_CLKMUXSTATUS:
+return s->clkmuxstatus;
+}
+
+hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
+return 0;
+}
+
+static void sifive_u_prci_write(void *opaque, hwaddr addr,
+uint64_t val64, unsigned int size)
+{
+SiFiveUPRCIState *s = opaque;
+
+switch (addr) {
+case SIFIVE_U_PRCI_HFXOSCCFG:
+s->hfxosccfg = (uint32_t) val64;
+/* OSC stays ready */
+s->hfxosccfg |= SIFIVE_U_PRCI_HFXOSCCFG_RDY;
+break;
+case SIFIVE_U_PRCI_COREPLLCFG0:
+s->corepllcfg0 = (uint32_t) val64;
+/* internal feedback */
+s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
+/* PLL stays locked */
+s->corepllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_U_PRCI_DDRPLLCFG0:
+s->ddrpllcfg0 = (uint32_t) val64;
+/* internal feedback */
+s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
+/* PLL stays locked */
+s->ddrpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_U_PRCI_DDRPLLCFG1:
+s->ddrpllcfg1 = (uint32_t) val64;
+break;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG0:
+s->gemgxlpllcfg0 = (uint32_t) val64;
+ /* internal feedback */
+s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_FSE;
+   /* PLL stays locked */
+s->gemgxlpllcfg0 |= SIFIVE_U_PRCI_PLLCFG0_LOCK;
+break;
+case SIFIVE_U_PRCI_GEMGXLPLLCFG1:
+s->gemgxlpllcfg1 = (uint32_t) val64;
+break;
+case SIFIVE_U_PRCI_CORECLKSEL:
+s->coreclksel = (uint32_t) val64;
+break;
+case SIFIVE_U_PRCI_DEVICESRESET:
+s->devicesreset = (uint32_t) val64;
+break;
+case SIFIVE_U_PRCI_CLKMUXSTATUS:
+s->clkmuxstatus = (uint32_t) val64;
+break;
+default:
+hw_error("%s: bad write: addr=0x%x v=0x%x\n",
+ __func__, (int)addr, (int)val64);
+}
+}
+
+static const MemoryRegionOps sifive_u_prci_ops = {
+.read = sifive_u_prci_read,
+.write = 

[Qemu-devel] [PATCH v4 18/28] riscv: sifive_u: Generate hfclk and rtcclk nodes

2019-08-18 Thread Bin Meng
To keep in sync with Linux kernel device tree, generate hfclk and
rtcclk nodes in the device tree, to be referenced by PRCI node.

Signed-off-by: Bin Meng 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 23 +++
 include/hw/riscv/sifive_u.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 284f7a5..08db741 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -80,6 +80,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char ethclk_names[] = "pclk\0hclk\0tx_clk";
 uint32_t plic_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
+uint32_t hfclk_phandle, rtcclk_phandle;
 
 fdt = s->fdt = create_device_tree(>fdt_size);
 if (!fdt) {
@@ -98,6 +99,28 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
 qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
 
+hfclk_phandle = phandle++;
+nodename = g_strdup_printf("/hfclk");
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", hfclk_phandle);
+qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "hfclk");
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+SIFIVE_U_HFCLK_FREQ);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
+g_free(nodename);
+
+rtcclk_phandle = phandle++;
+nodename = g_strdup_printf("/rtcclk");
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", rtcclk_phandle);
+qemu_fdt_setprop_string(fdt, nodename, "clock-output-names", "rtcclk");
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+SIFIVE_U_RTCCLK_FREQ);
+qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
+g_free(nodename);
+
 nodename = g_strdup_printf("/memory@%lx",
 (long)memmap[SIFIVE_U_DRAM].base);
 qemu_fdt_add_subnode(fdt, nodename);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 7a1a4f3..debbf28 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -68,6 +68,8 @@ enum {
 
 enum {
 SIFIVE_U_CLOCK_FREQ = 10,
+SIFIVE_U_HFCLK_FREQ = ,
+SIFIVE_U_RTCCLK_FREQ = 100,
 SIFIVE_U_GEM_CLOCK_FREQ = 12500
 };
 
-- 
2.7.4




[Qemu-devel] [PATCH v4 19/28] riscv: sifive_u: Add PRCI block to the SoC

2019-08-18 Thread Bin Meng
Add PRCI mmio base address and size mappings to sifive_u machine,
and generate the corresponding device tree node.

Signed-off-by: Bin Meng 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 21 -
 include/hw/riscv/sifive_u.h |  1 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 08db741..bd5551c 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -9,6 +9,7 @@
  * 0) UART
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
+ * 3) PRCI (Power, Reset, Clock, Interrupt)
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -43,6 +44,7 @@
 #include "hw/riscv/sifive_clint.h"
 #include "hw/riscv/sifive_uart.h"
 #include "hw/riscv/sifive_u.h"
+#include "hw/riscv/sifive_u_prci.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
 #include "sysemu/arch_init.h"
@@ -61,6 +63,7 @@ static const struct MemmapEntry {
 [SIFIVE_U_MROM] = { 0x1000,0x11000 },
 [SIFIVE_U_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
+[SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
 [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
 [SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
@@ -78,7 +81,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 uint32_t *cells;
 char *nodename;
 char ethclk_names[] = "pclk\0hclk\0tx_clk";
-uint32_t plic_phandle, ethclk_phandle, phandle = 1;
+uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
 uint32_t hfclk_phandle, rtcclk_phandle;
 
@@ -189,6 +192,21 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(cells);
 g_free(nodename);
 
+prci_phandle = phandle++;
+nodename = g_strdup_printf("/soc/clock-controller@%lx",
+(long)memmap[SIFIVE_U_PRCI].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", prci_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x1);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+hfclk_phandle, rtcclk_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "reg",
+0x0, memmap[SIFIVE_U_PRCI].base,
+0x0, memmap[SIFIVE_U_PRCI].size);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"sifive,fu540-c000-prci");
+g_free(nodename);
+
 plic_phandle = phandle++;
 cells =  g_new0(uint32_t, ms->smp.cpus * 4 - 2);
 for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
@@ -483,6 +501,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
 memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
+sifive_u_prci_create(memmap[SIFIVE_U_PRCI].base);
 
 for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
 plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index debbf28..0ec04df 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -54,6 +54,7 @@ enum {
 SIFIVE_U_MROM,
 SIFIVE_U_CLINT,
 SIFIVE_U_PLIC,
+SIFIVE_U_PRCI,
 SIFIVE_U_UART0,
 SIFIVE_U_UART1,
 SIFIVE_U_DRAM,
-- 
2.7.4




[Qemu-devel] [PATCH v4 13/28] riscv: hart: Add a "hartid-base" property to RISC-V hart array

2019-08-18 Thread Bin Meng
At present each hart's hartid in a RISC-V hart array is assigned
the same value of its index in the hart array. But for a system
that has multiple hart arrays, this is not the case any more.

Add a new "hartid-base" property so that hartid number can be
assigned based on the property value.

Signed-off-by: Bin Meng 

---

Changes in v4:
- new patch to add a "hartid-base" property to RISC-V hart array

Changes in v3: None
Changes in v2: None

 hw/riscv/riscv_hart.c | 8 +---
 include/hw/riscv/riscv_hart.h | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index 9deef869..52ab86a 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -27,6 +27,7 @@
 
 static Property riscv_harts_props[] = {
 DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
+DEFINE_PROP_UINT32("hartid-base", RISCVHartArrayState, hartid_base, 0),
 DEFINE_PROP_STRING("cpu-type", RISCVHartArrayState, cpu_type),
 DEFINE_PROP_END_OF_LIST(),
 };
@@ -37,7 +38,7 @@ static void riscv_harts_cpu_reset(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
-static void riscv_hart_realize(RISCVHartArrayState *s, int idx,
+static void riscv_hart_realize(RISCVHartArrayState *s, int idx, uint32_t 
hartid,
char *cpu_type, Error **errp)
 {
 Error *err = NULL;
@@ -45,7 +46,7 @@ static void riscv_hart_realize(RISCVHartArrayState *s, int 
idx,
 object_initialize_child(OBJECT(s), "harts[*]", >harts[idx],
 sizeof(RISCVCPU), cpu_type,
 _abort, NULL);
-s->harts[idx].env.mhartid = idx;
+s->harts[idx].env.mhartid = hartid;
 qemu_register_reset(riscv_harts_cpu_reset, >harts[idx]);
 object_property_set_bool(OBJECT(>harts[idx]), true,
  "realized", );
@@ -58,12 +59,13 @@ static void riscv_hart_realize(RISCVHartArrayState *s, int 
idx,
 static void riscv_harts_realize(DeviceState *dev, Error **errp)
 {
 RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
+uint32_t hartid = s->hartid_base;
 int n;
 
 s->harts = g_new0(RISCVCPU, s->num_harts);
 
 for (n = 0; n < s->num_harts; n++) {
-riscv_hart_realize(s, n, s->cpu_type, errp);
+riscv_hart_realize(s, n, hartid + n, s->cpu_type, errp);
 }
 }
 
diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
index 0671d88..1984e30 100644
--- a/include/hw/riscv/riscv_hart.h
+++ b/include/hw/riscv/riscv_hart.h
@@ -32,6 +32,7 @@ typedef struct RISCVHartArrayState {
 
 /*< public >*/
 uint32_t num_harts;
+uint32_t hartid_base;
 char *cpu_type;
 RISCVCPU *harts;
 } RISCVHartArrayState;
-- 
2.7.4




[Qemu-devel] [PATCH v4 22/28] riscv: sifive_u: Change UART node name in device tree

2019-08-18 Thread Bin Meng
OpenSBI for fu540 does DT fix up (see fu540_modify_dt()) by updating
chosen "stdout-path" to point to "/soc/serial@...", and U-Boot will
use this information to locate the serial node and probe its driver.
However currently we generate the UART node name as "/soc/uart@...",
causing U-Boot fail to find the serial node in DT.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index a85db77..8f16028 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -288,7 +288,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 uartclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
-nodename = g_strdup_printf("/soc/uart@%lx",
+nodename = g_strdup_printf("/soc/serial@%lx",
 (long)memmap[SIFIVE_U_UART0].base);
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
-- 
2.7.4




[Qemu-devel] [PATCH v4 11/28] riscv: Add a sifive_cpu.h to include both E and U cpu type defines

2019-08-18 Thread Bin Meng
Group SiFive E and U cpu type defines into one header file.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 include/hw/riscv/sifive_cpu.h | 31 +++
 include/hw/riscv/sifive_e.h   |  7 +--
 include/hw/riscv/sifive_u.h   |  7 +--
 3 files changed, 33 insertions(+), 12 deletions(-)
 create mode 100644 include/hw/riscv/sifive_cpu.h

diff --git a/include/hw/riscv/sifive_cpu.h b/include/hw/riscv/sifive_cpu.h
new file mode 100644
index 000..1367996
--- /dev/null
+++ b/include/hw/riscv/sifive_cpu.h
@@ -0,0 +1,31 @@
+/*
+ * SiFive CPU types
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef HW_SIFIVE_CPU_H
+#define HW_SIFIVE_CPU_H
+
+#if defined(TARGET_RISCV32)
+#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E31
+#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U34
+#elif defined(TARGET_RISCV64)
+#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E51
+#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
+#endif
+
+#endif /* HW_SIFIVE_CPU_H */
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index d175b24..e17cdfd 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -19,6 +19,7 @@
 #ifndef HW_SIFIVE_E_H
 #define HW_SIFIVE_E_H
 
+#include "hw/riscv/sifive_cpu.h"
 #include "hw/riscv/sifive_gpio.h"
 
 #define TYPE_RISCV_E_SOC "riscv.sifive.e.soc"
@@ -83,10 +84,4 @@ enum {
 #define SIFIVE_E_PLIC_CONTEXT_BASE 0x20
 #define SIFIVE_E_PLIC_CONTEXT_STRIDE 0x1000
 
-#if defined(TARGET_RISCV32)
-#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E31
-#elif defined(TARGET_RISCV64)
-#define SIFIVE_E_CPU TYPE_RISCV_CPU_SIFIVE_E51
-#endif
-
 #endif
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 892f0ee..4abc621 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -20,6 +20,7 @@
 #define HW_SIFIVE_U_H
 
 #include "hw/net/cadence_gem.h"
+#include "hw/riscv/sifive_cpu.h"
 
 #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
 #define RISCV_U_SOC(obj) \
@@ -77,10 +78,4 @@ enum {
 #define SIFIVE_U_PLIC_CONTEXT_BASE 0x20
 #define SIFIVE_U_PLIC_CONTEXT_STRIDE 0x1000
 
-#if defined(TARGET_RISCV32)
-#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U34
-#elif defined(TARGET_RISCV64)
-#define SIFIVE_U_CPU TYPE_RISCV_CPU_SIFIVE_U54
-#endif
-
 #endif
-- 
2.7.4




Re: [Qemu-devel] [PATCH v3] hw: net: cadence_gem: Fix build errors in DB_PRINT()

2019-08-18 Thread Bin Meng
On Sat, Aug 10, 2019 at 9:58 AM Alistair Francis  wrote:
>
> On Fri, Aug 9, 2019 at 12:26 AM Bin Meng  wrote:
> >
> > When CADENCE_GEM_ERR_DEBUG is turned on, there are several
> > compilation errors in DB_PRINT(). Fix them.
> >
> > While we are here, update to use appropriate modifiers in
> > the same DB_PRINT() call.
> >
> > Signed-off-by: Bin Meng 
>
> Reviewed-by: Alistair Francis 
>

Ping?

What's the status of this patch?

Regards,
Bin



[Qemu-devel] [PATCH v4 20/28] riscv: sifive_u: Reference PRCI clocks in UART and ethernet nodes

2019-08-18 Thread Bin Meng
Now that we have added a PRCI node, update existing UART and ethernet
nodes to reference PRCI as their clock sources, to keep in sync with
the Linux kernel device tree.

Signed-off-by: Bin Meng 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c  |  7 ---
 include/hw/riscv/sifive_u_prci.h | 10 ++
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index bd5551c..8818fd6 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -80,7 +80,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 int cpu;
 uint32_t *cells;
 char *nodename;
-char ethclk_names[] = "pclk\0hclk\0tx_clk";
+char ethclk_names[] = "pclk\0hclk";
 uint32_t plic_phandle, prci_phandle, ethclk_phandle, phandle = 1;
 uint32_t uartclk_phandle;
 uint32_t hfclk_phandle, rtcclk_phandle;
@@ -265,7 +265,7 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
-ethclk_phandle, ethclk_phandle, ethclk_phandle);
+prci_phandle, PRCI_CLK_GEMGXLPLL, prci_phandle, PRCI_CLK_GEMGXLPLL);
 qemu_fdt_setprop(fdt, nodename, "clock-names", ethclk_names,
 sizeof(ethclk_names));
 qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
@@ -295,7 +295,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_UART0].base,
 0x0, memmap[SIFIVE_U_UART0].size);
-qemu_fdt_setprop_cell(fdt, nodename, "clocks", uartclk_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+prci_phandle, PRCI_CLK_TLCLK);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
 qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
 
diff --git a/include/hw/riscv/sifive_u_prci.h b/include/hw/riscv/sifive_u_prci.h
index 66eacb5..cdf1d33 100644
--- a/include/hw/riscv/sifive_u_prci.h
+++ b/include/hw/riscv/sifive_u_prci.h
@@ -87,4 +87,14 @@ typedef struct SiFiveUPRCIState {
 
 DeviceState *sifive_u_prci_create(hwaddr addr);
 
+/*
+ * Clock indexes for use by Device Tree data and the PRCI driver.
+ *
+ * These values are from sifive-fu540-prci.h in the Linux kernel.
+ */
+#define PRCI_CLK_COREPLL0
+#define PRCI_CLK_DDRPLL 1
+#define PRCI_CLK_GEMGXLPLL  2
+#define PRCI_CLK_TLCLK  3
+
 #endif /* HW_SIFIVE_U_PRCI_H */
-- 
2.7.4




[Qemu-devel] [PATCH v4 07/28] riscv: sifive: Rename sifive_prci.{c, h} to sifive_e_prci.{c, h}

2019-08-18 Thread Bin Meng
Current SiFive PRCI model only works with sifive_e machine, as it
only emulates registers or PRCI block in the FE310 SoC.

Rename the file name to make it clear that it is for sifive_e.
This also prefix "sifive_e"/"SIFIVE_E" for all macros, variables
and functions.

Signed-off-by: Bin Meng 
Reviewed-by: Chih-Min Chao 

---

Changes in v4:
- prefix all macros/variables/functions with SIFIVE_E/sifive_e
  in the sifive_e_prci driver

Changes in v3: None
Changes in v2: None

 hw/riscv/Makefile.objs  |  2 +-
 hw/riscv/sifive_e.c |  4 +-
 hw/riscv/{sifive_prci.c => sifive_e_prci.c} | 79 ++---
 include/hw/riscv/sifive_e_prci.h| 69 +
 include/hw/riscv/sifive_prci.h  | 69 -
 5 files changed, 111 insertions(+), 112 deletions(-)
 rename hw/riscv/{sifive_prci.c => sifive_e_prci.c} (50%)
 create mode 100644 include/hw/riscv/sifive_e_prci.h
 delete mode 100644 include/hw/riscv/sifive_prci.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index eb9d4f9..c859697 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -2,9 +2,9 @@ obj-y += boot.o
 obj-$(CONFIG_SPIKE) += riscv_htif.o
 obj-$(CONFIG_HART) += riscv_hart.o
 obj-$(CONFIG_SIFIVE_E) += sifive_e.o
+obj-$(CONFIG_SIFIVE_E) += sifive_e_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_clint.o
 obj-$(CONFIG_SIFIVE) += sifive_gpio.o
-obj-$(CONFIG_SIFIVE) += sifive_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 2a499d8..2d67670 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -41,9 +41,9 @@
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
 #include "hw/riscv/sifive_clint.h"
-#include "hw/riscv/sifive_prci.h"
 #include "hw/riscv/sifive_uart.h"
 #include "hw/riscv/sifive_e.h"
+#include "hw/riscv/sifive_e_prci.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
 #include "sysemu/arch_init.h"
@@ -174,7 +174,7 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, 
Error **errp)
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
 sifive_mmio_emulate(sys_mem, "riscv.sifive.e.aon",
 memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
-sifive_prci_create(memmap[SIFIVE_E_PRCI].base);
+sifive_e_prci_create(memmap[SIFIVE_E_PRCI].base);
 
 /* GPIO */
 
diff --git a/hw/riscv/sifive_prci.c b/hw/riscv/sifive_e_prci.c
similarity index 50%
rename from hw/riscv/sifive_prci.c
rename to hw/riscv/sifive_e_prci.c
index f406682..e87a3ce 100644
--- a/hw/riscv/sifive_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -1,5 +1,5 @@
 /*
- * QEMU SiFive PRCI (Power, Reset, Clock, Interrupt)
+ * QEMU SiFive E PRCI (Power, Reset, Clock, Interrupt)
  *
  * Copyright (c) 2017 SiFive, Inc.
  *
@@ -22,46 +22,46 @@
 #include "hw/sysbus.h"
 #include "qemu/module.h"
 #include "target/riscv/cpu.h"
-#include "hw/riscv/sifive_prci.h"
+#include "hw/riscv/sifive_e_prci.h"
 
-static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
+static uint64_t sifive_e_prci_read(void *opaque, hwaddr addr, unsigned int 
size)
 {
-SiFivePRCIState *s = opaque;
+SiFiveEPRCIState *s = opaque;
 switch (addr) {
-case SIFIVE_PRCI_HFROSCCFG:
+case SIFIVE_E_PRCI_HFROSCCFG:
 return s->hfrosccfg;
-case SIFIVE_PRCI_HFXOSCCFG:
+case SIFIVE_E_PRCI_HFXOSCCFG:
 return s->hfxosccfg;
-case SIFIVE_PRCI_PLLCFG:
+case SIFIVE_E_PRCI_PLLCFG:
 return s->pllcfg;
-case SIFIVE_PRCI_PLLOUTDIV:
+case SIFIVE_E_PRCI_PLLOUTDIV:
 return s->plloutdiv;
 }
 hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
 return 0;
 }
 
-static void sifive_prci_write(void *opaque, hwaddr addr,
-   uint64_t val64, unsigned int size)
+static void sifive_e_prci_write(void *opaque, hwaddr addr,
+uint64_t val64, unsigned int size)
 {
-SiFivePRCIState *s = opaque;
+SiFiveEPRCIState *s = opaque;
 switch (addr) {
-case SIFIVE_PRCI_HFROSCCFG:
+case SIFIVE_E_PRCI_HFROSCCFG:
 s->hfrosccfg = (uint32_t) val64;
 /* OSC stays ready */
-s->hfrosccfg |= SIFIVE_PRCI_HFROSCCFG_RDY;
+s->hfrosccfg |= SIFIVE_E_PRCI_HFROSCCFG_RDY;
 break;
-case SIFIVE_PRCI_HFXOSCCFG:
+case SIFIVE_E_PRCI_HFXOSCCFG:
 s->hfxosccfg = (uint32_t) val64;
 /* OSC stays ready */
-s->hfxosccfg |= SIFIVE_PRCI_HFXOSCCFG_RDY;
+s->hfxosccfg |= SIFIVE_E_PRCI_HFXOSCCFG_RDY;
 break;
-case SIFIVE_PRCI_PLLCFG:
+case SIFIVE_E_PRCI_PLLCFG:
 s->pllcfg = (uint32_t) val64;
 /* PLL stays locked */
-s->pllcfg |= SIFIVE_PRCI_PLLCFG_LOCK;
+s->pllcfg |= SIFIVE_E_PRCI_PLLCFG_LOCK;
 break;
-case SIFIVE_PRCI_PLLOUTDIV:
+case SIFIVE_E_PRCI_PLLOUTDIV:
 s->plloutdiv 

[Qemu-devel] [PATCH v4 16/28] riscv: sifive_u: Update PLIC hart topology configuration string

2019-08-18 Thread Bin Meng
With heterogeneous harts config, the PLIC hart topology configuration
string are "M,MS,.." because of the monitor hart #0.

Suggested-by: Fabien Chouteau 
Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index a36cd77..284f7a5 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -433,10 +433,11 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 plic_hart_config = g_malloc0(plic_hart_config_len);
 for (i = 0; i < ms->smp.cpus; i++) {
 if (i != 0) {
-strncat(plic_hart_config, ",", plic_hart_config_len);
+strncat(plic_hart_config, "," SIFIVE_U_PLIC_HART_CONFIG,
+plic_hart_config_len);
+} else {
+strncat(plic_hart_config, "M", plic_hart_config_len);
 }
-strncat(plic_hart_config, SIFIVE_U_PLIC_HART_CONFIG,
-plic_hart_config_len);
 plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1);
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH v4 25/28] riscv: sifive_u: Instantiate OTP memory with a serial number

2019-08-18 Thread Bin Meng
This adds an OTP memory with a given serial number to the sifive_u
machine. With such support, the upstream U-Boot for sifive_fu540
boots out of the box on the sifive_u machine.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 5 +
 include/hw/riscv/sifive_u.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 8f16028..d66a7e8 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -10,6 +10,7 @@
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
  * 3) PRCI (Power, Reset, Clock, Interrupt)
+ * 4) OTP (One-Time Programmable) memory with stored serial number
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -44,6 +45,7 @@
 #include "hw/riscv/sifive_clint.h"
 #include "hw/riscv/sifive_uart.h"
 #include "hw/riscv/sifive_u.h"
+#include "hw/riscv/sifive_u_otp.h"
 #include "hw/riscv/sifive_u_prci.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
@@ -66,10 +68,12 @@ static const struct MemmapEntry {
 [SIFIVE_U_PRCI] = { 0x1000, 0x1000 },
 [SIFIVE_U_UART0] ={ 0x1001, 0x1000 },
 [SIFIVE_U_UART1] ={ 0x10011000, 0x1000 },
+[SIFIVE_U_OTP] =  { 0x1007, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
 [SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
 };
 
+#define SIFIVE_OTP_SERIAL   1
 #define GEM_REVISION0x10070109
 
 static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
@@ -503,6 +507,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
 sifive_u_prci_create(memmap[SIFIVE_U_PRCI].base);
+sifive_u_otp_create(memmap[SIFIVE_U_OTP].base, SIFIVE_OTP_SERIAL);
 
 for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
 plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 9acb69e..0362121 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -57,6 +57,7 @@ enum {
 SIFIVE_U_PRCI,
 SIFIVE_U_UART0,
 SIFIVE_U_UART1,
+SIFIVE_U_OTP,
 SIFIVE_U_DRAM,
 SIFIVE_U_GEM
 };
-- 
2.7.4




[Qemu-devel] [PATCH v4 08/28] riscv: sifive_e: prci: Fix a typo of hfxosccfg register programming

2019-08-18 Thread Bin Meng
For hfxosccfg register programming, SIFIVE_E_PRCI_HFXOSCCFG_RDY and
SIFIVE_E_PRCI_HFXOSCCFG_EN should be used.

Signed-off-by: Bin Meng 
Acked-by: Alistair Francis 
Reviewed-by: Chih-Min Chao 
Reviewed-by: Philippe Mathieu-Daudé 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_e_prci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_e_prci.c b/hw/riscv/sifive_e_prci.c
index e87a3ce..603a54b 100644
--- a/hw/riscv/sifive_e_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -89,7 +89,7 @@ static void sifive_e_prci_init(Object *obj)
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
 
 s->hfrosccfg = (SIFIVE_E_PRCI_HFROSCCFG_RDY | SIFIVE_E_PRCI_HFROSCCFG_EN);
-s->hfxosccfg = (SIFIVE_E_PRCI_HFROSCCFG_RDY | SIFIVE_E_PRCI_HFROSCCFG_EN);
+s->hfxosccfg = (SIFIVE_E_PRCI_HFXOSCCFG_RDY | SIFIVE_E_PRCI_HFXOSCCFG_EN);
 s->pllcfg = (SIFIVE_E_PRCI_PLLCFG_REFSEL | SIFIVE_E_PRCI_PLLCFG_BYPASS |
  SIFIVE_E_PRCI_PLLCFG_LOCK);
 s->plloutdiv = SIFIVE_E_PRCI_PLLOUTDIV_DIV1;
-- 
2.7.4




[Qemu-devel] [PATCH v4 12/28] riscv: hart: Extract hart realize to a separate routine

2019-08-18 Thread Bin Meng
Currently riscv_harts_realize() creates all harts based on the
same cpu type given in the hart array property. With current
implementation it can only create homogeneous harts. Exact the
hart realize to a separate routine in preparation for supporting
multiple hart arrays.

Note the file header says the RISC-V hart array holds the state
of a heterogeneous array of RISC-V harts, which is not true.
Update the comment to mention homogeneous array of RISC-V harts.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/riscv_hart.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index ca69a1b..9deef869 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2017 SiFive, Inc.
  *
- * Holds the state of a heterogenous array of RISC-V harts
+ * Holds the state of a homogeneous array of RISC-V harts
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -37,26 +37,33 @@ static void riscv_harts_cpu_reset(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
+static void riscv_hart_realize(RISCVHartArrayState *s, int idx,
+   char *cpu_type, Error **errp)
+{
+Error *err = NULL;
+
+object_initialize_child(OBJECT(s), "harts[*]", >harts[idx],
+sizeof(RISCVCPU), cpu_type,
+_abort, NULL);
+s->harts[idx].env.mhartid = idx;
+qemu_register_reset(riscv_harts_cpu_reset, >harts[idx]);
+object_property_set_bool(OBJECT(>harts[idx]), true,
+ "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+}
+
 static void riscv_harts_realize(DeviceState *dev, Error **errp)
 {
 RISCVHartArrayState *s = RISCV_HART_ARRAY(dev);
-Error *err = NULL;
 int n;
 
 s->harts = g_new0(RISCVCPU, s->num_harts);
 
 for (n = 0; n < s->num_harts; n++) {
-object_initialize_child(OBJECT(s), "harts[*]", >harts[n],
-sizeof(RISCVCPU), s->cpu_type,
-_abort, NULL);
-s->harts[n].env.mhartid = n;
-qemu_register_reset(riscv_harts_cpu_reset, >harts[n]);
-object_property_set_bool(OBJECT(>harts[n]), true,
- "realized", );
-if (err) {
-error_propagate(errp, err);
-return;
-}
+riscv_hart_realize(s, n, s->cpu_type, errp);
 }
 }
 
-- 
2.7.4




[Qemu-devel] [PATCH v4 24/28] riscv: sifive: Implement a model for SiFive FU540 OTP

2019-08-18 Thread Bin Meng
This implements a simple model for SiFive FU540 OTP (One-Time
Programmable) Memory interface, primarily for reading out the
stored serial number from the first 1 KiB of the 16 KiB OTP
memory reserved by SiFive for internal use.

Signed-off-by: Bin Meng 

---

Changes in v4:
- prefix all macros/variables/functions with SIFIVE_U/sifive_u
  in the sifive_u_otp driver

Changes in v3: None
Changes in v2: None

 hw/riscv/Makefile.objs  |   1 +
 hw/riscv/sifive_u_otp.c | 194 
 include/hw/riscv/sifive_u_otp.h |  90 +++
 3 files changed, 285 insertions(+)
 create mode 100644 hw/riscv/sifive_u_otp.c
 create mode 100644 include/hw/riscv/sifive_u_otp.h

diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index b95bbd5..fc3c6dd 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -8,6 +8,7 @@ obj-$(CONFIG_SIFIVE) += sifive_gpio.o
 obj-$(CONFIG_SIFIVE) += sifive_plic.o
 obj-$(CONFIG_SIFIVE) += sifive_test.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u.o
+obj-$(CONFIG_SIFIVE_U) += sifive_u_otp.o
 obj-$(CONFIG_SIFIVE_U) += sifive_u_prci.o
 obj-$(CONFIG_SIFIVE) += sifive_uart.o
 obj-$(CONFIG_SPIKE) += spike.o
diff --git a/hw/riscv/sifive_u_otp.c b/hw/riscv/sifive_u_otp.c
new file mode 100644
index 000..de8801c
--- /dev/null
+++ b/hw/riscv/sifive_u_otp.c
@@ -0,0 +1,194 @@
+/*
+ * QEMU SiFive U OTP (One-Time Programmable) Memory interface
+ *
+ * Copyright (c) 2019 Bin Meng 
+ *
+ * Simple model of the OTP to emulate register reads made by the SDK BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qemu/module.h"
+#include "target/riscv/cpu.h"
+#include "hw/riscv/sifive_u_otp.h"
+
+static uint64_t sifive_u_otp_read(void *opaque, hwaddr addr, unsigned int size)
+{
+SiFiveUOTPState *s = opaque;
+
+switch (addr) {
+case SIFIVE_U_OTP_PA:
+return s->pa;
+case SIFIVE_U_OTP_PAIO:
+return s->paio;
+case SIFIVE_U_OTP_PAS:
+return s->pas;
+case SIFIVE_U_OTP_PCE:
+return s->pce;
+case SIFIVE_U_OTP_PCLK:
+return s->pclk;
+case SIFIVE_U_OTP_PDIN:
+return s->pdin;
+case SIFIVE_U_OTP_PDOUT:
+if ((s->pce & SIFIVE_U_OTP_PCE_EN) &&
+(s->pdstb & SIFIVE_U_OTP_PDSTB_EN) &&
+(s->ptrim & SIFIVE_U_OTP_PTRIM_EN)) {
+return s->fuse[s->pa & SIFIVE_U_OTP_PA_MASK];
+} else {
+return 0xff;
+}
+case SIFIVE_U_OTP_PDSTB:
+return s->pdstb;
+case SIFIVE_U_OTP_PPROG:
+return s->pprog;
+case SIFIVE_U_OTP_PTC:
+return s->ptc;
+case SIFIVE_U_OTP_PTM:
+return s->ptm;
+case SIFIVE_U_OTP_PTM_REP:
+return s->ptm_rep;
+case SIFIVE_U_OTP_PTR:
+return s->ptr;
+case SIFIVE_U_OTP_PTRIM:
+return s->ptrim;
+case SIFIVE_U_OTP_PWE:
+return s->pwe;
+}
+
+hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
+return 0;
+}
+
+static void sifive_u_otp_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+SiFiveUOTPState *s = opaque;
+
+switch (addr) {
+case SIFIVE_U_OTP_PA:
+s->pa = (uint32_t) val64 & SIFIVE_U_OTP_PA_MASK;
+break;
+case SIFIVE_U_OTP_PAIO:
+s->paio = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PAS:
+s->pas = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PCE:
+s->pce = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PCLK:
+s->pclk = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PDIN:
+s->pdin = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PDOUT:
+/* read-only */
+break;
+case SIFIVE_U_OTP_PDSTB:
+s->pdstb = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PPROG:
+s->pprog = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PTC:
+s->ptc = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PTM:
+s->ptm = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PTM_REP:
+s->ptm_rep = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PTR:
+s->ptr = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PTRIM:
+s->ptrim = (uint32_t) val64;
+break;
+case SIFIVE_U_OTP_PWE:
+s->pwe = (uint32_t) 

[Qemu-devel] [PATCH v4 15/28] riscv: sifive_u: Set the minimum number of cpus to 2

2019-08-18 Thread Bin Meng
It is not useful if we only have one management CPU.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v4: None
Changes in v3:
- use management cpu count + 1 for the min_cpus

Changes in v2:
- update the file header to indicate at least 2 harts are created

 hw/riscv/sifive_u.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 0e5bbe7..a36cd77 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -10,8 +10,8 @@
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
  *
- * This board currently generates devicetree dynamically that indicates at most
- * five harts.
+ * This board currently generates devicetree dynamically that indicates at 
least
+ * two harts and up to five harts.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -485,6 +485,7 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
 mc->desc = "RISC-V Board compatible with SiFive U SDK";
 mc->init = riscv_sifive_u_init;
 mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
+mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
 }
 
 DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
-- 
2.7.4




[Qemu-devel] [PATCH v4 06/28] riscv: sifive_u: Remove the unnecessary include of prci header

2019-08-18 Thread Bin Meng
sifive_u machine does not use PRCI as of today. Remove the prci
header inclusion.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index e22803b..3f58f61 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -39,7 +39,6 @@
 #include "hw/riscv/sifive_plic.h"
 #include "hw/riscv/sifive_clint.h"
 #include "hw/riscv/sifive_uart.h"
-#include "hw/riscv/sifive_prci.h"
 #include "hw/riscv/sifive_u.h"
 #include "hw/riscv/boot.h"
 #include "chardev/char.h"
-- 
2.7.4




[Qemu-devel] [PATCH v4 14/28] riscv: sifive_u: Update hart configuration to reflect the real FU540 SoC

2019-08-18 Thread Bin Meng
The FU540-C000 includes a 64-bit E51 RISC-V core and four 64-bit U54
RISC-V cores. Currently the sifive_u machine only populates 4 U54
cores. Update the max cpu number to 5 to reflect the real hardware,
by creating 2 CPU clusters as containers for RISC-V hart arrays to
populate heterogeneous harts.

The cpu nodes in the generated DTS have been updated as well.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v4:
- changed to create clusters for each cpu type

Changes in v3:
- changed to use macros for management and compute cpu count

Changes in v2:
- fixed the "interrupts-extended" property size

 hw/riscv/sifive_u.c | 102 +---
 include/hw/riscv/sifive_u.h |   8 +++-
 2 files changed, 84 insertions(+), 26 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 3f58f61..0e5bbe7 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -10,7 +10,8 @@
  * 1) CLINT (Core Level Interruptor)
  * 2) PLIC (Platform Level Interrupt Controller)
  *
- * This board currently uses a hardcoded devicetree that indicates one hart.
+ * This board currently generates devicetree dynamically that indicates at most
+ * five harts.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -26,6 +27,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
@@ -34,6 +36,7 @@
 #include "hw/loader.h"
 #include "hw/sysbus.h"
 #include "hw/char/serial.h"
+#include "hw/cpu/cluster.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/sifive_plic.h"
@@ -69,6 +72,7 @@ static const struct MemmapEntry {
 static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
+MachineState *ms = MACHINE(qdev_get_machine());
 void *fdt;
 int cpu;
 uint32_t *cells;
@@ -109,15 +113,21 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
-for (cpu = s->soc.cpus.num_harts - 1; cpu >= 0; cpu--) {
+for (cpu = ms->smp.cpus - 1; cpu >= 0; cpu--) {
 int cpu_phandle = phandle++;
 nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
-char *isa = riscv_isa_string(>soc.cpus.harts[cpu]);
+char *isa;
 qemu_fdt_add_subnode(fdt, nodename);
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
   SIFIVE_U_CLOCK_FREQ);
-qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+/* cpu 0 is the management hart that does not have mmu */
+if (cpu != 0) {
+qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
+isa = riscv_isa_string(>soc.u_cpus.harts[cpu - 1]);
+} else {
+isa = riscv_isa_string(>soc.e_cpus.harts[0]);
+}
 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
 qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
@@ -133,8 +143,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 }
 
-cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
-for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
+cells =  g_new0(uint32_t, ms->smp.cpus * 4);
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
 nodename =
 g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
@@ -152,20 +162,26 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 0x0, memmap[SIFIVE_U_CLINT].base,
 0x0, memmap[SIFIVE_U_CLINT].size);
 qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
-cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
+cells, ms->smp.cpus * sizeof(uint32_t) * 4);
 g_free(cells);
 g_free(nodename);
 
 plic_phandle = phandle++;
-cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
-for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
+cells =  g_new0(uint32_t, ms->smp.cpus * 4 - 2);
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
 nodename =
 g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
-cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
-cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
-cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle);
-cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
+/* cpu 0 is the management hart that 

[Qemu-devel] [PATCH v4 05/28] riscv: roms: Remove executable attribute of opensbi images

2019-08-18 Thread Bin Meng
Like other binary files, the executable attribute of opensbi images
should not be set.

Signed-off-by: Bin Meng 

---

Changes in v4:
- new patch to remove executable attribute of opensbi images

Changes in v3: None
Changes in v2: None

 pc-bios/opensbi-riscv32-virt-fw_jump.bin | Bin
 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin
 pc-bios/opensbi-riscv64-virt-fw_jump.bin | Bin
 3 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 pc-bios/opensbi-riscv32-virt-fw_jump.bin
 mode change 100755 => 100644 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
 mode change 100755 => 100644 pc-bios/opensbi-riscv64-virt-fw_jump.bin

diff --git a/pc-bios/opensbi-riscv32-virt-fw_jump.bin 
b/pc-bios/opensbi-riscv32-virt-fw_jump.bin
old mode 100755
new mode 100644
diff --git a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin 
b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
old mode 100755
new mode 100644
diff --git a/pc-bios/opensbi-riscv64-virt-fw_jump.bin 
b/pc-bios/opensbi-riscv64-virt-fw_jump.bin
old mode 100755
new mode 100644
-- 
2.7.4




[Qemu-devel] [PATCH v4 00/28] riscv: sifive_u: Improve the emulation fidelity of sifive_u machine

2019-08-18 Thread Bin Meng
As of today, the QEMU 'sifive_u' machine is a special target that does
not boot the upstream OpenSBI/U-Boot firmware images built for the real
SiFive HiFive Unleashed board. Hence OpenSBI supports a special platform
"qemu/sifive_u". For U-Boot, the sifive_fu540_defconfig is referenced
in the OpenSBI doc as its payload, but that does not boot at all due
to various issues in current QEMU 'sifive_u' machine codes.

This series aims to improve the emulation fidelity of sifive_u machine,
so that the upstream OpenSBI, U-Boot and kernel images built for the
SiFive HiFive Unleashed board can be used out of the box without any
special hack.

The major changes include:
- Heterogeneous harts creation supported, so that we can create a CPU
  that exactly mirrors the real hardware: 1 E51 + 4 U54.
- Implemented a PRCI model for FU540
- Implemented an OTP model for FU540, primarily used for storing serial
  number of the board
- Fixed GEM support that was seriously broken on sifive_u
- Synced device tree with upstream Linux kernel on sifive_u

OpenSBI v0.4 image built for sifive/fu540 is included as the default
bios image for 'sifive_u' machine.

The series is tested against OpenSBI v0.4 image for sifive/fu540
paltform, U-Boot v2019.10-rc1 image for sifive_fu540_defconfig,
and Linux kernel v5.3-rc3 image with the following patch:

macb: Update compatibility string for SiFive FU540-C000 [1]

OpenSBI + U-Boot, ping/tftpboot with U-Boot MACB driver works well.
Boot Linux 64-bit defconfig image, verified that system console on
the serial 0 and ping host work pretty well.

An OpenSBI patch [2] was sent to drop the special "qemu/sifive_u" platform
support in OpenSBI. The original plan was to get the drop patch applied
after this QEMU series is merged. However after discussion in the OpenSBI
mailing list, it seems the best option for us is to let OpenSBI continue
shipping the special "qemu/sifive_u" platform support to work with QEMU
version <= 4.1 and deprecate the support sometime in the future. A patch
will need to be sent to OpenSBI mailing list to update its document.

v4 is now rebased on Palmer's QEMU RISC-V repo "for-master" branch.
Dropped the following v3 patch that was already done by someone else.
- riscv: sifive_u: Generate an aliases node in the device tree
- riscv: sifive_u: Support loading initramfs

The following v3 patch was dropped too due to a different cluster approach
suggested by Richard Henderson is used in v4:
- riscv: hart: Support heterogeneous harts population

[1]: https://patchwork.kernel.org/patch/11050003/
[2]: http://lists.infradead.org/pipermail/opensbi/2019-August/000335.html

Changes in v4:
- remove 2 more "linux,phandle" instances in sifive_u.c and spike.c
  after rebasing on Palmer's QEMU RISC-V tree
- change create_fdt() to return void in sifive_u.c too, after rebasing
  on Palmer's QEMU RISC-V tree
- new patch to remove executable attribute of opensbi images
- prefix all macros/variables/functions with SIFIVE_E/sifive_e
  in the sifive_e_prci driver
- new patch to add a "hartid-base" property to RISC-V hart array
- changed to create clusters for each cpu type
- prefix all macros/variables/functions with SIFIVE_U/sifive_u
  in the sifive_u_prci driver
- prefix all macros/variables/functions with SIFIVE_U/sifive_u
  in the sifive_u_otp driver
- new patch to remove handcrafted clock nodes for UART and ethernet

Changes in v3:
- changed to use macros for management and compute cpu count
- use management cpu count + 1 for the min_cpus
- update IRQ numbers of both UARTs to match hardware as well

Changes in v2:
- keep the PLIC compatible string unchanged as OpenSBI uses that
  for DT fix up
- drop patch "riscv: sifive: Move sifive_mmio_emulate() to a common place"
- new patch "riscv: sifive_e: Drop sifive_mmio_emulate()"
- fixed the "interrupts-extended" property size
- update the file header to indicate at least 2 harts are created
- use create_unimplemented_device() to create the GEM management
  block instead of sifive_mmio_emulate()
- add "phy-handle" property to the ethernet node

Bin Meng (28):
  riscv: hw: Remove superfluous "linux,phandle" property
  riscv: hw: Use qemu_fdt_setprop_cell() for property with only 1 cell
  riscv: hw: Remove not needed PLIC properties in device tree
  riscv: hw: Change create_fdt() to return void
  riscv: roms: Remove executable attribute of opensbi images
  riscv: sifive_u: Remove the unnecessary include of prci header
  riscv: sifive: Rename sifive_prci.{c,h} to sifive_e_prci.{c,h}
  riscv: sifive_e: prci: Fix a typo of hfxosccfg register programming
  riscv: sifive_e: prci: Update the PRCI register block size
  riscv: sifive_e: Drop sifive_mmio_emulate()
  riscv: Add a sifive_cpu.h to include both E and U cpu type defines
  riscv: hart: Extract hart realize to a separate routine
  riscv: hart: Add a "hartid-base" property to RISC-V hart array
  riscv: sifive_u: Update hart configuration to reflect the real FU540
SoC
  riscv: sifive_u: Set the 

[Qemu-devel] [PATCH v4 04/28] riscv: hw: Change create_fdt() to return void

2019-08-18 Thread Bin Meng
There is no need to return fdt at the end of create_fdt() because
it's already saved in s->fdt.

Signed-off-by: Bin Meng 
Reviewed-by: Chih-Min Chao 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 

---

Changes in v4:
- change create_fdt() to return void in sifive_u.c too, after rebasing
  on Palmer's QEMU RISC-V tree

Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 11 ---
 hw/riscv/virt.c | 11 ---
 2 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 5fe0033..e22803b 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -67,7 +67,7 @@ static const struct MemmapEntry {
 
 #define GEM_REVISION0x10070109
 
-static void *create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
+static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
 void *fdt;
@@ -253,14 +253,11 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
 
 g_free(nodename);
-
-return fdt;
 }
 
 static void riscv_sifive_u_init(MachineState *machine)
 {
 const struct MemmapEntry *memmap = sifive_u_memmap;
-void *fdt;
 
 SiFiveUState *s = g_new0(SiFiveUState, 1);
 MemoryRegion *system_memory = get_system_memory();
@@ -281,7 +278,7 @@ static void riscv_sifive_u_init(MachineState *machine)
 main_mem);
 
 /* create device tree */
-fdt = create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 riscv_find_and_load_firmware(machine, BIOS_FILENAME,
  memmap[SIFIVE_U_DRAM].base);
@@ -294,9 +291,9 @@ static void riscv_sifive_u_init(MachineState *machine)
 hwaddr end = riscv_load_initrd(machine->initrd_filename,
machine->ram_size, kernel_entry,
);
-qemu_fdt_setprop_cell(fdt, "/chosen",
+qemu_fdt_setprop_cell(s->fdt, "/chosen",
   "linux,initrd-start", start);
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
   end);
 }
 }
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2f75195..6bfa721 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -112,7 +112,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename,
0x1800, 0, 0, 0x7);
 }
 
-static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
+static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
 void *fdt;
@@ -316,8 +316,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
 }
 g_free(nodename);
-
-return fdt;
 }
 
 
@@ -373,7 +371,6 @@ static void riscv_virt_board_init(MachineState *machine)
 size_t plic_hart_config_len;
 int i;
 unsigned int smp_cpus = machine->smp.cpus;
-void *fdt;
 
 /* Initialize SOC */
 object_initialize_child(OBJECT(machine), "soc", >soc, sizeof(s->soc),
@@ -392,7 +389,7 @@ static void riscv_virt_board_init(MachineState *machine)
 main_mem);
 
 /* create device tree */
-fdt = create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 /* boot rom */
 memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom",
@@ -411,9 +408,9 @@ static void riscv_virt_board_init(MachineState *machine)
 hwaddr end = riscv_load_initrd(machine->initrd_filename,
machine->ram_size, kernel_entry,
);
-qemu_fdt_setprop_cell(fdt, "/chosen",
+qemu_fdt_setprop_cell(s->fdt, "/chosen",
   "linux,initrd-start", start);
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
   end);
 }
 }
-- 
2.7.4




[Qemu-devel] [PATCH v4 09/28] riscv: sifive_e: prci: Update the PRCI register block size

2019-08-18 Thread Bin Meng
Currently the PRCI register block size is set to 0x8000, but in fact
0x1000 is enough, which is also what the manual says.

Signed-off-by: Bin Meng 
Reviewed-by: Chih-Min Chao 
Reviewed-by: Alistair Francis 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_e_prci.c | 2 +-
 include/hw/riscv/sifive_e_prci.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_e_prci.c b/hw/riscv/sifive_e_prci.c
index 603a54b..3afcb84 100644
--- a/hw/riscv/sifive_e_prci.c
+++ b/hw/riscv/sifive_e_prci.c
@@ -85,7 +85,7 @@ static void sifive_e_prci_init(Object *obj)
 SiFiveEPRCIState *s = SIFIVE_E_PRCI(obj);
 
 memory_region_init_io(>mmio, obj, _e_prci_ops, s,
-  TYPE_SIFIVE_E_PRCI, 0x8000);
+  TYPE_SIFIVE_E_PRCI, SIFIVE_E_PRCI_REG_SIZE);
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mmio);
 
 s->hfrosccfg = (SIFIVE_E_PRCI_HFROSCCFG_RDY | SIFIVE_E_PRCI_HFROSCCFG_EN);
diff --git a/include/hw/riscv/sifive_e_prci.h b/include/hw/riscv/sifive_e_prci.h
index c4b76aa..698b0b4 100644
--- a/include/hw/riscv/sifive_e_prci.h
+++ b/include/hw/riscv/sifive_e_prci.h
@@ -47,6 +47,8 @@ enum {
 SIFIVE_E_PRCI_PLLOUTDIV_DIV1 = (1 << 8)
 };
 
+#define SIFIVE_E_PRCI_REG_SIZE  0x1000
+
 #define TYPE_SIFIVE_E_PRCI  "riscv.sifive.e.prci"
 
 #define SIFIVE_E_PRCI(obj) \
-- 
2.7.4




[Qemu-devel] [PATCH v4 03/28] riscv: hw: Remove not needed PLIC properties in device tree

2019-08-18 Thread Bin Meng
This removes "reg-names" and "riscv,max-priority" properties of the
PLIC node from device tree.

Signed-off-by: Bin Meng 
Reviewed-by: Jonathan Behrens 
Reviewed-by: Alistair Francis 

---

Changes in v4: None
Changes in v3: None
Changes in v2:
- keep the PLIC compatible string unchanged as OpenSBI uses that
  for DT fix up

 hw/riscv/sifive_u.c | 2 --
 hw/riscv/virt.c | 2 --
 2 files changed, 4 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 3f9284e..5fe0033 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -180,8 +180,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_PLIC].base,
 0x0, memmap[SIFIVE_U_PLIC].size);
-qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 127f005..2f75195 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -244,8 +244,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[VIRT_PLIC].base,
 0x0, memmap[VIRT_PLIC].size);
-qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
-- 
2.7.4




[Qemu-devel] [PATCH v4 02/28] riscv: hw: Use qemu_fdt_setprop_cell() for property with only 1 cell

2019-08-18 Thread Bin Meng
Some of the properties only have 1 cell so we should use
qemu_fdt_setprop_cell() instead of qemu_fdt_setprop_cells().

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 18 +-
 hw/riscv/virt.c | 24 
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index afe304f..3f9284e 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -183,7 +183,7 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
-qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -208,20 +208,20 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 0x0, memmap[SIFIVE_U_GEM].size);
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
 qemu_fdt_setprop_cells(fdt, nodename, "clocks",
 ethclk_phandle, ethclk_phandle, ethclk_phandle);
 qemu_fdt_setprop(fdt, nodename, "clock-names", ethclk_names,
 sizeof(ethclk_names));
-qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 1);
-qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
+qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
 g_free(nodename);
 
 nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
 (long)memmap[SIFIVE_U_GEM].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
+qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
 uartclk_phandle = phandle++;
@@ -241,9 +241,9 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_UART0].base,
 0x0, memmap[SIFIVE_U_UART0].size);
-qemu_fdt_setprop_cells(fdt, nodename, "clocks", uartclk_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
+qemu_fdt_setprop_cell(fdt, nodename, "clocks", uartclk_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART0_IRQ);
 
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 00be05a..127f005 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -233,8 +233,8 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
 (long)memmap[VIRT_PLIC].base);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cells(fdt, nodename, "#address-cells",
-   FDT_PLIC_ADDR_CELLS);
+qemu_fdt_setprop_cell(fdt, nodename, "#address-cells",
+  FDT_PLIC_ADDR_CELLS);
 qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells",
   FDT_PLIC_INT_CELLS);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
@@ -247,7 +247,7 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
-qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
+qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -260,19 +260,19 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size,
 0x0, memmap[VIRT_VIRTIO].size);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", 
plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "interrupts", VIRTIO_IRQ + i);
+  

[Qemu-devel] [PATCH v4 01/28] riscv: hw: Remove superfluous "linux, phandle" property

2019-08-18 Thread Bin Meng
"linux,phandle" property is optional. Remove all instances in the
sifive_u, virt and spike machine device trees.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v4:
- remove 2 more "linux,phandle" instances in sifive_u.c and spike.c
  after rebasing on Palmer's QEMU RISC-V tree

Changes in v3: None
Changes in v2: None

 hw/riscv/sifive_u.c | 4 
 hw/riscv/spike.c| 1 -
 hw/riscv/virt.c | 3 ---
 3 files changed, 8 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 64e233d..afe304f 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -126,7 +126,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", cpu_phandle);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", cpu_phandle);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
@@ -185,7 +184,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
 qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
@@ -198,7 +196,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
 SIFIVE_U_GEM_CLOCK_FREQ);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", ethclk_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", ethclk_phandle);
 ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
@@ -234,7 +231,6 @@ static void *create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 3686400);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", uartclk_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", uartclk_phandle);
 uartclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(nodename);
 
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 2991b34..14acaef 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -112,7 +112,6 @@ static void create_fdt(SpikeState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", 1);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", 1);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 25faf3b..00be05a 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -170,11 +170,9 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
 qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", cpu_phandle);
-qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", cpu_phandle);
 intc_phandle = phandle++;
 qemu_fdt_add_subnode(fdt, intc);
 qemu_fdt_setprop_cell(fdt, intc, "phandle", intc_phandle);
-qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", intc_phandle);
 qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
 qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
@@ -250,7 +248,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
 qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", VIRTIO_NDEV);
 qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
-qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
 g_free(nodename);
-- 
2.7.4




Re: [Qemu-devel] [PATCH] migrtion: define MigrationState/MigrationIncomingState.state as MigrationStatus

2019-08-18 Thread Wei Yang
On Fri, Jun 21, 2019 at 10:27:39PM +0800, Wei Yang wrote:
>No functional change. Add default case to fix warning.
>

Hi, David & Juan

Do you like this?

>Signed-off-by: Wei Yang 
>---
> migration/migration.c | 8 +++-
> migration/migration.h | 6 +++---
> 2 files changed, 10 insertions(+), 4 deletions(-)
>
>diff --git a/migration/migration.c b/migration/migration.c
>index 2865ae3fa9..0fd2364961 100644
>--- a/migration/migration.c
>+++ b/migration/migration.c
>@@ -946,6 +946,8 @@ static void fill_source_migration_info(MigrationInfo *info)
> case MIGRATION_STATUS_CANCELLED:
> info->has_status = true;
> break;
>+default:
>+return;
> }
> info->status = s->state;
> }
>@@ -1054,6 +1056,8 @@ static void 
>fill_destination_migration_info(MigrationInfo *info)
> info->has_status = true;
> fill_destination_postcopy_migration_info(info);
> break;
>+default:
>+return;
> }
> info->status = mis->state;
> }
>@@ -1446,7 +1450,7 @@ void qmp_migrate_start_postcopy(Error **errp)
> 
> /* shared migration helpers */
> 
>-void migrate_set_state(int *state, int old_state, int new_state)
>+void migrate_set_state(MigrationStatus *state, int old_state, int new_state)
> {
> assert(new_state < MIGRATION_STATUS__MAX);
> if (atomic_cmpxchg(state, old_state, new_state) == old_state) {
>@@ -1683,6 +1687,8 @@ bool migration_is_idle(void)
> return false;
> case MIGRATION_STATUS__MAX:
> g_assert_not_reached();
>+default:
>+g_assert_not_reached();
> }
> 
> return false;
>diff --git a/migration/migration.h b/migration/migration.h
>index 5e8f09c6db..418ee00053 100644
>--- a/migration/migration.h
>+++ b/migration/migration.h
>@@ -65,7 +65,7 @@ struct MigrationIncomingState {
> 
> QEMUBH *bh;
> 
>-int state;
>+MigrationStatus state;
> 
> bool have_colo_incoming_thread;
> QemuThread colo_incoming_thread;
>@@ -151,7 +151,7 @@ struct MigrationState
> /* params from 'migrate-set-parameters' */
> MigrationParameters parameters;
> 
>-int state;
>+MigrationStatus state;
> 
> /* State related to return path */
> struct {
>@@ -234,7 +234,7 @@ struct MigrationState
> bool decompress_error_check;
> };
> 
>-void migrate_set_state(int *state, int old_state, int new_state);
>+void migrate_set_state(MigrationStatus *state, int old_state, int new_state);
> 
> void migration_fd_process_incoming(QEMUFile *f);
> void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp);
>-- 
>2.19.1

-- 
Wei Yang
Help you, Help me



[Qemu-devel] [PATCH v2] migration: cleanup check on ops in savevm.handlers iterations

2019-08-18 Thread Wei Yang
During migration, there are several places to iterate on
savevm.handlers. And on each iteration, we need to check its ops and
related callbacks before invoke it.

Generally, ops is the first element to check, and it is only necessary
to check it once.

This patch clean all the related part in savevm.c to check ops only once
in those iterations.

Signed-off-by: Wei Yang 

---
v2: rebase on latest upstream
---
 migration/savevm.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 4a86128ac4..35426d1db8 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1100,7 +1100,7 @@ void qemu_savevm_state_setup(QEMUFile *f)
 if (!se->ops || !se->ops->save_setup) {
 continue;
 }
-if (se->ops && se->ops->is_active) {
+if (se->ops->is_active) {
 if (!se->ops->is_active(se->opaque)) {
 continue;
 }
@@ -1131,7 +1131,7 @@ int qemu_savevm_state_resume_prepare(MigrationState *s)
 if (!se->ops || !se->ops->resume_prepare) {
 continue;
 }
-if (se->ops && se->ops->is_active) {
+if (se->ops->is_active) {
 if (!se->ops->is_active(se->opaque)) {
 continue;
 }
@@ -1227,7 +1227,7 @@ void qemu_savevm_state_complete_postcopy(QEMUFile *f)
 if (!se->ops || !se->ops->save_live_complete_postcopy) {
 continue;
 }
-if (se->ops && se->ops->is_active) {
+if (se->ops->is_active) {
 if (!se->ops->is_active(se->opaque)) {
 continue;
 }
@@ -1264,7 +1264,7 @@ int qemu_savevm_state_complete_precopy_iterable(QEMUFile 
*f, bool in_postcopy)
 continue;
 }
 
-if (se->ops && se->ops->is_active) {
+if (se->ops->is_active) {
 if (!se->ops->is_active(se->opaque)) {
 continue;
 }
@@ -1413,7 +1413,7 @@ void qemu_savevm_state_pending(QEMUFile *f, uint64_t 
threshold_size,
 if (!se->ops || !se->ops->save_live_pending) {
 continue;
 }
-if (se->ops && se->ops->is_active) {
+if (se->ops->is_active) {
 if (!se->ops->is_active(se->opaque)) {
 continue;
 }
@@ -2334,7 +2334,7 @@ static int qemu_loadvm_state_setup(QEMUFile *f)
 if (!se->ops || !se->ops->load_setup) {
 continue;
 }
-if (se->ops && se->ops->is_active) {
+if (se->ops->is_active) {
 if (!se->ops->is_active(se->opaque)) {
 continue;
 }
-- 
2.17.1




Re: [Qemu-devel] [PATCH 0/6] net/eth: Remove duplicated tcp/udp_hdr structures

2019-08-18 Thread Jason Wang


On 2019/8/19 上午5:38, Philippe Mathieu-Daudé wrote:
> Hi Jason,
>
> On 8/8/19 4:34 PM, Philippe Mathieu-Daudé wrote:
>> This is a preparatory cleanup series.
>>
>> Commit 75020a70215 introduced 4 very equivalent structures:
>> - tcp_header and tcp_hdr,
>> - udp_header and udp_hdr.
>>
>> Choose the most widely use in the codebase, which happens to
>> provide convenient bitfields manipulation macros and is not
>> endian-specific.
>>
>> Philippe Mathieu-Daudé (6):
>>   hw/net/virtio-net: Use TCP_HEADER_FLAGS/TCP_HEADER_DATA_OFFSET macros
>>   net/colo-compare: Use the tcp_header structure
>>   net/filter-rewriter: Use the tcp_header structure
>>   hw/net/vmxnet3: Use the tcp_header structure
>>   net/eth: Remove the unused tcp_hdr structure
>>   net/eth: Remove the single use of udp_hdr structure
> Are you OK to take this series?
>
> It got reviewed by Dmitry Fleytman.
>
> Thanks,
>
> Phil.


Yes. Applied.

Thanks





Re: [Qemu-devel] [PATCH 0/6] Refine exec

2019-08-18 Thread Wei Yang
On Thu, Mar 21, 2019 at 04:25:49PM +0800, Wei Yang wrote:
>This serial refine exec a little.
>

Ping again.

>Wei Yang (6):
>  exec.c: replace hwaddr with uint64_t for better understanding
>  exec.c: remove an unnecessary assert on PHYS_MAP_NODE_NIL in
>phys_map_node_alloc()
>  exec.c: get nodes_nb_alloc with one MAX calculation
>  exec.c: subpage->sub_section is already initialized to 0
>  exec.c: correct the maximum skip value during compact
>  exec.c: add a check between constants to see whether we could skip
>
> exec.c | 21 ++---
> 1 file changed, 10 insertions(+), 11 deletions(-)
>
>-- 
>2.19.1

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v2 1/2] memory-device: not necessary to use goto for the last check

2019-08-18 Thread Wei Yang
On Thu, Aug 08, 2019 at 09:06:21AM +0200, David Hildenbrand wrote:
>On 08.08.19 04:38, Wei Yang wrote:
>> On Thu, Aug 08, 2019 at 02:30:02AM +, Zeng, Star wrote:
 -Original Message-
 From: Wei Yang [mailto:richardw.y...@linux.intel.com]
 Sent: Thursday, August 8, 2019 10:13 AM
 To: Zeng, Star 
 Cc: Wei Yang ; qemu-devel@nongnu.org;
 imamm...@redhat.com; da...@redhat.com; m...@redhat.com
 Subject: Re: [Qemu-devel] [PATCH v2 1/2] memory-device: not necessary to
 use goto for the last check

 On Thu, Aug 08, 2019 at 01:42:14AM +, Zeng, Star wrote:
>> -Original Message-
>> From: Qemu-devel [mailto:qemu-devel-
>> bounces+star.zeng=intel@nongnu.org] On Behalf Of Wei Yang
>> Sent: Tuesday, July 30, 2019 8:38 AM
>> To: qemu-devel@nongnu.org
>> Cc: imamm...@redhat.com; da...@redhat.com; Wei Yang
>> ; m...@redhat.com
>> Subject: [Qemu-devel] [PATCH v2 1/2] memory-device: not necessary to
>> use goto for the last check
>>
>> We are already at the last condition check.
>>
>> Signed-off-by: Wei Yang 
>> Reviewed-by: Igor Mammedov 
>> Reviewed-by: David Hildenbrand 
>> ---
>>  hw/mem/memory-device.c | 1 -
>>  1 file changed, 1 deletion(-)
>>
>> diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
 index
>> 5f2c408036..df3261b32a 100644
>> --- a/hw/mem/memory-device.c
>> +++ b/hw/mem/memory-device.c
>> @@ -186,7 +186,6 @@ static uint64_t
>> memory_device_get_free_addr(MachineState *ms,
>>  if (!range_contains_range(, )) {
>>  error_setg(errp, "could not find position in guest address 
>> space for "
>> "memory device - memory fragmented due to 
>> alignments");
>> -goto out;
>
> Is it better to return 0 (or set new_addr to 0) for this error path and 
> another
 remaining "goto out" path?
>

 I may not get your point.

 We set errp which is handled in its caller. By doing so, the error is 
 propagated.

 Do I miss something?
>>>
>>> Yes, you are right. Currently, the caller is checking errp, but not the 
>>> returned address, so there should be no issue.
>>> But when you see other error paths, you will find they all return 0. To be 
>>> aligned (return 0 when error), so just suggest also returning 0 for these 
>>> two "goto out" error path. :)
>>>
>> 
>> You may have some point.
>> 
>> Let's see whether others have the same taste, or we can refine it separately.
>> 
>
>I don't think that's necessary (callers really should check for errors
>before using the return values), but I would also not object to that change.
>

In case there is no strong requirement to refactor the code. I would leave it
here.

>-- 
>
>Thanks,
>
>David / dhildenb

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH 0/2] migration/qemu-file: cleanup and refine qemu-file

2019-08-18 Thread Wei Yang
On Wed, Jul 31, 2019 at 10:42:23PM +0800, Wei Yang wrote:
>Two cleanup:
>
>Patch #1 make code consistent on calling add_to_iovec
>Patch #2 refine the code to handle the case when buf already flushed
>

Ping~

>Wei Yang (2):
>  migration/qemu-file: remove check on writev_buffer in
>qemu_put_compression_data
>  migration/qemu-file: fix potential buf waste for extra buf_index
>adjustment
>
> migration/qemu-file.c | 44 +++
> 1 file changed, 28 insertions(+), 16 deletions(-)
>
>-- 
>2.17.1

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH] migration: check length directly to make sure the range is aligned

2019-08-18 Thread Wei Yang
On Fri, Jul 19, 2019 at 06:54:00PM +0100, Dr. David Alan Gilbert wrote:
>* Wei Yang (richardw.y...@linux.intel.com) wrote:
>> Since the start addr is already checked, to make sure the range is
>> aligned, checking the length is enough.
>> 
>> Signed-off-by: Wei Yang 
>> ---
>>  exec.c | 7 +++
>>  1 file changed, 3 insertions(+), 4 deletions(-)
>> 
>> diff --git a/exec.c b/exec.c
>> index 50ea9c5aaa..8fa980baae 100644
>> --- a/exec.c
>> +++ b/exec.c
>> @@ -4067,10 +4067,9 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t 
>> start, size_t length)
>>  
>>  if ((start + length) <= rb->used_length) {
>>  bool need_madvise, need_fallocate;
>> -uint8_t *host_endaddr = host_startaddr + length;
>> -if ((uintptr_t)host_endaddr & (rb->page_size - 1)) {
>> -error_report("ram_block_discard_range: Unaligned end address: 
>> %p",
>> - host_endaddr);
>> +if (length & (rb->page_size - 1)) {
>> +error_report("ram_block_discard_range: Unaligned length: %lx",
>> + length);
>
>Yes, I *think* this is safe, we'll need to watch out for any warnings;
>David Gibson's balloon fix from February means that the balloon code
>should now warn in it's case.
>
>rth: Want to pick this up?
>
>Reviewed-by: Dr. David Alan Gilbert 
>

Hi, David

Do you like this one?

>>  goto err;
>>  }
>>  
>> -- 
>> 2.17.1
>> 
>--
>Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v4 14/14] audio: fix memory leak reported by ASAN

2019-08-18 Thread Zoltán Kővágó
Hi,

On 2019-08-19 01:25, Philippe Mathieu-Daudé wrote:
> Hi Zoltán,
> 
> On 8/19/19 1:06 AM, Kővágó, Zoltán wrote:
>> Signed-off-by: Kővágó, Zoltán 
>> ---
>>  audio/audio.c | 6 ++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/audio/audio.c b/audio/audio.c
>> index 924dddf2e7..9b28abca14 100644
>> --- a/audio/audio.c
>> +++ b/audio/audio.c
>> @@ -1343,6 +1343,12 @@ static void free_audio_state(AudioState *s)
>>  qapi_free_Audiodev(s->dev);
>>  s->dev = NULL;
>>  }
>> +
>> +if (s->ts) {
>> +timer_free(s->ts);
>> +s->ts = NULL;
>> +}
> 
> Why not directly fix audio_cleanup() previous to your series?

I didn't really think about it.  When I found the memory leak and
figured out it wasn't made by one of my patches, I just patched it on
top of my worktree.

> 
>> +
>>  g_free(s);
>>  }
>>  
>>

Regards,
Zoltan



Re: [Qemu-devel] [PATCH 1/3] pc: Fix error message on die-id validation

2019-08-18 Thread Like Xu

On 2019/8/16 21:49, Eduardo Habkost wrote:

On Fri, Aug 16, 2019 at 09:04:16AM +0800, Like Xu wrote:

Hi,

On 2019/8/16 2:38, Eduardo Habkost wrote:

The error message for die-id range validation is incorrect.  Example:

$ qemu-system-x86_64 -smp 1,sockets=6,maxcpus=6 \
  -device qemu64-x86_64-cpu,socket-id=1,die-id=1,core-id=0,thread-id=0
qemu-system-x86_64: -device 
qemu64-x86_64-cpu,socket-id=1,die-id=1,core-id=0,thread-id=0: \
  Invalid CPU die-id: 1 must be in range 0:5

The actual range for die-id in this example is 0:0.


There is one die per socket by default.

The case sockets=6 means there are 6 dies by default
and the range for die-id is 0:5.



I don't understand why you say that.  die-id supposed to identify
a die inside a socket.  The code below is already checking for
(cpu->die_id > pcms->smp_dies - 1) because of that.



You're right about this.
Sorry to make a mess to support die topology.





Fix the error message to use smp_dies and print the correct range.

Signed-off-by: Eduardo Habkost 
---
   hw/i386/pc.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 549c437050..24b03bb49c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2412,7 +2412,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
   return;
   } else if (cpu->die_id > pcms->smp_dies - 1) {
   error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u",
-   cpu->die_id, max_socket);
+   cpu->die_id, pcms->smp_dies - 1);
   return;
   }
   if (cpu->core_id < 0) {










[Qemu-devel] Machine specific option ROMs

2019-08-18 Thread BALATON Zoltan

Hello,

I know about the possibility to set the option ROM of a PCIDevice with the 
romfile property (that we can set on command line or in a device's init 
method) but is there a way to set it depending on the machine that uses 
the device? If this is not currently possible what would be needed to 
allow this?


I'm asking because some cards may have different option ROMs on different 
platforms: e.g. gfx cards need different ROM on Mac than on PC due to 
using different firmware (and CPU arch). For Mac machines emulated by QEMU 
OpenBIOS now patches in a driver that it downloads via FW_CFG but it could 
use an FCode ROM (or the driver directly passed as the ROM image) instead 
which would be a simpler solution and more like how real hardware works. 
Also sam460ex firmware has a BIOS emulator for using PC option ROMs but 
that can't run QEMU vgabios binaries (as these are i386 real mode and it 
can only run x86 real mode) so we may need a way to specify a different 
ROM if the card is used in sam460ex.


So I'm looking for a way for board code to set romfile when the device is 
added to the board. Should the normal way of setting a property work for 
this or is that too late by then to change ROM of the device? (Also this 
may need to work together with the -vga option to ensure card has the 
right ROM on different machines even if added by -vga.)


Regards,
BALATON Zoltan



Re: [Qemu-devel] [PATCH v4 00/14] Multiple simultaneous audio backends

2019-08-18 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/cover.1566168923.git.dirty.ice...@gmail.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [PATCH v4 00/14] Multiple simultaneous audio backends
Message-id: cover.1566168923.git.dirty.ice...@gmail.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/cover.1566168923.git.dirty.ice...@gmail.com -> 
patchew/cover.1566168923.git.dirty.ice...@gmail.com
Submodule 'capstone' (https://git.qemu.org/git/capstone.git) registered for 
path 'capstone'
Submodule 'dtc' (https://git.qemu.org/git/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (https://git.qemu.org/git/QemuMacDrivers.git) 
registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (https://git.qemu.org/git/SLOF.git) registered for path 
'roms/SLOF'
Submodule 'roms/edk2' (https://git.qemu.org/git/edk2.git) registered for path 
'roms/edk2'
Submodule 'roms/ipxe' (https://git.qemu.org/git/ipxe.git) registered for path 
'roms/ipxe'
Submodule 'roms/openbios' (https://git.qemu.org/git/openbios.git) registered 
for path 'roms/openbios'
Submodule 'roms/openhackware' (https://git.qemu.org/git/openhackware.git) 
registered for path 'roms/openhackware'
Submodule 'roms/opensbi' (https://git.qemu.org/git/opensbi.git) registered for 
path 'roms/opensbi'
Submodule 'roms/qemu-palcode' (https://git.qemu.org/git/qemu-palcode.git) 
registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (https://git.qemu.org/git/seabios.git/) registered for 
path 'roms/seabios'
Submodule 'roms/seabios-hppa' (https://git.qemu.org/git/seabios-hppa.git) 
registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (https://git.qemu.org/git/sgabios.git) registered for 
path 'roms/sgabios'
Submodule 'roms/skiboot' (https://git.qemu.org/git/skiboot.git) registered for 
path 'roms/skiboot'
Submodule 'roms/u-boot' (https://git.qemu.org/git/u-boot.git) registered for 
path 'roms/u-boot'
Submodule 'roms/u-boot-sam460ex' (https://git.qemu.org/git/u-boot-sam460ex.git) 
registered for path 'roms/u-boot-sam460ex'
Submodule 'slirp' (https://git.qemu.org/git/libslirp.git) registered for path 
'slirp'
Submodule 'tests/fp/berkeley-softfloat-3' 
(https://git.qemu.org/git/berkeley-softfloat-3.git) registered for path 
'tests/fp/berkeley-softfloat-3'
Submodule 'tests/fp/berkeley-testfloat-3' 
(https://git.qemu.org/git/berkeley-testfloat-3.git) registered for path 
'tests/fp/berkeley-testfloat-3'
Submodule 'ui/keycodemapdb' (https://git.qemu.org/git/keycodemapdb.git) 
registered for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out 
'22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '88f18909db731a627456f26d779445f84e449536'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 
'90c488d5f4a407342247b9ea869df1c2d9c8e266'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 
'ba1ab360eebe6338bb8d7d83a9220ccf7e213af3'
Cloning into 'roms/edk2'...
Submodule path 'roms/edk2': checked out 
'20d2e5a125e34fc8501026613a71549b2a1a3e54'
Submodule 'SoftFloat' (https://github.com/ucb-bar/berkeley-softfloat-3.git) 
registered for path 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'
Submodule 'CryptoPkg/Library/OpensslLib/openssl' 
(https://github.com/openssl/openssl) registered for path 
'CryptoPkg/Library/OpensslLib/openssl'
Cloning into 'ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3'...
Submodule path 'roms/edk2/ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3': 
checked out 'b64af41c3276f97f0e181920400ee056b9c88037'
Cloning into 'CryptoPkg/Library/OpensslLib/openssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl': checked out 
'50eaac9f3337667259de725451f201e784599687'
Submodule 'boringssl' (https://boringssl.googlesource.com/boringssl) registered 
for path 'boringssl'
Submodule 'krb5' (https://github.com/krb5/krb5) registered for path 'krb5'
Submodule 'pyca.cryptography' (https://github.com/pyca/cryptography.git) 
registered for path 'pyca-cryptography'
Cloning into 'boringssl'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/boringssl': 
checked out '2070f8ad9151dc8f3a73bffaa146b5e6937a583f'
Cloning into 'krb5'...
Submodule path 'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/krb5': checked 
out 'b9ad6c49505c96a088326b62a52568e3484f2168'
Cloning into 'pyca-cryptography'...
Submodule path 
'roms/edk2/CryptoPkg/Library/OpensslLib/openssl/pyca-cryptography': checked out 
'09403100de2f6f1cdd0d484dcb8e620f1c335c8f'
Cloning into 'roms/ipxe'...

Re: [Qemu-devel] [PATCH v4 14/14] audio: fix memory leak reported by ASAN

2019-08-18 Thread Philippe Mathieu-Daudé
Hi Zoltán,

On 8/19/19 1:06 AM, Kővágó, Zoltán wrote:
> Signed-off-by: Kővágó, Zoltán 
> ---
>  audio/audio.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/audio/audio.c b/audio/audio.c
> index 924dddf2e7..9b28abca14 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -1343,6 +1343,12 @@ static void free_audio_state(AudioState *s)
>  qapi_free_Audiodev(s->dev);
>  s->dev = NULL;
>  }
> +
> +if (s->ts) {
> +timer_free(s->ts);
> +s->ts = NULL;
> +}

Why not directly fix audio_cleanup() previous to your series?

> +
>  g_free(s);
>  }
>  
> 



[Qemu-devel] [PATCH 4/4] tests/docker: Use Travis-CI default environment variables

2019-08-18 Thread Philippe Mathieu-Daudé
Update to environment variables of our Docker image to closely
reproduce the builds run by the Travis-CI service.

Default variables from:
https://docs.travis-ci.com/user/environment-variables/#default-environment-variables

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/docker/dockerfiles/travis.docker | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tests/docker/dockerfiles/travis.docker 
b/tests/docker/dockerfiles/travis.docker
index b5c5036534..a0e8152317 100644
--- a/tests/docker/dockerfiles/travis.docker
+++ b/tests/docker/dockerfiles/travis.docker
@@ -1,7 +1,11 @@
 FROM travisci/ci-sardonyx:packer-1546978056-2c98a19
-ENV DEBIAN_FRONTEND noninteractive
-ENV LANG en_US.UTF-8
-ENV LC_ALL en_US.UTF-8
+ENV CI=true \
+TRAVIS=true \
+CONTINUOUS_INTEGRATION=true \
+DEBIAN_FRONTEND=noninteractive \
+LANG=en_US.UTF-8 \
+LC_ALL=en_US.UTF-8 \
+TRAVIS_OS_NAME=linux
 RUN sed -i "s/# deb-src/deb-src/" /etc/apt/sources.list
 RUN apt-get update
 RUN apt-get -y build-dep qemu
-- 
2.20.1




[Qemu-devel] [PATCH 3/4] tests/docker: Add test-acceptance runner

2019-08-18 Thread Philippe Mathieu-Daudé
Add a runner script to be able to run acceptance tests within
Docker images. We can now reproduce Travis CI builds locally (and
debug  them!).

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/docker/test-acceptance | 21 +
 1 file changed, 21 insertions(+)
 create mode 100755 tests/docker/test-acceptance

diff --git a/tests/docker/test-acceptance b/tests/docker/test-acceptance
new file mode 100755
index 00..84edaa676c
--- /dev/null
+++ b/tests/docker/test-acceptance
@@ -0,0 +1,21 @@
+#!/bin/bash -e
+#
+# Compile default Travis-CI target and run Avocado acceptance tests
+#
+# Copyright (c) 2019 Red Hat Inc.
+#
+# Authors:
+#  Philippe Mathieu-Daudé 
+#
+# This work is licensed under the terms of the GNU GPL, version 2
+# or (at your option) any later version. See the COPYING file in
+# the top-level directory.
+
+. common.rc
+
+cd "$BUILD_DIR"
+
+DEF_TARGET_LIST="x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu"
+TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \
+build_qemu
+check_qemu check-acceptance
-- 
2.20.1




[Qemu-devel] [PATCH 1/4] tests/docker: Use one package per line to improve readability

2019-08-18 Thread Philippe Mathieu-Daudé
Use one package per line to improve readability. This also
helps while reviewing patches.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/docker/dockerfiles/travis.docker | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tests/docker/dockerfiles/travis.docker 
b/tests/docker/dockerfiles/travis.docker
index e72dc85ca7..35714664a1 100644
--- a/tests/docker/dockerfiles/travis.docker
+++ b/tests/docker/dockerfiles/travis.docker
@@ -5,7 +5,15 @@ ENV LC_ALL en_US.UTF-8
 RUN sed -i "s/# deb-src/deb-src/" /etc/apt/sources.list
 RUN apt-get update
 RUN apt-get -y build-dep qemu
-RUN apt-get -y install device-tree-compiler python2.7 python-yaml 
dh-autoreconf gdb strace lsof net-tools gcovr
+RUN apt-get -y install \
+device-tree-compiler \
+dh-autoreconf \
+gcovr \
+gdb strace \
+lsof \
+net-tools \
+python2.7 \
+python-yaml
 # Travis tools require PhantomJS / Neo4j / Maven accessible
 # in their PATH (QEMU build won't access them).
 ENV PATH 
/usr/local/phantomjs/bin:/usr/local/phantomjs:/usr/local/neo4j-3.2.7/bin:/usr/local/maven-3.5.2/bin:/usr/local/cmake-3.9.2/bin:/usr/local/clang-5.0.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-- 
2.20.1




[Qemu-devel] [PATCH v4 13/14] audio: use size_t where makes sense

2019-08-18 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán 
---

Notes:
Changes from v3:

* (Hopefully) fix windows build

 audio/audio.h   |   4 +-
 audio/audio_int.h   |  26 +++
 audio/audio_template.h  |  14 ++--
 audio/mixeng.h  |   9 +--
 audio/rate_template.h   |   2 +-
 include/sysemu/replay.h |   4 +-
 audio/alsaaudio.c   |  26 +++
 audio/audio.c   | 156 
 audio/coreaudio.c   |  10 +--
 audio/dsoundaudio.c |  17 ++---
 audio/noaudio.c |  16 ++---
 audio/ossaudio.c|  45 ++--
 audio/paaudio.c |  44 ++--
 audio/sdlaudio.c|  20 +++---
 audio/spiceaudio.c  |  12 ++--
 audio/wavaudio.c|   8 +--
 replay/replay-audio.c   |  16 ++---
 replay/replay.c |   2 +-
 18 files changed, 215 insertions(+), 216 deletions(-)

diff --git a/audio/audio.h b/audio/audio.h
index 96e22887a0..c74abb8c47 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -113,7 +113,7 @@ SWVoiceOut *AUD_open_out (
 );
 
 void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
-int  AUD_write (SWVoiceOut *sw, void *pcm_buf, int size);
+size_t AUD_write (SWVoiceOut *sw, void *pcm_buf, size_t size);
 int  AUD_get_buffer_size_out (SWVoiceOut *sw);
 void AUD_set_active_out (SWVoiceOut *sw, int on);
 int  AUD_is_active_out (SWVoiceOut *sw);
@@ -134,7 +134,7 @@ SWVoiceIn *AUD_open_in (
 );
 
 void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
-int  AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
+size_t AUD_read (SWVoiceIn *sw, void *pcm_buf, size_t size);
 void AUD_set_active_in (SWVoiceIn *sw, int on);
 int  AUD_is_active_in (SWVoiceIn *sw);
 
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 003b7ab8cc..a674c5374a 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -61,12 +61,12 @@ typedef struct HWVoiceOut {
 
 f_sample *clip;
 
-int rpos;
+size_t rpos;
 uint64_t ts_helper;
 
 struct st_sample *mix_buf;
 
-int samples;
+size_t samples;
 QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
 QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
 int ctl_caps;
@@ -82,13 +82,13 @@ typedef struct HWVoiceIn {
 
 t_sample *conv;
 
-int wpos;
-int total_samples_captured;
+size_t wpos;
+size_t total_samples_captured;
 uint64_t ts_helper;
 
 struct st_sample *conv_buf;
 
-int samples;
+size_t samples;
 QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
 int ctl_caps;
 struct audio_pcm_ops *pcm_ops;
@@ -103,7 +103,7 @@ struct SWVoiceOut {
 int64_t ratio;
 struct st_sample *buf;
 void *rate;
-int total_hw_samples_mixed;
+size_t total_hw_samples_mixed;
 int active;
 int empty;
 HWVoiceOut *hw;
@@ -120,7 +120,7 @@ struct SWVoiceIn {
 struct audio_pcm_info info;
 int64_t ratio;
 void *rate;
-int total_hw_samples_acquired;
+size_t total_hw_samples_acquired;
 struct st_sample *buf;
 f_sample *clip;
 HWVoiceIn *hw;
@@ -149,12 +149,12 @@ struct audio_driver {
 struct audio_pcm_ops {
 int  (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_out)(HWVoiceOut *hw);
-int  (*run_out) (HWVoiceOut *hw, int live);
+size_t (*run_out)(HWVoiceOut *hw, size_t live);
 int  (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
 
 int  (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_in) (HWVoiceIn *hw);
-int  (*run_in)  (HWVoiceIn *hw);
+size_t (*run_in)(HWVoiceIn *hw);
 int  (*ctl_in)  (HWVoiceIn *hw, int cmd, ...);
 };
 
@@ -208,10 +208,10 @@ audio_driver *audio_driver_lookup(const char *name);
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int 
len);
 
-int  audio_pcm_hw_get_live_in (HWVoiceIn *hw);
+size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw);
 
-int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
-   int live, int pending);
+size_t audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf,
+ size_t live, size_t pending);
 
 int audio_bug (const char *funcname, int cond);
 void *audio_calloc (const char *funcname, int nmemb, size_t size);
@@ -224,7 +224,7 @@ void audio_run(AudioState *s, const char *msg);
 
 #define VOICE_VOLUME_CAP (1 << VOICE_VOLUME)
 
-static inline int audio_ring_dist (int dst, int src, int len)
+static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len)
 {
 return (dst >= src) ? (dst - src) : (len - src + dst);
 }
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 54f07338e7..2562bf5f00 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -75,16 +75,16 @@ static void glue (audio_pcm_hw_free_resources_, TYPE) (HW 
*hw)
 HWBUF = NULL;
 }
 
-static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
+static bool 

[Qemu-devel] [PATCH 2/4] tests/docker: update our Travis image to run acceptance tests locally

2019-08-18 Thread Philippe Mathieu-Daudé
Since commit aa983ff67c3, Travis CI runs acceptance tests using
the Avocado framework. Since Avocado requires Python 3, update
our Docker image to be able to run these tests locally.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/docker/dockerfiles/travis.docker | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/docker/dockerfiles/travis.docker 
b/tests/docker/dockerfiles/travis.docker
index 35714664a1..b5c5036534 100644
--- a/tests/docker/dockerfiles/travis.docker
+++ b/tests/docker/dockerfiles/travis.docker
@@ -13,6 +13,8 @@ RUN apt-get -y install \
 lsof \
 net-tools \
 python2.7 \
+python3-pip \
+python3.5-venv \
 python-yaml
 # Travis tools require PhantomJS / Neo4j / Maven accessible
 # in their PATH (QEMU build won't access them).
-- 
2.20.1




[Qemu-devel] [PATCH 0/4] docker: Update Travis-CI image to run acceptance tests

2019-08-18 Thread Philippe Mathieu-Daudé
This series adds a 'test-acceptance' Docker target, so we can
run 'make docker-test-acceptance@travis' similarly to how the
Travis-CI service runs its builds.

This is particularly useful to debug Travis-CI failures locally.

Regards,

Phil.

Philippe Mathieu-Daudé (4):
  tests/docker: Use one package per line to improve readability
  tests/docker: update our Travis image to run acceptance tests locally
  tests/docker: Add test-acceptance runner
  tests/docker: Use Travis-CI default environment variables

 tests/docker/dockerfiles/travis.docker | 22 ++
 tests/docker/test-acceptance   | 21 +
 2 files changed, 39 insertions(+), 4 deletions(-)
 create mode 100755 tests/docker/test-acceptance

-- 
2.20.1




[Qemu-devel] [PATCH v4 12/14] audio: remove read and write pcm_ops

2019-08-18 Thread Kővágó, Zoltán
They just called audio_pcm_sw_read/write anyway, so it makes no sense
to have them too.  (The noaudio's read is the only exception, but it
should work with the generic code too.)

Signed-off-by: Kővágó, Zoltán 
---
 audio/audio_int.h   |  5 -
 audio/alsaaudio.c   | 12 
 audio/audio.c   |  8 
 audio/coreaudio.c   |  6 --
 audio/dsoundaudio.c | 12 
 audio/noaudio.c | 19 ---
 audio/ossaudio.c| 12 
 audio/paaudio.c | 12 
 audio/sdlaudio.c|  6 --
 audio/spiceaudio.c  | 12 
 audio/wavaudio.c|  6 --
 11 files changed, 4 insertions(+), 106 deletions(-)

diff --git a/audio/audio_int.h b/audio/audio_int.h
index 7e00c1332e..003b7ab8cc 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -150,13 +150,11 @@ struct audio_pcm_ops {
 int  (*init_out)(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_out)(HWVoiceOut *hw);
 int  (*run_out) (HWVoiceOut *hw, int live);
-int  (*write)   (SWVoiceOut *sw, void *buf, int size);
 int  (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
 
 int  (*init_in) (HWVoiceIn *hw, struct audsettings *as, void *drv_opaque);
 void (*fini_in) (HWVoiceIn *hw);
 int  (*run_in)  (HWVoiceIn *hw);
-int  (*read)(SWVoiceIn *sw, void *buf, int size);
 int  (*ctl_in)  (HWVoiceIn *hw, int cmd, ...);
 };
 
@@ -210,11 +208,8 @@ audio_driver *audio_driver_lookup(const char *name);
 void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int 
len);
 
-int  audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
 int  audio_pcm_hw_get_live_in (HWVoiceIn *hw);
 
-int  audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
-
 int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
int live, int pending);
 
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 3daa7c8f8f..e9e3a4819c 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -270,11 +270,6 @@ static int alsa_poll_in (HWVoiceIn *hw)
 return alsa_poll_helper (alsa->handle, >pollhlp, POLLIN);
 }
 
-static int alsa_write (SWVoiceOut *sw, void *buf, int len)
-{
-return audio_pcm_sw_write (sw, buf, len);
-}
-
 static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
 {
 switch (fmt) {
@@ -988,11 +983,6 @@ static int alsa_run_in (HWVoiceIn *hw)
 return read_samples;
 }
 
-static int alsa_read (SWVoiceIn *sw, void *buf, int size)
-{
-return audio_pcm_sw_read (sw, buf, size);
-}
-
 static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
 {
 ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
@@ -1076,13 +1066,11 @@ static struct audio_pcm_ops alsa_pcm_ops = {
 .init_out = alsa_init_out,
 .fini_out = alsa_fini_out,
 .run_out  = alsa_run_out,
-.write= alsa_write,
 .ctl_out  = alsa_ctl_out,
 
 .init_in  = alsa_init_in,
 .fini_in  = alsa_fini_in,
 .run_in   = alsa_run_in,
-.read = alsa_read,
 .ctl_in   = alsa_ctl_in,
 };
 
diff --git a/audio/audio.c b/audio/audio.c
index cb6a9d8ac5..43db134bb9 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -594,7 +594,7 @@ static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
 }
 }
 
-int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
+static int audio_pcm_sw_read(SWVoiceIn *sw, void *buf, int size)
 {
 HWVoiceIn *hw = sw->hw;
 int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
@@ -696,7 +696,7 @@ static int audio_pcm_hw_get_live_out (HWVoiceOut *hw, int 
*nb_live)
 /*
  * Soft voice (playback)
  */
-int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
+static int audio_pcm_sw_write(SWVoiceOut *sw, void *buf, int size)
 {
 int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
 int ret = 0, pos = 0, total = 0;
@@ -854,7 +854,7 @@ int AUD_write (SWVoiceOut *sw, void *buf, int size)
 return 0;
 }
 
-return sw->hw->pcm_ops->write(sw, buf, size);
+return audio_pcm_sw_write(sw, buf, size);
 }
 
 int AUD_read (SWVoiceIn *sw, void *buf, int size)
@@ -869,7 +869,7 @@ int AUD_read (SWVoiceIn *sw, void *buf, int size)
 return 0;
 }
 
-return sw->hw->pcm_ops->read(sw, buf, size);
+return audio_pcm_sw_read(sw, buf, size);
 }
 
 int AUD_get_buffer_size_out (SWVoiceOut *sw)
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index f0ab4014a8..091fe84a34 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -489,11 +489,6 @@ static OSStatus audioDeviceIOProc(
 return 0;
 }
 
-static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
-{
-return audio_pcm_sw_write (sw, buf, len);
-}
-
 static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
   void *drv_opaque)
 {
@@ -692,7 +687,6 @@ static struct audio_pcm_ops coreaudio_pcm_ops = {
 .init_out = coreaudio_init_out,
 .fini_out = 

[Qemu-devel] [PATCH v4 14/14] audio: fix memory leak reported by ASAN

2019-08-18 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán 
---
 audio/audio.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/audio/audio.c b/audio/audio.c
index 924dddf2e7..9b28abca14 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1343,6 +1343,12 @@ static void free_audio_state(AudioState *s)
 qapi_free_Audiodev(s->dev);
 s->dev = NULL;
 }
+
+if (s->ts) {
+timer_free(s->ts);
+s->ts = NULL;
+}
+
 g_free(s);
 }
 
-- 
2.22.0




[Qemu-devel] [PATCH v4 11/14] paaudio: fix playback glitches

2019-08-18 Thread Kővágó, Zoltán
Pulseaudio normally assumes that when the server wants it, the client
can generate the audio samples and send it right away.  Unfortunately
this is not the case with QEMU -- it's up to the emulated system when
does it generate the samples.  Buffering the samples and sending them
from a background thread is just a workaround, that doesn't work too
well.  Instead enable pa's compatibility support and let pa worry about
the details.

Signed-off-by: Kővágó, Zoltán 
---
 audio/paaudio.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index f3864e1d50..c8ae1a6eca 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -512,10 +512,8 @@ static pa_stream *qpa_simple_new (
 
 flags =
 PA_STREAM_INTERPOLATE_TIMING
-#ifdef PA_STREAM_ADJUST_LATENCY
-| PA_STREAM_ADJUST_LATENCY
-#endif
-| PA_STREAM_AUTO_TIMING_UPDATE;
+| PA_STREAM_AUTO_TIMING_UPDATE
+| PA_STREAM_EARLY_REQUESTS;
 
 if (dev) {
 /* don't move the stream if the user specified a sink/source */
-- 
2.22.0




[Qemu-devel] [PATCH v4 07/14] paaudio: do not move stream when sink/source name is specified

2019-08-18 Thread Kővágó, Zoltán
Unless we disable stream moving, pulseaudio can easily move the stream
on connect, effectively ignoring the source/sink specified by the user.

Signed-off-by: Kővágó, Zoltán 
Reviewed-by: Marc-André Lureau 
---
 audio/paaudio.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index cc3a34c2ea..24d98b344a 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -517,6 +517,11 @@ static pa_stream *qpa_simple_new (
 #endif
 | PA_STREAM_AUTO_TIMING_UPDATE;
 
+if (dev) {
+/* don't move the stream if the user specified a sink/source */
+flags |= PA_STREAM_DONT_MOVE;
+}
+
 if (dir == PA_STREAM_PLAYBACK) {
 r = pa_stream_connect_playback(stream, dev, attr, flags, NULL, NULL);
 } else {
-- 
2.22.0




[Qemu-devel] [PATCH v4 05/14] paaudio: prepare for multiple audiodev

2019-08-18 Thread Kővágó, Zoltán
Have a pool of refcounted connections per server, so if the user creates
multiple audiodevs to the same pa server, it will use a single connection.  (It
will still create different streams, so the user can manage those streams
separately in pulseaudio.)

Signed-off-by: Kővágó, Zoltán 
---
 audio/paaudio.c | 329 +++-
 1 file changed, 188 insertions(+), 141 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 5fc886bb33..cc3a34c2ea 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -11,10 +11,21 @@
 #include "audio_int.h"
 #include "audio_pt_int.h"
 
-typedef struct {
-Audiodev *dev;
+typedef struct PAConnection {
+char *server;
+int refcount;
+QTAILQ_ENTRY(PAConnection) list;
+
 pa_threaded_mainloop *mainloop;
 pa_context *context;
+} PAConnection;
+
+static QTAILQ_HEAD(PAConnectionHead, PAConnection) pa_conns =
+QTAILQ_HEAD_INITIALIZER(pa_conns);
+
+typedef struct {
+Audiodev *dev;
+PAConnection *conn;
 } paaudio;
 
 typedef struct {
@@ -45,7 +56,7 @@ typedef struct {
 int samples;
 } PAVoiceIn;
 
-static void qpa_audio_fini(void *opaque);
+static void qpa_conn_fini(PAConnection *c);
 
 static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
 {
@@ -108,11 +119,11 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
 
 static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int 
*rerror)
 {
-paaudio *g = p->g;
+PAConnection *c = p->g->conn;
 
-pa_threaded_mainloop_lock (g->mainloop);
+pa_threaded_mainloop_lock(c->mainloop);
 
-CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
+CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail);
 
 while (length > 0) {
 size_t l;
@@ -121,11 +132,11 @@ static int qpa_simple_read (PAVoiceIn *p, void *data, 
size_t length, int *rerror
 int r;
 
 r = pa_stream_peek (p->stream, >read_data, >read_length);
-CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
+CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail);
 
 if (!p->read_data) {
-pa_threaded_mainloop_wait (g->mainloop);
-CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
+pa_threaded_mainloop_wait(c->mainloop);
+CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail);
 } else {
 p->read_index = 0;
 }
@@ -148,53 +159,53 @@ static int qpa_simple_read (PAVoiceIn *p, void *data, 
size_t length, int *rerror
 p->read_length = 0;
 p->read_index = 0;
 
-CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
+CHECK_SUCCESS_GOTO(c, rerror, r == 0, unlock_and_fail);
 }
 }
 
-pa_threaded_mainloop_unlock (g->mainloop);
+pa_threaded_mainloop_unlock(c->mainloop);
 return 0;
 
 unlock_and_fail:
-pa_threaded_mainloop_unlock (g->mainloop);
+pa_threaded_mainloop_unlock(c->mainloop);
 return -1;
 }
 
 static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, 
int *rerror)
 {
-paaudio *g = p->g;
+PAConnection *c = p->g->conn;
 
-pa_threaded_mainloop_lock (g->mainloop);
+pa_threaded_mainloop_lock(c->mainloop);
 
-CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
+CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail);
 
 while (length > 0) {
 size_t l;
 int r;
 
 while (!(l = pa_stream_writable_size (p->stream))) {
-pa_threaded_mainloop_wait (g->mainloop);
-CHECK_DEAD_GOTO (g, p->stream, rerror, unlock_and_fail);
+pa_threaded_mainloop_wait(c->mainloop);
+CHECK_DEAD_GOTO(c, p->stream, rerror, unlock_and_fail);
 }
 
-CHECK_SUCCESS_GOTO (g, rerror, l != (size_t) -1, unlock_and_fail);
+CHECK_SUCCESS_GOTO(c, rerror, l != (size_t) -1, unlock_and_fail);
 
 if (l > length) {
 l = length;
 }
 
 r = pa_stream_write (p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
-CHECK_SUCCESS_GOTO (g, rerror, r >= 0, unlock_and_fail);
+CHECK_SUCCESS_GOTO(c, rerror, r >= 0, unlock_and_fail);
 
 data = (const uint8_t *) data + l;
 length -= l;
 }
 
-pa_threaded_mainloop_unlock (g->mainloop);
+pa_threaded_mainloop_unlock(c->mainloop);
 return 0;
 
 unlock_and_fail:
-pa_threaded_mainloop_unlock (g->mainloop);
+pa_threaded_mainloop_unlock(c->mainloop);
 return -1;
 }
 
@@ -432,13 +443,13 @@ static AudioFormat pa_to_audfmt (pa_sample_format_t fmt, 
int *endianness)
 
 static void context_state_cb (pa_context *c, void *userdata)
 {
-paaudio *g = userdata;
+PAConnection *conn = userdata;
 
 switch (pa_context_get_state(c)) {
 case PA_CONTEXT_READY:
 case PA_CONTEXT_TERMINATED:
 case PA_CONTEXT_FAILED:
-pa_threaded_mainloop_signal (g->mainloop, 0);
+

[Qemu-devel] [PATCH v4 09/14] audio: remove audio_MIN, audio_MAX

2019-08-18 Thread Kővágó, Zoltán
There's already a MIN and MAX macro in include/qemu/osdep.h, use them
instead.

Signed-off-by: Kővágó, Zoltán 
Reviewed-by: Marc-André Lureau 
---
 audio/audio.h | 17 -
 audio/alsaaudio.c |  6 +++---
 audio/audio.c | 20 ++--
 audio/coreaudio.c |  2 +-
 audio/dsoundaudio.c   |  2 +-
 audio/noaudio.c   | 10 +-
 audio/ossaudio.c  |  6 +++---
 audio/paaudio.c   | 12 ++--
 audio/sdlaudio.c  |  6 +++---
 audio/spiceaudio.c| 10 +-
 audio/wavaudio.c  |  4 ++--
 hw/audio/ac97.c   | 10 +-
 hw/audio/adlib.c  |  4 ++--
 hw/audio/cs4231a.c|  4 ++--
 hw/audio/es1370.c |  6 +++---
 hw/audio/gus.c|  6 +++---
 hw/audio/hda-codec.c  | 16 
 hw/audio/milkymist-ac97.c |  8 
 hw/audio/pcspk.c  |  2 +-
 hw/audio/sb16.c   |  2 +-
 hw/audio/wm8750.c |  4 ++--
 21 files changed, 70 insertions(+), 87 deletions(-)

diff --git a/audio/audio.h b/audio/audio.h
index 3257165b05..96e22887a0 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -147,23 +147,6 @@ static inline void *advance (void *p, int incr)
 return (d + incr);
 }
 
-#ifdef __GNUC__
-#define audio_MIN(a, b) ( __extension__ ({  \
-__typeof (a) ta = a;\
-__typeof (b) tb = b;\
-((ta)>(tb)?(tb):(ta));  \
-}))
-
-#define audio_MAX(a, b) ( __extension__ ({  \
-__typeof (a) ta = a;\
-__typeof (b) tb = b;\
-((ta)<(tb)?(tb):(ta));  \
-}))
-#else
-#define audio_MIN(a, b) ((a)>(b)?(b):(a))
-#define audio_MAX(a, b) ((a)<(b)?(b):(a))
-#endif
-
 int wav_start_capture(AudioState *state, CaptureState *s, const char *path,
   int freq, int bits, int nchannels);
 
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 3745c823ad..6b9e0f06af 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -634,7 +634,7 @@ static void alsa_write_pending (ALSAVoiceOut *alsa)
 
 while (alsa->pending) {
 int left_till_end_samples = hw->samples - alsa->wpos;
-int len = audio_MIN (alsa->pending, left_till_end_samples);
+int len = MIN (alsa->pending, left_till_end_samples);
 char *src = advance (alsa->pcm_buf, alsa->wpos << hw->info.shift);
 
 while (len) {
@@ -697,7 +697,7 @@ static int alsa_run_out (HWVoiceOut *hw, int live)
 return 0;
 }
 
-decr = audio_MIN (live, avail);
+decr = MIN (live, avail);
 decr = audio_pcm_hw_clip_out (hw, alsa->pcm_buf, decr, alsa->pending);
 alsa->pending += decr;
 alsa_write_pending (alsa);
@@ -915,7 +915,7 @@ static int alsa_run_in (HWVoiceIn *hw)
 }
 }
 
-decr = audio_MIN (dead, avail);
+decr = MIN (dead, avail);
 if (!decr) {
 return 0;
 }
diff --git a/audio/audio.c b/audio/audio.c
index 7267cab9d7..100c3ea177 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -533,7 +533,7 @@ static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
 
 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
 if (sw->active) {
-m = audio_MIN (m, sw->total_hw_samples_acquired);
+m = MIN (m, sw->total_hw_samples_acquired);
 }
 }
 return m;
@@ -553,14 +553,14 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
int live, int pending)
 {
 int left = hw->samples - pending;
-int len = audio_MIN (left, live);
+int len = MIN (left, live);
 int clipped = 0;
 
 while (len) {
 struct st_sample *src = hw->mix_buf + hw->rpos;
 uint8_t *dst = advance (pcm_buf, hw->rpos << hw->info.shift);
 int samples_till_end_of_buf = hw->samples - hw->rpos;
-int samples_to_clip = audio_MIN (len, samples_till_end_of_buf);
+int samples_to_clip = MIN (len, samples_till_end_of_buf);
 
 hw->clip (dst, src, samples_to_clip);
 
@@ -614,7 +614,7 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
 }
 
 swlim = (live * sw->ratio) >> 32;
-swlim = audio_MIN (swlim, samples);
+swlim = MIN (swlim, samples);
 
 while (swlim) {
 src = hw->conv_buf + rpos;
@@ -662,7 +662,7 @@ static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int 
*nb_livep)
 
 for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
 if (sw->active || !sw->empty) {
-m = audio_MIN (m, sw->total_hw_samples_mixed);
+m = MIN (m, sw->total_hw_samples_mixed);
 nb_live += 1;
 }
 }
@@ -725,7 +725,7 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
 
 dead = hwsamples - live;
 swlim = ((int64_t) dead << 32) / sw->ratio;
-swlim = audio_MIN (swlim, samples);
+swlim = MIN (swlim, samples);
 if (swlim) {
 sw->conv (sw->buf, buf, 

[Qemu-devel] [PATCH v4 10/14] audio: do not run each backend in audio_run

2019-08-18 Thread Kővágó, Zoltán
audio_run is called manually by alsa and oss backends when polling.
In this case only the requesting backend should be run, not all of them.

Signed-off-by: Kővágó, Zoltán 
Reviewed-by: Marc-André Lureau 
---
 audio/audio_int.h |  2 +-
 audio/alsaaudio.c |  7 +--
 audio/audio.c | 14 +-
 audio/ossaudio.c  | 12 ++--
 4 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/audio/audio_int.h b/audio/audio_int.h
index 9f01f6ad00..7e00c1332e 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -221,7 +221,7 @@ int audio_pcm_hw_clip_out (HWVoiceOut *hw, void *pcm_buf,
 int audio_bug (const char *funcname, int cond);
 void *audio_calloc (const char *funcname, int nmemb, size_t size);
 
-void audio_run (const char *msg);
+void audio_run(AudioState *s, const char *msg);
 
 #define VOICE_ENABLE 1
 #define VOICE_DISABLE 2
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 6b9e0f06af..3daa7c8f8f 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -39,6 +39,7 @@ struct pollhlp {
 struct pollfd *pfds;
 int count;
 int mask;
+AudioState *s;
 };
 
 typedef struct ALSAVoiceOut {
@@ -199,11 +200,11 @@ static void alsa_poll_handler (void *opaque)
 break;
 
 case SND_PCM_STATE_PREPARED:
-audio_run ("alsa run (prepared)");
+audio_run(hlp->s, "alsa run (prepared)");
 break;
 
 case SND_PCM_STATE_RUNNING:
-audio_run ("alsa run (running)");
+audio_run(hlp->s, "alsa run (running)");
 break;
 
 default:
@@ -749,6 +750,7 @@ static int alsa_init_out(HWVoiceOut *hw, struct audsettings 
*as,
 return -1;
 }
 
+alsa->pollhlp.s = hw->s;
 alsa->handle = handle;
 alsa->dev = dev;
 return 0;
@@ -850,6 +852,7 @@ static int alsa_init_in(HWVoiceIn *hw, struct audsettings 
*as, void *drv_opaque)
 return -1;
 }
 
+alsa->pollhlp.s = hw->s;
 alsa->handle = handle;
 alsa->dev = dev;
 return 0;
diff --git a/audio/audio.c b/audio/audio.c
index 100c3ea177..cb6a9d8ac5 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -835,7 +835,7 @@ static void audio_timer (void *opaque)
 }
 s->timer_last = now;
 
-audio_run("timer");
+audio_run(s, "timer");
 audio_reset_timer(s);
 }
 
@@ -1237,15 +1237,11 @@ static void audio_run_capture (AudioState *s)
 }
 }
 
-void audio_run (const char *msg)
+void audio_run(AudioState *s, const char *msg)
 {
-AudioState *s;
-
-QTAILQ_FOREACH(s, _states, list) {
-audio_run_out(s);
-audio_run_in(s);
-audio_run_capture(s);
-}
+audio_run_out(s);
+audio_run_in(s);
+audio_run_capture(s);
 
 #ifdef DEBUG_POLL
 {
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 29139ef1f5..456fba7480 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -110,28 +110,28 @@ static void oss_anal_close (int *fdp)
 
 static void oss_helper_poll_out (void *opaque)
 {
-(void) opaque;
-audio_run ("oss_poll_out");
+AudioState *s = opaque;
+audio_run(s, "oss_poll_out");
 }
 
 static void oss_helper_poll_in (void *opaque)
 {
-(void) opaque;
-audio_run ("oss_poll_in");
+AudioState *s = opaque;
+audio_run(s, "oss_poll_in");
 }
 
 static void oss_poll_out (HWVoiceOut *hw)
 {
 OSSVoiceOut *oss = (OSSVoiceOut *) hw;
 
-qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL);
+qemu_set_fd_handler(oss->fd, NULL, oss_helper_poll_out, hw->s);
 }
 
 static void oss_poll_in (HWVoiceIn *hw)
 {
 OSSVoiceIn *oss = (OSSVoiceIn *) hw;
 
-qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL);
+qemu_set_fd_handler(oss->fd, oss_helper_poll_in, NULL, hw->s);
 }
 
 static int oss_write (SWVoiceOut *sw, void *buf, int len)
-- 
2.22.0




[Qemu-devel] [PATCH v4 02/14] audio: basic support for multi backend audio

2019-08-18 Thread Kővágó, Zoltán
Audio functions no longer access glob_audio_state, instead they get an
AudioState as a parameter.  This is required in order to support
multiple backends.

glob_audio_state is also gone, and replaced with a tailq so we can store
more than one states.

Signed-off-by: Kővágó, Zoltán 
---

Notes:
Changes from v1:

* Moved wav_capture/vnc audiodev param to a separate commit

 audio/audio.h  |  12 +++--
 audio/audio_int.h  |   2 +
 audio/audio_template.h |   2 +-
 audio/audio.c  | 102 +++--
 audio/wavcapture.c |   6 +--
 monitor/misc.c |   2 +-
 ui/vnc.c   |   2 +-
 7 files changed, 95 insertions(+), 33 deletions(-)

diff --git a/audio/audio.h b/audio/audio.h
index 64b0f761bc..ad2457f4de 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -78,8 +78,10 @@ typedef struct SWVoiceOut SWVoiceOut;
 typedef struct CaptureVoiceOut CaptureVoiceOut;
 typedef struct SWVoiceIn SWVoiceIn;
 
+typedef struct AudioState AudioState;
 typedef struct QEMUSoundCard {
 char *name;
+AudioState *state;
 QLIST_ENTRY (QEMUSoundCard) entries;
 } QEMUSoundCard;
 
@@ -92,7 +94,8 @@ void AUD_log (const char *cap, const char *fmt, ...) 
GCC_FMT_ATTR(2, 3);
 
 void AUD_register_card (const char *name, QEMUSoundCard *card);
 void AUD_remove_card (QEMUSoundCard *card);
-CaptureVoiceOut *AUD_add_capture (
+CaptureVoiceOut *AUD_add_capture(
+AudioState *s,
 struct audsettings *as,
 struct audio_capture_ops *ops,
 void *opaque
@@ -160,8 +163,8 @@ static inline void *advance (void *p, int incr)
 #define audio_MAX(a, b) ((a)<(b)?(b):(a))
 #endif
 
-int wav_start_capture (CaptureState *s, const char *path, int freq,
-   int bits, int nchannels);
+int wav_start_capture(AudioState *state, CaptureState *s, const char *path,
+  int freq, int bits, int nchannels);
 
 bool audio_is_cleaning_up(void);
 void audio_cleanup(void);
@@ -175,4 +178,7 @@ void audio_parse_option(const char *opt);
 void audio_init_audiodevs(void);
 void audio_legacy_help(void);
 
+AudioState *audio_state_by_name(const char *name);
+const char *audio_get_id(QEMUSoundCard *card);
+
 #endif /* QEMU_AUDIO_H */
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 8164696b2c..9f01f6ad00 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -196,6 +196,8 @@ typedef struct AudioState {
 
 bool timer_running;
 uint64_t timer_last;
+
+QTAILQ_ENTRY(AudioState) list;
 } AudioState;
 
 extern const struct mixeng_volume nominal_volume;
diff --git a/audio/audio_template.h b/audio/audio_template.h
index c721fed75d..54f07338e7 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -428,7 +428,7 @@ SW *glue (AUD_open_, TYPE) (
 struct audsettings *as
 )
 {
-AudioState *s = _audio_state;
+AudioState *s = card->state;
 AudiodevPerDirectionOptions *pdo = glue(audio_get_pdo_, TYPE)(s->dev);
 
 if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
diff --git a/audio/audio.c b/audio/audio.c
index 4f27e33245..8e9ccd0ac4 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -87,7 +87,8 @@ audio_driver *audio_driver_lookup(const char *name)
 return NULL;
 }
 
-static AudioState glob_audio_state;
+static QTAILQ_HEAD(AudioStateHead, AudioState) audio_states =
+QTAILQ_HEAD_INITIALIZER(audio_states);
 
 const struct mixeng_volume nominal_volume = {
 .mute = 0,
@@ -1236,11 +1237,14 @@ static void audio_run_capture (AudioState *s)
 
 void audio_run (const char *msg)
 {
-AudioState *s = _audio_state;
+AudioState *s;
+
+QTAILQ_FOREACH(s, _states, list) {
+audio_run_out(s);
+audio_run_in(s);
+audio_run_capture(s);
+}
 
-audio_run_out (s);
-audio_run_in (s);
-audio_run_capture (s);
 #ifdef DEBUG_POLL
 {
 static double prevtime;
@@ -1304,13 +1308,11 @@ bool audio_is_cleaning_up(void)
 return is_cleaning_up;
 }
 
-void audio_cleanup(void)
+static void free_audio_state(AudioState *s)
 {
-AudioState *s = _audio_state;
 HWVoiceOut *hwo, *hwon;
 HWVoiceIn *hwi, *hwin;
 
-is_cleaning_up = true;
 QLIST_FOREACH_SAFE(hwo, >hw_head_out, entries, hwon) {
 SWVoiceCap *sc;
 
@@ -1347,6 +1349,17 @@ void audio_cleanup(void)
 qapi_free_Audiodev(s->dev);
 s->dev = NULL;
 }
+g_free(s);
+}
+
+void audio_cleanup(void)
+{
+is_cleaning_up = true;
+while (!QTAILQ_EMPTY(_states)) {
+AudioState *s = QTAILQ_FIRST(_states);
+QTAILQ_REMOVE(_states, s, list);
+free_audio_state(s);
+}
 }
 
 static const VMStateDescription vmstate_audio = {
@@ -1373,28 +1386,33 @@ static AudiodevListEntry *audiodev_find(
 return NULL;
 }
 
-static int audio_init(Audiodev *dev)
+/*
+ * if we have dev, this function was called because of an -audiodev argument =>
+ *   initialize a new state with it
+ * if dev == NULL => legacy implicit initialization, return the already created
+ 

[Qemu-devel] [PATCH v4 04/14] audio: add audiodev properties to frontends

2019-08-18 Thread Kővágó, Zoltán
Finally add audiodev= options to audio frontends so users can specify
which backend to use when multiple backends exist.  Not specifying an
audiodev= option currently causes the first audiodev to be used, this is
fixed in the next commit.

Example usage: -audiodev pa,id=foo -device AC97,audiodev=foo

Signed-off-by: Kővágó, Zoltán 
Reviewed-by: Marc-André Lureau 
---

Notes:
Changes from v3:

* Fixed compilation error due to changes in master (#include
  "hw/qdev-properties.h" in audio.h)

 audio/audio.h|  4 +++
 include/hw/qdev-properties.h |  3 ++
 hw/audio/ac97.c  |  1 +
 hw/audio/adlib.c |  1 +
 hw/audio/cs4231a.c   |  1 +
 hw/audio/es1370.c|  7 +++-
 hw/audio/gus.c   |  1 +
 hw/audio/hda-codec.c |  1 +
 hw/audio/milkymist-ac97.c|  6 
 hw/audio/pcspk.c |  1 +
 hw/audio/pl041.c |  1 +
 hw/audio/sb16.c  |  1 +
 hw/audio/wm8750.c|  6 
 hw/core/qdev-properties-system.c | 57 
 hw/usb/dev-audio.c   |  1 +
 15 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/audio/audio.h b/audio/audio.h
index ad2457f4de..3257165b05 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -27,6 +27,7 @@
 
 #include "qemu/queue.h"
 #include "qapi/qapi-types-audio.h"
+#include "hw/qdev-properties.h"
 
 typedef void (*audio_callback_fn) (void *opaque, int avail);
 
@@ -181,4 +182,7 @@ void audio_legacy_help(void);
 AudioState *audio_state_by_name(const char *name);
 const char *audio_get_id(QEMUSoundCard *card);
 
+#define DEFINE_AUDIO_PROPERTIES(_s, _f) \
+DEFINE_PROP_AUDIODEV("audiodev", _s, _f)
+
 #endif /* QEMU_AUDIO_H */
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index bb34a614e2..2e98dd60db 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -33,6 +33,7 @@ extern const PropertyInfo qdev_prop_blocksize;
 extern const PropertyInfo qdev_prop_pci_host_devaddr;
 extern const PropertyInfo qdev_prop_uuid;
 extern const PropertyInfo qdev_prop_arraylen;
+extern const PropertyInfo qdev_prop_audiodev;
 extern const PropertyInfo qdev_prop_link;
 extern const PropertyInfo qdev_prop_off_auto_pcibar;
 extern const PropertyInfo qdev_prop_pcie_link_speed;
@@ -234,6 +235,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
 + type_check(QemuUUID, typeof_field(_state, _field)),  \
 .set_default = true,   \
 }
+#define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
+DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
 
 #define DEFINE_PROP_END_OF_LIST()   \
 {}
diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
index 115ee51c7c..b4c0b690d7 100644
--- a/hw/audio/ac97.c
+++ b/hw/audio/ac97.c
@@ -1410,6 +1410,7 @@ static int ac97_init (PCIBus *bus)
 }
 
 static Property ac97_properties[] = {
+DEFINE_AUDIO_PROPERTIES(AC97LinkState, card),
 DEFINE_PROP_UINT32 ("use_broken_id", AC97LinkState, use_broken_id, 0),
 DEFINE_PROP_END_OF_LIST (),
 };
diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index 2f4aacbf43..64a1060b80 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -299,6 +299,7 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
 }
 
 static Property adlib_properties[] = {
+DEFINE_AUDIO_PROPERTIES(AdlibState, card),
 DEFINE_PROP_UINT32 ("iobase",  AdlibState, port, 0x220),
 DEFINE_PROP_UINT32 ("freq",AdlibState, freq,  44100),
 DEFINE_PROP_END_OF_LIST (),
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index d77a4e713e..5b7baeae25 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -690,6 +690,7 @@ static int cs4231a_init (ISABus *bus)
 }
 
 static Property cs4231a_properties[] = {
+DEFINE_AUDIO_PROPERTIES(CSState, card),
 DEFINE_PROP_UINT32 ("iobase",  CSState, port, 0x534),
 DEFINE_PROP_UINT32 ("irq", CSState, irq,  9),
 DEFINE_PROP_UINT32 ("dma", CSState, dma,  3),
diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index 39deecbbc6..88f886491b 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -887,6 +887,11 @@ static int es1370_init (PCIBus *bus)
 return 0;
 }
 
+static Property es1370_properties[] = {
+DEFINE_AUDIO_PROPERTIES(ES1370State, card),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void es1370_class_init (ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS (klass);
@@ -903,6 +908,7 @@ static void es1370_class_init (ObjectClass *klass, void 
*data)
 dc->desc = "ENSONIQ AudioPCI ES1370";
 dc->vmsd = _es1370;
 dc->reset = es1370_on_reset;
+dc->props = es1370_properties;
 }
 
 static const TypeInfo es1370_info = {
@@ -923,4 +929,3 @@ static void es1370_register_types (void)
 }
 
 type_init (es1370_register_types)
-
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index dbfe7cf634..effec31d35 100644
--- 

[Qemu-devel] [PATCH v4 08/14] paaudio: properly disconnect streams in fini_*

2019-08-18 Thread Kővágó, Zoltán
Currently this needs a workaround due to bug #247 in pulseaudio.

Signed-off-by: Kővágó, Zoltán 
Reviewed-by: Marc-André Lureau 
---
 audio/paaudio.c | 25 +++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 24d98b344a..1d68173636 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -685,6 +685,27 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings 
*as, void *drv_opaque)
 return -1;
 }
 
+static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
+{
+int err;
+
+pa_threaded_mainloop_lock(c->mainloop);
+/*
+ * wait until actually connects. workaround pa bug #247
+ * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/247
+ */
+while (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
+pa_threaded_mainloop_wait(c->mainloop);
+}
+
+err = pa_stream_disconnect(stream);
+if (err != 0) {
+dolog("Failed to disconnect! err=%d\n", err);
+}
+pa_stream_unref(stream);
+pa_threaded_mainloop_unlock(c->mainloop);
+}
+
 static void qpa_fini_out (HWVoiceOut *hw)
 {
 void *ret;
@@ -696,7 +717,7 @@ static void qpa_fini_out (HWVoiceOut *hw)
 audio_pt_join(>pt, , __func__);
 
 if (pa->stream) {
-pa_stream_unref (pa->stream);
+qpa_simple_disconnect(pa->g->conn, pa->stream);
 pa->stream = NULL;
 }
 
@@ -716,7 +737,7 @@ static void qpa_fini_in (HWVoiceIn *hw)
 audio_pt_join(>pt, , __func__);
 
 if (pa->stream) {
-pa_stream_unref (pa->stream);
+qpa_simple_disconnect(pa->g->conn, pa->stream);
 pa->stream = NULL;
 }
 
-- 
2.22.0




[Qemu-devel] [PATCH v4 06/14] audio: audiodev= parameters no longer optional when -audiodev present

2019-08-18 Thread Kővágó, Zoltán
This means you should probably stop using -soundhw (as it doesn't allow
you to specify any options) and add the device manually with -device.
The exception is pcspk, it's currently not possible to manually add it.
To use it with audiodev, use something like this:

-audiodev id=foo,... -global isa-pcspk.audiodev=foo -soundhw pcspk

Signed-off-by: Kővágó, Zoltán 
---

Notes:
Changes from v1:

* Split off paaudio changes to a different commit.

 audio/audio.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 8e9ccd0ac4..7267cab9d7 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -101,6 +101,8 @@ const struct mixeng_volume nominal_volume = {
 #endif
 };
 
+static bool legacy_config = true;
+
 #ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
 #error No its not
 #else
@@ -1392,7 +1394,7 @@ static AudiodevListEntry *audiodev_find(
  * if dev == NULL => legacy implicit initialization, return the already created
  *   state or create a new one
  */
-static AudioState *audio_init(Audiodev *dev)
+static AudioState *audio_init(Audiodev *dev, const char *name)
 {
 static bool atexit_registered;
 size_t i;
@@ -1406,12 +1408,13 @@ static AudioState *audio_init(Audiodev *dev)
 
 if (dev) {
 /* -audiodev option */
+legacy_config = false;
 drvname = AudiodevDriver_str(dev->driver);
 } else if (!QTAILQ_EMPTY(_states)) {
-/*
- * todo: check for -audiodev once we have normal audiodev selection
- * support
- */
+if (!legacy_config) {
+dolog("You must specify an audiodev= for the device %s\n", name);
+exit(1);
+}
 return QTAILQ_FIRST(_states);
 } else {
 /* legacy implicit initialization */
@@ -1518,7 +1521,7 @@ void audio_free_audiodev_list(AudiodevListHead *head)
 void AUD_register_card (const char *name, QEMUSoundCard *card)
 {
 if (!card->state) {
-card->state = audio_init(NULL);
+card->state = audio_init(NULL, name);
 }
 
 card->name = g_strdup (name);
@@ -1544,8 +1547,11 @@ CaptureVoiceOut *AUD_add_capture(
 struct capture_callback *cb;
 
 if (!s) {
-/* todo: remove when we have normal audiodev selection support */
-s = audio_init(NULL);
+if (!legacy_config) {
+dolog("You must specify audiodev when trying to capture\n");
+return NULL;
+}
+s = audio_init(NULL, NULL);
 }
 
 if (audio_validate_settings (as)) {
@@ -1776,7 +1782,7 @@ void audio_init_audiodevs(void)
 AudiodevListEntry *e;
 
 QSIMPLEQ_FOREACH(e, , next) {
-audio_init(e->dev);
+audio_init(e->dev, NULL);
 }
 }
 
-- 
2.22.0




[Qemu-devel] [PATCH v4 03/14] audio: add audiodev property to vnc and wav_capture

2019-08-18 Thread Kővágó, Zoltán
Signed-off-by: Kővágó, Zoltán 
---

Notes:
Changes from v2:

* audiodev parameter for wavcapture is now mandatory.
* removed some unnecessary qdict_haskey calls from hmp_wavcapture

 ui/vnc.h|  2 ++
 monitor/misc.c  | 22 +++---
 ui/vnc.c| 15 ++-
 hmp-commands.hx | 11 ++-
 qemu-options.hx |  6 ++
 5 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/ui/vnc.h b/ui/vnc.h
index 18f1b1d6d0..8643860967 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -182,6 +182,8 @@ struct VncDisplay
 #ifdef CONFIG_VNC_SASL
 VncDisplaySASL sasl;
 #endif
+
+AudioState *audio_state;
 };
 
 typedef struct VncTight {
diff --git a/monitor/misc.c b/monitor/misc.c
index 6b71059739..aef16f6cfb 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -1142,21 +1142,21 @@ static void hmp_stopcapture(Monitor *mon, const QDict 
*qdict)
 static void hmp_wavcapture(Monitor *mon, const QDict *qdict)
 {
 const char *path = qdict_get_str(qdict, "path");
-int has_freq = qdict_haskey(qdict, "freq");
-int freq = qdict_get_try_int(qdict, "freq", -1);
-int has_bits = qdict_haskey(qdict, "bits");
-int bits = qdict_get_try_int(qdict, "bits", -1);
-int has_channels = qdict_haskey(qdict, "nchannels");
-int nchannels = qdict_get_try_int(qdict, "nchannels", -1);
+int freq = qdict_get_try_int(qdict, "freq", 44100);
+int bits = qdict_get_try_int(qdict, "bits", 16);
+int nchannels = qdict_get_try_int(qdict, "nchannels", 2);
+const char *audiodev = qdict_get_str(qdict, "audiodev");
 CaptureState *s;
+AudioState *as = audio_state_by_name(audiodev);
+
+if (!as) {
+monitor_printf(mon, "Audiodev '%s' not found\n", audiodev);
+return;
+}
 
 s = g_malloc0 (sizeof (*s));
 
-freq = has_freq ? freq : 44100;
-bits = has_bits ? bits : 16;
-nchannels = has_channels ? nchannels : 2;
-
-if (wav_start_capture(NULL, s, path, freq, bits, nchannels)) {
+if (wav_start_capture(as, s, path, freq, bits, nchannels)) {
 monitor_printf(mon, "Failed to add wave capture\n");
 g_free (s);
 return;
diff --git a/ui/vnc.c b/ui/vnc.c
index ed5e8aa5f8..649ce93cd2 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1224,7 +1224,7 @@ static void audio_add(VncState *vs)
 ops.destroy = audio_capture_destroy;
 ops.capture = audio_capture;
 
-vs->audio_cap = AUD_add_capture(NULL, >as, , vs);
+vs->audio_cap = AUD_add_capture(vs->vd->audio_state, >as, , vs);
 if (!vs->audio_cap) {
 error_report("Failed to add audio capture");
 }
@@ -3371,6 +3371,9 @@ static QemuOptsList qemu_vnc_opts = {
 },{
 .name = "non-adaptive",
 .type = QEMU_OPT_BOOL,
+},{
+.name = "audiodev",
+.type = QEMU_OPT_STRING,
 },
 { /* end of list */ }
 },
@@ -3808,6 +3811,7 @@ void vnc_display_open(const char *id, Error **errp)
 const char *saslauthz;
 int lock_key_sync = 1;
 int key_delay_ms;
+const char *audiodev;
 
 if (!vd) {
 error_setg(errp, "VNC display not active");
@@ -3993,6 +3997,15 @@ void vnc_display_open(const char *id, Error **errp)
 }
 vd->ledstate = 0;
 
+audiodev = qemu_opt_get(opts, "audiodev");
+if (audiodev) {
+vd->audio_state = audio_state_by_name(audiodev);
+if (!vd->audio_state) {
+error_setg(errp, "Audiodev '%s' not found", audiodev);
+goto fail;
+}
+}
+
 device_id = qemu_opt_get(opts, "display");
 if (device_id) {
 int head = qemu_opt_get_number(opts, "head", 0);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index bfa5681dd2..cfcc044ce4 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -819,16 +819,17 @@ ETEXI
 
 {
 .name   = "wavcapture",
-.args_type  = "path:F,freq:i?,bits:i?,nchannels:i?",
-.params = "path [frequency [bits [channels]]]",
+.args_type  = "path:F,audiodev:s,freq:i?,bits:i?,nchannels:i?",
+.params = "path audiodev [frequency [bits [channels]]]",
 .help   = "capture audio to a wave file (default frequency=44100 
bits=16 channels=2)",
 .cmd= hmp_wavcapture,
 },
 STEXI
-@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
+@item wavcapture @var{filename} @var{audiodev} [@var{frequency} [@var{bits} 
[@var{channels}]]]
 @findex wavcapture
-Capture audio into @var{filename}. Using sample rate @var{frequency}
-bits per sample @var{bits} and number of channels @var{channels}.
+Capture audio into @var{filename} from @var{audiodev}, using sample rate
+@var{frequency} bits per sample @var{bits} and number of channels
+@var{channels}.
 
 Defaults:
 @itemize @minus
diff --git a/qemu-options.hx b/qemu-options.hx
index 9621e934c0..a308e5f5aa 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1978,6 +1978,12 @@ can help the device and guest to keep up and not lose 
events 

[Qemu-devel] [PATCH v4 00/14] Multiple simultaneous audio backends

2019-08-18 Thread Kővágó, Zoltán
Hello,

This is the v4 of my audio patches.  This is a compile-fix revision, hopefully
fixing windows compile errors in "audio: use size_t where makes sense" and
compile errors introduced by changes on master in "audio: add audiodev
properties to frontends".

Regards,
Zoltan

Kővágó, Zoltán (14):
  audio: reduce glob_audio_state usage
  audio: basic support for multi backend audio
  audio: add audiodev property to vnc and wav_capture
  audio: add audiodev properties to frontends
  paaudio: prepare for multiple audiodev
  audio: audiodev= parameters no longer optional when -audiodev present
  paaudio: do not move stream when sink/source name is specified
  paaudio: properly disconnect streams in fini_*
  audio: remove audio_MIN, audio_MAX
  audio: do not run each backend in audio_run
  paaudio: fix playback glitches
  audio: remove read and write pcm_ops
  audio: use size_t where makes sense
  audio: fix memory leak reported by ASAN

 audio/audio.h|  37 ++-
 audio/audio_int.h|  43 ++--
 audio/audio_template.h   |  62 +++--
 audio/mixeng.h   |   9 +-
 audio/rate_template.h|   2 +-
 include/hw/qdev-properties.h |   3 +
 include/sysemu/replay.h  |   4 +-
 ui/vnc.h |   2 +
 audio/alsaaudio.c|  49 ++--
 audio/audio.c| 345 ++---
 audio/coreaudio.c|  18 +-
 audio/dsoundaudio.c  |  31 +--
 audio/noaudio.c  |  39 +--
 audio/ossaudio.c |  75 +++---
 audio/paaudio.c  | 421 ++-
 audio/sdlaudio.c |  30 +--
 audio/spiceaudio.c   |  34 +--
 audio/wavaudio.c |  18 +-
 audio/wavcapture.c   |   6 +-
 hw/audio/ac97.c  |  11 +-
 hw/audio/adlib.c |   5 +-
 hw/audio/cs4231a.c   |   5 +-
 hw/audio/es1370.c|  13 +-
 hw/audio/gus.c   |   7 +-
 hw/audio/hda-codec.c |  17 +-
 hw/audio/milkymist-ac97.c|  14 +-
 hw/audio/pcspk.c |   3 +-
 hw/audio/pl041.c |   1 +
 hw/audio/sb16.c  |   3 +-
 hw/audio/wm8750.c|  10 +-
 hw/core/qdev-properties-system.c |  57 +
 hw/usb/dev-audio.c   |   1 +
 monitor/misc.c   |  22 +-
 replay/replay-audio.c|  16 +-
 replay/replay.c  |   2 +-
 ui/vnc.c |  15 +-
 hmp-commands.hx  |  11 +-
 qemu-options.hx  |   6 +
 38 files changed, 792 insertions(+), 655 deletions(-)

-- 
2.22.0




[Qemu-devel] [PATCH v4 01/14] audio: reduce glob_audio_state usage

2019-08-18 Thread Kővágó, Zoltán
Remove glob_audio_state from functions, where possible without breaking
the API.  This means that most static functions in audio.c now take an
AudioState pointer instead of implicitly using glob_audio_state.  Also
included a pointer in SWVoice*, HWVoice* structs, so that functions
dealing them can know the audio state without having to pass it around
separately.

This is required in order to support multiple simultaneous audio
backends (added in a later commit).

Signed-off-by: Kővágó, Zoltán 
Reviewed-by: Marc-André Lureau 
---
 audio/audio_int.h  |  8 ++
 audio/audio_template.h | 46 
 audio/audio.c  | 59 +++---
 3 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/audio/audio_int.h b/audio/audio_int.h
index 3f14842709..8164696b2c 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -49,9 +49,11 @@ struct audio_pcm_info {
 int swap_endianness;
 };
 
+typedef struct AudioState AudioState;
 typedef struct SWVoiceCap SWVoiceCap;
 
 typedef struct HWVoiceOut {
+AudioState *s;
 int enabled;
 int poll_mode;
 int pending_disable;
@@ -73,6 +75,7 @@ typedef struct HWVoiceOut {
 } HWVoiceOut;
 
 typedef struct HWVoiceIn {
+AudioState *s;
 int enabled;
 int poll_mode;
 struct audio_pcm_info info;
@@ -94,6 +97,7 @@ typedef struct HWVoiceIn {
 
 struct SWVoiceOut {
 QEMUSoundCard *card;
+AudioState *s;
 struct audio_pcm_info info;
 t_sample *conv;
 int64_t ratio;
@@ -111,6 +115,7 @@ struct SWVoiceOut {
 
 struct SWVoiceIn {
 QEMUSoundCard *card;
+AudioState *s;
 int active;
 struct audio_pcm_info info;
 int64_t ratio;
@@ -188,6 +193,9 @@ typedef struct AudioState {
 int nb_hw_voices_in;
 int vm_running;
 int64_t period_ticks;
+
+bool timer_running;
+uint64_t timer_last;
 } AudioState;
 
 extern const struct mixeng_volume nominal_volume;
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 1232bb54db..c721fed75d 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -36,9 +36,9 @@
 #define HWBUF hw->conv_buf
 #endif
 
-static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv)
+static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
+  struct audio_driver *drv)
 {
-AudioState *s = _audio_state;
 int max_voices = glue (drv->max_voices_, TYPE);
 int voice_size = glue (drv->voice_size_, TYPE);
 
@@ -183,8 +183,8 @@ static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
 
 static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
 {
-AudioState *s = _audio_state;
 HW *hw = *hwp;
+AudioState *s = hw->s;
 
 if (!hw->sw_head.lh_first) {
 #ifdef DAC
@@ -199,15 +199,14 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
 }
 }
 
-static HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw)
+static HW *glue(audio_pcm_hw_find_any_, TYPE)(AudioState *s, HW *hw)
 {
-AudioState *s = _audio_state;
 return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first;
 }
 
-static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw)
+static HW *glue(audio_pcm_hw_find_any_enabled_, TYPE)(AudioState *s, HW *hw)
 {
-while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
+while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
 if (hw->enabled) {
 return hw;
 }
@@ -215,12 +214,10 @@ static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) 
(HW *hw)
 return NULL;
 }
 
-static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
-HW *hw,
-struct audsettings *as
-)
+static HW *glue(audio_pcm_hw_find_specific_, TYPE)(AudioState *s, HW *hw,
+   struct audsettings *as)
 {
-while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) {
+while ((hw = glue(audio_pcm_hw_find_any_, TYPE)(s, hw))) {
 if (audio_pcm_info_eq (>info, as)) {
 return hw;
 }
@@ -228,10 +225,10 @@ static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
 return NULL;
 }
 
-static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
+static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
+ struct audsettings *as)
 {
 HW *hw;
-AudioState *s = _audio_state;
 struct audio_driver *drv = s->drv;
 
 if (!glue (s->nb_hw_voices_, TYPE)) {
@@ -255,6 +252,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct 
audsettings *as)
 return NULL;
 }
 
+hw->s = s;
 hw->pcm_ops = drv->pcm_ops;
 hw->ctl_caps = drv->ctl_caps;
 
@@ -328,33 +326,33 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, 
TYPE)(Audiodev *dev)
 abort();
 }
 
-static HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as)
+static HW *glue(audio_pcm_hw_add_, TYPE)(AudioState *s, struct audsettings *as)
 {
 HW *hw;
-AudioState *s = _audio_state;
 

[Qemu-devel] [PATCH v4 12/15] hw/i386/pc: Let pc_build_feature_control() take a FWCfgState argument

2019-08-18 Thread Philippe Mathieu-Daudé
Pass the FWCfgState object by argument, this will
allow us to remove the PCMachineState argument later.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e11ba7efce..460f55fd09 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1608,7 +1608,8 @@ void pc_cpus_init(PCMachineState *pcms)
 }
 }
 
-static void pc_build_feature_control_file(PCMachineState *pcms)
+static void pc_build_feature_control_file(PCMachineState *pcms,
+  FWCfgState *fw_cfg)
 {
 MachineState *ms = MACHINE(pcms);
 X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
@@ -1634,7 +1635,7 @@ static void pc_build_feature_control_file(PCMachineState 
*pcms)
 
 val = g_malloc(sizeof(*val));
 *val = cpu_to_le64(feature_control_bits | FEATURE_CONTROL_LOCKED);
-fw_cfg_add_file(pcms->fw_cfg, "etc/msr_feature_control", val, 
sizeof(*val));
+fw_cfg_add_file(fw_cfg, "etc/msr_feature_control", val, sizeof(*val));
 }
 
 static void rtc_set_cpus_count(ISADevice *rtc, uint16_t cpus_count)
@@ -1680,7 +1681,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 acpi_setup();
 if (pcms->fw_cfg) {
 fw_cfg_build_smbios(MACHINE(pcms), pcms->fw_cfg);
-pc_build_feature_control_file(pcms);
+pc_build_feature_control_file(pcms, pcms->fw_cfg);
 /* update FW_CFG_NB_CPUS to account for -device added CPUs */
 fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
 }
-- 
2.20.1




[Qemu-devel] [PATCH v4 15/15] hw/i386/pc: Extract the x86 generic fw_cfg code

2019-08-18 Thread Philippe Mathieu-Daudé
Extract all the functions that are not PC-machine specific into
the (arch-specific) fw_cfg.c file. This will allow other X86-machine
to reuse these functions.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
v4: rebased using  MachineState argument with smbios_get_tables*()
calls but not with fw_cfg_arch_create().
---
 hw/i386/fw_cfg.c | 136 +++
 hw/i386/fw_cfg.h |   7 +++
 hw/i386/pc.c | 129 +---
 3 files changed, 144 insertions(+), 128 deletions(-)

diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index 380a819230..7ae3fa084c 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -13,8 +13,15 @@
  */
 
 #include "qemu/osdep.h"
+#include "sysemu/numa.h"
+#include "hw/acpi/acpi.h"
+#include "hw/firmware/smbios.h"
+#include "hw/i386/pc.h"
 #include "hw/i386/fw_cfg.h"
+#include "hw/timer/hpet.h"
 #include "hw/nvram/fw_cfg.h"
+#include "e820_memory_layout.h"
+#include "kvm_i386.h"
 
 const char *fw_cfg_arch_key_name(uint16_t key)
 {
@@ -36,3 +43,132 @@ const char *fw_cfg_arch_key_name(uint16_t key)
 }
 return NULL;
 }
+
+FWCfgState *fw_cfg_arch_create(const CPUArchIdList *cpus,
+   uint16_t boot_cpus,
+   uint16_t apic_id_limit)
+{
+FWCfgState *fw_cfg;
+uint64_t *numa_fw_cfg;
+int i;
+
+fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4,
+_space_memory);
+fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, boot_cpus);
+
+/*
+ * FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
+ *
+ * For machine types prior to 1.8, SeaBIOS needs FW_CFG_MAX_CPUS for
+ * building MPTable, ACPI MADT, ACPI CPU hotplug and ACPI SRAT table,
+ * that tables are based on xAPIC ID and QEMU<->SeaBIOS interface
+ * for CPU hotplug also uses APIC ID and not "CPU index".
+ * This means that FW_CFG_MAX_CPUS is not the "maximum number of CPUs",
+ * but the "limit to the APIC ID values SeaBIOS may see".
+ *
+ * So for compatibility reasons with old BIOSes we are stuck with
+ * "etc/max-cpus" actually being apic_id_limit
+ */
+fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, apic_id_limit);
+fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
+ acpi_tables, acpi_tables_len);
+fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
+
+fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
+ _reserve, sizeof(e820_reserve));
+fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
+sizeof(struct e820_entry) * e820_get_num_entries());
+
+fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, _cfg, sizeof(hpet_cfg));
+/*
+ * allocate memory for the NUMA channel: one (64bit) word for the number
+ * of nodes, one word for each VCPU->node and one word for each node to
+ * hold the amount of memory.
+ */
+numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + nb_numa_nodes);
+numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
+for (i = 0; i < cpus->len; i++) {
+unsigned int apic_id = cpus->cpus[i].arch_id;
+assert(apic_id < apic_id_limit);
+numa_fw_cfg[apic_id + 1] = cpu_to_le64(cpus->cpus[i].props.node_id);
+}
+for (i = 0; i < nb_numa_nodes; i++) {
+numa_fw_cfg[apic_id_limit + 1 + i] =
+cpu_to_le64(numa_info[i].node_mem);
+}
+fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
+ (1 + apic_id_limit + nb_numa_nodes) *
+ sizeof(*numa_fw_cfg));
+
+return fw_cfg;
+}
+
+void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
+{
+uint8_t *smbios_tables, *smbios_anchor;
+size_t smbios_tables_len, smbios_anchor_len;
+struct smbios_phys_mem_area *mem_array;
+unsigned i, array_count;
+X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
+
+/* tell smbios about cpuid version and features */
+smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
+
+smbios_tables = smbios_get_table_legacy(ms, _tables_len);
+if (smbios_tables) {
+fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
+ smbios_tables, smbios_tables_len);
+}
+
+/* build the array of physical mem area from e820 table */
+mem_array = g_malloc0(sizeof(*mem_array) * e820_get_num_entries());
+for (i = 0, array_count = 0; i < e820_get_num_entries(); i++) {
+uint64_t addr, len;
+
+if (e820_get_entry(i, E820_RAM, , )) {
+mem_array[array_count].address = addr;
+mem_array[array_count].length = len;
+array_count++;
+}
+}
+smbios_get_tables(ms, mem_array, array_count,
+  _tables, _tables_len,
+  _anchor, _anchor_len);
+g_free(mem_array);
+
+if (smbios_anchor) {
+

[Qemu-devel] [PATCH v4 14/15] hw/i386/pc: Rename pc_build_feature_control() as generic fw_cfg_build_*

2019-08-18 Thread Philippe Mathieu-Daudé
Now that the pc_build_feature_control_file() function has been
refactored to not depend of PC specific types, rename it to a
more generic name.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e57468a1a2..4413d3202f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1608,8 +1608,8 @@ void pc_cpus_init(PCMachineState *pcms)
 }
 }
 
-static void pc_build_feature_control_file(MachineState *ms,
-  FWCfgState *fw_cfg)
+static void fw_cfg_build_feature_control(MachineState *ms,
+ FWCfgState *fw_cfg)
 {
 X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
 CPUX86State *env = >env;
@@ -1680,7 +1680,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 acpi_setup();
 if (pcms->fw_cfg) {
 fw_cfg_build_smbios(MACHINE(pcms), pcms->fw_cfg);
-pc_build_feature_control_file(MACHINE(pcms), pcms->fw_cfg);
+fw_cfg_build_feature_control(MACHINE(pcms), pcms->fw_cfg);
 /* update FW_CFG_NB_CPUS to account for -device added CPUs */
 fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
 }
-- 
2.20.1




Re: [Qemu-devel] [edk2-devel] CPU hotplug using SMM with QEMU+OVMF

2019-08-18 Thread Yao, Jiewen
in real world, we deprecate AB-seg usage because they are vulnerable to smm 
cache poison attack.
I assume cache poison is out of scope in the virtual world, or there is a way 
to prevent ABseg cache poison. 

thank you!
Yao, Jiewen


> 在 2019年8月19日,上午3:50,Paolo Bonzini  写道:
> 
>> On 17/08/19 02:20, Yao, Jiewen wrote:
>> [Jiewen] That is OK. Then we MUST add the third adversary.
>> -- Adversary: Simple hardware attacker, who can use device to perform DMA 
>> attack in the virtual world.
>> NOTE: The DMA attack in the real world is out of scope. That is be handled 
>> by IOMMU in the real world, such as VTd. -- Please do clarify if this is 
>> TRUE.
>> 
>> In the real world:
>> #1: the SMM MUST be non-DMA capable region.
>> #2: the MMIO MUST be non-DMA capable region.
>> #3: the stolen memory MIGHT be DMA capable region or non-DMA capable
>> region. It depends upon the silicon design.
>> #4: the normal OS accessible memory - including ACPI reclaim, ACPI
>> NVS, and reserved memory not included by #3 - MUST be DMA capable region.
>> As such, IOMMU protection is NOT required for #1 and #2. IOMMU
>> protection MIGHT be required for #3 and MUST be required for #4.
>> I assume the virtual environment is designed in the same way. Please
>> correct me if I am wrong.
>> 
> 
> Correct.  The 0x3...0x3 area is the only problematic one;
> Igor's idea (or a variant, for example optionally remapping
> 0xa..0xa SMRAM to 0x3) is becoming more and more attractive.
> 
> Paolo



[Qemu-devel] [PATCH v4 11/15] hw/i386/pc: Rename pc_build_smbios() as generic fw_cfg_build_smbios()

2019-08-18 Thread Philippe Mathieu-Daudé
Now that the pc_build_smbios() function has been refactored to not
depend of PC specific types, rename it to a more generic name.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0bd411de6e..e11ba7efce 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -891,7 +891,7 @@ static uint32_t x86_cpu_apic_id_from_index(PCMachineState 
*pcms,
 }
 }
 
-static void pc_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
+static void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
 {
 uint8_t *smbios_tables, *smbios_anchor;
 size_t smbios_tables_len, smbios_anchor_len;
@@ -1679,7 +1679,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 
 acpi_setup();
 if (pcms->fw_cfg) {
-pc_build_smbios(MACHINE(pcms), pcms->fw_cfg);
+fw_cfg_build_smbios(MACHINE(pcms), pcms->fw_cfg);
 pc_build_feature_control_file(pcms);
 /* update FW_CFG_NB_CPUS to account for -device added CPUs */
 fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
-- 
2.20.1




[Qemu-devel] [PATCH v4 13/15] hw/i386/pc: Let pc_build_feature_control() take a MachineState argument

2019-08-18 Thread Philippe Mathieu-Daudé
Let the pc_build_feature_control_file() function take a generic MachineState
argument.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 460f55fd09..e57468a1a2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1608,10 +1608,9 @@ void pc_cpus_init(PCMachineState *pcms)
 }
 }
 
-static void pc_build_feature_control_file(PCMachineState *pcms,
+static void pc_build_feature_control_file(MachineState *ms,
   FWCfgState *fw_cfg)
 {
-MachineState *ms = MACHINE(pcms);
 X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
 CPUX86State *env = >env;
 uint32_t unused, ecx, edx;
@@ -1681,7 +1680,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 acpi_setup();
 if (pcms->fw_cfg) {
 fw_cfg_build_smbios(MACHINE(pcms), pcms->fw_cfg);
-pc_build_feature_control_file(pcms, pcms->fw_cfg);
+pc_build_feature_control_file(MACHINE(pcms), pcms->fw_cfg);
 /* update FW_CFG_NB_CPUS to account for -device added CPUs */
 fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
 }
-- 
2.20.1




[Qemu-devel] [PATCH v4 10/15] hw/i386/pc: Let pc_build_smbios() take a generic MachineState argument

2019-08-18 Thread Philippe Mathieu-Daudé
Let the pc_build_smbios() function take a generic MachineState
argument.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 63cb27ff18..0bd411de6e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -891,13 +891,12 @@ static uint32_t x86_cpu_apic_id_from_index(PCMachineState 
*pcms,
 }
 }
 
-static void pc_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
+static void pc_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
 {
 uint8_t *smbios_tables, *smbios_anchor;
 size_t smbios_tables_len, smbios_anchor_len;
 struct smbios_phys_mem_area *mem_array;
 unsigned i, array_count;
-MachineState *ms = MACHINE(pcms);
 X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
 
 /* tell smbios about cpuid version and features */
@@ -1680,7 +1679,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 
 acpi_setup();
 if (pcms->fw_cfg) {
-pc_build_smbios(pcms, pcms->fw_cfg);
+pc_build_smbios(MACHINE(pcms), pcms->fw_cfg);
 pc_build_feature_control_file(pcms);
 /* update FW_CFG_NB_CPUS to account for -device added CPUs */
 fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
-- 
2.20.1




[Qemu-devel] [PATCH v4 09/15] hw/i386/pc: Let pc_build_smbios() take a FWCfgState argument

2019-08-18 Thread Philippe Mathieu-Daudé
Pass the FWCfgState object by argument, this will
allow us to remove the PCMachineState argument later.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index acd9641d05..63cb27ff18 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -891,7 +891,7 @@ static uint32_t x86_cpu_apic_id_from_index(PCMachineState 
*pcms,
 }
 }
 
-static void pc_build_smbios(PCMachineState *pcms)
+static void pc_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
 {
 uint8_t *smbios_tables, *smbios_anchor;
 size_t smbios_tables_len, smbios_anchor_len;
@@ -905,7 +905,7 @@ static void pc_build_smbios(PCMachineState *pcms)
 
 smbios_tables = smbios_get_table_legacy(ms, _tables_len);
 if (smbios_tables) {
-fw_cfg_add_bytes(pcms->fw_cfg, FW_CFG_SMBIOS_ENTRIES,
+fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
  smbios_tables, smbios_tables_len);
 }
 
@@ -926,9 +926,9 @@ static void pc_build_smbios(PCMachineState *pcms)
 g_free(mem_array);
 
 if (smbios_anchor) {
-fw_cfg_add_file(pcms->fw_cfg, "etc/smbios/smbios-tables",
+fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-tables",
 smbios_tables, smbios_tables_len);
-fw_cfg_add_file(pcms->fw_cfg, "etc/smbios/smbios-anchor",
+fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-anchor",
 smbios_anchor, smbios_anchor_len);
 }
 }
@@ -1680,7 +1680,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 
 acpi_setup();
 if (pcms->fw_cfg) {
-pc_build_smbios(pcms);
+pc_build_smbios(pcms, pcms->fw_cfg);
 pc_build_feature_control_file(pcms);
 /* update FW_CFG_NB_CPUS to account for -device added CPUs */
 fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
-- 
2.20.1




[Qemu-devel] [PATCH v4 02/15] hw/i386/pc: Extract e820 memory layout code

2019-08-18 Thread Philippe Mathieu-Daudé
Suggested-by: Samuel Ortiz 
Reviewed-by: Li Qiang 
Signed-off-by: Philippe Mathieu-Daudé 
---
v3: KISS, do not use unsigned, do not add broken documentation
---
 hw/i386/Makefile.objs|  2 +-
 hw/i386/e820_memory_layout.c | 59 ++
 hw/i386/e820_memory_layout.h | 42 +
 hw/i386/pc.c | 61 +---
 include/hw/i386/pc.h | 11 ---
 target/i386/kvm.c|  1 +
 6 files changed, 104 insertions(+), 72 deletions(-)
 create mode 100644 hw/i386/e820_memory_layout.c
 create mode 100644 hw/i386/e820_memory_layout.h

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 5d9c9efd5f..d3374e0831 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -1,5 +1,5 @@
 obj-$(CONFIG_KVM) += kvm/
-obj-y += multiboot.o
+obj-y += e820_memory_layout.o multiboot.o
 obj-y += pc.o
 obj-$(CONFIG_I440FX) += pc_piix.o
 obj-$(CONFIG_Q35) += pc_q35.o
diff --git a/hw/i386/e820_memory_layout.c b/hw/i386/e820_memory_layout.c
new file mode 100644
index 00..bcf9eaf837
--- /dev/null
+++ b/hw/i386/e820_memory_layout.c
@@ -0,0 +1,59 @@
+/*
+ * QEMU BIOS e820 routines
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "e820_memory_layout.h"
+
+static size_t e820_entries;
+struct e820_table e820_reserve;
+struct e820_entry *e820_table;
+
+int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
+{
+int index = le32_to_cpu(e820_reserve.count);
+struct e820_entry *entry;
+
+if (type != E820_RAM) {
+/* old FW_CFG_E820_TABLE entry -- reservations only */
+if (index >= E820_NR_ENTRIES) {
+return -EBUSY;
+}
+entry = _reserve.entry[index++];
+
+entry->address = cpu_to_le64(address);
+entry->length = cpu_to_le64(length);
+entry->type = cpu_to_le32(type);
+
+e820_reserve.count = cpu_to_le32(index);
+}
+
+/* new "etc/e820" file -- include ram too */
+e820_table = g_renew(struct e820_entry, e820_table, e820_entries + 1);
+e820_table[e820_entries].address = cpu_to_le64(address);
+e820_table[e820_entries].length = cpu_to_le64(length);
+e820_table[e820_entries].type = cpu_to_le32(type);
+e820_entries++;
+
+return e820_entries;
+}
+
+int e820_get_num_entries(void)
+{
+return e820_entries;
+}
+
+bool e820_get_entry(int idx, uint32_t type, uint64_t *address, uint64_t 
*length)
+{
+if (idx < e820_entries && e820_table[idx].type == cpu_to_le32(type)) {
+*address = le64_to_cpu(e820_table[idx].address);
+*length = le64_to_cpu(e820_table[idx].length);
+return true;
+}
+return false;
+}
diff --git a/hw/i386/e820_memory_layout.h b/hw/i386/e820_memory_layout.h
new file mode 100644
index 00..2a0ceb8b9c
--- /dev/null
+++ b/hw/i386/e820_memory_layout.h
@@ -0,0 +1,42 @@
+/*
+ * QEMU BIOS e820 routines
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef HW_I386_E820_H
+#define HW_I386_E820_H
+
+/* e820 types */
+#define E820_RAM1
+#define E820_RESERVED   2
+#define E820_ACPI   3
+#define E820_NVS4
+#define E820_UNUSABLE   5
+
+#define E820_NR_ENTRIES 16
+
+struct e820_entry {
+uint64_t address;
+uint64_t length;
+uint32_t type;
+} QEMU_PACKED __attribute((__aligned__(4)));
+
+struct e820_table {
+uint32_t count;
+struct e820_entry entry[E820_NR_ENTRIES];
+} QEMU_PACKED __attribute((__aligned__(4)));
+
+extern struct e820_table e820_reserve;
+extern struct e820_entry *e820_table;
+
+int e820_add_entry(uint64_t address, uint64_t length, uint32_t type);
+int e820_get_num_entries(void);
+bool e820_get_entry(int index, uint32_t type,
+uint64_t *address, uint64_t *length);
+
+
+
+#endif
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ab1fe1169a..75cdf57922 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -87,6 +87,7 @@
 #include "sysemu/replay.h"
 #include "qapi/qmp/qerror.h"
 #include "config-devices.h"
+#include "e820_memory_layout.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -98,22 +99,6 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-#define E820_NR_ENTRIES16
-
-struct e820_entry {
-uint64_t address;
-uint64_t length;
-uint32_t type;
-} QEMU_PACKED __attribute((__aligned__(4)));
-
-struct e820_table {
-uint32_t count;
-struct e820_entry entry[E820_NR_ENTRIES];
-} QEMU_PACKED __attribute((__aligned__(4)));
-
-static struct e820_table e820_reserve;
-static struct e820_entry *e820_table;
-static unsigned e820_entries;
 struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
 
 /* Physical Address of PVH entry point read from kernel ELF NOTE */
@@ -877,50 +862,6 @@ static void handle_a20_line_change(void *opaque, int irq, 
int level)
 x86_cpu_set_a20(cpu, level);
 }
 
-int e820_add_entry(uint64_t address, 

[Qemu-devel] [PATCH v4 07/15] hw/i386/pc: Pass the CPUArchIdList array by argument

2019-08-18 Thread Philippe Mathieu-Daudé
Pass the CPUArchIdList array by argument, this will
allow us to remove the PCMachineState argument later.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b97d1991cf..d296b3c3e1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -934,14 +934,13 @@ static void pc_build_smbios(PCMachineState *pcms)
 }
 
 static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms,
+  const CPUArchIdList *cpus,
   uint16_t boot_cpus,
   uint16_t apic_id_limit)
 {
 FWCfgState *fw_cfg;
 uint64_t *numa_fw_cfg;
 int i;
-const CPUArchIdList *cpus;
-MachineClass *mc = MACHINE_GET_CLASS(pcms);
 
 fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4,
 _space_memory);
@@ -959,7 +958,7 @@ static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms,
  * So for compatibility reasons with old BIOSes we are stuck with
  * "etc/max-cpus" actually being apic_id_limit
  */
-fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)pcms->apic_id_limit);
+fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, apic_id_limit);
 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
 fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
  acpi_tables, acpi_tables_len);
@@ -975,20 +974,19 @@ static FWCfgState *fw_cfg_arch_create(PCMachineState 
*pcms,
  * of nodes, one word for each VCPU->node and one word for each node to
  * hold the amount of memory.
  */
-numa_fw_cfg = g_new0(uint64_t, 1 + pcms->apic_id_limit + nb_numa_nodes);
+numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + nb_numa_nodes);
 numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
-cpus = mc->possible_cpu_arch_ids(MACHINE(pcms));
 for (i = 0; i < cpus->len; i++) {
 unsigned int apic_id = cpus->cpus[i].arch_id;
-assert(apic_id < pcms->apic_id_limit);
+assert(apic_id < apic_id_limit);
 numa_fw_cfg[apic_id + 1] = cpu_to_le64(cpus->cpus[i].props.node_id);
 }
 for (i = 0; i < nb_numa_nodes; i++) {
-numa_fw_cfg[pcms->apic_id_limit + 1 + i] =
+numa_fw_cfg[apic_id_limit + 1 + i] =
 cpu_to_le64(numa_info[i].node_mem);
 }
 fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
- (1 + pcms->apic_id_limit + nb_numa_nodes) *
+ (1 + apic_id_limit + nb_numa_nodes) *
  sizeof(*numa_fw_cfg));
 
 return fw_cfg;
@@ -1760,6 +1758,7 @@ void pc_memory_init(PCMachineState *pcms,
 MemoryRegion *ram_below_4g, *ram_above_4g;
 FWCfgState *fw_cfg;
 MachineState *machine = MACHINE(pcms);
+MachineClass *mc = MACHINE_GET_CLASS(machine);
 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
 
 assert(machine->ram_size == pcms->below_4g_mem_size +
@@ -1793,7 +1792,6 @@ void pc_memory_init(PCMachineState *pcms,
 if (!pcmc->has_reserved_memory &&
 (machine->ram_slots ||
  (machine->maxram_size > machine->ram_size))) {
-MachineClass *mc = MACHINE_GET_CLASS(machine);
 
 error_report("\"-memory 'slots|maxmem'\" is not supported by: %s",
  mc->name);
@@ -1856,7 +1854,8 @@ void pc_memory_init(PCMachineState *pcms,
 option_rom_mr,
 1);
 
-fw_cfg = fw_cfg_arch_create(pcms, pcms->boot_cpus, pcms->apic_id_limit);
+fw_cfg = fw_cfg_arch_create(pcms, mc->possible_cpu_arch_ids(machine),
+pcms->boot_cpus, pcms->apic_id_limit);
 
 rom_set_fw(fw_cfg);
 
-- 
2.20.1




[Qemu-devel] [PATCH v4 08/15] hw/i386/pc: Remove unused PCMachineState argument in fw_cfg_arch_create

2019-08-18 Thread Philippe Mathieu-Daudé
In the previous commit we removed the last access to PCMachineState.
It is now an unused argument, remove it from the function prototype.

Suggested-by: Christophe de Dinechin 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d296b3c3e1..acd9641d05 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -933,8 +933,7 @@ static void pc_build_smbios(PCMachineState *pcms)
 }
 }
 
-static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms,
-  const CPUArchIdList *cpus,
+static FWCfgState *fw_cfg_arch_create(const CPUArchIdList *cpus,
   uint16_t boot_cpus,
   uint16_t apic_id_limit)
 {
@@ -1854,7 +1853,7 @@ void pc_memory_init(PCMachineState *pcms,
 option_rom_mr,
 1);
 
-fw_cfg = fw_cfg_arch_create(pcms, mc->possible_cpu_arch_ids(machine),
+fw_cfg = fw_cfg_arch_create(mc->possible_cpu_arch_ids(machine),
 pcms->boot_cpus, pcms->apic_id_limit);
 
 rom_set_fw(fw_cfg);
-- 
2.20.1




[Qemu-devel] [PATCH v4 06/15] hw/i386/pc: Pass the apic_id_limit value by argument

2019-08-18 Thread Philippe Mathieu-Daudé
Pass the apic_id_limit value by argument, this will
allow us to remove the PCMachineState argument later.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4963551ee8..b97d1991cf 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -934,7 +934,8 @@ static void pc_build_smbios(PCMachineState *pcms)
 }
 
 static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms,
-  uint16_t boot_cpus)
+  uint16_t boot_cpus,
+  uint16_t apic_id_limit)
 {
 FWCfgState *fw_cfg;
 uint64_t *numa_fw_cfg;
@@ -1855,7 +1856,7 @@ void pc_memory_init(PCMachineState *pcms,
 option_rom_mr,
 1);
 
-fw_cfg = fw_cfg_arch_create(pcms, pcms->boot_cpus);
+fw_cfg = fw_cfg_arch_create(pcms, pcms->boot_cpus, pcms->apic_id_limit);
 
 rom_set_fw(fw_cfg);
 
-- 
2.20.1




[Qemu-devel] [PATCH v4 01/15] hw/i386/pc: Use e820_get_num_entries() to access e820_entries

2019-08-18 Thread Philippe Mathieu-Daudé
To be able to extract the e820* code out of this file (in the next
patch), access e820_entries with its correct helper.

Reviewed-by: Li Qiang 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3ab4bcb3ca..ab1fe1169a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1024,7 +1024,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, 
PCMachineState *pcms)
 fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
  _reserve, sizeof(e820_reserve));
 fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
-sizeof(struct e820_entry) * e820_entries);
+sizeof(struct e820_entry) * e820_get_num_entries());
 
 fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, _cfg, sizeof(hpet_cfg));
 /* allocate memory for the NUMA channel: one (64bit) word for the number
-- 
2.20.1




[Qemu-devel] [PATCH v4 05/15] hw/i386/pc: Pass the boot_cpus value by argument

2019-08-18 Thread Philippe Mathieu-Daudé
The boot_cpus is used once. Pass it by argument, this will
allow us to remove the PCMachineState argument later.

Suggested-by: Samuel Ortiz 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6cb39883e8..4963551ee8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -933,7 +933,8 @@ static void pc_build_smbios(PCMachineState *pcms)
 }
 }
 
-static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms)
+static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms,
+  uint16_t boot_cpus)
 {
 FWCfgState *fw_cfg;
 uint64_t *numa_fw_cfg;
@@ -943,7 +944,7 @@ static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms)
 
 fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4,
 _space_memory);
-fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
+fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, boot_cpus);
 
 /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
  *
@@ -1854,7 +1855,7 @@ void pc_memory_init(PCMachineState *pcms,
 option_rom_mr,
 1);
 
-fw_cfg = fw_cfg_arch_create(pcms);
+fw_cfg = fw_cfg_arch_create(pcms, pcms->boot_cpus);
 
 rom_set_fw(fw_cfg);
 
-- 
2.20.1




[Qemu-devel] [PATCH v4 03/15] hw/i386/pc: Use address_space_memory in place

2019-08-18 Thread Philippe Mathieu-Daudé
The address_space_memory variable is used once.
Use it in place and remove the argument.

Suggested-by: Samuel Ortiz 
Reviewed-by: Li Qiang 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 75cdf57922..68086cc0fc 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -933,7 +933,7 @@ static void pc_build_smbios(PCMachineState *pcms)
 }
 }
 
-static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
+static FWCfgState *bochs_bios_init(PCMachineState *pcms)
 {
 FWCfgState *fw_cfg;
 uint64_t *numa_fw_cfg;
@@ -941,7 +941,8 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, 
PCMachineState *pcms)
 const CPUArchIdList *cpus;
 MachineClass *mc = MACHINE_GET_CLASS(pcms);
 
-fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
+fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4,
+_space_memory);
 fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
 
 /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
@@ -1853,7 +1854,7 @@ void pc_memory_init(PCMachineState *pcms,
 option_rom_mr,
 1);
 
-fw_cfg = bochs_bios_init(_space_memory, pcms);
+fw_cfg = bochs_bios_init(pcms);
 
 rom_set_fw(fw_cfg);
 
-- 
2.20.1




[Qemu-devel] [PATCH v4 04/15] hw/i386/pc: Rename bochs_bios_init as more generic fw_cfg_arch_create

2019-08-18 Thread Philippe Mathieu-Daudé
The bochs_bios_init() function is not restricted to the Bochs
BIOS and is useful to other BIOS.
Since it is not specific to the PC machine, and can be reused
by other machines of the X86 architecture, rename it as
fw_cfg_arch_create().

Suggested-by: Samuel Ortiz 
Reviewed-by: Li Qiang 
Signed-off-by: Philippe Mathieu-Daudé 
---
v2: Rename x86_create_fw_cfg() -> fw_cfg_arch_create() (MST)
---
 hw/i386/pc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 68086cc0fc..6cb39883e8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -933,7 +933,7 @@ static void pc_build_smbios(PCMachineState *pcms)
 }
 }
 
-static FWCfgState *bochs_bios_init(PCMachineState *pcms)
+static FWCfgState *fw_cfg_arch_create(PCMachineState *pcms)
 {
 FWCfgState *fw_cfg;
 uint64_t *numa_fw_cfg;
@@ -1600,7 +1600,7 @@ void pc_cpus_init(PCMachineState *pcms)
  * Limit for the APIC ID value, so that all
  * CPU APIC IDs are < pcms->apic_id_limit.
  *
- * This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
+ * This is used for FW_CFG_MAX_CPUS. See comments on fw_cfg_arch_create().
  */
 pcms->apic_id_limit = x86_cpu_apic_id_from_index(pcms,
  ms->smp.max_cpus - 1) + 1;
@@ -1854,7 +1854,7 @@ void pc_memory_init(PCMachineState *pcms,
 option_rom_mr,
 1);
 
-fw_cfg = bochs_bios_init(pcms);
+fw_cfg = fw_cfg_arch_create(pcms);
 
 rom_set_fw(fw_cfg);
 
-- 
2.20.1




[Qemu-devel] [PATCH v4 00/15] hw/i386/pc: Do not restrict the fw_cfg functions to the PC machine

2019-08-18 Thread Philippe Mathieu-Daudé
Hi,

This is my take at salvaging some NEMU good work.
Samuel worked in adding the fw_cfg device to the x86-virt NEMU machine.
This series is inspired by NEMU's commit 3cb92d080835 [0] and adapted
to upstream style. The result makes the upstream codebase more
modularizable.
There are very little logical changes, this is mostly a cleanup
refactor.

Since v3 [3]:
- Addressed Christophe suggestion (patch #8)
- Rebased patch #15 since Eduardo merged Like Xu's work between.

Since v2 [2]:
- Addressed MST comments from v2 (only patch #2 modified)
  - do not use unsigned for enum
  - do not add unuseful documentation

Since v1 [1]:
- Addressed Li and MST comments

$ git backport-diff -u v3
Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/15:[] [--] 'hw/i386/pc: Use e820_get_num_entries() to access 
e820_entries'
002/15:[] [-C] 'hw/i386/pc: Extract e820 memory layout code'
003/15:[] [--] 'hw/i386/pc: Use address_space_memory in place'
004/15:[] [-C] 'hw/i386/pc: Rename bochs_bios_init as more generic 
fw_cfg_arch_create'
005/15:[] [--] 'hw/i386/pc: Pass the boot_cpus value by argument'
006/15:[] [--] 'hw/i386/pc: Pass the apic_id_limit value by argument'
007/15:[0002] [FC] 'hw/i386/pc: Pass the CPUArchIdList array by argument'
008/15:[down] 'hw/i386/pc: Remove unused PCMachineState argument in 
fw_cfg_arch_create'
009/15:[] [-C] 'hw/i386/pc: Let pc_build_smbios() take a FWCfgState 
argument'
010/15:[] [-C] 'hw/i386/pc: Let pc_build_smbios() take a generic 
MachineState argument'
011/15:[] [-C] 'hw/i386/pc: Rename pc_build_smbios() as generic 
fw_cfg_build_smbios()'
012/15:[] [--] 'hw/i386/pc: Let pc_build_feature_control() take a 
FWCfgState argument'
013/15:[] [--] 'hw/i386/pc: Let pc_build_feature_control() take a 
MachineState argument'
014/15:[] [--] 'hw/i386/pc: Rename pc_build_feature_control() as generic 
fw_cfg_build_*'
015/15:[0017] [FC] 'hw/i386/pc: Extract the x86 generic fw_cfg code'

Regards,

Phil.

[0] 
https://github.com/intel/nemu/commit/3cb92d080835ac8d47c8b713156338afa33cff5c
[1] https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg05759.html
[2] https://lists.gnu.org/archive/html/qemu-devel/2019-06/msg02786.html
[3] https://lists.gnu.org/archive/html/qemu-devel/2019-07/msg00193.html

Philippe Mathieu-Daudé (15):
  hw/i386/pc: Use e820_get_num_entries() to access e820_entries
  hw/i386/pc: Extract e820 memory layout code
  hw/i386/pc: Use address_space_memory in place
  hw/i386/pc: Rename bochs_bios_init as more generic fw_cfg_arch_create
  hw/i386/pc: Pass the boot_cpus value by argument
  hw/i386/pc: Pass the apic_id_limit value by argument
  hw/i386/pc: Pass the CPUArchIdList array by argument
  hw/i386/pc: Remove unused PCMachineState argument in
fw_cfg_arch_create
  hw/i386/pc: Let pc_build_smbios() take a FWCfgState argument
  hw/i386/pc: Let pc_build_smbios() take a generic MachineState argument
  hw/i386/pc: Rename pc_build_smbios() as generic fw_cfg_build_smbios()
  hw/i386/pc: Let pc_build_feature_control() take a FWCfgState argument
  hw/i386/pc: Let pc_build_feature_control() take a MachineState
argument
  hw/i386/pc: Rename pc_build_feature_control() as generic
fw_cfg_build_*
  hw/i386/pc: Extract the x86 generic fw_cfg code

 hw/i386/Makefile.objs|   2 +-
 hw/i386/e820_memory_layout.c |  59 ++
 hw/i386/e820_memory_layout.h |  42 
 hw/i386/fw_cfg.c | 136 +++
 hw/i386/fw_cfg.h |   7 ++
 hw/i386/pc.c | 202 ++-
 include/hw/i386/pc.h |  11 --
 target/i386/kvm.c|   1 +
 8 files changed, 254 insertions(+), 206 deletions(-)
 create mode 100644 hw/i386/e820_memory_layout.c
 create mode 100644 hw/i386/e820_memory_layout.h

-- 
2.20.1




Re: [Qemu-devel] [PATCH] linux-user: add memfd_create

2019-08-18 Thread Philippe Mathieu-Daudé
Cc'ing Marc-André

On 8/16/19 11:10 PM, Shu-Chun Weng via Qemu-devel wrote:
> Add support for the memfd_create syscall. If the host does not have the
> libc wrapper, translate to a direct syscall with NC-macro.
> 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1734792
> Signed-off-by: Shu-Chun Weng 
> ---
>  include/qemu/memfd.h |  4 
>  linux-user/syscall.c | 11 +++
>  util/memfd.c |  2 +-
>  3 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h
> index d551c28b68..975b6bdb77 100644
> --- a/include/qemu/memfd.h
> +++ b/include/qemu/memfd.h
> @@ -32,6 +32,10 @@
>  #define MFD_HUGE_SHIFT 26
>  #endif
>  
> +#if defined CONFIG_LINUX && !defined CONFIG_MEMFD
> +int memfd_create(const char *name, unsigned int flags);
> +#endif
> +
>  int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
>uint64_t hugetlbsize, unsigned int seals, Error 
> **errp);
>  bool qemu_memfd_alloc_check(void);
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 8367cb138d..b506c1f40e 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -20,6 +20,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu/cutils.h"
>  #include "qemu/path.h"
> +#include "qemu/memfd.h"
>  #include 
>  #include 
>  #include 
> @@ -11938,6 +11939,16 @@ static abi_long do_syscall1(void *cpu_env, int num, 
> abi_long arg1,
>  /* PowerPC specific.  */
>  return do_swapcontext(cpu_env, arg1, arg2, arg3);
>  #endif
> +#ifdef TARGET_NR_memfd_create
> +case TARGET_NR_memfd_create:
> +p = lock_user_string(arg1);
> +if (!p) {
> +return -TARGET_EFAULT;
> +}
> +ret = get_errno(memfd_create(p, arg2));
> +unlock_user(p, arg1, 0);
> +return ret;
> +#endif
>  
>  default:
>  qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
> diff --git a/util/memfd.c b/util/memfd.c
> index 00334e5b21..4a3c07e0be 100644
> --- a/util/memfd.c
> +++ b/util/memfd.c
> @@ -35,7 +35,7 @@
>  #include 
>  #include 
>  
> -static int memfd_create(const char *name, unsigned int flags)
> +int memfd_create(const char *name, unsigned int flags)
>  {
>  #ifdef __NR_memfd_create
>  return syscall(__NR_memfd_create, name, flags);
> 



Re: [Qemu-devel] [PATCH] Fix hw/rdma/vmw/pvrdma_cmd.c build

2019-08-18 Thread Philippe Mathieu-Daudé
On 8/18/19 2:28 PM, Yuval Shaia wrote:
> On Thu, Aug 15, 2019 at 02:12:44PM +0200, Stephen Kitt wrote:
>> On Thu, 15 Aug 2019 13:57:05 +0300, Yuval Shaia 
>> wrote:
>>
>>> On Sun, Aug 11, 2019 at 09:42:47PM +0200, Stephen Kitt wrote:
 This was broken by the cherry-pick in 41dd30f. Fix by handling errors
 as in the rest of the function: "goto out" instead of "return rc".

 Signed-off-by: Stephen Kitt 
 ---
  hw/rdma/vmw/pvrdma_cmd.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
 index bb9a9f1cd1..a3a86d7c8e 100644
 --- a/hw/rdma/vmw/pvrdma_cmd.c
 +++ b/hw/rdma/vmw/pvrdma_cmd.c
 @@ -514,7 +514,7 @@ static int create_qp(PVRDMADev *dev, union
 pvrdma_cmd_req *req, cmd->recv_cq_handle, rings, >qpn);
  if (resp->hdr.err) {
  destroy_qp_rings(rings);
 -return rc;
 +goto out;  
>>>
>>> This label was removed, can you please check master branch?
>>
>> Sorry, it wasn’t clear from my message — my patch is against the stable-3.1
>> branch.

You want to Cc then ;) Doing it for you.

> I see, in that case fix make sense.
> 
> Reviewed-by: Yuval Shaia 
> 
>>
>> Regards,
>>
>> Stephen
> 
> 
> 



Re: [Qemu-devel] [PATCH v2 1/3] decodetree: Allow !function with no input bits

2019-08-18 Thread Philippe Mathieu-Daudé
On 8/18/19 8:39 AM, Richard Henderson wrote:
> Call this form a "parameter", returning a value extracted
> from the DisasContext.
> 
> Signed-off-by: Richard Henderson 
> ---
>  docs/devel/decodetree.rst |  8 -
>  scripts/decodetree.py | 49 ---
>  tests/decode/err_field6.decode|  5 
>  tests/decode/succ_function.decode |  6 
>  4 files changed, 56 insertions(+), 12 deletions(-)
>  create mode 100644 tests/decode/err_field6.decode
>  create mode 100644 tests/decode/succ_function.decode
> 
> diff --git a/docs/devel/decodetree.rst b/docs/devel/decodetree.rst
> index 44ac621ea8..ce7f52308f 100644
> --- a/docs/devel/decodetree.rst
> +++ b/docs/devel/decodetree.rst
> @@ -23,7 +23,7 @@ Fields
>  
>  Syntax::
>  
> -  field_def := '%' identifier ( unnamed_field )+ ( !function=identifier 
> )?
> +  field_def := '%' identifier ( unnamed_field )* ( !function=identifier 
> )?
>unnamed_field := number ':' ( 's' ) number
>  
>  For *unnamed_field*, the first number is the least-significant bit position
> @@ -34,6 +34,12 @@ present, they are concatenated.  In this way one can 
> define disjoint fields.
>  If ``!function`` is specified, the concatenated result is passed through the
>  named function, taking and returning an integral value.
>  
> +One may use ``!function`` with zero ``unnamed_fields``.  This case is called
> +a *parameter*, and the named function is only passed the ``DisasContext``
> +and returns an integral value extracted from there.
> +
> +A field with no ``unnamed_fields`` and no ``!function`` is in error.
> +
>  FIXME: the fields of the structure into which this result will be stored
>  is restricted to ``int``.  Which means that we cannot expand 64-bit items.
>  
> diff --git a/scripts/decodetree.py b/scripts/decodetree.py
> index d7a59d63ac..31e2f04ecb 100755
> --- a/scripts/decodetree.py
> +++ b/scripts/decodetree.py
> @@ -245,7 +245,7 @@ class ConstField:
>  
>  
>  class FunctionField:
> -"""Class representing a field passed through an expander"""
> +"""Class representing a field passed through a function"""
>  def __init__(self, func, base):
>  self.mask = base.mask
>  self.sign = base.sign
> @@ -266,6 +266,27 @@ class FunctionField:
>  # end FunctionField
>  
>  
> +class ParameterField:
> +"""Class representing a pseudo-field read from a function"""
> +def __init__(self, func):
> +self.mask = 0
> +self.sign = 0
> +self.func = func
> +
> +def __str__(self):
> +return self.func
> +
> +def str_extract(self):
> +return self.func + '(ctx)'
> +
> +def __eq__(self, other):
> +return self.func == other.func
> +
> +def __ne__(self, other):
> +return not self.__eq__(other)
> +# end FunctionField

Nit: end ParameterField

> +
> +
>  class Arguments:
>  """Class representing the extracted fields of a format"""
>  def __init__(self, nm, flds, extern):
> @@ -433,17 +454,23 @@ def parse_field(lineno, name, toks):
>  
>  if width > insnwidth:
>  error(lineno, 'field too large')
> -if len(subs) == 1:
> -f = subs[0]
> +if len(subs) == 0:
> +if func:
> +f = ParameterField(func)
> +else:
> +error(lineno, 'field with no value')
>  else:
> -mask = 0
> -for s in subs:
> -if mask & s.mask:
> -error(lineno, 'field components overlap')
> -mask |= s.mask
> -f = MultiField(subs, mask)
> -if func:
> -f = FunctionField(func, f)
> +if len(subs) == 1:
> +f = subs[0]
> +else:
> +mask = 0
> +for s in subs:
> +if mask & s.mask:
> +error(lineno, 'field components overlap')
> +mask |= s.mask
> +f = MultiField(subs, mask)
> +if func:
> +f = FunctionField(func, f)
>  
>  if name in fields:
>  error(lineno, 'duplicate field', name)
> diff --git a/tests/decode/err_field6.decode b/tests/decode/err_field6.decode
> new file mode 100644
> index 00..a719884572
> --- /dev/null
> +++ b/tests/decode/err_field6.decode
> @@ -0,0 +1,5 @@
> +# This work is licensed under the terms of the GNU LGPL, version 2 or later.
> +# See the COPYING.LIB file in the top-level directory.
> +
> +# Diagnose no bits in field
> +%field
> diff --git a/tests/decode/succ_function.decode 
> b/tests/decode/succ_function.decode
> new file mode 100644
> index 00..7751b1784e
> --- /dev/null
> +++ b/tests/decode/succ_function.decode
> @@ -0,0 +1,6 @@
> +# This work is licensed under the terms of the GNU LGPL, version 2 or later.
> +# See the COPYING.LIB file in the top-level directory.
> +
> +# "Field" as parameter pulled from DisasContext.
> +%foo  !function=foo
> +foo    %foo
> 

Reviewed-by: Philippe Mathieu-Daude 



Re: [Qemu-devel] [PATCH v7 11/42] memory: Access MemoryRegion with MemOp

2019-08-18 Thread Philippe Mathieu-Daudé
On 8/16/19 9:30 AM, tony.ngu...@bt.com wrote:
> Convert memory_region_dispatch_{read|write} operand "unsigned size"
> into a "MemOp op".
> 
> Signed-off-by: Tony Nguyen 
> Reviewed-by: Richard Henderson 
> ---
>  include/exec/memop.h  | 20 ++--
>  include/exec/memory.h |  9 +
>  memory.c              |  7 +--
>  3 files changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/include/exec/memop.h b/include/exec/memop.h
> index dfd76a1..0a610b7 100644
> --- a/include/exec/memop.h
> +++ b/include/exec/memop.h
> @@ -12,6 +12,8 @@
>  #ifndef MEMOP_H
>  #define MEMOP_H
>  
> +#include "qemu/host-utils.h"
> +
>  typedef enum MemOp {
>      MO_8     = 0,
>      MO_16    = 1,
> @@ -107,14 +109,20 @@ typedef enum MemOp {
>      MO_SSIZE = MO_SIZE | MO_SIGN,
>  } MemOp;
>  
> +/* MemOp to size in bytes.  */
> +static inline unsigned memop_size(MemOp op)
> +{
> +    return 1 << (op & MO_SIZE);
> +}
> +
>  /* Size in bytes to MemOp.  */
> -static inline unsigned size_memop(unsigned size)
> +static inline MemOp size_memop(unsigned size)
>  {
> -    /*
> -     * FIXME: No-op to aid conversion of
> memory_region_dispatch_{read|write}
> -     * "unsigned size" operand into a "MemOp op".
> -     */
> -    return size;
> +#ifdef CONFIG_DEBUG_TCG
> +    /* Power of 2 up to 8.  */
> +    assert((size & (size - 1)) == 0 && size >= 1 && size <= 8);

Easier to review as:

   assert(is_power_of_2(size) && size <= 8);

(This can be cleaned later).

> +#endif
> +    return ctz32(size);
>  }
>  
>  #endif
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index bb0961d..975b86a 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -19,6 +19,7 @@
>  #include "exec/cpu-common.h"
>  #include "exec/hwaddr.h"
>  #include "exec/memattrs.h"
> +#include "exec/memop.h"
>  #include "exec/ramlist.h"
>  #include "qemu/queue.h"
>  #include "qemu/int128.h"
> @@ -1731,13 +1732,13 @@ void mtree_info(bool flatview, bool
> dispatch_tree, bool owner);
>   * @mr: #MemoryRegion to access
>   * @addr: address within that region
>   * @pval: pointer to uint64_t which the data is written to
> - * @size: size of the access in bytes
> + * @op: size, sign, and endianness of the memory operation
>   * @attrs: memory transaction attributes to use for the access
>   */
>  MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
>                                          hwaddr addr,
>                                          uint64_t *pval,
> -                                        unsigned size,
> +                                        MemOp op,
>                                          MemTxAttrs attrs);
>  /**
>   * memory_region_dispatch_write: perform a write directly to the specified
> @@ -1746,13 +1747,13 @@ MemTxResult
> memory_region_dispatch_read(MemoryRegion *mr,
>   * @mr: #MemoryRegion to access
>   * @addr: address within that region
>   * @data: data to write
> - * @size: size of the access in bytes
> + * @op: size, sign, and endianness of the memory operation
>   * @attrs: memory transaction attributes to use for the access
>   */
>  MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
>                                           hwaddr addr,
>                                           uint64_t data,
> -                                         unsigned size,
> +                                         MemOp op,
>                                           MemTxAttrs attrs);
>  
>  /**
> diff --git a/memory.c b/memory.c
> index 5d8c9a9..89ea4fb 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1439,9 +1439,10 @@ static MemTxResult
> memory_region_dispatch_read1(MemoryRegion *mr,
>  MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
>                                          hwaddr addr,
>                                          uint64_t *pval,
> -                                        unsigned size,
> +                                        MemOp op,
>                                          MemTxAttrs attrs)
>  {
> +    unsigned size = memop_size(op);
>      MemTxResult r;
>  
>      if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
> @@ -1483,9 +1484,11 @@ static bool
> memory_region_dispatch_write_eventfds(MemoryRegion *mr,
>  MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
>                                           hwaddr addr,
>                                           uint64_t data,
> -                                         unsigned size,
> +                                         MemOp op,
>                                           MemTxAttrs attrs)
>  {
> +    unsigned size = memop_size(op);
> +
>      if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
>          unassigned_mem_write(mr, addr, data, size);
>          return MEMTX_DECODE_ERROR;
> -- 
> 1.8.3.1
> 
> ​
> 
> 



Re: [Qemu-devel] [PATCH 0/6] net/eth: Remove duplicated tcp/udp_hdr structures

2019-08-18 Thread Philippe Mathieu-Daudé
Hi Jason,

On 8/8/19 4:34 PM, Philippe Mathieu-Daudé wrote:
> This is a preparatory cleanup series.
> 
> Commit 75020a70215 introduced 4 very equivalent structures:
> - tcp_header and tcp_hdr,
> - udp_header and udp_hdr.
> 
> Choose the most widely use in the codebase, which happens to
> provide convenient bitfields manipulation macros and is not
> endian-specific.
> 
> Philippe Mathieu-Daudé (6):
>   hw/net/virtio-net: Use TCP_HEADER_FLAGS/TCP_HEADER_DATA_OFFSET macros
>   net/colo-compare: Use the tcp_header structure
>   net/filter-rewriter: Use the tcp_header structure
>   hw/net/vmxnet3: Use the tcp_header structure
>   net/eth: Remove the unused tcp_hdr structure
>   net/eth: Remove the single use of udp_hdr structure

Are you OK to take this series?

It got reviewed by Dmitry Fleytman.

Thanks,

Phil.



Re: [Qemu-devel] [PATCH] ppc: Three floating point fixes

2019-08-18 Thread Aleksandar Markovic
18.08.2019. 10.10, "Richard Henderson"  је
написао/ла:
>
> On 8/16/19 11:59 PM, Aleksandar Markovic wrote:
> >> From: "Paul A. Clarke" 
> ...
> >>   ISA 3.0B has xscvdpspn leaving its result in word 1 of the target
> > register,
> >>   and mffprwz expecting its input to come from word 0 of the source
> > register.
> >>   This sequence fails with QEMU, as a shift is required between those
two
> >>   instructions.  However, the hardware splats the result to both word 0
> > and
> >>   word 1 of its output register, so the shift is not necessary.
> >>   Expect a future revision of the ISA to specify this behavior.
> >>
> >
> > Hmmm... Isn't this a gcc bug (using undocumented hardware feature),
given
> > everything you said here?
>
> The key here is "expect a future revision of the ISA to specify this
behavior".
>
> It's clearly within IBM's purview to adjust the specification to document
a
> previously undocumented hardware feature.
>

By no means, yes, the key is in ISA documentation. But, the impression that
full original commit message conveys is that the main reason for change is
gcc behavior. If we accepted in general that gcc behavior determines QEMU
behavior, I am afraid we would be on a very slippery slope - therefore I
think the commit message (and possible code comment) should, in my opinion,
mention ISA docs as the central reason for change. Paul, is there any
tentative release date of the new ISA specification?

Aleksandar

>
> r~


Re: [Qemu-devel] [edk2-devel] CPU hotplug using SMM with QEMU+OVMF

2019-08-18 Thread Paolo Bonzini
On 17/08/19 02:20, Yao, Jiewen wrote:
> [Jiewen] That is OK. Then we MUST add the third adversary.
> -- Adversary: Simple hardware attacker, who can use device to perform DMA 
> attack in the virtual world.
> NOTE: The DMA attack in the real world is out of scope. That is be handled by 
> IOMMU in the real world, such as VTd. -- Please do clarify if this is TRUE.
> 
> In the real world:
> #1: the SMM MUST be non-DMA capable region.
> #2: the MMIO MUST be non-DMA capable region.
> #3: the stolen memory MIGHT be DMA capable region or non-DMA capable
> region. It depends upon the silicon design.
> #4: the normal OS accessible memory - including ACPI reclaim, ACPI
> NVS, and reserved memory not included by #3 - MUST be DMA capable region.
> As such, IOMMU protection is NOT required for #1 and #2. IOMMU
> protection MIGHT be required for #3 and MUST be required for #4.
> I assume the virtual environment is designed in the same way. Please
> correct me if I am wrong.
> 

Correct.  The 0x3...0x3 area is the only problematic one;
Igor's idea (or a variant, for example optionally remapping
0xa..0xa SMRAM to 0x3) is becoming more and more attractive.

Paolo



[Qemu-devel] [Bug 1796520] Re: autogen crashes on qemu-sh4-user after 61dedf2af7

2019-08-18 Thread John Paul Adrian Glaubitz
We can ask both glibc upstream and some SuperH experts. I'll ask.

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

Title:
  autogen crashes on qemu-sh4-user after 61dedf2af7

Status in QEMU:
  Confirmed

Bug description:
  Running "autogen --help" crashes on qemu-sh4-user with:

  (sid-sh4-sbuild)root@nofan:/# autogen --help
  Unhandled trap: 0x180
  pc=0xf64dd2de sr=0x pr=0xf63b9c74 fpscr=0x0008
  spc=0x ssr=0x gbr=0xf61102a8 vbr=0x
  sgr=0x dbr=0x delayed_pc=0xf64dd2a0 fpul=0x0003
  r0=0xf6fc1320 r1=0x r2=0x5dc4 r3=0xf67bfb50
  r4=0xf6fc1230 r5=0xf6fc141c r6=0x03ff r7=0x
  r8=0x0004 r9=0xf63e20bc r10=0xf6fc141c r11=0xf63e28f0
  r12=0xf63e2258 r13=0xf63eae1c r14=0x0804 r15=0xf6fc1220
  r16=0x r17=0x r18=0x r19=0x
  r20=0x r21=0x r22=0x r23=0x
  (sid-sh4-sbuild)root@nofan:/#

  Bi-secting found this commit to be the culprit:

  61dedf2af79fb5866dc7a0f972093682f2185e17 is the first bad commit
  commit 61dedf2af79fb5866dc7a0f972093682f2185e17
  Author: Richard Henderson 
  Date:   Tue Jul 18 10:02:50 2017 -1000

  target/sh4: Add missing FPSCR.PR == 0 checks
  
  Both frchg and fschg require PR == 0, otherwise undefined_operation.
  
  Reviewed-by: Aurelien Jarno 
  Signed-off-by: Richard Henderson 
  Message-Id: <20170718200255.31647-26-...@twiddle.net>
  Signed-off-by: Aurelien Jarno 

  :04 04 980d79b69ae712f23a1e4c56983e97a843153b4a
  1024c109f506c7ad57367c63bc8bbbc8a7a36cd7 M  target

  Reverting 61dedf2af79fb5866dc7a0f972093682f2185e17 fixes the problem
  for me.

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



[Qemu-devel] [PATCH 1/2] configure: Check if we can use ibv_reg_mr_iova

2019-08-18 Thread Yuval Shaia
The function reg_mr_iova is an enhanced version of ibv_reg_mr function
that can help to easly register and use guest's MRs.

Add check in 'configure' phase to detect if we have libibverbs with this
support.

Signed-off-by: Yuval Shaia 
---
 configure | 28 
 1 file changed, 28 insertions(+)

diff --git a/configure b/configure
index 714e7fb6a1..e8e4a57b6f 100755
--- a/configure
+++ b/configure
@@ -3205,6 +3205,34 @@ else
 pvrdma="no"
 fi
 
+# Let's see if enhanced reg_mr is supported
+if test "$pvrdma" = "yes" ; then
+
+cat > $TMPC <
+
+int
+main(void)
+{
+struct ibv_mr *mr;
+struct ibv_pd *pd = NULL;
+size_t length = 10;
+uint64_t iova = 0;
+int access = 0;
+void *addr = NULL;
+
+mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
+
+ibv_dereg_mr(mr);
+
+return 0;
+}
+EOF
+if ! compile_prog "" "-libverbs"; then
+QEMU_CFLAGS="$QEMU_CFLAGS -DLEGACY_RDMA_REG_MR"
+fi
+fi
+
 ##
 # VNC SASL detection
 if test "$vnc" = "yes" && test "$vnc_sasl" != "no" ; then
-- 
2.20.1




[Qemu-devel] [PATCH 0/2] rdma: Utilize ibv_reg_mr_iova for memory registration

2019-08-18 Thread Yuval Shaia
The virtual address that is provided by the guest in post_send and
post_recv operations is related to the guest address space. This
address
space is unknown to the HCA resides on host so extra step in these
operations is needed to adjust the address to host virtual address.

This step, which is done in data-path affects performances.

An enhanced verion of MR registration introduced here
https://patchwork.kernel.org/patch/11044467/ can be used so that the
guest virtual address space for this MR is known to the HCA in host.

This will save the data-path adjustment.

patch #1 deals with what is needed to detect if the library installed in
the host supports this function
patch #2 enhance the data-path ops by utilizing the new function

Yuval Shaia (2):
  configure: Check if we can use ibv_reg_mr_iova
  hw/rdma: Utilize ibv_reg_mr_iova for memory registration

 configure | 28 
 hw/rdma/rdma_backend.c| 13 +
 hw/rdma/rdma_backend.h|  5 +
 hw/rdma/rdma_rm.c |  5 +
 hw/rdma/vmw/pvrdma_main.c |  6 ++
 5 files changed, 57 insertions(+)

-- 
2.20.1




[Qemu-devel] [PATCH 2/2] hw/rdma: Utilize ibv_reg_mr_iova for memory registration

2019-08-18 Thread Yuval Shaia
The virtual address that is provided by the guest in post_send and
post_recv operations is related to the guest address space. This address
space is unknown to the HCA resides on host so extra step in these
operations is needed to adjust the address to host virtual address.

This step, which is done in data-path affects performances.

An enhanced verion of MR registration introduced here
https://patchwork.kernel.org/patch/11044467/ can be used so that the
guest virtual address space for this MR is known to the HCA in host.

This will save the data-path adjustment.

Signed-off-by: Yuval Shaia 
---
 hw/rdma/rdma_backend.c| 13 +
 hw/rdma/rdma_backend.h|  5 +
 hw/rdma/rdma_rm.c |  5 +
 hw/rdma/vmw/pvrdma_main.c |  6 ++
 4 files changed, 29 insertions(+)

diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
index c39051068d..c346407cd3 100644
--- a/hw/rdma/rdma_backend.c
+++ b/hw/rdma/rdma_backend.c
@@ -391,7 +391,11 @@ static int build_host_sge_array(RdmaDeviceResources 
*rdma_dev_res,
 return VENDOR_ERR_INVLKEY | ssge[ssge_idx].lkey;
 }
 
+#ifdef LEGACY_RDMA_REG_MR
 dsge->addr = (uintptr_t)mr->virt + ssge[ssge_idx].addr - mr->start;
+#else
+dsge->addr = ssge[ssge_idx].addr;
+#endif
 dsge->length = ssge[ssge_idx].length;
 dsge->lkey = rdma_backend_mr_lkey(>backend_mr);
 
@@ -735,10 +739,19 @@ void rdma_backend_destroy_pd(RdmaBackendPD *pd)
 }
 }
 
+#ifdef LEGACY_RDMA_REG_MR
 int rdma_backend_create_mr(RdmaBackendMR *mr, RdmaBackendPD *pd, void *addr,
size_t length, int access)
+#else
+int rdma_backend_create_mr(RdmaBackendMR *mr, RdmaBackendPD *pd, void *addr,
+   size_t length, uint64_t guest_start, int access)
+#endif
 {
+#ifdef LEGACY_RDMA_REG_MR
 mr->ibmr = ibv_reg_mr(pd->ibpd, addr, length, access);
+#else
+mr->ibmr = ibv_reg_mr_iova(pd->ibpd, addr, length, guest_start, access);
+#endif
 if (!mr->ibmr) {
 rdma_error_report("ibv_reg_mr fail, errno=%d", errno);
 return -EIO;
diff --git a/hw/rdma/rdma_backend.h b/hw/rdma/rdma_backend.h
index 7c1a19a2b5..127f96e2d5 100644
--- a/hw/rdma/rdma_backend.h
+++ b/hw/rdma/rdma_backend.h
@@ -78,8 +78,13 @@ int rdma_backend_query_port(RdmaBackendDev *backend_dev,
 int rdma_backend_create_pd(RdmaBackendDev *backend_dev, RdmaBackendPD *pd);
 void rdma_backend_destroy_pd(RdmaBackendPD *pd);
 
+#ifdef LEGACY_RDMA_REG_MR
 int rdma_backend_create_mr(RdmaBackendMR *mr, RdmaBackendPD *pd, void *addr,
size_t length, int access);
+#else
+int rdma_backend_create_mr(RdmaBackendMR *mr, RdmaBackendPD *pd, void *addr,
+   size_t length, uint64_t guest_start, int access);
+#endif
 void rdma_backend_destroy_mr(RdmaBackendMR *mr);
 
 int rdma_backend_create_cq(RdmaBackendDev *backend_dev, RdmaBackendCQ *cq,
diff --git a/hw/rdma/rdma_rm.c b/hw/rdma/rdma_rm.c
index 1927f85472..1524dfaeaa 100644
--- a/hw/rdma/rdma_rm.c
+++ b/hw/rdma/rdma_rm.c
@@ -227,8 +227,13 @@ int rdma_rm_alloc_mr(RdmaDeviceResources *dev_res, 
uint32_t pd_handle,
 mr->length = guest_length;
 mr->virt += (mr->start & (TARGET_PAGE_SIZE - 1));
 
+#ifdef LEGACY_RDMA_REG_MR
 ret = rdma_backend_create_mr(>backend_mr, >backend_pd, 
mr->virt,
  mr->length, access_flags);
+#else
+ret = rdma_backend_create_mr(>backend_mr, >backend_pd, 
mr->virt,
+ mr->length, guest_start, access_flags);
+#endif
 if (ret) {
 ret = -EIO;
 goto out_dealloc_mr;
diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
index 3e36e13013..18075285f6 100644
--- a/hw/rdma/vmw/pvrdma_main.c
+++ b/hw/rdma/vmw/pvrdma_main.c
@@ -664,6 +664,12 @@ static void pvrdma_realize(PCIDevice *pdev, Error **errp)
 dev->shutdown_notifier.notify = pvrdma_shutdown_notifier;
 qemu_register_shutdown_notifier(>shutdown_notifier);
 
+#ifdef LEGACY_RDMA_REG_MR
+rdma_info_report("Using legacy reg_mr");
+#else
+rdma_info_report("Using iova reg_mr");
+#endif
+
 out:
 if (rc) {
 pvrdma_fini(pdev);
-- 
2.20.1




[Qemu-devel] [PATCH] input-linux: add shift+shift as a grab toggle

2019-08-18 Thread Niklas Haas
From: Niklas Haas 

We have ctrl-ctrl and alt-alt; why not shift-shift? That's my preferred
grab binding, personally.

Signed-off-by: Niklas Haas 
---
 qapi/ui.json | 3 ++-
 ui/input-linux.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/qapi/ui.json b/qapi/ui.json
index 59e412139a..e04525d8b4 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1025,7 +1025,8 @@
 #
 ##
 { 'enum': 'GrabToggleKeys',
-  'data': [ 'ctrl-ctrl', 'alt-alt', 'meta-meta', 'scrolllock', 
'ctrl-scrolllock' ] }
+  'data': [ 'ctrl-ctrl', 'alt-alt', 'shift-shift','meta-meta', 'scrolllock',
+'ctrl-scrolllock' ] }
 
 ##
 # @DisplayGTK:
diff --git a/ui/input-linux.c b/ui/input-linux.c
index 59456fe765..a7b280b25b 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -113,6 +113,10 @@ static bool input_linux_check_toggle(InputLinux *il)
 return il->keydown[KEY_LEFTALT] &&
 il->keydown[KEY_RIGHTALT];
 
+case GRAB_TOGGLE_KEYS_SHIFT_SHIFT:
+return il->keydown[KEY_LEFTSHIFT] &&
+il->keydown[KEY_RIGHTSHIFT];
+
 case GRAB_TOGGLE_KEYS_META_META:
 return il->keydown[KEY_LEFTMETA] &&
 il->keydown[KEY_RIGHTMETA];
-- 
2.21.0




Re: [Qemu-devel] [PATCH v7 38/42] memory: Single byte swap along the I/O path

2019-08-18 Thread Richard Henderson
On 8/16/19 8:38 AM, tony.ngu...@bt.com wrote:
> +static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)
>  {
> +if ((op & MO_BSWAP) != mr->ops->endianness) {
> +switch (op & MO_SIZE) {

You'll want to use devend_memop() here, as previously discussed.

> @@ -2331,7 +2322,7 @@ void memory_region_add_eventfd(MemoryRegion *mr,
>  }
> 
>  if (size) {
> -adjust_endianness(mr, , size);
> +adjust_endianness(mr, , size_memop(size));
>  }
>  memory_region_transaction_begin();
>  for (i = 0; i < mr->ioeventfd_nb; ++i) {
> @@ -2366,7 +2357,7 @@ void memory_region_del_eventfd(MemoryRegion *mr,
>  unsigned i;
> 
>  if (size) {
> -adjust_endianness(mr, , size);
> +adjust_endianness(mr, , size_memop(size));
>  }
>  memory_region_transaction_begin();
>  for (i = 0; i < mr->ioeventfd_nb; ++i) {

To preserve behaviour it would appear that these need MO_TE.


r~



Re: [Qemu-devel] [PATCH v7 37/42] cputlb: Replace size and endian operands for MemOp

2019-08-18 Thread Richard Henderson
On 8/16/19 8:38 AM, tony.ngu...@bt.com wrote:
>  static uint64_t full_ldub_mmu(CPUArchState *env, target_ulong addr,
>TCGMemOpIdx oi, uintptr_t retaddr)
>  {
> -return load_helper(env, addr, oi, retaddr, 1, false, false,
> -   full_ldub_mmu);
> +return load_helper(env, addr, oi, retaddr, MO_8, false, full_ldub_mmu);
...
>  void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
>  TCGMemOpIdx oi, uintptr_t retaddr)
>  {
> -store_helper(env, addr, val, oi, retaddr, 1, false);
> +store_helper(env, addr, val, oi, retaddr, MO_8);
>  }

MO_UB.

Otherwise,
Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH] Fix hw/rdma/vmw/pvrdma_cmd.c build

2019-08-18 Thread Yuval Shaia
On Thu, Aug 15, 2019 at 02:12:44PM +0200, Stephen Kitt wrote:
> On Thu, 15 Aug 2019 13:57:05 +0300, Yuval Shaia 
> wrote:
> 
> > On Sun, Aug 11, 2019 at 09:42:47PM +0200, Stephen Kitt wrote:
> > > This was broken by the cherry-pick in 41dd30f. Fix by handling errors
> > > as in the rest of the function: "goto out" instead of "return rc".
> > > 
> > > Signed-off-by: Stephen Kitt 
> > > ---
> > >  hw/rdma/vmw/pvrdma_cmd.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
> > > index bb9a9f1cd1..a3a86d7c8e 100644
> > > --- a/hw/rdma/vmw/pvrdma_cmd.c
> > > +++ b/hw/rdma/vmw/pvrdma_cmd.c
> > > @@ -514,7 +514,7 @@ static int create_qp(PVRDMADev *dev, union
> > > pvrdma_cmd_req *req, cmd->recv_cq_handle, rings, >qpn);
> > >  if (resp->hdr.err) {
> > >  destroy_qp_rings(rings);
> > > -return rc;
> > > +goto out;  
> > 
> > This label was removed, can you please check master branch?
> 
> Sorry, it wasn’t clear from my message — my patch is against the stable-3.1
> branch.

I see, in that case fix make sense.

Reviewed-by: Yuval Shaia 

> 
> Regards,
> 
> Stephen





Re: [Qemu-devel] [PATCH v7 36/42] memory: Access MemoryRegion with endianness

2019-08-18 Thread Richard Henderson
On 8/16/19 8:38 AM, tony.ngu...@bt.com wrote:
> Preparation for collapsing the two byte swaps adjust_endianness and
> handle_bswap into the former.
> 
> Call memory_region_dispatch_{read|write} with endianness encoded into
> the "MemOp op" operand.
> 
> This patch does not change any behaviour as
> memory_region_dispatch_{read|write} is yet to handle the endianness.
> 
> Once it does handle endianness, callers with byte swaps can collapse
> them into adjust_endianness.
> 
> Signed-off-by: Tony Nguyen 
> ---
>  accel/tcg/cputlb.c   |  6 --
>  exec.c   |  5 +++--
>  hw/intc/armv7m_nvic.c| 15 ---
>  hw/s390x/s390-pci-inst.c |  6 --
>  hw/vfio/pci-quirks.c |  5 +++--
>  hw/virtio/virtio-pci.c   |  6 --
>  memory_ldst.inc.c| 18 --
>  7 files changed, 38 insertions(+), 23 deletions(-)
> 
> diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
> index 6c83878..0aff6a3 100644
> --- a/accel/tcg/cputlb.c
> +++ b/accel/tcg/cputlb.c
> @@ -906,7 +906,8 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
> *iotlbentry,
>  qemu_mutex_lock_iothread();
>  locked = true;
>  }
> -r = memory_region_dispatch_read(mr, mr_offset, , size_memop(size),
> +r = memory_region_dispatch_read(mr, mr_offset, ,
> +size_memop(size) | MO_TE,
>  iotlbentry->attrs);
>  if (r != MEMTX_OK) {
>  hwaddr physaddr = mr_offset +
> @@ -947,7 +948,8 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
> *iotlbentry,
>  qemu_mutex_lock_iothread();
>  locked = true;
>  }
> -r = memory_region_dispatch_write(mr, mr_offset, val, size_memop(size),
> +r = memory_region_dispatch_write(mr, mr_offset, val,
> + size_memop(size) | MO_TE,
>   iotlbentry->attrs);

Ok.  Conversion to target-endian via handle_bswap() in the callers.

> diff --git a/exec.c b/exec.c
> index 303f9a7..562fb5b 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -3335,7 +3335,8 @@ static MemTxResult flatview_write_continue(FlatView 
> *fv, hwaddr addr,
> potential bugs */
>  val = ldn_p(buf, l);
>  result |= memory_region_dispatch_write(mr, addr1, val,
> -   size_memop(l), attrs);
> +   size_memop(l) | MO_TE,
> +   attrs);
>  } else {
>  /* RAM case */
>  ptr = qemu_ram_ptr_length(mr->ram_block, addr1, , false);
> @@ -3397,7 +3398,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr 
> addr,
>  release_lock |= prepare_mmio_access(mr);
>  l = memory_access_size(mr, l, addr1);
>  result |= memory_region_dispatch_read(mr, addr1, ,
> -  size_memop(l), attrs);
> +  size_memop(l) | MO_TE, 
> attrs);
>  stn_p(buf, l, val);

Ok.  Please add comments:

/*
 * TODO: Merge bswap from ldn_p into memory_region_dispatch_write
 * by using ldn_he_p and dropping MO_TE to get a host-endian value.
 */

and similar for the store.

This must be delayed until after patch 38, when the MO_BSWAP component of the
MemOp is operated on by memory_region_dispatch_*.

> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -2346,8 +2346,8 @@ static MemTxResult nvic_sysreg_ns_write(void *opaque, 
> hwaddr addr,
>  if (attrs.secure) {
>  /* S accesses to the alias act like NS accesses to the real region */
>  attrs.secure = 0;
> -return memory_region_dispatch_write(mr, addr, value, 
> size_memop(size),
> -attrs);
> +return memory_region_dispatch_write(mr, addr, value,
> +size_memop(size) | MO_TE, attrs);
>  } else {
>  /* NS attrs are RAZ/WI for privileged, and BusFault for user */
>  if (attrs.user) {
> @@ -2366,8 +2366,8 @@ static MemTxResult nvic_sysreg_ns_read(void *opaque, 
> hwaddr addr,
>  if (attrs.secure) {
>  /* S accesses to the alias act like NS accesses to the real region */
>  attrs.secure = 0;
> -return memory_region_dispatch_read(mr, addr, data, size_memop(size),
> -   attrs);
> +return memory_region_dispatch_read(mr, addr, data,
> +   size_memop(size) | MO_TE, attrs);
>  } else {
>  /* NS attrs are RAZ/WI for privileged, and BusFault for user */
>  if (attrs.user) {
> @@ -2393,8 +2393,8 @@ static MemTxResult nvic_systick_write(void *opaque, 
> hwaddr addr,
> 
>  /* Direct the access to the correct systick */
>  mr = 

Re: [Qemu-devel] [PATCH 1/2] virtio: add vhost-user-fs base device

2019-08-18 Thread Michael S. Tsirkin
On Fri, Aug 16, 2019 at 03:33:20PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" 
> 
> The virtio-fs virtio device provides shared file system access using
> the FUSE protocol carried ovew virtio.
> The actual file server is implemented in an external vhost-user-fs device
> backend process.
> 
> Signed-off-by: Stefan Hajnoczi 
> Signed-off-by: Sebastien Boeuf 
> Signed-off-by: Dr. David Alan Gilbert 
> ---
>  configure   |  13 +
>  hw/virtio/Makefile.objs |   1 +
>  hw/virtio/vhost-user-fs.c   | 297 
>  include/hw/virtio/vhost-user-fs.h   |  45 +++
>  include/standard-headers/linux/virtio_fs.h  |  41 +++
>  include/standard-headers/linux/virtio_ids.h |   1 +
>  6 files changed, 398 insertions(+)
>  create mode 100644 hw/virtio/vhost-user-fs.c
>  create mode 100644 include/hw/virtio/vhost-user-fs.h
>  create mode 100644 include/standard-headers/linux/virtio_fs.h
> 
> diff --git a/configure b/configure
> index 714e7fb6a1..e7e33ee783 100755
> --- a/configure
> +++ b/configure
> @@ -382,6 +382,7 @@ vhost_crypto=""
>  vhost_scsi=""
>  vhost_vsock=""
>  vhost_user=""
> +vhost_user_fs=""
>  kvm="no"
>  hax="no"
>  hvf="no"
> @@ -1316,6 +1317,10 @@ for opt do
>;;
>--enable-vhost-vsock) vhost_vsock="yes"
>;;
> +  --disable-vhost-user-fs) vhost_user_fs="no"
> +  ;;
> +  --enable-vhost-user-fs) vhost_user_fs="yes"
> +  ;;
>--disable-opengl) opengl="no"
>;;
>--enable-opengl) opengl="yes"
> @@ -2269,6 +2274,10 @@ test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
>  if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
>error_exit "--enable-vhost-crypto requires --enable-vhost-user"
>  fi
> +test "$vhost_user_fs" = "" && vhost_user_fs=$vhost_user
> +if test "$vhost_user_fs" = "yes" && test "$vhost_user" = "no"; then
> +  error_exit "--enable-vhost-user-fs requires --enable-vhost-user"
> +fi
>  
>  # OR the vhost-kernel and vhost-user values for simplicity
>  if test "$vhost_net" = ""; then
> @@ -6425,6 +6434,7 @@ echo "vhost-crypto support $vhost_crypto"
>  echo "vhost-scsi support $vhost_scsi"
>  echo "vhost-vsock support $vhost_vsock"
>  echo "vhost-user support $vhost_user"
> +echo "vhost-user-fs support $vhost_user_fs"
>  echo "Trace backends$trace_backends"
>  if have_backend "simple"; then
>  echo "Trace output file $trace_file-"
> @@ -6921,6 +6931,9 @@ fi
>  if test "$vhost_user" = "yes" ; then
>echo "CONFIG_VHOST_USER=y" >> $config_host_mak
>  fi
> +if test "$vhost_user_fs" = "yes" ; then
> +  echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
> +fi
>  if test "$blobs" = "yes" ; then
>echo "INSTALL_BLOBS=yes" >> $config_host_mak
>  fi
> diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
> index 964ce78607..47ffbf22c4 100644
> --- a/hw/virtio/Makefile.objs
> +++ b/hw/virtio/Makefile.objs
> @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
>  common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
>  obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
>  obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
> +obj-$(CONFIG_VHOST_USER_FS) += vhost-user-fs.o
>  obj-$(call land,$(CONFIG_VIRTIO_CRYPTO),$(CONFIG_VIRTIO_PCI)) += 
> virtio-crypto-pci.o
>  obj-$(CONFIG_VIRTIO_PMEM) += virtio-pmem.o
>  common-obj-$(call land,$(CONFIG_VIRTIO_PMEM),$(CONFIG_VIRTIO_PCI)) += 
> virtio-pmem-pci.o
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> new file mode 100644
> index 00..2753c2c07a
> --- /dev/null
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -0,0 +1,297 @@
> +/*
> + * Vhost-user filesystem virtio device
> + *
> + * Copyright 2018 Red Hat, Inc.
> + *
> + * Authors:
> + *  Stefan Hajnoczi 
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version.  See the COPYING file in the
> + * top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include 
> +#include "standard-headers/linux/virtio_fs.h"
> +#include "qapi/error.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/virtio-access.h"
> +#include "qemu/error-report.h"
> +#include "hw/virtio/vhost-user-fs.h"
> +#include "monitor/monitor.h"
> +
> +static void vuf_get_config(VirtIODevice *vdev, uint8_t *config)
> +{
> +VHostUserFS *fs = VHOST_USER_FS(vdev);
> +struct virtio_fs_config fscfg = {};
> +
> +memcpy((char *)fscfg.tag, fs->conf.tag,
> +   MIN(strlen(fs->conf.tag) + 1, sizeof(fscfg.tag)));
> +
> +virtio_stl_p(vdev, _queues, fs->conf.num_queues);
> +
> +memcpy(config, , sizeof(fscfg));
> +}
> +
> +static void vuf_start(VirtIODevice *vdev)
> +{
> +VHostUserFS *fs = VHOST_USER_FS(vdev);
> +BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
> +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> +int ret;
> +int i;
> +
> +if (!k->set_guest_notifiers) {
> +error_report("binding does not support guest notifiers");
> +   

[Qemu-devel] Patchew s390 QEMU build issues

2019-08-18 Thread Stefan Hajnoczi
Hi,
Peter messaged me on IRC to say that QEMU Patchew s390 builds seemed broken.

Any chance you could take a look?

Thanks,
Stefan



Re: [Qemu-devel] [PATCH] qcow2: Fix the calculation of the maximum L2 cache size

2019-08-18 Thread Leonid Bloch
Thanks, Berto!

On 8/16/19 3:17 PM, Alberto Garcia wrote:
> The size of the qcow2 L2 cache defaults to 32 MB, which can be easily
> larger than the maximum amount of L2 metadata that the image can have.
> For example: with 64 KB clusters the user would need a qcow2 image
> with a virtual size of 256 GB in order to have 32 MB of L2 metadata.
> 
> Because of that, since commit b749562d9822d14ef69c9eaa5f85903010b86c30
> we forbid the L2 cache to become larger than the maximum amount of L2
> metadata for the image, calculated using this formula:
> 
>  uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
> 
> The problem with this formula is that the result should be rounded up
> to the cluster size because an L2 table on disk always takes one full
> cluster.
> 
> For example, a 1280 MB qcow2 image with 64 KB clusters needs exactly
> 160 KB of L2 metadata, but we need 192 KB on disk (3 clusters) even if
> the last 32 KB of those are not going to be used.
> 
> However QEMU rounds the numbers down and only creates 2 cache tables
> (128 KB), which is not enough for the image.
> 
> A quick test doing 4KB random writes on a 1280 MB image gives me
> around 500 IOPS, while with the correct cache size I get 16K IOPS.
> 
> Signed-off-by: Alberto Garcia 
> ---
>   block/qcow2.c | 6 +-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 039bdc2f7e..865839682c 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -826,7 +826,11 @@ static void read_cache_sizes(BlockDriverState *bs, 
> QemuOpts *opts,
>   bool l2_cache_entry_size_set;
>   int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
>   uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
> -uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
> +uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, 
> s->cluster_size);
> +/* An L2 table is always one cluster in size so the max cache size
> + * should be a multiple of the cluster size. */
> +uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),
> + s->cluster_size);
>   
>   combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
>   l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
> 


  1   2   >