Re: [PATCH 3/4] hw/cpu: Introduce CPUClass::cpu_resolving_type field
Hi Philippe, On 10/11/23 13:28, Philippe Mathieu-Daudé wrote: On 25/9/23 02:24, Gavin Shan wrote: On 9/12/23 08:40, Gavin Shan wrote: On 9/11/23 19:43, Philippe Mathieu-Daudé wrote: On 11/9/23 01:28, Gavin Shan wrote: On 9/8/23 21:22, Philippe Mathieu-Daudé wrote: Add a field to return the QOM type name of a CPU class. Signed-off-by: Philippe Mathieu-Daudé --- diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 129d179937..e469efd409 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -100,6 +100,7 @@ struct SysemuCPUOps; /** * CPUClass: + * @cpu_resolving_type: CPU QOM type name * @class_by_name: Callback to map -cpu command line model name to an * instantiatable CPU type. * @parse_features: Callback to parse command line arguments. @@ -148,6 +149,7 @@ struct CPUClass { DeviceClass parent_class; /*< public >*/ + const char *cpu_resolving_type; ObjectClass *(*class_by_name)(const char *cpu_model); void (*parse_features)(const char *typename, char *str, Error **errp); The question is why not use CPU_RESOLVING_TYPE directly? It seems CPU_RESOLVING_TYPE is exactly what you want here. Unfortunately CPU_RESOLVING_TYPE is target-specific, we want hw/core/cpu-common.c to be target-agnostic (build once for all targets). This is particularly important in the context of heterogeneous QEMU, where a single binary will be able to create CPUs from different targets. CPU_RESOLVING_TYPE and CPUClass::cpu_resolving_type is duplicate to each other. There are two options I can figure out to avoid the duplication. (a) move cpu_class_by_name() from hw/core/cpu-common.c to cpu.c, so that CPU_RESOLVING_TYPE can be seen. cpu.c::list_cpus() is the example. (b) remove hw/core/cpu-common.c::cpu_calss_by_name() and squeeze its logic to cpu.c::parse_cpu_option() since there are not too much users for it. target/arm and target/s390 needs some tweaks so that hw/core/cpu-common.c::cpu_calss_by_name() can be removed. [gshan@gshan q]$ git grep \ cpu_class_by_name\( cpu.c: oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]); target/arm/arm-qmp-cmds.c: oc = cpu_class_by_name(TYPE_ARM_CPU, model->name); target/s390x/cpu_models_sysemu.c: oc = cpu_class_by_name(TYPE_S390_CPU, info->name); When option (b) is taken, this series to have the checks against @oc in hw/core/cpu-common.c::cpu_calss_by_name() becomes non-sense. Instead, we need the same (and complete) checks in CPUClass::class_by_name() for individual targets. Further more, an inline helper can be provided to do the check in CPUClass::class_by_name() for individual targets. include/hw/core/cpu.h static inline bool cpu_class_is_valid(ObjectClass *oc, const char *parent) { if (!object_class_dynamic_cast(oc, parent) || object_class_is_abstract(oc)) { return false; } return true; } Since my series to make CPU type check unified depends on this series, could you please share your thoughts? If you don't have bandwidth for this, I can improve the code based on your thoughts, and include your patches to my series so that they can be reviewed at once. Please just let me know. You seem to prove (b) is not useful, so we have to do (a). Unfortunately at this moment I feel hopeless with this topic. I don't want to delay your work further. If you find a way to integrate both series, please go ahead. Otherwise let's drop my approach and continue with your previous work. I apologize I kept you waiting that long. Ah, nope, nothing went to wrong here. Thanks for your reply, I will try to follow (a) and integrate your patches to my series. Please help to review my series when it's posted :) Thanks, Gavin
Re: [PATCH v2 1/7] tap: Fix virtio-net header buffer size
On 2023/10/10 16:56, Michael Tokarev wrote: 10.10.2023 05:59, Akihiko Odaki wrote: The largest possible virtio-net header is struct virtio_net_hdr_v1_hash. Fixes: fbbdbddec0 ("tap: allow extended virtio header with hash info") Signed-off-by: Akihiko Odaki --- net/tap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tap.c b/net/tap.c index c6639d9f20..ea46feeaa8 100644 --- a/net/tap.c +++ b/net/tap.c @@ -118,7 +118,7 @@ static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov, TAPState *s = DO_UPCAST(TAPState, nc, nc); const struct iovec *iovp = iov; struct iovec iov_copy[iovcnt + 1]; - struct virtio_net_hdr_mrg_rxbuf hdr = { }; + struct virtio_net_hdr_v1_hash hdr = { }; BTW, can we get rid of (implicit) memzero() here and in similar places, initializing only the actually used fields? Not that his particular structure is very large (and this change makes it 8 bytes larger), but still.. These variables are rarely used so I think it's fine. In particular, these variables are used only when QEMU sends an ARP packet while virtio-net is enabled. Regards, Akihiko Odaki
[PULL 5/8] hw/audio/es1370: remove #ifdef ES1370_VERBOSE to avoid bit rot
From: Volker Rümelin Replace the #ifdef ES1370_VERBOSE code with code that the compiler can optimize away to avoid bit rot and fix the already rotten code. Tested-by: Rene Engel Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-5-vr_q...@t-online.de> --- hw/audio/es1370.c | 25 + 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index f111206709..7c58337076 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -23,7 +23,7 @@ */ #define DEBUG_ES1370 0 -/* #define VERBOSE_ES1370 */ +#define VERBOSE_ES1370 0 #include "qemu/osdep.h" #include "hw/audio/soundhw.h" @@ -238,11 +238,12 @@ static void print_sctl(uint32_t val) } } -#ifdef VERBOSE_ES1370 -#define lwarn(...) AUD_log ("es1370: warning", __VA_ARGS__) -#else -#define lwarn(...) -#endif +#define lwarn(...) \ +do { \ +if (VERBOSE_ES1370) { \ +AUD_log("es1370: warning", __VA_ARGS__); \ +} \ +} while (0) #define TYPE_ES1370 "ES1370" OBJECT_DECLARE_SIMPLE_TYPE(ES1370State, ES1370) @@ -504,10 +505,10 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) break; case ES1370_REG_PHANTOM_FRAMECNT: -lwarn ("writing to phantom frame count %#x\n", val); +lwarn("writing to phantom frame count 0x%" PRIx64 "\n", val); break; case ES1370_REG_PHANTOM_FRAMEADR: -lwarn ("writing to phantom frame address %#x\n", val); +lwarn("writing to phantom frame address 0x%" PRIx64 "\n", val); break; case ES1370_REG_ADC_FRAMECNT: @@ -524,7 +525,7 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) break; default: -lwarn ("writel %#x <- %#x\n", addr, val); +lwarn("writel 0x%" PRIx64 " <- 0x%" PRIx64 "\n", addr, val); break; } } @@ -588,16 +589,16 @@ static uint64_t es1370_read(void *opaque, hwaddr addr, unsigned size) case ES1370_REG_PHANTOM_FRAMECNT: val = ~0U; -lwarn ("reading from phantom frame count\n"); +lwarn("reading from phantom frame count\n"); break; case ES1370_REG_PHANTOM_FRAMEADR: val = ~0U; -lwarn ("reading from phantom frame address\n"); +lwarn("reading from phantom frame address\n"); break; default: val = ~0U; -lwarn ("readl %#x -> %#x\n", addr, val); +lwarn("readl 0x%" PRIx64 " -> 0x%x\n", addr, val); break; } return val; -- 2.41.0
[PULL 6/8] hw/audio/es1370: block structure coding style fixes
From: Volker Rümelin Change the block structure according to the QEMU Coding Style documentation. Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-6-vr_q...@t-online.de> --- hw/audio/es1370.c | 36 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 7c58337076..b4c00df189 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -309,8 +309,7 @@ static void es1370_update_status (ES1370State *s, uint32_t new_status) if (level) { s->status = new_status | STAT_INTR; -} -else { +} else { s->status = new_status & ~STAT_INTR; } pci_set_irq(&s->dev, !!level); @@ -333,8 +332,7 @@ static void es1370_reset (ES1370State *s) if (i == ADC_CHANNEL) { AUD_close_in (&s->card, s->adc_voice); s->adc_voice = NULL; -} -else { +} else { AUD_close_out (&s->card, s->dac_voice[i]); s->dac_voice[i] = NULL; } @@ -421,8 +419,7 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl) es1370_adc_callback, &as ); -} -else { +} else { s->dac_voice[i] = AUD_open_out ( &s->card, @@ -442,8 +439,7 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl) if (i == ADC_CHANNEL) { AUD_set_active_in (s->adc_voice, on); -} -else { +} else { AUD_set_active_out (s->dac_voice[i], on); } } @@ -456,8 +452,9 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl) static inline uint32_t es1370_fixup (ES1370State *s, uint32_t addr) { addr &= 0xff; -if (addr >= 0x30 && addr <= 0x3f) +if (addr >= 0x30 && addr <= 0x3f) { addr |= s->mempage << 8; +} return addr; } @@ -630,8 +627,9 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); acquired = AUD_read (s->adc_voice, tmpbuf, to_copy); -if (!acquired) +if (!acquired) { break; +} pci_dma_write (&s->dev, addr, tmpbuf, acquired); @@ -639,8 +637,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, addr += acquired; transferred += acquired; } -} -else { +} else { SWVoiceOut *voice = s->dac_voice[index]; while (temp > 0) { @@ -649,8 +646,9 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied = AUD_write (voice, tmpbuf, to_copy); -if (!copied) +if (!copied) { break; +} temp -= copied; addr += copied; transferred += copied; @@ -660,8 +658,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, if (csc_bytes == transferred) { *irq = 1; d->scount = sc | (sc << 16); -} -else { +} else { *irq = 0; d->scount = sc | (((csc_bytes - transferred - 1) >> d->shift) << 16); } @@ -672,12 +669,12 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, /* Bah, how stupid is that having a 0 represent true value? i just spent few hours on this shit */ AUD_log ("es1370: warning", "non looping mode\n"); -} -else { +} else { d->frame_cnt = size; -if ((uint32_t) cnt <= d->frame_cnt) +if ((uint32_t) cnt <= d->frame_cnt) { d->frame_cnt |= cnt << 16; +} } d->leftover = (transferred + d->leftover) & 3; @@ -778,8 +775,7 @@ static int es1370_post_load (void *opaque, int version_id) AUD_close_in (&s->card, s->adc_voice); s->adc_voice = NULL; } -} -else { +} else { if (s->dac_voice[i]) { AUD_close_out (&s->card, s->dac_voice[i]); s->dac_voice[i] = NULL; -- 2.41.0
Re: [PATCH 0/8] hw/audio/es1370: bug fix
Hi On Tue, Oct 10, 2023 at 4:26 PM BALATON Zoltan wrote: > > On Sun, 17 Sep 2023, Volker Rümelin wrote: > > Cc: qemu-stable. Patch 1/8 is a bug fix. > > Cc: more people. The maintainer of hw/audio is busy with other projects. > > > > Earlier this year I was asked if I could help to debug an audio playback > > speed issue with the es1370 device. While debugging the playback speed > > error, I noticed that the debug code of the ES1370 device has not been > > compiled for a long time and has bit-rotted. This patch series fixes the > > rotten code and also fixes a bug I found while debugging the code. The > > bug fix is in patch 1/8 and prevents corrupted data streams. The > > playback speed issue was caused by lost interrupts. Patch 8/8 helps to > > debug this kind of issues. > > > > Volker Rümelin (8): > > hw/audio/es1370: reset current sample counter > > hw/audio/es1370: replace bit-rotted code with tracepoints > > hw/audio/es1370: remove unused dolog macro > > hw/audio/es1370: remove #ifdef ES1370_DEBUG to avoid bit rot > > hw/audio/es1370: remove #ifdef ES1370_VERBOSE to avoid bit rot > > hw/audio/es1370: block structure coding style fixes > > hw/audio/es1370: change variable type and name > > hw/audio/es1370: trace lost interrupts > > > > hw/audio/es1370.c | 289 +++--- > > hw/audio/trace-events | 11 ++ > > 2 files changed, 143 insertions(+), 157 deletions(-) > > Tested-by: BALATON Zoltan > > The whole series also got a reirwed-by from Marc-Andre already so maybe > Gerd should have a look merging this. I am going to send a PR. thanks -- Marc-André Lureau
[PULL 7/8] hw/audio/es1370: change variable type and name
From: Volker Rümelin Change the type of the variable temp to size_t to avoid a type cast. While at it, rename the variable name to to_transfer. This improves the readability of the code. Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-7-vr_q...@t-online.de> --- hw/audio/es1370.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index b4c00df189..b47794f786 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -605,6 +605,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, int max, int *irq) { uint8_t tmpbuf[4096]; +size_t to_transfer; uint32_t addr = d->frame_addr; int sc = d->scount & 0x; int csc = d->scount >> 16; @@ -616,16 +617,16 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, } int left = ((size - cnt + 1) << 2) + d->leftover; int transferred = 0; -int temp = MIN (max, MIN (left, csc_bytes)); int index = d - &s->chan[0]; +to_transfer = MIN(max, MIN(left, csc_bytes)); addr += (cnt << 2) + d->leftover; if (index == ADC_CHANNEL) { -while (temp > 0) { +while (to_transfer > 0) { int acquired, to_copy; -to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); +to_copy = MIN(to_transfer, sizeof(tmpbuf)); acquired = AUD_read (s->adc_voice, tmpbuf, to_copy); if (!acquired) { break; @@ -633,23 +634,23 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, pci_dma_write (&s->dev, addr, tmpbuf, acquired); -temp -= acquired; +to_transfer -= acquired; addr += acquired; transferred += acquired; } } else { SWVoiceOut *voice = s->dac_voice[index]; -while (temp > 0) { +while (to_transfer > 0) { int copied, to_copy; -to_copy = MIN ((size_t) temp, sizeof (tmpbuf)); +to_copy = MIN(to_transfer, sizeof(tmpbuf)); pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied = AUD_write (voice, tmpbuf, to_copy); if (!copied) { break; } -temp -= copied; +to_transfer -= copied; addr += copied; transferred += copied; } -- 2.41.0
[PULL 8/8] hw/audio/es1370: trace lost interrupts
From: Volker Rümelin It turns out that there are drivers which assume that interrupts can't be lost. E.g. the AROS sb128 driver is such a driver. Add a lost interrupt tracepoint to debug this kind of issues. Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-8-vr_q...@t-online.de> --- hw/audio/es1370.c | 14 ++ hw/audio/trace-events | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index b47794f786..91c47330ad 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -602,7 +602,7 @@ static uint64_t es1370_read(void *opaque, hwaddr addr, unsigned size) } static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, - int max, int *irq) + int max, bool *irq) { uint8_t tmpbuf[4096]; size_t to_transfer; @@ -657,10 +657,13 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, } if (csc_bytes == transferred) { -*irq = 1; +if (*irq) { +trace_es1370_lost_interrupt(index); +} +*irq = true; d->scount = sc | (sc << 16); } else { -*irq = 0; +*irq = false; d->scount = sc | (((csc_bytes - transferred - 1) >> d->shift) << 16); } @@ -688,7 +691,8 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, static void es1370_run_channel (ES1370State *s, size_t chan, int free_or_avail) { uint32_t new_status = s->status; -int max_bytes, irq; +int max_bytes; +bool irq; struct chan *d = &s->chan[chan]; const struct chan_bits *b = &es1370_chan_bits[chan]; @@ -702,6 +706,8 @@ static void es1370_run_channel (ES1370State *s, size_t chan, int free_or_avail) return; } +irq = s->sctl & b->sctl_inten && s->status & b->stat_int; + es1370_transfer_audio (s, d, b->sctl_loopsel, max_bytes, &irq); if (irq) { diff --git a/hw/audio/trace-events b/hw/audio/trace-events index 9ae2f717b6..059ce451f5 100644 --- a/hw/audio/trace-events +++ b/hw/audio/trace-events @@ -11,10 +11,11 @@ es1370_frame_address_rd(int ch, uint32_t addr) "ch=%d addr=0x%08x" es1370_frame_address_wr(int ch, uint32_t addr) "ch=%d addr=0x%08x" es1370_frame_count_rd(int ch, uint32_t curr, uint32_t size) "ch=%d CURR_CT=%u BUF_SIZE=%u" es1370_frame_count_wr(int ch, uint32_t curr, uint32_t size) "ch=%d CURR_CT=%u BUF_SIZE=%u" +es1370_lost_interrupt(int ch) "ch=%d lost interrupt" es1370_sample_count_rd(int ch, uint32_t curr, uint32_t num) "ch=%d CURR_SAMP_CT=%u SAMP_CT=%u" es1370_sample_count_wr(int ch, uint32_t curr, uint32_t num) "ch=%d CURR_SAMP_CT=%u SAMP_CT=%u" es1370_stream_format(int ch, uint32_t freq, const char *fmt, const char *mode, uint32_t shift) "ch=%d fmt=%u:%s:%s shift=%u" -es1370_transfer_audio(int ch, uint32_t f_curr, uint32_t f_size, uint32_t s_curr, uint32_t s_num, uint32_t leftover, int irq) "ch=%d CURR_CT=%u BUF_SIZE=%u CURR_SAMP_CT=%u SAMP_CT=%u leftover=%u irq=%d" +es1370_transfer_audio(int ch, uint32_t f_curr, uint32_t f_size, uint32_t s_curr, uint32_t s_num, uint32_t leftover, bool irq) "ch=%d CURR_CT=%u BUF_SIZE=%u CURR_SAMP_CT=%u SAMP_CT=%u leftover=%u irq=%d" # hda-codec.c hda_audio_running(const char *stream, int nr, bool running) "st %s, nr %d, run %d" -- 2.41.0
[PULL 0/8] Audio patches
From: Marc-André Lureau The following changes since commit cea3ea670fe265421131aad90c36fbb87bc4d206: Merge tag 'pull-vfio-20231009' of https://github.com/legoater/qemu into staging (2023-10-09 10:11:35 -0400) are available in the Git repository at: https://gitlab.com/marcandre.lureau/qemu.git tags/audio-pull-request for you to fetch changes up to 5bf1a71c5b7b2d1999f65c08b4d82b5dec9f3013: hw/audio/es1370: trace lost interrupts (2023-10-10 12:31:05 +) Audio es1370 fix & cleanups Volker Rümelin (8): hw/audio/es1370: reset current sample counter hw/audio/es1370: replace bit-rotted code with tracepoints hw/audio/es1370: remove unused dolog macro hw/audio/es1370: remove #ifdef ES1370_DEBUG to avoid bit rot hw/audio/es1370: remove #ifdef ES1370_VERBOSE to avoid bit rot hw/audio/es1370: block structure coding style fixes hw/audio/es1370: change variable type and name hw/audio/es1370: trace lost interrupts hw/audio/es1370.c | 289 +++--- hw/audio/trace-events | 11 ++ 2 files changed, 143 insertions(+), 157 deletions(-) -- 2.41.0
[PULL 4/8] hw/audio/es1370: remove #ifdef ES1370_DEBUG to avoid bit rot
From: Volker Rümelin Replace the #ifdef ES1370_DEBUG code with code that the compiler can optimize away to avoid bit rot. While at it, replace strcat() with pstrcat(). Tested-by: Rene Engel Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-4-vr_q...@t-online.de> --- hw/audio/es1370.c | 135 +++--- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index dd09fd59e1..f111206709 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -/* #define DEBUG_ES1370 */ +#define DEBUG_ES1370 0 /* #define VERBOSE_ES1370 */ #include "qemu/osdep.h" @@ -30,6 +30,7 @@ #include "audio/audio.h" #include "hw/pci/pci_device.h" #include "migration/vmstate.h" +#include "qemu/cutils.h" #include "qemu/module.h" #include "sysemu/dma.h" #include "qom/object.h" @@ -164,82 +165,78 @@ static void es1370_dac1_callback (void *opaque, int free); static void es1370_dac2_callback (void *opaque, int free); static void es1370_adc_callback (void *opaque, int avail); -#ifdef DEBUG_ES1370 - -static void print_ctl (uint32_t val) +static void print_ctl(uint32_t val) { -char buf[1024]; - -buf[0] = '\0'; -#define a(n) if (val & CTRL_##n) strcat (buf, " "#n) -a (ADC_STOP); -a (XCTL1); -a (OPEN); -a (MSFMTSEL); -a (M_SBB); -a (DAC_SYNC); -a (CCB_INTRM); -a (M_CB); -a (XCTL0); -a (BREQ); -a (DAC1_EN); -a (DAC2_EN); -a (ADC_EN); -a (UART_EN); -a (JYSTK_EN); -a (CDC_EN); -a (SERR_DIS); +if (DEBUG_ES1370) { +char buf[1024]; + +buf[0] = '\0'; +#define a(n) if (val & CTRL_##n) pstrcat(buf, sizeof(buf), " "#n) +a(ADC_STOP); +a(XCTL1); +a(OPEN); +a(MSFMTSEL); +a(M_SBB); +a(DAC_SYNC); +a(CCB_INTRM); +a(M_CB); +a(XCTL0); +a(BREQ); +a(DAC1_EN); +a(DAC2_EN); +a(ADC_EN); +a(UART_EN); +a(JYSTK_EN); +a(CDC_EN); +a(SERR_DIS); #undef a -AUD_log ("es1370", "ctl - PCLKDIV %d(DAC2 freq %d), freq %d,%s\n", - (val & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV, - DAC2_DIVTOSR ((val & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), - dac1_samplerate[(val & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], - buf); +AUD_log("es1370", "ctl - PCLKDIV %d(DAC2 freq %d), freq %d,%s\n", +(val & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV, +DAC2_DIVTOSR((val & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), +dac1_samplerate[(val & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], +buf); +} } -static void print_sctl (uint32_t val) +static void print_sctl(uint32_t val) { -static const char *fmt_names[] = {"8M", "8S", "16M", "16S"}; -char buf[1024]; - -buf[0] = '\0'; - -#define a(n) if (val & SCTRL_##n) strcat (buf, " "#n) -#define b(n) if (!(val & SCTRL_##n)) strcat (buf, " "#n) -b (R1LOOPSEL); -b (P2LOOPSEL); -b (P1LOOPSEL); -a (P2PAUSE); -a (P1PAUSE); -a (R1INTEN); -a (P2INTEN); -a (P1INTEN); -a (P1SCTRLD); -a (P2DACSEN); -if (buf[0]) { -strcat (buf, "\n"); -} -else { -buf[0] = ' '; -buf[1] = '\0'; -} +if (DEBUG_ES1370) { +static const char *fmt_names[] = {"8M", "8S", "16M", "16S"}; +char buf[1024]; + +buf[0] = '\0'; + +#define a(n) if (val & SCTRL_##n) pstrcat(buf, sizeof(buf), " "#n) +#define b(n) if (!(val & SCTRL_##n)) pstrcat(buf, sizeof(buf), " "#n) +b(R1LOOPSEL); +b(P2LOOPSEL); +b(P1LOOPSEL); +a(P2PAUSE); +a(P1PAUSE); +a(R1INTEN); +a(P2INTEN); +a(P1INTEN); +a(P1SCTRLD); +a(P2DACSEN); +if (buf[0]) { +pstrcat(buf, sizeof(buf), "\n"); +} else { +buf[0] = ' '; +buf[1] = '\0'; +} #undef b #undef a -AUD_log ("es1370", - "%s" - "p2_end_inc %d, p2_st_inc %d, r1_fmt %s, p2_fmt %s, p1_fmt %s\n", - buf, - (val & SCTRL_P2ENDINC) >> SCTRL_SH_P2ENDINC, - (val & SCTRL_P2STINC) >> SCTRL_SH_P2STINC, - fmt_names [(val >> SCTRL_SH_R1FMT) & 3], - fmt_names [(val >> SCTRL_SH_P2FMT) & 3], - fmt_names [(val >> SCTRL_SH_P1FMT) & 3] -); +AUD_log("es1370", +"%s p2_end_inc %d, p2_st_inc %d," +" r1_fmt %s, p2_fmt %s, p1_fmt %s\n", +buf, +(val & SCTRL_P2ENDINC) >> SCTRL_SH_P2ENDINC, +(val & SCTRL_P2STINC) >> SCTRL_SH_P2STINC, +fmt_names[(val >> SCTRL_SH_R1FMT) & 3], +fmt_names[(val >> SCTRL_SH_P2FMT) & 3], +fmt_names[(val >> SCTRL_SH_P1FMT) & 3]); +} } -#else -#define print_ctl(...) -#
[PULL 2/8] hw/audio/es1370: replace bit-rotted code with tracepoints
From: Volker Rümelin It seems that nobody has enabled the debug code of the ES1370 device for a long time. Since then, the code has bit-rotted. Replace the bit-rotten code with tracepoints. Tested-by: Rene Engel Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-2-vr_q...@t-online.de> --- hw/audio/es1370.c | 55 ++- hw/audio/trace-events | 10 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 0567721eb7..2b55e31a9a 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -34,6 +34,7 @@ #include "qemu/module.h" #include "sysemu/dma.h" #include "qom/object.h" +#include "trace.h" /* Missing stuff: SCTRL_P[12](END|ST)INC @@ -166,8 +167,6 @@ static void es1370_adc_callback (void *opaque, int avail); #ifdef DEBUG_ES1370 -#define ldebug(...) AUD_log ("es1370", __VA_ARGS__) - static void print_ctl (uint32_t val) { char buf[1024]; @@ -239,7 +238,6 @@ static void print_sctl (uint32_t val) ); } #else -#define ldebug(...) #define print_ctl(...) #define print_sctl(...) #endif @@ -411,12 +409,9 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl) if ((old_fmt != new_fmt) || (old_freq != new_freq)) { d->shift = (new_fmt & 1) + (new_fmt >> 1); -ldebug ("channel %zu, freq = %d, nchannels %d, fmt %d, shift %d\n", -i, -new_freq, -1 << (new_fmt & 1), -(new_fmt & 2) ? AUDIO_FORMAT_S16 : AUDIO_FORMAT_U8, -d->shift); +trace_es1370_stream_format(i, new_freq, +new_fmt & 2 ? "s16" : "u8", new_fmt & 1 ? "stereo" : "mono", +d->shift); if (new_freq) { struct audsettings as; @@ -503,8 +498,8 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) case ES1370_REG_ADC_SCOUNT: d += (addr - ES1370_REG_DAC1_SCOUNT) >> 2; d->scount = (val & 0x) << 16 | (val & 0x); -ldebug ("chan %td CURR_SAMP_CT %d, SAMP_CT %d\n", -d - &s->chan[0], val >> 16, (val & 0x)); +trace_es1370_sample_count_wr(d - &s->chan[0], +d->scount >> 16, d->scount & 0x); break; case ES1370_REG_ADC_FRAMEADR: @@ -515,7 +510,7 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) d += (addr - ES1370_REG_DAC1_FRAMEADR) >> 3; frameadr: d->frame_addr = val; -ldebug ("chan %td frame address %#x\n", d - &s->chan[0], val); +trace_es1370_frame_address_wr(d - &s->chan[0], d->frame_addr); break; case ES1370_REG_PHANTOM_FRAMECNT: @@ -534,8 +529,8 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) framecnt: d->frame_cnt = val; d->leftover = 0; -ldebug ("chan %td frame count %d, buffer size %d\n", -d - &s->chan[0], val >> 16, val & 0x); +trace_es1370_frame_count_wr(d - &s->chan[0], +d->frame_cnt >> 16, d->frame_cnt & 0x); break; default: @@ -573,17 +568,9 @@ static uint64_t es1370_read(void *opaque, hwaddr addr, unsigned size) case ES1370_REG_DAC2_SCOUNT: case ES1370_REG_ADC_SCOUNT: d += (addr - ES1370_REG_DAC1_SCOUNT) >> 2; +trace_es1370_sample_count_rd(d - &s->chan[0], +d->scount >> 16, d->scount & 0x); val = d->scount; -#ifdef DEBUG_ES1370 -{ -uint32_t curr_count = d->scount >> 16; -uint32_t count = d->scount & 0x; - -curr_count <<= d->shift; -count <<= d->shift; -dolog ("read scount curr %d, total %d\n", curr_count, count); -} -#endif break; case ES1370_REG_ADC_FRAMECNT: @@ -593,17 +580,9 @@ static uint64_t es1370_read(void *opaque, hwaddr addr, unsigned size) case ES1370_REG_DAC2_FRAMECNT: d += (addr - ES1370_REG_DAC1_FRAMECNT) >> 3; framecnt: +trace_es1370_frame_count_rd(d - &s->chan[0], +d->frame_cnt >> 16, d->frame_cnt & 0x); val = d->frame_cnt; -#ifdef DEBUG_ES1370 -{ -uint32_t size = ((d->frame_cnt & 0x) + 1) << 2; -uint32_t curr = ((d->frame_cnt >> 16) + 1) << 2; -if (curr > size) { -dolog ("read framecnt curr %d, size %d %d\n", curr, size, - curr > size); -} -} -#endif break; case ES1370_REG_ADC_FRAMEADR: @@ -613,6 +592,7 @@ static uint64_t es1370_read(void *opaque, hwaddr addr, unsigned size) case ES1370_REG_DAC2_FRAMEADR: d += (addr - ES1370_REG_DAC1_FRAMEADR) >> 3; frameadr: +trace_es1370_frame_address_rd(d - &s->chan[0], d->frame_addr);
[PULL 3/8] hw/audio/es1370: remove unused dolog macro
From: Volker Rümelin The dolog macro is unused. Remove the macro and use the now unused ES1370_VERBOSE macro to replace its inverse ES1370_SILENT macro. Tested-by: Rene Engel Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-3-vr_q...@t-online.de> --- hw/audio/es1370.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 2b55e31a9a..dd09fd59e1 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -24,7 +24,6 @@ /* #define DEBUG_ES1370 */ /* #define VERBOSE_ES1370 */ -#define SILENT_ES1370 #include "qemu/osdep.h" #include "hw/audio/soundhw.h" @@ -243,12 +242,6 @@ static void print_sctl (uint32_t val) #endif #ifdef VERBOSE_ES1370 -#define dolog(...) AUD_log ("es1370", __VA_ARGS__) -#else -#define dolog(...) -#endif - -#ifndef SILENT_ES1370 #define lwarn(...) AUD_log ("es1370: warning", __VA_ARGS__) #else #define lwarn(...) -- 2.41.0
[PULL 1/8] hw/audio/es1370: reset current sample counter
From: Volker Rümelin Reset the current sample counter when writing the Channel Sample Count Register. The Linux ens1370 driver and the AROS sb128 driver expect the current sample counter counts down from sample count to 0 after a write to the Channel Sample Count Register. Currently the current sample counter starts from 0 after a reset or the last count when the counter was stopped. The current sample counter is used to raise an interrupt whenever a complete buffer was transferred. When the counter starts with a value lower than the reload value, the interrupt triggeres before the buffer was completly transferred. This may lead to corrupted audio streams. Tested-by: Rene Engel Signed-off-by: Volker Rümelin Reviewed-by: Marc-André Lureau Tested-by: BALATON Zoltan Message-Id: <20230917065813.6692-1-vr_q...@t-online.de> --- hw/audio/es1370.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 90f73d4c23..0567721eb7 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -502,7 +502,7 @@ static void es1370_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) case ES1370_REG_DAC2_SCOUNT: case ES1370_REG_ADC_SCOUNT: d += (addr - ES1370_REG_DAC1_SCOUNT) >> 2; -d->scount = (val & 0x) | (d->scount & ~0x); +d->scount = (val & 0x) << 16 | (val & 0x); ldebug ("chan %td CURR_SAMP_CT %d, SAMP_CT %d\n", d - &s->chan[0], val >> 16, (val & 0x)); break; -- 2.41.0
Re: [PATCH 04/18] target: Declare FOO_CPU_TYPE_NAME/SUFFIX in 'cpu-qom.h'
On 2023/10/11 11:21, Philippe Mathieu-Daudé wrote: Hi Zhiwei, On 11/10/23 04:51, LIU Zhiwei wrote: On 2023/10/10 17:28, Philippe Mathieu-Daudé wrote: Hegerogeneous code needs access to the FOO_CPU_TYPE_NAME() macro to resolve target CPU types. Hi Philippe, I don't understand why should we use FOO_CPU_TYPE_NAME macro to resolve target CPU types? In my opinion, we should pass the CPU typename from command line for heterogeneous case. Could you make it clearer how should we use FOO_CPU_TYPE_NAME macro to resolve target CPU types in heterogeneous case? To be honest I start to feel a bit lost with the "cpu resolving type" design. We are not quite there yet to "create from command line" or "create from QMP", so I'm prototyping in plain C. One of my test is: #include "target/arm/cpu-qom.h" #include "target/hexagon/cpu-qom.h" ... static void my_machine3_init((MachineState *machine) { CPUState cpu[2]; ... cpu[0] = CPU(object_new(ARM_CPU_TYPE_NAME("cortex-a72"))); cpu[1] = CPU(object_new(HEXAGON_CPU_TYPE_NAME("v68"))); ... } The machine code need access to the per-target FOO_CPU_TYPE_NAME() macros. I see what you mean. It works if we will pass the cpu model instead of cpu typename to the machine state(Not yet). Acked-by: LIU Zhiwei Zhiwei I'm not sure what each macro expands to is considered stable, so IIUC I can't inline and use: cpu[0] = CPU(object_new("cortex-a72-arm-cpu")); cpu[1] = CPU(object_new("v68"-hexagon-cpu)); That said, maybe I'm mistaken. Kinda related discussion with Gavin/Igor: https://lore.kernel.org/qemu-devel/35653f53-a977-02ea-28f6-6fe85b1ef...@redhat.com/ (related to https://lore.kernel.org/qemu-devel/20230907003553.1636896-1-gs...@redhat.com/). Thanks, Zhiwei Move the declaration (along with the required FOO_CPU_TYPE_SUFFIX) to "cpu-qom.h". Signed-off-by: Philippe Mathieu-Daudé --- target/alpha/cpu-qom.h | 5 - target/alpha/cpu.h | 2 -- target/avr/cpu-qom.h | 5 - target/avr/cpu.h | 2 -- target/cris/cpu-qom.h | 5 - target/cris/cpu.h | 2 -- target/i386/cpu-qom.h | 3 +++ target/i386/cpu.h | 2 -- target/m68k/cpu-qom.h | 5 - target/m68k/cpu.h | 2 -- target/mips/cpu-qom.h | 3 +++ target/mips/cpu.h | 2 -- target/rx/cpu-qom.h | 5 - target/rx/cpu.h | 2 -- target/s390x/cpu-qom.h | 5 - target/s390x/cpu.h | 2 -- target/sh4/cpu-qom.h | 5 - target/sh4/cpu.h | 2 -- target/sparc/cpu-qom.h | 5 - target/sparc/cpu.h | 2 -- target/tricore/cpu-qom.h | 5 + target/tricore/cpu.h | 2 -- target/xtensa/cpu-qom.h | 5 - target/xtensa/cpu.h | 2 -- 24 files changed, 47 insertions(+), 33 deletions(-) diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h index 1f200724b6..d596d1b69f 100644 --- a/target/alpha/cpu-qom.h +++ b/target/alpha/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU Alpha CPU + * QEMU Alpha CPU QOM header (target agnostic) * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -27,6 +27,9 @@ OBJECT_DECLARE_CPU_TYPE(AlphaCPU, AlphaCPUClass, ALPHA_CPU) +#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU +#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX + /** * AlphaCPUClass: * @parent_realize: The parent class' realize handler. diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index e2a467ec17..ba0d9e3468 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -428,8 +428,6 @@ enum { void alpha_translate_init(void); -#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU -#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU void alpha_cpu_list(void); [...]
wiki.qemu.org is experiencing technical difficulties
Hi, https://wiki.qemu.org/ displays: (Cannot access the database) Backtrace: #0 /var/www/html/includes/libs/rdbms/loadbalancer/LoadBalancer.php(972): Wikimedia\Rdbms\LoadBalancer->reportConnectionError() #1 /var/www/html/includes/libs/rdbms/loadbalancer/LoadBalancer.php(944): Wikimedia\Rdbms\LoadBalancer->getServerConnection(0, 'qemu_mediawiki', 0) #2 /var/www/html/includes/libs/rdbms/database/DBConnRef.php(95): Wikimedia\Rdbms\LoadBalancer->getConnectionInternal(-1, Array, 'qemu_mediawiki', 0) #3 /var/www/html/includes/libs/rdbms/database/DBConnRef.php(101): Wikimedia\Rdbms\DBConnRef->ensureConnection() #4 /var/www/html/includes/libs/rdbms/database/DBConnRef.php(706): Wikimedia\Rdbms\DBConnRef->__call('getSessionLagSt...', Array) #5 /var/www/html/includes/libs/rdbms/database/Database.php(3151): Wikimedia\Rdbms\DBConnRef->getSessionLagStatus() #6 /var/www/html/includes/user/User.php(527): Wikimedia\Rdbms\Database::getCacheSetOptions(Object(Wikimedia\Rdbms\DBConnRef)) #7 /var/www/html/includes/libs/objectcache/wancache/WANObjectCache.php(1689): User->{closure}(false, 3600, Array, NULL, Array) #8 /var/www/html/includes/libs/objectcache/wancache/WANObjectCache.php(1522): WANObjectCache->fetchOrRegenerate('global:user:id:...', 3600, Object(Closure), Array, Array) #9 /var/www/html/includes/user/User.php(560): WANObjectCache->getWithSetCallback('global:user:id:...', 3600, Object(Closure), Array) #10 /var/www/html/includes/user/User.php(471): User->loadFromCache() #11 /var/www/html/includes/user/User.php(404): User->loadFromId(0) #12 /var/www/html/includes/session/UserInfo.php(92): User->load() #13 /var/www/html/includes/session/CookieSessionProvider.php(131): MediaWiki\Session\UserInfo::newFromId('1303') #14 /var/www/html/includes/session/SessionManager.php(537): MediaWiki\Session\CookieSessionProvider->provideSessionInfo(Object(WebRequest)) #15 /var/www/html/includes/session/SessionManager.php(243): MediaWiki\Session\SessionManager->getSessionInfoForRequest(Object(WebRequest)) #16 /var/www/html/includes/WebRequest.php(843): MediaWiki\Session\SessionManager->getSessionForRequest(Object(WebRequest)) #17 /var/www/html/includes/session/SessionManager.php(164): WebRequest->getSession() #18 /var/www/html/includes/Setup.php(448): MediaWiki\Session\SessionManager::getGlobalSession() #19 /var/www/html/includes/WebStart.php(86): require_once('/var/www/html/i...') #20 /var/www/html/index.php(44): require('/var/www/html/i...') #21 {main}
Re: [PULL 50/51] subprojects: add wrap file for libblkio
Hi Paolo, On 7/9/23 14:59, Paolo Bonzini wrote: This allows building libblkio at the same time as QEMU, if QEMU is configured with --enable-blkio --enable-download. Signed-off-by: Paolo Bonzini --- subprojects/libblkio.wrap | 6 ++ 1 file changed, 6 insertions(+) create mode 100644 subprojects/libblkio.wrap diff --git a/subprojects/libblkio.wrap b/subprojects/libblkio.wrap new file mode 100644 index 000..f77af72210c --- /dev/null +++ b/subprojects/libblkio.wrap @@ -0,0 +1,6 @@ +[wrap-git] +url = https://gitlab.com/libblkio/libblkio Tyler noticed this project isn't mirrored on QEMU gitlab namespace. +revision = f84cc963a444e4cb34813b2dcfc5bf8526947dc0 + +[provide] +blkio = libblkio_dep
Re: [PATCH 2/6] target/riscv: Use env_archcpu() in [check_]nanbox()
On 11/10/23 05:25, LIU Zhiwei wrote: On 2023/10/11 1:04, Richard Henderson wrote: On 10/9/23 05:42, LIU Zhiwei wrote: On 2023/10/9 19:02, Philippe Mathieu-Daudé wrote: When CPUArchState* is available (here CPURISCVState*), we can use the fast env_archcpu() macro to get ArchCPU* (here RISCVCPU*). The QOM cast RISCV_CPU() macro will be slower when building with --enable-qom-cast-debug. If so, maybe we have to do this qom cast somewhere. No, I don't think so. Or at least not in these places. Yes. Perhaps, we should remove all RISCV_CPU macros using after the qom objects realized. Do you think we should remove the RISCV_CPU using in riscv_cpu_exec_interrupt? Although it is not so hot. I think there is no reason to use it there. I have some note in my TODO to check replacing CPUState by ArchCPU in TCGCPUOps (like the cpu_exec_interrupt handler you mentioned). However I'm running out of time, so feel free to try it. Using ArchCPU avoids the cast in target code. Except this, there are many other places in hw/ and target/riscv using the RISCV_CPU macro. If a method is exposed as API, we need to check the type. After that for internal calls this is pointless. If we know whether we should remove the RISCV_CPU macro use in these places, we can do it in another patch. Thanks, Zhiwei r~
Re: [PATCH for-8.1] hw/rdma/vmw/pvrdma_cmd: Use correct struct in query_port()
On 25/07/2023 13.36, Peter Maydell wrote: In query_port() we pass the address of a local pvrdma_port_attr struct to the rdma_query_backend_port() function. Unfortunately, rdma_backend_query_port() wants a pointer to a struct ibv_port_attr, and the two are not the same length. Coverity spotted this (CID 1507146): pvrdma_port_attr is 48 bytes long, and ibv_port_attr is 52 bytes, because it has a few extra fields at the end. Fortunately, all we do with the attrs struct after the call is to read a few specific fields out of it which are all at the same offsets in both structs, so we can simply make the local variable the correct type. This also lets us drop the cast (which should have been a bit of a warning flag that we were doing something wrong here). Cc: qemu-sta...@nongnu.org Signed-off-by: Peter Maydell --- I don't know anything about the rdma code so this fix is based purely on looking at the code, and is untested beyond just make check/make check-avocado. --- hw/rdma/vmw/pvrdma_cmd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c index c6ed0259821..d31c1875938 100644 --- a/hw/rdma/vmw/pvrdma_cmd.c +++ b/hw/rdma/vmw/pvrdma_cmd.c @@ -129,14 +129,13 @@ static int query_port(PVRDMADev *dev, union pvrdma_cmd_req *req, { struct pvrdma_cmd_query_port *cmd = &req->query_port; struct pvrdma_cmd_query_port_resp *resp = &rsp->query_port_resp; -struct pvrdma_port_attr attrs = {}; +struct ibv_port_attr attrs = {}; if (cmd->port_num > MAX_PORTS) { return -EINVAL; } -if (rdma_backend_query_port(&dev->backend_dev, -(struct ibv_port_attr *)&attrs)) { +if (rdma_backend_query_port(&dev->backend_dev, &attrs)) { return -ENOMEM; } Hi Peter, this seems to fail with Clang: ../../devel/qemu/hw/rdma/vmw/pvrdma_cmd.c:144:59: error: implicit conversion from enumeration type 'enum ibv_port_state' to different enumeration type 'enum pvrdma_port_state' [-Werror,-Wenum-conversion] resp->attrs.state = dev->func0->device_active ? attrs.state : ~ ~~^ ../../devel/qemu/hw/rdma/vmw/pvrdma_cmd.c:146:33: error: implicit conversion from enumeration type 'enum ibv_mtu' to different enumeration type 'enum pvrdma_mtu' [-Werror,-Wenum-conversion] resp->attrs.max_mtu = attrs.max_mtu; ~ ~~^~~ ../../devel/qemu/hw/rdma/vmw/pvrdma_cmd.c:147:36: error: implicit conversion from enumeration type 'enum ibv_mtu' to different enumeration type 'enum pvrdma_mtu' [-Werror,-Wenum-conversion] resp->attrs.active_mtu = attrs.active_mtu; ~ ~~^~ 3 errors generated. Could you please have a look ? Thomas
Re: [PATCH v2] migration: Use g_autofree to simplify ram_dirty_bitmap_reload()
Philippe Mathieu-Daudé writes: > Signed-off-by: Philippe Mathieu-Daudé g_autofree enables direct return, which is easier to understand. Like it. Reviewed-by: Markus Armbruster
Re: [PATCH v3 3/4] migration/qapi: Replace @MigrateSetParameters with @MigrationParameters
Peter Xu writes: > Hi, Markus, > > On Tue, Oct 10, 2023 at 09:18:23PM +0200, Markus Armbruster wrote: > > [...] > >> >> The point I was trying to make is this. Before the patch, we reject >> >> attempts to set the property value to null. Afterwards, we accept them, >> >> i.e. the patch loses "reject null property value". If this loss is >> >> undesirable, we better replace it with suitable hand-written code. >> > >> > I don't even know how to set it to NULL before.. as it can only be accessed >> > via cmdline "-global" as mentioned above, which must be a string anyway. >> > So I assume this is not an issue. >> >> Something like >> >> {"execute": "migrate-set-parameters", >> "arguments": {"tls-authz": null}} >> >> Hmm, crashes in migrate_params_apply(), which is a bug. I'm getting >> more and more suspicious about user-facing migration code... > > Did you apply patch 1 of this series? Since we're talking about "how to set it to NULL before", I was using master. > https://lore.kernel.org/qemu-devel/20230905162335.235619-2-pet...@redhat.com/ > > QMP "migrate-set-parameters" does not go via migration_properties, so even > if we change handling of migration_properties, it shouldn't yet affect the > QMP interface of that. I see. I want to understand the impact of the change from 'str' to 'StrOrNull' on external interfaces. The first step is to know where exactly the type is exposed externally. *Know*, not gut-feel based on intended use. I'll have another look at the schema change, and how the types are used. >> If the migration object is accessible with qom-set, then that's another >> way to assign null values. > > I see what you meant. IMHO we just don't need to worry on breaking that as > I am not aware of anyone using that to set migration parameters, and I > think the whole idea of migration_properties is for debugging. The only > legal way an user should set migration parameters should be via QMP, afaik. No matter the intended purpose of an interface, its meaning should be clear. If we accept null, what does it mean? >> In my "QAPI string visitors crashes" memo, I demonstrated that the crash >> on funny property type predates your series. You merely add another >> instance. Moreover, crashing -global is less serious than a crashing >> monitor command, because only the latter can take down a running guest. >> Can't see why your series needs to wait for a fix of the crash bug. >> Makes sense? > > What's your suggestion to move on with this series without a fix for that > crash bug? > > I started this series with making tls_* all strings (rather than StrOrNull) > and that actually worked out, mostly. We switched to StrOrNull just > because we think it's cleaner and 100% not breaking anyone (even though I > still don't think the other way will). I don't see how I can proceed this > series without fixing this visitor issue but keep using StrOrNull. I forgot it the switch to alternate crashes on normal usage, not just when you attempt to pass null. > Please don't worry on blocking my work: it won't anymore. The thing I need > is: > > https://lore.kernel.org/qemu-devel/20230905193802.250440-1-pet...@redhat.com/ > > While this whole series is just paving way for it. If I can't get > immediate results out of this series, I'll just go with the triplications, > leaving all the rest for later. Okay.
Re: [RFC PATCH 06/11] tests/avocado: Add FreeBSD distro boot tests for ppc
On Tue, Oct 10, 2023 at 8:23 PM Nicholas Piggin wrote: > On Wed Oct 11, 2023 at 7:55 AM AEST, Warner Losh wrote: > > On Tue, Oct 10, 2023 at 1:53 AM Nicholas Piggin > wrote: > > > > > FreeBSD project provides qcow2 images that work well for testing QEMU. > > > Add pseries tests for HPT and Radix, KVM and TCG. > > > > > > Other architectures could be added so this does not get a ppc_ prefix > > > but is instead named similarly to boot_linux. > > > > > > Cc: Warner Losh > > > Signed-off-by: Nicholas Piggin > > > > > > CC'ing Warner to check if it's okay for us to use these images and > > > any comments or suggestions. avocado tests have many Linux boots so > we'd > > > do much better to expand test coverage by adding some other systems. > > > > > > > I like this I'm a little worried at the exact hash encoded in it, but > > since there's a checksum > > to match, it's OK I guess. It will give this code a shelf-life of months, > > IIRC our retention policy. > > The oldest 15.0 CURRENT image on there is May 1st, so ~6 months? That's > not too bad. There are some release qcow2 images as well which sound > like they're maintained longer-term: > > https://download.freebsd.org/releases/VM-IMAGES/ > > No builds for powerpc, but those might be preferable for other targets. > > Another option for powerpc might be to use a release .iso. It's much > nicer to have a qcow image already installed though. I'll tinker with > it a bit more, but may stick with the snapshot for now. > I'll try to track that down. It may just be an oversight since powerpc64le is new. Warner > Thanks, > Nick >
Re: [RFC PATCH 06/11] tests/avocado: Add FreeBSD distro boot tests for ppc
On Tue, Oct 10, 2023 at 6:36 PM Nicholas Piggin wrote: > On Wed Oct 11, 2023 at 7:55 AM AEST, Warner Losh wrote: > > On Tue, Oct 10, 2023 at 1:53 AM Nicholas Piggin > wrote: > > > > > FreeBSD project provides qcow2 images that work well for testing QEMU. > > > Add pseries tests for HPT and Radix, KVM and TCG. > > > > > > Other architectures could be added so this does not get a ppc_ prefix > > > but is instead named similarly to boot_linux. > > > > > > Cc: Warner Losh > > > Signed-off-by: Nicholas Piggin > > > > > > CC'ing Warner to check if it's okay for us to use these images and > > > any comments or suggestions. avocado tests have many Linux boots so > we'd > > > do much better to expand test coverage by adding some other systems. > > > > > > > I like this I'm a little worried at the exact hash encoded in it, but > > since there's a checksum > > to match, it's OK I guess. It will give this code a shelf-life of months, > > IIRC our retention policy. > > Oh I didn't realise, I saw some 2021 dates in the directory listing but > looks > like they're not for the artifacts themselves. > > I don't suppose you know if there are any long-term artifacts kept > around, or someone who I could ask? > > The downside of using short term images is that it can be harder to > reproduce reports from others, bisect, run manual testing, etc. I think > these would still be useful, so long as they get updated regularly. > Yes. We're in kind of a weird zone. powerpc64le is a new architecture, so hasn't had artifacts for long. 14.0 is in progress, but not done yet, so there's no 'long term stable' version to use yet. I don't know what our current retention policy is, hence my caution. > > > > Other than that, I think this is good. Not familiar enough with Avocado > to > > understand > > skipping for gitlab CI, but given the extreme crunch on minutes, I think > > that's OK. > > Yeah I'm not sure what the situation there is, I didn't want to add new > tests of any significant weight yet. We could always flip it on later if > people want it. > That makes sense. > > > > Other than one nit below which is fine if it is intentionally left behind > > (or removed): > > > > Reviewed-by: Warner Losh > > > > Please don't hesitate to reach out to me if this is failing. I'll act as > a > > backstop to get > > it to the right people. > > Thanks Warner. > You bet. I'll give a heads up once we have 14.0 out so we can switch to a more stable artifact. Warner > > > > Warner > > > > > [snip] > > > > +def run_pseries_test(self, force_HPT=False): > > > +# We need zstd for all the tuxrun tests > > > +# See > https://github.com/avocado-framework/avocado/issues/5609 > > > +zstd = find_command('zstd', False) > > > +if zstd is False: > > > +self.cancel('Could not find "zstd", which is required to ' > > > +'decompress rootfs') > > > +self.zstd = zstd > > > + > > > +drive_url = (' > > > > https://artifact.ci.freebsd.org/snapshot/15.0-CURRENT/a2440348eed75bb7682579af0905b652747fd016/powerpc/powerpc64le/disk.qcow2.zst > > > ') > > > +drive_hash = '8ab11a05ccab3d44215fd4667a70454ed10a203f' > > > +drive_path_zstd = self.fetch_asset(drive_url, > > > asset_hash=drive_hash) > > > +drive_path = os.path.join(self.workdir, 'disk.qcow2') > > > +# archive.zstd_uncompress(drive_path_zstd, drive_path) > > > > > > > Why is this commented out? It looks like a leftover maybe? > > > > Ah yes, avocado recently got zstd_uncompress but it seems not > available for QEMU yet so we have to do it by hand. I'll remove. > > Thanks, > Nick >
[Beginner-Help] Help understanding the migration Code
Hi I am trying to understand how migration, more specifically live-migration works in QEMU. I've tried going through the source code but didn't understand much, and couldn't find documentation either. I want to work on live migration and need help getting to know the code. More specifically I want to understand - where the pre/post copy algorithms are implemented - which files/data-structures that I should look at - should I need to make changes, where and how should I start? I am new to working with such large code bases, hence need some guidance. Thanks Amit Kumar
Re: [PATCH 3/4] hw/cpu: Introduce CPUClass::cpu_resolving_type field
Hi Gavin, On 25/9/23 02:24, Gavin Shan wrote: On 9/12/23 08:40, Gavin Shan wrote: On 9/11/23 19:43, Philippe Mathieu-Daudé wrote: On 11/9/23 01:28, Gavin Shan wrote: On 9/8/23 21:22, Philippe Mathieu-Daudé wrote: Add a field to return the QOM type name of a CPU class. Signed-off-by: Philippe Mathieu-Daudé --- diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 129d179937..e469efd409 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -100,6 +100,7 @@ struct SysemuCPUOps; /** * CPUClass: + * @cpu_resolving_type: CPU QOM type name * @class_by_name: Callback to map -cpu command line model name to an * instantiatable CPU type. * @parse_features: Callback to parse command line arguments. @@ -148,6 +149,7 @@ struct CPUClass { DeviceClass parent_class; /*< public >*/ + const char *cpu_resolving_type; ObjectClass *(*class_by_name)(const char *cpu_model); void (*parse_features)(const char *typename, char *str, Error **errp); The question is why not use CPU_RESOLVING_TYPE directly? It seems CPU_RESOLVING_TYPE is exactly what you want here. Unfortunately CPU_RESOLVING_TYPE is target-specific, we want hw/core/cpu-common.c to be target-agnostic (build once for all targets). This is particularly important in the context of heterogeneous QEMU, where a single binary will be able to create CPUs from different targets. CPU_RESOLVING_TYPE and CPUClass::cpu_resolving_type is duplicate to each other. There are two options I can figure out to avoid the duplication. (a) move cpu_class_by_name() from hw/core/cpu-common.c to cpu.c, so that CPU_RESOLVING_TYPE can be seen. cpu.c::list_cpus() is the example. (b) remove hw/core/cpu-common.c::cpu_calss_by_name() and squeeze its logic to cpu.c::parse_cpu_option() since there are not too much users for it. target/arm and target/s390 needs some tweaks so that hw/core/cpu-common.c::cpu_calss_by_name() can be removed. [gshan@gshan q]$ git grep \ cpu_class_by_name\( cpu.c: oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]); target/arm/arm-qmp-cmds.c: oc = cpu_class_by_name(TYPE_ARM_CPU, model->name); target/s390x/cpu_models_sysemu.c: oc = cpu_class_by_name(TYPE_S390_CPU, info->name); When option (b) is taken, this series to have the checks against @oc in hw/core/cpu-common.c::cpu_calss_by_name() becomes non-sense. Instead, we need the same (and complete) checks in CPUClass::class_by_name() for individual targets. Further more, an inline helper can be provided to do the check in CPUClass::class_by_name() for individual targets. include/hw/core/cpu.h static inline bool cpu_class_is_valid(ObjectClass *oc, const char *parent) { if (!object_class_dynamic_cast(oc, parent) || object_class_is_abstract(oc)) { return false; } return true; } Since my series to make CPU type check unified depends on this series, could you please share your thoughts? If you don't have bandwidth for this, I can improve the code based on your thoughts, and include your patches to my series so that they can be reviewed at once. Please just let me know. You seem to prove (b) is not useful, so we have to do (a). Unfortunately at this moment I feel hopeless with this topic. I don't want to delay your work further. If you find a way to integrate both series, please go ahead. Otherwise let's drop my approach and continue with your previous work. I apologize I kept you waiting that long. Regards, Phil.
Re: [PATCH 2/6] target/riscv: Use env_archcpu() in [check_]nanbox()
On 2023/10/11 1:04, Richard Henderson wrote: On 10/9/23 05:42, LIU Zhiwei wrote: On 2023/10/9 19:02, Philippe Mathieu-Daudé wrote: When CPUArchState* is available (here CPURISCVState*), we can use the fast env_archcpu() macro to get ArchCPU* (here RISCVCPU*). The QOM cast RISCV_CPU() macro will be slower when building with --enable-qom-cast-debug. Inspired-by: Richard W.M. Jones Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: LIU Zhiwei By the way, does the community has the plan to support heterogeneous architecture cpus in one soc? Yes. Hi Richard, It's a good news. Thanks. If so, maybe we have to do this qom cast somewhere. No, I don't think so. Or at least not in these places. Yes. Perhaps, we should remove all RISCV_CPU macros using after the qom objects realized. Do you think we should remove the RISCV_CPU using in riscv_cpu_exec_interrupt? Although it is not so hot. I think there is no reason to use it there. Except this, there are many other places in hw/ and target/riscv using the RISCV_CPU macro. If we know whether we should remove the RISCV_CPU macro use in these places, we can do it in another patch. Thanks, Zhiwei r~
Re: [PATCH 04/18] target: Declare FOO_CPU_TYPE_NAME/SUFFIX in 'cpu-qom.h'
Hi Zhiwei, On 11/10/23 04:51, LIU Zhiwei wrote: On 2023/10/10 17:28, Philippe Mathieu-Daudé wrote: Hegerogeneous code needs access to the FOO_CPU_TYPE_NAME() macro to resolve target CPU types. Hi Philippe, I don't understand why should we use FOO_CPU_TYPE_NAME macro to resolve target CPU types? In my opinion, we should pass the CPU typename from command line for heterogeneous case. Could you make it clearer how should we use FOO_CPU_TYPE_NAME macro to resolve target CPU types in heterogeneous case? To be honest I start to feel a bit lost with the "cpu resolving type" design. We are not quite there yet to "create from command line" or "create from QMP", so I'm prototyping in plain C. One of my test is: #include "target/arm/cpu-qom.h" #include "target/hexagon/cpu-qom.h" ... static void my_machine3_init((MachineState *machine) { CPUState cpu[2]; ... cpu[0] = CPU(object_new(ARM_CPU_TYPE_NAME("cortex-a72"))); cpu[1] = CPU(object_new(HEXAGON_CPU_TYPE_NAME("v68"))); ... } The machine code need access to the per-target FOO_CPU_TYPE_NAME() macros. I'm not sure what each macro expands to is considered stable, so IIUC I can't inline and use: cpu[0] = CPU(object_new("cortex-a72-arm-cpu")); cpu[1] = CPU(object_new("v68"-hexagon-cpu)); That said, maybe I'm mistaken. Kinda related discussion with Gavin/Igor: https://lore.kernel.org/qemu-devel/35653f53-a977-02ea-28f6-6fe85b1ef...@redhat.com/ (related to https://lore.kernel.org/qemu-devel/20230907003553.1636896-1-gs...@redhat.com/). Thanks, Zhiwei Move the declaration (along with the required FOO_CPU_TYPE_SUFFIX) to "cpu-qom.h". Signed-off-by: Philippe Mathieu-Daudé --- target/alpha/cpu-qom.h | 5 - target/alpha/cpu.h | 2 -- target/avr/cpu-qom.h | 5 - target/avr/cpu.h | 2 -- target/cris/cpu-qom.h | 5 - target/cris/cpu.h | 2 -- target/i386/cpu-qom.h | 3 +++ target/i386/cpu.h | 2 -- target/m68k/cpu-qom.h | 5 - target/m68k/cpu.h | 2 -- target/mips/cpu-qom.h | 3 +++ target/mips/cpu.h | 2 -- target/rx/cpu-qom.h | 5 - target/rx/cpu.h | 2 -- target/s390x/cpu-qom.h | 5 - target/s390x/cpu.h | 2 -- target/sh4/cpu-qom.h | 5 - target/sh4/cpu.h | 2 -- target/sparc/cpu-qom.h | 5 - target/sparc/cpu.h | 2 -- target/tricore/cpu-qom.h | 5 + target/tricore/cpu.h | 2 -- target/xtensa/cpu-qom.h | 5 - target/xtensa/cpu.h | 2 -- 24 files changed, 47 insertions(+), 33 deletions(-) diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h index 1f200724b6..d596d1b69f 100644 --- a/target/alpha/cpu-qom.h +++ b/target/alpha/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU Alpha CPU + * QEMU Alpha CPU QOM header (target agnostic) * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -27,6 +27,9 @@ OBJECT_DECLARE_CPU_TYPE(AlphaCPU, AlphaCPUClass, ALPHA_CPU) +#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU +#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX + /** * AlphaCPUClass: * @parent_realize: The parent class' realize handler. diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index e2a467ec17..ba0d9e3468 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -428,8 +428,6 @@ enum { void alpha_translate_init(void); -#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU -#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU void alpha_cpu_list(void); [...]
Re: [PATCH] Add epmp to extensions list and rename it to smepmp
On Mon, Sep 25, 2023 at 9:08 PM Mayuresh Chitale wrote: > > From: Himanshu Chauhan > > Smepmp is a ratified extension which qemu refers to as epmp. > Rename epmp to smepmp and add it to extension list so that > it is added to the isa string. > > Signed-off-by: Himanshu Chauhan > Signed-off-by: Mayuresh Chitale > Reviewed-by: Daniel Henrique Barboza > --- > target/riscv/cpu.c | 9 + > target/riscv/cpu.h | 2 +- > target/riscv/csr.c | 6 +++--- > target/riscv/pmp.c | 12 ++-- > 4 files changed, 15 insertions(+), 14 deletions(-) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index befa64528f..0fb01788e7 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -126,6 +126,7 @@ static const struct isa_ext_data isa_edata_arr[] = { > ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), > ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), > ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt), > +ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp), > ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba), > ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb), > ISA_EXT_DATA_ENTRY(xtheadbs, PRIV_VERSION_1_11_0, ext_xtheadbs), > @@ -488,7 +489,7 @@ static void rv32_ibex_cpu_init(Object *obj) > #ifndef CONFIG_USER_ONLY > set_satp_mode_max_supported(cpu, VM_1_10_MBARE); > #endif > -cpu->cfg.epmp = true; > +cpu->cfg.ext_smepmp = true; > } > > static void rv32_imafcu_nommu_cpu_init(Object *obj) > @@ -1198,12 +1199,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error > **errp) > } > } > > -if (cpu->cfg.epmp && !cpu->cfg.pmp) { > +if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) { > /* > * Enhanced PMP should only be available > * on harts with PMP support > */ > -error_setg(errp, "Invalid configuration: EPMP requires PMP support"); > +error_setg(errp, "Invalid configuration: Smepmp requires PMP > support"); > return; > } > > @@ -1560,7 +1561,7 @@ static Property riscv_cpu_extensions[] = { > DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false), > > /* ePMP 0.9.3 */ Can you remove this comment? Alistair > -DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), > +DEFINE_PROP_BOOL("smepmp", RISCVCPU, cfg.ext_smepmp, false), > DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false), > DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false), > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index de7e43126a..9b4b012896 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -434,6 +434,7 @@ struct RISCVCPUConfig { > bool ext_zvfh; > bool ext_zvfhmin; > bool ext_smaia; > +bool ext_smepmp; > bool ext_ssaia; > bool ext_sscofpmf; > bool rvv_ta_all_1s; > @@ -468,7 +469,6 @@ struct RISCVCPUConfig { > uint16_t cboz_blocksize; > bool mmu; > bool pmp; > -bool epmp; > bool debug; > bool misa_w; > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 4451bd1263..d9ecc222e7 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -519,9 +519,9 @@ static RISCVException pmp(CPURISCVState *env, int csrno) > return RISCV_EXCP_ILLEGAL_INST; > } > > -static RISCVException epmp(CPURISCVState *env, int csrno) > +static RISCVException smepmp(CPURISCVState *env, int csrno) > { > -if (riscv_cpu_cfg(env)->epmp) { > +if (riscv_cpu_cfg(env)->ext_smepmp) { > return RISCV_EXCP_NONE; > } > > @@ -4337,7 +4337,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { > [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph > }, > > /* Physical Memory Protection */ > -[CSR_MSECCFG]= { "mseccfg", epmp, read_mseccfg, write_mseccfg, > +[CSR_MSECCFG]= { "mseccfg", smepmp, read_mseccfg, write_mseccfg, > .min_priv_ver = PRIV_VERSION_1_11_0 }, > [CSR_PMPCFG0]= { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg }, > [CSR_PMPCFG1]= { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg }, > diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c > index 1f5aca42e8..f498e414f0 100644 > --- a/target/riscv/pmp.c > +++ b/target/riscv/pmp.c > @@ -88,7 +88,7 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t > pmp_index, uint8_t val) > if (pmp_index < MAX_RISCV_PMPS) { > bool locked = true; > > -if (riscv_cpu_cfg(env)->epmp) { > +if (riscv_cpu_cfg(env)->ext_smepmp) { > /* mseccfg.RLB is set */ > if (MSECCFG_RLB_ISSET(env)) { > locked = false; > @@ -243,7 +243,7 @@ static bool pmp_hart_has_privs_default(CPURISCVState > *env, target_ulong addr, > { > bool ret; > > -if (riscv_cpu_cfg(env)->epmp) { > +if (riscv_cpu_cfg(env)->ext_smepmp) { > if (MSECCFG_MMWP_ISSET(env)) { >
Re: [RFC PATCH v2 1/9] Add Rust SEV library as subproject
On 10/5/23 11:54 AM, Stefan Hajnoczi wrote: On Wed, Oct 04, 2023 at 04:34:10PM -0400, Tyler Fanelli wrote: The Rust sev library provides a C API for the AMD SEV launch ioctls, as well as the ability to build with meson. Add the Rust sev library as a QEMU subproject with the goal of outsourcing all SEV launch ioctls to C APIs provided by it. Signed-off-by: Tyler Fanelli --- meson.build | 8 meson_options.txt | 2 ++ scripts/meson-buildoptions.sh | 3 +++ subprojects/sev.wrap | 6 ++ target/i386/meson.build | 2 +- 5 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 subprojects/sev.wrap diff --git a/meson.build b/meson.build index 20ceeb8158..8a17c29de8 100644 --- a/meson.build +++ b/meson.build @@ -960,6 +960,13 @@ if not get_option('slirp').auto() or have_system endif endif +sev = not_found +if not get_option('sev').auto() When 'sev' is auto, then it won't be built. That seems strange. The auto-detection part is missing! I did you test this on a system that doesn't have libsev installed system-wide? My testing environment had libsev installed system-wide. Thanks for pointing this out. I guess the auto-detection would look something like: cargo = find_program('cargo', required: true) if not get_option('sev').auto() or cargo.found() ... That way 'sev' is only built automatically on systems that have cargo installed. + sev = dependency('sev', + method: 'pkg-config', + required: get_option('sev')) +endif If you update the auto logic, see the documentation about fallbacks to subprojects for optional dependencies: https://mesonbuild.com/Wrap-dependency-system-manual.html#provide-section It might be necessary to add dependency(..., fallback='sev'). Noted. Thanks! + vde = not_found if not get_option('vde').auto() or have_system or have_tools vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'], @@ -4331,6 +4338,7 @@ summary_info += {'libudev': libudev} # Dummy dependency, keep .found() summary_info += {'FUSE lseek':fuse_lseek.found()} summary_info += {'selinux': selinux} +summary_info += {'sev': sev} summary_info += {'libdw': libdw} summary(summary_info, bool_yn: true, section: 'Dependencies') diff --git a/meson_options.txt b/meson_options.txt index 57e265c871..5b8d283717 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -204,6 +204,8 @@ option('sdl_image', type : 'feature', value : 'auto', description: 'SDL Image support for icons') option('seccomp', type : 'feature', value : 'auto', description: 'seccomp support') +option('sev', type : 'feature', value : 'auto', +description: 'Rust AMD SEV library') option('smartcard', type : 'feature', value : 'auto', description: 'CA smartcard emulation support') option('snappy', type : 'feature', value : 'auto', diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index e4b46d5715..e585a548fa 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -161,6 +161,7 @@ meson_options_help() { printf "%s\n" ' sdl-image SDL Image support for icons' printf "%s\n" ' seccomp seccomp support' printf "%s\n" ' selinux SELinux support in qemu-nbd' + printf "%s\n" ' sev SEV library support' printf "%s\n" ' slirp libslirp user mode network backend support' printf "%s\n" ' slirp-smbd use smbd (at path --smbd=*) in slirp networking' printf "%s\n" ' smartcard CA smartcard emulation support' @@ -440,6 +441,8 @@ _meson_option_parse() { --disable-seccomp) printf "%s" -Dseccomp=disabled ;; --enable-selinux) printf "%s" -Dselinux=enabled ;; --disable-selinux) printf "%s" -Dselinux=disabled ;; +--enable-sev) printf "%s" -Dsev=enabled ;; +--disable-sev) printf "%s" -Dsev=disabled ;; --enable-slirp) printf "%s" -Dslirp=enabled ;; --disable-slirp) printf "%s" -Dslirp=disabled ;; --enable-slirp-smbd) printf "%s" -Dslirp_smbd=enabled ;; diff --git a/subprojects/sev.wrap b/subprojects/sev.wrap new file mode 100644 index 00..5be1faccf6 --- /dev/null +++ b/subprojects/sev.wrap @@ -0,0 +1,6 @@ +[wrap-git] +url = https://github.com/tylerfanelli/sev +revision = b81b1da5df50055600a5b0349b0c4afda677cccb + +[provide] +sev = sev_dep diff --git a/target/i386/meson.build b/target/i386/meson.build index 6f1036d469..8972a4fb17 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -20,7 +20,7 @@ i386_system_ss.add(files( 'monitor.c', 'cpu-sysemu.c', )) -i386_system_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-sysemu-stub.c')) +i386_system_ss.add(when: 'CONFIG_SEV', if_true: [sev, files('sev.c')], if_false: files('sev-sysemu-stub.c')) i386_user_ss = ss.source_set() -- 2.40.1
Re: [RFC PATCH v2 1/9] Add Rust SEV library as subproject
On 10/5/23 2:03 AM, Philippe Mathieu-Daudé wrote: Hi Tyler, On 4/10/23 22:34, Tyler Fanelli wrote: The Rust sev library provides a C API for the AMD SEV launch ioctls, as well as the ability to build with meson. Add the Rust sev library as a QEMU subproject with the goal of outsourcing all SEV launch ioctls to C APIs provided by it. Signed-off-by: Tyler Fanelli --- meson.build | 8 meson_options.txt | 2 ++ scripts/meson-buildoptions.sh | 3 +++ subprojects/sev.wrap | 6 ++ target/i386/meson.build | 2 +- 5 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 subprojects/sev.wrap diff --git a/subprojects/sev.wrap b/subprojects/sev.wrap new file mode 100644 index 00..5be1faccf6 --- /dev/null +++ b/subprojects/sev.wrap @@ -0,0 +1,6 @@ +[wrap-git] +url = https://github.com/tylerfanelli/sev +revision = b81b1da5df50055600a5b0349b0c4afda677cccb Why use your tree instead of the mainstream one? Before this gets merged we need to mirror the subproject on our GitLab namespace, then use the mirror URL here. Hi Philippe, Why must the subproject be mirrored on qemu's GitLab namespace? With the changes being accepted in the upstream sev repository, meson will be able to fetch it from there. I see that libblkio (another Rust project) is not mirrored in the GitLab namespace [0] (assuming I'm looking in the right place) and that meson also fetches it from its upstream repo [1]. [0] https://gitlab.com/qemu-project [1] https://gitlab.com/qemu-project/qemu/-/blob/master/subprojects/libblkio.wrap?ref_type=heads#L2 Tyler
Re: [PATCH v2 08/10] target/riscv/tcg: add riscv_cpu_write_misa_bit()
On Sat, Oct 7, 2023 at 12:29 AM Daniel Henrique Barboza wrote: > > We have two instances of the setting/clearing a MISA bit from > env->misa_ext and env->misa_ext_mask pattern. And the next patch will > end up adding one more. > > Create a helper to avoid code repetition. > > Signed-off-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Alistair > --- > target/riscv/tcg/tcg-cpu.c | 44 -- > 1 file changed, 23 insertions(+), 21 deletions(-) > > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c > index 58de4428a9..b1e778913c 100644 > --- a/target/riscv/tcg/tcg-cpu.c > +++ b/target/riscv/tcg/tcg-cpu.c > @@ -42,6 +42,20 @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset) > GUINT_TO_POINTER(ext_offset)); > } > > +static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit, > + bool enabled) > +{ > +CPURISCVState *env = &cpu->env; > + > +if (enabled) { > +env->misa_ext |= bit; > +env->misa_ext_mask |= bit; > +} else { > +env->misa_ext &= ~bit; > +env->misa_ext_mask &= ~bit; > +} > +} > + > static void riscv_cpu_synchronize_from_tb(CPUState *cs, >const TranslationBlock *tb) > { > @@ -700,20 +714,14 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor > *v, const char *name, > return; > } > > -if (value) { > -if (!generic_cpu) { > -g_autofree char *cpuname = riscv_cpu_get_name(cpu); > -error_setg(errp, "'%s' CPU does not allow enabling extensions", > - cpuname); > -return; > -} > - > -env->misa_ext |= misa_bit; > -env->misa_ext_mask |= misa_bit; > -} else { > -env->misa_ext &= ~misa_bit; > -env->misa_ext_mask &= ~misa_bit; > +if (value && !generic_cpu) { > +g_autofree char *cpuname = riscv_cpu_get_name(cpu); > +error_setg(errp, "'%s' CPU does not allow enabling extensions", > + cpuname); > +return; > } > + > +riscv_cpu_write_misa_bit(cpu, misa_bit, value); > } > > static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name, > @@ -757,7 +765,6 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = { > */ > static void riscv_cpu_add_misa_properties(Object *cpu_obj) > { > -CPURISCVState *env = &RISCV_CPU(cpu_obj)->env; > bool use_def_vals = riscv_cpu_is_generic(cpu_obj); > int i; > > @@ -778,13 +785,8 @@ static void riscv_cpu_add_misa_properties(Object > *cpu_obj) > NULL, (void *)misa_cfg); > object_property_set_description(cpu_obj, name, desc); > if (use_def_vals) { > -if (misa_cfg->enabled) { > -env->misa_ext |= bit; > -env->misa_ext_mask |= bit; > -} else { > -env->misa_ext &= ~bit; > -env->misa_ext_mask &= ~bit; > -} > +riscv_cpu_write_misa_bit(RISCV_CPU(cpu_obj), bit, > + misa_cfg->enabled); > } > } > } > -- > 2.41.0 > >
Re: [PATCH v2 07/10] target/riscv/tcg: add MISA user options hash
On Sat, Oct 7, 2023 at 12:25 AM Daniel Henrique Barboza wrote: > > We already track user choice for multi-letter extensions because we > needed to honor user choice when enabling/disabling extensions during > realize(). We refrained from adding the same mechanism for MISA > extensions since we didn't need it. > > Profile support requires tne need to check for user choice for MISA > extensions, so let's add the corresponding hash now. It works like the > existing multi-letter hash (multi_ext_user_opts) but tracking MISA bits > options in the cpu_set_misa_ext_cfg() callback. > > Note that we can't re-use the same hash from multi-letter extensions > because that hash uses cpu->cfg offsets as keys, while for MISA > extensions we're using MISA bits as keys. > > After adding the user hash in cpu_set_misa_ext_cfg(), setting default > values with object_property_set_bool() in add_misa_properties() will end > up marking the user choice hash with them. Set the default value > manually to avoid it. > > Signed-off-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Alistair > --- > target/riscv/tcg/tcg-cpu.c | 15 ++- > 1 file changed, 14 insertions(+), 1 deletion(-) > > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c > index 8fb77e9e35..58de4428a9 100644 > --- a/target/riscv/tcg/tcg-cpu.c > +++ b/target/riscv/tcg/tcg-cpu.c > @@ -34,6 +34,7 @@ > > /* Hash that stores user set extensions */ > static GHashTable *multi_ext_user_opts; > +static GHashTable *misa_ext_user_opts; > > static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset) > { > @@ -689,6 +690,10 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor > *v, const char *name, > return; > } > > +g_hash_table_insert(misa_ext_user_opts, > +GUINT_TO_POINTER(misa_bit), > +(gpointer)value); > + > prev_val = env->misa_ext & misa_bit; > > if (value == prev_val) { > @@ -752,6 +757,7 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = { > */ > static void riscv_cpu_add_misa_properties(Object *cpu_obj) > { > +CPURISCVState *env = &RISCV_CPU(cpu_obj)->env; > bool use_def_vals = riscv_cpu_is_generic(cpu_obj); > int i; > > @@ -772,7 +778,13 @@ static void riscv_cpu_add_misa_properties(Object > *cpu_obj) > NULL, (void *)misa_cfg); > object_property_set_description(cpu_obj, name, desc); > if (use_def_vals) { > -object_property_set_bool(cpu_obj, name, misa_cfg->enabled, NULL); > +if (misa_cfg->enabled) { > +env->misa_ext |= bit; > +env->misa_ext_mask |= bit; > +} else { > +env->misa_ext &= ~bit; > +env->misa_ext_mask &= ~bit; > +} > } > } > } > @@ -967,6 +979,7 @@ static void tcg_cpu_instance_init(CPUState *cs) > RISCVCPU *cpu = RISCV_CPU(cs); > Object *obj = OBJECT(cpu); > > +misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal); > multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal); > riscv_cpu_add_user_properties(obj); > > -- > 2.41.0 > >
Re: [PATCH v2 00/10] riscv: RVA22U64 profile support
On Sat, Oct 7, 2023 at 12:23 AM Daniel Henrique Barboza wrote: > > Hi, > > Several design changes were made in this version after the reviews and > feedback in the v1 [1]. The high-level summary is: > > - we'll no longer allow users to set profile flags for vendor CPUs. If > we're to adhere to the current policy of not allowing users to enable > extensions for vendor CPUs, the profile support would become a > glorified way of checking if the vendor CPU happens to support a > specific profile. If a future vendor CPU supports a profile the CPU > can declare it manually in its cpu_init() function, the flag will > still be set, but users can't change it; > > - disabling a profile will now disable all the mandatory extensions from > the CPU; What happens if you enable one profile and disable a different one? Alistair > > - the profile logic was moved to realize() time in a step we're calling > 'commit profile'. This allows us to enable/disable profile extensions > after considering user input in other individual extensions. The > result is that we don't care about the order in which the profile flag > was set in comparison with other extensions in the command line, i.e. > the following lines are equal: > > -cpu rv64,zicbom=false,rva22u64=true,Zifencei=false > > -cpu rv64,rva22u64=true,zicbom=false,Zifencei=false > > and they mean 'enable the rva22u64 profile while keeping zicbom and > Zifencei disabled'. > > > Other minor changes were needed as result of these design changes. E.g. > we're now having to track MISA extensions set by users (patch 7), > something that we were doing only for multi-letter extensions. > > Changes from v1: > - patch 6 from v1 ("target/riscv/kvm: add 'rva22u64' flag as unavailable"): > - moved up to patch 4 > - patch 5 from v1("target/riscv/tcg-cpu.c: enable profile support for vendor > CPUs"): > - dropped > - patch 6 (new): > - add riscv_cpu_commit_profile() > - patch 7 (new): > - add user choice hash for MISA extensions > - patch 9 (new): > - handle MISA bits user choice when commiting profiles > - patch 8 and 10 (new): > - helpers to avoid code repetition > - v1 link: > https://lore.kernel.org/qemu-riscv/20230926194951.183767-1-dbarb...@ventanamicro.com/ > > > Daniel Henrique Barboza (10): > target/riscv/cpu.c: add zicntr extension flag > target/riscv/cpu.c: add zihpm extension flag > target/riscv: add rva22u64 profile definition > target/riscv/kvm: add 'rva22u64' flag as unavailable > target/riscv/tcg: add user flag for profile support > target/riscv/tcg: commit profiles during realize() > target/riscv/tcg: add MISA user options hash > target/riscv/tcg: add riscv_cpu_write_misa_bit() > target/riscv/tcg: handle MISA bits on profile commit > target/riscv/tcg: add hash table insert helpers > > target/riscv/cpu.c | 29 +++ > target/riscv/cpu.h | 12 +++ > target/riscv/cpu_cfg.h | 2 + > target/riscv/kvm/kvm-cpu.c | 7 +- > target/riscv/tcg/tcg-cpu.c | 165 + > 5 files changed, 197 insertions(+), 18 deletions(-) > > -- > 2.41.0 > >
Re: [PATCH v2 04/10] target/riscv/kvm: add 'rva22u64' flag as unavailable
On Fri, Oct 6, 2023 at 11:24 PM Daniel Henrique Barboza wrote: > > KVM does not have the means to support enabling the rva22u64 profile. > The main reasons are: > > - we're missing support for some mandatory rva22u64 extensions in the > KVM module; > > - we can't make promises about enabling a profile since it all depends > on host support in the end. > > We'll revisit this decision in the future if needed. For now mark the > 'rva22u64' profile as unavailable when running a KVM CPU: > > $ qemu-system-riscv64 -machine virt,accel=kvm -cpu rv64,rva22u64=true > qemu-system-riscv64: can't apply global rv64-riscv-cpu.rva22u64=true: > 'rva22u64' is not available with KVM > > Signed-off-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Alistair > --- > target/riscv/kvm/kvm-cpu.c | 7 ++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c > index c6615cb807..5f563b83df 100644 > --- a/target/riscv/kvm/kvm-cpu.c > +++ b/target/riscv/kvm/kvm-cpu.c > @@ -358,7 +358,7 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor > *v, > } > > if (value) { > -error_setg(errp, "extension %s is not available with KVM", > +error_setg(errp, "'%s' is not available with KVM", > propname); > } > } > @@ -438,6 +438,11 @@ static void kvm_riscv_add_cpu_user_properties(Object > *cpu_obj) > riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_extensions); > riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_vendor_exts); > riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, > riscv_cpu_experimental_exts); > + > + /* We don't have the needed KVM support for profiles */ > +for (i = 0; riscv_profiles[i] != NULL; i++) { > +riscv_cpu_add_kvm_unavail_prop(cpu_obj, riscv_profiles[i]->name); > +} > } > > static int kvm_riscv_get_regs_core(CPUState *cs) > -- > 2.41.0 > >
Re: [PATCH RFC v4 4/9] target/loongarch: Implement kvm get/set registers
Hi Li and Zhao, On 9/10/23 11:01, xianglai li wrote: From: Tianrui Zhao Implement kvm_arch_get/set_registers interfaces, many regs can be get/set in the function, such as core regs, csr regs, fpu regs, mp state, etc. Cc: "Michael S. Tsirkin" Cc: Cornelia Huck Cc: Paolo Bonzini Cc: "Marc-André Lureau" Cc: "Daniel P. Berrangé" Cc: Thomas Huth Cc: "Philippe Mathieu-Daudé" Cc: Richard Henderson Cc: Peter Maydell Cc: Bibo Mao Cc: Song Gao Cc: Xiaojuan Yang Cc: Tianrui Zhao Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li --- meson.build | 1 + target/loongarch/cpu.c| 3 + target/loongarch/cpu.h| 2 + target/loongarch/kvm.c| 406 +- target/loongarch/trace-events | 13 ++ target/loongarch/trace.h | 1 + 6 files changed, 424 insertions(+), 2 deletions(-) create mode 100644 target/loongarch/trace-events create mode 100644 target/loongarch/trace.h +static int kvm_larch_getq(CPUState *cs, uint64_t reg_id, + uint64_t *addr) +{ +struct kvm_one_reg csrreg = { +.id = reg_id, +.addr = (uintptr_t)addr +}; + +return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); +} This is kvm_get_one_reg(). +static int kvm_larch_putq(CPUState *cs, uint64_t reg_id, + uint64_t *addr) +{ +struct kvm_one_reg csrreg = { +.id = reg_id, +.addr = (uintptr_t)addr +}; + +return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); +} This is kvm_set_one_reg(). + +#define KVM_GET_ONE_UREG64(cs, ret, regidx, addr) \ +({\ +err = kvm_larch_getq(cs, KVM_IOC_CSRID(regidx), addr);\ +if (err < 0) {\ +ret = err;\ +trace_kvm_failed_get_csr(regidx, strerror(errno));\ +} \ +}) + +#define KVM_PUT_ONE_UREG64(cs, ret, regidx, addr) \ +({\ +err = kvm_larch_putq(cs, KVM_IOC_CSRID(regidx), addr);\ +if (err < 0) {\ +ret = err;\ +trace_kvm_failed_put_csr(regidx, strerror(errno));\ +} \ +})
Re: [PATCH v2 03/10] target/riscv: add rva22u64 profile definition
On Fri, Oct 6, 2023 at 11:23 PM Daniel Henrique Barboza wrote: > > The rva22U64 profile, described in: > > https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva22-profiles > > Contains a set of CPU extensions aimed for 64-bit userspace > applications. Enabling this set to be enabled via a single user flag > makes it convenient to enable a predictable set of features for the CPU, > giving users more predicability when running/testing their workloads. > > QEMU implements all possible extensions of this profile. The exception > is Zicbop (Cache-Block Prefetch Operations) that is not available since > QEMU RISC-V does not implement a cache model. For this same reason all > the so called 'synthetic extensions' described in the profile that are > cache related are ignored (Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa, > Zicclsm). > > An abstraction called RISCVCPUProfile is created to store the profile. > 'ext_offsets' contains mandatory extensions that QEMU supports. Same > thing with the 'misa_ext' mask. Optional extensions must be enabled > manually in the command line if desired. > > The design here is to use the common target/riscv/cpu.c file to store > the profile declaration and export it to the accelerator files. Each > accelerator is then responsible to expose it (or not) to users and how > to enable the extensions. > > Next patches will implement the profile for TCG and KVM. > > Signed-off-by: Daniel Henrique Barboza Acked-by: Alistair Francis Alistair > --- > target/riscv/cpu.c | 20 > target/riscv/cpu.h | 12 > 2 files changed, 32 insertions(+) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index b3befccf89..a439ff57a4 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -1376,6 +1376,26 @@ Property riscv_cpu_options[] = { > DEFINE_PROP_END_OF_LIST(), > }; > > +/* Optional extensions left out: RVV, zfh, zkn, zks */ > +static RISCVCPUProfile RVA22U64 = { > +.name = "rva22u64", > +.misa_ext = RVM | RVA | RVF | RVD | RVC, > +.ext_offsets = { > +CPU_CFG_OFFSET(ext_icsr), CPU_CFG_OFFSET(ext_zihintpause), > +CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb), > +CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin), > +CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_icntr), > +CPU_CFG_OFFSET(ext_ihpm), CPU_CFG_OFFSET(ext_icbom), > +CPU_CFG_OFFSET(ext_icboz), > + > +RISCV_PROFILE_EXT_LIST_END > +} > +}; > + > +RISCVCPUProfile *riscv_profiles[] = { > +&RVA22U64, NULL, > +}; > + > static Property riscv_cpu_properties[] = { > DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true), > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 3f11e69223..216bbbe7cd 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -66,6 +66,18 @@ const char *riscv_get_misa_ext_description(uint32_t bit); > > #define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop) > > +typedef struct riscv_cpu_profile { > +const char *name; > +uint32_t misa_ext; > +bool enabled; > +bool user_set; > +const int32_t ext_offsets[]; > +} RISCVCPUProfile; > + > +#define RISCV_PROFILE_EXT_LIST_END -1 > + > +extern RISCVCPUProfile *riscv_profiles[]; > + > /* Privileged specification version */ > enum { > PRIV_VERSION_1_10_0 = 0, > -- > 2.41.0 > >
Re: [PATCH 04/18] target: Declare FOO_CPU_TYPE_NAME/SUFFIX in 'cpu-qom.h'
On 2023/10/10 17:28, Philippe Mathieu-Daudé wrote: Hegerogeneous code needs access to the FOO_CPU_TYPE_NAME() macro to resolve target CPU types. Hi Philippe, I don't understand why should we use FOO_CPU_TYPE_NAME macro to resolve target CPU types? In my opinion, we should pass the CPU typename from command line for heterogeneous case. Could you make it clearer how should we use FOO_CPU_TYPE_NAME macro to resolve target CPU types in heterogeneous case? Thanks, Zhiwei Move the declaration (along with the required FOO_CPU_TYPE_SUFFIX) to "cpu-qom.h". Signed-off-by: Philippe Mathieu-Daudé --- target/alpha/cpu-qom.h | 5 - target/alpha/cpu.h | 2 -- target/avr/cpu-qom.h | 5 - target/avr/cpu.h | 2 -- target/cris/cpu-qom.h| 5 - target/cris/cpu.h| 2 -- target/i386/cpu-qom.h| 3 +++ target/i386/cpu.h| 2 -- target/m68k/cpu-qom.h| 5 - target/m68k/cpu.h| 2 -- target/mips/cpu-qom.h| 3 +++ target/mips/cpu.h| 2 -- target/rx/cpu-qom.h | 5 - target/rx/cpu.h | 2 -- target/s390x/cpu-qom.h | 5 - target/s390x/cpu.h | 2 -- target/sh4/cpu-qom.h | 5 - target/sh4/cpu.h | 2 -- target/sparc/cpu-qom.h | 5 - target/sparc/cpu.h | 2 -- target/tricore/cpu-qom.h | 5 + target/tricore/cpu.h | 2 -- target/xtensa/cpu-qom.h | 5 - target/xtensa/cpu.h | 2 -- 24 files changed, 47 insertions(+), 33 deletions(-) diff --git a/target/alpha/cpu-qom.h b/target/alpha/cpu-qom.h index 1f200724b6..d596d1b69f 100644 --- a/target/alpha/cpu-qom.h +++ b/target/alpha/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU Alpha CPU + * QEMU Alpha CPU QOM header (target agnostic) * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -27,6 +27,9 @@ OBJECT_DECLARE_CPU_TYPE(AlphaCPU, AlphaCPUClass, ALPHA_CPU) +#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU +#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX + /** * AlphaCPUClass: * @parent_realize: The parent class' realize handler. diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index e2a467ec17..ba0d9e3468 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -428,8 +428,6 @@ enum { void alpha_translate_init(void); -#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU -#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU void alpha_cpu_list(void); diff --git a/target/avr/cpu-qom.h b/target/avr/cpu-qom.h index 01ea5f160b..a810d6dc09 100644 --- a/target/avr/cpu-qom.h +++ b/target/avr/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU AVR CPU + * QEMU AVR CPU QOM header (target agnostic) * * Copyright (c) 2016-2020 Michael Rolnik * @@ -28,6 +28,9 @@ OBJECT_DECLARE_CPU_TYPE(AVRCPU, AVRCPUClass, AVR_CPU) +#define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU +#define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX) + /** * AVRCPUClass: * @parent_realize: The parent class' realize handler. diff --git a/target/avr/cpu.h b/target/avr/cpu.h index 4ce22d8e4f..d3f0cc65d4 100644 --- a/target/avr/cpu.h +++ b/target/avr/cpu.h @@ -28,8 +28,6 @@ #error "AVR 8-bit does not support user mode" #endif -#define AVR_CPU_TYPE_SUFFIX "-" TYPE_AVR_CPU -#define AVR_CPU_TYPE_NAME(name) (name AVR_CPU_TYPE_SUFFIX) #define CPU_RESOLVING_TYPE TYPE_AVR_CPU #define TCG_GUEST_DEFAULT_MO 0 diff --git a/target/cris/cpu-qom.h b/target/cris/cpu-qom.h index 431a1d536a..02a5b589b8 100644 --- a/target/cris/cpu-qom.h +++ b/target/cris/cpu-qom.h @@ -1,5 +1,5 @@ /* - * QEMU CRIS CPU + * QEMU CRIS CPU QOM header (target agnostic) * * Copyright (c) 2012 SUSE LINUX Products GmbH * @@ -27,6 +27,9 @@ OBJECT_DECLARE_CPU_TYPE(CRISCPU, CRISCPUClass, CRIS_CPU) +#define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU +#define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX) + /** * CRISCPUClass: * @parent_realize: The parent class' realize handler. diff --git a/target/cris/cpu.h b/target/cris/cpu.h index 676b8e93ca..1af7ae5ef9 100644 --- a/target/cris/cpu.h +++ b/target/cris/cpu.h @@ -242,8 +242,6 @@ enum { /* CRIS uses 8k pages. */ #define MMAP_SHIFT TARGET_PAGE_BITS -#define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU -#define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX) #define CPU_RESOLVING_TYPE TYPE_CRIS_CPU /* MMU modes definitions */ diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h index 2350f4ae60..78207c0a7c 100644 --- a/target/i386/cpu-qom.h +++ b/target/i386/cpu-qom.h @@ -32,6 +32,9 @@ OBJECT_DECLARE_CPU_TYPE(X86CPU, X86CPUClass, X86_CPU) +#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU +#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX) + typedef struct X86CPUModel X86CPUModel; /** diff --git a/target/i386/cpu.h b/target/i386/cpu.h index e1875466b9..862e4f1ff5 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2241,8 +2241,6 @@ v
Re: [PATCH v2 01/10] target/riscv/cpu.c: add zicntr extension flag
On Fri, Oct 6, 2023 at 11:23 PM Daniel Henrique Barboza wrote: > > zicntr is the Base Counters and Timers extension described in chapter 12 > of the unprivileged spec. It describes support for RDCYCLE, RDTIME and > RDINSTRET. > > QEMU already implements it way before it was a discrete extension. > zicntr is part of the RVA22 profile, so let's add it to QEMU to make the > future profile implementation flag complete. > > Given than it represents an already existing feature, default it to > 'true'. Change the realize() time validation to disable it in case its > dependency (icsr) isn't present. What happens if a user disables this though? Alistair > > Signed-off-by: Daniel Henrique Barboza > --- > target/riscv/cpu.c | 7 +++ > target/riscv/cpu_cfg.h | 1 + > target/riscv/tcg/tcg-cpu.c | 4 > 3 files changed, 12 insertions(+) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 521bb88538..8783a415b1 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -79,6 +79,7 @@ const RISCVIsaExtData isa_edata_arr[] = { > ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_icbom), > ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_icboz), > ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond), > +ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_icntr), > ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr), > ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei), > ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl), > @@ -1265,6 +1266,12 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { > MULTI_EXT_CFG_BOOL("svnapot", ext_svnapot, false), > MULTI_EXT_CFG_BOOL("svpbmt", ext_svpbmt, false), > > +/* > + * Always default true - we'll disable it during > + * realize() if needed. > + */ > +MULTI_EXT_CFG_BOOL("zicntr", ext_icntr, true), > + > MULTI_EXT_CFG_BOOL("zba", ext_zba, true), > MULTI_EXT_CFG_BOOL("zbb", ext_zbb, true), > MULTI_EXT_CFG_BOOL("zbc", ext_zbc, true), > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h > index 0e6a0f245c..671b8c7cb8 100644 > --- a/target/riscv/cpu_cfg.h > +++ b/target/riscv/cpu_cfg.h > @@ -62,6 +62,7 @@ struct RISCVCPUConfig { > bool ext_zksh; > bool ext_zkt; > bool ext_ifencei; > +bool ext_icntr; > bool ext_icsr; > bool ext_icbom; > bool ext_icboz; > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c > index 08b806dc07..df187bc143 100644 > --- a/target/riscv/tcg/tcg-cpu.c > +++ b/target/riscv/tcg/tcg-cpu.c > @@ -542,6 +542,10 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, > Error **errp) > cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zksh), true); > } > > +if (cpu->cfg.ext_icntr && !cpu->cfg.ext_icsr) { > +cpu->cfg.ext_icntr = false; > +} > + > /* > * Disable isa extensions based on priv spec after we > * validated and set everything we need. > -- > 2.41.0 > >
Re: [PATCH QEMU] tulip: Fix LXT970 PHY registers
Hi Dmitry, On 8/10/23 08:54, ~disean wrote: From: Dmitry Borisov Fix incorrect MII status value (0xf02c). Use default values from a 21143-based board: https://www.beowulf.org/pipermail/tulip-bug/2000-February/000485.html Thank you for your patch! Cc'ing the maintainers for this file (you can get them doing:) $ ./scripts/get_maintainer.pl -f hw/net/tulip.c Sven Schnelle (maintainer:tulip) Jason Wang (odd fixer:Network devices) Regards, Phil. Signed-off-by: Dmitry Borisov --- hw/net/tulip.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 hw/net/tulip.c diff --git a/hw/net/tulip.c b/hw/net/tulip.c old mode 100644 new mode 100755 index 915e5fb595..43e8f4bcb5 --- a/hw/net/tulip.c +++ b/hw/net/tulip.c @@ -415,14 +415,15 @@ static void tulip_update_rs(TULIPState *s, int state) trace_tulip_rx_state(tulip_rx_state_name(state)); } +/* LEVEL1 LXT970 PHY registers */ static uint16_t tulip_mdi_default[] = { /* MDI Registers 0 - 6, 7 */ -0x3100, 0xf02c, 0x7810, 0x, 0x0501, 0x4181, 0x, 0x, +0x1000, 0x782d, 0x7810, 0x0001, 0x01e1, 0x41e1, 0x0001, 0x, /* MDI Registers 8 - 15 */ 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x, /* MDI Registers 16 - 31 */ -0x0003, 0x, 0x0001, 0x, 0x, 0x, 0x, 0x, -0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x, +0x, 0x, 0x4000, 0x, 0x38c8, 0x0010, 0x, 0x0002, +0x0001, 0x, 0x, 0x, 0x, 0x, 0x, 0x, }; /* Readonly mask for MDI (PHY) registers */
Re: [PATCH v2 1/3] arm/kvm: convert to kvm_set_one_reg
On 10/10/23 16:24, Cornelia Huck wrote: We can neaten the code by switching to the kvm_set_one_reg function. Reviewed-by: Gavin Shan Signed-off-by: Cornelia Huck --- target/arm/kvm.c | 13 +++-- target/arm/kvm64.c | 66 +- 2 files changed, 21 insertions(+), 58 deletions(-) Reviewed-by: Philippe Mathieu-Daudé
Re: [PATCH v2 2/3] arm/kvm: convert to kvm_get_one_reg
On 10/10/23 16:24, Cornelia Huck wrote: We can neaten the code by switching the callers that work on a CPUstate to the kvm_get_one_reg function. Reviewed-by: Gavin Shan Signed-off-by: Cornelia Huck --- target/arm/kvm.c | 15 +++- target/arm/kvm64.c | 57 -- 2 files changed, 18 insertions(+), 54 deletions(-) Reviewed-by: Philippe Mathieu-Daudé
[PATCH v2] migration: Use g_autofree to simplify ram_dirty_bitmap_reload()
Signed-off-by: Philippe Mathieu-Daudé --- Based-on: v2: Do use g_autofree... --- migration/ram.c | 15 ++- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/migration/ram.c b/migration/ram.c index 982fbbeee1..a0e2ef4f1c 100644 --- a/migration/ram.c +++ b/migration/ram.c @@ -4164,11 +4164,11 @@ bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block, Error **errp) { /* from_dst_file is always valid because we're within rp_thread */ QEMUFile *file = s->rp_state.from_dst_file; -unsigned long *le_bitmap, nbits = block->used_length >> TARGET_PAGE_BITS; +g_autofree unsigned long *le_bitmap = NULL; +unsigned long nbits = block->used_length >> TARGET_PAGE_BITS; uint64_t local_size = DIV_ROUND_UP(nbits, 8); uint64_t size, end_mark; RAMState *rs = ram_state; -bool result = false; trace_ram_dirty_bitmap_reload_begin(block->idstr); @@ -4193,7 +4193,7 @@ bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block, Error **errp) if (size != local_size) { error_setg(errp, "ramblock '%s' bitmap size mismatch (0x%"PRIx64 " != 0x%"PRIx64")", block->idstr, size, local_size); -goto out; +return false; } size = qemu_get_buffer(file, (uint8_t *)le_bitmap, local_size); @@ -4203,13 +4203,13 @@ bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block, Error **errp) error_setg(errp, "read bitmap failed for ramblock '%s': " "(size 0x%"PRIx64", got: 0x%"PRIx64")", block->idstr, local_size, size); -goto out; +return false; } if (end_mark != RAMBLOCK_RECV_BITMAP_ENDING) { error_setg(errp, "ramblock '%s' end mark incorrect: 0x%"PRIx64, block->idstr, end_mark); -goto out; +return false; } /* @@ -4241,10 +4241,7 @@ bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block, Error **errp) */ migration_rp_kick(s); -result = true; -out: -g_free(le_bitmap); -return result; +return true; } static int ram_resume_prepare(MigrationState *s, void *opaque) -- 2.41.0
Re: [RFC PATCH 06/11] tests/avocado: Add FreeBSD distro boot tests for ppc
On Wed Oct 11, 2023 at 7:55 AM AEST, Warner Losh wrote: > On Tue, Oct 10, 2023 at 1:53 AM Nicholas Piggin wrote: > > > FreeBSD project provides qcow2 images that work well for testing QEMU. > > Add pseries tests for HPT and Radix, KVM and TCG. > > > > Other architectures could be added so this does not get a ppc_ prefix > > but is instead named similarly to boot_linux. > > > > Cc: Warner Losh > > Signed-off-by: Nicholas Piggin > > > > CC'ing Warner to check if it's okay for us to use these images and > > any comments or suggestions. avocado tests have many Linux boots so we'd > > do much better to expand test coverage by adding some other systems. > > > > I like this I'm a little worried at the exact hash encoded in it, but > since there's a checksum > to match, it's OK I guess. It will give this code a shelf-life of months, > IIRC our retention policy. The oldest 15.0 CURRENT image on there is May 1st, so ~6 months? That's not too bad. There are some release qcow2 images as well which sound like they're maintained longer-term: https://download.freebsd.org/releases/VM-IMAGES/ No builds for powerpc, but those might be preferable for other targets. Another option for powerpc might be to use a release .iso. It's much nicer to have a qcow image already installed though. I'll tinker with it a bit more, but may stick with the snapshot for now. Thanks, Nick
Re: [PATCH 0/2] hw/loongarch/virt: Remove unused ISA bus
在 2023/10/10 下午9:53, Philippe Mathieu-Daudé 写道: ISA bus and serial aren't used by the LoongArch virt machine. Remove the dead code. Philippe Mathieu-Daudé (2): hw/loongarch/virt: Remove unused ISA UART hw/loongarch/virt: Remove unused ISA Bus include/hw/loongarch/virt.h | 3 --- hw/loongarch/virt.c | 5 - hw/loongarch/Kconfig| 2 -- 3 files changed, 10 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao
RE: [PATCH v5 07/15] vfio/pci: Introduce vfio_[attach/detach]_device
Hi Eric, >-Original Message- >From: Eric Auger >Sent: Monday, October 9, 2023 5:09 PM >Subject: [PATCH v5 07/15] vfio/pci: Introduce vfio_[attach/detach]_device > >We want the VFIO devices to be able to use two different >IOMMU backends, the legacy VFIO one and the new iommufd one. > >Introduce vfio_[attach/detach]_device which aim at hiding the >underlying IOMMU backend (IOCTLs, datatypes, ...). > >Once vfio_attach_device completes, the device is attached >to a security context and its fd can be used. Conversely >When vfio_detach_device completes, the device has been >detached from the security context. > >At the moment only the implementation based on the legacy >container/group exists. Let's use it from the vfio-pci device. >Subsequent patches will handle other devices. > >We also take benefit of this patch to properly free >vbasedev->name on failure. > >Signed-off-by: Eric Auger >Signed-off-by: Yi Liu >Signed-off-by: Zhenzhong Duan >Reviewed-by: Cédric Le Goater > >--- > >v4 -> v5: >- remove vbasedev->name g_free as it is done on instance_finalize > >v2 -> v3: >- added trace_vfio_detach_device >- added a comment explaining why we pass @name to vfio_attach_device > although vbasedev->name is populated >- free vbasedev->name and detach_device if needed >--- > include/hw/vfio/vfio-common.h | 3 ++ > hw/vfio/common.c | 74 +++ > hw/vfio/pci.c | 66 +++ > hw/vfio/trace-events | 3 +- > 4 files changed, 93 insertions(+), 53 deletions(-) > >diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h >index c4e7c3b4a7..12fbfbc37d 100644 >--- a/include/hw/vfio/vfio-common.h >+++ b/include/hw/vfio/vfio-common.h >@@ -225,6 +225,9 @@ void vfio_put_group(VFIOGroup *group); > struct vfio_device_info *vfio_get_device_info(int fd); > int vfio_get_device(VFIOGroup *group, const char *name, > VFIODevice *vbasedev, Error **errp); >+int vfio_attach_device(char *name, VFIODevice *vbasedev, >+ AddressSpace *as, Error **errp); >+void vfio_detach_device(VFIODevice *vbasedev); > > int vfio_kvm_device_add_fd(int fd, Error **errp); > int vfio_kvm_device_del_fd(int fd, Error **errp); >diff --git a/hw/vfio/common.c b/hw/vfio/common.c >index d8ed432cb6..f4c33c9858 100644 >--- a/hw/vfio/common.c >+++ b/hw/vfio/common.c >@@ -2611,3 +2611,77 @@ int vfio_eeh_as_op(AddressSpace *as, uint32_t op) > } > return vfio_eeh_container_op(container, op); > } >+ >+static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp) >+{ >+char *tmp, group_path[PATH_MAX], *group_name; >+int ret, groupid; >+ssize_t len; >+ >+tmp = g_strdup_printf("%s/iommu_group", vbasedev->sysfsdev); >+len = readlink(tmp, group_path, sizeof(group_path)); >+g_free(tmp); >+ >+if (len <= 0 || len >= sizeof(group_path)) { >+ret = len < 0 ? -errno : -ENAMETOOLONG; >+error_setg_errno(errp, -ret, "no iommu_group found"); >+return ret; >+} >+ >+group_path[len] = 0; >+ >+group_name = basename(group_path); >+if (sscanf(group_name, "%d", &groupid) != 1) { >+error_setg_errno(errp, errno, "failed to read %s", group_path); >+return -errno; >+} >+return groupid; >+} >+ >+/* >+ * vfio_attach_device: attach a device to a security context >+ * @name and @vbasedev->name are likely to be different depending >+ * on the type of the device, hence the need for passing @name >+ */ >+int vfio_attach_device(char *name, VFIODevice *vbasedev, >+ AddressSpace *as, Error **errp) >+{ >+int groupid = vfio_device_groupid(vbasedev, errp); >+VFIODevice *vbasedev_iter; >+VFIOGroup *group; >+int ret; >+ >+if (groupid < 0) { >+return groupid; >+} >+ >+trace_vfio_attach_device(vbasedev->name, groupid); >+ >+group = vfio_get_group(groupid, as, errp); >+if (!group) { >+return -ENOENT; >+} >+ >+QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { >+if (strcmp(vbasedev_iter->name, vbasedev->name) == 0) { >+error_setg(errp, "device is already attached"); >+vfio_put_group(group); >+return -EBUSY; >+} >+} >+ret = vfio_get_device(group, name, vbasedev, errp); >+if (ret) { >+vfio_put_group(group); >+} >+ >+return ret; >+} >+ >+void vfio_detach_device(VFIODevice *vbasedev) >+{ >+VFIOGroup *group = vbasedev->group; >+ >+trace_vfio_detach_device(vbasedev->name, group->groupid); >+vfio_put_base_device(vbasedev); >+vfio_put_group(group); >+} >diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c >index 898296fd54..40ae46266e 100644 >--- a/hw/vfio/pci.c >+++ b/hw/vfio/pci.c >@@ -2895,10 +2895,10 @@ static void vfio_populate_device(VFIOPCIDevice >*vdev, Error **errp) > > static void vfio_pci_put_device(VFIOPCIDevice *vdev) > { >+vfio_detach_device(&vdev->vbasedev); >+ > g_free(vdev
Re: [PATCH] target/riscv: Fix vfwmaccbf16.vf
On Thu, Oct 5, 2023 at 8:29 PM Max Chou wrote: > > The operator (fwmacc16) of vfwmaccbf16.vf helper function should be > replaced by fwmaccbf16. > > Signed-off-by: Max Chou Thanks! Applied to riscv-to-apply.next Alistair > --- > target/riscv/vector_helper.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c > index 3fb05cc3d6e..c45d94c165c 100644 > --- a/target/riscv/vector_helper.c > +++ b/target/riscv/vector_helper.c > @@ -3361,7 +3361,7 @@ static uint32_t fwmaccbf16(uint16_t a, uint16_t b, > uint32_t d, float_status *s) > > RVVCALL(OPFVV3, vfwmaccbf16_vv, WOP_UUU_H, H4, H2, H2, fwmaccbf16) > GEN_VEXT_VV_ENV(vfwmaccbf16_vv, 4) > -RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmacc16) > +RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmaccbf16) > GEN_VEXT_VF(vfwmaccbf16_vf, 4) > > static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status > *s) > -- > 2.34.1 > >
Re: [PATCH v2 1/1] target/riscv: deprecate capital 'Z' CPU properties
On Mon, Oct 9, 2023 at 11:08 PM Daniel Henrique Barboza wrote: > > At this moment there are eleven CPU extension properties that starts > with capital 'Z': Zifencei, Zicsr, Zihintntl, Zihintpause, Zawrs, Zfa, > Zfh, Zfhmin, Zve32f, Zve64f and Zve64d. All other extensions are named > with lower-case letters. > > We want all properties to be named with lower-case letters since it's > consistent with the riscv-isa string that we create in the FDT. Having > these 11 properties to be exceptions can be confusing. > > Deprecate all of them. Create their lower-case counterpart to be used as > maintained CPU properties. When trying to use any deprecated property a > warning message will be displayed, recommending users to switch to the > lower-case variant: > > ./build/qemu-system-riscv64 -M virt -cpu rv64,Zifencei=true --nographic > qemu-system-riscv64: warning: CPU property 'Zifencei' is deprecated. Please > use 'zifencei' instead > > This will give users some time to change their scripts before we remove > the capital 'Z' properties entirely. > > Signed-off-by: Daniel Henrique Barboza > Reviewed-by: Alistair Francis > Reviewed-by: Andrew Jones Thanks! Applied to riscv-to-apply.next Alistair > --- > docs/about/deprecated.rst | 23 ++ > target/riscv/cpu.c | 39 +++--- > target/riscv/cpu.h | 1 + > target/riscv/tcg/tcg-cpu.c | 31 +- > 4 files changed, 82 insertions(+), 12 deletions(-) > > diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst > index 694b878f36..fda383b5a4 100644 > --- a/docs/about/deprecated.rst > +++ b/docs/about/deprecated.rst > @@ -378,6 +378,29 @@ of generic CPUs: rv32 and rv64 as default CPUs and 'max' > as a feature complete > CPU for both 32 and 64 bit builds. Users are then discouraged to use the > 'any' > CPU type starting in 8.2. > > +RISC-V CPU properties which start with capital 'Z' (since 8.2) > +^^ > + > +All RISC-V CPU properties which start with capital 'Z' are being deprecated > +starting in 8.2. The reason is that they were wrongly added with capital 'Z' > +in the past. CPU properties were later added with lower-case names, which > +is the format we want to use from now on. > + > +Users which try to use these deprecated properties will receive a warning > +recommending to switch to their stable counterparts: > + > +- "Zifencei" should be replaced with "zifencei" > +- "Zicsr" should be replaced with "zicsr" > +- "Zihintntl" should be replaced with "zihintntl" > +- "Zihintpause" should be replaced with "zihintpause" > +- "Zawrs" should be replaced with "zawrs" > +- "Zfa" should be replaced with "zfa" > +- "Zfh" should be replaced with "zfh" > +- "Zfhmin" should be replaced with "zfhmin" > +- "Zve32f" should be replaced with "zve32f" > +- "Zve64f" should be replaced with "zve64f" > +- "Zve64d" should be replaced with "zve64d" > + > Block device options > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 521bb88538..1cdc3d2609 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -1246,17 +1246,17 @@ const char *riscv_get_misa_ext_description(uint32_t > bit) > const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { > /* Defaults for standard extensions */ > MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false), > -MULTI_EXT_CFG_BOOL("Zifencei", ext_ifencei, true), > -MULTI_EXT_CFG_BOOL("Zicsr", ext_icsr, true), > -MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true), > -MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true), > -MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true), > -MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true), > -MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false), > -MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false), > -MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false), > -MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false), > -MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false), > +MULTI_EXT_CFG_BOOL("zifencei", ext_ifencei, true), > +MULTI_EXT_CFG_BOOL("zicsr", ext_icsr, true), > +MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true), > +MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true), > +MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true), > +MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true), > +MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false), > +MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false), > +MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false), > +MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false), > +MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false), > MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true), > > MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false), > @@ -1349,6 +1349,23 @@ const RISCVCPUMultiExtConfig > riscv_cpu_experimental_exts[] = { > DEFINE_PROP_END_OF_LIST(), > }; > > +/* Deprecated entries marked for future removal */ > +const RISCVCPUMultiExtConfig risc
Re: [PATCH 1/6] target/ppc: Use env_archcpu() in helper_book3s_msgsndp()
On Mon, Oct 9, 2023 at 9:03 PM Philippe Mathieu-Daudé wrote: > > When CPUArchState* is available (here CPUPPCState*), we > can use the fast env_archcpu() macro to get ArchCPU* (here > PowerPCCPU*). The QOM cast POWERPC_CPU() macro will be > slower when building with --enable-qom-cast-debug. > > Signed-off-by: Philippe Mathieu-Daudé Acked-by: Alistair Francis Alistair > --- > target/ppc/excp_helper.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c > index 7926114d5c..a42743a3e0 100644 > --- a/target/ppc/excp_helper.c > +++ b/target/ppc/excp_helper.c > @@ -3136,7 +3136,7 @@ void helper_book3s_msgclrp(CPUPPCState *env, > target_ulong rb) > void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) > { > CPUState *cs = env_cpu(env); > -PowerPCCPU *cpu = POWERPC_CPU(cs); > +PowerPCCPU *cpu = env_archcpu(env); > CPUState *ccs; > uint32_t nr_threads = cs->nr_threads; > int ttir = rb & PPC_BITMASK(57, 63); > -- > 2.41.0 > >
Re: [PATCH v3] target/riscv: Use env_archcpu for better performance
On Mon, Oct 9, 2023 at 10:50 PM Richard W.M. Jones wrote: > > RISCV_CPU(cs) uses a checked cast. When QOM cast debugging is enabled > this adds about 5% total overhead when emulating RV64 on x86-64 host. > > Using a RISC-V guest with 16 vCPUs, 16 GB of guest RAM, virtio-blk > disk. The guest has a copy of the qemu source tree. The test > involves compiling the qemu source tree with 'make clean; time make -j16'. > > Before making this change the compile step took 449 & 447 seconds over > two consecutive runs. > > After making this change: 428 & 421 seconds. > > The saving is over 5%. > > Thanks: Paolo Bonzini > Thanks: Philippe Mathieu-Daudé > Signed-off-by: Richard W.M. Jones Thanks! Applied to riscv-to-apply.next Alistair > --- > target/riscv/cpu_helper.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > index 3a02079290..8c28241c18 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -65,8 +65,7 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) > void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, >uint64_t *cs_base, uint32_t *pflags) > { > -CPUState *cs = env_cpu(env); > -RISCVCPU *cpu = RISCV_CPU(cs); > +RISCVCPU *cpu = env_archcpu(env); > RISCVExtStatus fs, vs; > uint32_t flags = 0; > > -- > 2.41.0 > >
Re: [PATCH 3/6] target/s390x: Use env_archcpu() in handle_diag_308()
On Mon, Oct 9, 2023 at 9:04 PM Philippe Mathieu-Daudé wrote: > > When CPUArchState* is available (here CPUS390XState*), we > can use the fast env_archcpu() macro to get ArchCPU* (here > S390CPU*). The QOM cast S390_CPU() macro will be slower when > building with --enable-qom-cast-debug. > > Signed-off-by: Philippe Mathieu-Daudé Acked-by: Alistair Francis Alistair > --- > target/s390x/diag.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/target/s390x/diag.c b/target/s390x/diag.c > index 8ce18e08f3..27ffd48576 100644 > --- a/target/s390x/diag.c > +++ b/target/s390x/diag.c > @@ -77,7 +77,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, > uint64_t r3, uintptr_t ra) > { > bool valid; > CPUState *cs = env_cpu(env); > -S390CPU *cpu = S390_CPU(cs); > +S390CPU *cpu = env_archcpu(env); > uint64_t addr = env->regs[r1]; > uint64_t subcode = env->regs[r3]; > IplParameterBlock *iplb; > -- > 2.41.0 > >
Re: [PATCH 4/6] target/xtensa: Use env_archcpu() in update_c[compare|count]()
On Mon, Oct 9, 2023 at 9:03 PM Philippe Mathieu-Daudé wrote: > > When CPUArchState* is available (here CPUXtensaState*), we > can use the fast env_archcpu() macro to get ArchCPU* (here > XtensaCPU*). The QOM cast XTENSA_CPU() macro will be slower > when building with --enable-qom-cast-debug. > > Signed-off-by: Philippe Mathieu-Daudé Acked-by: Alistair Francis Alistair > --- > target/xtensa/op_helper.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c > index 7bb8cd6726..496754ba57 100644 > --- a/target/xtensa/op_helper.c > +++ b/target/xtensa/op_helper.c > @@ -37,7 +37,7 @@ > > void HELPER(update_ccount)(CPUXtensaState *env) > { > -XtensaCPU *cpu = XTENSA_CPU(env_cpu(env)); > +XtensaCPU *cpu = env_archcpu(env); > uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); > > env->ccount_time = now; > @@ -58,7 +58,7 @@ void HELPER(wsr_ccount)(CPUXtensaState *env, uint32_t v) > > void HELPER(update_ccompare)(CPUXtensaState *env, uint32_t i) > { > -XtensaCPU *cpu = XTENSA_CPU(env_cpu(env)); > +XtensaCPU *cpu = env_archcpu(env); > uint64_t dcc; > > qatomic_and(&env->sregs[INTSET], > -- > 2.41.0 > >
Re: [PATCH 2/6] target/riscv: Use env_archcpu() in [check_]nanbox()
On Mon, Oct 9, 2023 at 9:03 PM Philippe Mathieu-Daudé wrote: > > When CPUArchState* is available (here CPURISCVState*), we > can use the fast env_archcpu() macro to get ArchCPU* (here > RISCVCPU*). The QOM cast RISCV_CPU() macro will be slower > when building with --enable-qom-cast-debug. > > Inspired-by: Richard W.M. Jones > Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Alistair > --- > target/riscv/internals.h | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/target/riscv/internals.h b/target/riscv/internals.h > index b5f823c7ec..8239ae83cc 100644 > --- a/target/riscv/internals.h > +++ b/target/riscv/internals.h > @@ -87,7 +87,7 @@ enum { > static inline uint64_t nanbox_s(CPURISCVState *env, float32 f) > { > /* the value is sign-extended instead of NaN-boxing for zfinx */ > -if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) { > +if (env_archcpu(env)->cfg.ext_zfinx) { > return (int32_t)f; > } else { > return f | MAKE_64BIT_MASK(32, 32); > @@ -97,7 +97,7 @@ static inline uint64_t nanbox_s(CPURISCVState *env, float32 > f) > static inline float32 check_nanbox_s(CPURISCVState *env, uint64_t f) > { > /* Disable NaN-boxing check when enable zfinx */ > -if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) { > +if (env_archcpu(env)->cfg.ext_zfinx) { > return (uint32_t)f; > } > > @@ -113,7 +113,7 @@ static inline float32 check_nanbox_s(CPURISCVState *env, > uint64_t f) > static inline uint64_t nanbox_h(CPURISCVState *env, float16 f) > { > /* the value is sign-extended instead of NaN-boxing for zfinx */ > -if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) { > +if (env_archcpu(env)->cfg.ext_zfinx) { > return (int16_t)f; > } else { > return f | MAKE_64BIT_MASK(16, 48); > @@ -123,7 +123,7 @@ static inline uint64_t nanbox_h(CPURISCVState *env, > float16 f) > static inline float16 check_nanbox_h(CPURISCVState *env, uint64_t f) > { > /* Disable nanbox check when enable zfinx */ > -if (RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) { > +if (env_archcpu(env)->cfg.ext_zfinx) { > return (uint16_t)f; > } > > -- > 2.41.0 > >
Re: [PATCH v3] target/riscv: Use env_archcpu for better performance
On Mon, Oct 9, 2023 at 10:50 PM Richard W.M. Jones wrote: > > RISCV_CPU(cs) uses a checked cast. When QOM cast debugging is enabled > this adds about 5% total overhead when emulating RV64 on x86-64 host. > > Using a RISC-V guest with 16 vCPUs, 16 GB of guest RAM, virtio-blk > disk. The guest has a copy of the qemu source tree. The test > involves compiling the qemu source tree with 'make clean; time make -j16'. > > Before making this change the compile step took 449 & 447 seconds over > two consecutive runs. > > After making this change: 428 & 421 seconds. > > The saving is over 5%. > > Thanks: Paolo Bonzini > Thanks: Philippe Mathieu-Daudé > Signed-off-by: Richard W.M. Jones Reviewed-by: Alistair Francis Alistair > --- > target/riscv/cpu_helper.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > index 3a02079290..8c28241c18 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -65,8 +65,7 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) > void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, >uint64_t *cs_base, uint32_t *pflags) > { > -CPUState *cs = env_cpu(env); > -RISCVCPU *cpu = RISCV_CPU(cs); > +RISCVCPU *cpu = env_archcpu(env); > RISCVExtStatus fs, vs; > uint32_t flags = 0; > > -- > 2.41.0 > >
Re: [PATCH 2/3] target/riscv: Support discontinuous PMU counters
On Tue, Oct 10, 2023 at 4:00 AM Atish Kumar Patra wrote: > > On Sun, Oct 8, 2023 at 5:58 PM Alistair Francis wrote: > > > > On Wed, Oct 4, 2023 at 7:36 PM Rob Bradford wrote: > > > > > > Hi Atish, > > > > > > On Tue, 2023-10-03 at 13:25 -0700, Atish Kumar Patra wrote: > > > > On Tue, Oct 3, 2023 at 5:51 AM Rob Bradford > > > > wrote: > > > > > > > > > > There is no requirement that the enabled counters in the platform > > > > > are > > > > > continuously numbered. Add a "pmu-mask" property that, if > > > > > specified, can > > > > > be used to specify the enabled PMUs. In order to avoid ambiguity if > > > > > "pmu-mask" is specified then "pmu-num" must also match the number > > > > > of > > > > > bits set in the mask. > > > > > > > > > > Signed-off-by: Rob Bradford > > > > > --- > > > > > target/riscv/cpu.c | 1 + > > > > > target/riscv/cpu_cfg.h | 1 + > > > > > target/riscv/pmu.c | 15 +-- > > > > > 3 files changed, 15 insertions(+), 2 deletions(-) > > > > > > > > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > > > > > index 9d79c20c1a..b89b006a76 100644 > > > > > --- a/target/riscv/cpu.c > > > > > +++ b/target/riscv/cpu.c > > > > > @@ -1817,6 +1817,7 @@ static void > > > > > riscv_cpu_add_misa_properties(Object *cpu_obj) > > > > > static Property riscv_cpu_extensions[] = { > > > > > /* Defaults for standard extensions */ > > > > > DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), > > > > > +DEFINE_PROP_UINT32("pmu-mask", RISCVCPU, cfg.pmu_mask, 0), > > > > > DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, > > > > > false), > > > > > DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), > > > > > DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), > > > > > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h > > > > > index 0e6a0f245c..40f7d970bc 100644 > > > > > --- a/target/riscv/cpu_cfg.h > > > > > +++ b/target/riscv/cpu_cfg.h > > > > > @@ -124,6 +124,7 @@ struct RISCVCPUConfig { > > > > > bool ext_XVentanaCondOps; > > > > > > > > > > uint8_t pmu_num; > > > > > +uint32_t pmu_mask; > > > > > char *priv_spec; > > > > > char *user_spec; > > > > > char *bext_spec; > > > > > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c > > > > > index 13801ccb78..f97e25a1f6 100644 > > > > > --- a/target/riscv/pmu.c > > > > > +++ b/target/riscv/pmu.c > > > > > @@ -437,6 +437,13 @@ int riscv_pmu_setup_timer(CPURISCVState *env, > > > > > uint64_t value, uint32_t ctr_idx) > > > > > void riscv_pmu_init(RISCVCPU *cpu, Error **errp) > > > > > { > > > > > uint8_t pmu_num = cpu->cfg.pmu_num; > > > > > +uint32_t pmu_mask = cpu->cfg.pmu_mask; > > > > > + > > > > > +if (pmu_mask && ctpop32(pmu_mask) != pmu_num) { > > > > > +error_setg(errp, "Mismatch between number of enabled > > > > > counters in " > > > > > + "\"pmu-mask\" and \"pmu-num\""); > > > > > +return; > > > > > +} > > > > > > > > > > > > > Is that necessary for the default case? I am thinking of marking > > > > pmu-num as deprecated and pmu-mask > > > > as the preferred way of doing things as it is more flexible. There is > > > > no real benefit carrying both. > > > > The default pmu-mask value will change in that case. > > > > We can just overwrite pmu-num with ctpop32(pmu_mask) if pmu-mask is > > > > available. Thoughts ? > > > > > > > > > > I agree it makes sense to me that there is only one way for the user to > > > adjust the PMU count. However i'm not sure how we can handle the > > > transition if we choose to deprecate "pmu-num". > > > > > > If we change the default "pmu-mask" to MAKE_32BIT_MASK(3, 16) then that > > > value in the config will always be set - you propose that we overwrite > > > "pmu-num" with the popcount of that property. But that will break if > > > > Couldn't we deprecate "pmu-num" and then throw an error if both are > > set? Then we can migrate away from "pmu-num" > > > > Yeah. pmu-num should be only available as a command line property and > marked deprecated. > If only pmu-num is set, it gets converted to a mask and throws a warning > that this is a deprecated property. > If only the pmu-mask is set, nothing additional is needed. These > patches are sufficient. > If nothing is set, the pmu-mask will be set to MAKE_32BIT_MASK(3, 16). That all sounds good to me, and if both are set we can throw an error. Alistair > If a CPU init code uses pmu-num, we should change it to mask. The upstream > code > doesn't have any other usage. Any downstream user will have to move > away from pmu-num > once this series is merged. > > > Alistair > > > > > the user has an existing setup that changes the value of "pmu-num" > > > (either as a property at runtime or in the CPU init code). > > > > > > One option would be to not make the mask configurable as property and > > > make choosing the layout of the counters something that the specialised > > > CPU init can
Re: [PATCH 16/25] target/arm: Remove references to gdb_has_xml
On Tue, Oct 10, 2023 at 3:52 AM Alex Bennée wrote: > > From: Akihiko Odaki > > GDB has XML support since 6.7 which was released in 2007. > It's time to remove support for old GDB versions without XML support. > > Signed-off-by: Akihiko Odaki > Acked-by: Alex Bennée > Message-Id: <20230912224107.29669-10-akihiko.od...@daynix.com> > Signed-off-by: Alex Bennée Reviewed-by: Alistair Francis Alistair > --- > target/arm/gdbstub.c | 32 ++-- > 1 file changed, 2 insertions(+), 30 deletions(-) > > diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c > index 8fc8351df7..b7ace24bfc 100644 > --- a/target/arm/gdbstub.c > +++ b/target/arm/gdbstub.c > @@ -46,21 +46,7 @@ int arm_cpu_gdb_read_register(CPUState *cs, GByteArray > *mem_buf, int n) > /* Core integer register. */ > return gdb_get_reg32(mem_buf, env->regs[n]); > } > -if (n < 24) { > -/* FPA registers. */ > -if (gdb_has_xml()) { > -return 0; > -} > -return gdb_get_zeroes(mem_buf, 12); > -} > -switch (n) { > -case 24: > -/* FPA status register. */ > -if (gdb_has_xml()) { > -return 0; > -} > -return gdb_get_reg32(mem_buf, 0); > -case 25: > +if (n == 25) { > /* CPSR, or XPSR for M-profile */ > if (arm_feature(env, ARM_FEATURE_M)) { > return gdb_get_reg32(mem_buf, xpsr_read(env)); > @@ -100,21 +86,7 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t > *mem_buf, int n) > env->regs[n] = tmp; > return 4; > } > -if (n < 24) { /* 16-23 */ > -/* FPA registers (ignored). */ > -if (gdb_has_xml()) { > -return 0; > -} > -return 12; > -} > -switch (n) { > -case 24: > -/* FPA status register (ignored). */ > -if (gdb_has_xml()) { > -return 0; > -} > -return 4; > -case 25: > +if (n == 25) { > /* CPSR, or XPSR for M-profile */ > if (arm_feature(env, ARM_FEATURE_M)) { > /* > -- > 2.39.2 > >
Re: Accessing emulated CXL memory is unstable
On Wed, Oct 11, 2023 at 12:54 AM Gregory Price wrote: > > On Tue, Oct 10, 2023 at 10:35:03AM +0900, Hyeonggon Yoo wrote: > > Hello folks, > > > > I experienced strange application crashes/internal KVM errors > > while playing with emulated type 3 CXL memory. I would like to know > > if this is a real issue or I missed something during setup. > > > > TL;DR: applications crash when accessing emulated CXL memory, > > and stressing VM subsystem causes KVM internal error > > (stressing via stress-ng --bigheap) > > > ... > > > > Hmm... it crashed, and it's 'invalid opcode'. > > Is this because the fetched instruction is different from what's > > written to memory during exec()? > > > > This is a known issue, and the working theory is 2 issues: Okay, at least it's a known issue. Thank you for confirming that! > > 1) CXL devices are implemented on top of an MMIO-style dispatch system >and as a result memory from CXL is non-cacheable. We think there >may be an issue with this in KVM but it hasn't been investigated >fully. > > 2) When we originally got CXL memory support, we discovered an edge case >where code pages hosted on CXL memory would cause a crash whenever an >instruction spanned across a page barrier. A similar issue could >affect KVM. > > We haven't done much research into the problem beyond this. For now, we > all just turn KVM off while we continue development. Thank you for summarizing the current state of the issue. Hope it will be resolved! ;) But I'm not sure if turning off KVM solves the problem. `numactl --membind=1 --show` works fine, but other basic UNIX commands like ls crashes QEMU when it's bind to the CXL NUMA node. [root@localhost ~]# numactl --membind=1 --show policy: bind preferred node: 1 physcpubind: 0 cpubind: 0 nodebind: 0 membind: 1 [root@localhost ~]# numactl --membind=1 ls qemu: fatal: cpu_io_recompile: could not find TB for pc=(nil) RAX=777f8000 RBX= RCX=0028 RDX= RSI=0354 RDI= RBP=88810628af40 RSP=c98cfd20 R8 =88810628af40 R9 =c98cfcc4 R10=000d R11= R12=00039044 R13=888107a464c0 R14= R15=88810a49cd18 RIP=810743e6 RFL=0007 [-PC] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES = CS =0010 00af9b00 DPL=0 CS64 [-RA] SS = DS = FS = GS = 88817bc0 LDT= 8200 DPL=0 LDT TR =0040 fe003000 4087 8900 DPL=0 TSS64-avl GDT= fe001000 007f IDT= fe00 0fff CR0=80050033 CR2=7fcb2504641c CR3=00039044 CR4=007506f0 DR0= DR1= DR2= DR3= DR6=0ff0 DR7=0400 CCS=777f8000 CCD=00039044 CCO=ADDQ EFER=0d01 FCW=037f FSW= [ST=0] FTW=00 MXCSR=1f80 FPR0= FPR1= FPR2= FPR3= FPR4= FPR5= FPR6= FPR7= YMM00= YMM01= YMM02= YMM03= YMM04= 6968705f6e6f 65786c6c6577 YMM05= YMM06= YMM07= YMM08= YMM09= YMM10= YMM11= YMM12= YMM13= YMM14= YMM15= cxl2.sh: line 24: 5386 Aborted (core dumped) $QEMU -cpu Cascadelake-Server -smp 1 -M q35,cxl=on -m 4G,maxmem=8G,slots=4 -object memory-backend-ram,id=vmem0,share=on,size=4G -device pxb-cc -- Cheers, Hyeonggon
Re: [PATCH 05/25] tests/docker: make docker engine choice entirely configure driven
On Tue, Oct 10, 2023 at 4:05 AM Alex Bennée wrote: > > Since 0b1a649047 (tests/docker: use direct RUNC call to build > containers) we ended up with the potential for the remaining docker.py > script calls to deviate from the direct RUNC calls. Fix this by > dropping the use of ENGINE in the makefile and rely entirely on what > we detect at configure time. > > We also tweak the RUNC detection so podman users can still run things > from the source tree. > > Signed-off-by: Alex Bennée Reviewed-by: Alistair Francis Alistair > > --- > v2 > - add RUNC stanza suggested by Paolo > --- > configure | 1 - > tests/docker/Makefile.include | 9 +++-- > 2 files changed, 3 insertions(+), 7 deletions(-) > > diff --git a/configure b/configure > index e08127045d..707132a3ae 100755 > --- a/configure > +++ b/configure > @@ -1694,7 +1694,6 @@ if test -n "$gdb_bin"; then > fi > > if test "$container" != no; then > -echo "ENGINE=$container" >> $config_host_mak > echo "RUNC=$runc" >> $config_host_mak > fi > echo "SUBDIRS=$subdirs" >> $config_host_mak > diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include > index dfabafab92..ab68b2dbad 100644 > --- a/tests/docker/Makefile.include > +++ b/tests/docker/Makefile.include > @@ -16,9 +16,8 @@ DOCKER_DEFAULT_REGISTRY := > registry.gitlab.com/qemu-project/qemu > endif > DOCKER_REGISTRY := $(if $(REGISTRY),$(REGISTRY),$(DOCKER_DEFAULT_REGISTRY)) > > -RUNC ?= docker > -ENGINE ?= auto > -DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(ENGINE) > +RUNC ?= $(if $(shell command -v docker), docker, podman) > +DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(RUNC) > > CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.) > DOCKER_SRC_COPY := $(BUILD_DIR)/docker-src.$(CUR_TIME) > @@ -158,7 +157,7 @@ $(foreach i,$(filter-out > $(DOCKER_PARTIAL_IMAGES),$(DOCKER_IMAGES)), \ > ) > > docker: > - @echo 'Build QEMU and run tests inside Docker or Podman containers' > + @echo 'Build QEMU and run tests inside $(RUNC) containers' > @echo > @echo 'Available targets:' > @echo > @@ -198,8 +197,6 @@ docker: > @echo 'EXECUTABLE=Include executable in image.' > @echo 'EXTRA_FILES=" [... ]"' > @echo ' Include extra files in image.' > - @echo 'ENGINE=auto/docker/podman' > - @echo ' Specify which container engine to > run.' > @echo 'REGISTRY=url Cache builds from registry > (default:$(DOCKER_REGISTRY))' > > docker-help: docker > -- > 2.39.2 > >
Re: [PATCH 08/25] gdbstub: Fix target_xml initialization
On Tue, Oct 10, 2023 at 4:36 AM Alex Bennée wrote: > > From: Akihiko Odaki > > target_xml is no longer a fixed-length array but a pointer to a > variable-length memory. > > Fixes: 56e534bd11 ("gdbstub: refactor get_feature_xml") > Signed-off-by: Akihiko Odaki > Reviewed-by: Philippe Mathieu-Daudé > Message-Id: <20230912224107.29669-2-akihiko.od...@daynix.com> > Signed-off-by: Alex Bennée Reviewed-by: Alistair Francis Alistair > --- > gdbstub/softmmu.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/gdbstub/softmmu.c b/gdbstub/softmmu.c > index 9f0b8b5497..42645d2220 100644 > --- a/gdbstub/softmmu.c > +++ b/gdbstub/softmmu.c > @@ -292,7 +292,7 @@ static int find_cpu_clusters(Object *child, void *opaque) > assert(cluster->cluster_id != UINT32_MAX); > process->pid = cluster->cluster_id + 1; > process->attached = false; > -process->target_xml[0] = '\0'; > +process->target_xml = NULL; > > return 0; > } > -- > 2.39.2 > >
Re: [PATCH 06/25] configure: allow user to override docker engine
On Tue, Oct 10, 2023 at 3:52 AM Alex Bennée wrote: > > If you have both engines installed but one is broken you are stuck > with the automagic. Allow the user to override the engine for this > case. > > Signed-off-by: Alex Bennée Reviewed-by: Alistair Francis Alistair > --- > configure | 8 ++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/configure b/configure > index 707132a3ae..ebad155d9e 100755 > --- a/configure > +++ b/configure > @@ -180,6 +180,7 @@ fi > # some defaults, based on the host environment > > # default parameters > +container_engine="auto" > cpu="" > cross_compile="no" > cross_prefix="" > @@ -787,6 +788,8 @@ for opt do >;; >--disable-containers) use_containers="no" >;; > + --container-engine=*) container_engine="$optarg" > + ;; >--gdb=*) gdb_bin="$optarg" >;; ># everything else has the same name in configure and meson > @@ -921,6 +924,7 @@ Advanced options (experts only): >--enable-plugins > enable plugins via shared library loading >--disable-containers don't use containers for cross-building > + --container-engine=TYPE which container engine to use [$container_engine] >--gdb=GDB-path gdb to use for gdbstub tests [$gdb_bin] > EOF >meson_options_help > @@ -1195,14 +1199,14 @@ fi > container="no" > runc="" > if test $use_containers = "yes" && (has "docker" || has "podman"); then > -case $($python "$source_path"/tests/docker/docker.py probe) in > +case $($python "$source_path"/tests/docker/docker.py --engine > "$container_engine" probe) in > *docker) container=docker ;; > podman) container=podman ;; > no) container=no ;; > esac > if test "$container" != "no"; then > docker_py="$python $source_path/tests/docker/docker.py --engine > $container" > -runc=$($python "$source_path"/tests/docker/docker.py probe) > +runc=$container > fi > fi > > -- > 2.39.2 > >
Re: [PATCH 18/25] gdbstub: Remove gdb_has_xml variable
On Tue, Oct 10, 2023 at 2:48 AM Alex Bennée wrote: > > From: Akihiko Odaki > > GDB has XML support since 6.7 which was released in 2007. > It's time to remove support for old GDB versions without XML support. > > Signed-off-by: Akihiko Odaki > Message-Id: <20230912224107.29669-12-akihiko.od...@daynix.com> > Signed-off-by: Alex Bennée Reviewed-by: Alistair Francis Alistair > --- > gdbstub/internals.h| 2 -- > include/exec/gdbstub.h | 8 > gdbstub/gdbstub.c | 15 --- > 3 files changed, 25 deletions(-) > > diff --git a/gdbstub/internals.h b/gdbstub/internals.h > index fee243081f..7128c4aa85 100644 > --- a/gdbstub/internals.h > +++ b/gdbstub/internals.h > @@ -32,8 +32,6 @@ enum { > typedef struct GDBProcess { > uint32_t pid; > bool attached; > - > -/* If gdb sends qXfer:features:read:target.xml this will be populated */ > char *target_xml; > } GDBProcess; > > diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h > index 705be2c5d7..1a01c35f8e 100644 > --- a/include/exec/gdbstub.h > +++ b/include/exec/gdbstub.h > @@ -45,14 +45,6 @@ int gdbserver_start(const char *port_or_device); > > void gdb_set_stop_cpu(CPUState *cpu); > > -/** > - * gdb_has_xml() - report of gdb supports modern target descriptions > - * > - * This will report true if the gdb negotiated qXfer:features:read > - * target descriptions. > - */ > -bool gdb_has_xml(void); > - > /* in gdbstub-xml.c, generated by scripts/feature_to_c.py */ > extern const GDBFeature gdb_static_features[]; > > diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c > index 3dc847f835..62608a5389 100644 > --- a/gdbstub/gdbstub.c > +++ b/gdbstub/gdbstub.c > @@ -349,11 +349,6 @@ static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid) > } > } > > -bool gdb_has_xml(void) > -{ > -return !!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml; > -} > - > static const char *get_feature_xml(const char *p, const char **newp, > GDBProcess *process) > { > @@ -1086,11 +1081,6 @@ static void handle_set_reg(GArray *params, void > *user_ctx) > { > int reg_size; > > -if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) { > -gdb_put_packet(""); > -return; > -} > - > if (params->len != 2) { > gdb_put_packet("E22"); > return; > @@ -1107,11 +1097,6 @@ static void handle_get_reg(GArray *params, void > *user_ctx) > { > int reg_size; > > -if (!gdb_get_cpu_process(gdbserver_state.g_cpu)->target_xml) { > -gdb_put_packet(""); > -return; > -} > - > if (!params->len) { > gdb_put_packet("E14"); > return; > -- > 2.39.2 > >
Re: [PATCH 19/25] gdbstub: Replace gdb_regs with an array
On Tue, Oct 10, 2023 at 2:47 AM Alex Bennée wrote: > > From: Akihiko Odaki > > An array is a more appropriate data structure than a list for gdb_regs > since it is initialized only with append operation and read-only after > initialization. > > Signed-off-by: Akihiko Odaki > Message-Id: <20230912224107.29669-13-akihiko.od...@daynix.com> > [AJB: fixed a checkpatch violation] > Signed-off-by: Alex Bennée Reviewed-by: Alistair Francis Alistair > --- > include/hw/core/cpu.h | 2 +- > gdbstub/gdbstub.c | 35 +-- > 2 files changed, 22 insertions(+), 15 deletions(-) > > diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h > index 7b8347ed5a..3968369554 100644 > --- a/include/hw/core/cpu.h > +++ b/include/hw/core/cpu.h > @@ -502,7 +502,7 @@ struct CPUState { > > CPUJumpCache *tb_jmp_cache; > > -struct GDBRegisterState *gdb_regs; > +GArray *gdb_regs; > int gdb_num_regs; > int gdb_num_g_regs; > QTAILQ_ENTRY(CPUState) node; > diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c > index 62608a5389..b1532118d1 100644 > --- a/gdbstub/gdbstub.c > +++ b/gdbstub/gdbstub.c > @@ -51,7 +51,6 @@ typedef struct GDBRegisterState { > gdb_get_reg_cb get_reg; > gdb_set_reg_cb set_reg; > const char *xml; > -struct GDBRegisterState *next; > } GDBRegisterState; > > GDBState gdbserver_state; > @@ -386,7 +385,8 @@ static const char *get_feature_xml(const char *p, const > char **newp, > xml, > g_markup_printf_escaped("", > cc->gdb_core_xml_file)); > -for (r = cpu->gdb_regs; r; r = r->next) { > +for (guint i = 0; i < cpu->gdb_regs->len; i++) { > +r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); > g_ptr_array_add( > xml, > g_markup_printf_escaped("", > @@ -430,7 +430,8 @@ static int gdb_read_register(CPUState *cpu, GByteArray > *buf, int reg) > return cc->gdb_read_register(cpu, buf, reg); > } > > -for (r = cpu->gdb_regs; r; r = r->next) { > +for (guint i = 0; i < cpu->gdb_regs->len; i++) { > +r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); > if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { > return r->get_reg(env, buf, reg - r->base_reg); > } > @@ -448,7 +449,8 @@ static int gdb_write_register(CPUState *cpu, uint8_t > *mem_buf, int reg) > return cc->gdb_write_register(cpu, mem_buf, reg); > } > > -for (r = cpu->gdb_regs; r; r = r->next) { > +for (guint i = 0; i < cpu->gdb_regs->len; i++) { > +r = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); > if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { > return r->set_reg(env, mem_buf, reg - r->base_reg); > } > @@ -461,17 +463,23 @@ void gdb_register_coprocessor(CPUState *cpu, >int num_regs, const char *xml, int g_pos) > { > GDBRegisterState *s; > -GDBRegisterState **p; > - > -p = &cpu->gdb_regs; > -while (*p) { > -/* Check for duplicates. */ > -if (strcmp((*p)->xml, xml) == 0) > -return; > -p = &(*p)->next; > +guint i; > + > +if (cpu->gdb_regs) { > +for (i = 0; i < cpu->gdb_regs->len; i++) { > +/* Check for duplicates. */ > +s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); > +if (strcmp(s->xml, xml) == 0) { > +return; > +} > +} > +} else { > +cpu->gdb_regs = g_array_new(false, false, sizeof(GDBRegisterState)); > +i = 0; > } > > -s = g_new0(GDBRegisterState, 1); > +g_array_set_size(cpu->gdb_regs, i + 1); > +s = &g_array_index(cpu->gdb_regs, GDBRegisterState, i); > s->base_reg = cpu->gdb_num_regs; > s->num_regs = num_regs; > s->get_reg = get_reg; > @@ -480,7 +488,6 @@ void gdb_register_coprocessor(CPUState *cpu, > > /* Add to end of list. */ > cpu->gdb_num_regs += num_regs; > -*p = s; > if (g_pos) { > if (g_pos != s->base_reg) { > error_report("Error: Bad gdb register numbering for '%s', " > -- > 2.39.2 > >
Re: [PATCH 14/25] hw/core/cpu: Return static value with gdb_arch_name()
On Tue, Oct 10, 2023 at 2:44 AM Alex Bennée wrote: > > From: Akihiko Odaki > > All implementations of gdb_arch_name() returns dynamic duplicates of > static strings. It's also unlikely that there will be an implementation > of gdb_arch_name() that returns a truly dynamic value due to the nature > of the function returning a well-known identifiers. Qualify the value > gdb_arch_name() with const and make all of its implementations return > static strings. > > Signed-off-by: Akihiko Odaki > Reviewed-by: Alex Bennée > Message-Id: <20230912224107.29669-8-akihiko.od...@daynix.com> > Signed-off-by: Alex Bennée Reviewed-by: Alistair Francis Alistair > --- > include/hw/core/cpu.h | 2 +- > target/ppc/internal.h | 2 +- > gdbstub/gdbstub.c | 3 +-- > target/arm/cpu.c | 6 +++--- > target/arm/cpu64.c | 4 ++-- > target/i386/cpu.c | 6 +++--- > target/loongarch/cpu.c | 8 > target/ppc/gdbstub.c | 6 +++--- > target/riscv/cpu.c | 6 +++--- > target/s390x/cpu.c | 4 ++-- > target/tricore/cpu.c | 4 ++-- > 11 files changed, 25 insertions(+), 26 deletions(-) > > diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h > index e02bc5980f..7b8347ed5a 100644 > --- a/include/hw/core/cpu.h > +++ b/include/hw/core/cpu.h > @@ -165,7 +165,7 @@ struct CPUClass { > vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr); > > const char *gdb_core_xml_file; > -gchar * (*gdb_arch_name)(CPUState *cpu); > +const gchar * (*gdb_arch_name)(CPUState *cpu); > const char * (*gdb_get_dynamic_xml)(CPUState *cpu, const char *xmlname); > > void (*disas_set_info)(CPUState *cpu, disassemble_info *info); > diff --git a/target/ppc/internal.h b/target/ppc/internal.h > index 15803bc313..c881c67a8b 100644 > --- a/target/ppc/internal.h > +++ b/target/ppc/internal.h > @@ -221,7 +221,7 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu); > > /* gdbstub.c */ > void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc); > -gchar *ppc_gdb_arch_name(CPUState *cs); > +const gchar *ppc_gdb_arch_name(CPUState *cs); > > /** > * prot_for_access_type: > diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c > index bba2640293..a20169c27b 100644 > --- a/gdbstub/gdbstub.c > +++ b/gdbstub/gdbstub.c > @@ -380,10 +380,9 @@ static const char *get_feature_xml(const char *p, const > char **newp, > ""); > > if (cc->gdb_arch_name) { > -g_autofree gchar *arch = cc->gdb_arch_name(cpu); > g_string_append_printf(xml, > "%s", > - arch); > + cc->gdb_arch_name(cpu)); > } > g_string_append(xml, " g_string_append(xml, cc->gdb_core_xml_file); > diff --git a/target/arm/cpu.c b/target/arm/cpu.c > index b65e8cfea3..6c6c551573 100644 > --- a/target/arm/cpu.c > +++ b/target/arm/cpu.c > @@ -2319,15 +2319,15 @@ static Property arm_cpu_properties[] = { > DEFINE_PROP_END_OF_LIST() > }; > > -static gchar *arm_gdb_arch_name(CPUState *cs) > +static const gchar *arm_gdb_arch_name(CPUState *cs) > { > ARMCPU *cpu = ARM_CPU(cs); > CPUARMState *env = &cpu->env; > > if (arm_feature(env, ARM_FEATURE_IWMMXT)) { > -return g_strdup("iwmmxt"); > +return "iwmmxt"; > } > -return g_strdup("arm"); > +return "arm"; > } > > #ifndef CONFIG_USER_ONLY > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c > index 811f3b38c2..1cb9d5b81a 100644 > --- a/target/arm/cpu64.c > +++ b/target/arm/cpu64.c > @@ -781,9 +781,9 @@ static void aarch64_cpu_finalizefn(Object *obj) > { > } > > -static gchar *aarch64_gdb_arch_name(CPUState *cs) > +static const gchar *aarch64_gdb_arch_name(CPUState *cs) > { > -return g_strdup("aarch64"); > +return "aarch64"; > } > > static void aarch64_cpu_class_init(ObjectClass *oc, void *data) > diff --git a/target/i386/cpu.c b/target/i386/cpu.c > index 9fad31b8db..c09bab4281 100644 > --- a/target/i386/cpu.c > +++ b/target/i386/cpu.c > @@ -5915,12 +5915,12 @@ static void x86_cpu_load_model(X86CPU *cpu, > X86CPUModel *model) > memset(&env->user_features, 0, sizeof(env->user_features)); > } > > -static gchar *x86_gdb_arch_name(CPUState *cs) > +static const gchar *x86_gdb_arch_name(CPUState *cs) > { > #ifdef TARGET_X86_64 > -return g_strdup("i386:x86-64"); > +return "i386:x86-64"; > #else > -return g_strdup("i386"); > +return "i386"; > #endif > } > > diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c > index 2bea7ca5d5..ef1bf89dac 100644 > --- a/target/loongarch/cpu.c > +++ b/target/loongarch/cpu.c > @@ -766,9 +766,9 @@ static void loongarch_cpu_class_init(ObjectClass *c, void > *data) > #endif > } > > -static gchar *loongarch32_gdb_arch_name(CPUState *cs) > +static const gchar *loongarch32_gdb_arch_name(CPUState *cs) > { > -return g_strdup("loongarch32"); > +return "loongarch32"; > } > >
Re: [PATCH 10/18] target/riscv: Inline target specific TYPE_RISCV_CPU_BASE definition
On Tue, Oct 10, 2023 at 7:32 PM Philippe Mathieu-Daudé wrote: > > TYPE_RISCV_CPU_BASE depends on the TARGET_RISCV32/TARGET_RISCV64 > definitions which are target specific. Such target specific > definition taints "cpu-qom.h". > > Since "cpu-qom.h" must be target agnostic, remove its target > specific definition uses by inlining TYPE_RISCV_CPU_BASE in the > two machines using it. > > "target/riscv/cpu-qom.h" is now fully target agnostic. > > Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Alistair > --- > target/riscv/cpu-qom.h | 8 +--- > hw/riscv/spike.c | 8 +++- > hw/riscv/virt.c| 8 +++- > 3 files changed, 15 insertions(+), 9 deletions(-) > > diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h > index 8cb67b84a4..f607687384 100644 > --- a/target/riscv/cpu-qom.h > +++ b/target/riscv/cpu-qom.h > @@ -1,5 +1,5 @@ > /* > - * QEMU RISC-V CPU QOM header > + * QEMU RISC-V CPU QOM header (target agnostic) > * > * Copyright (c) 2023 Ventana Micro Systems Inc. > * > @@ -43,12 +43,6 @@ > #define TYPE_RISCV_CPU_VEYRON_V1RISCV_CPU_TYPE_NAME("veyron-v1") > #define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host") > > -#if defined(TARGET_RISCV32) > -# define TYPE_RISCV_CPU_BASETYPE_RISCV_CPU_BASE32 > -#elif defined(TARGET_RISCV64) > -# define TYPE_RISCV_CPU_BASETYPE_RISCV_CPU_BASE64 > -#endif > - > typedef struct CPUArchState CPURISCVState; > > OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU) > diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c > index 81f7e53aed..eae49da6d6 100644 > --- a/hw/riscv/spike.c > +++ b/hw/riscv/spike.c > @@ -349,7 +349,13 @@ static void spike_machine_class_init(ObjectClass *oc, > void *data) > mc->init = spike_board_init; > mc->max_cpus = SPIKE_CPUS_MAX; > mc->is_default = true; > -mc->default_cpu_type = TYPE_RISCV_CPU_BASE; > +#if defined(TARGET_RISCV32) > +mc->default_cpu_type = TYPE_RISCV_CPU_BASE32; > +#elif defined(TARGET_RISCV64) > +mc->default_cpu_type = TYPE_RISCV_CPU_BASE64; > +#else > +#error unsupported target > +#endif > mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids; > mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props; > mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id; > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c > index 5edc1d98d2..620a4e5f07 100644 > --- a/hw/riscv/virt.c > +++ b/hw/riscv/virt.c > @@ -1685,7 +1685,13 @@ static void virt_machine_class_init(ObjectClass *oc, > void *data) > mc->desc = "RISC-V VirtIO board"; > mc->init = virt_machine_init; > mc->max_cpus = VIRT_CPUS_MAX; > -mc->default_cpu_type = TYPE_RISCV_CPU_BASE; > +#if defined(TARGET_RISCV32) > +mc->default_cpu_type = TYPE_RISCV_CPU_BASE32; > +#elif defined(TARGET_RISCV64) > +mc->default_cpu_type = TYPE_RISCV_CPU_BASE64; > +#else > +#error unsupported target > +#endif > mc->pci_allow_0_address = true; > mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids; > mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props; > -- > 2.41.0 > >
Re: [RFC PATCH 06/11] tests/avocado: Add FreeBSD distro boot tests for ppc
On Wed Oct 11, 2023 at 7:55 AM AEST, Warner Losh wrote: > On Tue, Oct 10, 2023 at 1:53 AM Nicholas Piggin wrote: > > > FreeBSD project provides qcow2 images that work well for testing QEMU. > > Add pseries tests for HPT and Radix, KVM and TCG. > > > > Other architectures could be added so this does not get a ppc_ prefix > > but is instead named similarly to boot_linux. > > > > Cc: Warner Losh > > Signed-off-by: Nicholas Piggin > > > > CC'ing Warner to check if it's okay for us to use these images and > > any comments or suggestions. avocado tests have many Linux boots so we'd > > do much better to expand test coverage by adding some other systems. > > > > I like this I'm a little worried at the exact hash encoded in it, but > since there's a checksum > to match, it's OK I guess. It will give this code a shelf-life of months, > IIRC our retention policy. Oh I didn't realise, I saw some 2021 dates in the directory listing but looks like they're not for the artifacts themselves. I don't suppose you know if there are any long-term artifacts kept around, or someone who I could ask? The downside of using short term images is that it can be harder to reproduce reports from others, bisect, run manual testing, etc. I think these would still be useful, so long as they get updated regularly. > > Other than that, I think this is good. Not familiar enough with Avocado to > understand > skipping for gitlab CI, but given the extreme crunch on minutes, I think > that's OK. Yeah I'm not sure what the situation there is, I didn't want to add new tests of any significant weight yet. We could always flip it on later if people want it. > > Other than one nit below which is fine if it is intentionally left behind > (or removed): > > Reviewed-by: Warner Losh > > Please don't hesitate to reach out to me if this is failing. I'll act as a > backstop to get > it to the right people. Thanks Warner. > > Warner > > [snip] > > +def run_pseries_test(self, force_HPT=False): > > +# We need zstd for all the tuxrun tests > > +# See https://github.com/avocado-framework/avocado/issues/5609 > > +zstd = find_command('zstd', False) > > +if zstd is False: > > +self.cancel('Could not find "zstd", which is required to ' > > +'decompress rootfs') > > +self.zstd = zstd > > + > > +drive_url = (' > > https://artifact.ci.freebsd.org/snapshot/15.0-CURRENT/a2440348eed75bb7682579af0905b652747fd016/powerpc/powerpc64le/disk.qcow2.zst > > ') > > +drive_hash = '8ab11a05ccab3d44215fd4667a70454ed10a203f' > > +drive_path_zstd = self.fetch_asset(drive_url, > > asset_hash=drive_hash) > > +drive_path = os.path.join(self.workdir, 'disk.qcow2') > > +# archive.zstd_uncompress(drive_path_zstd, drive_path) > > > > Why is this commented out? It looks like a leftover maybe? > Ah yes, avocado recently got zstd_uncompress but it seems not available for QEMU yet so we have to do it by hand. I'll remove. Thanks, Nick
Re: [RFC PATCH 08/11] tests/avocado: Add ppc MacOS tests
On Tue Oct 10, 2023 at 5:58 PM AEST, Philippe Mathieu-Daudé wrote: > Hi Nicholas, > > On 10/10/23 09:52, Nicholas Piggin wrote: > > Similarly to the AIX test, this adds some tests that can boot MacOS9 > > and OSX images that are provided. > > --- > > tests/avocado/ppc/macos9.ppm | Bin 0 -> 921615 bytes > > tests/avocado/ppc_macos.py | 90 +++ > > 2 files changed, 90 insertions(+) > > create mode 100644 tests/avocado/ppc/macos9.ppm > > create mode 100644 tests/avocado/ppc_macos.py > > > > diff --git a/tests/avocado/ppc_macos.py b/tests/avocado/ppc_macos.py > > new file mode 100644 > > index 00..055fc3aca4 > > --- /dev/null > > +++ b/tests/avocado/ppc_macos.py > > @@ -0,0 +1,90 @@ > > +# Functional test that boots MacOS on ppc mac99 > > +# > > +# Copyright (c) 2023 IBM Corporation > > +# > > +# This work is licensed under the terms of the GNU GPL, version 2 or > > +# later. See the COPYING file in the top-level directory. > > + > > +import time > > +import tempfile > > +import filecmp > > +import os > > + > > +from typing import List > > +from avocado.utils import archive > > +from avocado_qemu import QemuSystemTest > > +from avocado_qemu import wait_for_console_pattern > > + > > +class PPCMacOSTest(QemuSystemTest): > > + > > +timeout = 240 > > + > > +def test_macos9(self): > > +""" > > +:avocado: tags=arch:ppc > > +:avocado: tags=machine:mac99 > > +:avocado: tags=device:framebuffer > > +""" > > + > > +basedir = os.getenv('AVOCADO_TEST_BASEDIR') > > +screenshot_path = os.path.join(basedir, 'ppc/macos9.ppm') > > + > > +image = os.getenv('MACOS9_IMAGE') > > +if not image: > > +self.cancel('No MACOS9_IMAGE environment variable defined') > > +drive_path = self.fetch_asset(image) > > + > > +self.vm.set_console() > > +self.vm.add_args('-M', 'via=pmu') > > +self.vm.add_args('-m', '1g') > > +self.vm.add_args('-cpu', 'G4') > > +self.vm.add_args('-drive', 'file=' + drive_path) > > +#self.vm.add_args('-net', 'nic,model=rtl8139') > > +#self.vm.add_args('-net', > > 'user,hostfwd=:127.0.0.1:2223-:22,hostname=qemu') > > +self.vm.add_args('-vga', 'std') > > +self.vm.add_args('-g', '640x480') > > +self.vm.launch() > > + > > +# This comes up after 60 seconds on a fast x86 CPU. Give it > > +# 180s to be sure. > > +time.sleep(180) > > +with tempfile.NamedTemporaryFile(suffix='.ppm', > > + prefix='screendump-', > > delete=False) as ppmfile: > > +self.vm.command('screendump', filename=ppmfile.name) > > +if not filecmp.cmp(ppmfile.name, screenshot_path): > > +self.fail('Screenshot does not match') > > + > > Nitpicking, I'd rather use: > > @skipUntil(os.getenv('MACOS10_IMAGE'), >'No MACOS10_IMAGE environment variable defined') Aha I didn't know about that one. I don't think it's nitpicking, that's a good suggestion, thank you. > > +def test_macos10(self): > > +""" > > +:avocado: tags=arch:ppc > > +:avocado: tags=machine:mac99 > > +:avocado: tags=device:framebuffer > > +""" > > + > > +basedir = os.getenv('AVOCADO_TEST_BASEDIR') > > +screenshot_path = os.path.join(basedir, 'ppc/macos10.ppm') > > + > > +image = os.getenv('MACOS10_IMAGE') > > +if not image: > > +self.cancel('No MACOS10_IMAGE environment variable defined') > > +drive_path = self.fetch_asset(image) > > Please commit the hash if the image you used. Sure. > > > +self.vm.set_console() > > +self.vm.add_args('-M', 'via=pmu') > > +self.vm.add_args('-m', '1g') > > +self.vm.add_args('-cpu', 'G4') > > +self.vm.add_args('-drive', 'file=' + drive_path) > > +#self.vm.add_args('-net', 'nic,model=rtl8139') > > +#self.vm.add_args('-net', > > 'user,hostfwd=:127.0.0.1:2223-:22,hostname=qemu') > > Why is that commented? If not needed, just drop, since your test > is already useful as it. Yeah I will. That was the option used by some scripts here but it doesn't seem to work for me here, whereas the default IIRC sungem does get networking up. Could be a QEMU regression so I was meaning to try a bisect. Thanks for the feedback on these. I'll leave the MacOS and AIX ones out of the next ppc PR so there is more time for thought and discussion about them. Thanks, Nick
Re: [PATCH v2 3/3] arm/kvm: convert to read_sys_reg64
On 10/11/23 00:24, Cornelia Huck wrote: We can use read_sys_reg64 to get the SVE_VLS register instead of calling GET_ONE_REG directly. Suggested-by: Gavin Shan Signed-off-by: Cornelia Huck --- target/arm/kvm64.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) Reviewed-by: Gavin Shan diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 558c0b88dd69..d40c89a84752 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -500,10 +500,6 @@ uint32_t kvm_arm_sve_get_vls(CPUState *cs) .target = -1, .features[0] = (1 << KVM_ARM_VCPU_SVE), }; -struct kvm_one_reg reg = { -.id = KVM_REG_ARM64_SVE_VLS, -.addr = (uint64_t)&vls[0], -}; int fdarray[3], ret; probed = true; @@ -512,7 +508,7 @@ uint32_t kvm_arm_sve_get_vls(CPUState *cs) error_report("failed to create scratch VCPU with SVE enabled"); abort(); } -ret = ioctl(fdarray[2], KVM_GET_ONE_REG, ®); +ret = read_sys_reg64(fdarray[2], &vls[0], KVM_REG_ARM64_SVE_VLS); kvm_arm_destroy_scratch_host_vcpu(fdarray); if (ret) { error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s",
Re: [PATCH v4 07/10] hw/arm: Hook up FSI module in AST2600
Hello Cedric, Thanks for the review. On 9/11/23 07:43, Cédric Le Goater wrote: On 9/9/23 00:28, Ninad Palsule wrote: This patchset introduces IBM's Flexible Service Interface(FSI). Time for some fun with inter-processor buses. FSI allows a service processor access to the internal buses of a host POWER processor to perform configuration or debugging. FSI has long existed in POWER processes and so comes with some baggage, including how it has been integrated into the ASPEED SoC. Working backwards from the POWER processor, the fundamental pieces of interest for the implementation are: 1. The Common FRU Access Macro (CFAM), an address space containing various "engines" that drive accesses on buses internal and external to the POWER chip. Examples include the SBEFIFO and I2C masters. The engines hang off of an internal Local Bus (LBUS) which is described by the CFAM configuration block. 2. The FSI slave: The slave is the terminal point of the FSI bus for FSI symbols addressed to it. Slaves can be cascaded off of one another. The slave's configuration registers appear in address space of the CFAM to which it is attached. 3. The FSI master: A controller in the platform service processor (e.g. BMC) driving CFAM engine accesses into the POWER chip. At the hardware level FSI is a bit-based protocol supporting synchronous and DMA-driven accesses of engines in a CFAM. 4. The On-Chip Peripheral Bus (OPB): A low-speed bus typically found in POWER processors. This now makes an appearance in the ASPEED SoC due to tight integration of the FSI master IP with the OPB, mainly the existence of an MMIO-mapping of the CFAM address straight onto a sub-region of the OPB address space. 5. An APB-to-OPB bridge enabling access to the OPB from the ARM core in the AST2600. Hardware limitations prevent the OPB from being directly mapped into APB, so all accesses are indirect through the bridge. The implementation appears as following in the qemu device tree: (qemu) info qtree bus: main-system-bus type System ... dev: aspeed.apb2opb, id "" gpio-out "sysbus-irq" 1 mmio 1e79b000/1000 bus: opb.1 type opb dev: fsi.master, id "" bus: fsi.bus.1 type fsi.bus dev: cfam.config, id "" dev: cfam, id "" bus: lbus.1 type lbus dev: scratchpad, id "" address = 0 (0x0) bus: opb.0 type opb dev: fsi.master, id "" bus: fsi.bus.0 type fsi.bus dev: cfam.config, id "" dev: cfam, id "" bus: lbus.0 type lbus dev: scratchpad, id "" address = 0 (0x0) The LBUS is modelled to maintain the qdev bus hierarchy and to take advantage of the object model to automatically generate the CFAM configuration block. The configuration block presents engines in the order they are attached to the CFAM's LBUS. Engine implementations should subclass the LBusDevice and set the 'config' member of LBusDeviceClass to match the engine's type. CFAM designs offer a lot of flexibility, for instance it is possible for a CFAM to be simultaneously driven from multiple FSI links. The modeling is not so complete; it's assumed that each CFAM is attached to a single FSI slave (as a consequence the CFAM subclasses the FSI slave). As for FSI, its symbols and wire-protocol are not modelled at all. This is not necessary to get FSI off the ground thanks to the mapping of the CFAM address space onto the OPB address space - the models follow this directly and map the CFAM memory region into the OPB's memory region. Future work includes supporting more advanced accesses that drive the FSI master directly rather than indirectly via the CFAM mapping, which will require implementing the FSI state machine and methods for each of the FSI symbols on the slave. Further down the track we can also look at supporting the bitbanged SoftFSI drivers in Linux by extending the FSI slave model to resolve sequences of GPIO IRQs into FSI symbols, and calling the associated symbol method on the slave to map the access onto the CFAM. Testing: Tested by reading cfam config address 0 on rainier machine type. root@p10bmc:~# pdbg -a getcfam 0x0 p0: 0x0 = 0xc0022d15 Signed-off-by: Andrew Jeffery Signed-off-by: Cédric Le Goater Signed-off-by: Ninad Palsule you might want to add a specific fsi realize routine if extra devices need to be realized at the board level. yes, we need to handle that once we are ready to add more devices. Thanks! ~Ninad Reviewed-by: Cédric Le Goater Thanks, C. --- hw/arm/aspeed_ast2600.c | 19 +++ include/hw/arm/aspeed_soc.h | 4 2 files changed, 23 insertions(+) d
Re: [PATCH v4 06/10] hw/fsi: Aspeed APB2OPB interface
Hello Cedric, Thanks for the review. On 9/11/23 07:41, Cédric Le Goater wrote: On 9/9/23 00:28, Ninad Palsule wrote: This is a part of patchset where IBM's Flexible Service Interface is introduced. An APB-to-OPB bridge enabling access to the OPB from the ARM core in the AST2600. Hardware limitations prevent the OPB from being directly mapped into APB, so all accesses are indirect through the bridge. Signed-off-by: Andrew Jeffery Signed-off-by: Cédric Le Goater Signed-off-by: Ninad Palsule --- v2: - Incorporated review comments by Joel v3: - Incorporated review comments by Thomas Huth v4: - Compile FSI with ASPEED_SOC only. --- hw/arm/Kconfig | 1 + hw/fsi/Kconfig | 20 +- hw/fsi/aspeed-apb2opb.c | 352 hw/fsi/meson.build | 9 +- hw/fsi/trace-events | 3 +- hw/fsi/trace.h | 1 + include/hw/fsi/aspeed-apb2opb.h | 33 +++ meson.build | 1 + 8 files changed, 407 insertions(+), 13 deletions(-) create mode 100644 hw/fsi/aspeed-apb2opb.c create mode 100644 hw/fsi/trace.h create mode 100644 include/hw/fsi/aspeed-apb2opb.h diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 7e68348440..d963de74c9 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -555,6 +555,7 @@ config ASPEED_SOC select LED select PMBUS select MAX31785 + select FSI_APB2OPB_ASPEED config MPS2 bool diff --git a/hw/fsi/Kconfig b/hw/fsi/Kconfig index 560ce536db..6bbcb8f6ca 100644 --- a/hw/fsi/Kconfig +++ b/hw/fsi/Kconfig @@ -1,19 +1,23 @@ -config OPB +config FSI_APB2OPB_ASPEED bool - select CFAM + select FSI_OPB -config CFAM +config FSI_OPB + bool + select FSI_CFAM + +config FSI_CFAM bool select FSI - select SCRATCHPAD - select LBUS + select FSI_SCRATCHPAD + select FSI_LBUS config FSI bool -config SCRATCHPAD +config FSI_SCRATCHPAD bool - select LBUS + select FSI_LBUS -config LBUS +config FSI_LBUS bool Some of these changes belong to another patch. Fixed it. diff --git a/hw/fsi/aspeed-apb2opb.c b/hw/fsi/aspeed-apb2opb.c new file mode 100644 index 00..88eabd8a73 --- /dev/null +++ b/hw/fsi/aspeed-apb2opb.c @@ -0,0 +1,352 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2023 IBM Corp. + * + * ASPEED APB-OPB FSI interface + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qom/object.h" +#include "qapi/error.h" +#include "trace.h" + +#include "hw/fsi/aspeed-apb2opb.h" +#include "hw/qdev-core.h" + +#define TO_REG(x) (x >> 2) +#define GENMASK(t, b) (((1ULL << ((t) + 1)) - 1) & ~((1ULL << (b)) - 1)) + +#define APB2OPB_VERSION TO_REG(0x00) +#define APB2OPB_VERSION_VER GENMASK(7, 0) + +#define APB2OPB_TRIGGER TO_REG(0x04) +#define APB2OPB_TRIGGER_EN BIT(0) + +#define APB2OPB_CONTROL TO_REG(0x08) +#define APB2OPB_CONTROL_OFF GENMASK(31, 13) + +#define APB2OPB_OPB2FSI TO_REG(0x0c) +#define APB2OPB_OPB2FSI_OFF GENMASK(31, 22) + +#define APB2OPB_OPB0_SEL TO_REG(0x10) +#define APB2OPB_OPB1_SEL TO_REG(0x28) +#define APB2OPB_OPB_SEL_EN BIT(0) + +#define APB2OPB_OPB0_MODE TO_REG(0x14) +#define APB2OPB_OPB1_MODE TO_REG(0x2c) +#define APB2OPB_OPB_MODE_RD BIT(0) + +#define APB2OPB_OPB0_XFER TO_REG(0x18) +#define APB2OPB_OPB1_XFER TO_REG(0x30) +#define APB2OPB_OPB_XFER_FULL BIT(1) +#define APB2OPB_OPB_XFER_HALF BIT(0) + +#define APB2OPB_OPB0_ADDR TO_REG(0x1c) +#define APB2OPB_OPB0_WRITE_DATA TO_REG(0x20) + +#define APB2OPB_OPB1_DMA_EN TO_REG(0x24) +#define APB2OPB_OPB1_DMA_EN_3 BIT(3) +#define APB2OPB_OPB1_DMA_EN_2 BIT(2) +#define APB2OPB_OPB1_DMA_EN_1 BIT(1) +#define APB2OPB_OPB1_DMA_EN_0 BIT(0) + +#define APB2OPB_OPB1_ADDR TO_REG(0x34) +#define APB2OPB_OPB1_WRITE_DATA TO_REG(0x38) + +#define APB2OPB_OPB_CLK TO_REG(0x3c) +#define APB2OPB_OPB_CLK_SYNC BIT(0) + +#define APB2OPB_IRQ_CLEAR TO_REG(0x40) +#define APB2OPB_IRQ_CLEAR_EN BIT(0) + +#define APB2OPB_IRQ_MASK TO_REG(0x44) +#define APB2OPB_IRQ_MASK_OPB1_TX_ACK BIT(17) +#define APB2OPB_IRQ_MASK_OPB0_TX_ACK BIT(16) +#define APB2OPB_IRQ_MASK_CH3_TCONT BIT(15) +#define APB2OPB_IRQ_MASK_CH2_TCONT BIT(14) +#define APB2OPB_IRQ_MASK_CH1_TCONT BIT(13) +#define APB2OPB_IRQ_MASK_CH0_TCONT BIT(12) +#define APB2OPB_IRQ_MASK_CH3_FIFO_EMPTY BIT(11) +#define APB2OPB_IRQ_MASK_CH2_FIFO_EMPTY BIT(10) +#define APB2OPB_IRQ_MASK_CH1_FIFO_EMPTY BIT(9) +#defin
Re: [QEMU][PATCH v1 2/7] xen: add pseudo RAM region for grant mappings
On Tue, 10 Oct 2023, Vikram Garhwal wrote: > On Mon, Oct 09, 2023 at 05:02:14PM -0700, Stefano Stabellini wrote: > > On Thu, 5 Oct 2023, Vikram Garhwal wrote: > > > From: Juergen Gross > > > > > > Add a memory region which can be used to automatically map granted > > > memory. It is starting at 0x8000ULL in order to be able to > > > distinguish it from normal RAM. > > > > > > For this reason the xen.ram memory region is expanded, which has no > > > further impact as it is used just as a container of the real RAM > > > regions and now the grant region. > > > > > > Signed-off-by: Juergen Gross > > > Signed-off-by: Vikram Garhwal > > > > This patch doesn't apply to staging anymore > Will re-base it. I rebased it against master branch. > > > > > > > --- > > > hw/i386/xen/xen-hvm.c | 3 ++ > > > hw/xen/xen-hvm-common.c | 4 +-- > > > hw/xen/xen-mapcache.c | 27 ++ > > > include/exec/ram_addr.h | 1 + > > > include/hw/xen/xen-hvm-common.h | 2 ++ > > > include/hw/xen/xen_pvdev.h | 3 ++ > > > include/sysemu/xen-mapcache.h | 3 ++ > > > softmmu/physmem.c | 62 + > > > 8 files changed, 80 insertions(+), 25 deletions(-) > > > > > > diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c > > > index f42621e674..67a8a6 100644 > > > --- a/hw/i386/xen/xen-hvm.c > > > +++ b/hw/i386/xen/xen-hvm.c > > > @@ -172,6 +172,9 @@ static void xen_ram_init(PCMachineState *pcms, > > > x86ms->above_4g_mem_size); > > > memory_region_add_subregion(sysmem, 0x1ULL, &ram_hi); > > > } > > > + > > > +/* Add grant mappings as a pseudo RAM region. */ > > > +ram_grants = *xen_init_grant_ram(); > > > } > > > > > > static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size) > > > diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c > > > index 565dc39c8f..b7255977a5 100644 > > > --- a/hw/xen/xen-hvm-common.c > > > +++ b/hw/xen/xen-hvm-common.c > > > @@ -9,7 +9,7 @@ > > > #include "hw/boards.h" > > > #include "hw/xen/arch_hvm.h" > > > > > > -MemoryRegion ram_memory; > > > +MemoryRegion ram_memory, ram_grants; > > > > > > void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion > > > *mr, > > > Error **errp) > > > @@ -26,7 +26,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t > > > size, MemoryRegion *mr, > > > return; > > > } > > > > > > -if (mr == &ram_memory) { > > > +if (mr == &ram_memory || mr == &ram_grants) { > > > return; > > > } > > > > > > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c > > > index f7d974677d..8115c44c00 100644 > > > --- a/hw/xen/xen-mapcache.c > > > +++ b/hw/xen/xen-mapcache.c > > > @@ -14,7 +14,9 @@ > > > > > > #include > > > > > > +#include "hw/xen/xen-hvm-common.h" > > > #include "hw/xen/xen_native.h" > > > +#include "hw/xen/xen_pvdev.h" > > > #include "qemu/bitmap.h" > > > > > > #include "sysemu/runstate.h" > > > @@ -597,3 +599,28 @@ uint8_t *xen_replace_cache_entry(hwaddr > > > old_phys_addr, > > > mapcache_unlock(); > > > return p; > > > } > > > + > > > +MemoryRegion *xen_init_grant_ram(void) > > > +{ > > > +RAMBlock *block; > > > + > > > +memory_region_init(&ram_grants, NULL, "xen.grants", > > > + XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE); > > > +block = g_malloc0(sizeof(*block)); > > > +block->mr = &ram_grants; > > > +block->used_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE; > > > +block->max_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE; > > > +block->fd = -1; > > > +block->page_size = XC_PAGE_SIZE; > > > +block->host = (void *)XEN_GRANT_ADDR_OFF; > > > +block->offset = XEN_GRANT_ADDR_OFF; > > > +block->flags = RAM_PREALLOC; > > > +ram_grants.ram_block = block; > > > +ram_grants.ram = true; > > > +ram_grants.terminates = true; > > > +ram_block_add_list(block); > > > +memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF, > > > +&ram_grants); > > > + > > > +return &ram_grants; > > > > It doesn't look like xen_init_grant_ram has anything to do with the > > mapcache. It should be in another file. Maybe ./hw/xen/xen-hvm-common.c > > or ./hw/i386/xen/xen-hvm.c (but this is x86 specific and we need grants > > on ARM too) > Do you mean to move all grant related functions? As moving this alone will not > be sufficient. There are lot of new grant related function added in later > patches. > > I am okay with moving all to xen-hvm-common.c > > Following code movement will happen in this case: > 1. All grant related static function to xen-hvm-common.c. > xen_ram_addr_from_grant_cache(), xen_ram_addr_from_mapcache(), > xen_map_grant_dyn(), xen_unmap_grant_dyn and xen_init_grant_ram(). > 2. Remove static from xen_ram_addr_from_mapcache_try(
Re: [PATCH v4 05/10] hw/fsi: IBM's On-chip Peripheral Bus
Hello Cedric, Thanks for the review. On 9/11/23 07:29, Cédric Le Goater wrote: On 9/9/23 00:28, Ninad Palsule wrote: This is a part of patchset where IBM's Flexible Service Interface is introduced. The On-Chip Peripheral Bus (OPB): A low-speed bus typically found in POWER processors. This now makes an appearance in the ASPEED SoC due to tight integration of the FSI master IP with the OPB, mainly the existence of an MMIO-mapping of the CFAM address straight onto a sub-region of the OPB address space. Signed-off-by: Andrew Jeffery Signed-off-by: Cédric Le Goater Signed-off-by: Ninad Palsule Reviewed-by: Joel Stanley --- v2: - Incorporated review comment by Joel. --- hw/fsi/Kconfig | 4 + hw/fsi/fsi-master.c | 6 +- hw/fsi/meson.build | 1 + hw/fsi/opb.c | 194 +++ include/hw/fsi/opb.h | 43 ++ 5 files changed, 244 insertions(+), 4 deletions(-) create mode 100644 hw/fsi/opb.c create mode 100644 include/hw/fsi/opb.h diff --git a/hw/fsi/Kconfig b/hw/fsi/Kconfig index 087980be22..560ce536db 100644 --- a/hw/fsi/Kconfig +++ b/hw/fsi/Kconfig @@ -1,3 +1,7 @@ +config OPB + bool + select CFAM + config CFAM bool select FSI diff --git a/hw/fsi/fsi-master.c b/hw/fsi/fsi-master.c index fe1693539a..46103f84e9 100644 --- a/hw/fsi/fsi-master.c +++ b/hw/fsi/fsi-master.c @@ -7,14 +7,12 @@ #include "qemu/osdep.h" +#include "qemu/bitops.h" #include "qapi/error.h" - #include "qemu/log.h" -#include "hw/fsi/bits.h" #include "hw/fsi/fsi-master.h" - -#define TYPE_OP_BUS "opb" +#include "hw/fsi/opb.h" #define TO_REG(x) ((x) >> 2) These change do not belong to this patch. I fixed some of them but in this patch TYPE_OP_BUS is replaced by correct header file. diff --git a/hw/fsi/meson.build b/hw/fsi/meson.build index ca80d11cb9..cab645f4ea 100644 --- a/hw/fsi/meson.build +++ b/hw/fsi/meson.build @@ -2,3 +2,4 @@ system_ss.add(when: 'CONFIG_LBUS', if_true: files('lbus.c')) system_ss.add(when: 'CONFIG_SCRATCHPAD', if_true: files('engine-scratchpad.c')) system_ss.add(when: 'CONFIG_CFAM', if_true: files('cfam.c')) system_ss.add(when: 'CONFIG_FSI', if_true: files('fsi.c','fsi-master.c','fsi-slave.c')) +system_ss.add(when: 'CONFIG_OPB', if_true: files('opb.c')) diff --git a/hw/fsi/opb.c b/hw/fsi/opb.c new file mode 100644 index 00..ac7693c001 --- /dev/null +++ b/hw/fsi/opb.c @@ -0,0 +1,194 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2023 IBM Corp. + * + * IBM On-chip Peripheral Bus + */ + +#include "qemu/osdep.h" + +#include "qapi/error.h" +#include "qemu/log.h" + +#include "hw/fsi/opb.h" + +static MemTxResult opb_read(OPBus *opb, hwaddr addr, void *data, size_t len) +{ + return address_space_read(&opb->as, addr, MEMTXATTRS_UNSPECIFIED, data, + len); +} This routine doesn't look very useful. Same for the write. Now I made them to qemu_log the error. + +uint8_t opb_read8(OPBus *opb, hwaddr addr) +{ + MemTxResult tx; + uint8_t data; + + tx = opb_read(opb, addr, &data, sizeof(data)); + /* FIXME: improve error handling */ + assert(!tx); should output a qemu_log_mask(LOG_GUEST_ERROR) may be ? But I don't think we should assert. I removed tx check from all other functions. + + return data; +} + +uint16_t opb_read16(OPBus *opb, hwaddr addr) +{ + MemTxResult tx; + uint16_t data; + + tx = opb_read(opb, addr, &data, sizeof(data)); + /* FIXME: improve error handling */ + assert(!tx); same Same as above. + + return data; +} + +uint32_t opb_read32(OPBus *opb, hwaddr addr) +{ + MemTxResult tx; + uint32_t data; + + tx = opb_read(opb, addr, &data, sizeof(data)); + /* FIXME: improve error handling */ + assert(!tx); + + return data; +} + +static MemTxResult opb_write(OPBus *opb, hwaddr addr, void *data, size_t len) +{ + return address_space_write(&opb->as, addr, MEMTXATTRS_UNSPECIFIED, data, + len); +} + +void opb_write8(OPBus *opb, hwaddr addr, uint8_t data) +{ + MemTxResult tx; + + tx = opb_write(opb, addr, &data, sizeof(data)); + /* FIXME: improve error handling */ + assert(!tx); +} + +void opb_write16(OPBus *opb, hwaddr addr, uint16_t data) +{ + MemTxResult tx; + + tx = opb_write(opb, addr, &data, sizeof(data)); + /* FIXME: improve error handling */ + assert(!tx); +} + +void opb_write32(OPBus *opb, hwaddr addr, uint32_t data) +{ + MemTxResult tx; + + tx = opb_write(opb, addr, &data, sizeof(data)); + /* FIXME: improve error handling */ + assert(!tx); +} + +void opb_fsi_master_address(OPBus *opb, hwaddr addr) +{ + memory_region_transaction_begin(); + memory_region_set_address(&opb->fsi.iomem, addr); + memory_region_transaction_commit(); +} + +void opb_opb2fsi_address(OPBus *opb, hwaddr addr) +{ + memory_region_transaction_begin(); + memory_region_set_addre
[PATCH v4] migration: Allow user to specify available switchover bandwidth
Migration bandwidth is a very important value to live migration. It's because it's one of the major factors that we'll make decision on when to switchover to destination in a precopy process. This value is currently estimated by QEMU during the whole live migration process by monitoring how fast we were sending the data. This can be the most accurate bandwidth if in the ideal world, where we're always feeding unlimited data to the migration channel, and then it'll be limited to the bandwidth that is available. However in reality it may be very different, e.g., over a 10Gbps network we can see query-migrate showing migration bandwidth of only a few tens of MB/s just because there are plenty of other things the migration thread might be doing. For example, the migration thread can be busy scanning zero pages, or it can be fetching dirty bitmap from other external dirty sources (like vhost or KVM). It means we may not be pushing data as much as possible to migration channel, so the bandwidth estimated from "how many data we sent in the channel" can be dramatically inaccurate sometimes. With that, the decision to switchover will be affected, by assuming that we may not be able to switchover at all with such a low bandwidth, but in reality we can. The migration may not even converge at all with the downtime specified, with that wrong estimation of bandwidth, keeping iterations forever with a low estimation of bandwidth. The issue is QEMU itself may not be able to avoid those uncertainties on measuing the real "available migration bandwidth". At least not something I can think of so far. One way to fix this is when the user is fully aware of the available bandwidth, then we can allow the user to help providing an accurate value. For example, if the user has a dedicated channel of 10Gbps for migration for this specific VM, the user can specify this bandwidth so QEMU can always do the calculation based on this fact, trusting the user as long as specified. It may not be the exact bandwidth when switching over (in which case qemu will push migration data as fast as possible), but much better than QEMU trying to wildly guess, especially when very wrong. A new parameter "avail-switchover-bandwidth" is introduced just for this. So when the user specified this parameter, instead of trusting the estimated value from QEMU itself (based on the QEMUFile send speed), it trusts the user more by using this value to decide when to switchover, assuming that we'll have such bandwidth available then. Note that specifying this value will not throttle the bandwidth for switchover yet, so QEMU will always use the full bandwidth possible for sending switchover data, assuming that should always be the most important way to use the network at that time. This can resolve issues like "unconvergence migration" which is caused by hilarious low "migration bandwidth" detected for whatever reason. Reported-by: Zhiyi Guo Reviewed-by: Joao Martins Signed-off-by: Peter Xu --- v4: - Rebase to master, with duplicated documentations --- qapi/migration.json| 34 +- migration/migration.h | 2 +- migration/options.h| 1 + migration/migration-hmp-cmds.c | 14 ++ migration/migration.c | 24 +--- migration/options.c| 28 migration/trace-events | 2 +- 7 files changed, 99 insertions(+), 6 deletions(-) diff --git a/qapi/migration.json b/qapi/migration.json index 8843e74b59..0c897a99b1 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -759,6 +759,16 @@ # @max-bandwidth: to set maximum speed for migration. maximum speed # in bytes per second. (Since 2.8) # +# @avail-switchover-bandwidth: to set the available bandwidth that +# migration can use during switchover phase. NOTE! This does not +# limit the bandwidth during switchover, but only for calculations when +# making decisions to switchover. By default, this value is zero, +# which means QEMU will estimate the bandwidth automatically. This can +# be set when the estimated value is not accurate, while the user is +# able to guarantee such bandwidth is available when switching over. +# When specified correctly, this can make the switchover decision much +# more accurate. (Since 8.2) +# # @downtime-limit: set maximum tolerated downtime for migration. # maximum downtime in milliseconds (Since 2.8) # @@ -840,7 +850,7 @@ 'cpu-throttle-initial', 'cpu-throttle-increment', 'cpu-throttle-tailslow', 'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth', - 'downtime-limit', + 'avail-switchover-bandwidth', 'downtime-limit', { 'name': 'x-checkpoint-delay', 'features': [ 'unstable' ] }, 'block-incremental', 'multifd-channels', @@ -925,6 +935,16 @@ # @max-bandwidth: to set maximum speed
Re: [RFC PATCH 1/3] migration/multifd: Move channels_ready semaphore
On Tue, Oct 10, 2023 at 06:43:05PM -0300, Fabiano Rosas wrote: > Peter Xu writes: > > > On Fri, Sep 22, 2023 at 11:53:17AM -0300, Fabiano Rosas wrote: > >> Commit d2026ee117 ("multifd: Fix the number of channels ready") moved > >> the "post" of channels_ready to the start of the multifd_send_thread() > >> loop and added a missing "wait" at multifd_send_sync_main(). While it > >> does work, the placement of the wait goes against what the rest of the > >> code does. > >> > >> The sequence at multifd_send_thread() is: > >> > >> qemu_sem_post(&multifd_send_state->channels_ready); > >> qemu_sem_wait(&p->sem); > >> > >> if (flags & MULTIFD_FLAG_SYNC) { > >> qemu_sem_post(&p->sem_sync); > >> } > >> > >> Which means that the sending thread makes itself available > >> (channels_ready) and waits for more work (sem). So the sequence in the > >> migration thread should be to check if any channel is available > >> (channels_ready), give it some work and set it off (sem): > >> > >> qemu_sem_wait(&multifd_send_state->channels_ready); > > > > Here it means we have at least 1 free send thread, then... > > > >> > >> qemu_sem_post(&p->sem); > > > > ... here we enqueue some work to the current thread (pointed by "i"), no > > matter it's free or not, as "i" may not always point to the free thread. > > > > Yes. Which means channels_ready is currently useless. Since I posted > this I realized that and have been working on a series to remove it > completely. > > ... I'm not opposed to "fixing" whatever needs to be fixed here as well, but > I think removing it makes sense. I'll try to focus on that and post a v2 > here. Happy to read it. > > >> if (flags & MULTIFD_FLAG_SYNC) { > >> qemu_sem_wait(&p->sem_sync); > >> } > > > > So I must confess I never fully digest how these sem/mutex/.. worked in > > multifd, since the 1st day it's introduced.. so please take below comment > > with a grain of salt.. > > We definitely need to clarify some things in the multifd > design. Specially if we're going to use it as the main migration > infrastructure moving forward. Exactly. > > I think what we lack is a design direction. I'm not really interested in > how things work currently, but in how they *should* work based on the > design. Unfortunately we can't ignore how old code works; normally old code has its reason to work like that. So the best way to go is trying to figure out exactly how it works with the author, unless reaching the consensus it was a design mistake after that conversation. The luckiest thing here is we have the author around (Juan). Let's discuss thoroughly with him to make sure nothing is overlooked. > > I'm confused about: > > 1) why channels_ready exists? Were we trying to do some lockstep > movement of: populate MultiFDPages -> release the sender thread -> move > to next channel -> wait for it to become ready -> repeat. If so, that > semaphore should be per-channel I think. > > (my future proposal will be to remove the channels_ready semaphore) > > 2) why do we need sem_sync? The SYNC flag makes sense, but why the > source needs to sync with itself when syncing with dst? > > (my proposal in this series is to rename sem_sync to sem_done and use it > to track sending completion) > > 3) why do we need to take the params lock? Shouldn't the semaphores > already ensure that only one of the main thread and the sender thread > will touch the params? The comment in multifd_send_pages says that we > don't take locks for the pages structure, but that seems pointeless to > me since we still lock the params structure. Heh, so I'm not the only one who is confused with all these. :) You reminded me of the days when I was reviewing the initial versions of multifd, since when I failed to understand the code.. It's great to start discussing this again. I'd say go ahead and propose your patches; I'll read them. > > > It seems to me that the current design allows >1 pending_job for a thread. > > Here the current code didn't do "wait(channels_ready)" because it doesn't > > need to - it simply always queue an MULTIFD_FLAG_SYNC pending job over the > > thread, and wait for it to run. > > > > From that POV I think I can understand why "wait(channels_ready)" is not > > needed here. But then I'm confused because we don't have a real QUEUE to > > put those requests; we simply apply this: > > > > multifd_send_sync_main(): > > p->flags |= MULTIFD_FLAG_SYNC; > > > > Even if this send thread can be busy handling a batch of pages and > > accessing p->flags. I think it can actually race with the send thread > > reading the flag at the exact same time: > > > > multifd_send_thread(): > > multifd_send_fill_packet(p); > > flags = p->flags; <-- here > > It doesn't race in reading due to the p->mutex lock. But it looks like > it could miss a newly set flag when it unlocks to start sending > (qio_channel_write*). Right. Se
Re: [RFC PATCH 06/11] tests/avocado: Add FreeBSD distro boot tests for ppc
On Tue, Oct 10, 2023 at 1:53 AM Nicholas Piggin wrote: > FreeBSD project provides qcow2 images that work well for testing QEMU. > Add pseries tests for HPT and Radix, KVM and TCG. > > Other architectures could be added so this does not get a ppc_ prefix > but is instead named similarly to boot_linux. > > Cc: Warner Losh > Signed-off-by: Nicholas Piggin > > CC'ing Warner to check if it's okay for us to use these images and > any comments or suggestions. avocado tests have many Linux boots so we'd > do much better to expand test coverage by adding some other systems. > I like this I'm a little worried at the exact hash encoded in it, but since there's a checksum to match, it's OK I guess. It will give this code a shelf-life of months, IIRC our retention policy. Other than that, I think this is good. Not familiar enough with Avocado to understand skipping for gitlab CI, but given the extreme crunch on minutes, I think that's OK. Other than one nit below which is fine if it is intentionally left behind (or removed): Reviewed-by: Warner Losh Please don't hesitate to reach out to me if this is failing. I'll act as a backstop to get it to the right people. Warner > --- > tests/avocado/boot_freebsd.py | 109 ++ > 1 file changed, 109 insertions(+) > create mode 100644 tests/avocado/boot_freebsd.py > > diff --git a/tests/avocado/boot_freebsd.py b/tests/avocado/boot_freebsd.py > new file mode 100644 > index 00..9a499a28ad > --- /dev/null > +++ b/tests/avocado/boot_freebsd.py > @@ -0,0 +1,109 @@ > +# Functional tests that boot FreeBSD in various configurations > +# > +# Copyright (c) 2023 IBM Corporation > +# > +# This work is licensed under the terms of the GNU GPL, version 2 or > +# later. See the COPYING file in the top-level directory. > + > +import os > + > +from avocado import skipUnless > +from avocado import skipIf > +from avocado_qemu import QemuSystemTest > +from avocado_qemu import wait_for_console_pattern > +from avocado_qemu import exec_command > +from avocado.utils import archive > +from avocado.utils import process > +from avocado.utils.path import find_command > + > +class BootFreeBSDPPC64(QemuSystemTest): > +""" > +:avocado: tags=arch:ppc64 > +""" > + > +timeout = 360 > + > +def run_pseries_test(self, force_HPT=False): > +# We need zstd for all the tuxrun tests > +# See https://github.com/avocado-framework/avocado/issues/5609 > +zstd = find_command('zstd', False) > +if zstd is False: > +self.cancel('Could not find "zstd", which is required to ' > +'decompress rootfs') > +self.zstd = zstd > + > +drive_url = (' > https://artifact.ci.freebsd.org/snapshot/15.0-CURRENT/a2440348eed75bb7682579af0905b652747fd016/powerpc/powerpc64le/disk.qcow2.zst > ') > +drive_hash = '8ab11a05ccab3d44215fd4667a70454ed10a203f' > +drive_path_zstd = self.fetch_asset(drive_url, > asset_hash=drive_hash) > +drive_path = os.path.join(self.workdir, 'disk.qcow2') > +# archive.zstd_uncompress(drive_path_zstd, drive_path) > Why is this commented out? It looks like a leftover maybe? > + > +cmd = f"{self.zstd} -d {drive_path_zstd} -o {drive_path}" > +process.run(cmd) > + > +drive = f"file={drive_path},format=qcow2,if=virtio" > + > +self.vm.set_console() > +if force_HPT: > +self.vm.add_args('-m', '4g') > +else: > +self.vm.add_args('-m', '1g') > +self.vm.add_args('-smp', '4') > +self.vm.add_args('-drive', drive) > +self.vm.add_args('-net', 'nic,model=virtio') > +self.vm.launch() > + > +wait_for_console_pattern(self, 'Hit [Enter] to boot immediately, > or any other key for command prompt.') > +if force_HPT: > +exec_command(self, 'x') > +wait_for_console_pattern(self, 'OK') > +exec_command(self, 'set radix_mmu=0') > +exec_command(self, 'boot') > +wait_for_console_pattern(self, 'cas: selected hash MMU', > 'panic:') > +else: > +exec_command(self, '') > +wait_for_console_pattern(self, 'cas: selected radix MMU') > + > +wait_for_console_pattern(self, 'FreeBSD 15.0-CURRENT #0 a244034: > Mon Sep 25 02:05:22 UTC 2023', 'panic:') > +wait_for_console_pattern(self, 'FreeBSD/SMP: Multiprocessor > System Detected: 4 CPUs') > +wait_for_console_pattern(self, 'FreeBSD/powerpc (Amnesiac) > (ttyu0)', 'panic:') > + > +@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') > +def test_pseries_tcg(self): > +""" > +:avocado: tags=arch:ppc64 > +:avocado: tags=machine:pseries > +:avocado: tags=accel:tcg > +""" > +self.require_accelerator("tcg") > +self.run_pseries_test() > + > +@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') > +def test_pseries_hpt_tcg(self): > +
Re: [RFC PATCH 1/3] migration/multifd: Move channels_ready semaphore
Peter Xu writes: > On Fri, Sep 22, 2023 at 11:53:17AM -0300, Fabiano Rosas wrote: >> Commit d2026ee117 ("multifd: Fix the number of channels ready") moved >> the "post" of channels_ready to the start of the multifd_send_thread() >> loop and added a missing "wait" at multifd_send_sync_main(). While it >> does work, the placement of the wait goes against what the rest of the >> code does. >> >> The sequence at multifd_send_thread() is: >> >> qemu_sem_post(&multifd_send_state->channels_ready); >> qemu_sem_wait(&p->sem); >> >> if (flags & MULTIFD_FLAG_SYNC) { >> qemu_sem_post(&p->sem_sync); >> } >> >> Which means that the sending thread makes itself available >> (channels_ready) and waits for more work (sem). So the sequence in the >> migration thread should be to check if any channel is available >> (channels_ready), give it some work and set it off (sem): >> >> qemu_sem_wait(&multifd_send_state->channels_ready); > > Here it means we have at least 1 free send thread, then... > >> >> qemu_sem_post(&p->sem); > > ... here we enqueue some work to the current thread (pointed by "i"), no > matter it's free or not, as "i" may not always point to the free thread. > Yes. Which means channels_ready is currently useless. Since I posted this I realized that and have been working on a series to remove it completely. ... I'm not opposed to "fixing" whatever needs to be fixed here as well, but I think removing it makes sense. I'll try to focus on that and post a v2 here. >> if (flags & MULTIFD_FLAG_SYNC) { >> qemu_sem_wait(&p->sem_sync); >> } > > So I must confess I never fully digest how these sem/mutex/.. worked in > multifd, since the 1st day it's introduced.. so please take below comment > with a grain of salt.. We definitely need to clarify some things in the multifd design. Specially if we're going to use it as the main migration infrastructure moving forward. I think what we lack is a design direction. I'm not really interested in how things work currently, but in how they *should* work based on the design. I'm confused about: 1) why channels_ready exists? Were we trying to do some lockstep movement of: populate MultiFDPages -> release the sender thread -> move to next channel -> wait for it to become ready -> repeat. If so, that semaphore should be per-channel I think. (my future proposal will be to remove the channels_ready semaphore) 2) why do we need sem_sync? The SYNC flag makes sense, but why the source needs to sync with itself when syncing with dst? (my proposal in this series is to rename sem_sync to sem_done and use it to track sending completion) 3) why do we need to take the params lock? Shouldn't the semaphores already ensure that only one of the main thread and the sender thread will touch the params? The comment in multifd_send_pages says that we don't take locks for the pages structure, but that seems pointeless to me since we still lock the params structure. > It seems to me that the current design allows >1 pending_job for a thread. > Here the current code didn't do "wait(channels_ready)" because it doesn't > need to - it simply always queue an MULTIFD_FLAG_SYNC pending job over the > thread, and wait for it to run. > > From that POV I think I can understand why "wait(channels_ready)" is not > needed here. But then I'm confused because we don't have a real QUEUE to > put those requests; we simply apply this: > > multifd_send_sync_main(): > p->flags |= MULTIFD_FLAG_SYNC; > > Even if this send thread can be busy handling a batch of pages and > accessing p->flags. I think it can actually race with the send thread > reading the flag at the exact same time: > > multifd_send_thread(): > multifd_send_fill_packet(p); > flags = p->flags; <-- here It doesn't race in reading due to the p->mutex lock. But it looks like it could miss a newly set flag when it unlocks to start sending (qio_channel_write*). > And whether it sees MULTIFD_FLAG_SYNC is unpredictable. If it sees it, > it'll post(sem_sync) in this round. If it doesn't see it, it'll > post(sem_sync) in the next round. In whatever way, we'll generate an empty > multifd packet to the wire I think, even though I don't know whether that's > needed at all... > > I'm not sure whether we should fix it in a more complete form, by not > sending that empty multifd packet at all? Because that only contains the > header without any real page inside, IIUC, so it seems to be a waste of > resource. Here what we want is only to kick sem_sync? > >> >> The reason there's no deadlock today is that the migration thread >> enqueues the SYNC packet right before the wait on channels_ready and >> we end up taking advantage of the out-of-order post to sem: >> >> ... >> qemu_sem_post(&p->sem); >> } >> for (i = 0; i < migrate_multifd_channels(); i++) { >> MultiFDSendParams *p = &multifd_send_state->params[i]; >> >>
Re: [RFC PATCH 1/3] migration/multifd: Move channels_ready semaphore
On Tue, Oct 10, 2023 at 05:00:37PM -0400, Peter Xu wrote: > On Fri, Sep 22, 2023 at 11:53:17AM -0300, Fabiano Rosas wrote: > > Commit d2026ee117 ("multifd: Fix the number of channels ready") moved > > the "post" of channels_ready to the start of the multifd_send_thread() > > loop and added a missing "wait" at multifd_send_sync_main(). While it > > does work, the placement of the wait goes against what the rest of the > > code does. > > > > The sequence at multifd_send_thread() is: > > > > qemu_sem_post(&multifd_send_state->channels_ready); > > qemu_sem_wait(&p->sem); > > > > if (flags & MULTIFD_FLAG_SYNC) { > > qemu_sem_post(&p->sem_sync); > > } > > > > Which means that the sending thread makes itself available > > (channels_ready) and waits for more work (sem). So the sequence in the > > migration thread should be to check if any channel is available > > (channels_ready), give it some work and set it off (sem): > > > > qemu_sem_wait(&multifd_send_state->channels_ready); > > Here it means we have at least 1 free send thread, then... > > > > > qemu_sem_post(&p->sem); > > ... here we enqueue some work to the current thread (pointed by "i"), no > matter it's free or not, as "i" may not always point to the free thread. > > > if (flags & MULTIFD_FLAG_SYNC) { > > qemu_sem_wait(&p->sem_sync); > > } > > So I must confess I never fully digest how these sem/mutex/.. worked in > multifd, since the 1st day it's introduced.. so please take below comment > with a grain of salt.. > > It seems to me that the current design allows >1 pending_job for a thread. > Here the current code didn't do "wait(channels_ready)" because it doesn't > need to - it simply always queue an MULTIFD_FLAG_SYNC pending job over the > thread, and wait for it to run. > > From that POV I think I can understand why "wait(channels_ready)" is not > needed here. But then I'm confused because we don't have a real QUEUE to > put those requests; we simply apply this: > > multifd_send_sync_main(): > p->flags |= MULTIFD_FLAG_SYNC; > > Even if this send thread can be busy handling a batch of pages and > accessing p->flags. I think it can actually race with the send thread > reading the flag at the exact same time: > > multifd_send_thread(): > multifd_send_fill_packet(p); > flags = p->flags; <-- here > > And whether it sees MULTIFD_FLAG_SYNC is unpredictable. If it sees it, > it'll post(sem_sync) in this round. If it doesn't see it, it'll > post(sem_sync) in the next round. In whatever way, we'll generate an empty > multifd packet to the wire I think, even though I don't know whether that's > needed at all... A correction: Since it's protected by p->mutex, I think we will only get an empty multifd packet when we have pending_jobs==2.. because then we'll see pending_job==2 with p->flags==SYNC, we send pages along with flags=SYNC to dest, after that we kick sem_sync on src, then we found another pending_jobs==1 even if p->flags will be zero. The next multifd packet will be only containing header (flags=0) and with no pages. > > I'm not sure whether we should fix it in a more complete form, by not > sending that empty multifd packet at all? Because that only contains the > header without any real page inside, IIUC, so it seems to be a waste of > resource. Here what we want is only to kick sem_sync? When thinking more about it, now I'm unsure whether sync is really working as expected now in general.. IIUC SYNC message is used to flush all pages from source to destination. We need that because we want to order the different versions of guest pages, making sure the new version of a page always arrives later than its old version, hence after all pages migrated we'll be sure all guest pages on dest will be the latest. Let's define "version X for page Y" as PyVx. Version 1 of page 2 is P2V1. So if without SYNC, a race can happen like this: sender 1 sender 2 receiver 1receiver 2 ---- send P1V1 ...P1 changed content.. queued again in sender 2... send P1V2 ...If we got unlucky on receiving order of P1 versions... receive P1V2 receive P1V1 So if receiver 1 got P1V1 after receiver 2 got P1V2, we'll ultimately have P1V1 on dst, which is an old data, causing data corrupt after migration. Now we have the SYNC packet, but would it always work? I'll discuss with the latest RAM_SAVE_FLAG_MULTIFD_FLUSH sync message: src mainsender 1 sender 2dst main receiver 1 receiver 2 -- -- send P1V1 send MULTIFD_FLUSH ...P1 changed.. queued again in sender 2... send P1V2
Re: [QEMU][PATCH v1 3/7] softmmu: let qemu_map_ram_ptr() use qemu_ram_ptr_length()
On Mon, Oct 09, 2023 at 05:10:43PM -0700, Stefano Stabellini wrote: > On Thu, 5 Oct 2023, Vikram Garhwal wrote: > > From: Juergen Gross > > > > qemu_map_ram_ptr() and qemu_ram_ptr_length() share quite some code, so > > modify qemu_ram_ptr_length() a little bit and use it for > > qemu_map_ram_ptr(), too. > > > > Signed-off-by: Juergen Gross > > Signed-off-by: Vikram Garhwal > > This patch also doesn't apply due to code movement. Will rebase it. > > Other than that, the patch looks good to me > > > > --- > > softmmu/physmem.c | 58 +++ > > 1 file changed, 23 insertions(+), 35 deletions(-) > > > > diff --git a/softmmu/physmem.c b/softmmu/physmem.c > > index e182a2fa07..6e5e379dd0 100644 > > --- a/softmmu/physmem.c > > +++ b/softmmu/physmem.c > > @@ -2163,38 +2163,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t > > length) > > } > > #endif /* !_WIN32 */ > > > > -/* Return a host pointer to ram allocated with qemu_ram_alloc. > > - * This should not be used for general purpose DMA. Use address_space_map > > - * or address_space_rw instead. For local memory (e.g. video ram) that the > > - * device owns, use memory_region_get_ram_ptr. > > - * > > - * Called within RCU critical section. > > - */ > > -void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr) > > -{ > > -RAMBlock *block = ram_block; > > - > > -if (block == NULL) { > > -block = qemu_get_ram_block(addr); > > -addr -= block->offset; > > -} > > - > > -if (xen_enabled() && block->host == NULL) { > > -/* We need to check if the requested address is in the RAM > > - * because we don't want to map the entire memory in QEMU. > > - * In that case just map until the end of the page. > > - */ > > -if (block->offset == 0) { > > -return xen_map_cache(addr, 0, 0, false); > > -} > > - > > -block->host = xen_map_cache(block->offset, block->max_length, 1, > > false); > > -} > > -return ramblock_ptr(block, addr); > > -} > > - > > -/* Return a host pointer to guest's ram. Similar to qemu_map_ram_ptr > > - * but takes a size argument. > > +/* > > + * Return a host pointer to guest's ram. > > * > > * Called within RCU critical section. > > */ > > @@ -2202,7 +2172,9 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, > > ram_addr_t addr, > > hwaddr *size, bool lock) > > { > > RAMBlock *block = ram_block; > > -if (*size == 0) { > > +hwaddr len = 0; > > + > > +if (size && *size == 0) { > > return NULL; > > } > > > > @@ -2210,7 +2182,10 @@ static void *qemu_ram_ptr_length(RAMBlock > > *ram_block, ram_addr_t addr, > > block = qemu_get_ram_block(addr); > > addr -= block->offset; > > } > > -*size = MIN(*size, block->max_length - addr); > > +if (size) { > > +*size = MIN(*size, block->max_length - addr); > > +len = *size; > > +} > > > > if (xen_enabled() && block->host == NULL) { > > /* We need to check if the requested address is in the RAM > > @@ -2218,7 +2193,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, > > ram_addr_t addr, > > * In that case just map the requested area. > > */ > > if (block->offset == 0) { > > -return xen_map_cache(addr, *size, lock, lock); > > +return xen_map_cache(addr, len, lock, lock); > > } > > > > block->host = xen_map_cache(block->offset, block->max_length, 1, > > lock); > > @@ -2227,6 +2202,19 @@ static void *qemu_ram_ptr_length(RAMBlock > > *ram_block, ram_addr_t addr, > > return ramblock_ptr(block, addr); > > } > > > > +/* > > + * Return a host pointer to ram allocated with qemu_ram_alloc. > > + * This should not be used for general purpose DMA. Use address_space_map > > + * or address_space_rw instead. For local memory (e.g. video ram) that the > > + * device owns, use memory_region_get_ram_ptr. > > + * > > + * Called within RCU critical section. > > + */ > > +void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr) > > +{ > > +return qemu_ram_ptr_length(ram_block, addr, NULL, false); > > +} > > + > > /* Return the offset of a hostpointer within a ramblock */ > > ram_addr_t qemu_ram_block_host_offset(RAMBlock *rb, void *host) > > { > > -- > > 2.17.1 > >
Re: [QEMU][PATCH v1 2/7] xen: add pseudo RAM region for grant mappings
Hi Stefano, On Mon, Oct 09, 2023 at 05:02:14PM -0700, Stefano Stabellini wrote: > On Thu, 5 Oct 2023, Vikram Garhwal wrote: > > From: Juergen Gross > > > > Add a memory region which can be used to automatically map granted > > memory. It is starting at 0x8000ULL in order to be able to > > distinguish it from normal RAM. > > > > For this reason the xen.ram memory region is expanded, which has no > > further impact as it is used just as a container of the real RAM > > regions and now the grant region. > > > > Signed-off-by: Juergen Gross > > Signed-off-by: Vikram Garhwal > > This patch doesn't apply to staging anymore Will re-base it. I rebased it against master branch. > > > > --- > > hw/i386/xen/xen-hvm.c | 3 ++ > > hw/xen/xen-hvm-common.c | 4 +-- > > hw/xen/xen-mapcache.c | 27 ++ > > include/exec/ram_addr.h | 1 + > > include/hw/xen/xen-hvm-common.h | 2 ++ > > include/hw/xen/xen_pvdev.h | 3 ++ > > include/sysemu/xen-mapcache.h | 3 ++ > > softmmu/physmem.c | 62 + > > 8 files changed, 80 insertions(+), 25 deletions(-) > > > > diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c > > index f42621e674..67a8a6 100644 > > --- a/hw/i386/xen/xen-hvm.c > > +++ b/hw/i386/xen/xen-hvm.c > > @@ -172,6 +172,9 @@ static void xen_ram_init(PCMachineState *pcms, > > x86ms->above_4g_mem_size); > > memory_region_add_subregion(sysmem, 0x1ULL, &ram_hi); > > } > > + > > +/* Add grant mappings as a pseudo RAM region. */ > > +ram_grants = *xen_init_grant_ram(); > > } > > > > static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size) > > diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c > > index 565dc39c8f..b7255977a5 100644 > > --- a/hw/xen/xen-hvm-common.c > > +++ b/hw/xen/xen-hvm-common.c > > @@ -9,7 +9,7 @@ > > #include "hw/boards.h" > > #include "hw/xen/arch_hvm.h" > > > > -MemoryRegion ram_memory; > > +MemoryRegion ram_memory, ram_grants; > > > > void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr, > > Error **errp) > > @@ -26,7 +26,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, > > MemoryRegion *mr, > > return; > > } > > > > -if (mr == &ram_memory) { > > +if (mr == &ram_memory || mr == &ram_grants) { > > return; > > } > > > > diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c > > index f7d974677d..8115c44c00 100644 > > --- a/hw/xen/xen-mapcache.c > > +++ b/hw/xen/xen-mapcache.c > > @@ -14,7 +14,9 @@ > > > > #include > > > > +#include "hw/xen/xen-hvm-common.h" > > #include "hw/xen/xen_native.h" > > +#include "hw/xen/xen_pvdev.h" > > #include "qemu/bitmap.h" > > > > #include "sysemu/runstate.h" > > @@ -597,3 +599,28 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr, > > mapcache_unlock(); > > return p; > > } > > + > > +MemoryRegion *xen_init_grant_ram(void) > > +{ > > +RAMBlock *block; > > + > > +memory_region_init(&ram_grants, NULL, "xen.grants", > > + XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE); > > +block = g_malloc0(sizeof(*block)); > > +block->mr = &ram_grants; > > +block->used_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE; > > +block->max_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE; > > +block->fd = -1; > > +block->page_size = XC_PAGE_SIZE; > > +block->host = (void *)XEN_GRANT_ADDR_OFF; > > +block->offset = XEN_GRANT_ADDR_OFF; > > +block->flags = RAM_PREALLOC; > > +ram_grants.ram_block = block; > > +ram_grants.ram = true; > > +ram_grants.terminates = true; > > +ram_block_add_list(block); > > +memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF, > > +&ram_grants); > > + > > +return &ram_grants; > > It doesn't look like xen_init_grant_ram has anything to do with the > mapcache. It should be in another file. Maybe ./hw/xen/xen-hvm-common.c > or ./hw/i386/xen/xen-hvm.c (but this is x86 specific and we need grants > on ARM too) Do you mean to move all grant related functions? As moving this alone will not be sufficient. There are lot of new grant related function added in later patches. I am okay with moving all to xen-hvm-common.c Following code movement will happen in this case: 1. All grant related static function to xen-hvm-common.c. xen_ram_addr_from_grant_cache(), xen_ram_addr_from_mapcache(), xen_map_grant_dyn(), xen_unmap_grant_dyn and xen_init_grant_ram(). 2. Remove static from xen_ram_addr_from_mapcache_try(). Does these changes looks good? > > > > +} > > diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h > > index 90676093f5..c0b5f9a7d0 100644 > > --- a/include/exec/ram_addr.h > > +++ b/include/exec/ram_addr.h > > @@ -139,6 +139,7 @@ void qemu_ram_free(RAMBlock *block); > > int qe
Re: [PATCH v4 04/10] hw/fsi: Introduce IBM's FSI
Hello Cedirc, Thanks for the review. On 9/11/23 07:26, Cédric Le Goater wrote: On 9/9/23 00:28, Ninad Palsule wrote: This is a part of patchset where IBM's Flexible Service Interface is introduced. This commit models the FSI bus. CFAM is hanging out of FSI bus. The bus is model such a way that it is embeded inside the FSI master which is a bus controller. The FSI master: A controller in the platform service processor (e.g. BMC) driving CFAM engine accesses into the POWER chip. At the hardware level FSI is a bit-based protocol supporting synchronous and DMA-driven accesses of engines in a CFAM. Signed-off-by: Andrew Jeffery Signed-off-by: Cédric Le Goater Signed-off-by: Ninad Palsule Reviewed-by: Joel Stanley --- v2: - Incorporated review comments by Joel --- hw/fsi/cfam.c | 3 +- hw/fsi/fsi-master.c | 203 hw/fsi/fsi.c | 54 ++ hw/fsi/meson.build | 2 +- include/hw/fsi/cfam.h | 8 +- include/hw/fsi/fsi-master.h | 30 ++ include/hw/fsi/fsi-slave.h | 4 +- include/hw/fsi/fsi.h | 31 ++ 8 files changed, 327 insertions(+), 8 deletions(-) create mode 100644 hw/fsi/fsi-master.c create mode 100644 hw/fsi/fsi.c create mode 100644 include/hw/fsi/fsi-master.h create mode 100644 include/hw/fsi/fsi.h diff --git a/hw/fsi/cfam.c b/hw/fsi/cfam.c index 9a9e65d33f..414dcebe63 100644 --- a/hw/fsi/cfam.c +++ b/hw/fsi/cfam.c @@ -7,12 +7,13 @@ #include "qemu/osdep.h" +#include "qemu/bitops.h" #include "qapi/error.h" #include "qemu/log.h" #include "trace.h" -#include "hw/fsi/bits.h" #include "hw/fsi/cfam.h" +#include "hw/fsi/fsi.h" #include "hw/fsi/engine-scratchpad.h" #include "hw/qdev-properties.h" These change do not belong to this patch. Fixed it but keeping include of fsi.h and removal of bitops.h as this is where we are defining the bits. diff --git a/hw/fsi/fsi-master.c b/hw/fsi/fsi-master.c new file mode 100644 index 00..fe1693539a --- /dev/null +++ b/hw/fsi/fsi-master.c @@ -0,0 +1,203 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2023 IBM Corp. + * + * IBM Flexible Service Interface master + */ + +#include "qemu/osdep.h" + +#include "qapi/error.h" + +#include "qemu/log.h" + +#include "hw/fsi/bits.h" +#include "hw/fsi/fsi-master.h" + +#define TYPE_OP_BUS "opb" + +#define TO_REG(x) ((x) >> 2) + +#define FSI_MMODE TO_REG(0x000) +#define FSI_MMODE_IPOLL_DMA_EN BE_BIT(0) +#define FSI_MMODE_HW_ERROR_RECOVERY_EN BE_BIT(1) +#define FSI_MMODE_RELATIVE_ADDRESS_EN BE_BIT(2) +#define FSI_MMODE_PARITY_CHECK_EN BE_BIT(3) +#define FSI_MMODE_CLOCK_DIVIDER_0 BE_GENMASK(4, 13) +#define FSI_MMODE_CLOCK_DIVIDER_1 BE_GENMASK(14, 23) +#define FSI_MMODE_DEBUG_EN BE_BIT(24) + +#define FSI_MDELAY TO_REG(0x004) +#define FSI_MDELAY_ECHO_0 BE_GENMASK(0, 3) +#define FSI_MDELAY_SEND_0 BE_GENMASK(4, 7) +#define FSI_MDELAY_ECHO_1 BE_GENMASK(8, 11) +#define FSI_MDELAY_SEND_1 BE_GENMASK(12, 15) + +#define FSI_MENP0 TO_REG(0x010) +#define FSI_MENP32 TO_REG(0x014) +#define FSI_MSENP0 TO_REG(0x018) +#define FSI_MLEVP0 TO_REG(0x018) +#define FSI_MSENP32 TO_REG(0x01c) +#define FSI_MLEVP32 TO_REG(0x01c) +#define FSI_MCENP0 TO_REG(0x020) +#define FSI_MREFP0 TO_REG(0x020) +#define FSI_MCENP32 TO_REG(0x024) +#define FSI_MREFP32 TO_REG(0x024) + +#define FSI_MAEB TO_REG(0x070) +#define FSI_MAEB_ANY_CPU_ERROR BE_BIT(0) +#define FSI_MAEB_ANY_DMA_ERROR BE_GENMASK(1, 16) +#define FSI_MAEB_ANY_PARITY_ERROR BE_BIT(17) + +#define FSI_MVER TO_REG(0x074) +#define FSI_MVER_VERSION BE_GENMASK(0, 7) +#define FSI_MVER_BRIDGES BE_GENMASK(8, 15) +#define FSI_MVER_PORTS BE_GENMASK(16, 23) + +#define FSI_MRESP0 TO_REG(0x0d0) +#define FSI_MRESP0_RESET_PORT_GENERAL BE_BIT(0) +#define FSI_MRESP0_RESET_PORT_ERROR BE_BIT(1) +#define FSI_MRESP0_RESET_ALL_BRIDGES_GENERAL BE_BIT(2) +#define FSI_MRESP0_RESET_ALL_PORTS_GENERAL BE_BIT(3) +#define FSI_MRESP0_RESET_MASTER BE_BIT(4) +#define FSI_MRESP0_RESET_PARITY_ERROR_LATCH BE_BIT(5) + +#define FSI_MRESB0 TO_REG(0x1d0) +#define FSI_MRESB0_RESET_GENERAL BE_BIT(0) +#define FSI_M
Re: [RFC PATCH 07/11] tests/avocado: Add ppc boot tests for non-free AIX images
On Tue Oct 10, 2023 at 10:49 PM AEST, Philippe Mathieu-Daudé wrote: > On 10/10/23 14:43, Alex Bennée wrote: > > > > Nicholas Piggin writes: > > > >> An AIX image can be provided by setting AIX_IMAGE environment > >> variable when running avocado. > >> > >> It's questionable whether we should carry these in upstream QEMU. > >> It's convenient to see how to run these things, but simple enough > >> to maintain in out of tree branch. I just wanted to see opinions > >> about it. > > > > Yeah there is no point adding a test no one else can run. We already > > have tests that utilise dead URLs that can only run if you happen to > > have the image in the avocado cache which should arguably be removed. > > This isn't quite the same problem. This test image can possibly be > shared among developers within the IBM realm. Yeah, and other people can have AIX and MacOS legally by other means (IIRC you could register an acount and get AIX, but that may have changed). We do have some people not at IBM who test AIX against upstram and report bugs. Not too sure if they would find these avocado tests useful though. Thanks, Nick
Re: [RFC PATCH 07/11] tests/avocado: Add ppc boot tests for non-free AIX images
On Tue Oct 10, 2023 at 11:01 PM AEST, Daniel P. Berrangé wrote: > On Tue, Oct 10, 2023 at 01:43:16PM +0100, Alex Bennée wrote: > > > > Nicholas Piggin writes: > > > > > An AIX image can be provided by setting AIX_IMAGE environment > > > variable when running avocado. > > > > > > It's questionable whether we should carry these in upstream QEMU. > > > It's convenient to see how to run these things, but simple enough > > > to maintain in out of tree branch. I just wanted to see opinions > > > about it. > > > > Yeah there is no point adding a test no one else can run. We already > > have tests that utilise dead URLs that can only run if you happen to > > have the image in the avocado cache which should arguably be removed. > > I can understand the appeal of wanting to sanity check QEMU > with esentially arbitrary guest OS, whether modern, or obsolete, > whether OSS or proprietary. > > The appeal of getting the test integrated into QEMU is you don't > have to worry about rebasing / merging local git changes forever > more. > > I feel like this tells us we should not require users to be writing > new avocado python test code merely to get a boring old guest OS > boot up smoke test integrated into avocado. Interesting thought. It is easier to be able to specify images location, qemu command line, and some expected output and input than to write an avocado test entirely. OTOH if you copy an existing one and don't need to do anything different then it is not so hard. > > I think we ought to have a 'guest_smoke_test.py' avocado test, that > pulls in guest OS scenarios from external YAML/JSON files. eg > > $ cat ppc_aix.yaml > image: > url: https:some/path > checksum: xx > console: > expect: ...some console message... > vm: > arch: ppc64 > machine: pseries > something something extra cli args something something... > > Users could then set > > export > QEMU_SMOKE_TEST_PATHS=$HOME/my-guestos-library:$HOME/shared-guestos-library > make check-avocado > > to load all the guest OS scenarios from these dirs, in addition to > any scenarios that are shipped in qemu.git by default. There would be a bunch of upstream avocado tests that could be converted to such a format. Thanks, Nick
Re: [RFC PATCH 1/3] migration/multifd: Move channels_ready semaphore
On Fri, Sep 22, 2023 at 11:53:17AM -0300, Fabiano Rosas wrote: > Commit d2026ee117 ("multifd: Fix the number of channels ready") moved > the "post" of channels_ready to the start of the multifd_send_thread() > loop and added a missing "wait" at multifd_send_sync_main(). While it > does work, the placement of the wait goes against what the rest of the > code does. > > The sequence at multifd_send_thread() is: > > qemu_sem_post(&multifd_send_state->channels_ready); > qemu_sem_wait(&p->sem); > > if (flags & MULTIFD_FLAG_SYNC) { > qemu_sem_post(&p->sem_sync); > } > > Which means that the sending thread makes itself available > (channels_ready) and waits for more work (sem). So the sequence in the > migration thread should be to check if any channel is available > (channels_ready), give it some work and set it off (sem): > > qemu_sem_wait(&multifd_send_state->channels_ready); Here it means we have at least 1 free send thread, then... > > qemu_sem_post(&p->sem); ... here we enqueue some work to the current thread (pointed by "i"), no matter it's free or not, as "i" may not always point to the free thread. > if (flags & MULTIFD_FLAG_SYNC) { > qemu_sem_wait(&p->sem_sync); > } So I must confess I never fully digest how these sem/mutex/.. worked in multifd, since the 1st day it's introduced.. so please take below comment with a grain of salt.. It seems to me that the current design allows >1 pending_job for a thread. Here the current code didn't do "wait(channels_ready)" because it doesn't need to - it simply always queue an MULTIFD_FLAG_SYNC pending job over the thread, and wait for it to run. >From that POV I think I can understand why "wait(channels_ready)" is not needed here. But then I'm confused because we don't have a real QUEUE to put those requests; we simply apply this: multifd_send_sync_main(): p->flags |= MULTIFD_FLAG_SYNC; Even if this send thread can be busy handling a batch of pages and accessing p->flags. I think it can actually race with the send thread reading the flag at the exact same time: multifd_send_thread(): multifd_send_fill_packet(p); flags = p->flags; <-- here And whether it sees MULTIFD_FLAG_SYNC is unpredictable. If it sees it, it'll post(sem_sync) in this round. If it doesn't see it, it'll post(sem_sync) in the next round. In whatever way, we'll generate an empty multifd packet to the wire I think, even though I don't know whether that's needed at all... I'm not sure whether we should fix it in a more complete form, by not sending that empty multifd packet at all? Because that only contains the header without any real page inside, IIUC, so it seems to be a waste of resource. Here what we want is only to kick sem_sync? > > The reason there's no deadlock today is that the migration thread > enqueues the SYNC packet right before the wait on channels_ready and > we end up taking advantage of the out-of-order post to sem: > > ... > qemu_sem_post(&p->sem); > } > for (i = 0; i < migrate_multifd_channels(); i++) { > MultiFDSendParams *p = &multifd_send_state->params[i]; > > qemu_sem_wait(&multifd_send_state->channels_ready); > trace_multifd_send_sync_main_wait(p->id); > qemu_sem_wait(&p->sem_sync); > ... > > Move the channels_ready wait before the sem post to keep the sequence > consistent. Also fix the error path to post to channels_ready and > sem_sync in the correct order. > > Signed-off-by: Fabiano Rosas > --- > migration/multifd.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/migration/multifd.c b/migration/multifd.c > index a7c7a947e3..d626740f2f 100644 > --- a/migration/multifd.c > +++ b/migration/multifd.c > @@ -618,6 +618,7 @@ int multifd_send_sync_main(QEMUFile *f) > > trace_multifd_send_sync_main_signal(p->id); > > +qemu_sem_wait(&multifd_send_state->channels_ready); > qemu_mutex_lock(&p->mutex); > > if (p->quit) { > @@ -635,7 +636,6 @@ int multifd_send_sync_main(QEMUFile *f) > for (i = 0; i < migrate_multifd_channels(); i++) { > MultiFDSendParams *p = &multifd_send_state->params[i]; > > -qemu_sem_wait(&multifd_send_state->channels_ready); > trace_multifd_send_sync_main_wait(p->id); > qemu_sem_wait(&p->sem_sync); > > @@ -763,8 +763,8 @@ out: > * who pay attention to me. > */ > if (ret != 0) { > -qemu_sem_post(&p->sem_sync); > qemu_sem_post(&multifd_send_state->channels_ready); > +qemu_sem_post(&p->sem_sync); I'm not sure why such movement will have a difference; afaiu on the semaphore semantics, post() to two sems don't matter on order? > } > > qemu_mutex_lock(&p->mutex); > -- > 2.35.3 > -- Peter Xu
Re: [RFC PATCH 11/11] ppc/pnv: Change powernv default to powernv10
On Tue Oct 10, 2023 at 10:05 PM AEST, Joel Stanley wrote: > On Tue, 10 Oct 2023 at 18:24, Nicholas Piggin wrote: > > > > POWER10 is the latest IBM Power machine. Although it is not offered in > > "OPAL mode" (i.e., powernv configuration), so there is a case that it > > should remain at powernv9, most of the development work is going into > > powernv10 at the moment. > > > > Signed-off-by: Nicholas Piggin > > Reviewed-by: Joel Stanley > > Do we need to update the docs? What did you have in mind? Add some powernv10 examples? > We should consider updating the skiboot to the latest release too. Yeah I will do that (and SLOF as well). Thanks, Nick
Re: [RFC PATCH 05/11] testing/avocado: ppc add new BookE boot_linux_console.py tests
On Tue Oct 10, 2023 at 10:03 PM AEST, Joel Stanley wrote: > On Tue, 10 Oct 2023 at 18:23, Nicholas Piggin wrote: > > > > Add simple Linux kernel boot tests for BookE 64-bit and 32-bit CPUs > > using Guenter Roeck's rootfs images for Linux testing, and a gitlab > > repository with kernel images that I built since there are very few > > sources of modern BookE images now. > > > > Signed-off-by: Nicholas Piggin > > Reviewed-by: Joel Stanley > > Should we get mpe to add a https://github.com/linuxppc/qemu-ci-images > for you to keep those kernel images? But perhaps you'd prefer to keep > them on gitlab. Just a suggestion. Not a bad idea. Or we could try for gitlab/qemu/ci-images I suppose. > > > --- > > tests/avocado/boot_linux_console.py | 53 + > > 1 file changed, 53 insertions(+) > > > > diff --git a/tests/avocado/boot_linux_console.py > > b/tests/avocado/boot_linux_console.py > > index 9434304cd3..dc3346ef49 100644 > > --- a/tests/avocado/boot_linux_console.py > > +++ b/tests/avocado/boot_linux_console.py > > @@ -1355,6 +1355,59 @@ def test_ppc64_e500(self): > > tar_hash = '6951d86d644b302898da2fd701739c9406527fe1' > > self.do_test_advcal_2018('19', tar_hash, 'uImage') > > > > +def test_ppc64_e6500(self): > > +""" > > +:avocado: tags=arch:ppc64 > > +:avocado: tags=machine:ppce500 > > +:avocado: tags=cpu:e6500 > > +:avocado: tags=accel:tcg > > +""" > > +kernel_url = > > ('https://gitlab.com/npiggin/qemu-ci-images/-/raw/main/ppc/corenet64_vmlinux?ref_type=heads&inline=false') > > Is the ref_type?heads=inline-false required? I seem to get the file > successfully with wget and those omitted. I just copied the download link, so if it works without then I'll remove it. Thanks, Nick
Re: [PATCH 00/22] block: Graph locking part 5 (protect children/parent links)
On Fri, Sep 29, 2023 at 04:51:35PM +0200, Kevin Wolf wrote: > After all the preparation in previous series, this series reaches an > important milestone for the graph locking work: TSA can now verify that > all accesses to the children and parent lists of nodes happen under the > graph lock. > > However, this is not the end of the graph locking work yet. On the one > hand, graph locking annotations aren't consistently present on all > functions and having an unannotated function in the middle of the call > chain means that TSA doesn't check if the locking is consistent (in > fact, we know that functions like bdrv_unref() are still called in > places where they strictly speaking must not be called). > > On the other hand, the graph consists of more than just the children and > parent lists. While it might be possible to convince me that the global > node lists (graph_bdrv_states/all_bdrv_states) are safe because > iothreads shouldn't access them, at least BlockDriverState.file/backing > still need proper locking. > > There may be other fields in BlockDriverState that need to be covered > by the lock, too. For example, Stefan said that he would look into > annotating BlockLimits accesses to be protected by the graph lock, too. > > Emanuele Giuseppe Esposito (1): > block: Mark drain related functions GRAPH_RDLOCK > > Kevin Wolf (21): > test-bdrv-drain: Don't call bdrv_graph_wrlock() in coroutine context > block-coroutine-wrapper: Add no_co_wrapper_bdrv_rdlock functions > block: Take graph rdlock in bdrv_inactivate_all() > block: Mark bdrv_first_blk() and bdrv_is_root_node() GRAPH_RDLOCK > block: Mark bdrv_parent_cb_resize() and callers GRAPH_RDLOCK > block: Mark bdrv_snapshot_fallback() and callers GRAPH_RDLOCK > block: Take graph rdlock in parts of reopen > block: Mark bdrv_get_xdbg_block_graph() and callers GRAPH_RDLOCK > block: Mark bdrv_refresh_filename() and callers GRAPH_RDLOCK > block: Mark bdrv_primary_child() and callers GRAPH_RDLOCK > block: Mark bdrv_get_parent_name() and callers GRAPH_RDLOCK > block: Mark bdrv_amend_options() and callers GRAPH_RDLOCK > qcow2: Mark qcow2_signal_corruption() and callers GRAPH_RDLOCK > qcow2: Mark qcow2_inactivate() and callers GRAPH_RDLOCK > qcow2: Mark check_constraints_on_bitmap() GRAPH_RDLOCK > block: Mark bdrv_op_is_blocked() and callers GRAPH_RDLOCK > block: Mark bdrv_apply_auto_read_only() and callers GRAPH_RDLOCK > block: Mark bdrv_get_specific_info() and callers GRAPH_RDLOCK > block: Protect bs->parents with graph_lock > block: Protect bs->children with graph_lock > block: Add assertion for bdrv_graph_wrlock() > > block/qcow2.h | 187 > block/vhdx.h| 5 +- > include/block/block-common.h| 7 +- > include/block/block-global-state.h | 34 ++-- > include/block/block-io.h| 42 +++-- > include/block/block_int-common.h| 69 > include/block/block_int-io.h| 7 +- > include/block/graph-lock.h | 3 +- > include/block/qapi.h| 23 ++- > include/block/snapshot.h| 24 +-- > include/sysemu/block-backend-global-state.h | 4 +- > block.c | 120 + > block/backup.c | 1 + > block/block-backend.c | 9 +- > block/bochs.c | 2 + > block/cloop.c | 2 + > block/commit.c | 1 + > block/crypto.c | 4 +- > block/curl.c| 2 + > block/dmg.c | 2 + > block/export/export.c | 4 + > block/gluster.c | 2 + > block/graph-lock.c | 3 +- > block/io.c | 45 - > block/iscsi.c | 2 + > block/monitor/block-hmp-cmds.c | 5 + > block/nbd.c | 3 +- > block/nfs.c | 2 +- > block/parallels.c | 3 + > block/qapi-sysemu.c | 11 +- > block/qapi.c| 11 +- > block/qcow.c| 3 + > block/qcow2-bitmap.c| 38 ++-- > block/qcow2-cache.c | 11 +- > block/qcow2-cluster.c | 62 +++ > block/qcow2-refcount.c | 80 + > block/qcow2.c | 72 +--- > block/quorum.c | 4 +- > block/raw-format.c | 2 + > block/rbd.c | 4 + > block/replication.c | 2
Re: [PATCH v3] misc/pca9552: Fix for pca9552 not getting reset
On 10/10/23 22:35, Miles Glenn wrote: On Tue, 2023-10-10 at 21:31 +0100, Mark Cave-Ayland wrote: On 10/10/2023 20:52, Glenn Miles wrote: Testing of the pca9552 device on the powernv platform showed that the reset method was not being called when an instance of the device was realized. This was causing the INPUT0/INPUT1 POR values to be incorrect. Fixed by overriding the parent pca955x_realize method with a new pca9552_realize method which first calls the parent pca955x_realize method followed by the pca9552_reset function. Signed-off-by: Glenn Miles --- hw/misc/pca9552.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c index fff19e369a..4e183cc554 100644 --- a/hw/misc/pca9552.c +++ b/hw/misc/pca9552.c @@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(dev, s->gpio, k->pin_count); } +static void pca9552_realize(DeviceState *dev, Error **errp) +{ +pca955x_realize(dev, errp); +pca9552_reset(dev); +} + static Property pca955x_properties[] = { DEFINE_PROP_STRING("description", PCA955xState, description), DEFINE_PROP_END_OF_LIST(), @@ -417,6 +423,7 @@ static void pca9552_class_init(ObjectClass *oc, void *data) PCA955xClass *pc = PCA955X_CLASS(oc); dc->reset = pca9552_reset; +dc->realize = pca9552_realize; dc->vmsd = &pca9552_vmstate; pc->max_reg = PCA9552_LS3; pc->pin_count = 16; The reason that the reset function isn't being called here is because TYPE_I2C_SLAVE is derived from TYPE_DEVICE, and for various historical reasons the DeviceClass reset function is only called for devices that inherit from TYPE_SYS_BUS_DEVICE. Probably the best way to make this work instead of mixing up the reset and realize parts of the object lifecycle is to convert pca9552_reset() to use the new Resettable interface for TYPE_PCA9552: take a look at commit d43e967f69 ("q800- glue.c: convert to Resettable interface") as an example, along with the documentation at https://www.qemu.org/docs/master/devel/reset.html. Ahh, that's very helpful. Thanks, Mark! yes. My bad, I didn't look close enough. Thanks Mark C.
Re: [PATCH v3] misc/pca9552: Fix for pca9552 not getting reset
On Tue, 2023-10-10 at 21:31 +0100, Mark Cave-Ayland wrote: > On 10/10/2023 20:52, Glenn Miles wrote: > > > Testing of the pca9552 device on the powernv platform > > showed that the reset method was not being called when > > an instance of the device was realized. This was causing > > the INPUT0/INPUT1 POR values to be incorrect. > > > > Fixed by overriding the parent pca955x_realize method with a > > new pca9552_realize method which first calls > > the parent pca955x_realize method followed by the > > pca9552_reset function. > > > > Signed-off-by: Glenn Miles > > --- > > hw/misc/pca9552.c | 7 +++ > > 1 file changed, 7 insertions(+) > > > > diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c > > index fff19e369a..4e183cc554 100644 > > --- a/hw/misc/pca9552.c > > +++ b/hw/misc/pca9552.c > > @@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, > > Error **errp) > > qdev_init_gpio_out(dev, s->gpio, k->pin_count); > > } > > > > +static void pca9552_realize(DeviceState *dev, Error **errp) > > +{ > > +pca955x_realize(dev, errp); > > +pca9552_reset(dev); > > +} > > + > > static Property pca955x_properties[] = { > > DEFINE_PROP_STRING("description", PCA955xState, description), > > DEFINE_PROP_END_OF_LIST(), > > @@ -417,6 +423,7 @@ static void pca9552_class_init(ObjectClass *oc, > > void *data) > > PCA955xClass *pc = PCA955X_CLASS(oc); > > > > dc->reset = pca9552_reset; > > +dc->realize = pca9552_realize; > > dc->vmsd = &pca9552_vmstate; > > pc->max_reg = PCA9552_LS3; > > pc->pin_count = 16; > > The reason that the reset function isn't being called here is because > TYPE_I2C_SLAVE > is derived from TYPE_DEVICE, and for various historical reasons the > DeviceClass reset > function is only called for devices that inherit from > TYPE_SYS_BUS_DEVICE. > > Probably the best way to make this work instead of mixing up the > reset and realize > parts of the object lifecycle is to convert pca9552_reset() to use > the new Resettable > interface for TYPE_PCA9552: take a look at commit d43e967f69 ("q800- > glue.c: convert > to Resettable interface") as an example, along with the documentation > at > https://www.qemu.org/docs/master/devel/reset.html. > Ahh, that's very helpful. Thanks, Mark! -Glenn > > ATB, > > Mark. >
Re: [PATCH v3] misc/pca9552: Fix for pca9552 not getting reset
On 10/10/2023 20:52, Glenn Miles wrote: Testing of the pca9552 device on the powernv platform showed that the reset method was not being called when an instance of the device was realized. This was causing the INPUT0/INPUT1 POR values to be incorrect. Fixed by overriding the parent pca955x_realize method with a new pca9552_realize method which first calls the parent pca955x_realize method followed by the pca9552_reset function. Signed-off-by: Glenn Miles --- hw/misc/pca9552.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c index fff19e369a..4e183cc554 100644 --- a/hw/misc/pca9552.c +++ b/hw/misc/pca9552.c @@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(dev, s->gpio, k->pin_count); } +static void pca9552_realize(DeviceState *dev, Error **errp) +{ +pca955x_realize(dev, errp); +pca9552_reset(dev); +} + static Property pca955x_properties[] = { DEFINE_PROP_STRING("description", PCA955xState, description), DEFINE_PROP_END_OF_LIST(), @@ -417,6 +423,7 @@ static void pca9552_class_init(ObjectClass *oc, void *data) PCA955xClass *pc = PCA955X_CLASS(oc); dc->reset = pca9552_reset; +dc->realize = pca9552_realize; dc->vmsd = &pca9552_vmstate; pc->max_reg = PCA9552_LS3; pc->pin_count = 16; The reason that the reset function isn't being called here is because TYPE_I2C_SLAVE is derived from TYPE_DEVICE, and for various historical reasons the DeviceClass reset function is only called for devices that inherit from TYPE_SYS_BUS_DEVICE. Probably the best way to make this work instead of mixing up the reset and realize parts of the object lifecycle is to convert pca9552_reset() to use the new Resettable interface for TYPE_PCA9552: take a look at commit d43e967f69 ("q800-glue.c: convert to Resettable interface") as an example, along with the documentation at https://www.qemu.org/docs/master/devel/reset.html. ATB, Mark.
Re: [PATCH v3] misc/pca9552: Fix for pca9552 not getting reset
On Tue, 2023-10-10 at 21:58 +0200, Cédric Le Goater wrote: > On 10/10/23 21:52, Glenn Miles wrote: > > Testing of the pca9552 device on the powernv platform > > showed that the reset method was not being called when > > an instance of the device was realized. This was causing > > the INPUT0/INPUT1 POR values to be incorrect. > > > > Fixed by overriding the parent pca955x_realize method with a > > new pca9552_realize method which first calls > > the parent pca955x_realize method followed by the > > pca9552_reset function. > > > > Signed-off-by: Glenn Miles > > --- > > It is good practice to include a changelog after '---' Ok, thanks. I'll remember that for next time! > > > > hw/misc/pca9552.c | 7 +++ > > 1 file changed, 7 insertions(+) > > > > diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c > > index fff19e369a..4e183cc554 100644 > > --- a/hw/misc/pca9552.c > > +++ b/hw/misc/pca9552.c > > @@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, > > Error **errp) > > qdev_init_gpio_out(dev, s->gpio, k->pin_count); > > } > > > > +static void pca9552_realize(DeviceState *dev, Error **errp) > > +{ > > +pca955x_realize(dev, errp); > > +pca9552_reset(dev); > > +} > > I don't see any change from v2. The change from v2 can be seen below here where I added back the line for setting the dc->reset method, which was removed in v2. Perhaps I misunderstood what you meant by "You need both handlers, a realize and a reset"? You can see below that both the reset and the realize methods are being initialized. Are you taking issue with the realize function calling the reset function? I did this because in my testing I noticed that reset was not getting called at any point. Is the reset function supposed to get called automatically during device realization? It does not seem to be happening. Thanks, Glenn > > Thanks, > > C. > > > + > > static Property pca955x_properties[] = { > > DEFINE_PROP_STRING("description", PCA955xState, description), > > DEFINE_PROP_END_OF_LIST(), > > @@ -417,6 +423,7 @@ static void pca9552_class_init(ObjectClass *oc, > > void *data) > > PCA955xClass *pc = PCA955X_CLASS(oc); > > > > dc->reset = pca9552_reset; > > +dc->realize = pca9552_realize; > > dc->vmsd = &pca9552_vmstate; > > pc->max_reg = PCA9552_LS3; > > pc->pin_count = 16;
Re: [QEMU][PATCH v1 1/7] xen: when unplugging emulated devices skip virtio devices
Hi Stefano, On Mon, Oct 09, 2023 at 04:51:53PM -0700, Stefano Stabellini wrote: > On Thu, 5 Oct 2023, Vikram Garhwal wrote: > > From: Juergen Gross > > > > Virtio devices should never be unplugged at boot time, as they are > > similar to pci passthrough devices. > > > > Signed-off-by: Juergen Gross > > Signed-off-by: Vikram Garhwal > > --- > > hw/i386/xen/xen_platform.c | 8 +++- > > 1 file changed, 7 insertions(+), 1 deletion(-) > > > > diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c > > index 17457ff3de..3560eaf8c8 100644 > > --- a/hw/i386/xen/xen_platform.c > > +++ b/hw/i386/xen/xen_platform.c > > @@ -28,6 +28,7 @@ > > #include "hw/ide/pci.h" > > #include "hw/pci/pci.h" > > #include "migration/vmstate.h" > > +#include "hw/virtio/virtio-bus.h" > > #include "net/net.h" > > #include "trace.h" > > #include "sysemu/xen.h" > > @@ -132,7 +133,8 @@ static void unplug_nic(PCIBus *b, PCIDevice *d, void *o) > > /* We have to ignore passthrough devices */ > > if (pci_get_word(d->config + PCI_CLASS_DEVICE) == > > PCI_CLASS_NETWORK_ETHERNET > > -&& !pci_device_is_passthrough(d)) { > > +&& !pci_device_is_passthrough(d) > > +&& !qdev_get_child_bus(&d->qdev, TYPE_VIRTIO_BUS)) { > > Please update the in-code comment above to say "ignore passthrough > devices and virtio devices" Sounds good. Will update in the code comment in v2. > > > > object_unparent(OBJECT(d)); > > } > > } > > @@ -208,6 +210,10 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void > > *opaque) > > /* We have to ignore passthrough devices */ > > if (pci_device_is_passthrough(d)) > > return; > > +/* Ignore virtio devices */ > > +if (qdev_get_child_bus(&d->qdev, TYPE_VIRTIO_BUS)) { > > +return; > > +} > > > > switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) { > > case PCI_CLASS_STORAGE_IDE: > > -- > > 2.17.1 > >
Re: [PATCH v2 0/6] scripts/migration: Fix analyze-migration.py and add a test
Fabiano Rosas writes: > was: [PATCH] qtest/migration: Add a test for the analyze-migration script > https://lore.kernel.org/r/20230927214756.14117-1-faro...@suse.de > > The analyze-migration.py script should be kept in sync with the code > that generates the migration stream. The addition/removal of sections > and flags from the stream can cause the script to break. Issues when > parsing the stream mostly manifest in the form of cryptic python > errors such as: Well, not _that_ cryptic. =) I meant to add this: UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 55: invalid start byte
Re: [PATCH 2/4] migration: check for rate_limit_max for RATE_LIMIT_DISABLED
On Thu, Sep 21, 2023 at 11:56:23PM -0700, Elena Ufimtseva wrote: > In migration rate limiting atomic operations are used > to read the rate limit variables and transferred bytes and > they are expensive. Check first if rate_limit_max is equal > to RATE_LIMIT_DISABLED and return false immediately if so. > > Signed-off-by: Elena Ufimtseva Reviewed-by: Peter Xu One trivial comment: > --- > migration/migration-stats.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/migration/migration-stats.c b/migration/migration-stats.c > index 095d6d75bb..abc31483d5 100644 > --- a/migration/migration-stats.c > +++ b/migration/migration-stats.c > @@ -24,14 +24,14 @@ bool migration_rate_exceeded(QEMUFile *f) > return true; > } > > -uint64_t rate_limit_start = stat64_get(&mig_stats.rate_limit_start); > -uint64_t rate_limit_current = migration_transferred_bytes(f); > -uint64_t rate_limit_used = rate_limit_current - rate_limit_start; > uint64_t rate_limit_max = stat64_get(&mig_stats.rate_limit_max); Side note: since we have a helper, this can be migration_rate_get() too. > - > if (rate_limit_max == RATE_LIMIT_DISABLED) { > return false; > } empty line would be nice. > +uint64_t rate_limit_start = stat64_get(&mig_stats.rate_limit_start); > +uint64_t rate_limit_current = migration_transferred_bytes(f); > +uint64_t rate_limit_used = rate_limit_current - rate_limit_start; > + > if (rate_limit_max > 0 && rate_limit_used > rate_limit_max) { > return true; > } > -- > 2.34.1 > > -- Peter Xu
Re: [PATCH] ppc/pnv: Add an I2C master controller model
On Mon, 2023-10-09 at 22:42 +0200, Cédric Le Goater wrote: > Hello Glenn, > > On 10/9/23 20:05, Glenn Miles wrote: > > From: Cédric Le Goater > > > > Not supported : > > > > . 10 bit addresses > > . multimaster > > . slave > > > > Signed-off-by: Cédric Le Goater > > Signed-off-by: Glenn Miles > > [milesg: fixed formatting warning] > > Overall it looks good ;) > > Some suggestions for the respin : > > * Please split the model implementation from the wiring in the board. >Adding a cover letter would be nice. > Done. > * In the commit log, please add more details on the unit being > modeled, >how this I2C unit interacts with the rest of the machine, what is >modeled, what is not, etc. A simple intro in short. > Done. > * Add a SPDX-License-Identifier tag in new files. > Done. > Thanks, > > C. > > PS: I am not getting your emails for some (corporate) reasons. > > Yes, sorry about that! I've added your redhat email. Hopefully that's ok. Thanks, Glenn > > --- > > hw/ppc/meson.build | 1 + > > hw/ppc/pnv.c | 26 ++ > > hw/ppc/pnv_i2c.c | 678 > > + > > include/hw/ppc/pnv_chip.h | 4 + > > include/hw/ppc/pnv_i2c.h | 39 +++ > > include/hw/ppc/pnv_xscom.h | 3 + > > 6 files changed, 751 insertions(+) > > create mode 100644 hw/ppc/pnv_i2c.c > > create mode 100644 include/hw/ppc/pnv_i2c.h > > > > diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build > > index 7c2c52434a..87b756a701 100644 > > --- a/hw/ppc/meson.build > > +++ b/hw/ppc/meson.build > > @@ -43,6 +43,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: > > files( > > 'pnv.c', > > 'pnv_xscom.c', > > 'pnv_core.c', > > + 'pnv_i2c.c', > > 'pnv_lpc.c', > > 'pnv_psi.c', > > 'pnv_occ.c', > > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c > > index eb54f93986..32b6d9889d 100644 > > --- a/hw/ppc/pnv.c > > +++ b/hw/ppc/pnv.c > > @@ -1438,6 +1438,10 @@ static void > > pnv_chip_power9_instance_init(Object *obj) > > object_initialize_child(obj, "pec[*]", &chip9->pecs[i], > > TYPE_PNV_PHB4_PEC); > > } > > + > > +for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) { > > +object_initialize_child(obj, "i2c[*]", &chip9->i2c[i], > > TYPE_PNV_I2C); > > +} > > } > > > > static void pnv_chip_quad_realize_one(PnvChip *chip, PnvQuad *eq, > > @@ -1510,6 +1514,7 @@ static void > > pnv_chip_power9_realize(DeviceState *dev, Error **errp) > > PnvChip *chip = PNV_CHIP(dev); > > Pnv9Psi *psi9 = &chip9->psi; > > Error *local_err = NULL; > > +int i; > > > > /* XSCOM bridge is first */ > > pnv_xscom_realize(chip, PNV9_XSCOM_SIZE, &local_err); > > @@ -1613,6 +1618,27 @@ static void > > pnv_chip_power9_realize(DeviceState *dev, Error **errp) > > error_propagate(errp, local_err); > > return; > > } > > + > > +/* > > + * I2C > > + * TODO: The number of busses is specific to each platform > > + */ > > +for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) { > > +Object *obj = OBJECT(&chip9->i2c[i]); > > + > > +object_property_set_int(obj, "engine", i + 1, > > &error_fatal); > > +object_property_set_int(obj, "num-busses", 1, > > &error_fatal); > > +object_property_set_link(obj, "chip", OBJECT(chip), > > &error_abort); > > +if (!qdev_realize(DEVICE(obj), NULL, errp)) { > > +return; > > +} > > +pnv_xscom_add_subregion(chip, PNV9_XSCOM_I2CM_BASE + > > + chip9->i2c[i].engine * > > PNV9_XSCOM_I2CM_SIZE, > > +&chip9->i2c[i].xscom_regs); > > +qdev_connect_gpio_out(DEVICE(&chip9->i2c[i]), 0, > > + qdev_get_gpio_in(DEVICE(&chip9- > > >psi), > > + PSIHB9_IRQ_SBE_I2C) > > ); > > +} > > } > > > > static uint32_t pnv_chip_power9_xscom_pcba(PnvChip *chip, > > uint64_t addr) > > diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c > > new file mode 100644 > > index 00..8c191912bf > > --- /dev/null > > +++ b/hw/ppc/pnv_i2c.c > > @@ -0,0 +1,678 @@ > > +/* > > + * QEMU PowerPC PowerNV Processor I2C model > > + * > > + * Copyright (c) 2019-2021, IBM Corporation. > > + * > > + * This code is licensed under the GPL version 2 or later. See the > > + * COPYING file in the top-level directory. > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "qemu/module.h" > > +#include "qemu/log.h" > > +#include "sysemu/reset.h" > > + > > +#include "hw/irq.h" > > +#include "hw/qdev-properties.h" > > + > > +#include "hw/ppc/pnv.h" > > +#include "hw/ppc/pnv_chip.h" > > +#include "hw/ppc/pnv_i2c.h" > > +#include "hw/ppc/pnv_xscom.h" > > +#include "hw/ppc/fdt.h" > > + > > +#include > > + > > +/* I2C FIFO register */ > > +#define I2C_FIFO_REG0x4 > > +#define I2C_FIFOPPC_BITMASK(0, 7)
Re: [PATCH 2/2] ppc/pnv: Connect I2C controller model to powernv9 chip
On 10/10/23 19:19, Glenn Miles wrote: From: Cédric Le Goater Wires up three I2C controller instances to the powernv9 chip XSCOM address space. Each controller instance is wired up to a single I2C bus of its own. No other I2C devices are connected to the buses at this time. Signed-off-by: Cédric Le Goater [milesg: Split wiring from addition of model itself] [milesg: Added new commit message] Signed-off-by: Glenn Miles --- hw/ppc/pnv.c | 26 ++ include/hw/ppc/pnv_chip.h | 4 2 files changed, 30 insertions(+) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index eb54f93986..32b6d9889d 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1438,6 +1438,10 @@ static void pnv_chip_power9_instance_init(Object *obj) object_initialize_child(obj, "pec[*]", &chip9->pecs[i], TYPE_PNV_PHB4_PEC); } + +for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) { +object_initialize_child(obj, "i2c[*]", &chip9->i2c[i], TYPE_PNV_I2C); +} } static void pnv_chip_quad_realize_one(PnvChip *chip, PnvQuad *eq, @@ -1510,6 +1514,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) PnvChip *chip = PNV_CHIP(dev); Pnv9Psi *psi9 = &chip9->psi; Error *local_err = NULL; +int i; /* XSCOM bridge is first */ pnv_xscom_realize(chip, PNV9_XSCOM_SIZE, &local_err); @@ -1613,6 +1618,27 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) error_propagate(errp, local_err); return; } + +/* + * I2C + * TODO: The number of busses is specific to each platform Could the hardcoded values used in the properties below be PnvChipClass attributes instead ? Thanks, C. + */ +for (i = 0; i < PNV9_CHIP_MAX_I2C; i++) { +Object *obj = OBJECT(&chip9->i2c[i]); + +object_property_set_int(obj, "engine", i + 1, &error_fatal); +object_property_set_int(obj, "num-busses", 1, &error_fatal); +object_property_set_link(obj, "chip", OBJECT(chip), &error_abort); +if (!qdev_realize(DEVICE(obj), NULL, errp)) { +return; +} +pnv_xscom_add_subregion(chip, PNV9_XSCOM_I2CM_BASE + + chip9->i2c[i].engine * PNV9_XSCOM_I2CM_SIZE, +&chip9->i2c[i].xscom_regs); +qdev_connect_gpio_out(DEVICE(&chip9->i2c[i]), 0, + qdev_get_gpio_in(DEVICE(&chip9->psi), + PSIHB9_IRQ_SBE_I2C)); +} } static uint32_t pnv_chip_power9_xscom_pcba(PnvChip *chip, uint64_t addr) diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h index 53e1d921d7..3bbe2783c9 100644 --- a/include/hw/ppc/pnv_chip.h +++ b/include/hw/ppc/pnv_chip.h @@ -9,6 +9,7 @@ #include "hw/ppc/pnv_psi.h" #include "hw/ppc/pnv_sbe.h" #include "hw/ppc/pnv_xive.h" +#include "hw/ppc/pnv_i2c.h" #include "hw/sysbus.h" OBJECT_DECLARE_TYPE(PnvChip, PnvChipClass, @@ -86,6 +87,9 @@ struct Pnv9Chip { #define PNV9_CHIP_MAX_PEC 3 PnvPhb4PecState pecs[PNV9_CHIP_MAX_PEC]; + +#define PNV9_CHIP_MAX_I2C 3 +PnvI2C i2c[PNV9_CHIP_MAX_I2C]; }; /*
Re: [PATCH v3 3/4] migration/qapi: Replace @MigrateSetParameters with @MigrationParameters
Hi, Markus, On Tue, Oct 10, 2023 at 09:18:23PM +0200, Markus Armbruster wrote: [...] > >> The point I was trying to make is this. Before the patch, we reject > >> attempts to set the property value to null. Afterwards, we accept them, > >> i.e. the patch loses "reject null property value". If this loss is > >> undesirable, we better replace it with suitable hand-written code. > > > > I don't even know how to set it to NULL before.. as it can only be accessed > > via cmdline "-global" as mentioned above, which must be a string anyway. > > So I assume this is not an issue. > > Something like > > {"execute": "migrate-set-parameters", > "arguments": {"tls-authz": null}} > > Hmm, crashes in migrate_params_apply(), which is a bug. I'm getting > more and more suspicious about user-facing migration code... Did you apply patch 1 of this series? https://lore.kernel.org/qemu-devel/20230905162335.235619-2-pet...@redhat.com/ QMP "migrate-set-parameters" does not go via migration_properties, so even if we change handling of migration_properties, it shouldn't yet affect the QMP interface of that. > > If the migration object is accessible with qom-set, then that's another > way to assign null values. I see what you meant. IMHO we just don't need to worry on breaking that as I am not aware of anyone using that to set migration parameters, and I think the whole idea of migration_properties is for debugging. The only legal way an user should set migration parameters should be via QMP, afaik. > In my "QAPI string visitors crashes" memo, I demonstrated that the crash > on funny property type predates your series. You merely add another > instance. Moreover, crashing -global is less serious than a crashing > monitor command, because only the latter can take down a running guest. > Can't see why your series needs to wait for a fix of the crash bug. > Makes sense? What's your suggestion to move on with this series without a fix for that crash bug? I started this series with making tls_* all strings (rather than StrOrNull) and that actually worked out, mostly. We switched to StrOrNull just because we think it's cleaner and 100% not breaking anyone (even though I still don't think the other way will). I don't see how I can proceed this series without fixing this visitor issue but keep using StrOrNull. Please don't worry on blocking my work: it won't anymore. The thing I need is: https://lore.kernel.org/qemu-devel/20230905193802.250440-1-pet...@redhat.com/ While this whole series is just paving way for it. If I can't get immediate results out of this series, I'll just go with the triplications, leaving all the rest for later. Thanks, -- Peter Xu
Re: [PATCH 1/2] ppc/pnv: Add an I2C controller model
On 10/10/23 19:19, Glenn Miles wrote: From: Cédric Le Goater The more recent IBM power processors have an embedded I2C controller that is accessible by software via the XSCOM address space. Each instance of the I2C controller is capable of controlling multiple I2C buses (one at a time). Prior to beginning a transaction on an I2C bus, the bus must be selected by writing the port number associated with the bus into the PORT_NUM field of the MODE register. Once an I2C bus is selected, the status of the bus can be determined by reading the Status and Extended Status registers. I2C bus transactions can be started by writing a command to the Command register and reading/writing data from/to the FIFO register. Not supported : . 10 bit I2C addresses . Multimaster . Slave Signed-off-by: Cédric Le Goater [milesg: Split wiring to powernv9 into its own commit] [milesg: Added more detail to commit message] Thanks ! [milesg: Added SPDX Licensed Identifier to new files] Signed-off-by: Glenn Miles --- hw/ppc/meson.build | 1 + hw/ppc/pnv_i2c.c | 680 + include/hw/ppc/pnv_i2c.h | 41 +++ include/hw/ppc/pnv_xscom.h | 3 + 4 files changed, 725 insertions(+) create mode 100644 hw/ppc/pnv_i2c.c create mode 100644 include/hw/ppc/pnv_i2c.h diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index 7c2c52434a..87b756a701 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -43,6 +43,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files( 'pnv.c', 'pnv_xscom.c', 'pnv_core.c', + 'pnv_i2c.c', 'pnv_lpc.c', 'pnv_psi.c', 'pnv_occ.c', diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c new file mode 100644 index 00..356d578ad4 --- /dev/null +++ b/hw/ppc/pnv_i2c.c @@ -0,0 +1,680 @@ +/* + * QEMU PowerPC PowerNV Processor I2C model + * + * Copyright (c) 2019-2021, IBM Corporation. The date range should be 2019-2023 now. + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + * + * SPDX-License-Identifier: GPL-2.0-or-later The SPDX tag is enough. You can remove the previous paragraph. + */ + +#include "qemu/osdep.h" +#include "qemu/module.h" +#include "qemu/log.h" +#include "sysemu/reset.h" + +#include "hw/irq.h" +#include "hw/qdev-properties.h" + +#include "hw/ppc/pnv.h" +#include "hw/ppc/pnv_chip.h" +#include "hw/ppc/pnv_i2c.h" +#include "hw/ppc/pnv_xscom.h" +#include "hw/ppc/fdt.h" + +#include + +/* I2C FIFO register */ +#define I2C_FIFO_REG0x4 +#define I2C_FIFOPPC_BITMASK(0, 7) + +/* I2C command register */ +#define I2C_CMD_REG 0x5 +#define I2C_CMD_WITH_START PPC_BIT(0) +#define I2C_CMD_WITH_ADDR PPC_BIT(1) +#define I2C_CMD_READ_CONT PPC_BIT(2) +#define I2C_CMD_WITH_STOP PPC_BIT(3) +#define I2C_CMD_INTR_STEERING PPC_BITMASK(6, 7) /* P9 */ +#define I2C_CMD_INTR_STEER_HOST 1 +#define I2C_CMD_INTR_STEER_OCC2 +#define I2C_CMD_DEV_ADDRPPC_BITMASK(8, 14) +#define I2C_CMD_READ_NOT_WRITE PPC_BIT(15) +#define I2C_CMD_LEN_BYTES PPC_BITMASK(16, 31) +#define I2C_MAX_TFR_LEN 0xfff0ull + +/* I2C mode register */ +#define I2C_MODE_REG0x6 +#define I2C_MODE_BIT_RATE_DIV PPC_BITMASK(0, 15) +#define I2C_MODE_PORT_NUM PPC_BITMASK(16, 21) +#define I2C_MODE_ENHANCED PPC_BIT(28) +#define I2C_MODE_DIAGNOSTIC PPC_BIT(29) +#define I2C_MODE_PACING_ALLOW PPC_BIT(30) +#define I2C_MODE_WRAP PPC_BIT(31) + +/* I2C watermark register */ +#define I2C_WATERMARK_REG 0x7 +#define I2C_WATERMARK_HIGH PPC_BITMASK(16, 19) +#define I2C_WATERMARK_LOW PPC_BITMASK(24, 27) + +/* + * I2C interrupt mask and condition registers + * + * NB: The function of 0x9 and 0xa changes depending on whether you're reading + * or writing to them. When read they return the interrupt condition bits + * and on writes they update the interrupt mask register. + * + * The bit definitions are the same for all the interrupt registers. + */ +#define I2C_INTR_MASK_REG 0x8 + +#define I2C_INTR_RAW_COND_REG 0x9 /* read */ +#define I2C_INTR_MASK_OR_REG0x9 /* write*/ + +#define I2C_INTR_COND_REG 0xa /* read */ +#define I2C_INTR_MASK_AND_REG 0xa /* write */ + +#define I2C_INTR_ALLPPC_BITMASK(16, 31) +#define I2C_INTR_INVALID_CMDPPC_BIT(16) +#define I2C_INTR_LBUS_PARITY_ERRPPC_BIT(17) +#define I2C_INTR_BKEND_OVERRUN_ERR PPC_BIT(18) +#define I2C_INTR_BKEND_ACCESS_ERR PPC_BIT(19) +#define I2C_INTR_ARBT_LOST_ERR PPC_BIT(20) +#define I2C_INTR_NACK_RCVD_ERR PPC_BIT(21) +#define I2C_INTR_DATA_REQ PPC_BIT(22) +#define I2C_INTR_CMD_COMP
Re: [PATCH v2 00/10] mirror: allow switching from background to active mode
On 10.10.23 20:55, Vladimir Sementsov-Ogievskiy wrote: On 09.10.23 12:46, Fiona Ebner wrote: Changes in v2: * move bitmap to filter which allows to avoid draining when changing the copy mode * add patch to determine copy_to_target only once * drop patches returning redundant information upon query * update QEMU version in QAPI * update indentation in QAPI * update indentation in QAPI (like in a937b6aa73 ("qapi: Reformat doc comments to conform to current conventions")) * add patch to adapt iotest output Discussion of v1: https://lists.nongnu.org/archive/html/qemu-devel/2023-02/msg07216.html With active mode, the guest write speed is limited by the synchronous writes to the mirror target. For this reason, management applications might want to start out in background mode and only switch to active mode later, when certain conditions are met. This series adds a block-job-change QMP command to achieve that, as well as job-type-specific information when querying block jobs, which can be used to decide when the switch should happen. For now, only the direction background -> active is supported. The information added upon querying is whether the target is actively synced, the total data sent, and the remaining dirty bytes. Initially, I tried to go for a more general 'job-change' command, but I couldn't figure out a way to avoid mutual inclusion between block-core.json and job.json. What is the problem with it? I still think that job-change would be better. However, that's not a show-stopper. We have block-job-* commands, they are not deprecated, no problem to add one more. -- Best regards, Vladimir
Re: [PATCH v3] misc/pca9552: Fix for pca9552 not getting reset
On 10/10/23 21:52, Glenn Miles wrote: Testing of the pca9552 device on the powernv platform showed that the reset method was not being called when an instance of the device was realized. This was causing the INPUT0/INPUT1 POR values to be incorrect. Fixed by overriding the parent pca955x_realize method with a new pca9552_realize method which first calls the parent pca955x_realize method followed by the pca9552_reset function. Signed-off-by: Glenn Miles --- It is good practice to include a changelog after '---' hw/misc/pca9552.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c index fff19e369a..4e183cc554 100644 --- a/hw/misc/pca9552.c +++ b/hw/misc/pca9552.c @@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(dev, s->gpio, k->pin_count); } +static void pca9552_realize(DeviceState *dev, Error **errp) +{ +pca955x_realize(dev, errp); +pca9552_reset(dev); +} I don't see any change from v2. Thanks, C. + static Property pca955x_properties[] = { DEFINE_PROP_STRING("description", PCA955xState, description), DEFINE_PROP_END_OF_LIST(), @@ -417,6 +423,7 @@ static void pca9552_class_init(ObjectClass *oc, void *data) PCA955xClass *pc = PCA955X_CLASS(oc); dc->reset = pca9552_reset; +dc->realize = pca9552_realize; dc->vmsd = &pca9552_vmstate; pc->max_reg = PCA9552_LS3; pc->pin_count = 16;
Re: [PATCH v2 10/10] iotests: adapt test output for new mirror query property
On 09.10.23 12:46, Fiona Ebner wrote: Signed-off-by: Fiona Ebner This should be merged to the previous patch, to not break git bisect. Tests should work at any commit. -- Best regards, Vladimir
Re: [PATCH v2] misc/pca9552: Fix for pca9552 not getting reset
On Mon, 2023-10-09 at 23:06 +0200, Cédric Le Goater wrote: > Hello Glenn, > > On 10/5/23 23:10, Glenn Miles wrote: > > Testing of the pca9552 device on the powernv platform > > showed that the reset method was not being called when > > an instance of the device was realized. This was causing > > the INPUT0/INPUT1 POR values to be incorrect. > > > > Fixed by overriding the parent pca955x_realize method with a > > new pca9552_realize method which first calls > > the parent pca955x_realize method followed by the > > pca9552_reset function. > > > > Signed-off-by: Glenn Miles > > --- > > hw/misc/pca9552.c | 8 +++- > > 1 file changed, 7 insertions(+), 1 deletion(-) > > > > diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c > > index fff19e369a..bc12dced7f 100644 > > --- a/hw/misc/pca9552.c > > +++ b/hw/misc/pca9552.c > > @@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, > > Error **errp) > > qdev_init_gpio_out(dev, s->gpio, k->pin_count); > > } > > > > +static void pca9552_realize(DeviceState *dev, Error **errp) > > +{ > > +pca955x_realize(dev, errp); > > +pca9552_reset(dev); > > +} > > This looks wrong. You need both handlers, a realize and a reset. > > Thanks, > > C. > Ok, sent version 3. Thanks, Glenn > > > + > > static Property pca955x_properties[] = { > > DEFINE_PROP_STRING("description", PCA955xState, description), > > DEFINE_PROP_END_OF_LIST(), > > @@ -416,7 +422,7 @@ static void pca9552_class_init(ObjectClass *oc, > > void *data) > > DeviceClass *dc = DEVICE_CLASS(oc); > > PCA955xClass *pc = PCA955X_CLASS(oc); > > > > -dc->reset = pca9552_reset; > > +dc->realize = pca9552_realize; > > dc->vmsd = &pca9552_vmstate; > > pc->max_reg = PCA9552_LS3; > > pc->pin_count = 16;
Re: [PATCH v2 09/10] mirror: return mirror-specific information upon query
On 09.10.23 12:46, Fiona Ebner wrote: To start out, only actively-synced is returned. For example, this is useful for jobs that started out in background mode and switched to active mode. Once actively-synced is true, it's clear that the mode switch has been completed. Note that completion of the switch might happen much earlier, e.g. if the switch happens before the job is ready, once all background operations have finished. It's assumed that whether the disks are actively-synced or not is more interesting than whether the mode switch completed. That information can still be added if required in the future. Signed-off-by: Fiona Ebner --- Changes in v2: * udpate QEMU version in QAPI * update indentation in QAPI (like in a937b6aa73 ("qapi: Reformat doc comments to conform to current conventions")) block/mirror.c | 10 ++ qapi/block-core.json | 16 +++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/block/mirror.c b/block/mirror.c index 83aa4176c2..33b72ec5e5 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1267,6 +1267,15 @@ static void mirror_change(BlockJob *job, BlockJobChangeOptions *opts, s->copy_mode = MIRROR_COPY_MODE_WRITE_BLOCKING; } +static void mirror_query(BlockJob *job, BlockJobInfo *info) +{ +MirrorBlockJob *s = container_of(job, MirrorBlockJob, common); + +info->u.mirror = (BlockJobInfoMirror) { +.actively_synced = s->actively_synced, So, seems we should use atomic operations to access this field too +}; +} + static const BlockJobDriver mirror_job_driver = { .job_driver = { .instance_size = sizeof(MirrorBlockJob), @@ -1282,6 +1291,7 @@ static const BlockJobDriver mirror_job_driver = { }, .drained_poll = mirror_drained_poll, .change = mirror_change, +.query = mirror_query, }; static const BlockJobDriver commit_active_job_driver = { diff --git a/qapi/block-core.json b/qapi/block-core.json index 950542b735..35d67410cc 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1352,6 +1352,20 @@ { 'enum': 'MirrorCopyMode', 'data': ['background', 'write-blocking'] } +## +# @BlockJobInfoMirror: +# +# Information specific to mirror block jobs. +# +# @actively-synced: Whether the source is actively synced to the +# target, i.e. same data and new writes are done synchronously to +# both. +# +# Since 8.2 +## +{ 'struct': 'BlockJobInfoMirror', + 'data': { 'actively-synced': 'bool' } } + ## # @BlockJobInfo: # @@ -1403,7 +1417,7 @@ 'auto-finalize': 'bool', 'auto-dismiss': 'bool', '*error': 'str' }, 'discriminator': 'type', - 'data': {} } + 'data': { 'mirror': 'BlockJobInfoMirror' } } ## # @query-block-jobs: -- Best regards, Vladimir
[PATCH v3] misc/pca9552: Fix for pca9552 not getting reset
Testing of the pca9552 device on the powernv platform showed that the reset method was not being called when an instance of the device was realized. This was causing the INPUT0/INPUT1 POR values to be incorrect. Fixed by overriding the parent pca955x_realize method with a new pca9552_realize method which first calls the parent pca955x_realize method followed by the pca9552_reset function. Signed-off-by: Glenn Miles --- hw/misc/pca9552.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c index fff19e369a..4e183cc554 100644 --- a/hw/misc/pca9552.c +++ b/hw/misc/pca9552.c @@ -384,6 +384,12 @@ static void pca955x_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(dev, s->gpio, k->pin_count); } +static void pca9552_realize(DeviceState *dev, Error **errp) +{ +pca955x_realize(dev, errp); +pca9552_reset(dev); +} + static Property pca955x_properties[] = { DEFINE_PROP_STRING("description", PCA955xState, description), DEFINE_PROP_END_OF_LIST(), @@ -417,6 +423,7 @@ static void pca9552_class_init(ObjectClass *oc, void *data) PCA955xClass *pc = PCA955X_CLASS(oc); dc->reset = pca9552_reset; +dc->realize = pca9552_realize; dc->vmsd = &pca9552_vmstate; pc->max_reg = PCA9552_LS3; pc->pin_count = 16; -- 2.31.1
Re: [PATCH v2 08/10] blockjob: query driver-specific info via a new 'query' driver method
On 09.10.23 12:46, Fiona Ebner wrote: Signed-off-by: Fiona Ebner --- No changes in v2. blockjob.c | 4 include/block/blockjob_int.h | 5 + 2 files changed, 9 insertions(+) diff --git a/blockjob.c b/blockjob.c index f8cf6e58e2..7e8cfad0fd 100644 --- a/blockjob.c +++ b/blockjob.c @@ -376,6 +376,7 @@ BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp) { BlockJobInfo *info; uint64_t progress_current, progress_total; +const BlockJobDriver *drv = block_job_driver(job); GLOBAL_STATE_CODE(); @@ -405,6 +406,9 @@ BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp) g_strdup(error_get_pretty(job->job.err)) : g_strdup(strerror(-job->job.ret)); } +if (drv->query) { +drv->query(job, info); Other handlers are called with job lock dropped. +} return info; } diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h index f604985315..4ab88b3c97 100644 --- a/include/block/blockjob_int.h +++ b/include/block/blockjob_int.h @@ -72,6 +72,11 @@ struct BlockJobDriver { * Change the @job's options according to @opts. */ void (*change)(BlockJob *job, BlockJobChangeOptions *opts, Error **errp); + +/* + * Query information specific to this kind of block job. + */ +void (*query)(BlockJob *job, BlockJobInfo *info); }; /* -- Best regards, Vladimir