Re: [PATCH 8/9] mirror: return the remaining dirty bytes upon query

2023-03-02 Thread Fiona Ebner
Am 02.03.23 um 17:31 schrieb Vladimir Sementsov-Ogievskiy:
> On 02.03.23 15:34, Fiona Ebner wrote:
>> Am 02.03.23 um 11:13 schrieb Vladimir Sementsov-Ogievskiy:
>>> On 02.03.23 13:00, Fiona Ebner wrote:
 Am 01.03.23 um 17:31 schrieb Vladimir Sementsov-Ogievskiy:
> On 24.02.23 17:48, Fiona Ebner wrote:
>> This can be used by management applications starting with a job in
>> background mode to determine when the switch to active mode should
>> happen.
>>
>> Suggested-by: Vladimir Sementsov-Ogievskiy
>> 
>> Signed-off-by: Fiona Ebner 
>> ---
>>     block/mirror.c   | 1 +
>>     qapi/block-core.json | 4 +++-
>>     2 files changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/block/mirror.c b/block/mirror.c
>> index 02b5bd8bd2..ac83309b82 100644
>> --- a/block/mirror.c
>> +++ b/block/mirror.c
>> @@ -1259,6 +1259,7 @@ static void mirror_query(BlockJob *job,
>> BlockJobInfo *info)
>>       info->u.mirror = (BlockJobInfoMirror) {
>>     .actively_synced = s->actively_synced,
>> +    .remaining_dirty = bdrv_get_dirty_count(s->dirty_bitmap),
>
> Doesn't it duplicate info->len - info->offset in meaning?
>

 Essentially yes, apart from the in-flight bytes:
>>>
>>> Is it worth reporting to user?
>>>
>>
>> You suggested that data_sent and remaining_dirty are important:
>> https://lists.nongnu.org/archive/html/qemu-devel/2023-02/msg03831.html
>>
> 
> Yes, sorry if it made you implement these fields :/ I was just thinking.

It was no big deal :)

> 
>> But I guess info->len - info->offset is just as good as part of a
>> heuristic to decide when the switch to active mode should happen.
>>
>> For us, it doesn't really matter right now, because our users didn't
>> report issues with convergence, so our plan is to just switch to active
>> mode after the job is ready. We just need actively_synced to infer when
>> the switch is complete.
>>
> 
> Hmm. But mirror can't become "actively_synced" until it not switched to
> active mode?

Yes, but that's fine. We'd wait for the job to be ready, then switch to
active mode and once actively_synced is true, we'd start migration. Then
we don't need to worry about triggering the assertion after inactivating
block devices upon switchover.

> 
>   job_progress_set_remaining(>common.job,
>  s->bytes_in_flight + cnt +
>  s->active_write_bytes_in_flight);

 Should I rather use that value (and rename it to e.g. data_remaining to
 be more similar to data_sent from 9/9)?

 But I'd argue the same way as in 9/9: it's not transparent to users
 what
 offset and len mean for the mirror job, because their documentation is
 for a generic block job. E.g. len is documented to be able to change in
 both directions while the job runs.

>>>
>>> Still I'm not sure that we need new status values. I.e. if you need some
>>> new ones, you should explain the case and why existing information is
>>> not enough.
>>>
>>> Especially when documentation of existing things is unclear, its better
>>> to start from improving it. And when we understand what len and offset
>>> means for mirror, it would probably be enough.
>>>
>>
>> Okay, makes sense! But I'm not sure how. Should I just add a paragraph
>> describing what the values mean for mirror in the description of @len
>> and @offset in @BlockJobInfo? Or where should this be documented?
>>
> 
> Hmm, or just in description of blockdev-mirror command. Still, I don't
> mean that you should do it.
> 
> If we want additional similar fields - then yes, we should describe why
> and what is different with existing fields, and good start for it - add
> details to documentation.
> If we don't add them - current heuristical understanding that "remaining
> ~= len - offset" is enough.
> So, I think better not add these fields now if you don't need them.
> 

Okay, sure. I'll let the people that actually need additional fields add
them :)

Best Regards,
Fiona




Re: [PATCH v3 00/18] hw/ide: Untangle ISA/PCI abuses of ide_init_ioport()

2023-03-02 Thread Mark Cave-Ayland

On 03/03/2023 06:58, David Woodhouse wrote:


On 2 March 2023 22:40:40 GMT, "Philippe Mathieu-Daudé"  
wrote:

Since v2: rebased

I'm posting this series as it to not block Bernhard's PIIX
cleanup work. I don't have code change planned, but eventually
reword / improve commit descriptions.

Tested commit after commit to be sure it is bisectable. Sadly
this was before Zoltan & Thomas report a problem with commit
bb98e0f59c ("hw/isa/vt82c686: Remove intermediate IRQ forwarder").


However much I stare at the partial revert which fixes it, I just cannot 
believe that the change could make any difference at all. There's got to be 
something weird going on there.

I was going to ask if the level mode for the PIT made any difference, but this 
is the output IRQ from the PIT to the CPU itself so I don't see how it would.

Would like to see a report with tracing from pic_update_irq, the CPU interrupt 
"handler" and the intermediate IRQ handler. With the intermediate present and 
without it. To compare the two.


I suspect it's related to the removal of the allocation of the qemu_irq: qdev gpios 
work by adding a child IRQ object to the device, so it could be possible that 
something in the gpio internals isn't being updated correctly when the value is 
overwritten directly.


Is the problem picked up when running a binary built with --enable-sanitizers? That's 
normally quite good at detecting this kind of issue.



ATB,

Mark.



[PATCH v2] vfio: Fix vfio_get_dev_region() trace event

2023-03-02 Thread Cédric Le Goater
From: Cédric Le Goater 

Simply revert 'x8' to fix the typo and remove the ending '8'

Fixes: e61a424f05 ("vfio: Create device specific region info helper")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1526
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/trace-events | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 669d9fe07c..28e82541a2 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -117,7 +117,7 @@ vfio_region_mmaps_set_enabled(const char *name, bool 
enabled) "Region %s mmaps e
 vfio_region_unmap(const char *name, unsigned long offset, unsigned long end) 
"Region %s unmap [0x%lx - 0x%lx]"
 vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) 
"Device %s region %d: %d sparse mmap entries"
 vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) 
"sparse entry %d [0x%lx - 0x%lx]"
-vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t 
subtype) "%s index %d, %08x/%0x8"
+vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t 
subtype) "%s index %d, %08x/%08x"
 vfio_dma_unmap_overflow_workaround(void) ""
 vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, uint64_t 
bitmap_size, uint64_t start) "container fd=%d, iova=0x%"PRIx64" size= 
0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64
 vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu 
dirty @ 0x%"PRIx64" - 0x%"PRIx64
-- 
2.39.2




Re: [PATCH] tests/qtest/migration-test: Disable migration/multifd/tcp/plain/cancel

2023-03-02 Thread Thomas Huth

On 02/03/2023 18.22, Peter Maydell wrote:

migration-test has been flaky for a long time, both in CI and
otherwise


Acked-by: Thomas Huth 

Do you want to apply it directly as a CI fix, or shall I queue it for my 
next pull request?


 Thomas





Re: [PATCH v2 4/6] docs/about/deprecated: Deprecate the qemu-system-arm binary

2023-03-02 Thread Thomas Huth

On 02/03/2023 23.16, Philippe Mathieu-Daudé wrote:

On 2/3/23 17:31, Thomas Huth wrote:

qemu-system-aarch64 is a proper superset of qemu-system-arm,
and the latter was mainly still required for 32-bit KVM support.
But this 32-bit KVM arm support has been dropped in the Linux
kernel a couple of years ago already, so we don't really need
qemu-system-arm anymore, thus deprecated it now.

Signed-off-by: Thomas Huth 
---
  docs/about/deprecated.rst | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index a30aa8dfdf..21ce70b5c9 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -45,6 +45,16 @@ run 32-bit guests by selecting a 32-bit CPU model, 
including KVM support

  on x86_64 hosts. Thus users are recommended to reconfigure their systems
  to use the ``qemu-system-x86_64`` binary instead.
+``qemu-system-arm`` binary (since 8.0)
+''
+
+``qemu-system-aarch64`` is a proper superset of ``qemu-system-arm``. The
+latter was mainly a requirement for running KVM on 32-bit arm hosts, but
+this 32-bit KVM support has been removed some years ago already (see:


s/some/few/?


I can also use "three years ago" since the patch had been merged in March 2020.

+https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=541ad0150ca4 


+). Thus the QEMU project will drop the ``qemu-system-arm`` binary in a
+future release. Use ``qemu-system-aarch64`` instead.


If we unify, wouldn't it be simpler to name the single qemu-system
binary emulating various ARM architectures as 'qemu-system-arm'?


That would be more intuitive for people who are completely new to QEMU, but 
I guess it will cause a lot of "you broke my script that uses the -aarch64 
binary" troubles again. So I think it's likely better to not go down that road.


 Thomas




Re: [PATCH 1/6] Add the Android Emulator hypervisor driver (AEHD) accelerator.

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 06:26:12PM -0800, Haitao Shan wrote:
> Add the configure support for the Android Emulator hypervisor driver
> accelerator. The Android Emulator hypervisor driver is a Windows
> driver made by porting the KVM from kernel 4.9-rc7.
> 
> Signed-off-by: Haitao Shan 

Replying on patch 1 but it applies to the whole patchset.

There's obvious duplication with kvm here - probably not surprising.

I'd be interested to hear from KVM people to know whether
there's interest in unifying code, or they would rather
not bother supporting this platform and it's better off
being kept separate.

> ---
>  accel/Kconfig  |  3 +++
>  docs/about/build-platforms.rst |  2 +-
>  include/exec/poison.h  |  1 +
>  meson.build| 16 
>  meson_options.txt  |  2 ++
>  qemu-options.hx| 20 ++--
>  scripts/meson-buildoptions.sh  |  2 ++
>  7 files changed, 35 insertions(+), 11 deletions(-)
> 
> diff --git a/accel/Kconfig b/accel/Kconfig
> index 8bdedb7d15..187d8f6acf 100644
> --- a/accel/Kconfig
> +++ b/accel/Kconfig
> @@ -16,6 +16,9 @@ config TCG
>  config KVM
>  bool
>  
> +config AEHD
> +bool
> +
>  config XEN
>  bool
>  select FSDEV_9P if VIRTFS
> diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst
> index 20b97c3310..184707bd62 100644
> --- a/docs/about/build-platforms.rst
> +++ b/docs/about/build-platforms.rst
> @@ -52,7 +52,7 @@ Those hosts are officially supported, with various 
> accelerators:
> * - SPARC
>   - tcg
> * - x86
> - - hax, hvf (64 bit only), kvm, nvmm, tcg, whpx (64 bit only), xen
> + - aehd (64 bit only), hax, hvf (64 bit only), kvm, nvmm, tcg, whpx (64 
> bit only), xen
>  
>  Other host architectures are not supported. It is possible to build QEMU 
> system
>  emulation on an unsupported host architecture using the configure
> diff --git a/include/exec/poison.h b/include/exec/poison.h
> index 140daa4a85..cb851744d1 100644
> --- a/include/exec/poison.h
> +++ b/include/exec/poison.h
> @@ -86,6 +86,7 @@
>  #pragma GCC poison CONFIG_HVF
>  #pragma GCC poison CONFIG_LINUX_USER
>  #pragma GCC poison CONFIG_KVM
> +#pragma GCC poison CONFIG_AEHD
>  #pragma GCC poison CONFIG_SOFTMMU
>  #pragma GCC poison CONFIG_WHPX
>  #pragma GCC poison CONFIG_XEN
> diff --git a/meson.build b/meson.build
> index 77d2ae87e4..f2b049ceac 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -146,6 +146,11 @@ if cpu in ['x86', 'x86_64']
>  'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
>}
>  endif
> +if cpu in ['x86_64']
> +  accelerator_targets += {
> +'CONFIG_AEHD': ['i386-softmmu', 'x86_64-softmmu'],
> +  }
> +endif
>  
>  modular_tcg = []
>  # Darwin does not support references to thread-local variables in modules
> @@ -421,6 +426,13 @@ accelerators = []
>  if get_option('kvm').allowed() and targetos == 'linux'
>accelerators += 'CONFIG_KVM'
>  endif
> +if get_option('aehd').allowed() and targetos == 'windows'
> +  if get_option('aehd').enabled() and host_machine.cpu() != 'x86_64'
> +error('AEHD requires 64-bit host')
> +  else
> +accelerators += 'CONFIG_AEHD'
> +  endif
> +endif
>  if get_option('whpx').allowed() and targetos == 'windows'
>if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
>  error('WHPX requires 64-bit host')
> @@ -482,6 +494,9 @@ endif
>  if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
>error('KVM not available on this platform')
>  endif
> +if 'CONFIG_AEHD' not in accelerators and get_option('aehd').enabled()
> +  error('AEHD not available on this platform')
> +endif
>  if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
>error('HVF not available on this platform')
>  endif
> @@ -3873,6 +3888,7 @@ endif
>  summary_info = {}
>  if have_system
>summary_info += {'KVM support':   config_all.has_key('CONFIG_KVM')}
> +  summary_info += {'AEHD support':  config_all.has_key('CONFIG_AEHD')}
>summary_info += {'HAX support':   config_all.has_key('CONFIG_HAX')}
>summary_info += {'HVF support':   config_all.has_key('CONFIG_HVF')}
>summary_info += {'WHPX support':  config_all.has_key('CONFIG_WHPX')}
> diff --git a/meson_options.txt b/meson_options.txt
> index fc9447d267..d3e9805b6d 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -66,6 +66,8 @@ option('malloc', type : 'combo', choices : ['system', 
> 'tcmalloc', 'jemalloc'],
>  
>  option('kvm', type: 'feature', value: 'auto',
> description: 'KVM acceleration support')
> +option('aehd', type: 'feature', value: 'auto',
> +   description: 'AEHD acceleration support')
>  option('hax', type: 'feature', value: 'auto',
> description: 'HAX acceleration support')
>  option('whpx', type: 'feature', value: 'auto',
> diff --git a/qemu-options.hx b/qemu-options.hx
> index beeb4475ba..2870c54a43 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> 

Re: Re: [PATCH v6 09/12] cryptodev: Account statistics

2023-03-02 Thread Michael S. Tsirkin
On Fri, Mar 03, 2023 at 03:02:24PM +0800, zhenwei pi wrote:
> 
> 
> On 3/1/23 19:05, Daniel P. Berrangé wrote:
> > On Wed, Mar 01, 2023 at 06:58:44PM +0800, zhenwei pi wrote:
> > > Account OPS/BPS for crypto device, this will be used for 'query-stats'
> > > QEMU monitor command and QoS in the next step.
> > > 
> > > Note that a crypto device may support symmetric mode, asymmetric mode,
> > > both symmetric and asymmetric mode. So we use two structure to
> > > describe the statistics of a crypto device.
> > > 
> > > Signed-off-by: zhenwei pi 
> > > ---
> > >   backends/cryptodev.c   | 68 +++---
> > >   include/sysemu/cryptodev.h | 49 +++
> > >   2 files changed, 112 insertions(+), 5 deletions(-)
> > 
> > Reviewed-by: Daniel P. Berrangé 
> > 
> > 
> > With regards,
> > Daniel
> 
> Hi Daniel,
> Thanks for your patience in the trunk of work!
> 
> Hi Michael,
> All the patches in this series have been reviewed by Daniel, a small
> improvement(use macro to walk a list which is pointed out by Dr. David Alan
> Gilbert) remains and I'd like to do this work in another followup change.

OK I will do a last pull Monday, should be there.

> -- 
> zhenwei pi




Re: Re: [PATCH v6 09/12] cryptodev: Account statistics

2023-03-02 Thread zhenwei pi




On 3/1/23 19:05, Daniel P. Berrangé wrote:

On Wed, Mar 01, 2023 at 06:58:44PM +0800, zhenwei pi wrote:

Account OPS/BPS for crypto device, this will be used for 'query-stats'
QEMU monitor command and QoS in the next step.

Note that a crypto device may support symmetric mode, asymmetric mode,
both symmetric and asymmetric mode. So we use two structure to
describe the statistics of a crypto device.

Signed-off-by: zhenwei pi 
---
  backends/cryptodev.c   | 68 +++---
  include/sysemu/cryptodev.h | 49 +++
  2 files changed, 112 insertions(+), 5 deletions(-)


Reviewed-by: Daniel P. Berrangé 


With regards,
Daniel


Hi Daniel,
Thanks for your patience in the trunk of work!

Hi Michael,
All the patches in this series have been reviewed by Daniel, a small 
improvement(use macro to walk a list which is pointed out by Dr. David 
Alan Gilbert) remains and I'd like to do this work in another followup 
change.


--
zhenwei pi



[PATCH v2 0/6] target/i386: Support new Intel platform Instructions in CPUID enumeration

2023-03-02 Thread Tao Su
Intel platforms Granite Rapids/Sierra Forest introduce below new
instructions and CPUID leaves:

 - CMPccXADD CPUID.(EAX=7,ECX=1):EAX[bit 7]
 - AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21]
 - AVX-IFMA CPUID.(EAX=7,ECX=1):EAX[bit 23]
 - AVX-VNNI-INT8 CPUID.(EAX=7,ECX=1):EDX[bit 4]
 - AVX-NE-CONVERT CPUID.(EAX=7,ECX=1):EDX[bit 5]
 - PREFETCHITI CPUID.(EAX=7,ECX=1):EDX[bit 14]

Details can be found in recent Intel ISE (Instruction Set Extensions)[1].

KVM part of advertising these CPUID bits have been already in Linux
mainline from commit(6a19d7aa5821) to commit(29c46979b25d). This series
adds the counterpart in QEMU to allow these features exposed to guest.

[1] Intel ISE: https://cdrdv2.intel.com/v1/dl/getContent/671368

---

Changelog:

v2:
 - Rebase to latest QEMU.
 - Improve changelog.
v1:
 - 
https://lore.kernel.org/all/20221208071917.1923093-1-jiaxi.c...@linux.intel.com/

Jiaxi Chen (6):
  target/i386: Add support for CMPCCXADD in CPUID enumeration
  target/i386: Add support for AMX-FP16 in CPUID enumeration
  target/i386: Add support for AVX-IFMA in CPUID enumeration
  target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration
  target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration
  target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration

 target/i386/cpu.c | 26 +++---
 target/i386/cpu.h | 14 ++
 2 files changed, 37 insertions(+), 3 deletions(-)


base-commit: 627634031092e1514f363fd8659a579398de0f0e
-- 
2.34.1




[PATCH v2 2/6] target/i386: Add support for AMX-FP16 in CPUID enumeration

2023-03-02 Thread Tao Su
From: Jiaxi Chen 

Latest Intel platform Granite Rapids has introduced a new instruction -
AMX-FP16, which performs dot-products of two FP16 tiles and accumulates
the results into a packed single precision tile. AMX-FP16 adds FP16
capability and allows a FP16 GPU trained model to run faster without
loss of accuracy or added SW overhead.

The bit definition:
CPUID.(EAX=7,ECX=1):EAX[bit 21]

Add CPUID definition for AMX-FP16.

Signed-off-by: Jiaxi Chen 
Signed-off-by: Tao Su 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index e54e13d050..ed08a52619 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, NULL, "fzrm", "fsrs",
 "fsrc", NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, "amx-fp16", NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 },
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 7df8f4b8f9..ae6a0fdfc2 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -912,6 +912,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EAX_FSRS  (1U << 11)
 /* Fast Short REP CMPS/SCAS */
 #define CPUID_7_1_EAX_FSRC  (1U << 12)
+/* Support Tile Computational Operations on FP16 Numbers */
+#define CPUID_7_1_EAX_AMX_FP16  (1U << 21)
 
 /* XFD Extend Feature Disabled */
 #define CPUID_D_1_EAX_XFD   (1U << 4)
-- 
2.34.1




[PATCH v2 5/6] target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration

2023-03-02 Thread Tao Su
From: Jiaxi Chen 

AVX-NE-CONVERT is a new set of instructions which can convert low
precision floating point like BF16/FP16 to high precision floating point
FP32, as well as convert FP32 elements to BF16. This instruction allows
the platform to have improved AI capabilities and better compatibility.

The bit definition:
CPUID.(EAX=7,ECX=1):EDX[bit 5]

Add CPUID definition for AVX-NE-CONVERT.

Signed-off-by: Jiaxi Chen 
Signed-off-by: Tao Su 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 246d10aa49..eee1e5c25f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -892,7 +892,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 .type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL, NULL, NULL, NULL,
-"avx-vnni-int8", NULL, NULL, NULL,
+"avx-vnni-int8", "avx-ne-convert", NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d53b960f23..14876938c1 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -920,6 +920,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 
 /* Support for VPDPB[SU,UU,SS]D[,S] */
 #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4)
+/* AVX NE CONVERT Instructions */
+#define CPUID_7_1_EDX_AVX_NE_CONVERT(1U << 5)
 
 /* XFD Extend Feature Disabled */
 #define CPUID_D_1_EAX_XFD   (1U << 4)
-- 
2.34.1




[PATCH v2 1/6] target/i386: Add support for CMPCCXADD in CPUID enumeration

2023-03-02 Thread Tao Su
From: Jiaxi Chen 

CMPccXADD is a new set of instructions in the latest Intel platform
Sierra Forest. This new instruction set includes a semaphore operation
that can compare and add the operands if condition is met, which can
improve database performance.

The bit definition:
CPUID.(EAX=7,ECX=1):EAX[bit 7]

Add CPUID definition for CMPCCXADD.

Signed-off-by: Jiaxi Chen 
Signed-off-by: Tao Su 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 4bad3d41d3..e54e13d050 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -872,7 +872,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 .type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL, NULL, NULL, NULL,
-"avx-vnni", "avx512-bf16", NULL, NULL,
+"avx-vnni", "avx512-bf16", NULL, "cmpccxadd",
 NULL, NULL, "fzrm", "fsrs",
 "fsrc", NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ea650e68a3..7df8f4b8f9 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -904,6 +904,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EAX_AVX_VNNI  (1U << 4)
 /* AVX512 BFloat16 Instruction */
 #define CPUID_7_1_EAX_AVX512_BF16   (1U << 5)
+/* CMPCCXADD Instructions */
+#define CPUID_7_1_EAX_CMPCCXADD (1U << 7)
 /* Fast Zero REP MOVS */
 #define CPUID_7_1_EAX_FZRM  (1U << 10)
 /* Fast Short REP STOS */
-- 
2.34.1




[PATCH v2 6/6] target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration

2023-03-02 Thread Tao Su
From: Jiaxi Chen 

Latest Intel platform Granite Rapids has introduced a new instruction -
PREFETCHIT0/1, which moves code to memory (cache) closer to the
processor depending on specific hints.

The bit definition:
CPUID.(EAX=7,ECX=1):EDX[bit 14]

Add CPUID definition for PREFETCHIT0/1.

Signed-off-by: Jiaxi Chen 
Signed-off-by: Tao Su 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index eee1e5c25f..719e6a2636 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -894,7 +894,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, NULL, NULL, NULL,
 "avx-vnni-int8", "avx-ne-convert", NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, NULL, "prefetchiti", NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 14876938c1..febb1837d0 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -922,6 +922,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4)
 /* AVX NE CONVERT Instructions */
 #define CPUID_7_1_EDX_AVX_NE_CONVERT(1U << 5)
+/* PREFETCHIT0/1 Instructions */
+#define CPUID_7_1_EDX_PREFETCHITI   (1U << 14)
 
 /* XFD Extend Feature Disabled */
 #define CPUID_D_1_EAX_XFD   (1U << 4)
-- 
2.34.1




[PATCH v2 4/6] target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration

2023-03-02 Thread Tao Su
From: Jiaxi Chen 

AVX-VNNI-INT8 is a new set of instructions in the latest Intel platform
Sierra Forest, aims for the platform to have superior AI capabilities.
This instruction multiplies the individual bytes of two unsigned or
unsigned source operands, then adds and accumulates the results into the
destination dword element size operand.

The bit definition:
CPUID.(EAX=7,ECX=1):EDX[bit 4]

AVX-VNNI-INT8 is on a new feature bits leaf. Add a CPUID feature word
FEAT_7_1_EDX for this leaf.

Add CPUID definition for AVX-VNNI-INT8.

Signed-off-by: Jiaxi Chen 
Signed-off-by: Tao Su 
---
 target/i386/cpu.c | 22 +-
 target/i386/cpu.h |  4 
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 9aaa373e97..246d10aa49 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -664,6 +664,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM
 #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \
   CPUID_7_1_EAX_FSRC)
+#define TCG_7_1_EDX_FEATURES 0
 #define TCG_APM_FEATURES 0
 #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT
 #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
@@ -887,6 +888,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 },
 .tcg_features = TCG_7_1_EAX_FEATURES,
 },
+[FEAT_7_1_EDX] = {
+.type = CPUID_FEATURE_WORD,
+.feat_names = {
+NULL, NULL, NULL, NULL,
+"avx-vnni-int8", NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+},
+.cpuid = {
+.eax = 7,
+.needs_ecx = true, .ecx = 1,
+.reg = R_EDX,
+},
+.tcg_features = TCG_7_1_EDX_FEATURES,
+},
 [FEAT_8000_0007_EDX] = {
 .type = CPUID_FEATURE_WORD,
 .feat_names = {
@@ -5516,9 +5536,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 }
 } else if (count == 1) {
 *eax = env->features[FEAT_7_1_EAX];
+*edx = env->features[FEAT_7_1_EDX];
 *ebx = 0;
 *ecx = 0;
-*edx = 0;
 } else {
 *eax = 0;
 *ebx = 0;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 8e50617efb..d53b960f23 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -623,6 +623,7 @@ typedef enum FeatureWord {
 FEAT_SGX_12_1_EAX,  /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */
 FEAT_XSAVE_XSS_LO, /* CPUID[EAX=0xd,ECX=1].ECX */
 FEAT_XSAVE_XSS_HI, /* CPUID[EAX=0xd,ECX=1].EDX */
+FEAT_7_1_EDX,   /* CPUID[EAX=7,ECX=1].EDX */
 FEATURE_WORDS,
 } FeatureWord;
 
@@ -917,6 +918,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 /* Support for VPMADD52[H,L]UQ */
 #define CPUID_7_1_EAX_AVX_IFMA  (1U << 23)
 
+/* Support for VPDPB[SU,UU,SS]D[,S] */
+#define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4)
+
 /* XFD Extend Feature Disabled */
 #define CPUID_D_1_EAX_XFD   (1U << 4)
 
-- 
2.34.1




[PATCH v2 3/6] target/i386: Add support for AVX-IFMA in CPUID enumeration

2023-03-02 Thread Tao Su
From: Jiaxi Chen 

AVX-IFMA is a new instruction in the latest Intel platform Sierra
Forest. This instruction packed multiplies unsigned 52-bit integers and
adds the low/high 52-bit products to Qword Accumulators.

The bit definition:
CPUID.(EAX=7,ECX=1):EAX[bit 23]

Add CPUID definition for AVX-IFMA.

Signed-off-by: Jiaxi Chen 
Signed-off-by: Tao Su 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ed08a52619..9aaa373e97 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, NULL, "fzrm", "fsrs",
 "fsrc", NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, "amx-fp16", NULL, NULL,
+NULL, "amx-fp16", NULL, "avx-ifma",
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 },
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ae6a0fdfc2..8e50617efb 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -914,6 +914,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
 #define CPUID_7_1_EAX_FSRC  (1U << 12)
 /* Support Tile Computational Operations on FP16 Numbers */
 #define CPUID_7_1_EAX_AMX_FP16  (1U << 21)
+/* Support for VPMADD52[H,L]UQ */
+#define CPUID_7_1_EAX_AVX_IFMA  (1U << 23)
 
 /* XFD Extend Feature Disabled */
 #define CPUID_D_1_EAX_XFD   (1U << 4)
-- 
2.34.1




Re: [PATCH v3 00/18] hw/ide: Untangle ISA/PCI abuses of ide_init_ioport()

2023-03-02 Thread David Woodhouse



On 2 March 2023 22:40:40 GMT, "Philippe Mathieu-Daudé"  
wrote:
>Since v2: rebased
>
>I'm posting this series as it to not block Bernhard's PIIX
>cleanup work. I don't have code change planned, but eventually
>reword / improve commit descriptions.
>
>Tested commit after commit to be sure it is bisectable. Sadly
>this was before Zoltan & Thomas report a problem with commit
>bb98e0f59c ("hw/isa/vt82c686: Remove intermediate IRQ forwarder").

However much I stare at the partial revert which fixes it, I just cannot 
believe that the change could make any difference at all. There's got to be 
something weird going on there.

I was going to ask if the level mode for the PIT made any difference, but this 
is the output IRQ from the PIT to the CPU itself so I don't see how it would.

Would like to see a report with tracing from pic_update_irq, the CPU interrupt 
"handler" and the intermediate IRQ handler. With the intermediate present and 
without it. To compare the two.



Re: [PATCH v5 7/7] hw/audio/via-ac97: Basic implementation of audio playback

2023-03-02 Thread Volker Rümelin

Add basic implementation of the AC'97 sound part used in VIA south
bridge chips. Not all features of the device is emulated, only one
playback channel is supported for now but this is enough to get sound
output from some guests using this device on pegasos2.

Signed-off-by: BALATON Zoltan 
---
v5: rebased on master
v3: Fixed CLEN_LEN mask, add check to avoid runaway DMA and some
tweaks to PCI config regs which now make it work with AmigaOS too.
This is probably as good as it gets for QEMU 8.0

  hw/audio/trace-events |   6 +
  hw/audio/via-ac97.c   | 455 +-
  hw/isa/trace-events   |   1 +
  hw/isa/vt82c686.c |   2 +-
  include/hw/isa/vt82c686.h |  25 +++
  5 files changed, 482 insertions(+), 7 deletions(-)



Reviewed-by: Volker Rümelin 




[PATCH 2/2] hw: intc: Use cpu_by_arch_id to fetch CPU state

2023-03-02 Thread Mayuresh Chitale


Qemu_get_cpu uses the logical CPU id assigned during init to fetch the
CPU state. However APLIC, IMSIC and ACLINT contain registers and states
which are specific to physical hart Ids. The hart Ids in any given system
might be sparse and hence calls to qemu_get_cpu need to be replaced by
cpu_by_arch_id which performs lookup based on the sparse physical hart IDs.

Signed-off-by: Mayuresh Chitale 
Signed-off-by: Anup Patel 
---
 hw/intc/riscv_aclint.c | 16 
 hw/intc/riscv_aplic.c  |  4 ++--
 hw/intc/riscv_imsic.c  |  6 +++---
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index eee04643cb..b466a6abaf 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -130,7 +130,7 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, 
hwaddr addr,
 addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) {
 size_t hartid = mtimer->hartid_base +
 ((addr - mtimer->timecmp_base) >> 3);
-CPUState *cpu = qemu_get_cpu(hartid);
+CPUState *cpu = cpu_by_arch_id(hartid);
 CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
 if (!env) {
 qemu_log_mask(LOG_GUEST_ERROR,
@@ -173,7 +173,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr 
addr,
 addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) {
 size_t hartid = mtimer->hartid_base +
 ((addr - mtimer->timecmp_base) >> 3);
-CPUState *cpu = qemu_get_cpu(hartid);
+CPUState *cpu = cpu_by_arch_id(hartid);
 CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
 if (!env) {
 qemu_log_mask(LOG_GUEST_ERROR,
@@ -231,7 +231,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr 
addr,
 
 /* Check if timer interrupt is triggered for each hart. */
 for (i = 0; i < mtimer->num_harts; i++) {
-CPUState *cpu = qemu_get_cpu(mtimer->hartid_base + i);
+CPUState *cpu = cpu_by_arch_id(mtimer->hartid_base + i);
 CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
 if (!env) {
 continue;
@@ -292,7 +292,7 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, 
Error **errp)
 s->timecmp = g_new0(uint64_t, s->num_harts);
 /* Claim timer interrupt bits */
 for (i = 0; i < s->num_harts; i++) {
-RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
+RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
 if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) {
 error_report("MTIP already claimed");
 exit(1);
@@ -372,7 +372,7 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr 
size,
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
 
 for (i = 0; i < num_harts; i++) {
-CPUState *cpu = qemu_get_cpu(hartid_base + i);
+CPUState *cpu = cpu_by_arch_id(hartid_base + i);
 RISCVCPU *rvcpu = RISCV_CPU(cpu);
 CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
 riscv_aclint_mtimer_callback *cb =
@@ -407,7 +407,7 @@ static uint64_t riscv_aclint_swi_read(void *opaque, hwaddr 
addr,
 
 if (addr < (swi->num_harts << 2)) {
 size_t hartid = swi->hartid_base + (addr >> 2);
-CPUState *cpu = qemu_get_cpu(hartid);
+CPUState *cpu = cpu_by_arch_id(hartid);
 CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
 if (!env) {
 qemu_log_mask(LOG_GUEST_ERROR,
@@ -430,7 +430,7 @@ static void riscv_aclint_swi_write(void *opaque, hwaddr 
addr, uint64_t value,
 
 if (addr < (swi->num_harts << 2)) {
 size_t hartid = swi->hartid_base + (addr >> 2);
-CPUState *cpu = qemu_get_cpu(hartid);
+CPUState *cpu = cpu_by_arch_id(hartid);
 CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
 if (!env) {
 qemu_log_mask(LOG_GUEST_ERROR,
@@ -545,7 +545,7 @@ DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t 
hartid_base,
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
 
 for (i = 0; i < num_harts; i++) {
-CPUState *cpu = qemu_get_cpu(hartid_base + i);
+CPUState *cpu = cpu_by_arch_id(hartid_base + i);
 RISCVCPU *rvcpu = RISCV_CPU(cpu);
 
 qdev_connect_gpio_out(dev, i,
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index cfd007e629..cd7efc4ad4 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -833,7 +833,7 @@ static void riscv_aplic_realize(DeviceState *dev, Error 
**errp)
 
 /* Claim the CPU interrupt to be triggered by this APLIC */
 for (i = 0; i < aplic->num_harts; i++) {
-RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(aplic->hartid_base + i));
+RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(aplic->hartid_base + i));
 if (riscv_cpu_claim_interrupts(cpu,
 (aplic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) {
 error_report("%s already 

[PATCH 0/2] Risc-V CPU state by hart ID

2023-03-02 Thread Mayuresh Chitale
Currently a Risc-V platform cannot realizes multiple CPUs with non contiguous
hart IDs because the APLIC, IMSIC and ACLINT emulation code uses the
contiguous logical CPU ID to fetch per CPU state.

This patchset implements cpu_by_arch_id for Risc-V to get the CPU state
by hart ID which may be sparse instead of the contigous logical CPU id.

Mayuresh Chitale (2):
  target/riscv: cpu: Implement get_arch_id callback
  hw: intc: Use cpu_by_arch_id to fetch CPU state

 hw/intc/riscv_aclint.c | 16 
 hw/intc/riscv_aplic.c  |  4 ++--
 hw/intc/riscv_imsic.c  |  6 +++---
 target/riscv/cpu.c |  8 
 4 files changed, 21 insertions(+), 13 deletions(-)

-- 
2.34.1




[PATCH 1/2] target/riscv: cpu: Implement get_arch_id callback

2023-03-02 Thread Mayuresh Chitale


Implement the callback for getting the architecture-dependent CPU ID ie
mhartid.

Signed-off-by: Mayuresh Chitale 
Signed-off-by: Anup Patel 
---
 target/riscv/cpu.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0dd2f0c753..467d8467a3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1243,6 +1243,13 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState 
*cs, const char *xmlname)
 }
 
 #ifndef CONFIG_USER_ONLY
+static int64_t riscv_get_arch_id(CPUState *cs)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+return cpu->env.mhartid;
+}
+
 #include "hw/core/sysemu-cpu-ops.h"
 
 static const struct SysemuCPUOps riscv_sysemu_ops = {
@@ -1297,6 +1304,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
*data)
 cc->disas_set_info = riscv_cpu_disas_set_info;
 #ifndef CONFIG_USER_ONLY
 cc->sysemu_ops = _sysemu_ops;
+cc->get_arch_id = riscv_get_arch_id;
 #endif
 cc->gdb_arch_name = riscv_gdb_arch_name;
 cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
-- 
2.34.1




Re: [PATCH v4 12/15] vdpa: block migration if device has unsupported features

2023-03-02 Thread Jason Wang



在 2023/3/2 03:32, Eugenio Perez Martin 写道:

On Mon, Feb 27, 2023 at 9:20 AM Jason Wang  wrote:

On Mon, Feb 27, 2023 at 4:15 PM Jason Wang  wrote:


在 2023/2/24 23:54, Eugenio Pérez 写道:

A vdpa net device must initialize with SVQ in order to be migratable at
this moment, and initialization code verifies some conditions.  If the
device is not initialized with the x-svq parameter, it will not expose
_F_LOG so the vhost subsystem will block VM migration from its
initialization.

Next patches change this, so we need to verify migration conditions
differently.

QEMU only supports a subset of net features in SVQ, and it cannot
migrate state that cannot track or restore in the destination.  Add a
migration blocker if the device offer an unsupported feature.

Signed-off-by: Eugenio Pérez 
---
v3: add mirgation blocker properly so vhost_dev can handle it.
---
   net/vhost-vdpa.c | 12 
   1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 4f983df000..094dc1c2d0 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -795,7 +795,8 @@ static NetClientState *net_vhost_vdpa_init(NetClientState 
*peer,
  int nvqs,
  bool is_datapath,
  bool svq,
-   struct vhost_vdpa_iova_range iova_range)
+   struct vhost_vdpa_iova_range iova_range,
+   uint64_t features)
   {
   NetClientState *nc = NULL;
   VhostVDPAState *s;
@@ -818,7 +819,10 @@ static NetClientState *net_vhost_vdpa_init(NetClientState 
*peer,
   s->vhost_vdpa.shadow_vqs_enabled = svq;
   s->vhost_vdpa.iova_range = iova_range;
   s->vhost_vdpa.shadow_data = svq;
-if (!is_datapath) {
+if (queue_pair_index == 0) {
+vhost_vdpa_net_valid_svq_features(features,
+  >vhost_vdpa.migration_blocker);


Since we do validation at initialization, is this necessary to valid
once again in other places?

Ok, after reading patch 13, I think the question is:

The validation seems to be independent to net, can we valid it once
during vhost_vdpa_init()?


vhost_vdpa_net_valid_svq_features also checks for net features. In
particular, all the non transport features must be in
vdpa_svq_device_features.

This is how we protect that the device / guest will never negotiate
things like VLAN filtering support, as SVQ still does not know how to
restore at the destination.

In the VLAN filtering case CVQ is needed to restore VLAN, so it is
covered by patch 11/15. But other future features may need support for
restoring it in the destination.



I wonder how hard to have a general validation code let net specific 
code to advertise a blacklist to avoid code duplication.


Thanks




Thanks!


Thanks


Thanks



+} else if (!is_datapath) {
   s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size(),
   
vhost_vdpa_net_cvq_cmd_page_len());
   memset(s->cvq_cmd_out_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len());
@@ -956,7 +960,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
   for (i = 0; i < queue_pairs; i++) {
   ncs[i] = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
vdpa_device_fd, i, 2, true, opts->x_svq,
- iova_range);
+ iova_range, features);
   if (!ncs[i])
   goto err;
   }
@@ -964,7 +968,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
   if (has_cvq) {
   nc = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name,
vdpa_device_fd, i, 1, false,
- opts->x_svq, iova_range);
+ opts->x_svq, iova_range, features);
   if (!nc)
   goto err;
   }





Re: [PATCH v4 09/15] vdpa: add vdpa net migration state notifier

2023-03-02 Thread Jason Wang



在 2023/3/2 03:26, Eugenio Perez Martin 写道:

On Mon, Feb 27, 2023 at 9:08 AM Jason Wang  wrote:


在 2023/2/24 23:54, Eugenio Pérez 写道:

This allows net to restart the device backend to configure SVQ on it.

Ideally, these changes should not be net specific. However, the vdpa net
backend is the one with enough knowledge to configure everything because
of some reasons:
* Queues might need to be shadowed or not depending on its kind (control
vs data).
* Queues need to share the same map translations (iova tree).

Because of that it is cleaner to restart the whole net backend and
configure again as expected, similar to how vhost-kernel moves between
userspace and passthrough.

If more kinds of devices need dynamic switching to SVQ we can create a
callback struct like VhostOps and move most of the code there.
VhostOps cannot be reused since all vdpa backend share them, and to
personalize just for networking would be too heavy.

Signed-off-by: Eugenio Pérez 
---
v4:
* Delete duplication of set shadow_data and shadow_vqs_enabled moving it
to data / cvq net start functions.

v3:
* Check for migration state at vdpa device start to enable SVQ in data
vqs.

v1 from RFC:
* Add TODO to use the resume operation in the future.
* Use migration_in_setup and migration_has_failed instead of a
complicated switch case.
---
   net/vhost-vdpa.c | 72 ++--
   1 file changed, 69 insertions(+), 3 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index b89c99066a..c5512ddf10 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -26,12 +26,15 @@
   #include 
   #include "standard-headers/linux/virtio_net.h"
   #include "monitor/monitor.h"
+#include "migration/migration.h"
+#include "migration/misc.h"
   #include "hw/virtio/vhost.h"

   /* Todo:need to add the multiqueue support here */
   typedef struct VhostVDPAState {
   NetClientState nc;
   struct vhost_vdpa vhost_vdpa;
+Notifier migration_state;
   VHostNetState *vhost_net;

   /* Control commands shadow buffers */
@@ -239,10 +242,59 @@ static VhostVDPAState 
*vhost_vdpa_net_first_nc_vdpa(VhostVDPAState *s)
   return DO_UPCAST(VhostVDPAState, nc, nc0);
   }

+static void vhost_vdpa_net_log_global_enable(VhostVDPAState *s, bool enable)
+{
+struct vhost_vdpa *v = >vhost_vdpa;
+VirtIONet *n;
+VirtIODevice *vdev;
+int data_queue_pairs, cvq, r;
+
+/* We are only called on the first data vqs and only if x-svq is not set */
+if (s->vhost_vdpa.shadow_vqs_enabled == enable) {
+return;
+}
+
+vdev = v->dev->vdev;
+n = VIRTIO_NET(vdev);
+if (!n->vhost_started) {
+return;
+}
+
+data_queue_pairs = n->multiqueue ? n->max_queue_pairs : 1;
+cvq = virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ) ?
+  n->max_ncs - n->max_queue_pairs : 0;
+/*
+ * TODO: vhost_net_stop does suspend, get_base and reset. We can be smarter
+ * in the future and resume the device if read-only operations between
+ * suspend and reset goes wrong.
+ */
+vhost_net_stop(vdev, n->nic->ncs, data_queue_pairs, cvq);
+
+/* Start will check migration setup_or_active to configure or not SVQ */
+r = vhost_net_start(vdev, n->nic->ncs, data_queue_pairs, cvq);
+if (unlikely(r < 0)) {
+error_report("unable to start vhost net: %s(%d)", g_strerror(-r), -r);
+}
+}
+
+static void vdpa_net_migration_state_notifier(Notifier *notifier, void *data)
+{
+MigrationState *migration = data;
+VhostVDPAState *s = container_of(notifier, VhostVDPAState,
+ migration_state);
+
+if (migration_in_setup(migration)) {
+vhost_vdpa_net_log_global_enable(s, true);
+} else if (migration_has_failed(migration)) {
+vhost_vdpa_net_log_global_enable(s, false);
+}
+}
+
   static void vhost_vdpa_net_data_start_first(VhostVDPAState *s)
   {
   struct vhost_vdpa *v = >vhost_vdpa;

+add_migration_state_change_notifier(>migration_state);
   if (v->shadow_vqs_enabled) {
   v->iova_tree = vhost_iova_tree_new(v->iova_range.first,
  v->iova_range.last);
@@ -256,6 +308,15 @@ static int vhost_vdpa_net_data_start(NetClientState *nc)

   assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

+if (s->always_svq ||
+migration_is_setup_or_active(migrate_get_current()->state)) {
+v->shadow_vqs_enabled = true;
+v->shadow_data = true;
+} else {
+v->shadow_vqs_enabled = false;
+v->shadow_data = false;
+}
+
   if (v->index == 0) {
   vhost_vdpa_net_data_start_first(s);
   return 0;
@@ -276,6 +337,10 @@ static void vhost_vdpa_net_client_stop(NetClientState *nc)

   assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

+if (s->vhost_vdpa.index == 0) {
+remove_migration_state_change_notifier(>migration_state);
+}


Re: [PATCH v4 01/15] vdpa net: move iova tree creation from init to start

2023-03-02 Thread Jason Wang



在 2023/3/1 15:01, Eugenio Perez Martin 写道:

On Mon, Feb 27, 2023 at 8:04 AM Jason Wang  wrote:


在 2023/2/24 23:54, Eugenio Pérez 写道:

Only create iova_tree if and when it is needed.

The cleanup keeps being responsible of last VQ but this change allows it
to merge both cleanup functions.

Signed-off-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
v4:
* Remove leak of iova_tree because double allocation
* Document better the sharing of IOVA tree between data and CVQ
---
   net/vhost-vdpa.c | 113 ++-
   1 file changed, 83 insertions(+), 30 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index de5ed8ff22..b89c99066a 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -178,13 +178,9 @@ err_init:
   static void vhost_vdpa_cleanup(NetClientState *nc)
   {
   VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
-struct vhost_dev *dev = >vhost_net->dev;

   qemu_vfree(s->cvq_cmd_out_buffer);
   qemu_vfree(s->status);
-if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
-g_clear_pointer(>vhost_vdpa.iova_tree, vhost_iova_tree_delete);
-}
   if (s->vhost_net) {
   vhost_net_cleanup(s->vhost_net);
   g_free(s->vhost_net);
@@ -234,10 +230,64 @@ static ssize_t vhost_vdpa_receive(NetClientState *nc, 
const uint8_t *buf,
   return size;
   }

+/** From any vdpa net client, get the netclient of first queue pair */
+static VhostVDPAState *vhost_vdpa_net_first_nc_vdpa(VhostVDPAState *s)
+{
+NICState *nic = qemu_get_nic(s->nc.peer);
+NetClientState *nc0 = qemu_get_peer(nic->ncs, 0);
+
+return DO_UPCAST(VhostVDPAState, nc, nc0);
+}
+
+static void vhost_vdpa_net_data_start_first(VhostVDPAState *s)
+{
+struct vhost_vdpa *v = >vhost_vdpa;
+
+if (v->shadow_vqs_enabled) {
+v->iova_tree = vhost_iova_tree_new(v->iova_range.first,
+   v->iova_range.last);
+}
+}
+
+static int vhost_vdpa_net_data_start(NetClientState *nc)
+{
+VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+struct vhost_vdpa *v = >vhost_vdpa;
+
+assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+
+if (v->index == 0) {
+vhost_vdpa_net_data_start_first(s);
+return 0;
+}
+
+if (v->shadow_vqs_enabled) {
+VhostVDPAState *s0 = vhost_vdpa_net_first_nc_vdpa(s);
+v->iova_tree = s0->vhost_vdpa.iova_tree;
+}
+
+return 0;
+}
+
+static void vhost_vdpa_net_client_stop(NetClientState *nc)
+{
+VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+struct vhost_dev *dev;
+
+assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+
+dev = s->vhost_vdpa.dev;
+if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
+g_clear_pointer(>vhost_vdpa.iova_tree, vhost_iova_tree_delete);
+}
+}
+
   static NetClientInfo net_vhost_vdpa_info = {
   .type = NET_CLIENT_DRIVER_VHOST_VDPA,
   .size = sizeof(VhostVDPAState),
   .receive = vhost_vdpa_receive,
+.start = vhost_vdpa_net_data_start,
+.stop = vhost_vdpa_net_client_stop,


Looking at the implementation, it seems nothing net specific, any reason
we can't simply use vhost_vdpa_dev_start()?


IOVA tree must be shared between (at least) all dataplane vhost_vdpa.
How could we move the call to vhost_vdpa_net_first_nc_vdpa to
vhost_vdpa_dev_start?



Ok, I think I get it. We should really consider to implement a parent 
structure in the future for vhost_vdpa then we can avoid tricks like:


vq_index_end and vhost_vdpa_net_first_nc_vdpa()

Thanks




A possibility is to always allocate it just in case. But it seems to
me it is better to not start allocating resources just in case :).


   .cleanup = vhost_vdpa_cleanup,
   .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
   .has_ufo = vhost_vdpa_has_ufo,
@@ -351,7 +401,7 @@ dma_map_err:

   static int vhost_vdpa_net_cvq_start(NetClientState *nc)
   {
-VhostVDPAState *s;
+VhostVDPAState *s, *s0;
   struct vhost_vdpa *v;
   uint64_t backend_features;
   int64_t cvq_group;
@@ -415,8 +465,6 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
   return r;
   }

-v->iova_tree = vhost_iova_tree_new(v->iova_range.first,
-   v->iova_range.last);
   v->shadow_vqs_enabled = true;
   s->vhost_vdpa.address_space_id = VHOST_VDPA_NET_CVQ_ASID;

@@ -425,6 +473,27 @@ out:
   return 0;
   }

+s0 = vhost_vdpa_net_first_nc_vdpa(s);
+if (s0->vhost_vdpa.iova_tree) {
+/*
+ * SVQ is already configured for all virtqueues.  Reuse IOVA tree for
+ * simplicity, wether CVQ shares ASID with guest or not, because:


Typo, should be "whether", or "regardless of whether"(not a native speaker).


Good catch, I can fix it in the next version.

Thanks!


Other looks good.

Thanks



+ * - Memory listener need access to guest's memory addresses 

[PATCH v4.5 13/29] gdbstub: abstract target specific details from gdb_put_packet_binary

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

We unfortunately handle the checking of packet acknowledgement
differently for user and softmmu modes. Abstract the user mode stuff
behind gdb_got_immediate_ack with a stub for softmmu.

Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-14-alex.ben...@linaro.org>
---
 gdbstub/internals.h | 15 +++
 gdbstub/gdbstub.c   | 10 ++
 gdbstub/softmmu.c   |  8 
 gdbstub/user.c  | 19 +++
 4 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 6bd6a05657..6534e373cb 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -110,6 +110,21 @@ void gdb_memtohex(GString *buf, const uint8_t *mem, int 
len);
 void gdb_memtox(GString *buf, const char *mem, int len);
 void gdb_read_byte(uint8_t ch);
 
+/*
+ * Packet acknowledgement - we handle this slightly differently
+ * between user and softmmu mode, mainly to deal with the differences
+ * between the flexible chardev and the direct fd approaches.
+ *
+ * We currently don't support a negotiated QStartNoAckMode
+ */
+
+/**
+ * gdb_got_immediate_ack() - check ok to continue
+ *
+ * Returns true to continue, false to re-transmit for user only, the
+ * softmmu stub always returns true.
+ */
+bool gdb_got_immediate_ack(void);
 /* utility helpers */
 CPUState *gdb_first_attached_cpu(void);
 void gdb_append_thread_id(CPUState *cpu, GString *buf);
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 6907bdc99c..0476ee7039 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -239,15 +239,9 @@ int gdb_put_packet_binary(const char *buf, int len, bool 
dump)
 gdb_put_buffer(gdbserver_state.last_packet->data,
gdbserver_state.last_packet->len);
 
-#ifdef CONFIG_USER_ONLY
-i = gdb_get_char();
-if (i < 0)
-return -1;
-if (i == '+')
+if (gdb_got_immediate_ack()) {
 break;
-#else
-break;
-#endif
+}
 }
 return 0;
 }
diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index 6796761fd9..04e75449a2 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -55,6 +55,14 @@ int gdb_get_cpu_index(CPUState *cpu)
 return cpu->cpu_index + 1;
 }
 
+/*
+ * We check the status of the last message in the chardev receive code
+ */
+bool gdb_got_immediate_ack(void)
+{
+return true;
+}
+
 /*
  * GDB Connection management. For system emulation we do all of this
  * via our existing Chardev infrastructure which allows us to support
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 23b2e726f6..0c8cd028b1 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -54,6 +54,25 @@ int gdb_get_char(void)
 return ch;
 }
 
+bool gdb_got_immediate_ack(void)
+{
+int i;
+
+i = gdb_get_char();
+if (i < 0) {
+/* no response, continue anyway */
+return true;
+}
+
+if (i == '+') {
+/* received correctly, continue */
+return true;
+}
+
+/* anything else, including '-' then try again */
+return false;
+}
+
 void gdb_put_buffer(const uint8_t *buf, int len)
 {
 int ret;
-- 
2.34.1




[PATCH v4.5 16/29] gdbstub: introduce gdb_get_max_cpus

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

This is needed for handling vcont packets as the way of calculating
max cpus vhanges between user and softmmu mode.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-17-alex.ben...@linaro.org>
---
 gdbstub/internals.h |  1 +
 gdbstub/gdbstub.c   | 11 +--
 gdbstub/softmmu.c   |  9 +
 gdbstub/user.c  | 17 +
 4 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index d8c0292d99..26a6468a69 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -129,6 +129,7 @@ bool gdb_got_immediate_ack(void);
 CPUState *gdb_first_attached_cpu(void);
 void gdb_append_thread_id(CPUState *cpu, GString *buf);
 int gdb_get_cpu_index(CPUState *cpu);
+unsigned int gdb_get_max_cpus(void); /* both */
 
 void gdb_create_default_process(GDBState *s);
 
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index ed38ab0aaa..1b783100c2 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -624,16 +624,7 @@ static int gdb_handle_vcont(const char *p)
 GDBProcess *process;
 CPUState *cpu;
 GDBThreadIdKind kind;
-#ifdef CONFIG_USER_ONLY
-int max_cpus = 1; /* global variable max_cpus exists only in system mode */
-
-CPU_FOREACH(cpu) {
-max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
-}
-#else
-MachineState *ms = MACHINE(qdev_get_machine());
-unsigned int max_cpus = ms->smp.max_cpus;
-#endif
+unsigned int max_cpus = gdb_get_max_cpus();
 /* uninitialised CPUs stay 0 */
 newstates = g_new0(char, max_cpus);
 
diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index ab2d182654..3a5587d387 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -440,6 +440,15 @@ int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
 }
 
+/*
+ * cpu helpers
+ */
+
+unsigned int gdb_get_max_cpus(void)
+{
+MachineState *ms = MACHINE(qdev_get_machine());
+return ms->smp.max_cpus;
+}
 
 /*
  * Softmmu specific command helpers
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 92663d971c..e10988a62b 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -393,6 +393,23 @@ int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
 }
 
+/*
+ * cpu helpers
+ */
+
+unsigned int gdb_get_max_cpus(void)
+{
+CPUState *cpu;
+unsigned int max_cpus = 1;
+
+CPU_FOREACH(cpu) {
+max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
+}
+
+return max_cpus;
+}
+
+
 /*
  * Break/Watch point helpers
  */
-- 
2.34.1




[PATCH v4.5 04/29] gdbstub: clean-up indent on gdb_exit

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

Otherwise checkpatch will throw a hissy fit on the later patches that
split this function up.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20230302190846.2593720-5-alex.ben...@linaro.org>
---
 gdbstub/gdbstub.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index fb9c49e0fd..63b56f0027 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -3021,27 +3021,27 @@ static void gdb_read_byte(uint8_t ch)
 /* Tell the remote gdb that the process has exited.  */
 void gdb_exit(int code)
 {
-  char buf[4];
+char buf[4];
 
-  if (!gdbserver_state.init) {
-  return;
-  }
+if (!gdbserver_state.init) {
+return;
+}
 #ifdef CONFIG_USER_ONLY
-  if (gdbserver_state.socket_path) {
-  unlink(gdbserver_state.socket_path);
-  }
-  if (gdbserver_state.fd < 0) {
-  return;
-  }
+if (gdbserver_state.socket_path) {
+unlink(gdbserver_state.socket_path);
+}
+if (gdbserver_state.fd < 0) {
+return;
+}
 #endif
 
-  trace_gdbstub_op_exiting((uint8_t)code);
+trace_gdbstub_op_exiting((uint8_t)code);
 
-  snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
-  put_packet(buf);
+snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
+put_packet(buf);
 
 #ifndef CONFIG_USER_ONLY
-  qemu_chr_fe_deinit(_state.chr, true);
+qemu_chr_fe_deinit(_state.chr, true);
 #endif
 }
 
-- 
2.34.1




[PATCH v4.5 22/29] gdbstub: only compile gdbstub twice for whole build

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

Now we have removed any target specific bits from the core gdbstub
code we only need to build it twice. We have to jump a few meson hoops
to manually define the CONFIG_USER_ONLY symbol but it seems to work.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-23-alex.ben...@linaro.org>
---
 gdbstub/gdbstub.c   |  4 +---
 gdbstub/meson.build | 30 ++
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index e264ed04e7..d9e9bf9294 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -39,9 +39,7 @@
 
 #include "sysemu/hw_accel.h"
 #include "sysemu/runstate.h"
-#include "exec/exec-all.h"
 #include "exec/replay-core.h"
-#include "exec/tb-flush.h"
 #include "exec/hwaddr.h"
 
 #include "internals.h"
@@ -1612,7 +1610,7 @@ static const GdbCmdParseEntry gdb_gen_query_table[] = {
 .cmd_startswith = 1,
 .schema = "s:l,l0"
 },
-#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX)
 {
 .handler = gdb_handle_query_xfer_auxv,
 .cmd = "Xfer:auxv:read::",
diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index c876222b9c..d679c7ab86 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -4,13 +4,35 @@
 # types such as hwaddr.
 #
 
-specific_ss.add(files('gdbstub.c'))
+# We need to build the core gdb code via a library to be able to tweak
+# cflags so:
+
+gdb_user_ss = ss.source_set()
+gdb_softmmu_ss = ss.source_set()
+
+# We build two versions of gdbstub, one for each mode
+gdb_user_ss.add(files('gdbstub.c', 'user.c'))
+gdb_softmmu_ss.add(files('gdbstub.c', 'softmmu.c'))
+
+gdb_user_ss = gdb_user_ss.apply(config_host, strict: false)
+gdb_softmmu_ss = gdb_softmmu_ss.apply(config_host, strict: false)
+
+libgdb_user = static_library('gdb_user',
+ gdb_user_ss.sources() + genh,
+ name_suffix: 'fa',
+ c_args: '-DCONFIG_USER_ONLY')
+
+libgdb_softmmu = static_library('gdb_softmmu',
+gdb_softmmu_ss.sources() + genh,
+name_suffix: 'fa')
+
+gdb_user = declare_dependency(link_whole: libgdb_user)
+user_ss.add(gdb_user)
+gdb_softmmu = declare_dependency(link_whole: libgdb_softmmu)
+softmmu_ss.add(gdb_softmmu)
 
 # These have to built to the target ABI
 specific_ss.add(files('syscalls.c'))
 
-softmmu_ss.add(files('softmmu.c'))
-user_ss.add(files('user.c'))
-
 # The user-target is specialised by the guest
 specific_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-target.c'))
-- 
2.34.1




[PATCH v4.5 07/29] includes: move tb_flush into its own header

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

This aids subsystems (like gdbstub) that want to trigger a flush
without pulling target specific headers.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-8-alex.ben...@linaro.org>
---
 MAINTAINERS |  1 +
 include/exec/exec-all.h |  1 -
 include/exec/tb-flush.h | 26 ++
 linux-user/user-internals.h |  1 +
 accel/stubs/tcg-stub.c  |  1 +
 accel/tcg/tb-maint.c|  1 +
 accel/tcg/translate-all.c   |  1 +
 cpu.c   |  1 +
 gdbstub/gdbstub.c   |  2 ++
 hw/ppc/spapr_hcall.c|  1 +
 plugins/core.c  |  1 +
 plugins/loader.c|  2 +-
 target/alpha/sys_helper.c   |  1 +
 target/riscv/csr.c  |  1 +
 14 files changed, 39 insertions(+), 2 deletions(-)
 create mode 100644 include/exec/tb-flush.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 76662969d7..234800e3dc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -136,6 +136,7 @@ F: docs/devel/decodetree.rst
 F: docs/devel/tcg*
 F: include/exec/cpu*.h
 F: include/exec/exec-all.h
+F: include/exec/tb-flush.h
 F: include/exec/helper*.h
 F: include/sysemu/cpus.h
 F: include/sysemu/tcg.h
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e09254333d..ad9eb6067b 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -677,7 +677,6 @@ void tb_invalidate_phys_addr(target_ulong addr);
 #else
 void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
 #endif
-void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end);
 void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr);
diff --git a/include/exec/tb-flush.h b/include/exec/tb-flush.h
new file mode 100644
index 00..d92d06565b
--- /dev/null
+++ b/include/exec/tb-flush.h
@@ -0,0 +1,26 @@
+/*
+ * tb-flush prototype for use by the rest of the system.
+ *
+ * Copyright (c) 2022 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef _TB_FLUSH_H_
+#define _TB_FLUSH_H_
+
+/**
+ * tb_flush() - flush all translation blocks
+ * @cs: CPUState (must be valid, but treated as anonymous pointer)
+ *
+ * Used to flush all the translation blocks in the system. Sometimes
+ * it is simpler to flush everything than work out which individual
+ * translations are now invalid and ensure they are not called
+ * anymore.
+ *
+ * tb_flush() takes care of running the flush in an exclusive context
+ * if it is not already running in one. This means no guest code will
+ * run until this complete.
+ */
+void tb_flush(CPUState *cs);
+
+#endif /* _TB_FLUSH_H_ */
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index 3576da413f..9333db4f51 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -20,6 +20,7 @@
 
 #include "exec/user/thunk.h"
 #include "exec/exec-all.h"
+#include "exec/tb-flush.h"
 #include "qemu/log.h"
 
 extern char *exec_path;
diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
index 96af23dc5d..813695b402 100644
--- a/accel/stubs/tcg-stub.c
+++ b/accel/stubs/tcg-stub.c
@@ -11,6 +11,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "exec/tb-flush.h"
 #include "exec/exec-all.h"
 
 void tb_flush(CPUState *cpu)
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
index efefa08ee1..7246c1c46b 100644
--- a/accel/tcg/tb-maint.c
+++ b/accel/tcg/tb-maint.c
@@ -22,6 +22,7 @@
 #include "exec/cputlb.h"
 #include "exec/log.h"
 #include "exec/exec-all.h"
+#include "exec/tb-flush.h"
 #include "exec/translate-all.h"
 #include "sysemu/tcg.h"
 #include "tcg/tcg.h"
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 4b5abc0f44..7096e68406 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -47,6 +47,7 @@
 #include "exec/cputlb.h"
 #include "exec/translate-all.h"
 #include "exec/translator.h"
+#include "exec/tb-flush.h"
 #include "qemu/bitmap.h"
 #include "qemu/qemu-print.h"
 #include "qemu/main-loop.h"
diff --git a/cpu.c b/cpu.c
index 2e9f931249..e6abc6c76c 100644
--- a/cpu.c
+++ b/cpu.c
@@ -36,6 +36,7 @@
 #include "exec/replay-core.h"
 #include "exec/cpu-common.h"
 #include "exec/exec-all.h"
+#include "exec/tb-flush.h"
 #include "exec/translate-all.h"
 #include "exec/log.h"
 #include "hw/core/accel-cpu.h"
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index ef506faa8e..abb1777e73 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -47,6 +47,8 @@
 #include "semihosting/semihost.h"
 #include "exec/exec-all.h"
 #include "exec/replay-core.h"
+#include "exec/tb-flush.h"
+#include "exec/hwaddr.h"
 
 #include "internals.h"
 
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 925ff523cc..ec4def62f8 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -8,6 +8,7 @@
 #include "qemu/module.h"
 #include "qemu/error-report.h"
 #include "exec/exec-all.h"

[PATCH v4.5 03/29] gdbstub: Make syscall_complete/[gs]et_reg target-agnostic typedefs

2023-03-02 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

Prototypes using gdb_syscall_complete_cb() or gdb_?et_reg_cb()
don't depend on "cpu.h", thus are not target-specific.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20221214143659.62133-1-phi...@linaro.org>
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-4-alex.ben...@linaro.org>
---
 include/exec/gdbstub.h | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index f667014888..1636fb3841 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -71,9 +71,6 @@ struct gdb_timeval {
   uint64_t tv_usec;   /* microsecond */
 } QEMU_PACKED;
 
-#ifdef NEED_CPU_H
-#include "cpu.h"
-
 typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, uint64_t ret, int err);
 
 /**
@@ -126,6 +123,7 @@ int gdb_handlesig(CPUState *, int);
 void gdb_signalled(CPUArchState *, int);
 void gdbserver_fork(CPUState *);
 #endif
+
 /* Get or set a register.  Returns the size of the register.  */
 typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
 typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
@@ -133,6 +131,9 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   int num_regs, const char *xml, int g_pos);
 
+#ifdef NEED_CPU_H
+#include "cpu.h"
+
 /*
  * The GDB remote protocol transfers values in target byte order. As
  * the gdbstub may be batching up several register values we always
-- 
2.34.1




[PATCH v4.5 17/29] gdbstub: specialise stub_can_reverse

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

Currently we only support replay for softmmu mode so it is a constant
false for user-mode.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-18-alex.ben...@linaro.org>
---
 gdbstub/internals.h |  1 +
 gdbstub/gdbstub.c   | 13 ++---
 gdbstub/softmmu.c   |  5 +
 gdbstub/user.c  |  5 +
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 26a6468a69..be0eef4850 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -130,6 +130,7 @@ CPUState *gdb_first_attached_cpu(void);
 void gdb_append_thread_id(CPUState *cpu, GString *buf);
 int gdb_get_cpu_index(CPUState *cpu);
 unsigned int gdb_get_max_cpus(void); /* both */
+bool gdb_can_reverse(void); /* softmmu, stub for user */
 
 void gdb_create_default_process(GDBState *s);
 
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 1b783100c2..7301466ff5 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -113,15 +113,6 @@ int use_gdb_syscalls(void)
 return gdb_syscall_mode == GDB_SYS_ENABLED;
 }
 
-static bool stub_can_reverse(void)
-{
-#ifdef CONFIG_USER_ONLY
-return false;
-#else
-return replay_mode == REPLAY_MODE_PLAY;
-#endif
-}
-
 /* writes 2*len+1 bytes in buf */
 void gdb_memtohex(GString *buf, const uint8_t *mem, int len)
 {
@@ -1308,7 +1299,7 @@ static void handle_step(GArray *params, void *user_ctx)
 
 static void handle_backward(GArray *params, void *user_ctx)
 {
-if (!stub_can_reverse()) {
+if (!gdb_can_reverse()) {
 gdb_put_packet("E22");
 }
 if (params->len == 1) {
@@ -1559,7 +1550,7 @@ static void handle_query_supported(GArray *params, void 
*user_ctx)
 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
 }
 
-if (stub_can_reverse()) {
+if (gdb_can_reverse()) {
 g_string_append(gdbserver_state.str_buf,
 ";ReverseStep+;ReverseContinue+");
 }
diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index 3a5587d387..d2863d0663 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -450,6 +450,11 @@ unsigned int gdb_get_max_cpus(void)
 return ms->smp.max_cpus;
 }
 
+bool gdb_can_reverse(void)
+{
+return replay_mode == REPLAY_MODE_PLAY;
+}
+
 /*
  * Softmmu specific command helpers
  */
diff --git a/gdbstub/user.c b/gdbstub/user.c
index e10988a62b..3f6183e66a 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -409,6 +409,11 @@ unsigned int gdb_get_max_cpus(void)
 return max_cpus;
 }
 
+/* replay not supported for user-mode */
+bool gdb_can_reverse(void)
+{
+return false;
+}
 
 /*
  * Break/Watch point helpers
-- 
2.34.1




[PATCH v4.5 21/29] gdbstub: move syscall handling to new file

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

Our GDB syscall support is the last chunk of code that needs target
specific support so move it to a new file. We take the opportunity to
move the syscall state into its own singleton instance and add in a
few helpers for the main gdbstub to interact with the module.

I also moved the gdb_exit() declaration into syscalls.h as it feels
pretty related and most of the callers of it treat it as such.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-22-alex.ben...@linaro.org>
---
 gdbstub/internals.h|   8 +-
 include/exec/gdbstub.h | 102 -
 include/gdbstub/syscalls.h | 124 +++
 gdbstub/gdbstub.c  | 177 +-
 gdbstub/softmmu.c  |   7 +-
 gdbstub/syscalls.c | 234 +
 gdbstub/user.c |   1 +
 linux-user/exit.c  |   2 +-
 semihosting/arm-compat-semi.c  |   1 +
 semihosting/guestfd.c  |   2 +-
 semihosting/syscalls.c |   2 +-
 softmmu/runstate.c |   2 +-
 target/m68k/m68k-semi.c|   2 +-
 target/mips/tcg/sysemu/mips-semi.c |   2 +-
 target/nios2/nios2-semi.c  |   2 +-
 gdbstub/meson.build|   4 +
 16 files changed, 384 insertions(+), 288 deletions(-)
 create mode 100644 include/gdbstub/syscalls.h
 create mode 100644 gdbstub/syscalls.c

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index be0eef4850..8db61f7fb4 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -61,8 +61,6 @@ typedef struct GDBState {
 bool multiprocess;
 GDBProcess *processes;
 int process_num;
-char syscall_buf[256];
-gdb_syscall_complete_cb current_syscall_cb;
 GString *str_buf;
 GByteArray *mem_buf;
 int sstep_flags;
@@ -191,6 +189,12 @@ void gdb_handle_query_attached(GArray *params, void 
*user_ctx); /* both */
 void gdb_handle_query_qemu_phy_mem_mode(GArray *params, void *user_ctx);
 void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx);
 
+/* sycall handling */
+void gdb_handle_file_io(GArray *params, void *user_ctx);
+bool gdb_handled_syscall(void);
+void gdb_disable_syscalls(void);
+void gdb_syscall_reset(void);
+
 /*
  * Break/Watch point support - there is an implementation for softmmu
  * and user mode.
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index bb8a3928dd..7d743fe1e9 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -10,98 +10,6 @@
 #define GDB_WATCHPOINT_READ  3
 #define GDB_WATCHPOINT_ACCESS4
 
-/* For gdb file i/o remote protocol open flags. */
-#define GDB_O_RDONLY  0
-#define GDB_O_WRONLY  1
-#define GDB_O_RDWR2
-#define GDB_O_APPEND  8
-#define GDB_O_CREAT   0x200
-#define GDB_O_TRUNC   0x400
-#define GDB_O_EXCL0x800
-
-/* For gdb file i/o remote protocol errno values */
-#define GDB_EPERM   1
-#define GDB_ENOENT  2
-#define GDB_EINTR   4
-#define GDB_EBADF   9
-#define GDB_EACCES 13
-#define GDB_EFAULT 14
-#define GDB_EBUSY  16
-#define GDB_EEXIST 17
-#define GDB_ENODEV 19
-#define GDB_ENOTDIR20
-#define GDB_EISDIR 21
-#define GDB_EINVAL 22
-#define GDB_ENFILE 23
-#define GDB_EMFILE 24
-#define GDB_EFBIG  27
-#define GDB_ENOSPC 28
-#define GDB_ESPIPE 29
-#define GDB_EROFS  30
-#define GDB_ENAMETOOLONG   91
-#define GDB_EUNKNOWN   
-
-/* For gdb file i/o remote protocol lseek whence. */
-#define GDB_SEEK_SET  0
-#define GDB_SEEK_CUR  1
-#define GDB_SEEK_END  2
-
-/* For gdb file i/o stat/fstat. */
-typedef uint32_t gdb_mode_t;
-typedef uint32_t gdb_time_t;
-
-struct gdb_stat {
-  uint32_tgdb_st_dev; /* device */
-  uint32_tgdb_st_ino; /* inode */
-  gdb_mode_t  gdb_st_mode;/* protection */
-  uint32_tgdb_st_nlink;   /* number of hard links */
-  uint32_tgdb_st_uid; /* user ID of owner */
-  uint32_tgdb_st_gid; /* group ID of owner */
-  uint32_tgdb_st_rdev;/* device type (if inode device) */
-  uint64_tgdb_st_size;/* total size, in bytes */
-  uint64_tgdb_st_blksize; /* blocksize for filesystem I/O */
-  uint64_tgdb_st_blocks;  /* number of blocks allocated */
-  gdb_time_t  gdb_st_atime;   /* time of last access */
-  gdb_time_t  gdb_st_mtime;   /* time of last modification */
-  gdb_time_t  gdb_st_ctime;   /* time of last change */
-} QEMU_PACKED;
-
-struct gdb_timeval {
-  gdb_time_t tv_sec;  /* second */
-  uint64_t tv_usec;   /* microsecond */
-} QEMU_PACKED;
-
-typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, uint64_t ret, int err);
-
-/**
- * gdb_do_syscall:
- * @cb: function to call when the system call has completed
- * @fmt: gdb syscall format string
- * ...: list of arguments to interpolate into @fmt
- *
- * Send a GDB syscall request. This function 

[PATCH v4.5 24/29] include: split target_long definition from cpu-defs

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

While we will continue to include this via cpu-defs it is useful to be
able to define this separately for 32 and 64 bit versions of an
otherwise target independent compilation unit.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-25-alex.ben...@linaro.org>
---
 MAINTAINERS|  1 +
 include/exec/cpu-defs.h| 19 +
 include/exec/target_long.h | 42 ++
 3 files changed, 44 insertions(+), 18 deletions(-)
 create mode 100644 include/exec/target_long.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d0113b8f9..3ef68cd0cf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -137,6 +137,7 @@ F: docs/devel/tcg*
 F: include/exec/cpu*.h
 F: include/exec/exec-all.h
 F: include/exec/tb-flush.h
+F: include/exec/target_long.h
 F: include/exec/helper*.h
 F: include/sysemu/cpus.h
 F: include/sysemu/tcg.h
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index be920d4208..cd8aa177cc 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -55,24 +55,7 @@
 # endif
 #endif
 
-#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
-
-/* target_ulong is the type of a virtual address */
-#if TARGET_LONG_SIZE == 4
-typedef int32_t target_long;
-typedef uint32_t target_ulong;
-#define TARGET_FMT_lx "%08x"
-#define TARGET_FMT_ld "%d"
-#define TARGET_FMT_lu "%u"
-#elif TARGET_LONG_SIZE == 8
-typedef int64_t target_long;
-typedef uint64_t target_ulong;
-#define TARGET_FMT_lx "%016" PRIx64
-#define TARGET_FMT_ld "%" PRId64
-#define TARGET_FMT_lu "%" PRIu64
-#else
-#error TARGET_LONG_SIZE undefined
-#endif
+#include "exec/target_long.h"
 
 #if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
 
diff --git a/include/exec/target_long.h b/include/exec/target_long.h
new file mode 100644
index 00..93c9472971
--- /dev/null
+++ b/include/exec/target_long.h
@@ -0,0 +1,42 @@
+/*
+ * Target Long Definitions
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2023 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _TARGET_LONG_H_
+#define _TARGET_LONG_H_
+
+/*
+ * Usually this should only be included via cpu-defs.h however for
+ * certain cases where we want to build only two versions of a binary
+ * object we can include directly. However the build-system must
+ * ensure TARGET_LONG_BITS is defined directly.
+ */
+#ifndef TARGET_LONG_BITS
+#error TARGET_LONG_BITS not defined
+#endif
+
+#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
+
+/* target_ulong is the type of a virtual address */
+#if TARGET_LONG_SIZE == 4
+typedef int32_t target_long;
+typedef uint32_t target_ulong;
+#define TARGET_FMT_lx "%08x"
+#define TARGET_FMT_ld "%d"
+#define TARGET_FMT_lu "%u"
+#elif TARGET_LONG_SIZE == 8
+typedef int64_t target_long;
+typedef uint64_t target_ulong;
+#define TARGET_FMT_lx "%016" PRIx64
+#define TARGET_FMT_ld "%" PRId64
+#define TARGET_FMT_lu "%" PRIu64
+#else
+#error TARGET_LONG_SIZE undefined
+#endif
+
+#endif /* _TARGET_LONG_H_ */
-- 
2.34.1




[PATCH v4.5 11/29] gdbstub: move chunks of user code into own files

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

The process was pretty similar to the softmmu move except we take the
time to split stuff between user.c and user-target.c to avoid as much
target specific compilation as possible. We also start to make use of
our shiny new header scheme so the user-only helpers can be included
without the rest of the exec/gsbstub.h cruft.

As before we split some functions into user and softmmu versions

Reviewed-by: Fabiano Rosas 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-12-alex.ben...@linaro.org>
---
 MAINTAINERS|   1 +
 gdbstub/internals.h|  18 ++
 include/exec/gdbstub.h |  21 --
 include/gdbstub/user.h |  43 +++
 gdbstub/gdbstub.c  | 678 +
 gdbstub/softmmu.c  |  90 ++
 gdbstub/user-target.c  | 283 +
 gdbstub/user.c | 344 +
 linux-user/main.c  |   1 +
 linux-user/signal.c|   2 +-
 gdbstub/meson.build|   3 +
 11 files changed, 788 insertions(+), 696 deletions(-)
 create mode 100644 include/gdbstub/user.h
 create mode 100644 gdbstub/user-target.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 234800e3dc..c7a8e2307f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2735,6 +2735,7 @@ S: Maintained
 F: docs/system/gdb.rst
 F: gdbstub/*
 F: include/exec/gdbstub.h
+F: include/gdbstub/*
 F: gdb-xml/
 F: tests/tcg/multiarch/gdbstub/
 F: scripts/feature_to_c.sh
diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 83989af859..6bd6a05657 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -117,6 +117,22 @@ int gdb_get_cpu_index(CPUState *cpu);
 
 void gdb_create_default_process(GDBState *s);
 
+/* signal mapping, common for softmmu, specialised for user-mode */
+int gdb_signal_to_target(int sig);
+int gdb_target_signal_to_gdb(int sig);
+
+int gdb_get_char(void); /* user only */
+
+/**
+ * gdb_continue() - handle continue in mode specific way.
+ */
+void gdb_continue(void);
+
+/**
+ * gdb_continue_partial() - handle partial continue in mode specific way.
+ */
+int gdb_continue_partial(char *newstates);
+
 /*
  * Helpers with separate softmmu and user implementations
  */
@@ -149,6 +165,8 @@ typedef union GdbCmdVariant {
 #define get_param(p, i)(_array_index(p, GdbCmdVariant, i))
 
 void gdb_handle_query_rcmd(GArray *params, void *user_ctx); /* softmmu */
+void gdb_handle_query_offsets(GArray *params, void *user_ctx); /* user */
+void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx); /*user */
 
 /*
  * Break/Watch point support - there is an implementation for softmmu
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 1636fb3841..8fff5450ed 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -103,27 +103,6 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char 
*fmt, ...);
 void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va);
 int use_gdb_syscalls(void);
 
-#ifdef CONFIG_USER_ONLY
-/**
- * gdb_handlesig: yield control to gdb
- * @cpu: CPU
- * @sig: if non-zero, the signal number which caused us to stop
- *
- * This function yields control to gdb, when a user-mode-only target
- * needs to stop execution. If @sig is non-zero, then we will send a
- * stop packet to tell gdb that we have stopped because of this signal.
- *
- * This function will block (handling protocol requests from gdb)
- * until gdb tells us to continue target execution. When it does
- * return, the return value is a signal to deliver to the target,
- * or 0 if no signal should be delivered, ie the signal that caused
- * us to stop should be ignored.
- */
-int gdb_handlesig(CPUState *, int);
-void gdb_signalled(CPUArchState *, int);
-void gdbserver_fork(CPUState *);
-#endif
-
 /* Get or set a register.  Returns the size of the register.  */
 typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
 typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
diff --git a/include/gdbstub/user.h b/include/gdbstub/user.h
new file mode 100644
index 00..d392e510c5
--- /dev/null
+++ b/include/gdbstub/user.h
@@ -0,0 +1,43 @@
+/*
+ * gdbstub user-mode only APIs
+ *
+ * Copyright (c) 2022 Linaro Ltd
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ */
+
+#ifndef GDBSTUB_USER_H
+#define GDBSTUB_USER_H
+
+/**
+ * gdb_handlesig() - yield control to gdb
+ * @cpu: CPU
+ * @sig: if non-zero, the signal number which caused us to stop
+ *
+ * This function yields control to gdb, when a user-mode-only target
+ * needs to stop execution. If @sig is non-zero, then we will send a
+ * stop packet to tell gdb that we have stopped because of this signal.
+ *
+ * This function will block (handling protocol requests from gdb)
+ * until gdb tells us to continue target execution. When it does
+ * return, the return value is a signal to deliver to the target,
+ * or 0 if no signal should be delivered, ie the signal that caused
+ * us to stop should be ignored.
+ */
+int gdb_handlesig(CPUState *, int);
+

[PATCH v4.5 19/29] gdbstub: don't use target_ulong while handling registers

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

This is a hangover from the original code. addr is misleading as it is
only really a register id. While len will never exceed
MAX_PACKET_LENGTH I've used size_t as that is what strlen returns.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-20-alex.ben...@linaro.org>
---
 gdbstub/gdbstub.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index b8aead03bd..f1504af44f 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -1193,7 +1193,8 @@ static void handle_read_mem(GArray *params, void 
*user_ctx)
 
 static void handle_write_all_regs(GArray *params, void *user_ctx)
 {
-target_ulong addr, len;
+int reg_id;
+size_t len;
 uint8_t *registers;
 int reg_size;
 
@@ -1205,9 +1206,10 @@ static void handle_write_all_regs(GArray *params, void 
*user_ctx)
 len = strlen(get_param(params, 0)->data) / 2;
 gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
 registers = gdbserver_state.mem_buf->data;
-for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
- addr++) {
-reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
+for (reg_id = 0;
+ reg_id < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
+ reg_id++) {
+reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, 
reg_id);
 len -= reg_size;
 registers += reg_size;
 }
@@ -1216,15 +1218,16 @@ static void handle_write_all_regs(GArray *params, void 
*user_ctx)
 
 static void handle_read_all_regs(GArray *params, void *user_ctx)
 {
-target_ulong addr, len;
+int reg_id;
+size_t len;
 
 cpu_synchronize_state(gdbserver_state.g_cpu);
 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
 len = 0;
-for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
+for (reg_id = 0; reg_id < gdbserver_state.g_cpu->gdb_num_g_regs; reg_id++) 
{
 len += gdb_read_register(gdbserver_state.g_cpu,
  gdbserver_state.mem_buf,
- addr);
+ reg_id);
 }
 g_assert(len == gdbserver_state.mem_buf->len);
 
-- 
2.34.1




[PATCH v4.5 29/29] gdbstub: move update guest debug to accel ops

2023-03-02 Thread Richard Henderson
From: Mads Ynddal 

Continuing the refactor of a48e7d9e52 (gdbstub: move guest debug support
check to ops) by removing hardcoded kvm_enabled() from generic cpu.c
code, and replace it with a property of AccelOpsClass.

Signed-off-by: Mads Ynddal 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20230207131721.49233-1-m...@ynddal.dk>
[AJB: add ifdef around update_guest_debug_ops, fix brace]
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-27-alex.ben...@linaro.org>
---
 include/sysemu/accel-ops.h |  1 +
 accel/kvm/kvm-accel-ops.c  |  8 
 cpu.c  | 11 ---
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/include/sysemu/accel-ops.h b/include/sysemu/accel-ops.h
index 30690c71bd..3c1fab4b1e 100644
--- a/include/sysemu/accel-ops.h
+++ b/include/sysemu/accel-ops.h
@@ -48,6 +48,7 @@ struct AccelOpsClass {
 
 /* gdbstub hooks */
 bool (*supports_guest_debug)(void);
+int (*update_guest_debug)(CPUState *cpu);
 int (*insert_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
 int (*remove_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
 void (*remove_all_breakpoints)(CPUState *cpu);
diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c
index fbf4fe3497..457eafa380 100644
--- a/accel/kvm/kvm-accel-ops.c
+++ b/accel/kvm/kvm-accel-ops.c
@@ -86,6 +86,13 @@ static bool kvm_cpus_are_resettable(void)
 return !kvm_enabled() || kvm_cpu_check_are_resettable();
 }
 
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+static int kvm_update_guest_debug_ops(CPUState *cpu)
+{
+return kvm_update_guest_debug(cpu, 0);
+}
+#endif
+
 static void kvm_accel_ops_class_init(ObjectClass *oc, void *data)
 {
 AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
@@ -99,6 +106,7 @@ static void kvm_accel_ops_class_init(ObjectClass *oc, void 
*data)
 ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm;
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
+ops->update_guest_debug = kvm_update_guest_debug_ops;
 ops->supports_guest_debug = kvm_supports_guest_debug;
 ops->insert_breakpoint = kvm_insert_breakpoint;
 ops->remove_breakpoint = kvm_remove_breakpoint;
diff --git a/cpu.c b/cpu.c
index e6abc6c76c..567b23af46 100644
--- a/cpu.c
+++ b/cpu.c
@@ -31,8 +31,8 @@
 #include "hw/core/sysemu-cpu-ops.h"
 #include "exec/address-spaces.h"
 #endif
+#include "sysemu/cpus.h"
 #include "sysemu/tcg.h"
-#include "sysemu/kvm.h"
 #include "exec/replay-core.h"
 #include "exec/cpu-common.h"
 #include "exec/exec-all.h"
@@ -326,9 +326,14 @@ void cpu_single_step(CPUState *cpu, int enabled)
 {
 if (cpu->singlestep_enabled != enabled) {
 cpu->singlestep_enabled = enabled;
-if (kvm_enabled()) {
-kvm_update_guest_debug(cpu, 0);
+
+#if !defined(CONFIG_USER_ONLY)
+const AccelOpsClass *ops = cpus_get_accel();
+if (ops->update_guest_debug) {
+ops->update_guest_debug(cpu);
 }
+#endif
+
 trace_breakpoint_singlestep(cpu->cpu_index, enabled);
 }
 }
-- 
2.34.1




[PATCH v4.5 27/29] gdbstub: Adjust gdb_do_syscall to only use uint32_t and uint64_t

2023-03-02 Thread Richard Henderson
Pass %x as uint32_t and %lx as uint64_t; pass the address
of %s as uint64_t and the length as uint32_t.

Add casts in semihosting/syscalls.c from target_ulong to
uint64_t; add casts from int to uint32_t for clarity.

Signed-off-by: Richard Henderson 
---
 gdbstub/syscalls.c | 12 ++--
 semihosting/syscalls.c | 34 --
 2 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/gdbstub/syscalls.c b/gdbstub/syscalls.c
index af42e244f9..b7d85c41c7 100644
--- a/gdbstub/syscalls.c
+++ b/gdbstub/syscalls.c
@@ -109,14 +109,14 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const 
char *fmt, ...)
 *(p++) = 'F';
 while (*fmt) {
 if (*fmt == '%') {
-target_ulong addr;
 uint64_t i64;
+uint32_t i32;
 
 fmt++;
 switch (*fmt++) {
 case 'x':
-addr = va_arg(va, target_ulong);
-p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
+i32 = va_arg(va, uint32_t);
+p += snprintf(p, p_end - p, "%" PRIx32, i32);
 break;
 case 'l':
 if (*(fmt++) != 'x') {
@@ -126,9 +126,9 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char 
*fmt, ...)
 p += snprintf(p, p_end - p, "%" PRIx64, i64);
 break;
 case 's':
-addr = va_arg(va, target_ulong);
-p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
-  addr, va_arg(va, int));
+i64 = va_arg(va, uint64_t);
+i32 = va_arg(va, uint32_t);
+p += snprintf(p, p_end - p, "%" PRIx64 "/%x" PRIx32, i64, i32);
 break;
 default:
 bad_format:
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 42080ffdda..68899ebb1c 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -139,46 +139,48 @@ static void gdb_open(CPUState *cs, 
gdb_syscall_complete_cb complete,
 
 gdb_open_complete = complete;
 gdb_do_syscall(gdb_open_cb, "open,%s,%x,%x",
-   fname, len, (target_ulong)gdb_flags, (target_ulong)mode);
+   (uint64_t)fname, (uint32_t)len,
+   (uint32_t)gdb_flags, (uint32_t)mode);
 }
 
 static void gdb_close(CPUState *cs, gdb_syscall_complete_cb complete,
   GuestFD *gf)
 {
-gdb_do_syscall(complete, "close,%x", (target_ulong)gf->hostfd);
+gdb_do_syscall(complete, "close,%x", (uint32_t)gf->hostfd);
 }
 
 static void gdb_read(CPUState *cs, gdb_syscall_complete_cb complete,
  GuestFD *gf, target_ulong buf, target_ulong len)
 {
-gdb_do_syscall(complete, "read,%x,%x,%x",
-   (target_ulong)gf->hostfd, buf, len);
+gdb_do_syscall(complete, "read,%x,%lx,%lx",
+   (uint32_t)gf->hostfd, (uint64_t)buf, (uint64_t)len);
 }
 
 static void gdb_write(CPUState *cs, gdb_syscall_complete_cb complete,
   GuestFD *gf, target_ulong buf, target_ulong len)
 {
-gdb_do_syscall(complete, "write,%x,%x,%x",
-   (target_ulong)gf->hostfd, buf, len);
+gdb_do_syscall(complete, "write,%x,%lx,%lx",
+   (uint32_t)gf->hostfd, (uint64_t)buf, (uint64_t)len);
 }
 
 static void gdb_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
   GuestFD *gf, int64_t off, int gdb_whence)
 {
 gdb_do_syscall(complete, "lseek,%x,%lx,%x",
-   (target_ulong)gf->hostfd, off, (target_ulong)gdb_whence);
+   (uint32_t)gf->hostfd, off, (uint32_t)gdb_whence);
 }
 
 static void gdb_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
GuestFD *gf)
 {
-gdb_do_syscall(complete, "isatty,%x", (target_ulong)gf->hostfd);
+gdb_do_syscall(complete, "isatty,%x", (uint32_t)gf->hostfd);
 }
 
 static void gdb_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
   GuestFD *gf, target_ulong addr)
 {
-gdb_do_syscall(complete, "fstat,%x,%x", (target_ulong)gf->hostfd, addr);
+gdb_do_syscall(complete, "fstat,%x,%lx",
+   (uint32_t)gf->hostfd, (uint64_t)addr);
 }
 
 static void gdb_stat(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -191,7 +193,8 @@ static void gdb_stat(CPUState *cs, gdb_syscall_complete_cb 
complete,
 return;
 }
 
-gdb_do_syscall(complete, "stat,%s,%x", fname, len, addr);
+gdb_do_syscall(complete, "stat,%s,%lx",
+   (uint64_t)fname, (uint32_t)len, (uint64_t)addr);
 }
 
 static void gdb_remove(CPUState *cs, gdb_syscall_complete_cb complete,
@@ -203,7 +206,7 @@ static void gdb_remove(CPUState *cs, 
gdb_syscall_complete_cb complete,
 return;
 }
 
-gdb_do_syscall(complete, "unlink,%s", fname, len);
+gdb_do_syscall(complete, "unlink,%s", (uint64_t)fname, (uint32_t)len);
 }
 
 static void gdb_rename(CPUState *cs, gdb_syscall_complete_cb 

[PATCH v4.5 23/29] testing: probe gdb for supported architectures ahead of time

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

Currently when we encounter a gdb that is old or not built with
multiarch in mind we fail rather messily. Try and improve the
situation by probing ahead of time and setting
HOST_GDB_SUPPORTS_ARCH=y in the relevant tcg configs. We can then skip
and give a more meaningful message if we don't run the test.

Cc: Paolo Bonzini 
Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20230302190846.2593720-24-alex.ben...@linaro.org>
---
 MAINTAINERS   |  1 +
 configure |  8 ++
 scripts/probe-gdb-support.py  | 88 +++
 tests/tcg/aarch64/Makefile.target |  2 +-
 tests/tcg/multiarch/Makefile.target   |  5 ++
 .../multiarch/system/Makefile.softmmu-target  |  6 +-
 tests/tcg/s390x/Makefile.target   |  2 +-
 7 files changed, 109 insertions(+), 3 deletions(-)
 create mode 100755 scripts/probe-gdb-support.py

diff --git a/MAINTAINERS b/MAINTAINERS
index c7a8e2307f..8d0113b8f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2739,6 +2739,7 @@ F: include/gdbstub/*
 F: gdb-xml/
 F: tests/tcg/multiarch/gdbstub/
 F: scripts/feature_to_c.sh
+F: scripts/probe-gdb-support.py
 
 Memory API
 M: Paolo Bonzini 
diff --git a/configure b/configure
index 50a0b80b27..f0cd3923f3 100755
--- a/configure
+++ b/configure
@@ -230,6 +230,7 @@ stack_protector=""
 safe_stack=""
 use_containers="yes"
 gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
+gdb_arches=""
 
 if test -e "$source_path/.git"
 then
@@ -2392,6 +2393,7 @@ if test -n "$gdb_bin"; then
 gdb_version=$($gdb_bin --version | head -n 1)
 if version_ge ${gdb_version##* } 9.1; then
 echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
+gdb_arches=$("$source_path/scripts/probe-gdb-support.py" $gdb_bin)
 else
 gdb_bin=""
 fi
@@ -2516,6 +2518,12 @@ for target in $target_list; do
   write_target_makefile "build-tcg-tests-$target" >> "$config_target_mak"
   echo "BUILD_STATIC=$build_static" >> "$config_target_mak"
   echo "QEMU=$PWD/$qemu" >> "$config_target_mak"
+
+  # will GDB work with these binaries?
+  if test "${gdb_arches#*$arch}" != "$gdb_arches"; then
+  echo "HOST_GDB_SUPPORTS_ARCH=y" >> "$config_target_mak"
+  fi
+
   echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> Makefile.prereqs
   tcg_tests_targets="$tcg_tests_targets $target"
   fi
diff --git a/scripts/probe-gdb-support.py b/scripts/probe-gdb-support.py
new file mode 100755
index 00..35219f555c
--- /dev/null
+++ b/scripts/probe-gdb-support.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+# coding: utf-8
+#
+# Probe gdb for supported architectures.
+#
+# This is required to support testing of the gdbstub as its hard to
+# handle errors gracefully during the test. Instead this script when
+# passed a GDB binary will probe its architecture support and return a
+# string of supported arches, stripped of guff.
+#
+# Copyright 2023 Linaro Ltd
+#
+# Author: Alex Bennée 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import argparse
+import re
+from subprocess import check_output, STDOUT
+
+# mappings from gdb arch to QEMU target
+mappings = {
+"alpha" : "alpha",
+"aarch64" : ["aarch64", "aarch64_be"],
+"armv7": "arm",
+"armv8-a" : ["aarch64", "aarch64_be"],
+"avr" : "avr",
+"cris" : "cris",
+# hexagon?
+"hppa1.0" : "hppa",
+"i386" : "i386",
+"i386:x86-64" : "x86_64",
+"Loongarch64" : "loongarch64",
+"m68k" : "m68k",
+"MicroBlaze" : "microblaze",
+"mips:isa64" : ["mips64", "mips64el"],
+"nios2" : "nios2",
+"or1k" : "or1k",
+"powerpc:common" : "ppc",
+"powerpc:common64" : ["ppc64", "ppc64le"],
+"riscv:rv32" : "riscv32",
+"riscv:rv64" : "riscv64",
+"s390:64-bit" : "s390x",
+"sh4" : ["sh4", "sh4eb"],
+"sparc": "sparc",
+"sparc:v8plus": "sparc32plus",
+"sparc:v9a" : "sparc64",
+# no tricore in upstream gdb
+"xtensa" : ["xtensa", "xtensaeb"]
+}
+
+def do_probe(gdb):
+gdb_out = check_output([gdb,
+"-ex", "set architecture",
+"-ex", "quit"], stderr=STDOUT)
+
+m = re.search(r"Valid arguments are (.*)",
+  gdb_out.decode("utf-8"))
+
+valid_arches = set()
+
+if m.group(1):
+for arch in m.group(1).split(", "):
+if arch in mappings:
+mapping = mappings[arch]
+if isinstance(mapping, str):
+valid_arches.add(mapping)
+else:
+for entry in mapping:
+valid_arches.add(entry)
+
+return valid_arches
+
+def main() -> None:
+parser = argparse.ArgumentParser(description='Probe GDB Architectures')
+parser.add_argument('gdb', help='Path to 

[PATCH v4.5 26/29] gdbstub: Remove gdb_do_syscallv

2023-03-02 Thread Richard Henderson
This function is unused, except to implement gdb_do_syscall.
Fold the implementations together.

Signed-off-by: Richard Henderson 
---
 include/gdbstub/syscalls.h | 11 ---
 gdbstub/syscalls.c | 26 ++
 2 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/include/gdbstub/syscalls.h b/include/gdbstub/syscalls.h
index 5851a2c706..243eaf8ce4 100644
--- a/include/gdbstub/syscalls.h
+++ b/include/gdbstub/syscalls.h
@@ -91,17 +91,6 @@ typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, 
uint64_t ret, int err);
  */
 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
 
-/**
- * gdb_do_syscallv:
- * @cb: function to call when the system call has completed
- * @fmt: gdb syscall format string
- * @va: arguments to interpolate into @fmt
- *
- * As gdb_do_syscall, but taking a va_list rather than a variable
- * argument list.
- */
-void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va);
-
 /**
  * use_gdb_syscalls() - report if GDB should be used for syscalls
  *
diff --git a/gdbstub/syscalls.c b/gdbstub/syscalls.c
index 0a48f58d70..af42e244f9 100644
--- a/gdbstub/syscalls.c
+++ b/gdbstub/syscalls.c
@@ -92,24 +92,26 @@ bool gdb_handled_syscall(void)
  *   %lx - 64-bit argument printed in hex.
  *   %s  - string pointer (target_ulong) and length (int) pair.
  */
-void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
+void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
 {
-char *p;
-char *p_end;
-target_ulong addr;
-uint64_t i64;
+char *p, *p_end;
+va_list va;
 
 if (!gdb_attached()) {
 return;
 }
 
 gdbserver_syscall_state.current_syscall_cb = cb;
+va_start(va, fmt);
 
-p = _syscall_state.syscall_buf[0];
-p_end = 
_syscall_state.syscall_buf[sizeof(gdbserver_syscall_state.syscall_buf)];
+p = gdbserver_syscall_state.syscall_buf;
+p_end = p + sizeof(gdbserver_syscall_state.syscall_buf);
 *(p++) = 'F';
 while (*fmt) {
 if (*fmt == '%') {
+target_ulong addr;
+uint64_t i64;
+
 fmt++;
 switch (*fmt++) {
 case 'x':
@@ -140,16 +142,8 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const 
char *fmt, va_list va)
 }
 *p = 0;
 
-gdb_syscall_handling(gdbserver_syscall_state.syscall_buf);
-}
-
-void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
-{
-va_list va;
-
-va_start(va, fmt);
-gdb_do_syscallv(cb, fmt, va);
 va_end(va);
+gdb_syscall_handling(gdbserver_syscall_state.syscall_buf);
 }
 
 /*
-- 
2.34.1




[PATCH v4.5 14/29] gdbstub: specialise handle_query_attached

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

In both user and softmmu cases we are just replying with a constant.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-15-alex.ben...@linaro.org>
---
 gdbstub/internals.h |  4 +++-
 gdbstub/gdbstub.c   | 15 ++-
 gdbstub/softmmu.c   |  5 +
 gdbstub/user.c  |  5 +
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 6534e373cb..20caacd744 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -154,7 +154,7 @@ int gdb_continue_partial(char *newstates);
 void gdb_put_buffer(const uint8_t *buf, int len);
 
 /*
- * Command handlers - either softmmu or user only
+ * Command handlers - either specialised or softmmu or user only
  */
 void gdb_init_gdbserver_state(void);
 
@@ -183,6 +183,8 @@ void gdb_handle_query_rcmd(GArray *params, void *user_ctx); 
/* softmmu */
 void gdb_handle_query_offsets(GArray *params, void *user_ctx); /* user */
 void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx); /*user */
 
+void gdb_handle_query_attached(GArray *params, void *user_ctx); /* both */
+
 /*
  * Break/Watch point support - there is an implementation for softmmu
  * and user mode.
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 0476ee7039..52d1769f57 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -46,12 +46,6 @@
 
 #include "internals.h"
 
-#ifdef CONFIG_USER_ONLY
-#define GDB_ATTACHED "0"
-#else
-#define GDB_ATTACHED "1"
-#endif
-
 #ifndef CONFIG_USER_ONLY
 static int phy_memory_mode;
 #endif
@@ -1673,11 +1667,6 @@ static void handle_query_xfer_features(GArray *params, 
void *user_ctx)
   gdbserver_state.str_buf->len, true);
 }
 
-static void handle_query_attached(GArray *params, void *user_ctx)
-{
-gdb_put_packet(GDB_ATTACHED);
-}
-
 static void handle_query_qemu_supported(GArray *params, void *user_ctx)
 {
 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
@@ -1787,12 +1776,12 @@ static const GdbCmdParseEntry gdb_gen_query_table[] = {
 },
 #endif
 {
-.handler = handle_query_attached,
+.handler = gdb_handle_query_attached,
 .cmd = "Attached:",
 .cmd_startswith = 1
 },
 {
-.handler = handle_query_attached,
+.handler = gdb_handle_query_attached,
 .cmd = "Attached",
 },
 {
diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index 04e75449a2..7c180b779a 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -446,6 +446,11 @@ void gdb_handle_query_rcmd(GArray *params, void *user_ctx)
  * Execution state helpers
  */
 
+void gdb_handle_query_attached(GArray *params, void *user_ctx)
+{
+gdb_put_packet("1");
+}
+
 void gdb_continue(void)
 {
 if (!runstate_needs_reset()) {
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 0c8cd028b1..c0fd83b373 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -345,6 +345,11 @@ void gdbserver_fork(CPUState *cpu)
  * Execution state helpers
  */
 
+void gdb_handle_query_attached(GArray *params, void *user_ctx)
+{
+gdb_put_packet("0");
+}
+
 void gdb_continue(void)
 {
 gdbserver_user_state.running_state = 1;
-- 
2.34.1




[PATCH v4.5 28/29] gdbstub: Build syscall.c once

2023-03-02 Thread Richard Henderson
There is no longer anything target specific.

Signed-off-by: Richard Henderson 
---
 gdbstub/syscalls.c  | 5 +
 gdbstub/meson.build | 3 +--
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/gdbstub/syscalls.c b/gdbstub/syscalls.c
index b7d85c41c7..4391d124e2 100644
--- a/gdbstub/syscalls.c
+++ b/gdbstub/syscalls.c
@@ -2,9 +2,7 @@
  * GDB Syscall Handling
  *
  * GDB can execute syscalls on the guests behalf, currently used by
- * the various semihosting extensions. As this interfaces with a guest
- * ABI we need to build it per-guest (although in reality its a 32 or
- * 64 bit target_ulong that is the only difference).
+ * the various semihosting extensions.
  *
  * Copyright (c) 2003-2005 Fabrice Bellard
  * Copyright (c) 2023 Linaro Ltd
@@ -13,7 +11,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "cpu.h"
 #include "semihosting/semihost.h"
 #include "sysemu/runstate.h"
 #include "gdbstub/user.h"
diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index d679c7ab86..bd5c5cd67d 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -31,8 +31,7 @@ user_ss.add(gdb_user)
 gdb_softmmu = declare_dependency(link_whole: libgdb_softmmu)
 softmmu_ss.add(gdb_softmmu)
 
-# These have to built to the target ABI
-specific_ss.add(files('syscalls.c'))
+common_ss.add(files('syscalls.c'))
 
 # The user-target is specialised by the guest
 specific_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-target.c'))
-- 
2.34.1




[PATCH v4.5 02/29] gdbstub: fix-up copyright and license files

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

When I started splitting gdbstub apart I was a little too boilerplate
with my file headers. Fix up to carry over Fabrice's copyright and the
LGPL license header.

Fixes: ae7467b1ac (gdbstub: move breakpoint logic to accel ops)
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-3-alex.ben...@linaro.org>
---
 gdbstub/softmmu.c | 3 ++-
 gdbstub/user.c| 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index 129575e510..05db6f8a9f 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -4,9 +4,10 @@
  * Debug integration depends on support from the individual
  * accelerators so most of this involves calling the ops helpers.
  *
+ * Copyright (c) 2003-2005 Fabrice Bellard
  * Copyright (c) 2022 Linaro Ltd
  *
- * SPDX-License-Identifier: GPL-2.0-or-later
+ * SPDX-License-Identifier: LGPL-2.0+
  */
 
 #include "qemu/osdep.h"
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 484bd8f461..09a18fb23b 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -3,9 +3,10 @@
  *
  * We know for user-mode we are using TCG so we can call stuff directly.
  *
+ * Copyright (c) 2003-2005 Fabrice Bellard
  * Copyright (c) 2022 Linaro Ltd
  *
- * SPDX-License-Identifier: GPL-2.0-or-later
+ * SPDX-License-Identifier: LGPL-2.0+
  */
 
 #include "qemu/osdep.h"
-- 
2.34.1




[PATCH v4.5 15/29] gdbstub: specialise target_memory_rw_debug

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

The two implementations are different enough to encourage having a
specialisation and we can move some of the softmmu only stuff out of
gdbstub.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-16-alex.ben...@linaro.org>
---
 gdbstub/internals.h | 19 
 gdbstub/gdbstub.c   | 73 +++--
 gdbstub/softmmu.c   | 51 +++
 gdbstub/user.c  | 15 ++
 4 files changed, 96 insertions(+), 62 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 20caacd744..d8c0292d99 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -185,6 +185,10 @@ void gdb_handle_query_xfer_auxv(GArray *params, void 
*user_ctx); /*user */
 
 void gdb_handle_query_attached(GArray *params, void *user_ctx); /* both */
 
+/* softmmu only */
+void gdb_handle_query_qemu_phy_mem_mode(GArray *params, void *user_ctx);
+void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx);
+
 /*
  * Break/Watch point support - there is an implementation for softmmu
  * and user mode.
@@ -194,4 +198,19 @@ int gdb_breakpoint_insert(CPUState *cs, int type, vaddr 
addr, vaddr len);
 int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len);
 void gdb_breakpoint_remove_all(CPUState *cs);
 
+/**
+ * gdb_target_memory_rw_debug() - handle debug access to memory
+ * @cs: CPUState
+ * @addr: nominal address, could be an entire physical address
+ * @buf: data
+ * @len: length of access
+ * @is_write: is it a write operation
+ *
+ * This function is specialised depending on the mode we are running
+ * in. For softmmu guests we can switch the interpretation of the
+ * address to a physical address.
+ */
+int gdb_target_memory_rw_debug(CPUState *cs, hwaddr addr,
+   uint8_t *buf, int len, bool is_write);
+
 #endif /* GDBSTUB_INTERNALS_H */
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 52d1769f57..ed38ab0aaa 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -46,33 +46,6 @@
 
 #include "internals.h"
 
-#ifndef CONFIG_USER_ONLY
-static int phy_memory_mode;
-#endif
-
-static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, bool is_write)
-{
-CPUClass *cc;
-
-#ifndef CONFIG_USER_ONLY
-if (phy_memory_mode) {
-if (is_write) {
-cpu_physical_memory_write(addr, buf, len);
-} else {
-cpu_physical_memory_read(addr, buf, len);
-}
-return 0;
-}
-#endif
-
-cc = CPU_GET_CLASS(cpu);
-if (cc->memory_rw_debug) {
-return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
-}
-return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
-}
-
 typedef struct GDBRegisterState {
 int base_reg;
 int num_regs;
@@ -1195,11 +1168,11 @@ static void handle_write_mem(GArray *params, void 
*user_ctx)
 }
 
 gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
- get_param(params, 1)->val_ull);
-if (target_memory_rw_debug(gdbserver_state.g_cpu,
-   get_param(params, 0)->val_ull,
-   gdbserver_state.mem_buf->data,
-   gdbserver_state.mem_buf->len, true)) {
+ get_param(params, 1)->val_ull);
+if (gdb_target_memory_rw_debug(gdbserver_state.g_cpu,
+   get_param(params, 0)->val_ull,
+   gdbserver_state.mem_buf->data,
+   gdbserver_state.mem_buf->len, true)) {
 gdb_put_packet("E14");
 return;
 }
@@ -1223,10 +1196,10 @@ static void handle_read_mem(GArray *params, void 
*user_ctx)
 g_byte_array_set_size(gdbserver_state.mem_buf,
   get_param(params, 1)->val_ull);
 
-if (target_memory_rw_debug(gdbserver_state.g_cpu,
-   get_param(params, 0)->val_ull,
-   gdbserver_state.mem_buf->data,
-   gdbserver_state.mem_buf->len, false)) {
+if (gdb_target_memory_rw_debug(gdbserver_state.g_cpu,
+   get_param(params, 0)->val_ull,
+   gdbserver_state.mem_buf->data,
+   gdbserver_state.mem_buf->len, false)) {
 gdb_put_packet("E14");
 return;
 }
@@ -1676,30 +1649,6 @@ static void handle_query_qemu_supported(GArray *params, 
void *user_ctx)
 gdb_put_strbuf();
 }
 
-#ifndef CONFIG_USER_ONLY
-static void handle_query_qemu_phy_mem_mode(GArray *params,
-   void *user_ctx)
-{
-g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
-gdb_put_strbuf();
-}
-
-static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
-{
-if (!params->len) {
-

[PATCH v4.5 20/29] gdbstub: move register helpers into standalone include

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

These inline helpers are all used by target specific code so move them
out of the general header so we don't needlessly pollute the rest of
the API with target specific stuff.

Note we have to include cpu.h in semihosting as it was relying on a
side effect before.

Reviewed-by: Taylor Simpson 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-21-alex.ben...@linaro.org>
---
 include/exec/gdbstub.h |  86 -
 include/gdbstub/helpers.h  | 103 +
 semihosting/syscalls.c |   1 +
 target/alpha/gdbstub.c |   2 +-
 target/arm/gdbstub.c   |   1 +
 target/arm/gdbstub64.c |   2 +-
 target/arm/tcg/helper-a64.c|   2 +-
 target/arm/tcg/m_helper.c  |   1 +
 target/avr/gdbstub.c   |   2 +-
 target/cris/gdbstub.c  |   2 +-
 target/hexagon/gdbstub.c   |   2 +-
 target/hppa/gdbstub.c  |   2 +-
 target/i386/gdbstub.c  |   2 +-
 target/i386/whpx/whpx-all.c|   2 +-
 target/loongarch/gdbstub.c |   1 +
 target/m68k/gdbstub.c  |   2 +-
 target/m68k/helper.c   |   1 +
 target/m68k/m68k-semi.c|   1 +
 target/microblaze/gdbstub.c|   2 +-
 target/mips/gdbstub.c  |   2 +-
 target/mips/tcg/sysemu/mips-semi.c |   1 +
 target/nios2/cpu.c |   2 +-
 target/nios2/nios2-semi.c  |   1 +
 target/openrisc/gdbstub.c  |   2 +-
 target/openrisc/interrupt.c|   2 +-
 target/openrisc/mmu.c  |   2 +-
 target/ppc/cpu_init.c  |   2 +-
 target/ppc/gdbstub.c   |   1 +
 target/riscv/gdbstub.c |   1 +
 target/rx/gdbstub.c|   2 +-
 target/s390x/gdbstub.c |   1 +
 target/s390x/helper.c  |   2 +-
 target/sh4/gdbstub.c   |   2 +-
 target/sparc/gdbstub.c |   2 +-
 target/tricore/gdbstub.c   |   2 +-
 target/xtensa/core-dc232b.c|   2 +-
 target/xtensa/core-dc233c.c|   2 +-
 target/xtensa/core-de212.c |   2 +-
 target/xtensa/core-de233_fpu.c |   2 +-
 target/xtensa/core-dsp3400.c   |   2 +-
 target/xtensa/core-fsf.c   |   2 +-
 target/xtensa/core-lx106.c |   2 +-
 target/xtensa/core-sample_controller.c |   2 +-
 target/xtensa/core-test_kc705_be.c |   2 +-
 target/xtensa/core-test_mmuhifi_c3.c   |   2 +-
 target/xtensa/gdbstub.c|   2 +-
 target/xtensa/helper.c |   2 +-
 target/xtensa/import_core.sh   |   2 +-
 48 files changed, 149 insertions(+), 121 deletions(-)
 create mode 100644 include/gdbstub/helpers.h

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 8fff5450ed..bb8a3928dd 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -110,92 +110,6 @@ void gdb_register_coprocessor(CPUState *cpu,
   gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   int num_regs, const char *xml, int g_pos);
 
-#ifdef NEED_CPU_H
-#include "cpu.h"
-
-/*
- * The GDB remote protocol transfers values in target byte order. As
- * the gdbstub may be batching up several register values we always
- * append to the array.
- */
-
-static inline int gdb_get_reg8(GByteArray *buf, uint8_t val)
-{
-g_byte_array_append(buf, , 1);
-return 1;
-}
-
-static inline int gdb_get_reg16(GByteArray *buf, uint16_t val)
-{
-uint16_t to_word = tswap16(val);
-g_byte_array_append(buf, (uint8_t *) _word, 2);
-return 2;
-}
-
-static inline int gdb_get_reg32(GByteArray *buf, uint32_t val)
-{
-uint32_t to_long = tswap32(val);
-g_byte_array_append(buf, (uint8_t *) _long, 4);
-return 4;
-}
-
-static inline int gdb_get_reg64(GByteArray *buf, uint64_t val)
-{
-uint64_t to_quad = tswap64(val);
-g_byte_array_append(buf, (uint8_t *) _quad, 8);
-return 8;
-}
-
-static inline int gdb_get_reg128(GByteArray *buf, uint64_t val_hi,
- uint64_t val_lo)
-{
-uint64_t to_quad;
-#if TARGET_BIG_ENDIAN
-to_quad = tswap64(val_hi);
-g_byte_array_append(buf, (uint8_t *) _quad, 8);
-to_quad = tswap64(val_lo);
-g_byte_array_append(buf, (uint8_t *) _quad, 8);
-#else
-to_quad = tswap64(val_lo);
-g_byte_array_append(buf, (uint8_t *) _quad, 8);
-to_quad = tswap64(val_hi);
-g_byte_array_append(buf, (uint8_t *) _quad, 8);
-#endif
-return 16;
-}
-
-static inline int gdb_get_zeroes(GByteArray *array, size_t len)
-{
-guint oldlen = array->len;
-g_byte_array_set_size(array, oldlen + len);
-memset(array->data + oldlen, 0, len);
-
-return len;
-}
-
-/**
- * gdb_get_reg_ptr: 

[PATCH v4.5 12/29] gdbstub: rationalise signal mapping in softmmu

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

We don't really need a table for mapping two symbols.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-13-alex.ben...@linaro.org>
---
 gdbstub/softmmu.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index a6c196ade6..6796761fd9 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -506,20 +506,14 @@ enum {
 TARGET_SIGTRAP = 5
 };
 
-static int gdb_signal_table[] = {
--1,
--1,
-TARGET_SIGINT,
--1,
--1,
-TARGET_SIGTRAP
-};
-
 int gdb_signal_to_target(int sig)
 {
-if (sig < ARRAY_SIZE(gdb_signal_table)) {
-return gdb_signal_table[sig];
-} else {
+switch (sig) {
+case 2:
+return TARGET_SIGINT;
+case 5:
+return TARGET_SIGTRAP;
+default:
 return -1;
 }
 }
-- 
2.34.1




[PATCH v4.5 01/29] gdbstub/internals.h: clean up include guard

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

Use something more specific to avoid name clashes.

Reviewed-by: Bin Meng 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-2-alex.ben...@linaro.org>
---
 gdbstub/internals.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index b23999f951..7df0e11c47 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -6,8 +6,8 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#ifndef _INTERNALS_H_
-#define _INTERNALS_H_
+#ifndef GDBSTUB_INTERNALS_H
+#define GDBSTUB_INTERNALS_H
 
 #include "exec/cpu-common.h"
 
@@ -16,4 +16,4 @@ int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, 
vaddr len);
 int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len);
 void gdb_breakpoint_remove_all(CPUState *cs);
 
-#endif /* _INTERNALS_H_ */
+#endif /* GDBSTUB_INTERNALS_H */
-- 
2.34.1




[PATCH v4.5 10/29] gdbstub: move chunk of softmmu functionality to own file

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

This is mostly code motion but a number of things needed to be done
for this minimal patch set:

  - move shared structures to internals.h
  - splitting some functions into user and softmmu versions
  - fixing a few casting issues to keep softmmu common

More CONFIG_USER_ONLY stuff will be handled in a following patches.

Reviewed-by: Richard Henderson 
Reviewed-by: Fabiano Rosas 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-11-alex.ben...@linaro.org>
---
 gdbstub/internals.h  |  43 -
 gdbstub/gdbstub.c| 421 +-
 gdbstub/softmmu.c| 423 +++
 gdbstub/trace-events |   4 +-
 4 files changed, 478 insertions(+), 413 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index cf76627cf7..83989af859 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -17,6 +17,18 @@
  * Shared structures and definitions
  */
 
+enum {
+GDB_SIGNAL_0 = 0,
+GDB_SIGNAL_INT = 2,
+GDB_SIGNAL_QUIT = 3,
+GDB_SIGNAL_TRAP = 5,
+GDB_SIGNAL_ABRT = 6,
+GDB_SIGNAL_ALRM = 14,
+GDB_SIGNAL_IO = 23,
+GDB_SIGNAL_XCPU = 24,
+GDB_SIGNAL_UNKNOWN = 143
+};
+
 typedef struct GDBProcess {
 uint32_t pid;
 bool attached;
@@ -57,6 +69,8 @@ typedef struct GDBState {
 int supported_sstep_flags;
 } GDBState;
 
+/* lives in main gdbstub.c */
+extern GDBState gdbserver_state;
 
 /*
  * Inline utility function, convert from int to hex and back
@@ -101,7 +115,6 @@ CPUState *gdb_first_attached_cpu(void);
 void gdb_append_thread_id(CPUState *cpu, GString *buf);
 int gdb_get_cpu_index(CPUState *cpu);
 
-void gdb_init_gdbserver_state(void);
 void gdb_create_default_process(GDBState *s);
 
 /*
@@ -109,6 +122,34 @@ void gdb_create_default_process(GDBState *s);
  */
 void gdb_put_buffer(const uint8_t *buf, int len);
 
+/*
+ * Command handlers - either softmmu or user only
+ */
+void gdb_init_gdbserver_state(void);
+
+typedef enum GDBThreadIdKind {
+GDB_ONE_THREAD = 0,
+GDB_ALL_THREADS, /* One process, all threads */
+GDB_ALL_PROCESSES,
+GDB_READ_THREAD_ERR
+} GDBThreadIdKind;
+
+typedef union GdbCmdVariant {
+const char *data;
+uint8_t opcode;
+unsigned long val_ul;
+unsigned long long val_ull;
+struct {
+GDBThreadIdKind kind;
+uint32_t pid;
+uint32_t tid;
+} thread_id;
+} GdbCmdVariant;
+
+#define get_param(p, i)(_array_index(p, GdbCmdVariant, i))
+
+void gdb_handle_query_rcmd(GArray *params, void *user_ctx); /* softmmu */
+
 /*
  * Break/Watch point support - there is an implementation for softmmu
  * and user mode.
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index f59ab12cc3..4b939c689c 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -24,8 +24,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/error-report.h"
 #include "qemu/ctype.h"
 #include "qemu/cutils.h"
 #include "qemu/module.h"
@@ -34,9 +32,6 @@
 #ifdef CONFIG_USER_ONLY
 #include "qemu.h"
 #else
-#include "monitor/monitor.h"
-#include "chardev/char.h"
-#include "chardev/char-fe.h"
 #include "hw/cpu/cluster.h"
 #include "hw/boards.h"
 #endif
@@ -88,30 +83,15 @@ static inline int target_memory_rw_debug(CPUState *cpu, 
target_ulong addr,
 /*
  * Return the GDB index for a given vCPU state.
  *
- * For user mode this is simply the thread id. In system mode GDB
- * numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
+ * For user mode this is simply the thread id.
  */
+#if defined(CONFIG_USER_ONLY)
 int gdb_get_cpu_index(CPUState *cpu)
 {
-#if defined(CONFIG_USER_ONLY)
 TaskState *ts = (TaskState *) cpu->opaque;
 return ts ? ts->ts_tid : -1;
-#else
-return cpu->cpu_index + 1;
-#endif
 }
-
-enum {
-GDB_SIGNAL_0 = 0,
-GDB_SIGNAL_INT = 2,
-GDB_SIGNAL_QUIT = 3,
-GDB_SIGNAL_TRAP = 5,
-GDB_SIGNAL_ABRT = 6,
-GDB_SIGNAL_ALRM = 14,
-GDB_SIGNAL_IO = 23,
-GDB_SIGNAL_XCPU = 24,
-GDB_SIGNAL_UNKNOWN = 143
-};
+#endif
 
 #ifdef CONFIG_USER_ONLY
 
@@ -333,15 +313,9 @@ typedef struct {
 int running_state;
 } GDBUserState;
 static GDBUserState gdbserver_user_state;
-#else
-typedef struct {
-CharBackend chr;
-Chardev *mon_chr;
-} GDBSystemState;
-static GDBSystemState gdbserver_system_state;
 #endif
 
-static GDBState gdbserver_state;
+GDBState gdbserver_state;
 
 void gdb_init_gdbserver_state(void)
 {
@@ -362,15 +336,6 @@ void gdb_init_gdbserver_state(void)
 gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
 }
 
-#ifndef CONFIG_USER_ONLY
-static void reset_gdbserver_state(void)
-{
-g_free(gdbserver_state.processes);
-gdbserver_state.processes = NULL;
-gdbserver_state.process_num = 0;
-}
-#endif
-
 bool gdb_has_xml;
 
 #ifdef CONFIG_USER_ONLY
@@ -446,7 +411,7 @@ static bool stub_can_reverse(void)
 }
 
 /* Resume execution.  */
-static inline void gdb_continue(void)
+static void gdb_continue(void)
 {
 
 #ifdef 

[PATCH v4.5 06/29] gdbstub: move GDBState to shared internals header

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

We are about to split softmmu and user mode helpers into different
files. To facilitate this we will need to share access to the GDBState
between those files.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-7-alex.ben...@linaro.org>
---
 gdbstub/internals.h | 50 +
 gdbstub/gdbstub.c   | 42 -
 2 files changed, 50 insertions(+), 42 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 7df0e11c47..32daaf73a3 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -11,6 +11,56 @@
 
 #include "exec/cpu-common.h"
 
+#define MAX_PACKET_LENGTH 4096
+
+/*
+ * Shared structures and definitions
+ */
+
+typedef struct GDBProcess {
+uint32_t pid;
+bool attached;
+
+char target_xml[1024];
+} GDBProcess;
+
+enum RSState {
+RS_INACTIVE,
+RS_IDLE,
+RS_GETLINE,
+RS_GETLINE_ESC,
+RS_GETLINE_RLE,
+RS_CHKSUM1,
+RS_CHKSUM2,
+};
+
+typedef struct GDBState {
+bool init;   /* have we been initialised? */
+CPUState *c_cpu; /* current CPU for step/continue ops */
+CPUState *g_cpu; /* current CPU for other ops */
+CPUState *query_cpu; /* for q{f|s}ThreadInfo */
+enum RSState state; /* parsing state */
+char line_buf[MAX_PACKET_LENGTH];
+int line_buf_index;
+int line_sum; /* running checksum */
+int line_csum; /* checksum at the end of the packet */
+GByteArray *last_packet;
+int signal;
+bool multiprocess;
+GDBProcess *processes;
+int process_num;
+char syscall_buf[256];
+gdb_syscall_complete_cb current_syscall_cb;
+GString *str_buf;
+GByteArray *mem_buf;
+int sstep_flags;
+int supported_sstep_flags;
+} GDBState;
+
+/*
+ * Break/Watch point support - there is an implementation for softmmu
+ * and user mode.
+ */
 bool gdb_supports_guest_debug(void);
 int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len);
 int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len);
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 1e6f8978b5..ef506faa8e 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -41,8 +41,6 @@
 #include "hw/boards.h"
 #endif
 
-#define MAX_PACKET_LENGTH 4096
-
 #include "qemu/sockets.h"
 #include "sysemu/hw_accel.h"
 #include "sysemu/runstate.h"
@@ -325,23 +323,6 @@ typedef struct GDBRegisterState {
 struct GDBRegisterState *next;
 } GDBRegisterState;
 
-typedef struct GDBProcess {
-uint32_t pid;
-bool attached;
-
-char target_xml[1024];
-} GDBProcess;
-
-enum RSState {
-RS_INACTIVE,
-RS_IDLE,
-RS_GETLINE,
-RS_GETLINE_ESC,
-RS_GETLINE_RLE,
-RS_CHKSUM1,
-RS_CHKSUM2,
-};
-
 #ifdef CONFIG_USER_ONLY
 typedef struct {
 int fd;
@@ -357,29 +338,6 @@ typedef struct {
 static GDBSystemState gdbserver_system_state;
 #endif
 
-typedef struct GDBState {
-bool init;   /* have we been initialised? */
-CPUState *c_cpu; /* current CPU for step/continue ops */
-CPUState *g_cpu; /* current CPU for other ops */
-CPUState *query_cpu; /* for q{f|s}ThreadInfo */
-enum RSState state; /* parsing state */
-char line_buf[MAX_PACKET_LENGTH];
-int line_buf_index;
-int line_sum; /* running checksum */
-int line_csum; /* checksum at the end of the packet */
-GByteArray *last_packet;
-int signal;
-bool multiprocess;
-GDBProcess *processes;
-int process_num;
-char syscall_buf[256];
-gdb_syscall_complete_cb current_syscall_cb;
-GString *str_buf;
-GByteArray *mem_buf;
-int sstep_flags;
-int supported_sstep_flags;
-} GDBState;
-
 static GDBState gdbserver_state;
 
 static void init_gdbserver_state(void)
-- 
2.34.1




[PATCH v4.5 25/29] gdbstub: split out softmmu/user specifics for syscall handling

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

Most of the syscall code is config agnostic aside from the size of
target_ulong. In preparation for the next patch move the final bits
of specialisation into the appropriate user and softmmu helpers.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20230302190846.2593720-26-alex.ben...@linaro.org>
---
 gdbstub/internals.h |  3 +++
 gdbstub/softmmu.c   | 14 ++
 gdbstub/syscalls.c  | 27 +++
 gdbstub/user.c  | 14 ++
 4 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 8db61f7fb4..94ddff4495 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -195,6 +195,9 @@ bool gdb_handled_syscall(void);
 void gdb_disable_syscalls(void);
 void gdb_syscall_reset(void);
 
+/* user/softmmu specific syscall handling */
+void gdb_syscall_handling(const char *syscall_packet);
+
 /*
  * Break/Watch point support - there is an implementation for softmmu
  * and user mode.
diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c
index d3152fb6e7..22ecd09d04 100644
--- a/gdbstub/softmmu.c
+++ b/gdbstub/softmmu.c
@@ -103,6 +103,20 @@ static void gdb_chr_event(void *opaque, QEMUChrEvent event)
 }
 }
 
+/*
+ * In softmmu mode we stop the VM and wait to send the syscall packet
+ * until notification that the CPU has stopped. This must be done
+ * because if the packet is sent now the reply from the syscall
+ * request could be received while the CPU is still in the running
+ * state, which can cause packets to be dropped and state transition
+ * 'T' packets to be sent while the syscall is still being processed.
+ */
+void gdb_syscall_handling(const char *syscall_packet)
+{
+vm_stop(RUN_STATE_DEBUG);
+qemu_cpu_kick(gdbserver_state.c_cpu);
+}
+
 static void gdb_vm_state_change(void *opaque, bool running, RunState state)
 {
 CPUState *cpu = gdbserver_state.c_cpu;
diff --git a/gdbstub/syscalls.c b/gdbstub/syscalls.c
index f15b210958..0a48f58d70 100644
--- a/gdbstub/syscalls.c
+++ b/gdbstub/syscalls.c
@@ -104,9 +104,7 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char 
*fmt, va_list va)
 }
 
 gdbserver_syscall_state.current_syscall_cb = cb;
-#ifndef CONFIG_USER_ONLY
-vm_stop(RUN_STATE_DEBUG);
-#endif
+
 p = _syscall_state.syscall_buf[0];
 p_end = 
_syscall_state.syscall_buf[sizeof(gdbserver_syscall_state.syscall_buf)];
 *(p++) = 'F';
@@ -141,27 +139,8 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const 
char *fmt, va_list va)
 }
 }
 *p = 0;
-#ifdef CONFIG_USER_ONLY
-gdb_put_packet(gdbserver_syscall_state.syscall_buf);
-/*
- * Return control to gdb for it to process the syscall request.
- * Since the protocol requires that gdb hands control back to us
- * using a "here are the results" F packet, we don't need to check
- * gdb_handlesig's return value (which is the signal to deliver if
- * execution was resumed via a continue packet).
- */
-gdb_handlesig(gdbserver_state.c_cpu, 0);
-#else
-/*
- * In this case wait to send the syscall packet until notification that
- * the CPU has stopped.  This must be done because if the packet is sent
- * now the reply from the syscall request could be received while the CPU
- * is still in the running state, which can cause packets to be dropped
- * and state transition 'T' packets to be sent while the syscall is still
- * being processed.
- */
-qemu_cpu_kick(gdbserver_state.c_cpu);
-#endif
+
+gdb_syscall_handling(gdbserver_syscall_state.syscall_buf);
 }
 
 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
diff --git a/gdbstub/user.c b/gdbstub/user.c
index 3da410e221..80488b6bb9 100644
--- a/gdbstub/user.c
+++ b/gdbstub/user.c
@@ -472,3 +472,17 @@ void gdb_breakpoint_remove_all(CPUState *cs)
 {
 cpu_breakpoint_remove_all(cs, BP_GDB);
 }
+
+/*
+ * For user-mode syscall support we send the system call immediately
+ * and then return control to gdb for it to process the syscall request.
+ * Since the protocol requires that gdb hands control back to us
+ * using a "here are the results" F packet, we don't need to check
+ * gdb_handlesig's return value (which is the signal to deliver if
+ * execution was resumed via a continue packet).
+ */
+void gdb_syscall_handling(const char *syscall_packet)
+{
+gdb_put_packet(syscall_packet);
+gdb_handlesig(gdbserver_state.c_cpu, 0);
+}
-- 
2.34.1




[PATCH v4.5 18/29] gdbstub: fix address type of gdb_set_cpu_pc

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

The underlying call uses vaddr and the comms API uses unsigned long
long which will always fit. We don't need to deal in target_ulong
here.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-19-alex.ben...@linaro.org>
---
 gdbstub/gdbstub.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 7301466ff5..b8aead03bd 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -535,7 +535,7 @@ static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 }
 
 
-static void gdb_set_cpu_pc(target_ulong pc)
+static void gdb_set_cpu_pc(vaddr pc)
 {
 CPUState *cpu = gdbserver_state.c_cpu;
 
@@ -1290,7 +1290,7 @@ static void handle_file_io(GArray *params, void *user_ctx)
 static void handle_step(GArray *params, void *user_ctx)
 {
 if (params->len) {
-gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
+gdb_set_cpu_pc(get_param(params, 0)->val_ull);
 }
 
 cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
-- 
2.34.1




[PATCH v4.5 09/29] gdbstub: make various helpers visible to the rest of the module

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

We will be needing to use these helpers between the user and softmmu
files so declare them in the headers, add a system prefix and remove
static from the implementations.

Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-10-alex.ben...@linaro.org>
---
 gdbstub/internals.h |  25 
 gdbstub/gdbstub.c   | 276 ++--
 2 files changed, 165 insertions(+), 136 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index b4620f99c4..cf76627cf7 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -84,6 +84,31 @@ static inline int tohex(int v)
 }
 }
 
+/*
+ * Connection helpers for both softmmu and user backends
+ */
+
+void gdb_put_strbuf(void);
+int gdb_put_packet(const char *buf);
+int gdb_put_packet_binary(const char *buf, int len, bool dump);
+void gdb_hextomem(GByteArray *mem, const char *buf, int len);
+void gdb_memtohex(GString *buf, const uint8_t *mem, int len);
+void gdb_memtox(GString *buf, const char *mem, int len);
+void gdb_read_byte(uint8_t ch);
+
+/* utility helpers */
+CPUState *gdb_first_attached_cpu(void);
+void gdb_append_thread_id(CPUState *cpu, GString *buf);
+int gdb_get_cpu_index(CPUState *cpu);
+
+void gdb_init_gdbserver_state(void);
+void gdb_create_default_process(GDBState *s);
+
+/*
+ * Helpers with separate softmmu and user implementations
+ */
+void gdb_put_buffer(const uint8_t *buf, int len);
+
 /*
  * Break/Watch point support - there is an implementation for softmmu
  * and user mode.
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index ba46ed73b3..f59ab12cc3 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -85,12 +85,13 @@ static inline int target_memory_rw_debug(CPUState *cpu, 
target_ulong addr,
 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
 }
 
-/* Return the GDB index for a given vCPU state.
+/*
+ * Return the GDB index for a given vCPU state.
  *
  * For user mode this is simply the thread id. In system mode GDB
  * numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
  */
-static inline int cpu_gdb_index(CPUState *cpu)
+int gdb_get_cpu_index(CPUState *cpu)
 {
 #if defined(CONFIG_USER_ONLY)
 TaskState *ts = (TaskState *) cpu->opaque;
@@ -342,7 +343,7 @@ static GDBSystemState gdbserver_system_state;
 
 static GDBState gdbserver_state;
 
-static void init_gdbserver_state(void)
+void gdb_init_gdbserver_state(void)
 {
 g_assert(!gdbserver_state.init);
 memset(_state, 0, sizeof(GDBState));
@@ -524,7 +525,7 @@ static int gdb_continue_partial(char *newstates)
 return res;
 }
 
-static void put_buffer(const uint8_t *buf, int len)
+void gdb_put_buffer(const uint8_t *buf, int len)
 {
 #ifdef CONFIG_USER_ONLY
 int ret;
@@ -547,7 +548,7 @@ static void put_buffer(const uint8_t *buf, int len)
 }
 
 /* writes 2*len+1 bytes in buf */
-static void memtohex(GString *buf, const uint8_t *mem, int len)
+void gdb_memtohex(GString *buf, const uint8_t *mem, int len)
 {
 int i, c;
 for(i = 0; i < len; i++) {
@@ -558,7 +559,7 @@ static void memtohex(GString *buf, const uint8_t *mem, int 
len)
 g_string_append_c(buf, '\0');
 }
 
-static void hextomem(GByteArray *mem, const char *buf, int len)
+void gdb_hextomem(GByteArray *mem, const char *buf, int len)
 {
 int i;
 
@@ -603,7 +604,7 @@ static void hexdump(const char *buf, int len,
 }
 
 /* return -1 if error, 0 if OK */
-static int put_packet_binary(const char *buf, int len, bool dump)
+int gdb_put_packet_binary(const char *buf, int len, bool dump)
 {
 int csum, i;
 uint8_t footer[3];
@@ -627,7 +628,7 @@ static int put_packet_binary(const char *buf, int len, bool 
dump)
 footer[2] = tohex((csum) & 0xf);
 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
 
-put_buffer(gdbserver_state.last_packet->data,
+gdb_put_buffer(gdbserver_state.last_packet->data,
gdbserver_state.last_packet->len);
 
 #ifdef CONFIG_USER_ONLY
@@ -644,20 +645,20 @@ static int put_packet_binary(const char *buf, int len, 
bool dump)
 }
 
 /* return -1 if error, 0 if OK */
-static int put_packet(const char *buf)
+int gdb_put_packet(const char *buf)
 {
 trace_gdbstub_io_reply(buf);
 
-return put_packet_binary(buf, strlen(buf), false);
+return gdb_put_packet_binary(buf, strlen(buf), false);
 }
 
-static void put_strbuf(void)
+void gdb_put_strbuf(void)
 {
-put_packet(gdbserver_state.str_buf->str);
+gdb_put_packet(gdbserver_state.str_buf->str);
 }
 
 /* Encode data using the encoding for 'x' packets.  */
-static void memtox(GString *buf, const char *mem, int len)
+void gdb_memtox(GString *buf, const char *mem, int len)
 {
 char c;
 
@@ -714,7 +715,7 @@ static CPUState *find_cpu(uint32_t thread_id)
 CPUState *cpu;
 
 CPU_FOREACH(cpu) {
-if (cpu_gdb_index(cpu) == thread_id) {
+if (gdb_get_cpu_index(cpu) == thread_id) {
 

[PATCH v4.5 08/29] gdbstub: move fromhex/tohex routines to internals

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

These will be needed from multiple places in the code. They are
declared as inline so move to the header and fix up to modern coding
style.

The only other place that messes with hex stuff at the moment is the
URI handling in utils but that would be more code churn so leave for
now.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 
Message-Id: <20230302190846.2593720-9-alex.ben...@linaro.org>
---
 gdbstub/internals.h | 27 +++
 gdbstub/gdbstub.c   | 20 
 2 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/gdbstub/internals.h b/gdbstub/internals.h
index 32daaf73a3..b4620f99c4 100644
--- a/gdbstub/internals.h
+++ b/gdbstub/internals.h
@@ -57,6 +57,33 @@ typedef struct GDBState {
 int supported_sstep_flags;
 } GDBState;
 
+
+/*
+ * Inline utility function, convert from int to hex and back
+ */
+
+static inline int fromhex(int v)
+{
+if (v >= '0' && v <= '9') {
+return v - '0';
+} else if (v >= 'A' && v <= 'F') {
+return v - 'A' + 10;
+} else if (v >= 'a' && v <= 'f') {
+return v - 'a' + 10;
+} else {
+return 0;
+}
+}
+
+static inline int tohex(int v)
+{
+if (v < 10) {
+return v + '0';
+} else {
+return v - 10 + 'a';
+}
+}
+
 /*
  * Break/Watch point support - there is an implementation for softmmu
  * and user mode.
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index abb1777e73..ba46ed73b3 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -546,26 +546,6 @@ static void put_buffer(const uint8_t *buf, int len)
 #endif
 }
 
-static inline int fromhex(int v)
-{
-if (v >= '0' && v <= '9')
-return v - '0';
-else if (v >= 'A' && v <= 'F')
-return v - 'A' + 10;
-else if (v >= 'a' && v <= 'f')
-return v - 'a' + 10;
-else
-return 0;
-}
-
-static inline int tohex(int v)
-{
-if (v < 10)
-return v + '0';
-else
-return v - 10 + 'a';
-}
-
 /* writes 2*len+1 bytes in buf */
 static void memtohex(GString *buf, const uint8_t *mem, int len)
 {
-- 
2.34.1




[PATCH v4.5 00/29] gdbstub/next: re-organise and split build

2023-03-02 Thread Richard Henderson
Hi Alex,

This is what I came up with when thinking about your user/softmmu
and syscall split.


r~


Alex Bennée (24):
  gdbstub/internals.h: clean up include guard
  gdbstub: fix-up copyright and license files
  gdbstub: clean-up indent on gdb_exit
  gdbstub: define separate user/system structures
  gdbstub: move GDBState to shared internals header
  includes: move tb_flush into its own header
  gdbstub: move fromhex/tohex routines to internals
  gdbstub: make various helpers visible to the rest of the module
  gdbstub: move chunk of softmmu functionality to own file
  gdbstub: move chunks of user code into own files
  gdbstub: rationalise signal mapping in softmmu
  gdbstub: abstract target specific details from gdb_put_packet_binary
  gdbstub: specialise handle_query_attached
  gdbstub: specialise target_memory_rw_debug
  gdbstub: introduce gdb_get_max_cpus
  gdbstub: specialise stub_can_reverse
  gdbstub: fix address type of gdb_set_cpu_pc
  gdbstub: don't use target_ulong while handling registers
  gdbstub: move register helpers into standalone include
  gdbstub: move syscall handling to new file
  gdbstub: only compile gdbstub twice for whole build
  testing: probe gdb for supported architectures ahead of time
  include: split target_long definition from cpu-defs
  gdbstub: split out softmmu/user specifics for syscall handling

Mads Ynddal (1):
  gdbstub: move update guest debug to accel ops

Philippe Mathieu-Daudé (1):
  gdbstub: Make syscall_complete/[gs]et_reg target-agnostic typedefs

Richard Henderson (3):
  gdbstub: Remove gdb_do_syscallv
  gdbstub: Adjust gdb_do_syscall to only use uint32_t and uint64_t
  gdbstub: Build syscall.c once

 MAINTAINERS   |4 +
 configure |8 +
 gdbstub/internals.h   |  212 ++-
 include/exec/cpu-defs.h   |   19 +-
 include/exec/exec-all.h   |1 -
 include/exec/gdbstub.h|  208 ---
 include/exec/target_long.h|   42 +
 include/exec/tb-flush.h   |   26 +
 include/gdbstub/helpers.h |  103 +
 include/gdbstub/syscalls.h|  113 ++
 include/gdbstub/user.h|   43 +
 include/sysemu/accel-ops.h|1 +
 linux-user/user-internals.h   |1 +
 accel/kvm/kvm-accel-ops.c |8 +
 accel/stubs/tcg-stub.c|1 +
 accel/tcg/tb-maint.c  |1 +
 accel/tcg/translate-all.c |1 +
 cpu.c |   12 +-
 gdbstub/gdbstub.c | 1655 ++---
 gdbstub/softmmu.c |  603 +-
 gdbstub/syscalls.c|  204 ++
 gdbstub/user-target.c |  283 +++
 gdbstub/user.c|  423 -
 hw/ppc/spapr_hcall.c  |1 +
 linux-user/exit.c |2 +-
 linux-user/main.c |1 +
 linux-user/signal.c   |2 +-
 plugins/core.c|1 +
 plugins/loader.c  |2 +-
 semihosting/arm-compat-semi.c |1 +
 semihosting/guestfd.c |2 +-
 semihosting/syscalls.c|   37 +-
 softmmu/runstate.c|2 +-
 target/alpha/gdbstub.c|2 +-
 target/alpha/sys_helper.c |1 +
 target/arm/gdbstub.c  |1 +
 target/arm/gdbstub64.c|2 +-
 target/arm/tcg/helper-a64.c   |2 +-
 target/arm/tcg/m_helper.c |1 +
 target/avr/gdbstub.c  |2 +-
 target/cris/gdbstub.c |2 +-
 target/hexagon/gdbstub.c  |2 +-
 target/hppa/gdbstub.c |2 +-
 target/i386/gdbstub.c |2 +-
 target/i386/whpx/whpx-all.c   |2 +-
 target/loongarch/gdbstub.c|1 +
 target/m68k/gdbstub.c |2 +-
 target/m68k/helper.c  |1 +
 target/m68k/m68k-semi.c   |3 +-
 target/microblaze/gdbstub.c   |2 +-
 target/mips/gdbstub.c |2 +-
 target/mips/tcg/sysemu/mips-semi.c|3 +-
 target/nios2/cpu.c|2 +-
 target/nios2/nios2-semi.c |3 +-
 target/openrisc/gdbstub.c |2 +-
 target/openrisc/interrupt.c   |2 +-
 target/openrisc/mmu.c |2 +-
 target/ppc/cpu_init.c |2 +-
 

[PATCH v4.5 05/29] gdbstub: define separate user/system structures

2023-03-02 Thread Richard Henderson
From: Alex Bennée 

In preparation for moving user/softmmu specific bits from the main
gdbstub file we need to separate the connection details into a
user/softmmu state. As these will eventually be defined in their own
files we move them out of the common GDBState structure.

Reviewed-by: Richard Henderson 
Signed-off-by: Alex Bennée 

Message-Id: <20230302190846.2593720-6-alex.ben...@linaro.org>
---
 gdbstub/gdbstub.c | 94 ++-
 1 file changed, 53 insertions(+), 41 deletions(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 63b56f0027..1e6f8978b5 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -341,6 +341,22 @@ enum RSState {
 RS_CHKSUM1,
 RS_CHKSUM2,
 };
+
+#ifdef CONFIG_USER_ONLY
+typedef struct {
+int fd;
+char *socket_path;
+int running_state;
+} GDBUserState;
+static GDBUserState gdbserver_user_state;
+#else
+typedef struct {
+CharBackend chr;
+Chardev *mon_chr;
+} GDBSystemState;
+static GDBSystemState gdbserver_system_state;
+#endif
+
 typedef struct GDBState {
 bool init;   /* have we been initialised? */
 CPUState *c_cpu; /* current CPU for step/continue ops */
@@ -353,14 +369,6 @@ typedef struct GDBState {
 int line_csum; /* checksum at the end of the packet */
 GByteArray *last_packet;
 int signal;
-#ifdef CONFIG_USER_ONLY
-int fd;
-char *socket_path;
-int running_state;
-#else
-CharBackend chr;
-Chardev *mon_chr;
-#endif
 bool multiprocess;
 GDBProcess *processes;
 int process_num;
@@ -412,15 +420,17 @@ static int get_char(void)
 int ret;
 
 for(;;) {
-ret = recv(gdbserver_state.fd, , 1, 0);
+ret = recv(gdbserver_user_state.fd, , 1, 0);
 if (ret < 0) {
-if (errno == ECONNRESET)
-gdbserver_state.fd = -1;
-if (errno != EINTR)
+if (errno == ECONNRESET) {
+gdbserver_user_state.fd = -1;
+}
+if (errno != EINTR) {
 return -1;
+}
 } else if (ret == 0) {
-close(gdbserver_state.fd);
-gdbserver_state.fd = -1;
+close(gdbserver_user_state.fd);
+gdbserver_user_state.fd = -1;
 return -1;
 } else {
 break;
@@ -479,7 +489,7 @@ static inline void gdb_continue(void)
 {
 
 #ifdef CONFIG_USER_ONLY
-gdbserver_state.running_state = 1;
+gdbserver_user_state.running_state = 1;
 trace_gdbstub_op_continue();
 #else
 if (!runstate_needs_reset()) {
@@ -508,7 +518,7 @@ static int gdb_continue_partial(char *newstates)
 cpu_single_step(cpu, gdbserver_state.sstep_flags);
 }
 }
-gdbserver_state.running_state = 1;
+gdbserver_user_state.running_state = 1;
 #else
 int flag = 0;
 
@@ -560,7 +570,7 @@ static void put_buffer(const uint8_t *buf, int len)
 int ret;
 
 while (len > 0) {
-ret = send(gdbserver_state.fd, buf, len, 0);
+ret = send(gdbserver_user_state.fd, buf, len, 0);
 if (ret < 0) {
 if (errno != EINTR)
 return;
@@ -572,7 +582,7 @@ static void put_buffer(const uint8_t *buf, int len)
 #else
 /* XXX this blocks entire thread. Rewrite to use
  * qemu_chr_fe_write and background I/O callbacks */
-qemu_chr_fe_write_all(_state.chr, buf, len);
+qemu_chr_fe_write_all(_system_state.chr, buf, len);
 #endif
 }
 
@@ -2094,7 +2104,8 @@ static void handle_query_rcmd(GArray *params, void 
*user_ctx)
 len = len / 2;
 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
 g_byte_array_append(gdbserver_state.mem_buf, , 1);
-qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
+qemu_chr_be_write(gdbserver_system_state.mon_chr,
+  gdbserver_state.mem_buf->data,
   gdbserver_state.mem_buf->len);
 put_packet("OK");
 }
@@ -3027,10 +3038,10 @@ void gdb_exit(int code)
 return;
 }
 #ifdef CONFIG_USER_ONLY
-if (gdbserver_state.socket_path) {
-unlink(gdbserver_state.socket_path);
+if (gdbserver_user_state.socket_path) {
+unlink(gdbserver_user_state.socket_path);
 }
-if (gdbserver_state.fd < 0) {
+if (gdbserver_user_state.fd < 0) {
 return;
 }
 #endif
@@ -3041,7 +3052,7 @@ void gdb_exit(int code)
 put_packet(buf);
 
 #ifndef CONFIG_USER_ONLY
-qemu_chr_fe_deinit(_state.chr, true);
+qemu_chr_fe_deinit(_system_state.chr, true);
 #endif
 }
 
@@ -3077,7 +3088,7 @@ gdb_handlesig(CPUState *cpu, int sig)
 char buf[256];
 int n;
 
-if (!gdbserver_state.init || gdbserver_state.fd < 0) {
+if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
 return sig;
 }
 
@@ -3095,15 +3106,15 @@ gdb_handlesig(CPUState *cpu, int sig)
 }
 /* put_packet() might have detected that the peer terminated the
connection.  */
-if (gdbserver_state.fd < 0) 

[PULL 2/5] loongarch: Add smbios command line option.

2023-03-02 Thread Song Gao
LoongArch has enabled CONFIG_SMBIOS, but didn't enable CLI '-smbios'.

Fixes: 3efa6fa1e629 ("hw/loongarch: Add smbios support")
Acked-by: Michael S. Tsirkin 
Reviewed-by: Markus Armbruster 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230227035905.1290953-2-gaos...@loongson.cn>
---
 qemu-options.hx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index beeb4475ba..d42f60fb91 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2585,7 +2585,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
 "specify SMBIOS type 17 fields\n"
 "-smbios type=41[,designation=str][,kind=str][,instance=%d][,pcidev=str]\n"
 "specify SMBIOS type 41 fields\n",
-QEMU_ARCH_I386 | QEMU_ARCH_ARM)
+QEMU_ARCH_I386 | QEMU_ARCH_ARM | QEMU_ARCH_LOONGARCH)
 SRST
 ``-smbios file=binary``
 Load SMBIOS entry from binary file.
-- 
2.31.1




[PULL 0/5] loongarch-to-apply queue

2023-03-02 Thread Song Gao
The following changes since commit 262312d7ba6e2966acedb4f9c134fd19176b4083:

  Merge tag 'pull-testing-next-010323-1' of https://gitlab.com/stsquad/qemu 
into staging (2023-03-02 13:02:53 +)

are available in the Git repository at:

  https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20230303

for you to fetch changes up to 0d588c4f999699a430b32c563fe9ccc1710b8fd7:

  hw/loongarch/virt: add system_powerdown hmp command support (2023-03-03 
09:37:30 +0800)


pull-loongarch-20230303


Bibo Mao (1):
  hw/loongarch/virt: rename PCH_PIC_IRQ_OFFSET with VIRT_GSI_BASE

Song Gao (4):
  loongarch: Add smbios command line option.
  docs/system/loongarch: update loongson3.rst and rename it to virt.rst
  target/loongarch: Implement Chip Configuraiton Version Register(0x)
  hw/loongarch/virt: add system_powerdown hmp command support

 docs/system/loongarch/{loongson3.rst => virt.rst} | 97 +--
 hw/loongarch/acpi-build.c |  3 +-
 hw/loongarch/virt.c   | 20 -
 include/hw/loongarch/virt.h   |  1 +
 include/hw/pci-host/ls7a.h| 17 ++--
 qemu-options.hx   |  2 +-
 target/loongarch/cpu.c|  2 +
 target/loongarch/cpu.h|  1 +
 8 files changed, 70 insertions(+), 73 deletions(-)
 rename docs/system/loongarch/{loongson3.rst => virt.rst} (51%)




[PULL 5/5] hw/loongarch/virt: add system_powerdown hmp command support

2023-03-02 Thread Song Gao
For loongarch virt machine, add powerdown notification callback
and send ACPI_POWER_DOWN_STATUS event by acpi ged. Also add
acpi dsdt table for ACPI_POWER_BUTTON_DEVICE device in this
patch.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Song Gao 
Message-Id: <20230303010548.295580-1-gaos...@loongson.cn>
---
 hw/loongarch/acpi-build.c   |  1 +
 hw/loongarch/virt.c | 12 
 include/hw/loongarch/virt.h |  1 +
 3 files changed, 14 insertions(+)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 8aed50e858..6cb2472d33 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -260,6 +260,7 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
  AML_SYSTEM_MEMORY,
  VIRT_GED_MEM_ADDR);
 }
+acpi_dsdt_add_power_button(dsdt);
 }
 
 static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 49d25059f8..38ef7cc49f 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -316,6 +316,14 @@ static void virt_machine_done(Notifier *notifier, void 
*data)
 loongarch_acpi_setup(lams);
 }
 
+static void virt_powerdown_req(Notifier *notifier, void *opaque)
+{
+LoongArchMachineState *s = container_of(notifier,
+   LoongArchMachineState, powerdown_notifier);
+
+acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
+}
+
 struct memmap_entry {
 uint64_t address;
 uint64_t length;
@@ -859,6 +867,10 @@ static void loongarch_init(MachineState *machine)
VIRT_PLATFORM_BUS_IRQ);
 lams->machine_done.notify = virt_machine_done;
 qemu_add_machine_init_done_notifier(>machine_done);
+ /* connect powerdown request */
+lams->powerdown_notifier.notify = virt_powerdown_req;
+qemu_register_powerdown_notifier(>powerdown_notifier);
+
 fdt_add_pcie_node(lams);
 /*
  * Since lowmem region starts from 0 and Linux kernel legacy start address
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index f5f818894e..7ae8a91229 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -45,6 +45,7 @@ struct LoongArchMachineState {
 /* State for other subsystems/APIs: */
 FWCfgState  *fw_cfg;
 Notifier machine_done;
+Notifier powerdown_notifier;
 OnOffAutoacpi;
 char *oem_id;
 char *oem_table_id;
-- 
2.31.1




[PULL 4/5] target/loongarch: Implement Chip Configuraiton Version Register(0x0000)

2023-03-02 Thread Song Gao
According to the 3A5000 manual 4.1 implement Chip Configuration
Version Register(0x).

Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
Message-Id: <20230227071046.1445572-1-gaos...@loongson.cn>
---
 target/loongarch/cpu.c | 2 ++
 target/loongarch/cpu.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index d6513f2d9d..97e6579f6a 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -546,6 +546,8 @@ static void loongarch_qemu_write(void *opaque, hwaddr addr,
 static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
 {
 switch (addr) {
+case VERSION_REG:
+return 0x11ULL;
 case FEATURE_REG:
 return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
1ULL << IOCSRF_CSRIPI;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index d60693fafe..e11c875188 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -28,6 +28,7 @@
 #define IOCSRF_GMOD 9
 #define IOCSRF_VM   11
 
+#define VERSION_REG 0x0
 #define FEATURE_REG 0x8
 #define VENDOR_REG  0x10
 #define CPUNAME_REG 0x20
-- 
2.31.1




[PULL 3/5] docs/system/loongarch: update loongson3.rst and rename it to virt.rst

2023-03-02 Thread Song Gao
Since the EDK2 had already support LoongArch, update build bios,
and update cpu type, cross-tools.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230227035905.1290953-1-gaos...@loongson.cn>
---
 .../loongarch/{loongson3.rst => virt.rst} | 97 ---
 1 file changed, 38 insertions(+), 59 deletions(-)
 rename docs/system/loongarch/{loongson3.rst => virt.rst} (51%)

diff --git a/docs/system/loongarch/loongson3.rst 
b/docs/system/loongarch/virt.rst
similarity index 51%
rename from docs/system/loongarch/loongson3.rst
rename to docs/system/loongarch/virt.rst
index 489ea20f8f..c37268b404 100644
--- a/docs/system/loongarch/loongson3.rst
+++ b/docs/system/loongarch/virt.rst
@@ -19,14 +19,14 @@ The ``virt`` machine supports:
 - Fw_cfg device
 - PCI/PCIe devices
 - Memory device
-- CPU device. Type: la464-loongarch-cpu.
+- CPU device. Type: la464.
 
 CPU and machine Type
 
 
 The ``qemu-system-loongarch64`` provides emulation for virt
 machine. You can specify the machine type ``virt`` and
-cpu type ``la464-loongarch-cpu``.
+cpu type ``la464``.
 
 Boot options
 
@@ -35,95 +35,74 @@ We can boot the LoongArch virt machine by specifying the 
uefi bios,
 initrd, and linux kernel. And those source codes and binary files
 can be accessed by following steps.
 
-(1) booting command:
+(1) Build qemu-system-loongarch64:
 
 .. code-block:: bash
 
-  $ qemu-system-loongarch64 -machine virt -m 4G -cpu la464-loongarch-cpu \
-  -smp 1 -bios QEMU_EFI.fd -kernel vmlinuz.efi -initrd initrd.img \
-  -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" \
-  --nographic
-
-Note: The running speed may be a little slow, as the performance of our
-qemu and uefi bios is not perfect, and it is being fixed.
-
-(2) cross compiler tools:
-
-.. code-block:: bash
-
-  wget https://github.com/loongson/build-tools/releases/download/ \
-  2022.05.29/loongarch64-clfs-5.0-cross-tools-gcc-full.tar.xz
-
-  tar -vxf loongarch64-clfs-5.0-cross-tools-gcc-full.tar.xz
-
-(3) qemu compile configure option:
-
-.. code-block:: bash
-
-  ./configure --disable-rdma --disable-pvrdma --prefix=usr \
+  ./configure --disable-rdma --disable-pvrdma --prefix=/usr \
   --target-list="loongarch64-softmmu" \
   --disable-libiscsi --disable-libnfs --disable-libpmem \
   --disable-glusterfs --enable-libusb --enable-usb-redir \
   --disable-opengl --disable-xen --enable-spice \
   --enable-debug --disable-capstone --disable-kvm \
   --enable-profiler
-  make
+  make -j8
 
-(4) uefi bios source code and compile method:
+(2) Set cross tools:
 
 .. code-block:: bash
 
-  git clone https://github.com/loongson/edk2-LoongarchVirt.git
-
-  cd edk2-LoongarchVirt
-
-  git submodule update --init
-
-  export PATH=$YOUR_COMPILER_PATH/bin:$PATH
-
-  export WORKSPACE=`pwd`
+  wget 
https://github.com/loongson/build-tools/releases/download/2022.09.06/loongarch64-clfs-6.3-cross-tools-gcc-glibc.tar.xz
 
-  export PACKAGES_PATH=$WORKSPACE/edk2-LoongarchVirt
+  tar -vxf loongarch64-clfs-6.3-cross-tools-gcc-glibc.tar.xz  -C /opt
 
-  export GCC5_LOONGARCH64_PREFIX=loongarch64-unknown-linux-gnu-
+  export PATH=/opt/cross-tools/bin:$PATH
+  export LD_LIBRARY_PATH=/opt/cross-tools/lib:$LD_LIBRARY_PATH
+  export 
LD_LIBRARY_PATH=/opt/cross-tools/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH
 
-  edk2-LoongarchVirt/edksetup.sh
+Note: You need get the latest cross-tools at 
https://github.com/loongson/build-tools
 
-  make -C edk2-LoongarchVirt/BaseTools
+(3) Build BIOS:
 
-  build --buildtarget=DEBUG --tagname=GCC5 --arch=LOONGARCH64  
--platform=OvmfPkg/LoongArchQemu/Loongson.dsc
+See: 
https://github.com/tianocore/edk2-platforms/tree/master/Platform/Loongson/LoongArchQemuPkg#readme
 
-  build --buildtarget=RELEASE --tagname=GCC5 --arch=LOONGARCH64  
--platform=OvmfPkg/LoongArchQemu/Loongson.dsc
+Note: To build the release version of the bios,  set --buildtarget=RELEASE,
+  the bios file path:  Build/LoongArchQemu/RELEASE_GCC5/FV/QEMU_EFI.fd
 
-The efi binary file path:
-
-  Build/LoongArchQemu/DEBUG_GCC5/FV/QEMU_EFI.fd
-
-  Build/LoongArchQemu/RELEASE_GCC5/FV/QEMU_EFI.fd
-
-(5) linux kernel source code and compile method:
+(4) Build kernel:
 
 .. code-block:: bash
 
   git clone https://github.com/loongson/linux.git
 
-  export PATH=$YOUR_COMPILER_PATH/bin:$PATH
-
-  export LD_LIBRARY_PATH=$YOUR_COMPILER_PATH/lib:$LD_LIBRARY_PATH
+  cd linux
 
-  export 
LD_LIBRARY_PATH=$YOUR_COMPILER_PATH/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH
+  git checkout loongarch-next
 
   make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- 
loongson3_defconfig
 
-  make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu-
-
-  make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- install
-
-  make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- 
modules_install
+  make ARCH=loongarch 

[PULL 1/5] hw/loongarch/virt: rename PCH_PIC_IRQ_OFFSET with VIRT_GSI_BASE

2023-03-02 Thread Song Gao
From: Bibo Mao 

In theory gsi base can start from 0 on loongarch virt machine,
however gsi base is hard-coded in linux kernel loongarch system,
else system fails to boot.

This patch renames macro PCH_PIC_IRQ_OFFSET with VIRT_GSI_BASE,
keeps value unchanged. GSI base is common concept in acpi spec
and easy to understand.

Signed-off-by: Bibo Mao 
Reviewed-by: Song Gao 
Message-Id: <20221228030719.991878-1-maob...@loongson.cn>
Signed-off-by: Song Gao 
---
 hw/loongarch/acpi-build.c  |  2 +-
 hw/loongarch/virt.c|  8 
 include/hw/pci-host/ls7a.h | 17 +
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index f551296a0e..8aed50e858 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -271,7 +271,7 @@ static void build_pci_device_aml(Aml *scope, 
LoongArchMachineState *lams)
 .pio.size= VIRT_PCI_IO_SIZE,
 .ecam.base   = VIRT_PCI_CFG_BASE,
 .ecam.size   = VIRT_PCI_CFG_SIZE,
-.irq = PCH_PIC_IRQ_OFFSET + VIRT_DEVICE_IRQS,
+.irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS,
 .bus = lams->pci_bus,
 };
 
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 66be925068..49d25059f8 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -432,7 +432,7 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic, 
LoongArchMachineState
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);
 
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
-   qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - 
PCH_PIC_IRQ_OFFSET));
+   qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - 
VIRT_GSI_BASE));
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 return dev;
 }
@@ -452,7 +452,7 @@ static DeviceState *create_platform_bus(DeviceState 
*pch_pic)
 
 sysbus = SYS_BUS_DEVICE(dev);
 for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) {
-irq = VIRT_PLATFORM_BUS_IRQ - PCH_PIC_IRQ_OFFSET + i;
+irq = VIRT_PLATFORM_BUS_IRQ - VIRT_GSI_BASE + i;
 sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(pch_pic, irq));
 }
 
@@ -509,7 +509,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
 
 serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
qdev_get_gpio_in(pch_pic,
-VIRT_UART_IRQ - PCH_PIC_IRQ_OFFSET),
+VIRT_UART_IRQ - VIRT_GSI_BASE),
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
 fdt_add_uart_node(lams);
 
@@ -531,7 +531,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
 create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
 sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
  qdev_get_gpio_in(pch_pic,
- VIRT_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
+ VIRT_RTC_IRQ - VIRT_GSI_BASE));
 fdt_add_rtc_node(lams);
 
 pm_mem = g_new(MemoryRegion, 1);
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index ff4b979912..e753449593 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -26,24 +26,25 @@
 #define VIRT_PCH_MSI_ADDR_LOW0x2FF0UL
 
 /*
- * According to the kernel pch irq start from 64 offset
- * 0 ~ 16 irqs used for non-pci device while 16 ~ 64 irqs
- * used for pci device.
+ * GSI_BASE is hard-coded with 64 in linux kernel, else kernel fails to boot
+ * 0  - 15  GSI for ISA devices even if there is no ISA devices
+ * 16 - 63  GSI for CPU devices such as timers/perf monitor etc
+ * 64 - GSI for external devices
  */
 #define VIRT_PCH_PIC_IRQ_NUM 32
-#define PCH_PIC_IRQ_OFFSET   64
+#define VIRT_GSI_BASE64
 #define VIRT_DEVICE_IRQS 16
-#define VIRT_UART_IRQ(PCH_PIC_IRQ_OFFSET + 2)
+#define VIRT_UART_IRQ(VIRT_GSI_BASE + 2)
 #define VIRT_UART_BASE   0x1fe001e0
 #define VIRT_UART_SIZE   0X100
-#define VIRT_RTC_IRQ (PCH_PIC_IRQ_OFFSET + 3)
+#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 3)
 #define VIRT_MISC_REG_BASE   (VIRT_PCH_REG_BASE + 0x0008)
 #define VIRT_RTC_REG_BASE(VIRT_MISC_REG_BASE + 0x00050100)
 #define VIRT_RTC_LEN 0x100
-#define VIRT_SCI_IRQ (PCH_PIC_IRQ_OFFSET + 4)
+#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 4)
 
 #define VIRT_PLATFORM_BUS_BASEADDRESS   0x1600
 #define VIRT_PLATFORM_BUS_SIZE  0x200
 #define VIRT_PLATFORM_BUS_NUM_IRQS  2
-#define VIRT_PLATFORM_BUS_IRQ   69
+#define VIRT_PLATFORM_BUS_IRQ   (VIRT_GSI_BASE + 5)
 #endif
-- 
2.31.1




[PATCH 3/6] Add the aehd-apic device type.

2023-03-02 Thread Haitao Shan
The aehd-apic device type represents the AEHD in kernel APIC.
The irqchips should be always in kernel when AEHD is used.

Signed-off-by: Haitao Shan 
---
 MAINTAINERS  |   2 +
 hw/i386/aehd/apic.c  | 204 +++
 hw/i386/aehd/meson.build |   4 +
 hw/i386/meson.build  |   1 +
 include/hw/core/cpu.h|   7 +
 include/sysemu/aehd.h|  52 ++
 target/i386/aehd/aehd-all.c  | 315 +++
 target/i386/aehd/aehd.c  |  88 ++
 target/i386/aehd/aehd_int.h  |  50 ++
 target/i386/aehd/meson.build |   4 +
 target/i386/cpu-sysemu.c |   3 +
 target/i386/meson.build  |   1 +
 12 files changed, 731 insertions(+)
 create mode 100644 hw/i386/aehd/apic.c
 create mode 100644 hw/i386/aehd/meson.build
 create mode 100644 target/i386/aehd/aehd-all.c
 create mode 100644 target/i386/aehd/aehd.c
 create mode 100644 target/i386/aehd/aehd_int.h
 create mode 100644 target/i386/aehd/meson.build

diff --git a/MAINTAINERS b/MAINTAINERS
index 54796da3b4..3db165dd9a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -535,6 +535,8 @@ W: 
https://github.com/google/android-emulator-hypervisor-driver
 S: Maintained
 F: include/sysemu/aehd-interface.h
 F: include/sysemu/aehd.h
+F: target/i386/aehd/
+F: hw/i386/aehd/
 
 Hosts
 -
diff --git a/hw/i386/aehd/apic.c b/hw/i386/aehd/apic.c
new file mode 100644
index 00..33a050ce11
--- /dev/null
+++ b/hw/i386/aehd/apic.c
@@ -0,0 +1,204 @@
+/*
+ * AEHD in-kernel APIC support
+ *
+ * Copyright (c) 2011 Siemens AG
+ *
+ * Authors:
+ *  Jan Kiszka  
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/i386/apic_internal.h"
+#include "hw/pci/msi.h"
+#include "sysemu/hw_accel.h"
+#include "sysemu/aehd.h"
+#include "sysemu/aehd-interface.h"
+
+static inline void aehd_apic_set_reg(struct aehd_lapic_state *aapic,
+ int reg_id, uint32_t val)
+{
+*((uint32_t *)(aapic->regs + (reg_id << 4))) = val;
+}
+
+static inline uint32_t aehd_apic_get_reg(struct aehd_lapic_state *aapic,
+ int reg_id)
+{
+return *((uint32_t *)(aapic->regs + (reg_id << 4)));
+}
+
+void aehd_put_apic_state(DeviceState *dev, struct aehd_lapic_state *aapic)
+{
+APICCommonState *s = APIC_COMMON(dev);
+int i;
+
+memset(aapic, 0, sizeof(*aapic));
+aehd_apic_set_reg(aapic, 0x2, s->id << 24);
+aehd_apic_set_reg(aapic, 0x8, s->tpr);
+aehd_apic_set_reg(aapic, 0xd, s->log_dest << 24);
+aehd_apic_set_reg(aapic, 0xe, s->dest_mode << 28 | 0x0fff);
+aehd_apic_set_reg(aapic, 0xf, s->spurious_vec);
+for (i = 0; i < 8; i++) {
+aehd_apic_set_reg(aapic, 0x10 + i, s->isr[i]);
+aehd_apic_set_reg(aapic, 0x18 + i, s->tmr[i]);
+aehd_apic_set_reg(aapic, 0x20 + i, s->irr[i]);
+}
+aehd_apic_set_reg(aapic, 0x28, s->esr);
+aehd_apic_set_reg(aapic, 0x30, s->icr[0]);
+aehd_apic_set_reg(aapic, 0x31, s->icr[1]);
+for (i = 0; i < APIC_LVT_NB; i++) {
+aehd_apic_set_reg(aapic, 0x32 + i, s->lvt[i]);
+}
+aehd_apic_set_reg(aapic, 0x38, s->initial_count);
+aehd_apic_set_reg(aapic, 0x3e, s->divide_conf);
+}
+
+void aehd_get_apic_state(DeviceState *dev, struct aehd_lapic_state *aapic)
+{
+APICCommonState *s = APIC_COMMON(dev);
+int i, v;
+
+s->id = aehd_apic_get_reg(aapic, 0x2) >> 24;
+s->tpr = aehd_apic_get_reg(aapic, 0x8);
+s->arb_id = aehd_apic_get_reg(aapic, 0x9);
+s->log_dest = aehd_apic_get_reg(aapic, 0xd) >> 24;
+s->dest_mode = aehd_apic_get_reg(aapic, 0xe) >> 28;
+s->spurious_vec = aehd_apic_get_reg(aapic, 0xf);
+for (i = 0; i < 8; i++) {
+s->isr[i] = aehd_apic_get_reg(aapic, 0x10 + i);
+s->tmr[i] = aehd_apic_get_reg(aapic, 0x18 + i);
+s->irr[i] = aehd_apic_get_reg(aapic, 0x20 + i);
+}
+s->esr = aehd_apic_get_reg(aapic, 0x28);
+s->icr[0] = aehd_apic_get_reg(aapic, 0x30);
+s->icr[1] = aehd_apic_get_reg(aapic, 0x31);
+for (i = 0; i < APIC_LVT_NB; i++) {
+s->lvt[i] = aehd_apic_get_reg(aapic, 0x32 + i);
+}
+s->initial_count = aehd_apic_get_reg(aapic, 0x38);
+s->divide_conf = aehd_apic_get_reg(aapic, 0x3e);
+
+v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
+s->count_shift = (v + 1) & 7;
+
+s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+apic_next_timer(s, s->initial_count_load_time);
+}
+
+static void aehd_apic_set_base(APICCommonState *s, uint64_t val)
+{
+s->apicbase = val;
+}
+
+static void aehd_apic_set_tpr(APICCommonState *s, uint8_t val)
+{
+s->tpr = (val & 0x0f) << 4;
+}
+
+static uint8_t aehd_apic_get_tpr(APICCommonState *s)
+{
+return s->tpr >> 4;
+}
+
+static void aehd_apic_vapic_base_update(APICCommonState *s)
+{
+/* Not Implemented. This function is only for 

[PATCH 6/6] Add the AEHD implementation.

2023-03-02 Thread Haitao Shan
Implement the AEHD accelerator including the AEHD AccelClass,
AccelCPUClass, AccelOpsClass.

Signed-off-by: Haitao Shan 
---
 hw/i386/x86.c |2 +-
 include/exec/ram_addr.h   |2 -
 include/sysemu/aehd.h |   87 ++
 include/sysemu/hw_accel.h |1 +
 target/i386/aehd/aehd-accel-ops.c |  119 ++
 target/i386/aehd/aehd-accel-ops.h |   22 +
 target/i386/aehd/aehd-all.c   | 1020 +++
 target/i386/aehd/aehd-cpu.c   |  150 +++
 target/i386/aehd/aehd-cpu.h   |   41 +
 target/i386/aehd/aehd-stub.c  |   22 +
 target/i386/aehd/aehd.c   | 1915 +
 target/i386/aehd/aehd_i386.h  |   26 +
 target/i386/aehd/aehd_int.h   |2 +-
 target/i386/aehd/meson.build  |4 +
 target/i386/cpu.c |   12 +-
 target/i386/cpu.h |5 +-
 target/i386/helper.c  |3 +
 target/i386/meson.build   |1 +
 18 files changed, 3428 insertions(+), 6 deletions(-)
 create mode 100644 target/i386/aehd/aehd-accel-ops.c
 create mode 100644 target/i386/aehd/aehd-accel-ops.h
 create mode 100644 target/i386/aehd/aehd-cpu.c
 create mode 100644 target/i386/aehd/aehd-cpu.h
 create mode 100644 target/i386/aehd/aehd-stub.c
 create mode 100644 target/i386/aehd/aehd_i386.h

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index ffc6f97ce0..fdf090f25d 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1251,7 +1251,7 @@ bool x86_machine_is_smm_enabled(const X86MachineState 
*x86ms)
 return false;
 }
 
-if (tcg_enabled() || qtest_enabled()) {
+if (tcg_enabled() || aehd_enabled() || qtest_enabled()) {
 smm_available = true;
 } else if (kvm_enabled()) {
 smm_available = kvm_has_smm();
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index f4fb6a2111..4ff1745c30 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -332,7 +332,6 @@ static inline void 
cpu_physical_memory_set_dirty_range(ram_addr_t start,
 xen_hvm_modified_memory(start, length);
 }
 
-#if !defined(_WIN32)
 static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long 
*bitmap,
   ram_addr_t start,
   ram_addr_t pages)
@@ -424,7 +423,6 @@ static inline void 
cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
 }
 }
 }
-#endif /* not _WIN32 */
 
 bool cpu_physical_memory_test_and_clear_dirty(ram_addr_t start,
   ram_addr_t length,
diff --git a/include/sysemu/aehd.h b/include/sysemu/aehd.h
index 534dd95e3c..f5846ee27e 100644
--- a/include/sysemu/aehd.h
+++ b/include/sysemu/aehd.h
@@ -28,8 +28,17 @@
 # define CONFIG_AEHD_IS_POSSIBLE
 #endif
 
+#ifdef CONFIG_AEHD_IS_POSSIBLE
+
+extern bool aehd_allowed;
+#define aehd_enabled()   (aehd_allowed)
+
+#else /* !CONFIG_AEHD_IS_POSSIBLE */
+
 #define aehd_enabled()   (0)
 
+#endif /* !CONFIG_AEHD_IS_POSSIBLE */
+
 struct aehd_run;
 struct aehd_lapic_state;
 struct aehd_irq_routing_entry;
@@ -43,6 +52,9 @@ DECLARE_INSTANCE_CHECKER(AEHDState, AEHD_STATE,
 
 extern AEHDState *aehd_state;
 
+/* external API */
+bool aehd_has_free_slot(MachineState *ms);
+
 #ifdef NEED_CPU_H
 #include "cpu.h"
 
@@ -57,6 +69,40 @@ int aehd_vcpu_ioctl(CPUState *cpu, int type, void *input, 
size_t input_size,
 
 /* Arch specific hooks */
 
+void aehd_arch_pre_run(CPUState *cpu, struct aehd_run *run);
+MemTxAttrs aehd_arch_post_run(CPUState *cpu, struct aehd_run *run);
+
+int aehd_arch_handle_exit(CPUState *cpu, struct aehd_run *run);
+
+int aehd_arch_handle_ioapic_eoi(CPUState *cpu, struct aehd_run *run);
+
+int aehd_arch_process_async_events(CPUState *cpu);
+
+int aehd_arch_get_registers(CPUState *cpu);
+
+/* state subset only touched by the VCPU itself during runtime */
+#define AEHD_PUT_RUNTIME_STATE   1
+/* state subset modified during VCPU reset */
+#define AEHD_PUT_RESET_STATE 2
+/* full state set, modified during initialization or on vmload */
+#define AEHD_PUT_FULL_STATE  3
+
+int aehd_arch_put_registers(CPUState *cpu, int level);
+
+int aehd_arch_init(MachineState *ms, AEHDState *s);
+
+int aehd_arch_init_vcpu(CPUState *cpu);
+
+bool aehd_vcpu_id_is_valid(int vcpu_id);
+
+/* Returns VCPU ID to be used on AEHD_CREATE_VCPU ioctl() */
+unsigned long aehd_arch_vcpu_id(CPUState *cpu);
+
+void aehd_arch_init_irq_routing(AEHDState *s);
+
+int aehd_arch_fixup_msi_route(struct aehd_irq_routing_entry *route,
+  uint64_t address, uint32_t data, PCIDevice *dev);
+
 /* Notify arch about newly added MSI routes */
 int aehd_arch_add_msi_route_post(struct aehd_irq_routing_entry *route,
  int vector, PCIDevice *dev);
@@ -71,11 +117,52 @@ void aehd_irqchip_add_irq_route(AEHDState *s, int gsi, int 
irqchip, int pin);
 void aehd_put_apic_state(DeviceState *d, struct 

[PATCH 2/6] Add a few AEHD headers.

2023-03-02 Thread Haitao Shan
aehd-interface.h  AEHD DeviceIoControl Definitions
aehd.h    AEHD generic header with only aehd_enabled defined.
  To be expanded later by following patches.

Signed-off-by: Haitao Shan 
---
 MAINTAINERS |  10 +
 include/sysemu/aehd-interface.h | 878 
 include/sysemu/aehd.h   |  25 +
 3 files changed, 913 insertions(+)
 create mode 100644 include/sysemu/aehd-interface.h
 create mode 100644 include/sysemu/aehd.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 76662969d7..54796da3b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -526,6 +526,16 @@ S: Maintained
 F: include/sysemu/nvmm.h
 F: target/i386/nvmm/
 
+Guest CPU Cores (AEHD)
+-
+Android Emulator hypervisor driver CPU support
+M: Haitao Shan 
+L: emu-...@google.com
+W: https://github.com/google/android-emulator-hypervisor-driver
+S: Maintained
+F: include/sysemu/aehd-interface.h
+F: include/sysemu/aehd.h
+
 Hosts
 -
 LINUX
diff --git a/include/sysemu/aehd-interface.h b/include/sysemu/aehd-interface.h
new file mode 100644
index 00..f39ea62a3f
--- /dev/null
+++ b/include/sysemu/aehd-interface.h
@@ -0,0 +1,878 @@
+/*
+ * QEMU AEHD support
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   
+ *
+ * Copyright (c) 2017 Intel Corporation
+ *  Written by:
+ *  Haitao Shan 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef AEHD_INTERFACE_H
+#define AEHD_INTERFACE_H
+
+#ifdef _WIN32
+#include 
+#include 
+#include 
+#endif
+#include 
+#include 
+#include 
+#include 
+
+#define __u8 uint8_t
+#define __u16 uint16_t
+#define __u32 uint32_t
+#define __u64 uint64_t
+#define __s8 int8_t
+#define __s16 int16_t
+#define __s32 int32_t
+#define __s64 int64_t
+
+/*
+ * AEHD x86 specific structures and definitions
+ *
+ */
+
+#define DE_VECTOR 0
+#define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
+#define UD_VECTOR 6
+#define NM_VECTOR 7
+#define DF_VECTOR 8
+#define TS_VECTOR 10
+#define NP_VECTOR 11
+#define SS_VECTOR 12
+#define GP_VECTOR 13
+#define PF_VECTOR 14
+#define MF_VECTOR 16
+#define AC_VECTOR 17
+#define MC_VECTOR 18
+#define XM_VECTOR 19
+#define VE_VECTOR 20
+
+/* Architectural interrupt line count. */
+#define AEHD_NR_INTERRUPTS 256
+
+struct aehd_memory_alias {
+__u32 slot;/* this has a different namespace than memory slots */
+__u32 flags;
+__u64 guest_phys_addr;
+__u64 memory_size;
+__u64 target_phys_addr;
+};
+
+/* for AEHD_GET_IRQCHIP and AEHD_SET_IRQCHIP */
+struct aehd_pic_state {
+__u8 last_irr;  /* edge detection */
+__u8 irr;   /* interrupt request register */
+__u8 imr;   /* interrupt mask register */
+__u8 isr;   /* interrupt service register */
+__u8 priority_add;  /* highest irq priority */
+__u8 irq_base;
+__u8 read_reg_select;
+__u8 poll;
+__u8 special_mask;
+__u8 init_state;
+__u8 auto_eoi;
+__u8 rotate_on_auto_eoi;
+__u8 special_fully_nested_mode;
+__u8 init4; /* true if 4 byte init */
+__u8 elcr;  /* PIIX edge/trigger selection */
+__u8 elcr_mask;
+};
+
+#define AEHD_IOAPIC_NUM_PINS  24
+struct aehd_ioapic_state {
+__u64 base_address;
+__u32 ioregsel;
+__u32 id;
+__u32 irr;
+__u32 pad;
+union {
+__u64 bits;
+struct {
+__u8 vector;
+__u8 delivery_mode:3;
+__u8 dest_mode:1;
+__u8 delivery_status:1;
+__u8 polarity:1;
+__u8 remote_irr:1;
+__u8 trig_mode:1;
+__u8 mask:1;
+__u8 reserve:7;
+__u8 reserved[4];
+__u8 dest_id;
+} fields;
+} redirtbl[AEHD_IOAPIC_NUM_PINS];
+};
+
+#define AEHD_IRQCHIP_PIC_MASTER   0
+#define AEHD_IRQCHIP_PIC_SLAVE1
+#define AEHD_IRQCHIP_IOAPIC   2
+#define AEHD_NR_IRQCHIPS  3
+
+#define AEHD_RUN_X86_SMM  (1 << 0)
+
+/* for AEHD_GET_REGS and AEHD_SET_REGS */
+struct aehd_regs {
+/* out (AEHD_GET_REGS) / in (AEHD_SET_REGS) */
+__u64 rax, rbx, rcx, rdx;
+__u64 rsi, rdi, rsp, rbp;
+__u64 r8,  r9,  r10, r11;
+__u64 r12, r13, r14, r15;
+__u64 rip, rflags;
+};
+
+/* for AEHD_GET_LAPIC and AEHD_SET_LAPIC */
+#define AEHD_APIC_REG_SIZE 0x400
+struct aehd_lapic_state {
+char regs[AEHD_APIC_REG_SIZE];
+};
+
+struct aehd_segment {
+__u64 base;
+__u32 limit;
+__u16 selector;
+__u8  type;
+__u8  present, dpl, db, s, l, g, avl;
+__u8  unusable;
+__u8  padding;
+};
+
+struct aehd_dtable {
+__u64 base;
+__u16 limit;
+__u16 padding[3];
+};
+
+
+/* for AEHD_GET_SREGS and AEHD_SET_SREGS */
+struct aehd_sregs {
+/* out (AEHD_GET_SREGS) / in (AEHD_SET_SREGS) */
+struct aehd_segment cs, ds, es, fs, gs, ss;
+struct aehd_segment tr, ldt;
+struct aehd_dtable gdt, idt;
+

[PATCH 1/6] Add the Android Emulator hypervisor driver (AEHD) accelerator.

2023-03-02 Thread Haitao Shan
Add the configure support for the Android Emulator hypervisor driver
accelerator. The Android Emulator hypervisor driver is a Windows
driver made by porting the KVM from kernel 4.9-rc7.

Signed-off-by: Haitao Shan 
---
 accel/Kconfig  |  3 +++
 docs/about/build-platforms.rst |  2 +-
 include/exec/poison.h  |  1 +
 meson.build| 16 
 meson_options.txt  |  2 ++
 qemu-options.hx| 20 ++--
 scripts/meson-buildoptions.sh  |  2 ++
 7 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/accel/Kconfig b/accel/Kconfig
index 8bdedb7d15..187d8f6acf 100644
--- a/accel/Kconfig
+++ b/accel/Kconfig
@@ -16,6 +16,9 @@ config TCG
 config KVM
 bool
 
+config AEHD
+bool
+
 config XEN
 bool
 select FSDEV_9P if VIRTFS
diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst
index 20b97c3310..184707bd62 100644
--- a/docs/about/build-platforms.rst
+++ b/docs/about/build-platforms.rst
@@ -52,7 +52,7 @@ Those hosts are officially supported, with various 
accelerators:
* - SPARC
  - tcg
* - x86
- - hax, hvf (64 bit only), kvm, nvmm, tcg, whpx (64 bit only), xen
+ - aehd (64 bit only), hax, hvf (64 bit only), kvm, nvmm, tcg, whpx (64 
bit only), xen
 
 Other host architectures are not supported. It is possible to build QEMU system
 emulation on an unsupported host architecture using the configure
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 140daa4a85..cb851744d1 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -86,6 +86,7 @@
 #pragma GCC poison CONFIG_HVF
 #pragma GCC poison CONFIG_LINUX_USER
 #pragma GCC poison CONFIG_KVM
+#pragma GCC poison CONFIG_AEHD
 #pragma GCC poison CONFIG_SOFTMMU
 #pragma GCC poison CONFIG_WHPX
 #pragma GCC poison CONFIG_XEN
diff --git a/meson.build b/meson.build
index 77d2ae87e4..f2b049ceac 100644
--- a/meson.build
+++ b/meson.build
@@ -146,6 +146,11 @@ if cpu in ['x86', 'x86_64']
 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
   }
 endif
+if cpu in ['x86_64']
+  accelerator_targets += {
+'CONFIG_AEHD': ['i386-softmmu', 'x86_64-softmmu'],
+  }
+endif
 
 modular_tcg = []
 # Darwin does not support references to thread-local variables in modules
@@ -421,6 +426,13 @@ accelerators = []
 if get_option('kvm').allowed() and targetos == 'linux'
   accelerators += 'CONFIG_KVM'
 endif
+if get_option('aehd').allowed() and targetos == 'windows'
+  if get_option('aehd').enabled() and host_machine.cpu() != 'x86_64'
+error('AEHD requires 64-bit host')
+  else
+accelerators += 'CONFIG_AEHD'
+  endif
+endif
 if get_option('whpx').allowed() and targetos == 'windows'
   if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
 error('WHPX requires 64-bit host')
@@ -482,6 +494,9 @@ endif
 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
   error('KVM not available on this platform')
 endif
+if 'CONFIG_AEHD' not in accelerators and get_option('aehd').enabled()
+  error('AEHD not available on this platform')
+endif
 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
   error('HVF not available on this platform')
 endif
@@ -3873,6 +3888,7 @@ endif
 summary_info = {}
 if have_system
   summary_info += {'KVM support':   config_all.has_key('CONFIG_KVM')}
+  summary_info += {'AEHD support':  config_all.has_key('CONFIG_AEHD')}
   summary_info += {'HAX support':   config_all.has_key('CONFIG_HAX')}
   summary_info += {'HVF support':   config_all.has_key('CONFIG_HVF')}
   summary_info += {'WHPX support':  config_all.has_key('CONFIG_WHPX')}
diff --git a/meson_options.txt b/meson_options.txt
index fc9447d267..d3e9805b6d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -66,6 +66,8 @@ option('malloc', type : 'combo', choices : ['system', 
'tcmalloc', 'jemalloc'],
 
 option('kvm', type: 'feature', value: 'auto',
description: 'KVM acceleration support')
+option('aehd', type: 'feature', value: 'auto',
+   description: 'AEHD acceleration support')
 option('hax', type: 'feature', value: 'auto',
description: 'HAX acceleration support')
 option('whpx', type: 'feature', value: 'auto',
diff --git a/qemu-options.hx b/qemu-options.hx
index beeb4475ba..2870c54a43 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -26,7 +26,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
 "-machine [type=]name[,prop[=value][,...]]\n"
 "selects emulated machine ('-machine help' for list)\n"
 "property accel=accel1[:accel2[:...]] selects 
accelerator\n"
-"supported accelerators are kvm, xen, hax, hvf, nvmm, whpx 
or tcg (default: tcg)\n"
+"supported accelerators are kvm, xen, hax, hvf, nvmm, 
whpx, aehd or tcg (default: tcg)\n"
 "vmport=on|off|auto controls emulation of vmport (default: 
auto)\n"
 "dump-guest-core=on|off 

[PATCH 5/6] Add the aehd-i8259 device type.

2023-03-02 Thread Haitao Shan
The aehd-i8259 device type represents the AEHD in kernel PICs.
The irqchips should be always in kernel when AEHD is used.

Signed-off-by: Haitao Shan 
---
 hw/i386/aehd/i8259.c | 165 +++
 hw/i386/aehd/meson.build |   1 +
 hw/i386/pc.c |   2 +
 include/hw/intc/i8259.h  |   1 +
 4 files changed, 169 insertions(+)
 create mode 100644 hw/i386/aehd/i8259.c

diff --git a/hw/i386/aehd/i8259.c b/hw/i386/aehd/i8259.c
new file mode 100644
index 00..9a18e824dc
--- /dev/null
+++ b/hw/i386/aehd/i8259.c
@@ -0,0 +1,165 @@
+/*
+ * AEHD in-kernel PIC (i8259) support
+ *
+ * Copyright (c) 2011 Siemens AG
+ *
+ * Authors:
+ *  Jan Kiszka  
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "hw/isa/i8259_internal.h"
+#include "hw/i386/apic_internal.h"
+#include "sysemu/aehd.h"
+#include "sysemu/aehd-interface.h"
+
+#define TYPE_AEHD_I8259 "aehd-i8259"
+#define AEHD_PIC_CLASS(class) \
+OBJECT_CLASS_CHECK(AEHDPICClass, (class), TYPE_AEHD_I8259)
+#define AEHD_PIC_GET_CLASS(obj) \
+OBJECT_GET_CLASS(AEHDPICClass, (obj), TYPE_AEHD_I8259)
+
+/**
+ * AEHDPICClass:
+ * @parent_realize: The parent's realizefn.
+ */
+typedef struct AEHDPICClass {
+PICCommonClass parent_class;
+
+DeviceRealize parent_realize;
+} AEHDPICClass;
+
+static void aehd_pic_get(PICCommonState *s)
+{
+struct aehd_irqchip chip;
+struct aehd_pic_state *aepic;
+int ret;
+
+chip.chip_id = s->master ? AEHD_IRQCHIP_PIC_MASTER : 
AEHD_IRQCHIP_PIC_SLAVE;
+ret = aehd_vm_ioctl(aehd_state, AEHD_GET_IRQCHIP, , sizeof(chip),
+, sizeof(chip));
+if (ret < 0) {
+fprintf(stderr, "AEHD_GET_IRQCHIP failed: %s\n", strerror(ret));
+abort();
+}
+
+aepic = 
+
+s->last_irr = aepic->last_irr;
+s->irr = aepic->irr;
+s->imr = aepic->imr;
+s->isr = aepic->isr;
+s->priority_add = aepic->priority_add;
+s->irq_base = aepic->irq_base;
+s->read_reg_select = aepic->read_reg_select;
+s->poll = aepic->poll;
+s->special_mask = aepic->special_mask;
+s->init_state = aepic->init_state;
+s->auto_eoi = aepic->auto_eoi;
+s->rotate_on_auto_eoi = aepic->rotate_on_auto_eoi;
+s->special_fully_nested_mode = aepic->special_fully_nested_mode;
+s->init4 = aepic->init4;
+s->elcr = aepic->elcr;
+s->elcr_mask = aepic->elcr_mask;
+}
+
+static void aehd_pic_put(PICCommonState *s)
+{
+struct aehd_irqchip chip;
+struct aehd_pic_state *aepic;
+int ret;
+
+chip.chip_id = s->master ? AEHD_IRQCHIP_PIC_MASTER : 
AEHD_IRQCHIP_PIC_SLAVE;
+
+aepic = 
+
+aepic->last_irr = s->last_irr;
+aepic->irr = s->irr;
+aepic->imr = s->imr;
+aepic->isr = s->isr;
+aepic->priority_add = s->priority_add;
+aepic->irq_base = s->irq_base;
+aepic->read_reg_select = s->read_reg_select;
+aepic->poll = s->poll;
+aepic->special_mask = s->special_mask;
+aepic->init_state = s->init_state;
+aepic->auto_eoi = s->auto_eoi;
+aepic->rotate_on_auto_eoi = s->rotate_on_auto_eoi;
+aepic->special_fully_nested_mode = s->special_fully_nested_mode;
+aepic->init4 = s->init4;
+aepic->elcr = s->elcr;
+aepic->elcr_mask = s->elcr_mask;
+
+ret = aehd_vm_ioctl(aehd_state, AEHD_SET_IRQCHIP,
+, sizeof(chip), NULL, 0);
+if (ret < 0) {
+fprintf(stderr, "AEHD_GET_IRQCHIP failed: %s\n", strerror(ret));
+abort();
+}
+}
+
+static void aehd_pic_reset(DeviceState *dev)
+{
+PICCommonState *s = PIC_COMMON(dev);
+
+s->elcr = 0;
+pic_reset_common(s);
+
+aehd_pic_put(s);
+}
+
+static void aehd_pic_set_irq(void *opaque, int irq, int level)
+{
+pic_stat_update_irq(irq, level);
+aehd_set_irq(aehd_state, irq, level);
+}
+
+static void aehd_pic_realize(DeviceState *dev, Error **errp)
+{
+PICCommonState *s = PIC_COMMON(dev);
+AEHDPICClass *kpc = AEHD_PIC_GET_CLASS(dev);
+
+memory_region_init_io(>base_io, OBJECT(dev), NULL, NULL, "aehd-pic", 2);
+memory_region_init_io(>elcr_io, OBJECT(dev), NULL, NULL, "aehd-elcr", 
1);
+
+
+kpc->parent_realize(dev, errp);
+}
+
+qemu_irq *aehd_i8259_init(ISABus *bus)
+{
+i8259_init_chip(TYPE_AEHD_I8259, bus, true);
+i8259_init_chip(TYPE_AEHD_I8259, bus, false);
+
+return qemu_allocate_irqs(aehd_pic_set_irq, NULL, ISA_NUM_IRQS);
+}
+
+static void aehd_i8259_class_init(ObjectClass *klass, void *data)
+{
+AEHDPICClass *kpc = AEHD_PIC_CLASS(klass);
+PICCommonClass *k = PIC_COMMON_CLASS(klass);
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->reset = aehd_pic_reset;
+kpc->parent_realize = dc->realize;
+dc->realize   = aehd_pic_realize;
+k->pre_save   = aehd_pic_get;
+k->post_load  = aehd_pic_put;
+}
+
+static const TypeInfo aehd_i8259_info = {
+.name = TYPE_AEHD_I8259,
+.parent = TYPE_PIC_COMMON,
+

[PATCH 4/6] Add the aehd-ioapic device type.

2023-03-02 Thread Haitao Shan
The aehd-ioapic device type represents the AEHD in kernel IO-APIC.
The irqchips should be always in kernel when AEHD is used.

Signed-off-by: Haitao Shan 
---
 hw/i386/aehd/ioapic.c   | 164 
 hw/i386/aehd/meson.build|   1 +
 hw/i386/pc.c|   3 +
 hw/i386/x86.c   |   3 +
 include/hw/intc/ioapic.h|   1 +
 include/sysemu/aehd.h   |   4 +
 target/i386/aehd/aehd-all.c |  14 +++
 7 files changed, 190 insertions(+)
 create mode 100644 hw/i386/aehd/ioapic.c

diff --git a/hw/i386/aehd/ioapic.c b/hw/i386/aehd/ioapic.c
new file mode 100644
index 00..62ffb0172f
--- /dev/null
+++ b/hw/i386/aehd/ioapic.c
@@ -0,0 +1,164 @@
+/*
+ * AEHD in-kernel IOPIC support
+ *
+ * Copyright (c) 2011 Siemens AG
+ *
+ * Authors:
+ *  Jan Kiszka  
+ *
+ * This work is licensed under the terms of the GNU GPL version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "monitor/monitor.h"
+#include "hw/i386/pc.h"
+#include "hw/qdev-properties.h"
+#include "hw/intc/ioapic_internal.h"
+#include "sysemu/aehd.h"
+#include "sysemu/aehd-interface.h"
+
+/* PC Utility function */
+void aehd_pc_setup_irq_routing(bool pci_enabled)
+{
+AEHDState *s = aehd_state;
+int i;
+
+for (i = 0; i < 8; ++i) {
+if (i == 2) {
+continue;
+}
+aehd_irqchip_add_irq_route(s, i, AEHD_IRQCHIP_PIC_MASTER, i);
+}
+for (i = 8; i < 16; ++i) {
+aehd_irqchip_add_irq_route(s, i, AEHD_IRQCHIP_PIC_SLAVE, i - 8);
+}
+if (pci_enabled) {
+for (i = 0; i < 24; ++i) {
+if (i == 0) {
+aehd_irqchip_add_irq_route(s, i, AEHD_IRQCHIP_IOAPIC, 2);
+} else if (i != 2) {
+aehd_irqchip_add_irq_route(s, i, AEHD_IRQCHIP_IOAPIC, i);
+}
+}
+}
+aehd_irqchip_commit_routes(s);
+}
+
+typedef struct AEHDIOAPICState AEHDIOAPICState;
+
+struct AEHDIOAPICState {
+IOAPICCommonState ioapic;
+uint32_t aehd_gsi_base;
+};
+
+static void aehd_ioapic_get(IOAPICCommonState *s)
+{
+struct aehd_irqchip chip;
+struct aehd_ioapic_state *aioapic;
+int ret, i;
+
+chip.chip_id = AEHD_IRQCHIP_IOAPIC;
+ret = aehd_vm_ioctl(aehd_state, AEHD_GET_IRQCHIP, , sizeof(chip),
+, sizeof(chip));
+if (ret < 0) {
+fprintf(stderr, "AEHD_GET_IRQCHIP failed: %s\n", strerror(ret));
+abort();
+}
+
+aioapic = 
+
+s->id = aioapic->id;
+s->ioregsel = aioapic->ioregsel;
+s->irr = aioapic->irr;
+for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+s->ioredtbl[i] = aioapic->redirtbl[i].bits;
+}
+}
+
+static void aehd_ioapic_put(IOAPICCommonState *s)
+{
+struct aehd_irqchip chip;
+struct aehd_ioapic_state *aioapic;
+int ret, i;
+
+chip.chip_id = AEHD_IRQCHIP_IOAPIC;
+aioapic = 
+
+aioapic->id = s->id;
+aioapic->ioregsel = s->ioregsel;
+aioapic->base_address = s->busdev.mmio[0].addr;
+aioapic->irr = s->irr;
+for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+aioapic->redirtbl[i].bits = s->ioredtbl[i];
+}
+
+ret = aehd_vm_ioctl(aehd_state, AEHD_SET_IRQCHIP,
+, sizeof(chip), NULL, 0);
+if (ret < 0) {
+fprintf(stderr, "AEHD_GET_IRQCHIP failed: %s\n", strerror(ret));
+abort();
+}
+}
+
+static void aehd_ioapic_reset(DeviceState *dev)
+{
+IOAPICCommonState *s = IOAPIC_COMMON(dev);
+
+ioapic_reset_common(dev);
+aehd_ioapic_put(s);
+}
+
+static void aehd_ioapic_set_irq(void *opaque, int irq, int level)
+{
+AEHDIOAPICState *s = opaque;
+
+aehd_set_irq(aehd_state, s->aehd_gsi_base + irq, level);
+}
+
+static void aehd_ioapic_realize(DeviceState *dev, Error **errp)
+{
+IOAPICCommonState *s = IOAPIC_COMMON(dev);
+
+memory_region_init_io(>io_memory, OBJECT(dev), NULL, NULL,
+  "aehd-ioapic", 0x1000);
+
+/*
+ * AEHD ioapic only supports 0x11 now. This will only be used when
+ * we want to dump ioapic version.
+ */
+s->version = 0x11;
+
+qdev_init_gpio_in(dev, aehd_ioapic_set_irq, IOAPIC_NUM_PINS);
+}
+
+static Property aehd_ioapic_properties[] = {
+DEFINE_PROP_UINT32("gsi_base", AEHDIOAPICState, aehd_gsi_base, 0),
+DEFINE_PROP_END_OF_LIST()
+};
+
+static void aehd_ioapic_class_init(ObjectClass *klass, void *data)
+{
+IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+k->realize   = aehd_ioapic_realize;
+k->pre_save  = aehd_ioapic_get;
+k->post_load = aehd_ioapic_put;
+dc->reset= aehd_ioapic_reset;
+device_class_set_props(dc, aehd_ioapic_properties);
+}
+
+static const TypeInfo aehd_ioapic_info = {
+.name  = TYPE_AEHD_IOAPIC,
+.parent = TYPE_IOAPIC_COMMON,
+.instance_size = sizeof(AEHDIOAPICState),
+.class_init = aehd_ioapic_class_init,
+};
+
+static void aehd_ioapic_register_types(void)
+{
+

[PATCH 0/6] Adding the Android Emulator hypervisor driver accelerator

2023-03-02 Thread Haitao Shan
Hi, qemu maintainers and community members,

The following 6 patches implemented a new x86_64 CPU accelerator called
the Android Emulator hypervisor driver (AEHD).

The Android Emulator hypervisor driver is a hypervisor for Windows (7
or later), made by porting the KVM from the linux kernel 4.9-rc7. Its
initial purpose was to support the Android Emulator on the AMD
platforms as the old name "Android Emulator Hypervisor Driver for AMD
Processors" suggested. Despite the name, Intel processors have been
supported ever since its first release. Since Intel dropped HAXM support,
the android emulator is switching from HAXM to AEHD.
Refer to:
https://github.com/google/android-emulator-hypervisor-driver.

This patchset implements the user space support for the new
hypervisor. It was initially made by cloning and modifying the KVM
source codes. In order to support users who wanted to use the new
hypervisor to run generic OSes such as Windows and Ubuntu,  it was
periodically rebased to latest QEMU releases ever since QEMU v4.2.0.
Refer to: https://github.com/qemu-gvm/qemu-gvm.

Given that both the Windows driver and patched QEMU were out and
tested for a few years, we would like to see if we could submit our
work to the QEMU community. Users can have another choice of
hypervisor on Windows.

The patchset is tested on Windows 11 (64bit) with the AEHD 2.1 by
installing Ubuntu 22.04 and Windows 10 guests and playing with
savevm/loadvm. It is also tested on Linux (Ubuntu 22.04) and MacOS
(Intel and Apple Silicon), making sure it does not break others.

Any comments are welcome. Thanks!

Note:
The Android Emulator hypervisor driver will be maintained by
Google. However, there is no plan to rebase it to the latest KVM.

-- 
Haitao @Google



Re: [PATCH v3 6/6] hw/cxl: Add clear poison mailbox command support.

2023-03-02 Thread Ira Weiny
Jonathan Cameron wrote:
> Current implementation is very simple so many of the corner
> cases do not exist (e.g. fragmenting larger poison list entries)
> 
> Signed-off-by: Jonathan Cameron 
> ---
> v2:
> - Endian fix
> ---
>  hw/cxl/cxl-mailbox-utils.c  | 79 +
>  hw/mem/cxl_type3.c  | 36 +
>  include/hw/cxl/cxl_device.h |  1 +
>  3 files changed, 116 insertions(+)
> 
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index da8732a547..f2a339bedc 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -65,6 +65,7 @@ enum {
>  MEDIA_AND_POISON = 0x43,
>  #define GET_POISON_LIST0x0
>  #define INJECT_POISON  0x1
> +#define CLEAR_POISON   0x2
>  };
>  
>  /* 8.2.8.4.5.1 Command Return Codes */
> @@ -511,6 +512,82 @@ static CXLRetCode cmd_media_inject_poison(struct cxl_cmd 
> *cmd,
>  return CXL_MBOX_SUCCESS;
>  }
>  
> +static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
> + CXLDeviceState *cxl_dstate,
> + uint16_t *len)
> +{
> +CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> +CXLPoisonList *poison_list = >poison_list;
> +CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> +struct clear_poison_pl {
> +uint64_t dpa;
> +uint8_t data[64];
> +};
> +CXLPoison *ent;
> +uint64_t dpa;
> +
> +struct clear_poison_pl *in = (void *)cmd->payload;
> +
> +dpa = ldq_le_p(>dpa);
> +if (dpa + 64 > cxl_dstate->mem_size) {
> +return CXL_MBOX_INVALID_PA;
> +}
> +
> +QLIST_FOREACH(ent, poison_list, node) {

Because you are removing from the list I think this needs to be
QLIST_FOREACH_SAFE()? 

> +/*
> + * Test for contained in entry. Simpler than general case
> + * as clearing 64 bytes and entries 64 byte aligned
> + */
> +if ((dpa < ent->start) || (dpa >= ent->start + ent->length)) {
> +continue;
> +}
> +/* Do accounting early as we know one will go away */
> +ct3d->poison_list_cnt--;
> +if (dpa > ent->start) {
> +CXLPoison *frag;
> +if (ct3d->poison_list_cnt == CXL_POISON_LIST_LIMIT) {

I'm still not seeing how this is ever going to be true with the above
decrement?

> +cxl_set_poison_list_overflowed(ct3d);
> +break;
> +}
> +frag = g_new0(CXLPoison, 1);
> +
> +frag->start = ent->start;
> +frag->length = dpa - ent->start;
> +frag->type = ent->type;
> +
> +QLIST_INSERT_HEAD(poison_list, frag, node);
> +ct3d->poison_list_cnt++;
> +}
> +if (dpa + 64 < ent->start + ent->length) {
> +CXLPoison *frag;
> +
> +if (ct3d->poison_list_cnt == CXL_POISON_LIST_LIMIT) {

Or this one.

> +cxl_set_poison_list_overflowed(ct3d);
> +break;
> +}
> +
> +frag = g_new0(CXLPoison, 1);
> +
> +frag->start = dpa + 64;
> +frag->length = ent->start + ent->length - frag->start;
> +frag->type = ent->type;
> +QLIST_INSERT_HEAD(poison_list, frag, node);
> +ct3d->poison_list_cnt++;
> +}
> +/* Any fragments have been added, free original entry */
> +QLIST_REMOVE(ent, node);

I think the decrement needs to happen here.

> +g_free(ent);
> +break;
> +}
> +/* Clearing a region with no poison is not an error so always do so */
> +if (cvc->set_cacheline)
> +if (!cvc->set_cacheline(ct3d, dpa, in->data)) {
> +return CXL_MBOX_INTERNAL_ERROR;
> +}
> +
> +return CXL_MBOX_SUCCESS;
> +}
> +
>  #define IMMEDIATE_CONFIG_CHANGE (1 << 1)
>  #define IMMEDIATE_DATA_CHANGE (1 << 2)
>  #define IMMEDIATE_POLICY_CHANGE (1 << 3)
> @@ -542,6 +619,8 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
>  cmd_media_get_poison_list, 16, 0 },
>  [MEDIA_AND_POISON][INJECT_POISON] = { "MEDIA_AND_POISON_INJECT_POISON",
>  cmd_media_inject_poison, 8, 0 },
> +[MEDIA_AND_POISON][CLEAR_POISON] = { "MEDIA_AND_POISON_CLEAR_POISON",
> +cmd_media_clear_poison, 72, 0 },
>  };
>  
>  void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
> diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
> index 21e3a84785..44ffc7d9b0 100644
> --- a/hw/mem/cxl_type3.c
> +++ b/hw/mem/cxl_type3.c
> @@ -919,6 +919,41 @@ static void set_lsa(CXLType3Dev *ct3d, const void *buf, 
> uint64_t size,
>   */
>  }
>  
> +static bool set_cacheline(CXLType3Dev *ct3d, uint64_t dpa_offset, uint8_t 
> *data)
> +{
> +MemoryRegion *vmr = NULL, *pmr = NULL;
> +AddressSpace *as;
> +
> +if (ct3d->hostvmem) {
> +vmr = host_memory_backend_get_memory(ct3d->hostvmem);
> +}
> +if 

[PATCH v2] hw/loongarch/virt: add system_powerdown hmp command support

2023-03-02 Thread Song Gao
For loongarch virt machine, add powerdown notification callback
and send ACPI_POWER_DOWN_STATUS event by acpi ged. Also add
acpi dsdt table for ACPI_POWER_BUTTON_DEVICE device in this
patch.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Song Gao 
---
 hw/loongarch/acpi-build.c   |  1 +
 hw/loongarch/virt.c | 12 
 include/hw/loongarch/virt.h |  1 +
 3 files changed, 14 insertions(+)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 8aed50e858..6cb2472d33 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -260,6 +260,7 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
  AML_SYSTEM_MEMORY,
  VIRT_GED_MEM_ADDR);
 }
+acpi_dsdt_add_power_button(dsdt);
 }
 
 static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 49d25059f8..38ef7cc49f 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -316,6 +316,14 @@ static void virt_machine_done(Notifier *notifier, void 
*data)
 loongarch_acpi_setup(lams);
 }
 
+static void virt_powerdown_req(Notifier *notifier, void *opaque)
+{
+LoongArchMachineState *s = container_of(notifier,
+   LoongArchMachineState, powerdown_notifier);
+
+acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
+}
+
 struct memmap_entry {
 uint64_t address;
 uint64_t length;
@@ -859,6 +867,10 @@ static void loongarch_init(MachineState *machine)
VIRT_PLATFORM_BUS_IRQ);
 lams->machine_done.notify = virt_machine_done;
 qemu_add_machine_init_done_notifier(>machine_done);
+ /* connect powerdown request */
+lams->powerdown_notifier.notify = virt_powerdown_req;
+qemu_register_powerdown_notifier(>powerdown_notifier);
+
 fdt_add_pcie_node(lams);
 /*
  * Since lowmem region starts from 0 and Linux kernel legacy start address
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index f5f818894e..7ae8a91229 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -45,6 +45,7 @@ struct LoongArchMachineState {
 /* State for other subsystems/APIs: */
 FWCfgState  *fw_cfg;
 Notifier machine_done;
+Notifier powerdown_notifier;
 OnOffAutoacpi;
 char *oem_id;
 char *oem_table_id;
-- 
2.31.1




Re: [PATCH v2 6/6] gitlab-ci.d/crossbuilds: Drop the 32-bit arm system emulation jobs

2023-03-02 Thread Wilfred Mallawa
On Thu, 2023-03-02 at 17:31 +0100, Thomas Huth wrote:
> Hardly anybody still uses 32-bit arm environments for running QEMU,
> so let's stop wasting our scarce CI minutes with these jobs.
> 
> Signed-off-by: Thomas Huth 
> ---
>  .gitlab-ci.d/crossbuilds.yml | 14 --
>  1 file changed, 14 deletions(-)
Reviewed-by: Wilfred Mallawa 
> 
> diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-
> ci.d/crossbuilds.yml
> index 3ce51adf77..419b0c2fe1 100644
> --- a/.gitlab-ci.d/crossbuilds.yml
> +++ b/.gitlab-ci.d/crossbuilds.yml
> @@ -1,13 +1,6 @@
>  include:
>    - local: '/.gitlab-ci.d/crossbuild-template.yml'
>  
> -cross-armel-system:
> -  extends: .cross_system_build_job
> -  needs:
> -    job: armel-debian-cross-container
> -  variables:
> -    IMAGE: debian-armel-cross
> -
>  cross-armel-user:
>    extends: .cross_user_build_job
>    needs:
> @@ -15,13 +8,6 @@ cross-armel-user:
>    variables:
>  IMAGE: debian-armel-cross
>  
> -cross-armhf-system:
> -  extends: .cross_system_build_job
> -  needs:
> -    job: armhf-debian-cross-container
> -  variables:
> -    IMAGE: debian-armhf-cross
> -
>  cross-armhf-user:
>    extends: .cross_user_build_job
>    needs:



Re: [PATCH v2 5/6] docs/about/deprecated: Deprecate 32-bit arm hosts

2023-03-02 Thread Wilfred Mallawa
On Thu, 2023-03-02 at 17:31 +0100, Thomas Huth wrote:
> For running QEMU in system emulation mode, the user needs a rather
> strong host system, i.e. not only an embedded low-frequency
> controller.
> All recent beefy arm host machines should support 64-bit now, it's
> unlikely that anybody is still seriously using QEMU on a 32-bit arm
> CPU, so we deprecate the 32-bit arm hosts here to finally save use
> some time and precious CI minutes.
> 
> Signed-off-by: Thomas Huth 
> ---
>  docs/about/deprecated.rst | 9 +
>  1 file changed, 9 insertions(+)
Reviewed-by: Wilfred Mallawa 
> 
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 21ce70b5c9..c7113a7510 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -229,6 +229,15 @@ discontinue it. Since all recent x86 hardware
> from the past >10 years
>  is capable of the 64-bit x86 extensions, a corresponding 64-bit OS
>  should be used instead.
>  
> +System emulation on 32-bit arm hosts (since 8.0)
> +
> +
> +Since QEMU needs a strong host machine for running full system
> emulation, and
> +all recent powerful arm hosts support 64-bit, the QEMU project
> deprecates the
> +support for running any system emulation on 32-bit arm hosts in
> general. Use
> +64-bit arm hosts for system emulation instead. (Note: "user" mode
> emulation
> +continuous to be supported on 32-bit arm hosts, too)
> +
>  
>  QEMU API (QAPI) events
>  --



Re: [PATCH v2 4/6] docs/about/deprecated: Deprecate the qemu-system-arm binary

2023-03-02 Thread Wilfred Mallawa
On Thu, 2023-03-02 at 17:31 +0100, Thomas Huth wrote:
> qemu-system-aarch64 is a proper superset of qemu-system-arm,
> and the latter was mainly still required for 32-bit KVM support.
> But this 32-bit KVM arm support has been dropped in the Linux
> kernel a couple of years ago already, so we don't really need
> qemu-system-arm anymore, thus deprecated it now.
> 
> Signed-off-by: Thomas Huth 
> ---
>  docs/about/deprecated.rst | 10 ++
>  1 file changed, 10 insertions(+)
Reviewed-by: Wilfred Mallawa 
> 
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index a30aa8dfdf..21ce70b5c9 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -45,6 +45,16 @@ run 32-bit guests by selecting a 32-bit CPU model,
> including KVM support
>  on x86_64 hosts. Thus users are recommended to reconfigure their
> systems
>  to use the ``qemu-system-x86_64`` binary instead.
>  
> +``qemu-system-arm`` binary (since 8.0)
> +''
> +
> +``qemu-system-aarch64`` is a proper superset of ``qemu-system-arm``.
> The
> +latter was mainly a requirement for running KVM on 32-bit arm hosts,
> but
> +this 32-bit KVM support has been removed some years ago already
> (see:
> +
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/com
> mit/?id=541ad0150ca4
> +). Thus the QEMU project will drop the ``qemu-system-arm`` binary in
> a
> +future release. Use ``qemu-system-aarch64`` instead.
> +
>  
>  System emulator command line arguments
>  --



Re: [PATCH v2 3/6] gitlab-ci.d/crossbuilds: Drop the i386 jobs

2023-03-02 Thread Wilfred Mallawa
On Thu, 2023-03-02 at 17:31 +0100, Thomas Huth wrote:
> Hardly anybody still uses 32-bit x86 environments for running QEMU,
> so let's stop wasting our scarce CI minutes with these jobs.
> 
> Signed-off-by: Thomas Huth 
> ---
>  .gitlab-ci.d/crossbuilds.yml | 16 
>  1 file changed, 16 deletions(-)
Reviewed-by: Wilfred Mallawa 
> 
> diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-
> ci.d/crossbuilds.yml
> index 101416080c..3ce51adf77 100644
> --- a/.gitlab-ci.d/crossbuilds.yml
> +++ b/.gitlab-ci.d/crossbuilds.yml
> @@ -43,22 +43,6 @@ cross-arm64-user:
>    variables:
>  IMAGE: debian-arm64-cross
>  
> -cross-i386-system:
> -  extends: .cross_system_build_job
> -  needs:
> -    job: i386-fedora-cross-container
> -  variables:
> -    IMAGE: fedora-i386-cross
> -    MAKE_CHECK_ARGS: check-qtest
> -
> -cross-i386-user:
> -  extends: .cross_user_build_job
> -  needs:
> -    job: i386-fedora-cross-container
> -  variables:
> -    IMAGE: fedora-i386-cross
> -    MAKE_CHECK_ARGS: check
> -
>  cross-i386-tci:
>    extends: .cross_accel_build_job
>    timeout: 60m



Re: [PATCH v2 2/6] docs/about/deprecated: Deprecate 32-bit x86 hosts

2023-03-02 Thread Wilfred Mallawa
On Thu, 2023-03-02 at 17:31 +0100, Thomas Huth wrote:
> Hardly anybody still uses 32-bit x86 hosts today, so we should start
> deprecating them to stop wasting our time and CI minutes here.
> For example, there are also still some unresolved problems with
> these:
> When emulating 64-bit binaries in user mode, TCG does not honor
> atomicity
> for 64-bit accesses, which is "perhaps worse than not working at all"
> (quoting Richard). Let's simply make it clear that people should use
> 64-bit x86 hosts nowadays and we do not intend to fix/maintain the
> old
> 32-bit stuff.
> 
> Signed-off-by: Thomas Huth 
> ---
>  docs/about/deprecated.rst | 12 
>  1 file changed, 12 insertions(+)
Reviewed-by: Wilfred Mallawa 
> 
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 11700adac9..a30aa8dfdf 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -208,6 +208,18 @@ CI coverage support may bitrot away before the
> deprecation process
>  completes. The little endian variants of MIPS (both 32 and 64 bit)
> are
>  still a supported host architecture.
>  
> +32-bit x86 hosts (since 8.0)
> +
> +
> +Support for 32-bit x86 host deployments is increasingly uncommon in
> +mainstream OS distributions given the widespread availability of 64-
> bit
> +x86 hardware. The QEMU project no longer considers 32-bit x86
> support
> +to be an effective use of its limited resources, and thus intends to
> +discontinue it. Since all recent x86 hardware from the past >10
> years
> +is capable of the 64-bit x86 extensions, a corresponding 64-bit OS
> +should be used instead.
> +
> +
>  QEMU API (QAPI) events
>  --
>  



Re: [PATCH v3 5/6] hw/cxl: Add poison injection via the mailbox.

2023-03-02 Thread Ira Weiny
Jonathan Cameron wrote:
> Very simple implementation to allow testing of corresponding
> kernel code. Note that for now we track each 64 byte section
> independently.  Whilst a valid implementation choice, it may
> make sense to fuse entries so as to prove out more complex
> corners of the kernel code.
> 
> Signed-off-by: Jonathan Cameron 

Reviewed-by: Ira Weiny 



Re: [PATCH v3 4/6] hw/cxl: QMP based poison injection support

2023-03-02 Thread Ira Weiny
Jonathan Cameron wrote:
> Inject poison using qmp command cxl-inject-poison to add an entry to the
> poison list.
> 
> For now, the poison is not returned CXL.mem reads, but only via the
> mailbox command Get Poison List.
> 
> See CXL rev 3.0, sec 8.2.9.8.4.1 Get Poison list (Opcode 4300h)
> 
> Kernel patches to use this interface here:
> https://lore.kernel.org/linux-cxl/cover.1665606782.git.alison.schofi...@intel.com/
> 
> To inject poison using qmp (telnet to the qmp port)
> { "execute": "qmp_capabilities" }
> 
> { "execute": "cxl-inject-poison",
> "arguments": {
>  "path": "/machine/peripheral/cxl-pmem0",
>  "start": 2048,
>  "length": 256
> }
> }
> 
> Adjusted to select a device on your machine.
> 
> Note that the poison list supported is kept short enough to avoid the
> complexity of state machine that is needed to handle the MORE flag.
> 
> Signed-off-by: Jonathan Cameron 
> 
> ---
> v2:
> Improve QMP documentation.
> Fix up some endian issues

[...]

> +/*
> + * This is very inefficient, but good enough for now!
> + * Also the payload will always fit, so no need to handle the MORE flag and
> + * make this stateful. We may want to allow longer poison lists to aid
> + * testing that kernel functionality.
> + */
> +static CXLRetCode cmd_media_get_poison_list(struct cxl_cmd *cmd,
> +CXLDeviceState *cxl_dstate,
> +uint16_t *len)
> +{
> +struct get_poison_list_pl {
> +uint64_t pa;
> +uint64_t length;
> +} QEMU_PACKED;
> +
> +struct get_poison_list_out_pl {
> +uint8_t flags;
> +uint8_t rsvd1;
> +uint64_t overflow_timestamp;
> +uint16_t count;
> +uint8_t rsvd2[0x14];
> +struct {
> +uint64_t addr;
> +uint32_t length;
> +uint32_t resv;
> +} QEMU_PACKED records[];
> +} QEMU_PACKED;
> +
> +struct get_poison_list_pl *in = (void *)cmd->payload;
> +struct get_poison_list_out_pl *out = (void *)cmd->payload;
> +CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> +uint16_t record_count = 0, i = 0;
> +uint64_t query_start, query_length;
> +CXLPoisonList *poison_list = >poison_list;
> +CXLPoison *ent;
> +uint16_t out_pl_len;
> +
> +query_start = ldq_le_p(>pa);
> +/* 64 byte alignemnt required */
> +if (query_start & 0x3f) {
> +return CXL_MBOX_INVALID_INPUT;
> +}
> +query_length = ldq_le_p(>length) * 64;
> +
> +QLIST_FOREACH(ent, poison_list, node) {
> +/* Check for no overlap */
> +if (ent->start >= query_start + query_length ||
> +ent->start + ent->length <= query_start) {
> +continue;
> +}
> +record_count++;
> +}
> +out_pl_len = sizeof(*out) + record_count * sizeof(out->records[0]);
> +assert(out_pl_len <= CXL_MAILBOX_MAX_PAYLOAD_SIZE);
> +
> +memset(out, 0, out_pl_len);
> +QLIST_FOREACH(ent, poison_list, node) {
> +uint64_t start, stop;
> +
> +/* Check for no overlap */
> +if (ent->start >= query_start + query_length ||
> +ent->start + ent->length <= query_start) {
> +continue;
> +}
> +
> +/* Deal with overlap */
> +start = MAX(ent->start & 0xffc0, query_start);
> +stop = MIN((ent->start & 0xffc0) + ent->length,
> +   query_start + query_length);
> +stq_le_p(>records[i].addr, start | (ent->type & 0x3));

Shouldn't the mask here be 0x7?  I see we have not define Vendor Specific
which I think is good but maybe better to allow it here?  I'm just not
sure what is going to happen if someone comes along later and wants to
use that value.

Ira

> +stl_le_p(>records[i].length, (stop - start) / 64);
> +i++;
> +}
> +if (ct3d->poison_list_overflowed) {
> +out->flags = (1 << 1);
> +stq_le_p(>overflow_timestamp, ct3d->poison_list_overflow_ts);
> +}
> +stw_le_p(>count, record_count);
> +*len = out_pl_len;
> +return CXL_MBOX_SUCCESS;
> +}
> +
>  #define IMMEDIATE_CONFIG_CHANGE (1 << 1)
>  #define IMMEDIATE_DATA_CHANGE (1 << 2)
>  #define IMMEDIATE_POLICY_CHANGE (1 << 3)
> @@ -411,6 +499,8 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
>  [CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 8, 0 },
>  [CCLS][SET_LSA] = { "CCLS_SET_LSA", cmd_ccls_set_lsa,
>  ~0, IMMEDIATE_CONFIG_CHANGE | IMMEDIATE_DATA_CHANGE },
> +[MEDIA_AND_POISON][GET_POISON_LIST] = { 
> "MEDIA_AND_POISON_GET_POISON_LIST",
> +cmd_media_get_poison_list, 16, 0 },
>  };
>  
>  void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
> diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
> index 572ad47fa2..21e3a84785 100644
> --- a/hw/mem/cxl_type3.c
> +++ b/hw/mem/cxl_type3.c
> @@ -919,6 +919,62 @@ static void set_lsa(CXLType3Dev *ct3d, const void *buf, 
> 

Re: [PATCH v2 1/6] docs/about/deprecated: Deprecate the qemu-system-i386 binary

2023-03-02 Thread Wilfred Mallawa
On Thu, 2023-03-02 at 18:05 +, Daniel P. Berrangé wrote:
> On Thu, Mar 02, 2023 at 05:31:01PM +0100, Thomas Huth wrote:
> > Hardly anybody really requires the i386 binary anymore, since the
> > qemu-system-x86_64 binary is a proper superset. So let's deprecate
> > the 32-bit variant now, so that we can finally stop wasting our
> > time
> > and CI minutes with this.
> 
> The first sentence isn't quite true wrt to KVM. Change slightly to:
> 
> Aside from not supporting KVM on 32-bit hosts, the qemu-system-x86_64
> binary is a proper superset of the qemu-system-i386 binary. With the
> 32-bit host support being deprecated, it is now also possible to
> deprecate the qemu-system-i386 binary.
> 
+1
> > With regards to 32-bit KVM support in the x86 Linux kernel,
> > the developers confirmed that they do not need a recent
> > qemu-system-i386 binary here:
> > 
> >  https://lore.kernel.org/kvm/y%2ffkts5ajfy0h...@google.com/
> > 
> > Signed-off-by: Thomas Huth 
> > ---
> >  docs/about/deprecated.rst | 12 
> >  1 file changed, 12 insertions(+)
> 
> Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Wilfred Mallawa 
> 
> 
> With regards,
> Daniel



Re: [RFC PATCH] gdbstub: attempt to split gdb into 32/64 bit targets [!WORKING PLZ HELP]

2023-03-02 Thread Richard Henderson

On 3/2/23 09:25, Alex Bennée wrote:

Instead of building gdb syscalls for every target only build what
really matters, 64 or 32 bit support.


Since the *only* usage of target_ulong is in the va_list for gdb_do_syscall, and as that 
passes on to printf, we could just adjust the interface to always pass uint64_t.



r~



Re: [PATCH v2 10/20] vfio/common: Record DMA mapped IOVA ranges

2023-03-02 Thread Joao Martins
On 02/03/2023 18:42, Alex Williamson wrote:
> On Thu, 2 Mar 2023 00:07:35 +
> Joao Martins  wrote:
>> On 28/02/2023 20:36, Alex Williamson wrote:
>>> On Tue, 28 Feb 2023 12:11:06 +
>>> Joao Martins  wrote:  
 On 23/02/2023 21:50, Alex Williamson wrote:  
> On Thu, 23 Feb 2023 21:19:12 +
> Joao Martins  wrote:
>> On 23/02/2023 21:05, Alex Williamson wrote:
>>> On Thu, 23 Feb 2023 10:37:10 +
>>> Joao Martins  wrote:  
 On 22/02/2023 22:10, Alex Williamson wrote:  
> On Wed, 22 Feb 2023 19:49:05 +0200
> Avihai Horon  wrote:
>> From: Joao Martins 
>> @@ -612,6 +665,16 @@ static int vfio_dma_map(VFIOContainer 
>> *container, hwaddr iova,
>>  .iova = iova,
>>  .size = size,
>>  };
>> +int ret;
>> +
>> +ret = vfio_record_mapping(container, iova, size, readonly);
>> +if (ret) {
>> +error_report("vfio: Failed to record mapping, iova: 0x%" 
>> HWADDR_PRIx
>> + ", size: 0x" RAM_ADDR_FMT ", ret: %d (%s)",
>> + iova, size, ret, strerror(-ret));
>> +
>> +return ret;
>> +}
>
> Is there no way to replay the mappings when a migration is started?
> This seems like a horrible latency and bloat trade-off for the
> possibility that the VM might migrate and the device might support
> these features.  Our performance with vIOMMU is already terrible, I
> can't help but believe this makes it worse.  Thanks,
> 

 It is a nop if the vIOMMU is being used (entries in 
 container->giommu_list) as
 that uses a max-iova based IOVA range. So this is really for iommu 
 identity
 mapping and no-VIOMMU.  
>>>
>>> Ok, yes, there are no mappings recorded for any containers that have a
>>> non-empty giommu_list.
>>>   
 We could replay them if they were tracked/stored anywhere.  
>>>
>>> Rather than piggybacking on vfio_memory_listener, why not simply
>>> register a new MemoryListener when migration is started?  That will
>>> replay all the existing ranges and allow tracking to happen separate
>>> from mapping, and only when needed.  
>>
>> The problem with that is that *starting* dirty tracking needs to have 
>> all the
>> range, we aren't supposed to start each range separately. So on a memory
>> listener callback you don't have introspection when you are dealing with 
>> the
>> last range, do we?
>
> As soon as memory_listener_register() returns, all your callbacks to
> build the IOVATree have been called and you can act on the result the
> same as if you were relying on the vfio mapping MemoryListener.  I'm
> not seeing the problem.  Thanks,
> 

 While doing these changes, the nice thing of the current patch is that 
 whatever
 changes apply to vfio_listener_region_add() will be reflected in the 
 mappings
 tree that stores what we will dirty track. If we move the mappings 
 calculation
 necessary for dirty tracking only when we start, we will have to duplicate 
 the
 same checks, and open for bugs where we ask things to be dirty track-ed 
 that
 haven't been DMA mapped. These two aren't necessarily tied, but felt like I
 should raise the potentially duplication of the checks (and the same thing
 applies for handling virtio-mem and what not).

 I understand that if we were going to store *a lot* of mappings that this 
 would
 add up in space requirements. But for no-vIOMMU (or iommu=pt) case this is 
 only
 about 12ranges or so, it is much simpler to piggyback the existing 
 listener.
 Would you still want to move this to its own dedicated memory listener?  
>>>
>>> Code duplication and bugs are good points, but while typically we're
>>> only seeing a few handfuls of ranges, doesn't virtio-mem in particular
>>> allow that we could be seeing quite a lot more?
>>>   
>> Ugh yes, it could be.
>>
>>> We used to be limited to a fairly small number of KVM memory slots,
>>> which effectively bounded non-vIOMMU DMA mappings, but that value is
>>> now 2^15, so we need to anticipate that we could see many more than a
>>> dozen mappings.
>>>   
>>
>> Even with 32k memory slots today we are still reduced on a handful. 
>> hv-balloon
>> and virtio-mem approaches though are the ones that may stress such limit IIUC
>> prior to starting migration.
>>
>>> Can we make the same argument that the overhead is negligible if a VM
>>> makes use of 10s of GB of virtio-mem with 2MB block size?
>>>
>>> But then on a 4KB host we're limited to 256 tracking entries, so
>>> wasting all that time and space on a runtime IOVATree is even more

Re: [PULL 35/53] chardev/char-socket: set s->listener = NULL in char_socket_finalize

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 02:49:56PM +0300, Michael Tokarev wrote:
> There are some url'ifications slipped into this one:
> 
> 02.03.2023 11:26, Michael S. Tsirkin пишет:
> ..
> 
> > Message-Id: <20230214021430.3638579-1-yaj...@nvidia.com>
> > Reviewed-by: Marc-André Lureau 
> > Signed-off-by: Yajun Wu mailto:yaj...@nvidia.com; 
> > target="_blank">yaj...@nvidia.com
> > Acked-by: Jiri Pirko mailto:j...@nvidia.com; 
> > target="_blank">j...@nvidia.comReviewed-by:
> >  Marc-André Lureau  > href="mailto:marcandre.lur...@redhat.com;>marcandre.lur...@redhat.com
> >  
> 
> 
> Thanks,
> 
> /mjt

Ugh yack. how did this happen - no idea.
Fixed now thanks!




Re: [PULL 31/53] pcie: set power indicator to off on reset by default

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 02:34:02PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> On 02.03.23 11:26, Michael S. Tsirkin wrote:
> > From: Vladimir Sementsov-Ogievskiy 
> > 
> > It should be zero, the only valid values are ON, OFF and BLINK.
> 
> At any chance, fix s/should be/should not be/

fixed now thanks!
> > 
> > Signed-off-by: Vladimir Sementsov-Ogievskiy 
> > Reviewed-by: Anton Kuchin 
> > Message-Id: <20230216180356.156832-13-vsement...@yandex-team.ru>
> > Reviewed-by: Michael S. Tsirkin 
> > Signed-off-by: Michael S. Tsirkin 
> > ---
> >   hw/pci/pcie.c | 1 +
> >   1 file changed, 1 insertion(+)
> > 
> > diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> > index 90faf0710a..b8c24cf45f 100644
> > --- a/hw/pci/pcie.c
> > +++ b/hw/pci/pcie.c
> > @@ -684,6 +684,7 @@ void pcie_cap_slot_reset(PCIDevice *dev)
> >PCI_EXP_SLTCTL_PDCE |
> >PCI_EXP_SLTCTL_ABPE);
> >   pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTCTL,
> > +   PCI_EXP_SLTCTL_PWR_IND_OFF |
> >  PCI_EXP_SLTCTL_ATTN_IND_OFF);
> >   if (dev->cap_present & QEMU_PCIE_SLTCAP_PCP) {
> 
> -- 
> Best regards,
> Vladimir




Re: [PULL 00/53] virtio,pc,pci: features, cleanups, fixes

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 03:24:28AM -0500, Michael S. Tsirkin wrote:
> The following changes since commit 627634031092e1514f363fd8659a579398de0f0e:
> 
>   Merge tag 'buildsys-qom-qdev-ui-20230227' of https://github.com/philmd/qemu 
> into staging (2023-02-28 15:09:18 +)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> 
> for you to fetch changes up to 65888be0d4da746e2f99930e21018d801bf8995e:


I re-pushed after fixing two commit log (same files):
commit ee92a56b08d0b59016a4a9bc1bf3a3de1fbe3956
now.

Thanks!


>   tests/data/acpi/virt: drop (most) duplicate files. (2023-03-02 03:16:26 
> -0500)
> 
> 
> virtio,pc,pci: features, cleanups, fixes
> 
> vhost-user support without ioeventfd
> word replacements in vhost user spec
> shpc improvements
> 
> cleanups, fixes all over the place
> 
> Signed-off-by: Michael S. Tsirkin 
> 
> 
> Akihiko Odaki (4):
>   vhost-user-gpio: Configure vhost_dev when connecting
>   vhost-user-i2c: Back up vqs before cleaning up vhost_dev
>   vhost-user-rng: Back up vqs before cleaning up vhost_dev
>   hw/timer/hpet: Fix expiration time overflow
> 
> Alex Bennée (1):
>   backends/vhost-user: remove the ioeventfd check
> 
> Carlos López (2):
>   vhost: avoid a potential use of an uninitialized variable in 
> vhost_svq_poll()
>   libvhost-user: check for NULL when allocating a virtqueue element
> 
> Dr. David Alan Gilbert (1):
>   virtio-rng-pci: fix transitional migration compat for vectors
> 
> Eugenio Pérez (2):
>   virtio-net: clear guest_announce feature if no cvq backend
>   vdpa: stop all svq on device deletion
> 
> Gregory Price (2):
>   hw/cxl: set cxl-type3 device type to PCI_CLASS_MEMORY_CXL
>   hw/cxl: Add CXL_CAPACITY_MULTIPLIER definition
> 
> Ira Weiny (3):
>   qemu/bswap: Add const_le64()
>   qemu/uuid: Add UUID static initializer
>   hw/cxl/mailbox: Use new UUID network order define for cel_uuid
> 
> Jason Wang (4):
>   intel-iommu: fail MAP notifier without caching mode
>   intel-iommu: fail DEVIOTLB_UNMAP without dt mode
>   memory: introduce memory_region_unmap_iommu_notifier_range()
>   smmu: switch to use memory_region_unmap_iommu_notifier_range()
> 
> Jonathan Cameron (6):
>   MAINTAINERS: Add Fan Ni as Compute eXpress Link QEMU reviewer
>   hw/mem/cxl_type3: Improve error handling in realize()
>   hw/pci-bridge/cxl_downstream: Fix type naming mismatch
>   tests/acpi: Allow update of q35/DSDT.cxl
>   hw/i386/acpi: Drop duplicate _UID entry for CXL root bridge
>   tests: acpi: Update q35/DSDT.cxl for removed duplicate UID
> 
> Julia Suvorova (1):
>   hw/smbios: fix field corruption in type 4 table
> 
> Maxime Coquelin (3):
>   docs: vhost-user: replace _SLAVE_ with _BACKEND_
>   libvhost-user: Adopt new backend naming
>   vhost-user: Adopt new backend naming
> 
> Michael S. Tsirkin (8):
>   Revert "x86: don't let decompressed kernel image clobber setup_data"
>   Revert "x86: do not re-randomize RNG seed on snapshot load"
>   Revert "x86: re-initialize RNG seed when selecting kernel"
>   Revert "x86: reinitialize RNG seed on system reboot"
>   Revert "x86: use typedef for SetupData struct"
>   Revert "x86: return modified setup_data only if read as memory, not as 
> file"
>   Revert "hw/i386: pass RNG seed via setup_data entry"
>   tests/data/acpi/virt: drop (most) duplicate files.
> 
> Peter Xu (1):
>   intel-iommu: send UNMAP notifications for domain or global inv desc
> 
> Philippe Mathieu-Daudé (1):
>   hw/pci: Trace IRQ routing on PCI topology
> 
> Vladimir Sementsov-Ogievskiy (12):
>   pci/shpc: set attention led to OFF on reset
>   pci/shpc: change shpc_get_status() return type to uint8_t
>   pci/shpc: shpc_slot_command(): handle PWRONLY -> ENABLED transition
>   pci/shpc: more generic handle hot-unplug in shpc_slot_command()
>   pci/shpc: pass PCIDevice pointer to shpc_slot_command()
>   pci/shpc: refactor shpc_device_plug_common()
>   pcie: pcie_cap_slot_write_config(): use correct macro
>   pcie_regs: drop duplicated indicator value macros
>   pcie: drop unused PCIExpressIndicator
>   pcie: pcie_cap_slot_enable_power() use correct helper
>   pcie: introduce pcie_sltctl_powered_off() helper
>   pcie: set power indicator to off on reset by default
> 
> Yajun Wu (1):
>   chardev/char-socket: set s->listener = NULL in char_socket_finalize
> 
> Zhenzhong Duan (1):
>   memory: Optimize replay of guest mapping
> 
>  include/exec/memory.h |  10 +++
>  include/hw/cxl/cxl_device.h   |   2 +-
>  include/hw/i386/microvm.h |   5 +-
>  include/hw/i386/pc.h  |   3 -
>  include/hw/i386/x86.h 

Re: [PATCH v3 00/18] hw/ide: Untangle ISA/PCI abuses of ide_init_ioport()

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 11:40:40PM +0100, Philippe Mathieu-Daudé wrote:
> Since v2: rebased
> 
> I'm posting this series as it to not block Bernhard's PIIX
> cleanup work. I don't have code change planned, but eventually
> reword / improve commit descriptions.
> 
> Tested commit after commit to be sure it is bisectable. Sadly
> this was before Zoltan & Thomas report a problem with commit
> bb98e0f59c ("hw/isa/vt82c686: Remove intermediate IRQ forwarder").
> 
> Background thread:
> https://lore.kernel.org/qemu-devel/5095dffc-309b-6c72-d255-8cdaa6fd3...@ilande.co.uk/


Acked-by: Michael S. Tsirkin 

who's merging this you?

I am unsure about interdependencies between all these patchsets at this
point.

> Philippe Mathieu-Daudé (18):
>   hw/ide/piix: Expose output IRQ as properties for late object
> population
>   hw/ide/piix: Allow using PIIX3-IDE as standalone PCI function
>   hw/i386/pc_piix: Wire PIIX3 IDE ouput IRQs to ISA bus IRQs 14/15
>   hw/isa/piix4: Wire PIIX4 IDE ouput IRQs to ISA bus IRQs 14/15
>   hw/ide: Rename ISA specific ide_init_ioport -> ide_bus_init_ioport_isa
>   hw/ide/piix: Ensure IDE output IRQs are wired at realization
>   hw/isa: Deprecate isa_get_irq() in favor of isa_bus_get_irq()
>   hw/ide: Introduce generic ide_init_ioport()
>   hw/ide/piix: Use generic ide_bus_init_ioport()
>   hw/isa: Ensure isa_register_portio_list() do not get NULL ISA device
>   hw/isa: Simplify isa_address_space[_io]()
>   hw/isa: Reduce 'isabus' singleton scope to isa_bus_new()
>   exec/ioport: Factor portio_list_register_flush_coalesced() out
>   exec/ioport: Factor portio_list_register() out
>   hw/southbridge/piix: Use OBJECT_DECLARE_SIMPLE_TYPE() macro
>   hw/isa/piix: Batch register QOM types using DEFINE_TYPES() macro
>   hw/isa/piix: Unify QOM type name of PIIX ISA function
>   hw/isa/piix: Unify PIIX-ISA QOM type names using qdev aliases
> 
>  hw/audio/adlib.c  |  4 +--
>  hw/display/qxl.c  |  7 ++--
>  hw/display/vga.c  |  9 +++--
>  hw/dma/i82374.c   |  7 ++--
>  hw/i386/pc_piix.c | 13 +---
>  hw/ide/ioport.c   | 15 +++--
>  hw/ide/isa.c  |  2 +-
>  hw/ide/piix.c | 54 +++---
>  hw/isa/isa-bus.c  | 36 
>  hw/isa/piix3.c| 63 +++
>  hw/isa/piix4.c| 12 ---
>  hw/mips/malta.c   |  2 +-
>  hw/watchdog/wdt_ib700.c   |  4 +--
>  include/exec/ioport.h | 15 +
>  include/hw/ide/internal.h |  3 +-
>  include/hw/ide/isa.h  |  3 ++
>  include/hw/ide/piix.h |  4 +++
>  include/hw/isa/isa.h  |  3 +-
>  include/hw/southbridge/piix.h | 14 
>  softmmu/ioport.c  | 48 +++---
>  softmmu/qdev-monitor.c|  3 ++
>  21 files changed, 190 insertions(+), 131 deletions(-)
> 
> -- 
> 2.38.1
> 
> 
> 




Re: [RFC PATCH] gdbstub: attempt to split gdb into 32/64 bit targets [!WORKING PLZ HELP]

2023-03-02 Thread Richard Henderson

On 3/2/23 13:21, Richard Henderson wrote:

On 3/2/23 09:25, Alex Bennée wrote:

-# These have to built to the target ABI
-specific_ss.add(files('syscalls.c'))
+# These have to built to the target ABI but are otherwise target
+# independent
+gdb32_ss = ss.source_set()
+gdb64_ss = ss.source_set()
+
+gdb32_ss.add(files('syscalls.c'))
+gdb64_ss.add(files('syscalls.c'))
+
+gdb32_ss = gdb32_ss.apply(config_host, strict: false)
+gdb64_ss = gdb64_ss.apply(config_host, strict: false)


You don't need the source sets.


+libgdb32 = static_library('gdb32', gdb32_ss.sources(),
+  name_suffix: 'fa',
+  c_args: ['-DTARGET_LONG_BITS=32'])
+libgdb64 = static_library('gdb64', gdb64_ss.sources(),
+  name_suffix: 'fa',
+  c_args: ['-DTARGET_LONG_BITS=64'])
+
+gdb32 = declare_dependency(link_whole: libgdb32)
+gdb64 = declare_dependency(link_whole: libgdb64)


It appears to work with "link_with:".

Both comments apply here and to your gdb_user/gdb_softmmu libraries.


Hmm.  It worked for qemu-system-aarch64, but not qemu-system-avr.
I'm at a bit of a loss...


r~




Re: [PATCH] vhost: accept VIRTIO_F_ORDER_PLATFORM as a valid SVQ feature

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 03:47:48PM +0100, Eugenio Perez Martin wrote:
> On Thu, Mar 2, 2023 at 12:43 PM Michael S. Tsirkin  wrote:
> >
> > On Thu, Mar 02, 2023 at 12:30:52PM +0100, Eugenio Perez Martin wrote:
> > > > You need to pass this to guest. My point is that there is no reason to
> > > > get it from the kernel driver. QEMU can figure out whether the flag is
> > > > needed itself.
> > > >
> > >
> > > Ok, I can see now how the HW device does not have all the knowledge to
> > > offer this flag or not. But I'm not sure how qemu can know either.
> > >
> > > If qemu opens /dev/vhost-vdpa-N, how can it know it? It has no way to
> > > tell if the device is sw or hw as far as I know. Am I missing
> > > something?
> > >
> > > Thanks!
> >
> > This is what I said earlier.  You can safely assume vdpa needs this
> > flag. Only exception is vduse and we don't care about performance there.
> >
> 
> Ok now I get your point, thanks for explaining.
> 
> But I'm missing why it is wrong to start using it properly from the
> kernel.
>
> I didn't test vDPA in non x86 / PCI, but if it does not work
> because of the lack of this feature flag the right fix would be to
> offer it, not to start assuming it in qemu, isn't it?
> 
> I can see how "assume VIRTIO_F_ORDER_PLATFORM from qemu" may need code
> comments and extra explanations, but to start offering it properly
> from the device is expected somehow.
> 
> Thanks!

Does kernel always expose it?

-- 
MST




Re: [PULL 00/53] virtio,pc,pci: features, cleanups, fixes

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 03:16:24PM +0300, Michael Tokarev wrote:
> 02.03.2023 11:24, Michael S. Tsirkin wrote:
> ..
> >https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> 
> It looks like this series contains quite a few changes which should be
> applied to -stable as well. Here are the ones which I think should be
> there, maybe others too:
> 
>  Julia Suvorova:
> hw/smbios: fix field corruption in type 4 table
> 
>  Michael S. Tsirkin:
> (Revert "x86: don't let decompressed kernel image clobber setup_data" 
> -- not in 7.2)
> Revert "x86: do not re-randomize RNG seed on snapshot load"
> Revert "x86: re-initialize RNG seed when selecting kernel"
> Revert "x86: reinitialize RNG seed on system reboot"
> Revert "x86: use typedef for SetupData struct"
> Revert "x86: return modified setup_data only if read as memory, not 
> as file"
> Revert "hw/i386: pass RNG seed via setup_data entry"
> 
>  Alex Bennée:
> backends/vhost-user: remove the ioeventfd check

not this one I think, it's a feature not a bugfix.

>  Akihiko Odaki:
> vhost-user-gpio: Configure vhost_dev when connecting
> vhost-user-i2c: Back up vqs before cleaning up vhost_dev
> vhost-user-rng: Back up vqs before cleaning up vhost_dev
> hw/timer/hpet: Fix expiration time overflow
> 
>  Dr. David Alan Gilbert (1):
> virtio-rng-pci: fix transitional migration compat for vectors
> 
> 
>  Eugenio Pérez:
> vdpa: stop all svq on device deletion
> 
>  Carlos López:
> vhost: avoid a potential use of an uninitialized variable in 
> vhost_svq_poll()
> libvhost-user: check for NULL when allocating a virtqueue element
> 
>  Yajun Wu:
>  chardev/char-socket: set s->listener = NULL in char_socket_finalize
> 
>  Jason Wang:
> intel-iommu: fail MAP notifier without caching mode
> intel-iommu: fail DEVIOTLB_UNMAP without dt mode


others ok

> 
> Does this make sense?
> 
> Thanks,
> 
> /mjt




Re: [RFC PATCH] gdbstub: attempt to split gdb into 32/64 bit targets [!WORKING PLZ HELP]

2023-03-02 Thread Richard Henderson

On 3/2/23 09:25, Alex Bennée wrote:

-# These have to built to the target ABI
-specific_ss.add(files('syscalls.c'))
+# These have to built to the target ABI but are otherwise target
+# independent
+gdb32_ss = ss.source_set()
+gdb64_ss = ss.source_set()
+
+gdb32_ss.add(files('syscalls.c'))
+gdb64_ss.add(files('syscalls.c'))
+
+gdb32_ss = gdb32_ss.apply(config_host, strict: false)
+gdb64_ss = gdb64_ss.apply(config_host, strict: false)


You don't need the source sets.


+libgdb32 = static_library('gdb32', gdb32_ss.sources(),
+  name_suffix: 'fa',
+  c_args: ['-DTARGET_LONG_BITS=32'])
+libgdb64 = static_library('gdb64', gdb64_ss.sources(),
+  name_suffix: 'fa',
+  c_args: ['-DTARGET_LONG_BITS=64'])
+
+gdb32 = declare_dependency(link_whole: libgdb32)
+gdb64 = declare_dependency(link_whole: libgdb64)


It appears to work with "link_with:".

Both comments apply here and to your gdb_user/gdb_softmmu libraries.


r~



Re: [PATCH 00/33] pci(pc/q35): acpi-index support on non-hotpluggable slots

2023-03-02 Thread Michael S. Tsirkin
On Thu, Mar 02, 2023 at 01:07:16PM +0100, Igor Mammedov wrote:
> On Thu, 2 Mar 2023 05:59:16 -0500
> "Michael S. Tsirkin"  wrote:
> 
> > On Fri, Feb 24, 2023 at 04:37:39PM +0100, Igor Mammedov wrote:
> > > Series extends acpi-index support to host-bridge(s) and bridges
> > > with disabled hotplug (either explicitly or implicitly).
> > > Whats new (it is still limited to 'pc' and 'q35' machines),
> > > acpi-index now works for non-hotpluggable slots/nics:
> > >  * q35: host-bridge
> > >  * pc: host-bridge with disabled hotplug
> > >'PIIX4_PM.acpi-root-pci-hotplug=off'
> > >  * non-hotpluggable multifunction nics
> > >  * on non-hotpluggable slots with native hotplug (i.e. without ACPI PCI 
> > > hotplug)
> > >PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off
> > >ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off
> > >  + pcie-root-port,hotplug=off | pci-bridge,shpc=off
> > > 
> > > where it doesn't work (and never will):
> > >  * on hotplugged ports/bridges
> > >  * on hotpluggable ports/bridges with native hotplug
> > > 
> > > 1-11/33:  fixes for bugs or odd behavior
> > > 13-23/33: non-hotplug/multifunction acpi-index enabling
> > > 28-33/33: cleanups 
> > > all of that is peppered by extra acpi tests or extensions to existing 
> > > ones  
> > 
> > dropped because viot was wrong.
> > Pls rebase fix up and repost.
> 
> I'll rebase on top of your recent pull req with c471eb4f4044 commit reverted
> to get properly updated tables.
> Partial table rebuilds are fragile anyways, should we make rebuild ignore
> checks the commit introduced?

Not sure how you mean.

> PS:
> Does the rest of the series look fine to you?

It does, was going to merge.

> 
> > 
> > 
> > Apropos I still think we should split up DSDT to several
> > SSDTs, in a way that multiple tests share some SSDTs.
> > This way it will be more common than a change only affects one table
> > and it's easier to merge things.
> > 
> > For example, how about moving CXL things to an SSDT?
> > 
> > 
> > > Somewhat tested with RHEL9.0 and WS2022.
> > > 
> > > What's in queue:
> > >  * PXB support 
> > >  * microvm and arm/virt support
> > > all of above only for non-hotpluggable slots as I don't really want to
> > > pull there complicated APCI PCI hotplug.
> > > 
> > > gitlab tree: 
> > > https://gitlab.com/imammedo/qemu/-/tree/acpi_index_non_hotplug
> > > CI: https://gitlab.com/imammedo/qemu/-/pipelines/787263630
> > >  it's red but only due to unrelated curl breakage in msys* targets,
> > >  the rest is green
> > > 
> > > Igor Mammedov (33):
> > >   tests: acpi: whitelist new q35.noacpihp test and pc.hpbrroot
> > >   tests: acpi: add test_acpi_q35_tcg_no_acpi_hotplug test and extend
> > > test_acpi_piix4_no_acpi_pci_hotplug
> > >   tests: acpi: update expected blobs
> > >   tests: acpi: whitelist q35/DSDT.multi-bridge before extending testcase
> > >   tests: acpi: extend multi-bridge case with case
> > > 'root-port,id=HOHP,hotplug=off root-port,bus=NOHP'
> > >   x86: pcihp: fix missing PCNT callchain when intermediate root-port has
> > > 'hotplug=off' set
> > >   tests: acpi: whitelist pc/DSDT.hpbrroot and pc/DSDT.hpbridge tests
> > >   x86: pcihp: fix missing bridge AML when intermediate root-port has
> > > 'hotplug=off' set
> > >   tests: acpi: update expected blobs
> > >   pcihp: piix4: do not redirect hotplug controller to piix4 when ACPI
> > > hotplug is disabled
> > >   pci: fix 'hotplugglable' property behavior
> > >   tests: acpi: whitelist DSDT blobs before isolating PCI _DSM func 0
> > > prolog
> > >   pcihp: move PCI _DSM function 0 prolog into separate function
> > >   tests: acpi: update expected blobs
> > >   tests: acpi: whitelist DSDT before adding EDSM method
> > >   acpi: pci: add EDSM method to DSDT
> > >   tests: acpi: update expected blobs
> > >   tests: acpi: whitelist DSDT before adding device with acpi-index to
> > > testcases
> > >   tests: acpi: add device with acpi-index on non-hotpluggble bus
> > >   acpi: pci: support acpi-index for non-hotpluggable devices
> > >   tests: acpi: update expected blobs
> > >   tests: acpi: whitelist DSDT before exposing non zero functions
> > >   acpi: pci: describe all functions on populated slots
> > >   tests: acpi: update expected blobs
> > >   tests: acpi: whitelist DSDT before adding non-0 function device with
> > > acpi-index to testcases
> > >   tests: acpi: add non zero function device with acpi-index on
> > > non-hotpluggble bus
> > >   tests: acpi: update expected blobs
> > >   pci: move acpi-index uniqueness check to generic PCI device code
> > >   acpi: pci: drop BSEL usage when deciding that device isn't
> > > hotpluggable
> > >   acpi: pci: move BSEL into build_append_pcihp_slots()
> > >   acpi: pci: move out ACPI PCI hotplug generator from generic slot
> > > generator build_append_pci_bus_devices()
> > >   pcihp: move fields enabling hotplug into AcpiPciHpState
> > >   pcihp: add ACPI PCI hotplug specific 

Re: [PULL v2 20/24] tests/docker: use direct RUNC call to build containers

2023-03-02 Thread Akihiro Suda
> No RUNC is defined in config-host.mak now because it can be docker or
podman.

I feel $(RUNC) isn't the right variable name as it can't be set to "runc".

If $(DOCKER) is not preferable either, $(CONTAINER_ENGINE) might be a
better name.
https://github.com/search?l=Makefile=%24%28CONTAINER_ENGINE%29=Code


2023年3月3日(金) 2:05 Alex Bennée :

>
> Akihiro Suda  writes:
>
> >> +   $(RUNC) build   \
> >
> > There is no `runc build` command.
> > Perhaps you meant `$(DOCKER) build`?
>
> No RUNC is defined in config-host.mak now because it can be docker or
> podman.
>
> >
> > Regards,
> > Akihiro Suda
>
>
> --
> Alex Bennée
> Virtualisation Tech Lead @ Linaro
>


[PATCH v3 17/18] hw/isa/piix: Unify QOM type name of PIIX ISA function

2023-03-02 Thread Philippe Mathieu-Daudé
Mechanical change doing:

  $ sed -i -e 's/PIIX4_PCI_DEVICE/PIIX4_ISA/g' $(git grep -l PIIX4_PCI_DEVICE)
  $ sed -i -e 's/PIIX3_XEN_DEVICE/PIIX3_ISA_XEN/g' $(git grep -l 
PIIX3_XEN_DEVICE)
  $ sed -i -e 's/PIIX3_DEVICE/PIIX3_ISA/g' $(git grep -l PIIX3_DEVICE)
  $ sed -i -e 's/PIIX3_PCI_DEVICE/PIIX_ISA/g' $(git grep -l PIIX3_PCI_DEVICE)

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc_piix.c |  5 ++---
 hw/isa/piix3.c| 20 ++--
 hw/isa/piix4.c| 10 +-
 hw/mips/malta.c   |  2 +-
 include/hw/southbridge/piix.h | 10 +-
 5 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1e90b9ff0d..c887b27009 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -221,8 +221,7 @@ static void pc_init1(MachineState *machine,
 if (pcmc->pci_enabled) {
 PIIX3State *piix3;
 PCIDevice *pci_dev;
-const char *type = xen_enabled() ? TYPE_PIIX3_XEN_DEVICE
- : TYPE_PIIX3_DEVICE;
+const char *type = xen_enabled() ? TYPE_PIIX3_ISA_XEN : TYPE_PIIX3_ISA;
 
 pci_bus = i440fx_init(pci_type,
   i440fx_host,
@@ -236,7 +235,7 @@ static void pc_init1(MachineState *machine,
 pcms->bus = pci_bus;
 
 pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, type);
-piix3 = PIIX3_PCI_DEVICE(pci_dev);
+piix3 = PIIX3_ISA(pci_dev);
 piix3->pic = x86ms->gsi;
 piix3_devfn = piix3->dev.devfn;
 isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 0ee94a2313..38e0c269ae 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -112,7 +112,7 @@ static void piix3_write_config(PCIDevice *dev,
 {
 pci_default_write_config(dev, address, val, len);
 if (ranges_overlap(address, len, PIIX_PIRQCA, 4)) {
-PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
+PIIX3State *piix3 = PIIX3_ISA(dev);
 int pic_irq;
 
 pci_bus_fire_intx_routing_notifier(pci_get_bus(>dev));
@@ -145,7 +145,7 @@ static void piix3_write_config_xen(PCIDevice *dev,
 
 static void piix3_reset(DeviceState *dev)
 {
-PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+PIIX3State *d = PIIX3_ISA(dev);
 uint8_t *pci_conf = d->dev.config;
 
 pci_conf[0x04] = 0x07; /* master, memory and I/O */
@@ -286,7 +286,7 @@ static const MemoryRegionOps rcr_ops = {
 
 static void pci_piix3_realize(PCIDevice *dev, Error **errp)
 {
-PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+PIIX3State *d = PIIX3_ISA(dev);
 ISABus *isa_bus;
 
 isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev),
@@ -349,7 +349,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 static void piix3_realize(PCIDevice *dev, Error **errp)
 {
 ERRP_GUARD();
-PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
+PIIX3State *piix3 = PIIX3_ISA(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
 
 pci_piix3_realize(dev, errp);
@@ -372,7 +372,7 @@ static void piix3_class_init(ObjectClass *klass, void *data)
 static void piix3_xen_realize(PCIDevice *dev, Error **errp)
 {
 ERRP_GUARD();
-PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
+PIIX3State *piix3 = PIIX3_ISA(dev);
 PCIBus *pci_bus = pci_get_bus(dev);
 
 pci_piix3_realize(dev, errp);
@@ -399,7 +399,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void 
*data)
 
 static const TypeInfo piix_isa_types[] = {
 {
-.name   = TYPE_PIIX3_PCI_DEVICE,
+.name   = TYPE_PIIX_ISA,
 .parent = TYPE_PCI_DEVICE,
 .instance_size  = sizeof(PIIX3State),
 .class_init = pci_piix3_class_init,
@@ -410,12 +410,12 @@ static const TypeInfo piix_isa_types[] = {
 { },
 },
 }, {
-.name   = TYPE_PIIX3_DEVICE,
-.parent = TYPE_PIIX3_PCI_DEVICE,
+.name   = TYPE_PIIX3_ISA,
+.parent = TYPE_PIIX_ISA,
 .class_init = piix3_class_init,
 }, {
-.name   = TYPE_PIIX3_XEN_DEVICE,
-.parent = TYPE_PIIX3_PCI_DEVICE,
+.name   = TYPE_PIIX3_ISA_XEN,
+.parent = TYPE_PIIX_ISA,
 .class_init = piix3_xen_class_init,
 }
 };
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 702b458a3e..90e19a4c37 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -56,7 +56,7 @@ struct PIIX4State {
 uint8_t rcr;
 };
 
-OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
+OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_ISA)
 
 static void piix4_set_irq(void *opaque, int irq_num, int level)
 {
@@ -81,7 +81,7 @@ static void piix4_set_irq(void *opaque, int irq_num, int 
level)
 
 static void piix4_isa_reset(DeviceState *dev)
 {
-PIIX4State *d = PIIX4_PCI_DEVICE(dev);
+PIIX4State *d = PIIX4_ISA(dev);
 uint8_t *pci_conf = d->dev.config;
 
 

[PATCH v3 03/18] hw/i386/pc_piix: Wire PIIX3 IDE ouput IRQs to ISA bus IRQs 14/15

2023-03-02 Thread Philippe Mathieu-Daudé
Since pc_init1() has access to the ISABus*, retrieve the
ISA IRQs with isa_bus_get_irq().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/i386/pc_piix.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 126b6c11df..1e90b9ff0d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -277,7 +277,13 @@ static void pc_init1(MachineState *machine,
 if (pcmc->pci_enabled) {
 PCIDevice *dev;
 
-dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE);
+dev = pci_new_multifunction(piix3_devfn + 1, false, TYPE_PIIX3_IDE);
+qdev_connect_gpio_out_named(DEVICE(dev), "ide-irq", 0,
+isa_bus_get_irq(isa_bus, 14));
+qdev_connect_gpio_out_named(DEVICE(dev), "ide-irq", 1,
+isa_bus_get_irq(isa_bus, 15));
+pci_realize_and_unref(dev, pci_bus, _fatal);
+
 pci_ide_create_devs(dev);
 idebus[0] = qdev_get_child_bus(>qdev, "ide.0");
 idebus[1] = qdev_get_child_bus(>qdev, "ide.1");
-- 
2.38.1




[PATCH v3 11/18] hw/isa: Simplify isa_address_space[_io]()

2023-03-02 Thread Philippe Mathieu-Daudé
We don't have any caller passing a NULL device argument,
so we can simplify, avoiding to access the global 'isabus'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/isa-bus.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 9c8224afa5..3036341d3b 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -252,20 +252,14 @@ static char *isabus_get_fw_dev_path(DeviceState *dev)
 
 MemoryRegion *isa_address_space(ISADevice *dev)
 {
-if (dev) {
-return isa_bus_from_device(dev)->address_space;
-}
-
-return isabus->address_space;
+assert(dev);
+return isa_bus_from_device(dev)->address_space;
 }
 
 MemoryRegion *isa_address_space_io(ISADevice *dev)
 {
-if (dev) {
-return isa_bus_from_device(dev)->address_space_io;
-}
-
-return isabus->address_space_io;
+assert(dev);
+return isa_bus_from_device(dev)->address_space_io;
 }
 
 type_init(isabus_register_types)
-- 
2.38.1




[PATCH v3 00/18] hw/ide: Untangle ISA/PCI abuses of ide_init_ioport()

2023-03-02 Thread Philippe Mathieu-Daudé
Since v2: rebased

I'm posting this series as it to not block Bernhard's PIIX
cleanup work. I don't have code change planned, but eventually
reword / improve commit descriptions.

Tested commit after commit to be sure it is bisectable. Sadly
this was before Zoltan & Thomas report a problem with commit
bb98e0f59c ("hw/isa/vt82c686: Remove intermediate IRQ forwarder").

Background thread:
https://lore.kernel.org/qemu-devel/5095dffc-309b-6c72-d255-8cdaa6fd3...@ilande.co.uk/

Philippe Mathieu-Daudé (18):
  hw/ide/piix: Expose output IRQ as properties for late object
population
  hw/ide/piix: Allow using PIIX3-IDE as standalone PCI function
  hw/i386/pc_piix: Wire PIIX3 IDE ouput IRQs to ISA bus IRQs 14/15
  hw/isa/piix4: Wire PIIX4 IDE ouput IRQs to ISA bus IRQs 14/15
  hw/ide: Rename ISA specific ide_init_ioport -> ide_bus_init_ioport_isa
  hw/ide/piix: Ensure IDE output IRQs are wired at realization
  hw/isa: Deprecate isa_get_irq() in favor of isa_bus_get_irq()
  hw/ide: Introduce generic ide_init_ioport()
  hw/ide/piix: Use generic ide_bus_init_ioport()
  hw/isa: Ensure isa_register_portio_list() do not get NULL ISA device
  hw/isa: Simplify isa_address_space[_io]()
  hw/isa: Reduce 'isabus' singleton scope to isa_bus_new()
  exec/ioport: Factor portio_list_register_flush_coalesced() out
  exec/ioport: Factor portio_list_register() out
  hw/southbridge/piix: Use OBJECT_DECLARE_SIMPLE_TYPE() macro
  hw/isa/piix: Batch register QOM types using DEFINE_TYPES() macro
  hw/isa/piix: Unify QOM type name of PIIX ISA function
  hw/isa/piix: Unify PIIX-ISA QOM type names using qdev aliases

 hw/audio/adlib.c  |  4 +--
 hw/display/qxl.c  |  7 ++--
 hw/display/vga.c  |  9 +++--
 hw/dma/i82374.c   |  7 ++--
 hw/i386/pc_piix.c | 13 +---
 hw/ide/ioport.c   | 15 +++--
 hw/ide/isa.c  |  2 +-
 hw/ide/piix.c | 54 +++---
 hw/isa/isa-bus.c  | 36 
 hw/isa/piix3.c| 63 +++
 hw/isa/piix4.c| 12 ---
 hw/mips/malta.c   |  2 +-
 hw/watchdog/wdt_ib700.c   |  4 +--
 include/exec/ioport.h | 15 +
 include/hw/ide/internal.h |  3 +-
 include/hw/ide/isa.h  |  3 ++
 include/hw/ide/piix.h |  4 +++
 include/hw/isa/isa.h  |  3 +-
 include/hw/southbridge/piix.h | 14 
 softmmu/ioport.c  | 48 +++---
 softmmu/qdev-monitor.c|  3 ++
 21 files changed, 190 insertions(+), 131 deletions(-)

-- 
2.38.1




[PATCH v3 05/18] hw/ide: Rename ISA specific ide_init_ioport -> ide_bus_init_ioport_isa

2023-03-02 Thread Philippe Mathieu-Daudé
Rename ide_init_ioport() as ide_bus_init_ioport_isa() to make
explicit it expects an ISA device. Move the declaration to
"hw/ide/isa.h" where it belongs.

Message-Id: <20230215161641.32663-13-phi...@linaro.org>
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/ioport.c   | 4 +++-
 hw/ide/isa.c  | 2 +-
 hw/ide/piix.c | 5 +++--
 include/hw/ide/internal.h | 1 -
 include/hw/ide/isa.h  | 3 +++
 5 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/hw/ide/ioport.c b/hw/ide/ioport.c
index e2ecc6230c..d869f8018a 100644
--- a/hw/ide/ioport.c
+++ b/hw/ide/ioport.c
@@ -25,6 +25,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/isa/isa.h"
+#include "hw/ide/isa.h"
 #include "hw/ide/internal.h"
 #include "trace.h"
 
@@ -40,7 +41,8 @@ static const MemoryRegionPortio ide_portio2_list[] = {
 PORTIO_END_OF_LIST(),
 };
 
-int ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
+int ide_bus_init_ioport_isa(IDEBus *bus, ISADevice *dev,
+int iobase, int iobase2)
 {
 int ret;
 
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 95053e026f..6eed16bf87 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -71,7 +71,7 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
 ISAIDEState *s = ISA_IDE(dev);
 
 ide_bus_init(>bus, sizeof(s->bus), dev, 0, 2);
-ide_init_ioport(>bus, isadev, s->iobase, s->iobase2);
+ide_bus_init_ioport_isa(>bus, isadev, s->iobase, s->iobase2);
 ide_bus_init_output_irq(>bus, isa_get_irq(isadev, s->irqnum));
 vmstate_register(VMSTATE_IF(dev), 0, _ide_isa, s);
 ide_bus_register_restart_cb(>bus);
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 7cb96ef67f..cb527553e2 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -33,6 +33,7 @@
 #include "hw/pci/pci.h"
 #include "hw/ide/piix.h"
 #include "hw/ide/pci.h"
+#include "hw/ide/isa.h"
 #include "trace.h"
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
@@ -142,8 +143,8 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, 
Error **errp)
 
 qemu_irq irq_out = d->isa_irq[i] ? : isa_get_irq(NULL, 
port_info[i].isairq);
 ide_bus_init(>bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
-ret = ide_init_ioport(>bus[i], NULL, port_info[i].iobase,
-  port_info[i].iobase2);
+ret = ide_bus_init_ioport_isa(>bus[i], NULL, port_info[i].iobase,
+  port_info[i].iobase2);
 if (ret) {
 error_setg_errno(errp, -ret, "Failed to realize %s port %u",
  object_get_typename(OBJECT(d)), i);
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
index d9f1f77dd5..d3b7fdc504 100644
--- a/include/hw/ide/internal.h
+++ b/include/hw/ide/internal.h
@@ -618,7 +618,6 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, 
IDEDriveKind kind,
int chs_trans, Error **errp);
 void ide_exit(IDEState *s);
 void ide_bus_init_output_irq(IDEBus *bus, qemu_irq irq_out);
-int ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
 void ide_bus_set_irq(IDEBus *bus);
 void ide_bus_register_restart_cb(IDEBus *bus);
 
diff --git a/include/hw/ide/isa.h b/include/hw/ide/isa.h
index 1cd0ff1fa6..7f7a850265 100644
--- a/include/hw/ide/isa.h
+++ b/include/hw/ide/isa.h
@@ -10,11 +10,14 @@
 #define HW_IDE_ISA_H
 
 #include "qom/object.h"
+#include "hw/ide/internal.h"
 
 #define TYPE_ISA_IDE "isa-ide"
 OBJECT_DECLARE_SIMPLE_TYPE(ISAIDEState, ISA_IDE)
 
 ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int irqnum,
 DriveInfo *hd0, DriveInfo *hd1);
+int ide_bus_init_ioport_isa(IDEBus *bus, ISADevice *isa,
+int iobase, int iobase2);
 
 #endif
-- 
2.38.1




[PATCH v3 13/18] exec/ioport: Factor portio_list_register_flush_coalesced() out

2023-03-02 Thread Philippe Mathieu-Daudé
We always follow the same pattern when registering
coalesced portio:

  - portio_list_init()
  - portio_list_set_flush_coalesced()
  - portio_list_add()

Factor these 3 operations in a single helper named
portio_list_register_flush_coalesced().

Drop portio_list_set_flush_coalesced() which is now
inlined.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20230207234615.77300-2-phi...@linaro.org>
---
 hw/display/qxl.c  |  7 +++
 hw/display/vga.c  |  5 ++---
 include/exec/ioport.h |  5 -
 softmmu/ioport.c  | 27 ++-
 4 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index ec712d3ca2..2ecaa0643f 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -2224,10 +2224,9 @@ static void qxl_realize_primary(PCIDevice *dev, Error 
**errp)
 }
 vga_init(vga, OBJECT(dev),
  pci_address_space(dev), pci_address_space_io(dev), false);
-portio_list_init(>vga_port_list, OBJECT(dev), qxl_vga_portio_list,
- vga, "vga");
-portio_list_set_flush_coalesced(>vga_port_list);
-portio_list_add(>vga_port_list, pci_address_space_io(dev), 0x3b0);
+portio_list_register_flush_coalesced(>vga_port_list, OBJECT(dev),
+ qxl_vga_portio_list, vga, "vga",
+ pci_address_space_io(dev), 0x3b0);
 qxl->have_vga = true;
 
 vga->con = graphic_console_init(DEVICE(dev), 0, _ops, qxl);
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 7a5fdff649..98d644922e 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -2309,9 +2309,8 @@ void vga_init(VGACommonState *s, Object *obj, 
MemoryRegion *address_space,
 1);
 memory_region_set_coalescing(vga_io_memory);
 if (init_vga_ports) {
-portio_list_init(>vga_port_list, obj, vga_ports, s, "vga");
-portio_list_set_flush_coalesced(>vga_port_list);
-portio_list_add(>vga_port_list, address_space_io, 0x3b0);
+portio_list_register_flush_coalesced(>vga_port_list, obj, vga_ports,
+ s, "vga", address_space_io, 
0x3b0);
 }
 if (vbe_ports) {
 portio_list_init(>vbe_port_list, obj, vbe_ports, s, "vbe");
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index e34f668998..eb9882a3ee 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -65,7 +65,10 @@ typedef struct PortioList {
 void portio_list_init(PortioList *piolist, Object *owner,
   const struct MemoryRegionPortio *callbacks,
   void *opaque, const char *name);
-void portio_list_set_flush_coalesced(PortioList *piolist);
+void portio_list_register_flush_coalesced(PortioList *piolist, Object *owner,
+  const MemoryRegionPortio *callbacks,
+  void *opaque, const char *name,
+  MemoryRegion *mr, uint32_t offset);
 void portio_list_destroy(PortioList *piolist);
 void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
diff --git a/softmmu/ioport.c b/softmmu/ioport.c
index cb8adb0b93..be0c920c5c 100644
--- a/softmmu/ioport.c
+++ b/softmmu/ioport.c
@@ -124,6 +124,7 @@ void portio_list_init(PortioList *piolist,
 ++n;
 }
 
+assert(owner);
 piolist->ports = callbacks;
 piolist->nr = 0;
 piolist->regions = g_new0(MemoryRegion *, n);
@@ -134,11 +135,6 @@ void portio_list_init(PortioList *piolist,
 piolist->flush_coalesced_mmio = false;
 }
 
-void portio_list_set_flush_coalesced(PortioList *piolist)
-{
-piolist->flush_coalesced_mmio = true;
-}
-
 void portio_list_destroy(PortioList *piolist)
 {
 MemoryRegionPortioList *mrpio;
@@ -297,3 +293,24 @@ void portio_list_del(PortioList *piolist)
 memory_region_del_subregion(piolist->address_space, >mr);
 }
 }
+
+static void do_portio_list_register(PortioList *piolist, Object *owner,
+const MemoryRegionPortio *callbacks,
+void *opaque, const char *name,
+MemoryRegion *mr, uint32_t offset,
+bool flush_coalesced_mmio)
+{
+assert(piolist && !piolist->owner);
+portio_list_init(piolist, owner, callbacks, opaque, name);
+piolist->flush_coalesced_mmio = flush_coalesced_mmio;
+portio_list_add(piolist, mr, offset);
+}
+
+void portio_list_register_flush_coalesced(PortioList *piolist, Object *owner,
+  const MemoryRegionPortio *callbacks,
+  void *opaque, const char *name,
+  MemoryRegion *mr, uint32_t offset)
+{
+do_portio_list_register(piolist, owner, callbacks,
+

[PATCH v3 01/18] hw/ide/piix: Expose output IRQ as properties for late object population

2023-03-02 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ide/piix.c | 14 --
 include/hw/ide/piix.h |  4 
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 41d60921e3..a36dac8469 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -121,6 +121,13 @@ static void piix_ide_reset(DeviceState *dev)
 pci_set_byte(pci_conf + 0x20, 0x01);  /* BMIBA: 20-23h */
 }
 
+static void piix_ide_initfn(Object *obj)
+{
+PCIIDEState *dev = PCI_IDE(obj);
+
+qdev_init_gpio_out_named(DEVICE(obj), dev->isa_irq, "ide-irq", 2);
+}
+
 static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, Error **errp)
 {
 static const struct {
@@ -133,6 +140,7 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, 
Error **errp)
 };
 int ret;
 
+qemu_irq irq_out = d->isa_irq[i] ? : isa_get_irq(NULL, 
port_info[i].isairq);
 ide_bus_init(>bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
 ret = ide_init_ioport(>bus[i], NULL, port_info[i].iobase,
   port_info[i].iobase2);
@@ -141,7 +149,7 @@ static bool pci_piix_init_bus(PCIIDEState *d, unsigned i, 
Error **errp)
  object_get_typename(OBJECT(d)), i);
 return false;
 }
-ide_bus_init_output_irq(>bus[i], isa_get_irq(NULL, 
port_info[i].isairq));
+ide_bus_init_output_irq(>bus[i], irq_out);
 
 bmdma_init(>bus[i], >bmdma[i], d);
 d->bmdma[i].bus = >bus[i];
@@ -162,7 +170,7 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error 
**errp)
 
 vmstate_register(VMSTATE_IF(dev), 0, _ide_pci, d);
 
-for (unsigned i = 0; i < 2; i++) {
+for (unsigned i = 0; i < ARRAY_SIZE(d->isa_irq); i++) {
 if (!pci_piix_init_bus(d, i, errp)) {
 return;
 }
@@ -199,6 +207,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void 
*data)
 static const TypeInfo piix3_ide_info = {
 .name  = TYPE_PIIX3_IDE,
 .parent= TYPE_PCI_IDE,
+.instance_init = piix_ide_initfn,
 .class_init= piix3_ide_class_init,
 };
 
@@ -221,6 +230,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void 
*data)
 static const TypeInfo piix4_ide_info = {
 .name  = TYPE_PIIX4_IDE,
 .parent= TYPE_PCI_IDE,
+.instance_init = piix_ide_initfn,
 .class_init= piix4_ide_class_init,
 };
 
diff --git a/include/hw/ide/piix.h b/include/hw/ide/piix.h
index ef3ef3d62d..533d24d408 100644
--- a/include/hw/ide/piix.h
+++ b/include/hw/ide/piix.h
@@ -1,6 +1,10 @@
 #ifndef HW_IDE_PIIX_H
 #define HW_IDE_PIIX_H
 
+/*
+ * QEMU interface:
+ *  + named GPIO outputs "ide-irq": asserted by each IDE channel
+ */
 #define TYPE_PIIX3_IDE "piix3-ide"
 #define TYPE_PIIX4_IDE "piix4-ide"
 
-- 
2.38.1




[PATCH v3 18/18] hw/isa/piix: Unify PIIX-ISA QOM type names using qdev aliases

2023-03-02 Thread Philippe Mathieu-Daudé
Unify PIIX ISA (PCI function #0) as:

 pci-piix3 -> piix-isa   (abstract base class)
 PIIX3 -> piix3-isa  (PIIX3 implementation)
 PIIX3-xen -> piix3-isa-xen  (PIIX3 implementation with Xen extensions)
 piix4-isa -> piix4-isa  (PIIX4 implementation)

Alias previous names in the QDevAlias table.

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/southbridge/piix.h | 6 +++---
 softmmu/qdev-monitor.c| 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 71a82ef266..cce65e8f44 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -58,9 +58,9 @@ struct PIIX3State {
 MemoryRegion rcr_mem;
 };
 
-#define TYPE_PIIX_ISA   "pci-piix3"
-#define TYPE_PIIX3_ISA  "PIIX3"
-#define TYPE_PIIX3_ISA_XEN  "PIIX3-xen"
+#define TYPE_PIIX_ISA   "piix-isa"
+#define TYPE_PIIX3_ISA  "piix3-isa"
+#define TYPE_PIIX3_ISA_XEN  "piix3-isa-xen"
 #define TYPE_PIIX4_ISA  "piix4-isa"
 
 OBJECT_DECLARE_SIMPLE_TYPE(PIIX3State, PIIX3_ISA)
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index b8d2c4dadd..820e7f52ad 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -72,6 +72,9 @@ static const QDevAlias qdev_alias_table[] = {
 { "ES1370", "es1370" }, /* -soundhw name */
 { "ich9-ahci", "ahci" },
 { "lsi53c895a", "lsi" },
+{ "piix-isa", "pci-piix3" },
+{ "piix3-isa", "PIIX3" },
+{ "piix3-isa-xen", "PIIX3-xen" },
 { "virtio-9p-device", "virtio-9p", QEMU_ARCH_VIRTIO_MMIO },
 { "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_VIRTIO_CCW },
 { "virtio-9p-pci", "virtio-9p", QEMU_ARCH_VIRTIO_PCI },
-- 
2.38.1




[PATCH v3 07/18] hw/isa: Deprecate isa_get_irq() in favor of isa_bus_get_irq()

2023-03-02 Thread Philippe Mathieu-Daudé
Last commit removed the last use of isa_get_irq(NULL).
Add an assertion to ensure we won't use that hack again.
Deprecate in favor of the BUS API: isa_bus_get_irq().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/isa-bus.c | 6 +++---
 include/hw/isa/isa.h | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index a289eccfb1..081bac18ee 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -85,10 +85,10 @@ qemu_irq isa_bus_get_irq(ISABus *bus, unsigned irqnum)
  * This function is only for special cases such as the 'ferr', and
  * temporary use for normal devices until they are converted to qdev.
  */
-qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq)
+qemu_irq isa_get_irq(ISADevice *dev, unsigned irqnum)
 {
-assert(!dev || ISA_BUS(qdev_get_parent_bus(DEVICE(dev))) == isabus);
-return isa_bus_get_irq(isabus, isairq);
+assert(dev);
+return isa_bus_get_irq(ISA_BUS(qdev_get_parent_bus(DEVICE(dev))), irqnum);
 }
 
 void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq)
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 40d6224a4e..75fb620782 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -87,7 +87,8 @@ ISADevice *isa_create_simple(ISABus *bus, const char *name);
 
 ISADevice *isa_vga_init(ISABus *bus);
 
-qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq);
+/*  isa_get_irq() is deprecated, please use isa_bus_get_irq() instead. */
+qemu_irq isa_get_irq(ISADevice *dev, unsigned irqnum);
 void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq);
 MemoryRegion *isa_address_space(ISADevice *dev);
 MemoryRegion *isa_address_space_io(ISADevice *dev);
-- 
2.38.1




[PATCH v3 14/18] exec/ioport: Factor portio_list_register() out

2023-03-02 Thread Philippe Mathieu-Daudé
We always follow the same pattern when registering
non-coalesced portio:

  - portio_list_init()
  - portio_list_add()

Factor these 2 operations in a single helper named
portio_list_register(). Since both calls become local
to ioport.c, reduce their scope by declaring them static.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20230207234615.77300-3-phi...@linaro.org>
---
 hw/audio/adlib.c|  4 ++--
 hw/display/vga.c|  4 ++--
 hw/dma/i82374.c |  7 +++
 hw/ide/ioport.c |  9 -
 hw/isa/isa-bus.c|  5 ++---
 hw/watchdog/wdt_ib700.c |  4 ++--
 include/exec/ioport.h   | 10 --
 softmmu/ioport.c| 21 ++---
 8 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index 5f979b1487..cc03c99306 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -291,8 +291,8 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
 
 adlib_portio_list[0].offset = s->port;
 adlib_portio_list[1].offset = s->port + 8;
-portio_list_init (>port_list, OBJECT(s), adlib_portio_list, s, "adlib");
-portio_list_add (>port_list, isa_address_space_io(>parent_obj), 0);
+portio_list_register(>port_list, OBJECT(s), adlib_portio_list, s,
+ "adlib", isa_address_space_io(>parent_obj), 0);
 }
 
 static Property adlib_properties[] = {
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 98d644922e..aa899fddc3 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -2313,7 +2313,7 @@ void vga_init(VGACommonState *s, Object *obj, 
MemoryRegion *address_space,
  s, "vga", address_space_io, 
0x3b0);
 }
 if (vbe_ports) {
-portio_list_init(>vbe_port_list, obj, vbe_ports, s, "vbe");
-portio_list_add(>vbe_port_list, address_space_io, 0x1ce);
+portio_list_register(>vbe_port_list, obj, vbe_ports, s,
+ "vbe", address_space_io, 0x1ce);
 }
 }
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index 63734c22c9..aeca0e8323 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -131,10 +131,9 @@ static void i82374_realize(DeviceState *dev, Error **errp)
 }
 i8257_dma_init(isa_bus, true);
 
-portio_list_init(>port_list, OBJECT(s), i82374_portio_list, s,
- "i82374");
-portio_list_add(>port_list, isa_address_space_io(>parent_obj),
-s->iobase);
+portio_list_register(>port_list, OBJECT(s), i82374_portio_list, s,
+ "i82374", isa_address_space_io(>parent_obj),
+ s->iobase);
 
 memset(s->commands, 0, sizeof(s->commands));
 }
diff --git a/hw/ide/ioport.c b/hw/ide/ioport.c
index ed7957dbae..7a6f29955f 100644
--- a/hw/ide/ioport.c
+++ b/hw/ide/ioport.c
@@ -60,9 +60,8 @@ int ide_bus_init_ioport_isa(IDEBus *bus, ISADevice *dev,
 void ide_bus_init_ioport(IDEBus *bus, Object *owner, MemoryRegion *io,
  int iobase, int iobase2)
 {
-portio_list_init(>portio_list, owner, ide_portio_list, bus, "ide");
-portio_list_add(>portio_list, io, iobase);
-
-portio_list_init(>portio2_list, owner, ide_portio2_list, bus, "ide");
-portio_list_add(>portio_list, io, iobase2);
+portio_list_register(>portio_list, owner, ide_portio_list,
+ bus, "ide", io, iobase);
+portio_list_register(>portio2_list, owner, ide_portio2_list,
+ bus, "ide", io, iobase2);
 }
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 8e3ca3785e..087293108e 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -130,15 +130,14 @@ int isa_register_portio_list(ISADevice *dev,
  void *opaque, const char *name)
 {
 assert(dev);
-assert(piolist && !piolist->owner);
 
 /* START is how we should treat DEV, regardless of the actual
contents of the portio array.  This is how the old code
actually handled e.g. the FDC device.  */
 isa_init_ioport(dev, start);
 
-portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name);
-portio_list_add(piolist, isa_address_space_io(dev), start);
+portio_list_register(piolist, OBJECT(dev), pio_start, opaque, name,
+ isa_address_space_io(dev), start);
 
 return 0;
 }
diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c
index b116c3a3aa..ac4f0be7d8 100644
--- a/hw/watchdog/wdt_ib700.c
+++ b/hw/watchdog/wdt_ib700.c
@@ -115,8 +115,8 @@ static void wdt_ib700_realize(DeviceState *dev, Error 
**errp)
 
 s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ib700_timer_expired, s);
 
-portio_list_init(>port_list, OBJECT(s), wdt_portio_list, s, "ib700");
-portio_list_add(>port_list, isa_address_space_io(>parent_obj), 0);
+portio_list_register(>port_list, OBJECT(s), wdt_portio_list, s,
+ "ib700", isa_address_space_io(>parent_obj), 0);
 }
 
 static 

[PATCH v3 16/18] hw/isa/piix: Batch register QOM types using DEFINE_TYPES() macro

2023-03-02 Thread Philippe Mathieu-Daudé
See rationale in commit 38b5d79b2e ("qom: add helper
macro DEFINE_TYPES()").

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/piix3.c | 53 +-
 1 file changed, 22 insertions(+), 31 deletions(-)

diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index a9cb39bf21..0ee94a2313 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -346,19 +346,6 @@ static void pci_piix3_class_init(ObjectClass *klass, void 
*data)
 adevc->build_dev_aml = build_pci_isa_aml;
 }
 
-static const TypeInfo piix3_pci_type_info = {
-.name = TYPE_PIIX3_PCI_DEVICE,
-.parent = TYPE_PCI_DEVICE,
-.instance_size = sizeof(PIIX3State),
-.abstract = true,
-.class_init = pci_piix3_class_init,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ TYPE_ACPI_DEV_AML_IF },
-{ },
-},
-};
-
 static void piix3_realize(PCIDevice *dev, Error **errp)
 {
 ERRP_GUARD();
@@ -382,12 +369,6 @@ static void piix3_class_init(ObjectClass *klass, void 
*data)
 k->realize = piix3_realize;
 }
 
-static const TypeInfo piix3_info = {
-.name  = TYPE_PIIX3_DEVICE,
-.parent= TYPE_PIIX3_PCI_DEVICE,
-.class_init= piix3_class_init,
-};
-
 static void piix3_xen_realize(PCIDevice *dev, Error **errp)
 {
 ERRP_GUARD();
@@ -416,17 +397,27 @@ static void piix3_xen_class_init(ObjectClass *klass, void 
*data)
 k->realize = piix3_xen_realize;
 }
 
-static const TypeInfo piix3_xen_info = {
-.name  = TYPE_PIIX3_XEN_DEVICE,
-.parent= TYPE_PIIX3_PCI_DEVICE,
-.class_init= piix3_xen_class_init,
+static const TypeInfo piix_isa_types[] = {
+{
+.name   = TYPE_PIIX3_PCI_DEVICE,
+.parent = TYPE_PCI_DEVICE,
+.instance_size  = sizeof(PIIX3State),
+.class_init = pci_piix3_class_init,
+.abstract   = true,
+.interfaces = (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ TYPE_ACPI_DEV_AML_IF },
+{ },
+},
+}, {
+.name   = TYPE_PIIX3_DEVICE,
+.parent = TYPE_PIIX3_PCI_DEVICE,
+.class_init = piix3_class_init,
+}, {
+.name   = TYPE_PIIX3_XEN_DEVICE,
+.parent = TYPE_PIIX3_PCI_DEVICE,
+.class_init = piix3_xen_class_init,
+}
 };
 
-static void piix3_register_types(void)
-{
-type_register_static(_pci_type_info);
-type_register_static(_info);
-type_register_static(_xen_info);
-}
-
-type_init(piix3_register_types)
+DEFINE_TYPES(piix_isa_types)
-- 
2.38.1




[PATCH v3 12/18] hw/isa: Reduce 'isabus' singleton scope to isa_bus_new()

2023-03-02 Thread Philippe Mathieu-Daudé
Previous commit ensured when entering isa_register_portio_list(),
'dev' is not NULL. Being a TYPE_ISA_DEVICE, the device must sit
on a ISA bus. This means isa_bus_new() as already been called
and 'isabus' can not be NULL.

Simplify by removing the 'isabus' NULL check in
isa_register_portio_list(). 'isabus' is now only used in
isa_bus_new(). Reduce its scope by only declaring it the
function using it (this will allows us to create multiple
ISA buses later).

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/isa/isa-bus.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 3036341d3b..8e3ca3785e 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -25,8 +25,6 @@
 #include "sysemu/sysemu.h"
 #include "hw/isa/isa.h"
 
-static ISABus *isabus;
-
 static char *isabus_get_fw_dev_path(DeviceState *dev);
 
 static void isa_bus_class_init(ObjectClass *klass, void *data)
@@ -52,6 +50,8 @@ static const TypeInfo isa_bus_info = {
 ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* address_space,
 MemoryRegion *address_space_io, Error **errp)
 {
+static ISABus *isabus;
+
 if (isabus) {
 error_setg(errp, "Can't create a second ISA bus");
 return NULL;
@@ -132,10 +132,6 @@ int isa_register_portio_list(ISADevice *dev,
 assert(dev);
 assert(piolist && !piolist->owner);
 
-if (!isabus) {
-return -ENODEV;
-}
-
 /* START is how we should treat DEV, regardless of the actual
contents of the portio array.  This is how the old code
actually handled e.g. the FDC device.  */
-- 
2.38.1




  1   2   3   4   5   6   7   >