Skip to content

Commit 67322d3

Browse files
committed
Merge tag 'drm-xe-next-2025-05-08' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next
UAPI Changes: - Expose PCIe link downgrade attributes (Raag) Cross-subsystem Changes: Core Changes: - gpusvm has_dma_mapping fix (Dafna) Driver Changes: - Forcewake hold fix (Tejas) - Fix guc_info debugfs for VFs (Daniele) - Fix devcoredump chunk alignment calculation (Arnd) - Don't print timedout job message on killed exec queues (Matt Brost) - Don't flush the GSC worker from the reset path (Daniele) - Use copy_from_user() instead of __copy_from_user() (Harish) - Only flush SVM garbage collector if CONFIG_DRM_XE_GPUSVM (Shuicheng) - Fix forcewake vs runtime pm ref release ordering (Shuicheng) - Move xe_device_sysfs_init() to xe_device_probe() (Raag) - Append PCIe Gen5 limitations to xe_firmware document (Raag) Signed-off-by: Dave Airlie <[email protected]> From: Thomas Hellstrom <[email protected]> Link: https://lore.kernel.org/r/aBzUwbzCzz7Qo7fA@fedora
2 parents 8d782ad + 252c471 commit 67322d3

25 files changed

+242
-69
lines changed

Documentation/gpu/xe/xe_firmware.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ GuC Power Conservation (PC)
3131
.. kernel-doc:: drivers/gpu/drm/xe/xe_guc_pc.c
3232
:doc: GuC Power Conservation (PC)
3333

34+
PCIe Gen5 Limitations
35+
=====================
36+
37+
.. kernel-doc:: drivers/gpu/drm/xe/xe_device_sysfs.c
38+
:doc: PCIe Gen5 Limitations
39+
3440
Internal API
3541
============
3642

drivers/gpu/drm/xe/tests/xe_mocs.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,11 @@ static void read_l3cc_table(struct xe_gt *gt,
4646
unsigned int fw_ref, i;
4747
u32 reg_val;
4848

49-
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
50-
KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
49+
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
50+
if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) {
51+
xe_force_wake_put(gt_to_fw(gt), fw_ref);
52+
KUNIT_ASSERT_TRUE_MSG(test, true, "Forcewake Failed.\n");
53+
}
5154

5255
for (i = 0; i < info->num_mocs_regs; i++) {
5356
if (!(i & 1)) {

drivers/gpu/drm/xe/xe_bo.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,7 +2569,7 @@ static int gem_create_user_ext_set_property(struct xe_device *xe,
25692569
int err;
25702570
u32 idx;
25712571

2572-
err = __copy_from_user(&ext, address, sizeof(ext));
2572+
err = copy_from_user(&ext, address, sizeof(ext));
25732573
if (XE_IOCTL_DBG(xe, err))
25742574
return -EFAULT;
25752575

@@ -2606,7 +2606,7 @@ static int gem_create_user_extensions(struct xe_device *xe, struct xe_bo *bo,
26062606
if (XE_IOCTL_DBG(xe, ext_number >= MAX_USER_EXTENSIONS))
26072607
return -E2BIG;
26082608

2609-
err = __copy_from_user(&ext, address, sizeof(ext));
2609+
err = copy_from_user(&ext, address, sizeof(ext));
26102610
if (XE_IOCTL_DBG(xe, err))
26112611
return -EFAULT;
26122612

drivers/gpu/drm/xe/xe_devcoredump.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
177177
struct xe_devcoredump *coredump = data;
178178
struct xe_devcoredump_snapshot *ss;
179179
ssize_t byte_copied;
180+
u32 chunk_offset;
181+
ssize_t new_chunk_position;
180182

181183
if (!coredump)
182184
return -ENODEV;
@@ -201,10 +203,14 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
201203
return 0;
202204
}
203205

206+
new_chunk_position = div_u64_rem(offset,
207+
XE_DEVCOREDUMP_CHUNK_MAX,
208+
&chunk_offset);
209+
204210
if (offset >= ss->read.chunk_position + XE_DEVCOREDUMP_CHUNK_MAX ||
205211
offset < ss->read.chunk_position) {
206-
ss->read.chunk_position =
207-
ALIGN_DOWN(offset, XE_DEVCOREDUMP_CHUNK_MAX);
212+
ss->read.chunk_position = new_chunk_position *
213+
XE_DEVCOREDUMP_CHUNK_MAX;
208214

209215
__xe_devcoredump_read(ss->read.buffer,
210216
XE_DEVCOREDUMP_CHUNK_MAX,
@@ -213,8 +219,7 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
213219

214220
byte_copied = count < ss->read.size - offset ? count :
215221
ss->read.size - offset;
216-
memcpy(buffer, ss->read.buffer +
217-
(offset % XE_DEVCOREDUMP_CHUNK_MAX), byte_copied);
222+
memcpy(buffer, ss->read.buffer + chunk_offset, byte_copied);
218223

219224
mutex_unlock(&coredump->lock);
220225

drivers/gpu/drm/xe/xe_device.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "xe_bo_evict.h"
2727
#include "xe_debugfs.h"
2828
#include "xe_devcoredump.h"
29+
#include "xe_device_sysfs.h"
2930
#include "xe_dma_buf.h"
3031
#include "xe_drm_client.h"
3132
#include "xe_drv.h"
@@ -915,6 +916,10 @@ int xe_device_probe(struct xe_device *xe)
915916
if (err)
916917
goto err_unregister_display;
917918

919+
err = xe_device_sysfs_init(xe);
920+
if (err)
921+
goto err_unregister_display;
922+
918923
xe_debugfs_register(xe);
919924

920925
err = xe_hwmon_register(xe);

drivers/gpu/drm/xe/xe_device_sysfs.c

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
* Copyright © 2023 Intel Corporation
44
*/
55

6+
#include <linux/device.h>
67
#include <linux/kobject.h>
78
#include <linux/pci.h>
89
#include <linux/sysfs.h>
910

10-
#include <drm/drm_managed.h>
11-
1211
#include "xe_device.h"
1312
#include "xe_device_sysfs.h"
13+
#include "xe_mmio.h"
14+
#include "xe_pcode_api.h"
15+
#include "xe_pcode.h"
1416
#include "xe_pm.h"
1517

1618
/**
@@ -63,21 +65,111 @@ vram_d3cold_threshold_store(struct device *dev, struct device_attribute *attr,
6365

6466
static DEVICE_ATTR_RW(vram_d3cold_threshold);
6567

68+
/**
69+
* DOC: PCIe Gen5 Limitations
70+
*
71+
* Default link speed of discrete GPUs is determined by configuration parameters
72+
* stored in their flash memory, which are subject to override through user
73+
* initiated firmware updates. It has been observed that devices configured with
74+
* PCIe Gen5 as their default link speed can come across link quality issues due
75+
* to host or motherboard limitations and may have to auto-downgrade their link
76+
* to PCIe Gen4 speed when faced with unstable link at Gen5, which makes
77+
* firmware updates rather risky on such setups. It is required to ensure that
78+
* the device is capable of auto-downgrading its link to PCIe Gen4 speed before
79+
* pushing the firmware image with PCIe Gen5 as default configuration. This can
80+
* be done by reading ``auto_link_downgrade_capable`` sysfs entry, which will
81+
* denote if the device is capable of auto-downgrading its link to PCIe Gen4
82+
* speed with boolean output value of ``0`` or ``1``, meaning `incapable` or
83+
* `capable` respectively.
84+
*
85+
* .. code-block:: shell
86+
*
87+
* $ cat /sys/bus/pci/devices/<bdf>/auto_link_downgrade_capable
88+
*
89+
* Pushing the firmware image with PCIe Gen5 as default configuration on a auto
90+
* link downgrade incapable device and facing link instability due to host or
91+
* motherboard limitations can result in driver failing to bind to the device,
92+
* making further firmware updates impossible with RMA being the only last
93+
* resort.
94+
*
95+
* Link downgrade status of auto link downgrade capable devices is available
96+
* through ``auto_link_downgrade_status`` sysfs entry with boolean output value
97+
* of ``0`` or ``1``, where ``0`` means no auto-downgrading was required during
98+
* link training (which is the optimal scenario) and ``1`` means the device has
99+
* auto-downgraded its link to PCIe Gen4 speed due to unstable Gen5 link.
100+
*
101+
* .. code-block:: shell
102+
*
103+
* $ cat /sys/bus/pci/devices/<bdf>/auto_link_downgrade_status
104+
*/
105+
106+
static ssize_t
107+
auto_link_downgrade_capable_show(struct device *dev, struct device_attribute *attr, char *buf)
108+
{
109+
struct pci_dev *pdev = to_pci_dev(dev);
110+
struct xe_device *xe = pdev_to_xe_device(pdev);
111+
u32 cap, val;
112+
113+
xe_pm_runtime_get(xe);
114+
val = xe_mmio_read32(xe_root_tile_mmio(xe), BMG_PCIE_CAP);
115+
xe_pm_runtime_put(xe);
116+
117+
cap = REG_FIELD_GET(LINK_DOWNGRADE, val);
118+
return sysfs_emit(buf, "%u\n", cap == DOWNGRADE_CAPABLE ? true : false);
119+
}
120+
static DEVICE_ATTR_ADMIN_RO(auto_link_downgrade_capable);
121+
122+
static ssize_t
123+
auto_link_downgrade_status_show(struct device *dev, struct device_attribute *attr, char *buf)
124+
{
125+
struct pci_dev *pdev = to_pci_dev(dev);
126+
struct xe_device *xe = pdev_to_xe_device(pdev);
127+
u32 val;
128+
int ret;
129+
130+
xe_pm_runtime_get(xe);
131+
ret = xe_pcode_read(xe_device_get_root_tile(xe),
132+
PCODE_MBOX(DGFX_PCODE_STATUS, DGFX_GET_INIT_STATUS, 0),
133+
&val, NULL);
134+
xe_pm_runtime_put(xe);
135+
136+
return ret ?: sysfs_emit(buf, "%u\n", REG_FIELD_GET(DGFX_LINK_DOWNGRADE_STATUS, val));
137+
}
138+
static DEVICE_ATTR_ADMIN_RO(auto_link_downgrade_status);
139+
140+
static const struct attribute *auto_link_downgrade_attrs[] = {
141+
&dev_attr_auto_link_downgrade_capable.attr,
142+
&dev_attr_auto_link_downgrade_status.attr,
143+
NULL
144+
};
145+
66146
static void xe_device_sysfs_fini(void *arg)
67147
{
68148
struct xe_device *xe = arg;
69149

70-
sysfs_remove_file(&xe->drm.dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
150+
if (xe->d3cold.capable)
151+
sysfs_remove_file(&xe->drm.dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
152+
153+
if (xe->info.platform == XE_BATTLEMAGE)
154+
sysfs_remove_files(&xe->drm.dev->kobj, auto_link_downgrade_attrs);
71155
}
72156

73157
int xe_device_sysfs_init(struct xe_device *xe)
74158
{
75159
struct device *dev = xe->drm.dev;
76160
int ret;
77161

78-
ret = sysfs_create_file(&dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
79-
if (ret)
80-
return ret;
162+
if (xe->d3cold.capable) {
163+
ret = sysfs_create_file(&dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
164+
if (ret)
165+
return ret;
166+
}
167+
168+
if (xe->info.platform == XE_BATTLEMAGE) {
169+
ret = sysfs_create_files(&dev->kobj, auto_link_downgrade_attrs);
170+
if (ret)
171+
return ret;
172+
}
81173

82174
return devm_add_action_or_reset(dev, xe_device_sysfs_fini, xe);
83175
}

drivers/gpu/drm/xe/xe_eu_stall.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ static int xe_eu_stall_user_ext_set_property(struct xe_device *xe, u64 extension
283283
int err;
284284
u32 idx;
285285

286-
err = __copy_from_user(&ext, address, sizeof(ext));
286+
err = copy_from_user(&ext, address, sizeof(ext));
287287
if (XE_IOCTL_DBG(xe, err))
288288
return -EFAULT;
289289

@@ -313,7 +313,7 @@ static int xe_eu_stall_user_extensions(struct xe_device *xe, u64 extension,
313313
if (XE_IOCTL_DBG(xe, ext_number >= MAX_USER_EXTENSIONS))
314314
return -E2BIG;
315315

316-
err = __copy_from_user(&ext, address, sizeof(ext));
316+
err = copy_from_user(&ext, address, sizeof(ext));
317317
if (XE_IOCTL_DBG(xe, err))
318318
return -EFAULT;
319319

drivers/gpu/drm/xe/xe_exec.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
176176
}
177177

178178
if (xe_exec_queue_is_parallel(q)) {
179-
err = __copy_from_user(addresses, addresses_user, sizeof(u64) *
180-
q->width);
179+
err = copy_from_user(addresses, addresses_user, sizeof(u64) *
180+
q->width);
181181
if (err) {
182182
err = -EFAULT;
183183
goto err_syncs;

drivers/gpu/drm/xe/xe_exec_queue.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ static int exec_queue_user_ext_set_property(struct xe_device *xe,
479479
int err;
480480
u32 idx;
481481

482-
err = __copy_from_user(&ext, address, sizeof(ext));
482+
err = copy_from_user(&ext, address, sizeof(ext));
483483
if (XE_IOCTL_DBG(xe, err))
484484
return -EFAULT;
485485

@@ -518,7 +518,7 @@ static int exec_queue_user_extensions(struct xe_device *xe, struct xe_exec_queue
518518
if (XE_IOCTL_DBG(xe, ext_number >= MAX_USER_EXTENSIONS))
519519
return -E2BIG;
520520

521-
err = __copy_from_user(&ext, address, sizeof(ext));
521+
err = copy_from_user(&ext, address, sizeof(ext));
522522
if (XE_IOCTL_DBG(xe, err))
523523
return -EFAULT;
524524

@@ -618,9 +618,8 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data,
618618
if (XE_IOCTL_DBG(xe, !len || len > XE_HW_ENGINE_MAX_INSTANCE))
619619
return -EINVAL;
620620

621-
err = __copy_from_user(eci, user_eci,
622-
sizeof(struct drm_xe_engine_class_instance) *
623-
len);
621+
err = copy_from_user(eci, user_eci,
622+
sizeof(struct drm_xe_engine_class_instance) * len);
624623
if (XE_IOCTL_DBG(xe, err))
625624
return -EFAULT;
626625

drivers/gpu/drm/xe/xe_gsc.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,28 @@ void xe_gsc_wait_for_worker_completion(struct xe_gsc *gsc)
555555
flush_work(&gsc->work);
556556
}
557557

558+
void xe_gsc_stop_prepare(struct xe_gsc *gsc)
559+
{
560+
struct xe_gt *gt = gsc_to_gt(gsc);
561+
int ret;
562+
563+
if (!xe_uc_fw_is_loadable(&gsc->fw) || xe_uc_fw_is_in_error_state(&gsc->fw))
564+
return;
565+
566+
xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GSC);
567+
568+
/*
569+
* If the GSC FW load or the proxy init are interrupted, the only way
570+
* to recover it is to do an FLR and reload the GSC from scratch.
571+
* Therefore, let's wait for the init to complete before stopping
572+
* operations. The proxy init is the last step, so we can just wait on
573+
* that
574+
*/
575+
ret = xe_gsc_wait_for_proxy_init_done(gsc);
576+
if (ret)
577+
xe_gt_err(gt, "failed to wait for GSC init completion before uc stop\n");
578+
}
579+
558580
/*
559581
* wa_14015076503: if the GSC FW is loaded, we need to alert it before doing a
560582
* GSC engine reset by writing a notification bit in the GS1 register and then

0 commit comments

Comments
 (0)