tree: https://git.kernel.org/pub/scm/virt/kvm/kvm.git queue head: da0fb9f3d73e7ab266d72a9b216ce0f3833c1e83 commit: 7360e4b14350a3a461645e0413ce58fbc8785fd8 [19/111] crypto: ccp: Implement SEV_PEK_CERT_IMPORT ioctl command reproduce: # apt-get install sparse git checkout 7360e4b14350a3a461645e0413ce58fbc8785fd8 make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) drivers/crypto/ccp/psp-dev.c:214:53: sparse: Using plain integer as NULL pointer drivers/crypto/ccp/psp-dev.c:274:59: sparse: Using plain integer as NULL pointer drivers/crypto/ccp/psp-dev.c:302:41: sparse: Using plain integer as NULL pointer drivers/crypto/ccp/psp-dev.c:324:14: sparse: incorrect type in argument 1 (different base types) @@ expected void const volatile @@ got unsigned long lonvoid const volatile @@ drivers/crypto/ccp/psp-dev.c:324:14: expected void const volatile drivers/crypto/ccp/psp-dev.c:324:14: got unsigned long long address drivers/crypto/ccp/psp-dev.c:530:45: sparse: Using plain integer as NULL pointer >> drivers/crypto/ccp/psp-dev.c:372:14: sparse: dereference of noderef expression drivers/crypto/ccp/psp-dev.c:383:60: sparse: dereference of noderef expression vim +372 drivers/crypto/ccp/psp-dev.c 209 210 static int __sev_platform_shutdown_locked(int *error) 211 { 212 int ret; 213 > 214 ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, 0, error); 215 if (ret) 216 return ret; 217 218 psp_master->sev_state = SEV_STATE_UNINIT; 219 dev_dbg(psp_master->dev, "SEV firmware shutdown\n"); 220 221 return ret; 222 } 223 224 static int sev_platform_shutdown(int *error) 225 { 226 int rc; 227 228 mutex_lock(&sev_cmd_mutex); 229 rc = __sev_platform_shutdown_locked(NULL); 230 mutex_unlock(&sev_cmd_mutex); 231 232 return rc; 233 } 234 235 static int sev_get_platform_state(int *state, int *error) 236 { 237 int rc; 238 239 rc = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, 240 &psp_master->status_cmd_buf, error); 241 if (rc) 242 return rc; 243 244 *state = psp_master->status_cmd_buf.state; 245 return rc; 246 } 247 248 static int sev_ioctl_do_reset(struct sev_issue_cmd *argp) 249 { 250 int state, rc; 251 252 /* 253 * The SEV spec requires that FACTORY_RESET must be issued in 254 * UNINIT state. Before we go further lets check if any guest is 255 * active. 256 * 257 * If FW is in WORKING state then deny the request otherwise issue 258 * SHUTDOWN command do INIT -> UNINIT before issuing the FACTORY_RESET. 259 * 260 */ 261 rc = sev_get_platform_state(&state, &argp->error); 262 if (rc) 263 return rc; 264 265 if (state == SEV_STATE_WORKING) 266 return -EBUSY; 267 268 if (state == SEV_STATE_INIT) { 269 rc = __sev_platform_shutdown_locked(&argp->error); 270 if (rc) 271 return rc; 272 } 273 274 return __sev_do_cmd_locked(SEV_CMD_FACTORY_RESET, 0, &argp->error); 275 } 276 277 static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp) 278 { 279 struct sev_user_data_status *data = &psp_master->status_cmd_buf; 280 int ret; 281 282 ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, data, &argp->error); 283 if (ret) 284 return ret; 285 286 if (copy_to_user((void __user *)argp->data, data, sizeof(*data))) 287 ret = -EFAULT; 288 289 return ret; 290 } 291 292 static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp) 293 { 294 int rc; 295 296 if (psp_master->sev_state == SEV_STATE_UNINIT) { 297 rc = __sev_platform_init_locked(&argp->error); 298 if (rc) 299 return rc; 300 } 301 302 return __sev_do_cmd_locked(cmd, 0, &argp->error); 303 } 304 305 static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp) 306 { 307 struct sev_user_data_pek_csr input; 308 struct sev_data_pek_csr *data; 309 void *blob = NULL; 310 int ret; 311 312 if (copy_from_user(&input, (void __user *)argp->data, sizeof(input))) 313 return -EFAULT; 314 315 data = kzalloc(sizeof(*data), GFP_KERNEL); 316 if (!data) 317 return -ENOMEM; 318 319 /* userspace wants to query CSR length */ 320 if (!input.address || !input.length) 321 goto cmd; 322 323 /* allocate a physically contiguous buffer to store the CSR blob */ 324 if (!access_ok(VERIFY_WRITE, input.address, input.length) || 325 input.length > SEV_FW_BLOB_MAX_SIZE) { 326 ret = -EFAULT; 327 goto e_free; 328 } 329 330 blob = kmalloc(input.length, GFP_KERNEL); 331 if (!blob) { 332 ret = -ENOMEM; 333 goto e_free; 334 } 335 336 data->address = __psp_pa(blob); 337 data->len = input.length; 338 339 cmd: 340 if (psp_master->sev_state == SEV_STATE_UNINIT) { 341 ret = __sev_platform_init_locked(&argp->error); 342 if (ret) 343 goto e_free_blob; 344 } 345 346 ret = __sev_do_cmd_locked(SEV_CMD_PEK_CSR, data, &argp->error); 347 348 /* If we query the CSR length, FW responded with expected data. */ 349 input.length = data->len; 350 351 if (copy_to_user((void __user *)argp->data, &input, sizeof(input))) { 352 ret = -EFAULT; 353 goto e_free_blob; 354 } 355 356 if (blob) { 357 if (copy_to_user((void __user *)input.address, blob, input.length)) 358 ret = -EFAULT; 359 } 360 361 e_free_blob: 362 kfree(blob); 363 e_free: 364 kfree(data); 365 return ret; 366 } 367 368 void *psp_copy_user_blob(u64 __user uaddr, u32 len) 369 { 370 void *data; 371 > 372 if (!uaddr || !len) 373 return ERR_PTR(-EINVAL); 374 375 /* verify that blob length does not exceed our limit */ 376 if (len > SEV_FW_BLOB_MAX_SIZE) 377 return ERR_PTR(-EINVAL); 378 379 data = kmalloc(len, GFP_KERNEL); 380 if (!data) 381 return ERR_PTR(-ENOMEM); 382 383 if (copy_from_user(data, (void __user *)(uintptr_t)uaddr, len)) 384 goto e_free; 385 386 return data; 387 388 e_free: 389 kfree(data); 390 return ERR_PTR(-EFAULT); 391 } 392 EXPORT_SYMBOL_GPL(psp_copy_user_blob); 393 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation