Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions debian/control.top.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Build-Depends:
libgl-dev | libgl1-mesa-dev,
libglu1-mesa-dev,
libgtk-3-dev,
libcap-dev,
libmodbus-dev (>= 3.0),
libgpiod-dev,
@LIBREADLINE_DEV@,
Expand Down
51 changes: 51 additions & 0 deletions debian/extras/lib/udev/rules.d/99-linuxcnc-hm2-pci.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# LinuxCNC - grant Mesa HostMot2 PCI cards to the plugdev group so
# rtapi_app can map their config space and BARs without CAP_DAC_OVERRIDE.
# Needed only for rootless (file-capabilities) builds; setuid-root builds
# bypass DAC regardless.
#
# Add or remove Mesa subsystem IDs below to match new boards. SSIDs come
# from src/hal/drivers/mesa-hostmot2/hm2_pci.h.

ACTION!="add|change", GOTO="linuxcnc_hm2_end"
SUBSYSTEM!="pci", GOTO="linuxcnc_hm2_end"

# Direct-Mesa cards (5i24, 5i25, 5i25T, 6i25, 6i25T): single vendor match.
ATTR{vendor}=="0x2718", GOTO="linuxcnc_hm2_chmod"

# PLX-bridged Mesa cards share vendor 0x10B5 with generic PLX bridges,
# so match Mesa subsystem_device ids one at a time.
ATTR{vendor}!="0x10b5", GOTO="linuxcnc_hm2_end"
# 5i20
ATTRS{subsystem_device}=="0x3131", GOTO="linuxcnc_hm2_chmod"
# 4i65
ATTRS{subsystem_device}=="0x3132", GOTO="linuxcnc_hm2_chmod"
# 4i68 (old SSID)
ATTRS{subsystem_device}=="0x3133", GOTO="linuxcnc_hm2_chmod"
# 4i68 (new SSID)
ATTRS{subsystem_device}=="0x3311", GOTO="linuxcnc_hm2_chmod"
# 5i21
ATTRS{subsystem_device}=="0x3312", GOTO="linuxcnc_hm2_chmod"
# 5i22-1.5M
ATTRS{subsystem_device}=="0x3313", GOTO="linuxcnc_hm2_chmod"
# 5i22-1.0M
ATTRS{subsystem_device}=="0x3314", GOTO="linuxcnc_hm2_chmod"
# 5i23
ATTRS{subsystem_device}=="0x3315", GOTO="linuxcnc_hm2_chmod"
# 3x20-10
ATTRS{subsystem_device}=="0x3427", GOTO="linuxcnc_hm2_chmod"
# 3x20-15
ATTRS{subsystem_device}=="0x3428", GOTO="linuxcnc_hm2_chmod"
# 3x20-20
ATTRS{subsystem_device}=="0x3429", GOTO="linuxcnc_hm2_chmod"
# 4i69-16
ATTRS{subsystem_device}=="0x3472", GOTO="linuxcnc_hm2_chmod"
# 4i69-25
ATTRS{subsystem_device}=="0x3473", GOTO="linuxcnc_hm2_chmod"
GOTO="linuxcnc_hm2_end"

LABEL="linuxcnc_hm2_chmod"
# Fork a helper; sysfs files may not exist until the device is fully
# sized, so the chmod failures are ignored.
RUN+="/bin/sh -c 'chgrp plugdev /sys%p/config /sys%p/resource* 2>/dev/null; chmod g+rw /sys%p/config /sys%p/resource* 2>/dev/null; exit 0'"

LABEL="linuxcnc_hm2_end"
8 changes: 8 additions & 0 deletions debian/extras/lib/udev/rules.d/99-linuxcnc-realtime.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# LinuxCNC - expose realtime tuning knobs to the plugdev group so that
# rtapi_app can tune latency without CAP_DAC_OVERRIDE when running under
# file capabilities. setuid-root builds do not need this rule.

# /dev/cpu_dma_latency: harden_rt() opens this to pin CPU idle states at
# C0, cutting wake-up jitter on AC-powered machines. Default is 0600
# root:root, so an unprivileged rtapi_app would fail to open it.
KERNEL=="cpu_dma_latency", MODE="0660", GROUP="plugdev"
59 changes: 58 additions & 1 deletion docs/src/man/man9/hm2_eth.9.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,24 @@ IO boards, with HostMot2 firmware.

== SYNOPSIS

*loadrt hm2_eth* [**config=**"__str__[,__str__...]"] [**board_ip=**__ip__[,__ip__...] ] [**board_mac=**__mac__[,__mac__...] ]
*loadrt hm2_eth* [**config=**"__str__[,__str__...]"] [**board_ip=**__ip__[,__ip__...] ] [**board_mac=**__mac__[,__mac__...] ] [**no_iptables=**__0|1__]

____
*config* [default: ""]::
HostMot2 config strings, described in the hostmot2(9) manpage.
*board_ip* [default: ""]::
The IP address of the board(s), separated by commas.
As shipped, the board address is 192.168.1.121.
*no_iptables* [default: 0]::
Explicit override that disables all iptables interaction. By default
hm2_eth installs *iptables* and *ip6tables* rules itself; rtapi_app
raises *cap_net_admin* into its ambient capability set at startup so
the calls succeed under both setuid-root and rootless (file-cap)
installs. If the cap is not held the probe fails and rule
installation is skipped with a warning; in that case configure the
rules manually using the recipe in the NOTES section below. Set
*no_iptables=1* when iptables is reachable but you prefer to manage
the firewall externally (nftables, firewalld, systemd units).
____

== DESCRIPTION
Expand Down Expand Up @@ -146,6 +156,53 @@ At (normal) exit, hm2_eth will remove the rules. After a crash, you can
manually clear the rules with *sudo iptables -F hm2-eth-rules-output*;
the rules are also removed by a reboot.

=== Manual iptables configuration

When LinuxCNC is installed without *cap_net_admin* on rtapi_app
(typically because *sudo make setcap* was not run after the build),
hm2_eth cannot install its rules and prints a warning. Set up the
chain manually as root. Adjust the IP addresses, UDP destination port,
and interface name to match your install:

----
HOST_IP=192.168.1.1
BOARD_IP=192.168.1.121
BOARD_DPORT=27181
IFACE=eth1

iptables -N hm2-eth-rules-output
iptables -I OUTPUT 1 -j hm2-eth-rules-output
iptables -A hm2-eth-rules-output \
-p udp -m udp -d $BOARD_IP --dport $BOARD_DPORT \
-s $HOST_IP -j ACCEPT
iptables -A hm2-eth-rules-output -o $IFACE -p icmp -j DROP
iptables -A hm2-eth-rules-output -o $IFACE \
-j REJECT --reject-with icmp-admin-prohibited
ip6tables -N hm2-eth-rules-output
ip6tables -I OUTPUT 1 -j hm2-eth-rules-output
ip6tables -A hm2-eth-rules-output -o $IFACE -j DROP
----

For full IPv6 quiescence (no router solicitations or neighbor discovery
on the dedicated interface), additionally add this line to
`/etc/sysctl.d/99-hm2-eth.conf` and reboot:

----
net.ipv6.conf.IFACE.disable_ipv6 = 1
----

(The default ip6tables rule above only drops outbound IPv6; the kernel
still generates the packets.) Tear down the runtime rules with:

----
iptables -F hm2-eth-rules-output
iptables -D OUTPUT -j hm2-eth-rules-output
iptables -X hm2-eth-rules-output
ip6tables -F hm2-eth-rules-output
ip6tables -D OUTPUT -j hm2-eth-rules-output
ip6tables -X hm2-eth-rules-output
----

"hardware-irq-coalesce-rx-usecs" decreases time waiting to receive a packet on most systems,
but on at least some Marvel-chipset NICs it is harmful.
If the line does not improve system performance, then remove it.
Expand Down
12 changes: 8 additions & 4 deletions docs/src/man/man9/hm2_rpspi.9.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,14 @@ Mesa's SPI based Anything I/O boards (with the HostMot2 firmware) to the
LinuxCNC HAL. This driver is not based on the linux spidev driver, but
on a dedicated BCM2835-SPI driver.

It is *strongly* recommended that you unload/disable the kernel's spidev
driver by disabling it using *raspi-config*. Please note that having
both kernel and user-space SPI drivers installed can result in
unexpected interactions and system instabilities.
The kernel's *spi_bcm2835* driver conflicts with this user-space driver
and must be disabled before *hm2_rpspi* will load. Use *raspi-config*
(Interface Options -> SPI -> Disable) and reboot. If the kernel module
is still present at load time the driver will refuse to start with
"Kernel SPI driver spi_bcm2835 is loaded and conflicts" rather than
fight the kernel for the bus. Having both kernel and user-space SPI
drivers installed otherwise leads to unexpected interactions and
system instabilities.

The supported boards are: 7I90HD.

Expand Down
28 changes: 21 additions & 7 deletions docs/src/man/man9/hm2_spix.9.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,27 @@ setting would be to set one step below the maximum speeds.

== NOTES

If you know your setup and do not require the spix_spidev driver, then
it is *strongly* recommended that you unload/disable the kernel's SPI
drivers *dw_spi* and *dw_spi_mmio* for the RPi5 or *spi_bmc2835* for the
RPi3 and RPi4. The hm2_spix hardware drivers attempt to unload the
kernel driver at startup if detected and restore it at exit if initially
loaded. However, there are no guarantees about the effectiveness of the
module unload/load actions.
If you do not require the spix_spidev driver you must disable the
kernel's SPI driver before *hm2_spix* will load. The conflicting module
is *spi_bcm2835* on the RPi3 / RPi4 and *dw_spi_mmio* (with its
dependency *dw_spi*) on the RPi5. The driver detects the kernel module
at startup and refuses to load with "Kernel SPI driver ... is loaded
and conflicts" rather than fight the kernel for the bus.

To disable on RPi3 / RPi4, run *raspi-config* and pick
Interface Options -> SPI -> Disable, then reboot.

To disable on RPi5, blacklist both kernel modules. Create
*/etc/modprobe.d/blacklist-linuxcnc.conf* containing:

----
blacklist dw_spi_mmio
blacklist dw_spi
----

Then reboot. If either module is built-in to the kernel rather than
loadable, use a kernel command-line override
(*modprobe.blacklist=dw_spi_mmio,dw_spi* in `/boot/firmware/cmdline.txt`).

*Warning*: having both kernel and user-space SPI drivers installed can
result in unexpected interactions and system instabilities.
Expand Down
34 changes: 29 additions & 5 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ endif
ifeq ($(MAKECMDGOALS),)
TRIVIAL_BUILD=no
else
ifeq ($(filter-out docclean clean setuid install tags swish,$(MAKECMDGOALS)),)
ifeq ($(filter-out docclean clean setuid setcap install tags swish,$(MAKECMDGOALS)),)
TRIVIAL_BUILD=yes
else
TRIVIAL_BUILD=no
Expand Down Expand Up @@ -140,7 +140,13 @@ ifeq ($(RUN_IN_PLACE),yes)
ifneq ($(BUILD_SYS),uspace)
@if [ -f ../bin/linuxcnc_module_helper ]; then if ! [ `id -u` = 0 -a -O ../bin/linuxcnc_module_helper -a -u ../bin/linuxcnc_module_helper ]; then $(VECHO) "You now need to run 'sudo make setuid' in order to run in place."; fi; fi
else
@if [ -f ../bin/rtapi_app ]; then if ! [ `id -u` = 0 -a -O ../bin/rtapi_app -a -u ../bin/rtapi_app ]; then $(VECHO) "You now need to run 'sudo make setuid' in order to run in place with access to hardware."; fi; fi
@if [ -f ../bin/rtapi_app ]; then \
if [ `id -u` = 0 -a -O ../bin/rtapi_app -a -u ../bin/rtapi_app ]; then :; \
elif PATH="/sbin:/usr/sbin:$$PATH" command -v getcap >/dev/null 2>&1 \
&& [ -n "`PATH=/sbin:/usr/sbin:$$PATH getcap ../bin/rtapi_app 2>/dev/null`" ]; then :; \
else $(VECHO) "You now need to run 'sudo make setuid' or 'sudo make setcap' in order to run in place with access to hardware."; \
fi; \
fi
endif
endif

Expand Down Expand Up @@ -568,6 +574,25 @@ endif
chown root ../bin/linuxcnc_module_helper
chmod 4750 ../bin/linuxcnc_module_helper

# File capabilities alternative to setuid (uspace only).
# Grants rtapi_app the kernel privileges it needs without running as root:
# cap_ipc_lock - mlock() for realtime memory
# cap_net_admin - raw socket access for hm2_eth / iptables management
# cap_sys_rawio - iopl() and /dev/mem for parallel port and PCI I/O
# cap_sys_nice - SCHED_FIFO scheduling and CPU affinity
# Linux capabilities are not inherited across exec(), so /sbin/iptables
# launched from rtapi_app would run unprivileged. rtapi_app raises
# cap_net_admin into its ambient set at startup so it survives execve().
# Clears any setuid bit left by a prior 'make setuid' so the two paths don't
# silently stack.
setcap:
ifeq ($(BUILD_SYS),uspace)
chmod u-s ../bin/rtapi_app
setcap cap_ipc_lock,cap_net_admin,cap_sys_rawio,cap_sys_nice+ep ../bin/rtapi_app
else
@echo "setcap target is only supported for uspace builds" >&2; exit 1
endif

# These rules allows a header file from this directory to be installed into
# ../include. A pair of rules like these will exist in the Submakefile
# of each file that contains headers.
Expand Down Expand Up @@ -1022,7 +1047,6 @@ hm2_pci-objs := \
$(MATHSTUB)
hm2_eth-objs := \
hal/drivers/mesa-hostmot2/hm2_eth.o \
hal/drivers/mesa-hostmot2/eshellf.o \
$(MATHSTUB)
hm2_spi-objs := \
hal/drivers/mesa-hostmot2/hm2_spi.o \
Expand All @@ -1031,15 +1055,15 @@ hm2_spi-objs := \
hm2_rpspi-objs := \
hal/drivers/mesa-hostmot2/hm2_rpspi.o \
hal/drivers/mesa-hostmot2/llio_info.o \
hal/drivers/mesa-hostmot2/eshellf.o \
hal/drivers/mesa-hostmot2/kmod_check.o \
$(MATHSTUB)
hm2_spix-objs := \
hal/drivers/mesa-hostmot2/hm2_spix.o \
hal/drivers/mesa-hostmot2/spix_rpi5.o \
hal/drivers/mesa-hostmot2/spix_rpi3.o \
hal/drivers/mesa-hostmot2/spix_spidev.o \
hal/drivers/mesa-hostmot2/llio_info.o \
hal/drivers/mesa-hostmot2/eshellf.o \
hal/drivers/mesa-hostmot2/kmod_check.o \
$(MATHSTUB)
hm2_modbus-objs := \
hal/drivers/mesa-hostmot2/hm2_modbus.o \
Expand Down
13 changes: 1 addition & 12 deletions src/hal/drivers/hal_evoreg.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,9 @@
#include <rtapi_ctype.h> /* isspace() */
#include <rtapi.h> /* RTAPI realtime OS API */
#include <rtapi_app.h> /* RTAPI realtime module decls */
#include <rtapi_io.h> /* rtapi_inb(), rtapi_outb() */
#include <hal.h> /* HAL public API decls */

/* If FASTIO is defined, uses outb() and inb() from <asm.io>,
instead of rtapi_outb() and rtapi_inb() - the <asm.io> ones
are inlined, and save a microsecond or two (on my 233MHz box)
*/
#define FASTIO

#ifdef FASTIO
#define rtapi_inb inb
#define rtapi_outb outb
#include <asm/io.h>
#endif

/* module information */
MODULE_AUTHOR("Martin Kuhnle");
MODULE_DESCRIPTION("SIEMENS-EVOREG Driver for EMC HAL");
Expand Down
63 changes: 0 additions & 63 deletions src/hal/drivers/mesa-hostmot2/eshellf.c

This file was deleted.

Loading
Loading