Uploaded image for project: 'Core ReactOS'
  1. Core ReactOS
  2. CORE-20379

x64: bootcd double-fault while uniata probes scsi via HalGetBusData

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • NTCore

    Description

      Settings:

      1. VBox 5.0.20 r106931

      2. IDE Controller (type PIIX4):

      • boot HDD disk on primary master;
      • secondary HDD disk on primary slave;
      • boot CD (with bootcd.iso) on secondary master;

      3. BusLogic SCSI controller:

      • HDD disk on SCSI port 0.

      4. ReactOS x64 MSVC build.

      Boot the bootcd using bootoptions: debug debugport=com1 baudrate=115200 sifoptionsoverride
      (This is in order to boot with the bootlogo showing up; it seems that having it shown increases the probability of the bug to show up.)


      When booting such a configuration, a double-fault is triggered while uniata is probing the hardware using HalGetBusData(ByOffset), see the attached debug log.

      Key part of the log:

       
      kd> kp
      Child-SP          RetAddr           Call Site
      fffff800`006b3190 fffff800`002c3cdf nt!KiDoubleFaultAbort+0xba
      fffff880`04d67fc0 fffff800`0028c707 hal!_RTC_CheckStackVars(void * _Esp = 0xfffff880`04d68020, struct _RTC_framedesc * _Fd = 0xfffff800`002c82f0)+0xf [D:\rossrc\reactos\sdk\lib\runtmchk\rtcapi.c @ 136]
      fffff880`04d68020 fffff800`0028bb84 hal!WRITE_REGISTER_ULONG(unsigned long * Register = 0xffffffff`fffe0310, unsigned long Value = 0)+0x47 [X:\rosbuilds\x64_MSVC19_ros_merge\sdk\include\ddk\wdm.h @ 15231]
      fffff880`04d68070 fffff800`0028bae9 hal!ApicWrite(_APIC_REGISTER Register = APIC_ICR1 (0n784), unsigned long Value = 0)+0x24 [D:\rossrc\reactos\hal\halx86\apic\apicp.h @ 328]
      fffff880`04d680a0 fffff800`0028bfbe hal!ApicRequestSelfInterrupt(unsigned char Vector = 0x2f '/', unsigned char TriggerMode = 0x00 '')+0x119 [D:\rossrc\reactos\hal\halx86\apic\apic.c @ 173]
      fffff880`04d68140 fffff800`004dbb46 hal!HalRequestSoftwareInterrupt(unsigned char Irql = 0x02 '')+0x1e [D:\rossrc\reactos\hal\halx86\apic\apic.c @ 657]
      fffff880`04d68170 fffff800`004db993 nt!KiCheckForTimerExpiration(struct _KPRCB * Prcb = 0xfffff800`006a4680, struct _KTRAP_FRAME * TrapFrame = 0xfffff880`04d68290, union _ULARGE_INTEGER InterruptTime = union _ULARGE_INTEGER 0x3f5476a)+0x76 [D:\rossrc\reactos\ntoskrnl\ke\time.c @ 60]
      fffff880`04d681b0 fffff800`0028cd24 nt!KeUpdateSystemTime(struct _KTRAP_FRAME * TrapFrame = 0xfffff880`04d68290, unsigned long Increment = 0x2625a, unsigned char Irql = 0x0b '')+0xc3 [D:\rossrc\reactos\ntoskrnl\ke\time.c @ 98]
      fffff880`04d68230 fffff800`0028d416 hal!HalpClockInterruptHandler(struct _KTRAP_FRAME * TrapFrame = 0xfffff880`04d68290)+0xd4 [D:\rossrc\reactos\hal\halx86\apic\rtctimer.c @ 196]
      fffff880`04d68290 fffff800`00419b7e hal!HalpClockInterrupt+0xa6
      fffff880`04d68420 fffff800`005ab582 nt!KeLowerIrql(unsigned char NewIrql = 0x0b '')+0xe [X:\rosbuilds\x64_MSVC19_ros_merge\sdk\include\ddk\wdm.h @ 10654]
      fffff880`04d68430 fffff800`002898e4 nt!KeReleaseSpinLock(unsigned int64 * SpinLock = 0xfffff800`002e0ed8, unsigned char OldIrql = 0x0b '')+0x22 [D:\rossrc\reactos\ntoskrnl\ke\amd64\spinlock.c @ 64]
      fffff880`04d68460 fffff800`0028afc8 hal!HalpPCIReleaseSynchronzationType1(struct _BUS_HANDLER * BusHandler = 0xfffff880`04d68680, unsigned char OldIrql = 0x0b '')+0x54 [D:\rossrc\reactos\hal\halx86\legacy\bus\pcibus.c @ 149]
      fffff880`04d684b0 fffff800`0028a211 hal!HalpPCIConfig(struct _BUS_HANDLER * BusHandler = 0xfffff880`04d68680, struct _PCI_SLOT_NUMBER Slot = struct _PCI_SLOT_NUMBER, unsigned char * Buffer = 0xfffff880`04d68610 "???", unsigned long Offset = 0x40, unsigned long Length = 0, <function> ** ConfigIO = 0xfffff800`002e0f10)+0x138 [D:\rossrc\reactos\hal\halx86\legacy\bus\pcibus.c @ 253]
      fffff880`04d68530 fffff800`0028a380 hal!HalpReadPCIConfig(struct _BUS_HANDLER * BusHandler = 0xfffff880`04d68680, struct _PCI_SLOT_NUMBER Slot = struct _PCI_SLOT_NUMBER, void * Buffer = 0xfffff880`04d685d0, unsigned long Offset = 0, unsigned long Length = 0x40)+0x71 [D:\rossrc\reactos\hal\halx86\legacy\bus\pcibus.c @ 279]
      fffff880`04d68570 fffff800`00288f53 hal!HalpGetPCIData(struct _BUS_HANDLER * BusHandler = 0xfffff880`04d68680, struct _BUS_HANDLER * RootHandler = 0xfffff880`04d68680, unsigned long SlotNumber = 0x21, void * Buffer = 0xfffff880`04d687e0, unsigned long Offset = 0, unsigned long Length = 0x4a)+0xf0 [D:\rossrc\reactos\hal\halx86\legacy\bus\pcibus.c @ 547]
      fffff880`04d68640 fffff800`00288e3e hal!HalGetBusDataByOffset(_BUS_DATA_TYPE BusDataType = PCIConfiguration (0n4), unsigned long BusNumber = 0, unsigned long SlotNumber = 0x21, void * Buffer = 0xfffff880`04d687e0, unsigned long Offset = 0, unsigned long Length = 0x4a)+0x103 [D:\rossrc\reactos\hal\halx86\acpi\busemul.c @ 218]
      fffff880`04d68760 fffff880`054f963b hal!HalGetBusData(_BUS_DATA_TYPE BusDataType = PCIConfiguration (0n4), unsigned long BusNumber = 0, unsigned long SlotNumber = 0x21, void * Buffer = 0xfffff880`04d687e0, unsigned long Length = 0x4a)+0x3e [D:\rossrc\reactos\hal\halx86\acpi\busemul.c @ 182]
      fffff880`04d687a0 fffff880`054e9ec6 uniata!ScsiPortGetBusDataByOffset(void * HwDeviceExtension = 0xfffffa80`297c7480, _BUS_DATA_TYPE BusDataType = PCIConfiguration (0n4), unsigned long BusNumber = 0, unsigned long SlotNumber = 0x21, void * Buffer = 0xfffff880`04d68ea4, unsigned long Offset = 0x48, unsigned long Length = 2)+0x8b [D:\rossrc\reactos\drivers\storage\ide\uniata\id_probe.cpp @ 757]
      

      Since the call stack is quite large I have checked whether this weren't going over the kernel stack.

      Kernel Stack Usage:
      fffff880`04d6de00 - fffff880`04d67fc0 == 0x5e40 bytes == 24128 bytes == 23 kB
      ntoskrnl/ke/amd64/kiinit.c	  32 UCHAR DECLSPEC_ALIGN(16) KiP0BootStackData[KERNEL_STACK_SIZE] = {0};
      sdk/include/xdk/amd64/ke.h	 184 #define KERNEL_STACK_SIZE 0x6000
      

      so we are OK but almost at the very bottom of it...


      The WRITE_REGISTER_ULONG helper (and few others), see https://git.reactos.org/?p=reactos.git;a=blob;f=sdk/include/xdk/iofuncs.h;hb=46fb20d4063b0e9ad7ade8f5dc8cebf3cb469524#l432 , appears to use a uninitialized Synch variable:

       436   LONG Synch;
       437   *Register = Value;
       438   InterlockedOr(&Synch, 1);
      

      to perform what could like some sort of memory fence. This code shown above comes originally from MinGW, still existing as of today:
      https://github.com/mingw-w64/mingw-w64/blob/3ecc9a715823dc5e1484634cb9cc9d0532676ce5/mingw-w64-headers/ddk/include/ddk/wdm.h#L11755

      Attachments

        Activity

          People

            Unassigned Unassigned
            hbelusca hbelusca
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: