# DF-4331 — mrsas firmware-zero divisors → kernel #DE panic (map load + IO paths)

File: `sys/dev/raid/mrsas/mrsas_fp.c`
* `mr_update_span_set:969` — `mega_div64_32(..., quad->diff)` with fw `diff == 0`
  (fires at map validation time)
* `get_arm:599` — `mega_mod64(stripe, SPAN_ROW_SIZE(...))` with fw
  `spanRowSize == 0` (fires on first FP IO, RAID 0/5/6)
* `mr_spanset_get_phy_params:653-654` — same `SPAN_ROW_SIZE` divisor for RAID 6

Same probe as DF-4330 (`fp_probe.ko` embedding the unmodified kernel
`mrsas_fp.c`).

## Run (guest, root) — panic run

```
kldload /root/fp4330/fp_probe.ko
sysctl hw.fp_probe_run=2      # quad[0].diff = 0
```

## Expected result (see panic.txt / serial_decisive.log)

```
fp_probe: calling real MR_ValidateMapInfo() (spanDepth=1 quad[0].diff=0) ...
Fatal trap 18: integer divide fault while in kernel mode
instruction pointer = 0x8:0xffffffff82600cb7
kernel: type 18 trap, code=0
Stopped at probe_mr_update_span_set.part.0+0x1d7: divq %rcx,%eax
```

Trap 18 = x86 #DE. The identical code compiled into the kernel is what a real
adapter delivering `quad.diff = 0` executes at attach (`mrsas.c:1762`) or at
any AEN map sync (`mrsas.c:2961`) — no user IO needed, the box panics while
bringing the controller up. Contrast: the IO-time paths *do* check
`quad->diff == 0` (`mrsas_fp.c:390-393`, `1431-1434`) and
`MR_GetPhyParams` checks `rowSize`/`modFactor` (`:1359-1370`), but the
spanset twins (`969`, `599`, `653-654`) have no zero guards.

## Fix validation

`fix.diff` (shared with DF-4330) rejects any map with a live
`quad->diff == 0` (or `spanRowSize == 0` on RAID 0/5/6) inside
`MR_ValidateMapInfo`, before `mr_update_span_set` runs:

```
kldload /root/fp4330_fixed/fp_probe.ko
sysctl hw.fp_probe_run=2      # -> "invalid RAID map geometry", returned 1,
                              #    NO panic, guest stays up (fix_run.log in DF-4330/)
```
