From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 23638 invoked from network); 21 Feb 2021 02:17:42 -0000 Received: from 1ess.inri.net (216.126.196.35) by inbox.vuxu.org with ESMTPUTF8; 21 Feb 2021 02:17:42 -0000 Received: from mail-pf1-f179.google.com ([209.85.210.179]) by 1ess; Sat Feb 20 21:12:25 -0500 2021 Received: by mail-pf1-f179.google.com with SMTP id 189so4421493pfy.6 for <9front@9front.org>; Sat, 20 Feb 2021 18:12:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mforney-org.20150623.gappssmtp.com; s=20150623; h=message-id:to:subject:from:date:mime-version; bh=TFmxvP1ysJb8Hsvp9cF5xPnr29dPQg2irOZ4RrtKiss=; b=RKQiF9KkXpbMod/lJ6mwIAukCaVZ1FmhlCczseHv6AjzalUnL3mWJqasUfdcEKnot1 Fzw8MbbZnhBaofyO8HtVQMbrFV2p/W+YDFdSFvoPztj3iFNCkgdrPiRoMB8hJBngmiwv i0qOTClR3Z7hDXRDap62y1GN5tHNzmrSQE+SLpmJaPVW1hjvAjcaLBWh1fi3IeA/bI89 ow7SSZfcDPoMgScvPOWxyl1VuWmH7W9381aLDrCbpAE2BE8XjDfnAN23Zvn/e0PSOY32 NUsIaQMMoZMEVKN1/dlc0qJCwjmVwVS+3qMHFhXfNqJfoLtErq4uLVQoTNPD0MmbcRlj gHXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:to:subject:from:date:mime-version; bh=TFmxvP1ysJb8Hsvp9cF5xPnr29dPQg2irOZ4RrtKiss=; b=SmQrMtIrch+mzWU/DXwB2ywuSkmkeneKOUR29f7a+o1Dv0X/vLwG7cvYY0ddz5YMPu Cnz1eMqFWmtOoB+eWoYa+iQTS3xARXEywk3IEXh0vpbjTcPYzzQr/3QiQD/se34zVqIz XAC7vw/fcj1HY0FyfWagpKe9HwTAHb6aI82aTLgYK2VaBU2HIc9LF3VMLN+XIyHg2eSR ccMNiia1oSBvRejeQUzE5ZQci77fio/WRF+XFHSYeYlq5q4ZGaep/HtskH4NDqurvBq1 Kg4JfNoMO2YZiH2u9TyrUDYf7uxRt71N0PKMRecqlCu5bCfuXRMiQMdFYDdFGijGxxVR Vr9Q== X-Gm-Message-State: AOAM532j9Njeli7Skw0Dj6TVGoADwN9+27x32dX4t98ggdsk2tGXBpHa QV5Rdrxt+Nn0mIKUvTXkSQcxsgsXLmow7igE5PI= X-Google-Smtp-Source: ABdhPJxHAuyz+mPseggiZfLKfl+eHFCKhr7G4VhtJL1IGRmvpyqEmJFEAThvO3dWlGwBooAsNKgmDQ== X-Received: by 2002:a63:1561:: with SMTP id 33mr14911847pgv.13.1613873534074; Sat, 20 Feb 2021 18:12:14 -0800 (PST) Return-Path: Received: from arrow.hsd1.ca.comcast.net (c-73-70-188-119.hsd1.ca.comcast.net. [73.70.188.119]) by smtp.gmail.com with ESMTPSA id f19sm14997886pgl.49.2021.02.20.18.12.13 for <9front@9front.org> (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Sat, 20 Feb 2021 18:12:13 -0800 (PST) Message-ID: <21DA83C13FBD21DF029B2E2CF47E4F95@arrow.hsd1.ca.comcast.net> To: 9front@9front.org From: Michael Forney Date: Sat, 20 Feb 2021 18:12:13 -0800 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-anzmbkbynotutflisibtltavuh" List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: patented configuration enhancement Subject: [9front] libaml IndexField Reply-To: 9front@9front.org Precedence: bulk This is a multi-part message in MIME format. --upas-anzmbkbynotutflisibtltavuh Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit In /dev/kmesg on my T14, I saw a message amlmapio: [0xffffff18-0x100000018] overlaps usable memory amlmapio: mapping \_SB.FRTP failed Here is the relevant snippet from my DSDT: Scope (_SB) { ... OperationRegion (ECMC, SystemIO, 0x72, 0x02) Field (ECMC, AnyAcc, NoLock, Preserve) { ECMI, 8, ECMD, 8 } IndexField (ECMI, ECMD, ByteAcc, NoLock, Preserve) { Offset (0x08), FRTB, 32 } OperationRegion (FRTP, SystemMemory, FRTB, 0x0100) Field (FRTP, AnyAcc, NoLock, Preserve) { ... } } With some debugging output: amlmapio(\_SB.ECMC): Io 72 - 74 rwreg(\_SB.ECMC): Io [72+0]/1 <- 8 rwreg(\_SB.ECMC): Io [72+1]/1 -> 18 amlmapio(\_SB.FRTP): Mem ffffff18 - 100000018 amlmapio: [0xffffff18-0x100000018) overlaps usable memory amlmapio: mapping \_SB.FRTP failed It seems that libaml does not handle IndexField correctly and just did a single read from ECMD after setting ECMI to 8, causing the FRTP region to be evaluated as 0xffffff18-0x100000018. Instead, it should be reading 4 bytes [18 c0 22 cc], evaluating it as 0xcc22c018-0xcc22118: amlmapio(\_SB.ECMC): Io 72 - 74 rwreg(\_SB.ECMC): Io [72+0]/1 <- 8 rwreg(\_SB.ECMC): Io [72+1]/1 -> 18 rwreg(\_SB.ECMC): Io [72+0]/1 <- 9 rwreg(\_SB.ECMC): Io [72+1]/1 -> c0 rwreg(\_SB.ECMC): Io [72+0]/1 <- a rwreg(\_SB.ECMC): Io [72+1]/1 -> 22 rwreg(\_SB.ECMC): Io [72+0]/1 <- b rwreg(\_SB.ECMC): Io [72+1]/1 -> cc amlmapio(\_SB.FRTP): Mem cc22c018 - cc22c118 I wrote a patch (attached) to fix this, and it seems to work. Though, it's not clear to me when things should be dereferenced. Previously, the data field was dereferenced at evalfield, but the region and index field were not until rwfield. After the patch, the index field is also dereferenced in evalfield. For BankField, the index *is* dereferenced in evalfield. I'm pretty sure that this means that BankField does not work currently, since store() just returns nil for 'f' objects. The bank selector will never get set. Anyway, I don't know if this solves any real problems; it's just something I noticed and thought I'd try to fix. --upas-anzmbkbynotutflisibtltavuh Content-Disposition: attachment; filename=0001-libaml-fix-IndexField-access-when-multiple-reads-writes-are-needed.patch Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit From 1e2c2c5c5f27c027f76cbce3a151d30e48f22006 From: Michael Forney Date: Sun, 21 Feb 2021 00:24:41 +0000 Subject: libaml: fix IndexField access when multiple reads/writes are needed Previously, accessing an IndexField would set the index field to a fixed value, and then read from the region associated with the data field (incorporating its offset). However if the read/write length is larger than the data field, it would just read past the end. Instead, the index needs to be updated for each access. To fix this, introduce a function rwfieldunit, which does one access of the region/index-data/bank, and use this in rwfield instead of rwreg directly. diff e7f36397ace2aaaf16a643080dcc439c5b061613 1e2c2c5c5f27c027f76cbce3a151d30e48f22006 --- a/sys/src/libaml/aml.c Thu Feb 18 00:58:35 2021 +++ b/sys/src/libaml/aml.c Sat Feb 20 16:24:41 2021 @@ -72,6 +72,7 @@ struct Field { void *reg; /* Buffer or Region */ Field *index; + Field *data; void *indexv; int flags; int bitoff; @@ -219,6 +220,7 @@ gcmark(f->reg); gcmark(f->index); gcmark(f->indexv); + gcmark(f->data); break; } } @@ -608,17 +610,41 @@ } } +static void *rwfield(Field *f, void *v, int write); + +static uvlong +rwfieldunit(Field *f, int off, int len, uvlong v, int write) +{ + void *b, *reg; + + if(f->reg){ + if((reg = deref(f->reg)) == nil) + return 0; + v = rwreg(reg, off, len, v, write); + }else if(f->index && f->data){ + rwfield(f->index, mki(off), 1); + if(write){ + b = mk('b', len); + putle(b, len, v); + rwfield(f->data, b, 1); + }else{ + b = rwfield(f->data, nil, 0); + v = getle(b, len); + } + } + return v; +} + static void* rwfield(Field *f, void *v, int write) { int boff, blen, wo, ws, wl, wa, wd, i; uvlong w, m; - void *reg; uchar *b; - if(f == nil || (reg = deref(f->reg)) == nil) + if(f == nil) return nil; - if(f->index) + if(f->indexv) store(f->indexv, f->index); blen = f->bitlen; if(write){ @@ -649,11 +675,11 @@ w <<= ws; if(wl != wd){ m = ((1ULL<> ws; + w = rwfieldunit(f, wo*wa, wa, 0, 0) >> ws; for(i = 0; i < wl; i++, boff++){ b[boff/8] |= (w&1)<<(boff%8); w >>= 1; @@ -937,9 +963,12 @@ /* no break */ case 'f': l = p; - if(l->index) + if(l->data) return fmtprint(f, "IndexField(%x, %x, %x) @ %V[%V]", - l->flags, l->bitoff, l->bitlen, l->index, l->indexv); + l->flags, l->bitoff, l->bitlen, l->data, l->index); + else if(l->indexv) + return fmtprint(f, "BankField(%x, %x, %x, %V=%V) @ %V", + l->flags, l->bitoff, l->bitlen, l->index, l->indexv, l->reg); return fmtprint(f, "Field(%x, %x, %x) @ %V", l->flags, l->bitoff, l->bitlen, l->reg); default: @@ -1374,11 +1403,12 @@ static void* evalfield(void) { - int flags, bitoff, wa, n; - Field *f, *df; + int flags, bitoff, n; + Field *f, *xf, *df; Name *d; uchar *p; + xf = nil; df = nil; flags = 0; bitoff = 0; @@ -1387,6 +1417,9 @@ flags = ival(FP->arg[1]); break; case Oxfld: + xf = deref(FP->arg[0]); + if(xf == nil || TAG(xf) != 'f') + goto Out; df = deref(FP->arg[1]); if(df == nil || TAG(df) != 'f') goto Out; @@ -1425,21 +1458,17 @@ f = mk('f', sizeof(Field)); f->flags = flags; f->bitlen = n; + f->bitoff = bitoff; switch(FP->op - optab){ case Ofld: f->reg = FP->arg[0]; - f->bitoff = bitoff; break; case Oxfld: - wa = fieldalign(df->flags); - f->reg = df->reg; - f->bitoff = df->bitoff + (bitoff % (wa*8)); - f->indexv = mki((bitoff/(wa*8))*wa); - f->index = FP->arg[0]; + f->data = df; + f->index = xf; break; case Obfld: f->reg = FP->arg[0]; - f->bitoff = bitoff; f->indexv = FP->arg[2]; f->index = df; break; --upas-anzmbkbynotutflisibtltavuh--