Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe/gsc: Improve SW proxy error checking and logging

If an error occurs in the GSC<->CSME handshake, the GSC will send a
PROXY_END msg to the driver with the status set to an error code. We
currently don't check the status when receiving a PROXY_END message and
instead check the proxy initialization status in the FWSTS reg;
therefore, while still catching any initialization failures, we lose the
actual returned error code. This can be easily improved by checking the
status value and printing it to dmesg if it's an error.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Reviewed-by: Alan Previn <alan.previn.teres.alexis@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241106002402.486700-1-daniele.ceraolospurio@intel.com

+36 -11
+36 -11
drivers/gpu/drm/xe/xe_gsc_proxy.c
··· 139 139 return 0; 140 140 } 141 141 142 - static int validate_proxy_header(struct xe_gsc_proxy_header *header, 142 + static int validate_proxy_header(struct xe_gt *gt, 143 + struct xe_gsc_proxy_header *header, 143 144 u32 source, u32 dest, u32 max_size) 144 145 { 145 146 u32 type = FIELD_GET(GSC_PROXY_TYPE, header->hdr); 146 147 u32 length = FIELD_GET(GSC_PROXY_PAYLOAD_LENGTH, header->hdr); 148 + int ret = 0; 147 149 148 - if (header->destination != dest || header->source != source) 149 - return -ENOEXEC; 150 + if (header->destination != dest || header->source != source) { 151 + ret = -ENOEXEC; 152 + goto out; 153 + } 150 154 151 - if (length + PROXY_HDR_SIZE > max_size) 152 - return -E2BIG; 155 + if (length + PROXY_HDR_SIZE > max_size) { 156 + ret = -E2BIG; 157 + goto out; 158 + } 159 + 160 + /* We only care about the status if this is a message for the driver */ 161 + if (dest == GSC_PROXY_ADDRESSING_KMD && header->status != 0) { 162 + ret = -EIO; 163 + goto out; 164 + } 153 165 154 166 switch (type) { 155 167 case GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD: ··· 169 157 break; 170 158 fallthrough; 171 159 case GSC_PROXY_MSG_TYPE_PROXY_INVALID: 172 - return -EIO; 160 + ret = -EIO; 161 + break; 173 162 default: 174 163 break; 175 164 } 176 165 177 - return 0; 166 + out: 167 + if (ret) 168 + xe_gt_err(gt, 169 + "GSC proxy error: s=0x%x[0x%x], d=0x%x[0x%x], t=%u, l=0x%x, st=0x%x\n", 170 + header->source, source, header->destination, dest, 171 + type, length, header->status); 172 + 173 + return ret; 178 174 } 179 175 180 176 #define proxy_header_wr(xe_, map_, offset_, field_, val_) \ ··· 248 228 xe_map_memcpy_from(xe, to_csme_hdr, &gsc->proxy.from_gsc, 249 229 reply_offset, PROXY_HDR_SIZE); 250 230 251 - /* stop if this was the last message */ 252 - if (FIELD_GET(GSC_PROXY_TYPE, to_csme_hdr->hdr) == GSC_PROXY_MSG_TYPE_PROXY_END) 231 + /* Check the status and stop if this was the last message */ 232 + if (FIELD_GET(GSC_PROXY_TYPE, to_csme_hdr->hdr) == GSC_PROXY_MSG_TYPE_PROXY_END) { 233 + ret = validate_proxy_header(gt, to_csme_hdr, 234 + GSC_PROXY_ADDRESSING_GSC, 235 + GSC_PROXY_ADDRESSING_KMD, 236 + GSC_PROXY_BUFFER_SIZE - reply_offset); 253 237 break; 238 + } 254 239 255 240 /* make sure the GSC-to-CSME proxy header is sane */ 256 - ret = validate_proxy_header(to_csme_hdr, 241 + ret = validate_proxy_header(gt, to_csme_hdr, 257 242 GSC_PROXY_ADDRESSING_GSC, 258 243 GSC_PROXY_ADDRESSING_CSME, 259 244 GSC_PROXY_BUFFER_SIZE - reply_offset); ··· 287 262 } 288 263 289 264 /* make sure the CSME-to-GSC proxy header is sane */ 290 - ret = validate_proxy_header(gsc->proxy.from_csme, 265 + ret = validate_proxy_header(gt, gsc->proxy.from_csme, 291 266 GSC_PROXY_ADDRESSING_CSME, 292 267 GSC_PROXY_ADDRESSING_GSC, 293 268 GSC_PROXY_BUFFER_SIZE - reply_offset);