Andriy Gapon [Wed, 15 Dec 2021 11:00:45 +0000 (13:00 +0200)]
rk_i2c_fill_tx: fix a number of issues
- maximum number of bytes that can be sent is 32, not 8;
- previous interface required callers to bump sc->msg->len in addition
to setting sc->tx_slave_addr;
- because of the above there was an issue with writing one too many bytes
because sc->cnt is not advanced when the slave address is written;
- the inetraction between outer and inner loops was confusing as the former
was bounded on the number of bytes to write and the counter was
incremented by one, but the inner loop advanced four bytes at a time;
- the return value was incorrect in the tx_slave_addr case; one call place
had to use its own (and incorrect in some cases) notion of the write
lenth.
All of the above issues should be fixed.
Some sanity asserts are added.
All callers use the return value to program RK_I2C_MTXCNT.
iic_msg::len no longer needs to be hacked.
A constant is added to reflect the maximum number of octets that can be
sent or received in one go (they are the same).
Andriy Gapon [Wed, 15 Dec 2021 09:11:15 +0000 (11:11 +0200)]
rk_i2c_transfer: minor improvement to bit twiddling
No need to mask a uint8_t with 0xff, the mask covers the whole type.
Explcitly cast to uint32_t before bit shifting instead of relying on
the implicit promotion to signed int.
Andriy Gapon [Wed, 15 Dec 2021 08:51:24 +0000 (10:51 +0200)]
rk_i2c: keep sending bytes until all bytes are sent
Previously the code would decalre the transfer complete after sending
first 31 bytes (plus the slave address) of a larger I2C write transfer.
That was tested using a large write to an EEPROM with 32-byte write page
size and a 2-byte address type. Such a transaction needed to send 34
bytes, 2 bytes for an offset and 32 bytes of actual data.
Cy Schubert [Sun, 12 Dec 2021 23:57:36 +0000 (15:57 -0800)]
ipfilter: Fix struct ifnet pointer type
The fr_info struct contains a summary of a packet. One of its fields
is a pointer to the ifnet struct the packet arrived on. It is pointed
to by a void* because ipfilter supports multiple O/Ses. Unfortunately
this makes it difficult it examine with DTrace. Defining fin_ifp as a
pointer to an ifnet struct makes the struct it points to using a DTrace
script possible.
Emmanuel Vadot [Wed, 1 Dec 2021 15:13:09 +0000 (16:13 +0100)]
fb: Add new FBTYPE_EFIFB
Currently the type isn't set in the fbtype struct so any userland
program that call the FBIOGTYPE ioctl will think it's a FBTYPE_SUN1BW
which is far from the truth.
No app that I found find checks the type but at least now it's correct.
Emmanuel Vadot [Wed, 1 Dec 2021 10:57:42 +0000 (11:57 +0100)]
fb: Remove some unused ioctls
6d1699583d7e added the FBIOGXINFO,FBIOMONINFO and FBIOPUTCMAPI/FBIOGETCMAPI
ioctls and said that implementation in driver will come later.
Since it was in 2001 I think we can remove this.
Emmanuel Vadot [Wed, 1 Dec 2021 10:53:03 +0000 (11:53 +0100)]
fb: Remove unused FBIOVERTICAL ioctl
Commit 6d1699583d7e added the FBIOVERTICAL ioctl and said that implementation
in driver will come later.
Since it was in 2001 I think we can remove this.
Alexander Motin [Tue, 14 Dec 2021 18:20:14 +0000 (13:20 -0500)]
isp(4): Allow more than 2 ports to read WWNs from NVRAM.
It appears at least on QLE2694L cards 3rd and 4th ports follow the
same NVRAM addressing logic as the first two. In lack of proper
documentation this guess is as good as it can be.
Ed Maste [Thu, 25 Nov 2021 18:50:03 +0000 (13:50 -0500)]
arch.7: update applicable FreeBSD versions to 12.0 and later
Information in this document is unchanged between 11.x and 12.x, but
this is intended to be a quick reference for supported architectures.
Also bump .Dd to cover recent changes including MIPS deprecation.
Andrew Turner [Mon, 22 Nov 2021 15:20:51 +0000 (15:20 +0000)]
Per-thread stack canary on arm64
With the update to llvm 13 we are able to tell the compiler it can find
the SSP canary relative to the register that holds the userspace stack
pointer. As this is unused in most of the kernel it can be used here
to point to a per-thread SSP canary.
As the kernel could be built with an old toolchain, e.g. when upgrading
from 13, add a warning that the options was enabled but the compiler
doesn't support it to both the build and kernel boot.
Discussed with: emaste
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D33079
John Baldwin [Wed, 8 Dec 2021 22:25:02 +0000 (14:25 -0800)]
libmd: Only define SHA256_Transform_c when using the ARM64 ifunc.
GCC 9 doesn't define a SHA256_Transform symbol when the stub just wraps
SHA256_Transform_c resulting in an undefined symbol for
_libmd_SHA256_Transform in libmd.so.
Andrew Turner [Fri, 23 Jul 2021 09:14:03 +0000 (10:14 +0100)]
Use arm64 sha256 intrinsics in libmd
Summary:
When running on a CPU that supports the arm64 sha256 intrinsics use them
to improve perfromance of sha256 calculations.
With this changethe following improvement has been seen on an Apple M1
with FreeBS running under Parallels, with similar results on a
Neoverse-N1 r3p1.
x sha256.orig
+ sha256.arm64
+--------------------------------------------------------------------+
|++ x x|
|+++ xxx|
||A |A||
+--------------------------------------------------------------------+
N Min Max Median Avg Stddev
x 5 3.41 3.5 3.46 3.458 0.042661458
+ 5 0.47 0.54 0.5 0.504 0.027018512
Difference at 95.0% confidence
-2.954 +/- 0.0520768
-85.4251% +/- 0.826831%
(Student's t, pooled s = 0.0357071)
Reviewed by: cem
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D31284
Rick Macklem [Sat, 6 Nov 2021 20:26:43 +0000 (13:26 -0700)]
vfs: Add "ioflag" and "cred" arguments to VOP_ALLOCATE
When the NFSv4.2 server does a VOP_ALLOCATE(), it needs
the operation to be done for the RPC's credential and not
td_ucred. It also needs the writing to be done synchronously.
This patch adds "ioflag" and "cred" arguments to VOP_ALLOCATE()
and modifies vop_stdallocate() to use these arguments.
The VOP_ALLOCATE.9 man page will be patched separately.
The ifp (struct ifnet) backpointer in the e1000 private ifnet
data is not used anymore since the iflib transition.
Remove it so that developers are not tempted to use it and
get a NULL pointer dereference.
Dimitry Andric [Wed, 15 Dec 2021 19:56:12 +0000 (20:56 +0100)]
Apply fix for clang incorrectly optimizing part of dns/bind916
Merge commit e5a8af7a90c6 from llvm git (by Gulfem Savrun Yeniceri):
[Passes] Fix relative lookup table converter pass
This patch fixes the relative table converter pass for the lookup table
accesses that are resulted in an instruction sequence, where gep is not
immediately followed by a load, such as gep being hoisted outside the loop
or another instruction is inserted in between them. The fix inserts the
call to load.relative.instrinsic in the original place of load instead of gep.
Issue is reported by FreeBSD via https://bugs.freebsd.org/259921.
Rick Macklem [Sat, 4 Dec 2021 22:38:55 +0000 (14:38 -0800)]
nfsd: Fix Verify for attributes like FilesAvail
When the Verify operation calls nfsv4_loadattr(), it provides
the "struct statfs" information that can be used for doing a
compare for FilesAvail, FilesFree, FilesTotal, SpaceAvail,
SpaceFree and SpaceTotal. However, the code erroneously
used the "struct nfsstatfs *" argument that is NULL.
This patch fixes these cases to use the correct argument
structure. For the case of FilesAvail, the code in
nfsv4_fillattr() was factored out into a separate function
called nfsv4_filesavail(), so that it can be called from
nfsv4_loadattr() as well as nfsv4_fillattr().
In fact, most of the code in nfsv4_filesavail() is old
OpenBSD code that does not build/run on FreeBSD, but I
left it in place, in case it is of some use someday.
I am not aware of any extant NFSv4 client that does Verify
on these attributes.
Alexander Motin [Sat, 11 Dec 2021 04:18:52 +0000 (23:18 -0500)]
Make msgbuf_peekbytes() not return leading zeroes.
Introduce new MSGBUF_WRAP flag, indicating that buffer has wrapped
at least once and does not keep zeroes from the last msgbuf_clear().
It allows msgbuf_peekbytes() to return only real data, not requiring
every consumer to trim the leading zeroes after doing pointless copy.
The most visible effect is that kern.msgbuf sysctl now always returns
proper zero-terminated string, not only after the first buffer wrap.
ocs_fc: Fix CAM status reporting in ocs_fc(4) when no data is returned.
In ocs_scsi_initiator_io_cb(), if the SCSI command that is
getting completed had a residual equal to the transfer length,
it was setting the CCB status to CAM_REQ_CMP.
That breaks the expected behavior for commands like READ ATTRIBUTE.
For READ ATTRIBUTE, if the first attribute requested doesn't exist,
the command is supposed to return an error (Illegal Request,
Invalid Field in CDB). The broken behavior for READ ATTRIBUTE
caused LTFS tape formatting to fail. It looks for attribute
0x1623, and expects to see an error if the attribute isn't present.
In addition, if the residual is negative (indicating an overrun),
only set the CCB status to CAM_DATA_RUN_ERR if we have not already
reported an error. The SCSI sense data will have more detail about
what went wrong.
sys/dev/ocs_fc/ocs_cam.c:
In ocs_scsi_initiator_io_cb(), don't set the status to
CAM_REQ_CMP if the residual is equal to the transfer length.
Also, only set CAM_DATA_RUN_ERR if we didn't get SCSI
status.
Andriy Gapon [Fri, 26 Nov 2021 09:48:21 +0000 (11:48 +0200)]
twsi: support more message combinations in transfers
Most prominently, add support for a transfer where a write with no-stop
flag is followed by a write with no-start flag. Logically, it's a
single larger write, but consumers may want to split it like that
because one part can be a register ID and the other part can be data to
be written to (or starting at) that register.
Such a transfer can be created by i2c tool and iic(4) driver, e.g., for
an EEPROM write at specific offset:
i2c -m tr -a 0x50 -d w -w 16 -o 0 -c 8 -v < /dev/random
This should be fixed by new code that handles the end of data transfer
for both reads and writes. It handles two existing conditions and one
new. Namely:
- the last message has been completed -- end of transfer;
- a message has been completed and the next one requires the start
condition;
- a message has been completed and the next one should be sent without
the start condition.
In the last case we simply switch to the next message and start sending
its data. Reads without the start condition are not supported yet,
though. That's because we NACK the last byte of the previous message,
so the device stops sending data. To fix this we will need to add a
look-ahead at the next message when handling the penultimate byte of the
current one.
This change also fixed a bug where msg_idx was not incremented after a
read message. Apparently, typically a read message is a last message in
a transfer, so the bug did not cause much trouble.
Andriy Gapon [Fri, 26 Nov 2021 08:34:42 +0000 (10:34 +0200)]
twsi: make data receiving code safer
Assert that we are not receiving data beyond the requested length.
Assert that we have not NACK-ed incoming data prematurely.
Abort the current transfer if the incoming data is NACK-ed or not
NACK-ed unexpectedly.
Add debug logging of received data to complement logging of sent data.
Andriy Gapon [Fri, 26 Nov 2021 08:07:27 +0000 (10:07 +0200)]
twsi: move handling of TWSI_CONTROL_ACK into the state machine
Previously the code set TWSI_CONTROL_ACK in twsi_transfer() based on
whether the first message had a length of one. That was done regardless
of whether the message was a read or write and what kind of messages
followed it.
Now the bit is set or cleared while handling TWSI_STATUS_ADDR_R_ACK
state transition based on the current (read) message.
The old code did not correctly work in a scenario where a single byte
was read from an EEPROM device with two byte addressing.
For example:
i2c -m tr -a 0x50 -d r -w 16 -o 0 -c 1 -v
The reason is that the first message (a write) has two bytes, so
TWSI_CONTROL_ACK was set and never cleared.
Since the controller did not send NACK the EEPROM sent more data resulting
in a buffer overrun.
While working on TWSI_STATUS_ADDR_R_ACK I also added support for
the zero-length read access and then I did the same for zero-length write
access.
While rare, those types of I2C transactions are completely valid and are
used by some devices.
Andriy Gapon [Tue, 30 Nov 2021 13:23:23 +0000 (15:23 +0200)]
kern_tc: unify timecounter to bintime delta conversion
There are two places where we convert from a timecounter delta to
a bintime delta: tc_windup and bintime_off.
Both functions use the same calculations when the timecounter delta is
small. But for a large delta (greater than approximately an equivalent
of 1 second) the calculations were different. Both functions use
approximate calculations based on th_scale that avoid division. Both
produce values slightly greater than a true value, calculated with
division by tc_frequency, would be. tc_windup is slightly more
accurate, so its result is closer to the true value and, thus, smaller
than bintime_off result.
As a consequence there can be a jump back in time when time hands are
switched after a long period of time (a large delta). Just before the
switch the time would be calculated with a large delta from
th_offset_count in bintime_off. tc_windup does the switch using its own
calculations of a new th_offset using the large delta. As explained
earlier, the new th_offset may end up being less than the previously
produced binuptime. So, for a period of time new binuptime values may
be "back in time" comparing to values just before the switch.
Such a jump must never happen. All the code assumes that the uptime is
monotonically nondecreasing and some code works incorrectly when that
assumption is broken. For example, we have observed sleepq_timeout()
ignoring a timeout when the sbinuptime value obtained by the callout
code was greater than the expiration value, but the sbinuptime obtained
in sleepq_timeout() was less than it. In that case the target thread
would never get woken up.
The unified calculations should ensure the monotonic property of the
uptime.
The problem is quite rare as normally tc_windup should be called HZ
times per second (typically 1000 or 100). But it may happen in VMs on
very busy hypervisors where a VM's virtual CPU may not get an execution
time slot for a second or more.
Alexander Motin [Thu, 2 Dec 2021 23:01:02 +0000 (18:01 -0500)]
APEI: Improve multiple error sources handling.
Some AMD systems I have report 8 NMI and 3591 polled error sources.
Previous code could handle only one NMI source and used separate
callout for each polled source. New code can handle multiple NMIs
and groups polled sources by power of 2 of the polling period.
Dimitry Andric [Sun, 12 Dec 2021 20:11:40 +0000 (21:11 +0100)]
Revert clang change that breaks CTF on aarch64
Revert commit e655e74a318e from llvm git (by Peter Collingbourne):
AST: Create __va_list in the std namespace even in C.
This ensures that the mangled type names match between C and C++,
which is significant when using -fsanitize=cfi-icall. Ideally we
wouldn't have created this namespace at all, but it's now part of
the ABI (e.g. in mangled names), so we can't change it.
As reported by Jessica in https://reviews.llvm.org/D104830#3129527, this
upstream change is implemented in such a way that it breaks DTrace's
CTF. Since a proper fix has not yet been forthcoming, and we are
unaffected by the (CFI-related) problem upstream was trying to address,
revert the change for now.
Mark Johnston [Mon, 15 Nov 2021 17:52:03 +0000 (12:52 -0500)]
amd64: Reduce the amount of cpuset copying done for TLB shootdowns
We use pmap_invalidate_cpu_mask() to get the set of active CPUs. This
(32-byte) set is copied by value through multiple frames until we get to
smp_targeted_tlb_shootdown(), where it is copied yet again.
Avoid this copying by having smp_targeted_tlb_shootdown() make a local
copy of the active CPUs for the pmap, and drop the cpuset parameter,
simplifying callers. Also leverage the use of the non-destructive
CPU_FOREACH_ISSET to avoid unneeded copying within
smp_targeted_tlb_shootdown().
Reviewed by: alc, kib
Tested by: pho
Sponsored by: The FreeBSD Foundation
Kornel Duleba [Tue, 23 Nov 2021 08:13:56 +0000 (09:13 +0100)]
pci: Don't try to read cfg registers of non-existing devices
Instead of returning 0xffs some controllers, such as Layerscape generate
an external exception when someone attempts to read any register
of config space of a non-existing device other than PCIR_VENDOR.
This causes a kernel panic.
Fix it by bailing during device enumeration if a device vendor register
returns invalid value. (0xffff)
Use this opportunity to replace some hardcoded values with a macro.
I believe that this change won't have any unintended side-effects since
it is safe to assume that vendor == 0xffff -> hdr_type == 0xffff.