qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"Daniel P . Berrange" <berrange@redhat.com>,
	"Eduardo Habkost" <eduardo@habkost.net>,
	"Alistair Francis" <alistair@alistair23.me>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Anton Johansson" <anjo@rev.ng>,
	"Edgar E . Iglesias" <edgar.iglesias@gmail.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Cédric Le Goater" <clg@kaod.org>,
	"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
	"Bernhard Beschow" <shentey@gmail.com>,
	"Alessandro Di Federico" <ale@rev.ng>,
	qemu-arm@nongnu.org, "Luc Michel" <luc@lmichel.fr>
Subject: Re: [PATCH 1/2] hw/sd/omap_mmc: Do not reset SDCard until being fully realized
Date: Mon, 18 Sep 2023 17:22:37 +0200	[thread overview]
Message-ID: <d1326804-2bca-3b06-250a-3ca3a8038d1c@linaro.org> (raw)
In-Reply-To: <CAFEAcA89z1vCwDzzB_GjbUBtcOCz4vU7r_zC4nMmunp5BGVWxA@mail.gmail.com>

On 18/9/23 13:00, Peter Maydell wrote:
> On Mon, 18 Sept 2023 at 11:17, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>>
>> We shouldn't call QDev DeviceReset() before DeviceRealize().
>>
>> Since the OMAP MMC model is not QDev'ified, it has to manually
>> call the SDCard reset() handler. This breaks QDev assumptions
>> that DeviceReset() is never called before a device is fully
>> realized. In order to avoid that, pass a 'realized' argument
>> to omap_mmc_reset(). All cases are explicit manual resets,
>> except in omap_mmc_write() where we expect the sdcard to be
>> realized.
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> ---
>>   include/hw/arm/omap.h |  2 +-
>>   hw/arm/omap1.c        |  2 +-
>>   hw/arm/omap2.c        |  2 +-
>>   hw/sd/omap_mmc.c      | 21 ++++++++++++---------
>>   4 files changed, 15 insertions(+), 12 deletions(-)
>>
>> diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
>> index 067e9419f7..d331467946 100644
>> --- a/include/hw/arm/omap.h
>> +++ b/include/hw/arm/omap.h
>> @@ -808,7 +808,7 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
>>   struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
>>                   BlockBackend *blk, qemu_irq irq, qemu_irq dma[],
>>                   omap_clk fclk, omap_clk iclk);
>> -void omap_mmc_reset(struct omap_mmc_s *s);
>> +void omap_mmc_reset(struct omap_mmc_s *s, bool realized);
>>   void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
>>   void omap_mmc_enable(struct omap_mmc_s *s, int enable);
>>
>> diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
>> index d5438156ee..3afeba6f86 100644
>> --- a/hw/arm/omap1.c
>> +++ b/hw/arm/omap1.c
>> @@ -3728,7 +3728,7 @@ static void omap1_mpu_reset(void *opaque)
>>       omap_uart_reset(mpu->uart[0]);
>>       omap_uart_reset(mpu->uart[1]);
>>       omap_uart_reset(mpu->uart[2]);
>> -    omap_mmc_reset(mpu->mmc);
>> +    omap_mmc_reset(mpu->mmc, false);
>>       omap_mpuio_reset(mpu->mpuio);
>>       omap_uwire_reset(mpu->microwire);
>>       omap_pwl_reset(mpu->pwl);
>> diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
>> index d5a2ae7af6..ef9b0dd60a 100644
>> --- a/hw/arm/omap2.c
>> +++ b/hw/arm/omap2.c
>> @@ -2253,7 +2253,7 @@ static void omap2_mpu_reset(void *opaque)
>>       omap_uart_reset(mpu->uart[0]);
>>       omap_uart_reset(mpu->uart[1]);
>>       omap_uart_reset(mpu->uart[2]);
>> -    omap_mmc_reset(mpu->mmc);
>> +    omap_mmc_reset(mpu->mmc, false);
>>       omap_mcspi_reset(mpu->mcspi[0]);
>>       omap_mcspi_reset(mpu->mcspi[1]);
>>       cpu_reset(CPU(mpu->cpu));
> 
> These are reset functions registered via qemu_register_reset().
> They should be OK to assume the SD card is realized.
> This matters, because this is the only place that the SD
> card will get reset -- as the comment in omap_mmc_reset() notes,
> the SD card object isn't going to be plugged into any bus, so
> it won't get auto-reset when the simulation starts, and these
> reset function are the place that does the manual reset.
> 
>> diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
>> index edd3cf2a1e..3c906993eb 100644
>> --- a/hw/sd/omap_mmc.c
>> +++ b/hw/sd/omap_mmc.c
>> @@ -287,7 +287,7 @@ static void omap_mmc_pseudo_reset(struct omap_mmc_s *host)
>>       host->fifo_len = 0;
>>   }
>>
>> -void omap_mmc_reset(struct omap_mmc_s *host)
>> +void omap_mmc_reset(struct omap_mmc_s *host, bool realized)
>>   {
>>       host->last_cmd = 0;
>>       memset(host->rsp, 0, sizeof(host->rsp));
>> @@ -314,11 +314,14 @@ void omap_mmc_reset(struct omap_mmc_s *host)
>>
>>       omap_mmc_pseudo_reset(host);
>>
>> -    /* Since we're still using the legacy SD API the card is not plugged
>> -     * into any bus, and we must reset it manually. When omap_mmc is
>> -     * QOMified this must move into the QOM reset function.
>> -     */
>> -    device_cold_reset(DEVICE(host->card));
>> +    if (realized) {
>> +        /*
>> +         * Since we're still using the legacy SD API the card is not plugged
>> +         * into any bus, and we must reset it manually. When omap_mmc is
>> +         * QOMified this must move into the QOM reset function.
>> +         */
>> +        device_cold_reset(DEVICE(host->card));
>> +    }
>>   }
>>
>>   static uint64_t omap_mmc_read(void *opaque, hwaddr offset, unsigned size)
>> @@ -556,7 +559,7 @@ static void omap_mmc_write(void *opaque, hwaddr offset,
>>           break;
>>       case 0x64: /* MMC_SYSC */
>>           if (value & (1 << 2))                                  /* SRTS */
>> -            omap_mmc_reset(s);
>> +            omap_mmc_reset(s, true);
>>           break;
>>       case 0x68: /* MMC_SYSS */
>>           OMAP_RO_REG(offset);
>> @@ -613,7 +616,7 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
>>           exit(1);
>>       }
>>
>> -    omap_mmc_reset(s);
>> +    omap_mmc_reset(s, false);
>>
>>       return s;
>>   }
>> @@ -643,7 +646,7 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
>>       s->cdet = qemu_allocate_irq(omap_mmc_cover_cb, s, 0);
>>       sd_set_cb(s->card, NULL, s->cdet);
>>
>> -    omap_mmc_reset(s);
>> +    omap_mmc_reset(s, false);
> 
> These calls from omap_mmc_init() are probably safe to remove, but I
> don't understand why they result in our resetting a non-realized
> SD card object. In both cases, the call happens after we call
> sd_init(). sd_init() both creates and realizes the SD card, so
> it should be realized at the point when it gets reset.

Indeed, sd_realize() is called:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
   * frame #0: 0x1001f047c qemu-system-arm`sd_realize [inlined] 
SD_CARD(obj=0x103b339e0) at sd.h:94:1
     frame #1: 0x1001f047c qemu-system-arm`sd_realize(dev=0x103b339e0, 
errp=0x16fdfeaa0) at sd.c:2193:19
     frame #2: 0x1001f03e8 qemu-system-arm`sd_init(blk=<unavailable>, 
is_spi=<unavailable>) at sd.c:765:5
     frame #3: 0x1001fa1c8 
qemu-system-arm`omap2_mmc_init(ta=0x104838060, blk=<unavailable>, 
irq=0x0000600001720080, dma=0x103b28c88, fclk=0x1048333f0, 
iclk=<unavailable>) at omap_mmc.c:638:15
     frame #4: 0x10033cf40 
qemu-system-arm`omap2420_mpu_init(sdram=<unavailable>, 
cpu_type=<unavailable>) at omap2.c:2487:14
     frame #5: 0x10031fe6c 
qemu-system-arm`n8x0_init(machine=0x103b1fc00, binfo=0x100dbf5a8, 
model=800) at nseries.c:1317:14
     frame #6: 0x100093d48 
qemu-system-arm`machine_run_board_init(machine=0x103b1fc00, 
mem_path=<unavailable>, errp=<unavailable>) at machine.c:1469:5
     frame #7: 0x100299fe8 qemu-system-arm`qmp_x_exit_preconfig 
[inlined] qemu_init_board at vl.c:2580:5
     frame #8: 0x100299fb4 
qemu-system-arm`qmp_x_exit_preconfig(errp=<unavailable>) at vl.c:2671:5
     frame #9: 0x10029d77c qemu-system-arm`qemu_init(argc=<unavailable>, 
argv=<unavailable>) at vl.c:3721:9
     frame #10: 0x1004df880 qemu-system-arm`main(argc=<unavailable>, 
argv=<unavailable>) at main.c:47:5
     frame #11: 0x1884b7f28 dyld`start + 2236

But then I'm getting:

     frame #3: 0x18871ce44 libsystem_c.dylib`__assert_rtn + 272
   * frame #4: 0x1006dbbe4 qemu-system-arm`device_cold_reset.cold.1 at 
qdev.c:256:5
     frame #5: 0x1004e1c44 
qemu-system-arm`device_cold_reset(dev=0x10347dde0) at qdev.c:256:5
     frame #6: 0x1001fa290 qemu-system-arm`omap2_mmc_init [inlined] 
omap_mmc_reset(host=0x10347d960) at omap_mmc.c:321:5
     frame #7: 0x1001fa1fc 
qemu-system-arm`omap2_mmc_init(ta=0x104025860, blk=<unavailable>, 
irq=0x000060000171d580, dma=0x103472f38, fclk=0x1040119f0, 
iclk=<unavailable>) at omap_mmc.c:646:5
     frame #8: 0x10033cf40 
qemu-system-arm`omap2420_mpu_init(sdram=<unavailable>, 
cpu_type=<unavailable>) at omap2.c:2487:14
     frame #9: 0x10031fe6c 
qemu-system-arm`n8x0_init(machine=0x1033dec60, binfo=0x100dbf5a8, 
model=800) at nseries.c:1317:14
     frame #10: 0x100093d48 
qemu-system-arm`machine_run_board_init(machine=0x1033dec60, 
mem_path=<unavailable>, errp=<unavailable>) at machine.c:1469:5
     frame #11: 0x100299fe8 qemu-system-arm`qmp_x_exit_preconfig 
[inlined] qemu_init_board at vl.c:2580:5
     frame #12: 0x100299fb4 
qemu-system-arm`qmp_x_exit_preconfig(errp=<unavailable>) at vl.c:2671:5
     frame #13: 0x10029d77c 
qemu-system-arm`qemu_init(argc=<unavailable>, argv=<unavailable>) at 
vl.c:3721:9
     frame #14: 0x1004df880 qemu-system-arm`main(argc=<unavailable>, 
argv=<unavailable>) at main.c:47:5

Because this isn't a full qdev_realize() call.

Then when using:

-- >8 --
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 4823befdef..db7d644fb7 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -763,7 +763,7 @@ SDState *sd_init(BlockBackend *blk, bool is_spi)
      object_ref(obj);
      object_unparent(obj);
      sd_realize(dev, &err);
-    if (err) {
+    if (err || !object_property_set_bool(OBJECT(dev), "realized", true, 
&err)) {
          error_reportf_err(err, "sd_init failed: ");
          return NULL;
      }
---

I get:

     frame #3: 0x18871ce44 libsystem_c.dylib`__assert_rtn + 272
   * frame #4: 0x1006dbcac 
qemu-system-arm`qdev_assert_realized_properly_cb.cold.2 at qdev.c:320:9
     frame #5: 0x1004e1e04 
qemu-system-arm`qdev_assert_realized_properly_cb(obj=0x10337e2e0, 
opaque=0x000000000) at qdev.c:320:9
     frame #6: 0x1004e7a8c 
qemu-system-arm`do_object_child_foreach(obj=0x0000600000c0df50, 
fn=(qemu-system-arm`qdev_assert_realized_properly_cb at qdev.c:313), 
opaque=0x000000000, recurse=true) at object.c:1120:19
     frame #7: 0x1004e7aa8 
qemu-system-arm`do_object_child_foreach(obj=0x1039de470, 
fn=(qemu-system-arm`qdev_assert_realized_properly_cb at qdev.c:313), 
opaque=0x000000000, recurse=true) at object.c:1125:23
     frame #8: 0x1004e7aa8 
qemu-system-arm`do_object_child_foreach(obj=<unavailable>, 
fn=(qemu-system-arm`qdev_assert_realized_properly_cb at qdev.c:313), 
opaque=0x000000000, recurse=true) at object.c:1125:23
     frame #9: 0x1004e7ae8 
qemu-system-arm`object_child_foreach_recursive(obj=<unavailable>, 
fn=<unavailable>, opaque=<unavailable>) at object.c:1145:12 [artificial]
     frame #10: 0x1004e1d70 
qemu-system-arm`qdev_assert_realized_properly at qdev.c:327:5 [artificial]
     frame #11: 0x100093fd4 qemu-system-arm`qdev_machine_creation_done 
at machine.c:1503:5
     frame #12: 0x10029a12c qemu-system-arm`qmp_x_exit_preconfig 
[inlined] qemu_machine_creation_done at vl.c:2644:5
     frame #13: 0x10029a0c8 
qemu-system-arm`qmp_x_exit_preconfig(errp=<unavailable>) at vl.c:2673:5
     frame #14: 0x10029d77c 
qemu-system-arm`qemu_init(argc=<unavailable>, argv=<unavailable>) at 
vl.c:3721:9
     frame #15: 0x1004df880 qemu-system-arm`main(argc=<unavailable>, 
argv=<unavailable>) at main.c:47:5

> In a truly ideal world we would QOMify the omap-mmc device: it
> is the only remaining user of the legacy sd_init function...

Yeah, and I remember I told you I already did it 3 years ago :)
IIRC it was hard to just convert one device, and I wasn't sure
it was worth it. Anyhow, I'll check my backups in a pair of weeks.

Thanks for the review,

Phil.


  reply	other threads:[~2023-09-18 15:23 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-18 10:17 [PATCH 0/2] qdev: Ensure devices are fully realized when calling DeviceReset handler Philippe Mathieu-Daudé
2023-09-18 10:17 ` [PATCH 1/2] hw/sd/omap_mmc: Do not reset SDCard until being fully realized Philippe Mathieu-Daudé
2023-09-18 11:00   ` Peter Maydell
2023-09-18 15:22     ` Philippe Mathieu-Daudé [this message]
2023-09-18 10:17 ` [PATCH 2/2] qdev: Ensure devices are fully realized when calling DeviceReset handler Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d1326804-2bca-3b06-250a-3ca3a8038d1c@linaro.org \
    --to=philmd@linaro.org \
    --cc=ale@rev.ng \
    --cc=alex.bennee@linaro.org \
    --cc=alistair@alistair23.me \
    --cc=anjo@rev.ng \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=clg@kaod.org \
    --cc=edgar.iglesias@gmail.com \
    --cc=eduardo@habkost.net \
    --cc=luc@lmichel.fr \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=shentey@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).