Hi, My vaio repeatedly crashed by "Data modified on freelist"(*1) or other memory corruptions. After my long time debug, I found the route cause is a handling of references of LocalX, like the following:
If ((SMRW (0x0B, 0x16, 0x21, RefOf (Local0)) == Zero)) In the called control method, "RefOf (Local1)" is referred as Arg3, is stored a value like the following: Arg3 = \_SB.PCI0.LPCB.EC0.SMD0 In aml_store(), lvalue is reset if lvalue is a LocalX. But since that was done before resolving the reference, lvalue was not reset if lvalue is a reference of LocalX. diff #1 fixes that problem. It resets lvalue after resolving references. ok? diff #2 adds aml_die() if any memory corruption occurs when creating field in a buffer. This actually happens on my vaio (pro pk 14) if diff #1 is not applied. ok? diff #1 Index: sys/dev/acpi/dsdt.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/dev/acpi/dsdt.c,v retrieving revision 1.257 diff -u -p -r1.257 dsdt.c --- sys/dev/acpi/dsdt.c 17 Dec 2020 17:57:19 -0000 1.257 +++ sys/dev/acpi/dsdt.c 26 Feb 2021 04:12:03 -0000 @@ -2961,11 +2961,11 @@ aml_store(struct aml_scope *scope, struc aml_rwfield(rhs, 0, rhs->v_field.bitlen, &tmp, ACPI_IOREAD); rhs = &tmp; } + + lhs = aml_gettgt(lhs, AMLOP_STORE); /* Store to LocalX: free value */ if (lhs->stack >= AMLOP_LOCAL0 && lhs->stack <= AMLOP_LOCAL7) aml_freevalue(lhs); - - lhs = aml_gettgt(lhs, AMLOP_STORE); switch (lhs->type) { case AML_OBJTYPE_UNINITIALIZED: aml_copyvalue(lhs, rhs); diff #2 Index: sys/dev/acpi/dsdt.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/dev/acpi/dsdt.c,v retrieving revision 1.257 diff -u -p -r1.257 dsdt.c --- sys/dev/acpi/dsdt.c 17 Dec 2020 17:57:19 -0000 1.257 +++ sys/dev/acpi/dsdt.c 26 Feb 2021 04:33:21 -0000 @@ -2742,11 +2742,17 @@ aml_rwfield(struct aml_value *fld, int b } else if (mode == ACPI_IOREAD) { /* bufferfield:read */ _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0); + if (ref1->length < aml_bytepos(fld->v_field.bitpos) + + aml_bytelen(fld->v_field.bitlen)) + aml_die("bufferfield:read out of range"); aml_bufcpy(&val->v_integer, 0, ref1->v_buffer, fld->v_field.bitpos, fld->v_field.bitlen); } else { /* bufferfield:write */ val = aml_convert(val, AML_OBJTYPE_INTEGER, -1); + if (ref1->length < aml_bytepos(fld->v_field.bitpos) + + aml_bytelen(fld->v_field.bitlen)) + aml_die("bufferfield:write out of range"); aml_bufcpy(ref1->v_buffer, fld->v_field.bitpos, &val->v_integer, 0, fld->v_field.bitlen); aml_delref(&val, "wrbuffld"); *1 example console log Data modified on freelist: word -35183627074926 of object 0xffff8000024a3060 size 0x10 previous type temp (invalid addr 0xffff8027023e55f0) uvm_fault(0xffffffff81f63958, 0xffff8027023e55f8, 0, 1) -> e kernel: page fault trap, code=0 Stopped at malloc+0x482: movq 0x8(%r14),%rcx Running script... ddb{0}> malloc(10,91,5) at malloc+0x482 i915_gem_do_execbuffer(ffff8000002ab078,ffff800000ee0c00,ffff8000337a7970,ffff8000020ca000,0) at i915_gem_do_execbuffer+0xa52 i915_gem_execbuffer2_ioctl(ffff8000002ab078,ffff8000337a7970,ffff800000ee0c00) at i915_gem_execbuffer2_ioctl+0x144 drmioctl(15700,80406469,ffff8000337a7970,3,ffff8000336a8798) at drmioctl+0xd8 VOP_IOCTL(fffffd8227abbeb0,80406469,ffff8000337a7970,3,fffffd826bd1dd88,ffff8000336a8798) at VOP_IOCTL+0x55 vn_ioctl(fffffd82282ee8e8,80406469,ffff8000337a7970,ffff8000336a8798) at vn_ioctl+0x64 sys_ioctl(ffff8000336a8798,ffff8000337a7a80,ffff8000337a7ae0) at sys_ioctl+0x3c2 syscall(ffff8000337a7b50) at syscall+0x389 Xsyscall(6,36,0,36,80406469,7f7fffff5c00) at Xsyscall+0x128 end of kernel end trace frame: 0x7f7fffff5bd0, count: -9