From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 16:01:40
Hi all,
The just released ACPI 6.4 spec [1] adds a new _OSC method that is used to
negotiate OS support for native USB4 features such as PCIe tunneling. This
patch series adds Linux support for the new _OSC and modifies the
Thunderbolt/USB4 driver accordingly to enable/disable tunneling of
different protocols.
There is an additional setting in the firmware connection manager that
allows the BIOS to disable PCIe tunneling, so we add support for this and
also make the software connection manager to switch to this "nopcie"
security level when the _OSC does not allow PCIe tunneling.
This applies on top of thunderbolt.git/next.
[1] https://uefi.org/sites/default/files/resources/ACPI_Spec_6_4_Jan22.pdf
Mario Limonciello (2):
thunderbolt: Fix possible NULL pointer dereference in tb_acpi_add_link()
ACPI: Execute platform _OSC also with query bit clear
Mika Westerberg (4):
thunderbolt: Add support for PCIe tunneling disabled (SL5)
thunderbolt: Allow disabling XDomain protocol
ACPI: Add support for native USB4 control _OSC
thunderbolt: Add support for native USB4 _OSC
.../ABI/testing/sysfs-bus-thunderbolt | 2 +
Documentation/admin-guide/thunderbolt.rst | 7 ++
drivers/acpi/bus.c | 119 ++++++++++++++++--
drivers/thunderbolt/acpi.c | 67 +++++++++-
drivers/thunderbolt/domain.c | 16 ++-
drivers/thunderbolt/icm.c | 6 +-
drivers/thunderbolt/nhi.c | 27 +++-
drivers/thunderbolt/switch.c | 6 +-
drivers/thunderbolt/tb.c | 22 +++-
drivers/thunderbolt/tb.h | 13 ++
drivers/thunderbolt/tunnel.c | 10 +-
drivers/thunderbolt/usb4.c | 11 +-
drivers/thunderbolt/xdomain.c | 9 ++
include/linux/acpi.h | 10 ++
include/linux/thunderbolt.h | 3 +
15 files changed, 299 insertions(+), 29 deletions(-)
--
2.29.2
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 15:59:54
Recent Intel Thunderbolt firmware connection manager has support for
another security level, SL5, that disables PCIe tunneling. This option
can be turned on from the BIOS.
When this is set the driver exposes a new security level "nopcie" to the
userspace and hides the authorized attribute under connected devices.
While there we also hide it when "dponly" security level is enabled
since it is not really usable in that case anyway.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Documentation/ABI/testing/sysfs-bus-thunderbolt | 2 ++
Documentation/admin-guide/thunderbolt.rst | 7 +++++++
drivers/thunderbolt/domain.c | 12 +++++++++++-
drivers/thunderbolt/switch.c | 6 +++++-
include/linux/thunderbolt.h | 3 +++
5 files changed, 28 insertions(+), 2 deletions(-)
@@ -85,6 +85,8 @@ Description: This attribute holds current Thunderbolt security level usbonly Automatically tunnel USB controller of the connected Thunderbolt dock (and Display Port). All PCIe links downstream of the dock are removed.+ nopcie USB4 system where PCIe tunneling is disabled from+ the BIOS. ======= ================================================== What: /sys/bus/thunderbolt/devices/.../authorized
@@ -47,6 +47,9 @@ be DMA masters and thus read contents of the host memory without CPU and OS knowing about it. There are ways to prevent this by setting up an IOMMU but it is not always available for various reasons.+Some USB4 systems have a BIOS setting to disable PCIe tunneling. This is+treated as another security level (nopcie).+ The security levels are as follows: none
@@ -77,6 +80,10 @@ The security levels are as follows: Display Port in a dock. All PCIe links downstream of the dock are removed.+ nopcie+ PCIe tunneling is disabled/forbidden from the BIOS. Available in some+ USB4 systems.+ The current security level can be read from``/sys/bus/thunderbolt/devices/domainX/security`` where ``domainX`` is the Thunderbolt domain the host controller manages. There is typically
@@ -243,8 +244,14 @@ static ssize_t deauthorization_show(struct device *dev,char*buf){conststructtb*tb=container_of(dev,structtb,dev);+booldeauthorization=false;-returnsprintf(buf,"%d\n",!!tb->cm_ops->disapprove_switch);+/* Only meaningful if authorization is supported */+if(tb->security_level==TB_SECURITY_USER||+tb->security_level==TB_SECURITY_SECURE)+deauthorization=!!tb->cm_ops->disapprove_switch;++returnsprintf(buf,"%d\n",deauthorization);}staticDEVICE_ATTR_RO(deauthorization);
@@ -452,6 +459,9 @@ int tb_domain_add(struct tb *tb)gotoerr_ctl_stop;}+tb_dbg(tb,"security level set to %s\n",+tb_security_names[tb->security_level]);+ret=device_add(&tb->dev);if(ret)gotoerr_ctl_stop;
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 16:00:06
This allows disabling XDomain protocol completely if the user does not
plan to use the USB4/Thunderbolt peer-to-peer functionality, or for
security reasons.
XDomain protocol is enabled by default but with this commit it is
possible to disable it by passing "xdomain=0" as module parameter (or
through the kernel command line).
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/domain.c | 4 +++-
drivers/thunderbolt/icm.c | 6 ++++--
drivers/thunderbolt/tb.c | 3 +++
drivers/thunderbolt/tb.h | 1 +
drivers/thunderbolt/xdomain.c | 9 +++++++++
5 files changed, 20 insertions(+), 3 deletions(-)
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 16:00:22
ACPI 6.4 introduced a new _OSC capability used to negotiate whether the
OS is supposed to use Software (native) or Firmware based Connection
Manager. If the native support is granted then there are set of bits
that enable/disable different tunnel types that the Software Connection
Manager is allowed to tunnel.
This adds support for this new USB4 _OSC accordingly. When PCIe
tunneling is disabled then the driver switches security level to be
"nopcie" following the security level 5 used in Firmware based
Connection Manager.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/acpi.c | 65 +++++++++++++++++++++++++++++++++++
drivers/thunderbolt/nhi.c | 27 +++++++++++++--
drivers/thunderbolt/tb.c | 19 +++++++++-
drivers/thunderbolt/tb.h | 12 +++++++
drivers/thunderbolt/tunnel.c | 10 +++---
drivers/thunderbolt/usb4.c | 11 ++++--
drivers/thunderbolt/xdomain.c | 2 +-
7 files changed, 134 insertions(+), 12 deletions(-)
@@ -331,13 +331,18 @@ int usb4_switch_setup(struct tb_switch *sw)if(ret)returnret;-if(sw->link_usb4&&tb_switch_find_port(parent,TB_TYPE_USB3_DOWN)){+if(tb_acpi_may_tunnel_usb3()&&sw->link_usb4&&+tb_switch_find_port(parent,TB_TYPE_USB3_DOWN)){val|=ROUTER_CS_5_UTO;xhci=false;}-/* Only enable PCIe tunneling if the parent router supports it */-if(tb_switch_find_port(parent,TB_TYPE_PCIE_DOWN)){+/*+*OnlyenablePCIetunnelingiftheparentroutersupportsit+*anditisnotdisabled.+*/+if(tb_acpi_may_tunnel_pcie()&&+tb_switch_find_port(parent,TB_TYPE_PCIE_DOWN)){val|=ROUTER_CS_5_PTO;/**xHCIcanbeenabledifPCIetunnelingissupported
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 16:01:16
ACPI 6.4 introduced a new _OSC capability that is used negotiate native
connection manager support. Connection manager is the entity that is
responsible for tunneling over the USB4 fabric. If the platform rejects
the native access then firmware based connection manager is used.
The new _OSC also includes a set of bits that can be used to disable
certain tunnel types such as PCIe for security reasons for instance.
This implements the new USB4 _OSC so that we try to negotiate native
USB4 support if the Thunderbolt/USB4 (CONFIG_USB4) driver is enabled.
Drivers can determine what was negotiated by checking two new variables
exposed in this patch.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/acpi/bus.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 10 ++++++
2 files changed, 86 insertions(+)
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 16:01:40
From: Mario Limonciello <redacted>
When we walk up the device hierarchy in tb_acpi_add_link() make sure we
break the loop if the device has no parent. Otherwise we may crash the
kernel by dereferencing a NULL pointer.
Fixes: b2be2b05cf3b ("thunderbolt: Create device links from ACPI description")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/acpi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 16:01:45
From: Mario Limonciello <redacted>
The platform _OSC can change the hardware state when query bit is not
set. According to ACPI spec it is recommended that the OS runs _OSC with
query bit set until the platform does not mask any of the capabilities.
Then it should run it with query bit clear in order to actually commit
the changes. At the moment Linux only runs the _OSC with query bit set
and this is going to cause problems with the USB4 CM (Connection
Manager) switch that is going to commit the switch only when the OS
requests control over the feature.
For this reason modify the _OSC support so that we first execute it with
query bit set, then use the returned valu as base of the features we
want to control and run the _OSC again with query bit clear.
Also rename the function to better match what it does.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/acpi/bus.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
@@ -321,17 +321,36 @@ static void acpi_bus_osc_support(void)capbuf[OSC_SUPPORT_DWORD]|=OSC_SB_APEI_SUPPORT;if(ACPI_FAILURE(acpi_get_handle(NULL,"\\_SB",&handle)))return;-if(ACPI_SUCCESS(acpi_run_osc(handle,&context))){-u32*capbuf_ret=context.ret.pointer;-if(context.ret.length>OSC_SUPPORT_DWORD){-osc_sb_apei_support_acked=-capbuf_ret[OSC_SUPPORT_DWORD]&OSC_SB_APEI_SUPPORT;-osc_pc_lpi_support_confirmed=-capbuf_ret[OSC_SUPPORT_DWORD]&OSC_SB_PCLPI_SUPPORT;-}++if(ACPI_FAILURE(acpi_run_osc(handle,&context)))+return;++capbuf_ret=context.ret.pointer;+if(context.ret.length<=OSC_SUPPORT_DWORD){kfree(context.ret.pointer);+return;}-/* do we need to check other returned cap? Sounds no */++/*+*Nowrun_OSCagainwithqueryflagcleanandwiththecaps+*bothplatformandOSsupports.+*/+capbuf[OSC_QUERY_DWORD]=0;+capbuf[OSC_SUPPORT_DWORD]=capbuf_ret[OSC_SUPPORT_DWORD];+kfree(context.ret.pointer);++if(ACPI_FAILURE(acpi_run_osc(handle,&context)))+return;++capbuf_ret=context.ret.pointer;+if(context.ret.length>OSC_SUPPORT_DWORD){+osc_sb_apei_support_acked=+capbuf_ret[OSC_SUPPORT_DWORD]&OSC_SB_APEI_SUPPORT;+osc_pc_lpi_support_confirmed=+capbuf_ret[OSC_SUPPORT_DWORD]&OSC_SB_PCLPI_SUPPORT;+}++kfree(context.ret.pointer);}/* --------------------------------------------------------------------------
@@ -1168,7 +1187,7 @@ static int __init acpi_bus_init(void)*_OSCmethodmayexistinmodulelevelcode,*soitmustberunafterACPI_FULL_INITIALIZATION*/-acpi_bus_osc_support();+acpi_bus_osc_negotiate_platform_control();/**_PDCcontrolmethodmayloaddynamicSSDTtables,
On Tue, Jan 26, 2021 at 5:57 PM Mika Westerberg
[off-list ref] wrote:
Recent Intel Thunderbolt firmware connection manager has support for
another security level, SL5, that disables PCIe tunneling. This option
can be turned on from the BIOS.
When this is set the driver exposes a new security level "nopcie" to the
userspace and hides the authorized attribute under connected devices.
While there we also hide it when "dponly" security level is enabled
since it is not really usable in that case anyway.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Looks good to me, I'm just not sure I understand how this is different from
dponly mode. Is this just because it comes from the new _OSC?
On Tue, Jan 26, 2021 at 5:57 PM Mika Westerberg
[off-list ref] wrote:
From: Mario Limonciello <redacted>
The platform _OSC can change the hardware state when query bit is not
set. According to ACPI spec it is recommended that the OS runs _OSC with
query bit set until the platform does not mask any of the capabilities.
Then it should run it with query bit clear in order to actually commit
the changes. At the moment Linux only runs the _OSC with query bit set
and this is going to cause problems with the USB4 CM (Connection
Manager) switch that is going to commit the switch only when the OS
requests control over the feature.
For this reason modify the _OSC support so that we first execute it with
query bit set, then use the returned valu as base of the features we
Totally out of my depth here, but just noticed the typo (valu => value).
want to control and run the _OSC again with query bit clear.
Also rename the function to better match what it does.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-26 16:29:00
On Tue, Jan 26, 2021 at 06:18:47PM +0200, Yehezkel Bernat wrote:
On Tue, Jan 26, 2021 at 5:57 PM Mika Westerberg
[off-list ref] wrote:
quoted
Recent Intel Thunderbolt firmware connection manager has support for
another security level, SL5, that disables PCIe tunneling. This option
can be turned on from the BIOS.
When this is set the driver exposes a new security level "nopcie" to the
userspace and hides the authorized attribute under connected devices.
While there we also hide it when "dponly" security level is enabled
since it is not really usable in that case anyway.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Looks good to me, I'm just not sure I understand how this is different from
dponly mode. Is this just because it comes from the new _OSC?
The firmware connection manager reports this new security level instead
of dponly so we reflect that to the userspace, and while at it take
advantage of the nopcie when USB4 _OSC disables PCIe tunneling so they
both look the same from userspace perspective.
On Tue, Jan 26, 2021 at 5:57 PM Mika Westerberg
[off-list ref] wrote:
Hi all,
The just released ACPI 6.4 spec [1] adds a new _OSC method that is used to
negotiate OS support for native USB4 features such as PCIe tunneling. This
patch series adds Linux support for the new _OSC and modifies the
Thunderbolt/USB4 driver accordingly to enable/disable tunneling of
different protocols.
There is an additional setting in the firmware connection manager that
allows the BIOS to disable PCIe tunneling, so we add support for this and
also make the software connection manager to switch to this "nopcie"
security level when the _OSC does not allow PCIe tunneling.
This applies on top of thunderbolt.git/next.
[1] https://uefi.org/sites/default/files/resources/ACPI_Spec_6_4_Jan22.pdf
Mario Limonciello (2):
thunderbolt: Fix possible NULL pointer dereference in tb_acpi_add_link()
ACPI: Execute platform _OSC also with query bit clear
Mika Westerberg (4):
thunderbolt: Add support for PCIe tunneling disabled (SL5)
thunderbolt: Allow disabling XDomain protocol
ACPI: Add support for native USB4 control _OSC
thunderbolt: Add support for native USB4 _OSC
For Thunderbolt parts,
Acked-by: Yehezkel Bernat [off-list ref]
On Tue, Jan 26, 2021 at 6:26 PM Mika Westerberg
[off-list ref] wrote:
On Tue, Jan 26, 2021 at 06:18:47PM +0200, Yehezkel Bernat wrote:
quoted
On Tue, Jan 26, 2021 at 5:57 PM Mika Westerberg
[off-list ref] wrote:
quoted
Recent Intel Thunderbolt firmware connection manager has support for
another security level, SL5, that disables PCIe tunneling. This option
can be turned on from the BIOS.
When this is set the driver exposes a new security level "nopcie" to the
userspace and hides the authorized attribute under connected devices.
While there we also hide it when "dponly" security level is enabled
since it is not really usable in that case anyway.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Looks good to me, I'm just not sure I understand how this is different from
dponly mode. Is this just because it comes from the new _OSC?
The firmware connection manager reports this new security level instead
of dponly so we reflect that to the userspace, and while at it take
advantage of the nopcie when USB4 _OSC disables PCIe tunneling so they
both look the same from userspace perspective.
From: "Rafael J. Wysocki" <rafael@kernel.org> Date: 2021-01-26 22:52:03
On Tue, Jan 26, 2021 at 5:01 PM Mika Westerberg
[off-list ref] wrote:
From: Mario Limonciello <redacted>
The platform _OSC can change the hardware state when query bit is not
set. According to ACPI spec it is recommended that the OS runs _OSC with
query bit set until the platform does not mask any of the capabilities.
Then it should run it with query bit clear in order to actually commit
the changes. At the moment Linux only runs the _OSC with query bit set
And that's because there was nothing it could ask to control using the
_SB scope _OSC.
Today it is just reporting what features are supported by it.
However, with the upcoming USB4 CM support it needs to ask for the
control of that feature and that's why the _SB scope _OSC support
needs to be extended. So it is not a fix for a bug or missing spec
coverage, which this part of the changelog kind of implies, it's just
enabling a new feature.
and this is going to cause problems with the USB4 CM (Connection
Manager) switch that is going to commit the switch only when the OS
requests control over the feature.
For this reason modify the _OSC support so that we first execute it with
query bit set, then use the returned valu as base of the features we
s/valu/value/
quoted hunk
want to control and run the _OSC again with query bit clear.
Also rename the function to better match what it does.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/acpi/bus.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
@@ -321,17 +321,36 @@ static void acpi_bus_osc_support(void)capbuf[OSC_SUPPORT_DWORD]|=OSC_SB_APEI_SUPPORT;if(ACPI_FAILURE(acpi_get_handle(NULL,"\\_SB",&handle)))return;-if(ACPI_SUCCESS(acpi_run_osc(handle,&context))){-u32*capbuf_ret=context.ret.pointer;-if(context.ret.length>OSC_SUPPORT_DWORD){-osc_sb_apei_support_acked=-capbuf_ret[OSC_SUPPORT_DWORD]&OSC_SB_APEI_SUPPORT;-osc_pc_lpi_support_confirmed=-capbuf_ret[OSC_SUPPORT_DWORD]&OSC_SB_PCLPI_SUPPORT;-}++if(ACPI_FAILURE(acpi_run_osc(handle,&context)))+return;++capbuf_ret=context.ret.pointer;+if(context.ret.length<=OSC_SUPPORT_DWORD){kfree(context.ret.pointer);+return;}-/* do we need to check other returned cap? Sounds no */++/*+*Nowrun_OSCagainwithqueryflagcleanandwiththecaps
s/clean/clear/
+ * both platform and OS supports.
s/both platform and OS supports/supported by both the OS and the platform/
@@ -1168,7 +1187,7 @@ static int __init acpi_bus_init(void) * _OSC method may exist in module level code, * so it must be run after ACPI_FULL_INITIALIZATION */- acpi_bus_osc_support();+ acpi_bus_osc_negotiate_platform_control(); /* * _PDC control method may load dynamic SSDT tables,--
From: "Rafael J. Wysocki" <rafael@kernel.org> Date: 2021-01-26 22:52:03
On Tue, Jan 26, 2021 at 5:01 PM Mika Westerberg
[off-list ref] wrote:
quoted hunk
ACPI 6.4 introduced a new _OSC capability that is used negotiate native
connection manager support. Connection manager is the entity that is
responsible for tunneling over the USB4 fabric. If the platform rejects
the native access then firmware based connection manager is used.
The new _OSC also includes a set of bits that can be used to disable
certain tunnel types such as PCIe for security reasons for instance.
This implements the new USB4 _OSC so that we try to negotiate native
USB4 support if the Thunderbolt/USB4 (CONFIG_USB4) driver is enabled.
Drivers can determine what was negotiated by checking two new variables
exposed in this patch.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/acpi/bus.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 10 ++++++
2 files changed, 86 insertions(+)
This is the same _OSC that is evaluated in
acpi_bus_osc_negotiate_platform_control(), right?
So shouldn't the capbuf[OSC_SUPPORT_DWORD] be whatever is negotiated
through acpi_bus_osc_negotiate_platform_control()? At least that
would be consistent with acpi_pci_osc_control_set().
And if this was done I'm not sure if the change in the previous patch
would be needed then?
quoted hunk
+ if (ACPI_FAILURE(status))
+ return;
+
+ if (context.ret.length != sizeof(capbuf)) {
+ printk(KERN_INFO PREFIX "USB4 _OSC: returned invalid length buffer\n");
+ goto out_free;
}
+ osc_sb_native_usb4_control =
+ control & ((u32 *)context.ret.pointer)[OSC_CONTROL_DWORD];
+
+ acpi_bus_decode_usb_osc("USB4 _OSC: OS supports", control);
+ acpi_bus_decode_usb_osc("USB4 _OSC: OS controls",
+ osc_sb_native_usb4_control);
+
+out_free:
kfree(context.ret.pointer);
}
@@ -1188,6 +1263,7 @@ static int __init acpi_bus_init(void) * so it must be run after ACPI_FULL_INITIALIZATION */ acpi_bus_osc_negotiate_platform_control();+ acpi_bus_osc_negotiate_usb_control(); /* * _PDC control method may load dynamic SSDT tables,
From: Limonciello, Mario <hidden> Date: 2021-01-26 22:52:03
On Tue, Jan 26, 2021 at 5:01 PM Mika Westerberg
[off-list ref] wrote:
quoted
From: Mario Limonciello <redacted>
The platform _OSC can change the hardware state when query bit is not
set. According to ACPI spec it is recommended that the OS runs _OSC with
query bit set until the platform does not mask any of the capabilities.
Then it should run it with query bit clear in order to actually commit
the changes. At the moment Linux only runs the _OSC with query bit set
And that's because there was nothing it could ask to control using the
_SB scope _OSC.
Today it is just reporting what features are supported by it.
However, with the upcoming USB4 CM support it needs to ask for the
control of that feature and that's why the _SB scope _OSC support
needs to be extended. So it is not a fix for a bug or missing spec
coverage, which this part of the changelog kind of implies, it's just
enabling a new feature.
Other operating systems behave as described in the ACPI spec long before USB4 CM
support was added. Admittedly this is semantics of whether to call it
a "bug", but specifically the lack of this in the existing Linux kernel code
*can* actually cause you to get into a situation where you have no functional
USB4. This will happen if you boot between two different kernels or potentially
two different operating systems. This is due to how the selection of FW or SW
CM is made. If this patch "alone" was brought further backward the older kernels
FW CM mode would be activated in those situations.
quoted
and this is going to cause problems with the USB4 CM (Connection
Manager) switch that is going to commit the switch only when the OS
requests control over the feature.
For this reason modify the _OSC support so that we first execute it with
query bit set, then use the returned valu as base of the features we
s/valu/value/
quoted
want to control and run the _OSC again with query bit clear.
Also rename the function to better match what it does.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/acpi/bus.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
- }
+
+ if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
+ return;
+
+ capbuf_ret = context.ret.pointer;
+ if (context.ret.length <= OSC_SUPPORT_DWORD) {
kfree(context.ret.pointer);
+ return;
}
- /* do we need to check other returned cap? Sounds no */
+
+ /*
+ * Now run _OSC again with query flag clean and with the caps
s/clean/clear/
quoted
+ * both platform and OS supports.
s/both platform and OS supports/supported by both the OS and the platform/
@@ -1168,7 +1187,7 @@ static int __init acpi_bus_init(void) * _OSC method may exist in module level code, * so it must be run after ACPI_FULL_INITIALIZATION */- acpi_bus_osc_support();+ acpi_bus_osc_negotiate_platform_control(); /* * _PDC control method may load dynamic SSDT tables,--
From: "Rafael J. Wysocki" <rafael@kernel.org> Date: 2021-01-26 22:52:04
On Tue, Jan 26, 2021 at 6:37 PM Limonciello, Mario
[off-list ref] wrote:
quoted
On Tue, Jan 26, 2021 at 5:01 PM Mika Westerberg
[off-list ref] wrote:
quoted
From: Mario Limonciello <redacted>
The platform _OSC can change the hardware state when query bit is not
set. According to ACPI spec it is recommended that the OS runs _OSC with
query bit set until the platform does not mask any of the capabilities.
Then it should run it with query bit clear in order to actually commit
the changes. At the moment Linux only runs the _OSC with query bit set
And that's because there was nothing it could ask to control using the
_SB scope _OSC.
Today it is just reporting what features are supported by it.
However, with the upcoming USB4 CM support it needs to ask for the
control of that feature and that's why the _SB scope _OSC support
needs to be extended. So it is not a fix for a bug or missing spec
coverage, which this part of the changelog kind of implies, it's just
enabling a new feature.
Other operating systems behave as described in the ACPI spec long before USB4 CM
support was added. Admittedly this is semantics of whether to call it
a "bug", but specifically the lack of this in the existing Linux kernel code
*can* actually cause you to get into a situation where you have no functional
USB4. This will happen if you boot between two different kernels or potentially
two different operating systems. This is due to how the selection of FW or SW
CM is made. If this patch "alone" was brought further backward the older kernels
FW CM mode would be activated in those situations.
I would put that information into the changelog.
Moreover, have you looked at acpi_pci_osc_control_set()?
What it does is analogous to what you are proposing, but a bit
different, and I would like to preserve consistency between _OSC use
cases.
So would it be possible to adjust the _SB _OSC evaluation flow to
follow the PCI _OSC one? That is, if any control bits are there, pass
them along with the last evaluation of _OSC with the query flag clear.
Or is the latter defective and if so then why?
quoted
quoted
and this is going to cause problems with the USB4 CM (Connection
Manager) switch that is going to commit the switch only when the OS
requests control over the feature.
For this reason modify the _OSC support so that we first execute it with
query bit set, then use the returned valu as base of the features we
s/valu/value/
quoted
want to control and run the _OSC again with query bit clear.
Also rename the function to better match what it does.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/acpi/bus.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
- }
+
+ if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
+ return;
+
+ capbuf_ret = context.ret.pointer;
+ if (context.ret.length <= OSC_SUPPORT_DWORD) {
kfree(context.ret.pointer);
+ return;
}
- /* do we need to check other returned cap? Sounds no */
+
+ /*
+ * Now run _OSC again with query flag clean and with the caps
s/clean/clear/
quoted
+ * both platform and OS supports.
s/both platform and OS supports/supported by both the OS and the platform/
@@ -1168,7 +1187,7 @@ static int __init acpi_bus_init(void) * _OSC method may exist in module level code, * so it must be run after ACPI_FULL_INITIALIZATION */- acpi_bus_osc_support();+ acpi_bus_osc_negotiate_platform_control(); /* * _PDC control method may load dynamic SSDT tables,--
This is the same _OSC that is evaluated in
acpi_bus_osc_negotiate_platform_control(), right?
Yes, but different UUID.
So shouldn't the capbuf[OSC_SUPPORT_DWORD] be whatever is negotiated
through acpi_bus_osc_negotiate_platform_control()? At least that
would be consistent with acpi_pci_osc_control_set().
The ACPI 6.4 spec says that the support field for this _OSC is reserved
(table 6.14 in the spec). So as far as I can tell this is not the same
as what we pass for the platform _OSC.
From: "Rafael J. Wysocki" <rafael@kernel.org> Date: 2021-01-27 12:48:14
On Tue, Jan 26, 2021 at 5:01 PM Mika Westerberg
[off-list ref] wrote:
ACPI 6.4 introduced a new _OSC capability that is used negotiate native
connection manager support. Connection manager is the entity that is
responsible for tunneling over the USB4 fabric. If the platform rejects
the native access then firmware based connection manager is used.
The new _OSC also includes a set of bits that can be used to disable
certain tunnel types such as PCIe for security reasons for instance.
This implements the new USB4 _OSC so that we try to negotiate native
USB4 support if the Thunderbolt/USB4 (CONFIG_USB4) driver is enabled.
Drivers can determine what was negotiated by checking two new variables
exposed in this patch.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-27 12:55:54
On Tue, Jan 26, 2021 at 10:43:32PM +0000, Limonciello, Mario wrote:
quoted
I would put that information into the changelog.
Thanks, @Mika Westerberg can you collapse that in when you re-spin the
series?
Sure.
quoted
Moreover, have you looked at acpi_pci_osc_control_set()?
What it does is analogous to what you are proposing, but a bit
different, and I would like to preserve consistency between _OSC use
cases.
So would it be possible to adjust the _SB _OSC evaluation flow to
follow the PCI _OSC one? That is, if any control bits are there, pass
them along with the last evaluation of _OSC with the query flag clear.
Or is the latter defective and if so then why?
Basically the only difference is another line cloning OSC_CONTROL_DWORD from
capbuf_ret to capbuf?
Yes, this actually sounds like it better adheres to the spec to me.
Quoting spec:
" If the OS is granted control of a feature in the Control Field in one call to
_OSC, then it must preserve the set state of that bit (requesting that feature)
in all subsequent calls."
However, the platform wide _OSC does not actually have this
OSC_CONTROL_DWORD at all ;-)
I think what we do in this patch is already equivalent to what the PCI
_OSC is doing:
1. Query bit set _OSC
2. Take the returned OSC_SUPPORT_DWORD buffer and
3. Pass it to the _OSC with query bit clear.
I may be missing something, though.
From: Limonciello, Mario <hidden> Date: 2021-01-27 13:10:40
I would put that information into the changelog.
Thanks, @Mika Westerberg can you collapse that in when you re-spin the
series?
Moreover, have you looked at acpi_pci_osc_control_set()?
What it does is analogous to what you are proposing, but a bit
different, and I would like to preserve consistency between _OSC use
cases.
So would it be possible to adjust the _SB _OSC evaluation flow to
follow the PCI _OSC one? That is, if any control bits are there, pass
them along with the last evaluation of _OSC with the query flag clear.
Or is the latter defective and if so then why?
Basically the only difference is another line cloning OSC_CONTROL_DWORD from
capbuf_ret to capbuf?
Yes, this actually sounds like it better adheres to the spec to me.
Quoting spec:
" If the OS is granted control of a feature in the Control Field in one call to
_OSC, then it must preserve the set state of that bit (requesting that feature)
in all subsequent calls."
quoted
quoted
quoted
and this is going to cause problems with the USB4 CM (Connection
Manager) switch that is going to commit the switch only when the OS
requests control over the feature.
For this reason modify the _OSC support so that we first execute it with
query bit set, then use the returned valu as base of the features we
s/valu/value/
quoted
want to control and run the _OSC again with query bit clear.
Also rename the function to better match what it does.
Cc: Rafael J. Wysocki <redacted>
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/acpi/bus.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
- }
+
+ if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
+ return;
+
+ capbuf_ret = context.ret.pointer;
+ if (context.ret.length <= OSC_SUPPORT_DWORD) {
kfree(context.ret.pointer);
+ return;
}
- /* do we need to check other returned cap? Sounds no */
+
+ /*
+ * Now run _OSC again with query flag clean and with the caps
s/clean/clear/
quoted
+ * both platform and OS supports.
s/both platform and OS supports/supported by both the OS and the platform/
@@ -1168,7 +1187,7 @@ static int __init acpi_bus_init(void) * _OSC method may exist in module level code, * so it must be run after ACPI_FULL_INITIALIZATION */- acpi_bus_osc_support();+ acpi_bus_osc_negotiate_platform_control(); /* * _PDC control method may load dynamic SSDT tables,--
From: "Rafael J. Wysocki" <rafael@kernel.org> Date: 2021-01-27 13:51:52
On Wed, Jan 27, 2021 at 1:49 PM Mika Westerberg
[off-list ref] wrote:
On Tue, Jan 26, 2021 at 10:43:32PM +0000, Limonciello, Mario wrote:
quoted
quoted
I would put that information into the changelog.
Thanks, @Mika Westerberg can you collapse that in when you re-spin the
series?
Sure.
quoted
quoted
Moreover, have you looked at acpi_pci_osc_control_set()?
What it does is analogous to what you are proposing, but a bit
different, and I would like to preserve consistency between _OSC use
cases.
So would it be possible to adjust the _SB _OSC evaluation flow to
follow the PCI _OSC one? That is, if any control bits are there, pass
them along with the last evaluation of _OSC with the query flag clear.
Or is the latter defective and if so then why?
Basically the only difference is another line cloning OSC_CONTROL_DWORD from
capbuf_ret to capbuf?
Yes, this actually sounds like it better adheres to the spec to me.
Quoting spec:
" If the OS is granted control of a feature in the Control Field in one call to
_OSC, then it must preserve the set state of that bit (requesting that feature)
in all subsequent calls."
However, the platform wide _OSC does not actually have this
OSC_CONTROL_DWORD at all ;-)
Right.
I think what we do in this patch is already equivalent to what the PCI
_OSC is doing:
1. Query bit set _OSC
2. Take the returned OSC_SUPPORT_DWORD buffer and
3. Pass it to the _OSC with query bit clear.
Yes, it is.
Given the way the USB4 _OSC protocol is defined (which admittedly
confused me somewhat), the code changes in this patch are fine by me.
Thanks and sorry for the confusion.
From: Mika Westerberg <mika.westerberg@linux.intel.com> Date: 2021-01-28 12:38:33
On Tue, Jan 26, 2021 at 06:57:18PM +0300, Mika Westerberg wrote:
From: Mario Limonciello <redacted>
When we walk up the device hierarchy in tb_acpi_add_link() make sure we
break the loop if the device has no parent. Otherwise we may crash the
kernel by dereferencing a NULL pointer.
Fixes: b2be2b05cf3b ("thunderbolt: Create device links from ACPI description")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <redacted>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Applied this one separately to thunderbolt.git/fixes.