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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto fixes from Herbert Xu:
"This fixes the following issues:

- racy use of ctx->rcvused in af_alg

- algif_aead crash in chacha20poly1305

- freeing bogus pointer in pcrypt

- build error on MIPS in mpi

- memory leak in inside-secure

- memory overwrite in inside-secure

- NULL pointer dereference in inside-secure

- state corruption in inside-secure

- build error without CRYPTO_GF128MUL in chelsio

- use after free in n2"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: inside-secure - do not use areq->result for partial results
crypto: inside-secure - fix request allocations in invalidation path
crypto: inside-secure - free requests even if their handling failed
crypto: inside-secure - per request invalidation
lib/mpi: Fix umul_ppmm() for MIPS64r6
crypto: pcrypt - fix freeing pcrypt instances
crypto: n2 - cure use after free
crypto: af_alg - Fix race around ctx->rcvused by making it atomic_t
crypto: chacha20poly1305 - validate the digest size
crypto: chelsio - select CRYPTO_GF128MUL

+173 -62
+2 -2
crypto/af_alg.c
··· 664 664 unsigned int i; 665 665 666 666 list_for_each_entry_safe(rsgl, tmp, &areq->rsgl_list, list) { 667 - ctx->rcvused -= rsgl->sg_num_bytes; 667 + atomic_sub(rsgl->sg_num_bytes, &ctx->rcvused); 668 668 af_alg_free_sg(&rsgl->sgl); 669 669 list_del(&rsgl->list); 670 670 if (rsgl != &areq->first_rsgl) ··· 1163 1163 1164 1164 areq->last_rsgl = rsgl; 1165 1165 len += err; 1166 - ctx->rcvused += err; 1166 + atomic_add(err, &ctx->rcvused); 1167 1167 rsgl->sg_num_bytes = err; 1168 1168 iov_iter_advance(&msg->msg_iter, err); 1169 1169 }
+1 -1
crypto/algif_aead.c
··· 571 571 INIT_LIST_HEAD(&ctx->tsgl_list); 572 572 ctx->len = len; 573 573 ctx->used = 0; 574 - ctx->rcvused = 0; 574 + atomic_set(&ctx->rcvused, 0); 575 575 ctx->more = 0; 576 576 ctx->merge = 0; 577 577 ctx->enc = 0;
+1 -1
crypto/algif_skcipher.c
··· 390 390 INIT_LIST_HEAD(&ctx->tsgl_list); 391 391 ctx->len = len; 392 392 ctx->used = 0; 393 - ctx->rcvused = 0; 393 + atomic_set(&ctx->rcvused, 0); 394 394 ctx->more = 0; 395 395 ctx->merge = 0; 396 396 ctx->enc = 0;
+5 -1
crypto/chacha20poly1305.c
··· 610 610 algt->mask)); 611 611 if (IS_ERR(poly)) 612 612 return PTR_ERR(poly); 613 + poly_hash = __crypto_hash_alg_common(poly); 614 + 615 + err = -EINVAL; 616 + if (poly_hash->digestsize != POLY1305_DIGEST_SIZE) 617 + goto out_put_poly; 613 618 614 619 err = -ENOMEM; 615 620 inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); ··· 623 618 624 619 ctx = aead_instance_ctx(inst); 625 620 ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize; 626 - poly_hash = __crypto_hash_alg_common(poly); 627 621 err = crypto_init_ahash_spawn(&ctx->poly, poly_hash, 628 622 aead_crypto_instance(inst)); 629 623 if (err)
+10 -9
crypto/pcrypt.c
··· 254 254 crypto_free_aead(ctx->child); 255 255 } 256 256 257 + static void pcrypt_free(struct aead_instance *inst) 258 + { 259 + struct pcrypt_instance_ctx *ctx = aead_instance_ctx(inst); 260 + 261 + crypto_drop_aead(&ctx->spawn); 262 + kfree(inst); 263 + } 264 + 257 265 static int pcrypt_init_instance(struct crypto_instance *inst, 258 266 struct crypto_alg *alg) 259 267 { ··· 327 319 inst->alg.encrypt = pcrypt_aead_encrypt; 328 320 inst->alg.decrypt = pcrypt_aead_decrypt; 329 321 322 + inst->free = pcrypt_free; 323 + 330 324 err = aead_register_instance(tmpl, inst); 331 325 if (err) 332 326 goto out_drop_aead; ··· 357 347 } 358 348 359 349 return -EINVAL; 360 - } 361 - 362 - static void pcrypt_free(struct crypto_instance *inst) 363 - { 364 - struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst); 365 - 366 - crypto_drop_aead(&ctx->spawn); 367 - kfree(inst); 368 350 } 369 351 370 352 static int pcrypt_cpumask_change_notify(struct notifier_block *self, ··· 471 469 static struct crypto_template pcrypt_tmpl = { 472 470 .name = "pcrypt", 473 471 .create = pcrypt_create, 474 - .free = pcrypt_free, 475 472 .module = THIS_MODULE, 476 473 }; 477 474
+1
drivers/crypto/chelsio/Kconfig
··· 5 5 select CRYPTO_SHA256 6 6 select CRYPTO_SHA512 7 7 select CRYPTO_AUTHENC 8 + select CRYPTO_GF128MUL 8 9 ---help--- 9 10 The Chelsio Crypto Co-processor driver for T6 adapters. 10 11
+1
drivers/crypto/inside-secure/safexcel.c
··· 607 607 ndesc = ctx->handle_result(priv, ring, sreq->req, 608 608 &should_complete, &ret); 609 609 if (ndesc < 0) { 610 + kfree(sreq); 610 611 dev_err(priv->dev, "failed to handle result (%d)", ndesc); 611 612 return; 612 613 }
+65 -20
drivers/crypto/inside-secure/safexcel_cipher.c
··· 14 14 15 15 #include <crypto/aes.h> 16 16 #include <crypto/skcipher.h> 17 + #include <crypto/internal/skcipher.h> 17 18 18 19 #include "safexcel.h" 19 20 ··· 32 31 33 32 __le32 key[8]; 34 33 unsigned int key_len; 34 + }; 35 + 36 + struct safexcel_cipher_req { 37 + bool needs_inv; 35 38 }; 36 39 37 40 static void safexcel_cipher_token(struct safexcel_cipher_ctx *ctx, ··· 131 126 return 0; 132 127 } 133 128 134 - static int safexcel_handle_result(struct safexcel_crypto_priv *priv, int ring, 135 - struct crypto_async_request *async, 136 - bool *should_complete, int *ret) 129 + static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 130 + struct crypto_async_request *async, 131 + bool *should_complete, int *ret) 137 132 { 138 133 struct skcipher_request *req = skcipher_request_cast(async); 139 134 struct safexcel_result_desc *rdesc; ··· 270 265 spin_unlock_bh(&priv->ring[ring].egress_lock); 271 266 272 267 request->req = &req->base; 273 - ctx->base.handle_result = safexcel_handle_result; 274 268 275 269 *commands = n_cdesc; 276 270 *results = n_rdesc; ··· 345 341 346 342 ring = safexcel_select_ring(priv); 347 343 ctx->base.ring = ring; 348 - ctx->base.needs_inv = false; 349 - ctx->base.send = safexcel_aes_send; 350 344 351 345 spin_lock_bh(&priv->ring[ring].queue_lock); 352 346 enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, async); ··· 361 359 return ndesc; 362 360 } 363 361 362 + static int safexcel_handle_result(struct safexcel_crypto_priv *priv, int ring, 363 + struct crypto_async_request *async, 364 + bool *should_complete, int *ret) 365 + { 366 + struct skcipher_request *req = skcipher_request_cast(async); 367 + struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 368 + int err; 369 + 370 + if (sreq->needs_inv) { 371 + sreq->needs_inv = false; 372 + err = safexcel_handle_inv_result(priv, ring, async, 373 + should_complete, ret); 374 + } else { 375 + err = safexcel_handle_req_result(priv, ring, async, 376 + should_complete, ret); 377 + } 378 + 379 + return err; 380 + } 381 + 364 382 static int safexcel_cipher_send_inv(struct crypto_async_request *async, 365 383 int ring, struct safexcel_request *request, 366 384 int *commands, int *results) ··· 389 367 struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 390 368 struct safexcel_crypto_priv *priv = ctx->priv; 391 369 int ret; 392 - 393 - ctx->base.handle_result = safexcel_handle_inv_result; 394 370 395 371 ret = safexcel_invalidate_cache(async, &ctx->base, priv, 396 372 ctx->base.ctxr_dma, ring, request); ··· 401 381 return 0; 402 382 } 403 383 384 + static int safexcel_send(struct crypto_async_request *async, 385 + int ring, struct safexcel_request *request, 386 + int *commands, int *results) 387 + { 388 + struct skcipher_request *req = skcipher_request_cast(async); 389 + struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 390 + int ret; 391 + 392 + if (sreq->needs_inv) 393 + ret = safexcel_cipher_send_inv(async, ring, request, 394 + commands, results); 395 + else 396 + ret = safexcel_aes_send(async, ring, request, 397 + commands, results); 398 + return ret; 399 + } 400 + 404 401 static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm) 405 402 { 406 403 struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); 407 404 struct safexcel_crypto_priv *priv = ctx->priv; 408 - struct skcipher_request req; 405 + SKCIPHER_REQUEST_ON_STACK(req, __crypto_skcipher_cast(tfm)); 406 + struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 409 407 struct safexcel_inv_result result = {}; 410 408 int ring = ctx->base.ring; 411 409 412 - memset(&req, 0, sizeof(struct skcipher_request)); 410 + memset(req, 0, sizeof(struct skcipher_request)); 413 411 414 412 /* create invalidation request */ 415 413 init_completion(&result.completion); 416 - skcipher_request_set_callback(&req, CRYPTO_TFM_REQ_MAY_BACKLOG, 417 - safexcel_inv_complete, &result); 414 + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 415 + safexcel_inv_complete, &result); 418 416 419 - skcipher_request_set_tfm(&req, __crypto_skcipher_cast(tfm)); 420 - ctx = crypto_tfm_ctx(req.base.tfm); 417 + skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm)); 418 + ctx = crypto_tfm_ctx(req->base.tfm); 421 419 ctx->base.exit_inv = true; 422 - ctx->base.send = safexcel_cipher_send_inv; 420 + sreq->needs_inv = true; 423 421 424 422 spin_lock_bh(&priv->ring[ring].queue_lock); 425 - crypto_enqueue_request(&priv->ring[ring].queue, &req.base); 423 + crypto_enqueue_request(&priv->ring[ring].queue, &req->base); 426 424 spin_unlock_bh(&priv->ring[ring].queue_lock); 427 425 428 426 if (!priv->ring[ring].need_dequeue) ··· 462 424 enum safexcel_cipher_direction dir, u32 mode) 463 425 { 464 426 struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm); 427 + struct safexcel_cipher_req *sreq = skcipher_request_ctx(req); 465 428 struct safexcel_crypto_priv *priv = ctx->priv; 466 429 int ret, ring; 467 430 431 + sreq->needs_inv = false; 468 432 ctx->direction = dir; 469 433 ctx->mode = mode; 470 434 471 435 if (ctx->base.ctxr) { 472 - if (ctx->base.needs_inv) 473 - ctx->base.send = safexcel_cipher_send_inv; 436 + if (ctx->base.needs_inv) { 437 + sreq->needs_inv = true; 438 + ctx->base.needs_inv = false; 439 + } 474 440 } else { 475 441 ctx->base.ring = safexcel_select_ring(priv); 476 - ctx->base.send = safexcel_aes_send; 477 - 478 442 ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, 479 443 EIP197_GFP_FLAGS(req->base), 480 444 &ctx->base.ctxr_dma); ··· 516 476 alg.skcipher.base); 517 477 518 478 ctx->priv = tmpl->priv; 479 + ctx->base.send = safexcel_send; 480 + ctx->base.handle_result = safexcel_handle_result; 481 + 482 + crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), 483 + sizeof(struct safexcel_cipher_req)); 519 484 520 485 return 0; 521 486 }
+64 -25
drivers/crypto/inside-secure/safexcel_hash.c
··· 32 32 bool last_req; 33 33 bool finish; 34 34 bool hmac; 35 + bool needs_inv; 35 36 36 37 u8 state_sz; /* expected sate size, only set once */ 37 - u32 state[SHA256_DIGEST_SIZE / sizeof(u32)]; 38 + u32 state[SHA256_DIGEST_SIZE / sizeof(u32)] __aligned(sizeof(u32)); 38 39 39 40 u64 len; 40 41 u64 processed; ··· 120 119 } 121 120 } 122 121 123 - static int safexcel_handle_result(struct safexcel_crypto_priv *priv, int ring, 124 - struct crypto_async_request *async, 125 - bool *should_complete, int *ret) 122 + static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring, 123 + struct crypto_async_request *async, 124 + bool *should_complete, int *ret) 126 125 { 127 126 struct safexcel_result_desc *rdesc; 128 127 struct ahash_request *areq = ahash_request_cast(async); 129 128 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq); 130 129 struct safexcel_ahash_req *sreq = ahash_request_ctx(areq); 131 - int cache_len, result_sz = sreq->state_sz; 130 + int cache_len; 132 131 133 132 *ret = 0; 134 133 ··· 149 148 spin_unlock_bh(&priv->ring[ring].egress_lock); 150 149 151 150 if (sreq->finish) 152 - result_sz = crypto_ahash_digestsize(ahash); 153 - memcpy(sreq->state, areq->result, result_sz); 151 + memcpy(areq->result, sreq->state, 152 + crypto_ahash_digestsize(ahash)); 154 153 155 154 dma_unmap_sg(priv->dev, areq->src, 156 155 sg_nents_for_len(areq->src, areq->nbytes), DMA_TO_DEVICE); ··· 166 165 return 1; 167 166 } 168 167 169 - static int safexcel_ahash_send(struct crypto_async_request *async, int ring, 170 - struct safexcel_request *request, int *commands, 171 - int *results) 168 + static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring, 169 + struct safexcel_request *request, 170 + int *commands, int *results) 172 171 { 173 172 struct ahash_request *areq = ahash_request_cast(async); 174 173 struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq); ··· 274 273 /* Add the token */ 275 274 safexcel_hash_token(first_cdesc, len, req->state_sz); 276 275 277 - ctx->base.result_dma = dma_map_single(priv->dev, areq->result, 276 + ctx->base.result_dma = dma_map_single(priv->dev, req->state, 278 277 req->state_sz, DMA_FROM_DEVICE); 279 278 if (dma_mapping_error(priv->dev, ctx->base.result_dma)) { 280 279 ret = -EINVAL; ··· 293 292 294 293 req->processed += len; 295 294 request->req = &areq->base; 296 - ctx->base.handle_result = safexcel_handle_result; 297 295 298 296 *commands = n_cdesc; 299 297 *results = 1; ··· 374 374 375 375 ring = safexcel_select_ring(priv); 376 376 ctx->base.ring = ring; 377 - ctx->base.needs_inv = false; 378 - ctx->base.send = safexcel_ahash_send; 379 377 380 378 spin_lock_bh(&priv->ring[ring].queue_lock); 381 379 enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, async); ··· 390 392 return 1; 391 393 } 392 394 395 + static int safexcel_handle_result(struct safexcel_crypto_priv *priv, int ring, 396 + struct crypto_async_request *async, 397 + bool *should_complete, int *ret) 398 + { 399 + struct ahash_request *areq = ahash_request_cast(async); 400 + struct safexcel_ahash_req *req = ahash_request_ctx(areq); 401 + int err; 402 + 403 + if (req->needs_inv) { 404 + req->needs_inv = false; 405 + err = safexcel_handle_inv_result(priv, ring, async, 406 + should_complete, ret); 407 + } else { 408 + err = safexcel_handle_req_result(priv, ring, async, 409 + should_complete, ret); 410 + } 411 + 412 + return err; 413 + } 414 + 393 415 static int safexcel_ahash_send_inv(struct crypto_async_request *async, 394 416 int ring, struct safexcel_request *request, 395 417 int *commands, int *results) ··· 418 400 struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq)); 419 401 int ret; 420 402 421 - ctx->base.handle_result = safexcel_handle_inv_result; 422 403 ret = safexcel_invalidate_cache(async, &ctx->base, ctx->priv, 423 404 ctx->base.ctxr_dma, ring, request); 424 405 if (unlikely(ret)) ··· 429 412 return 0; 430 413 } 431 414 415 + static int safexcel_ahash_send(struct crypto_async_request *async, 416 + int ring, struct safexcel_request *request, 417 + int *commands, int *results) 418 + { 419 + struct ahash_request *areq = ahash_request_cast(async); 420 + struct safexcel_ahash_req *req = ahash_request_ctx(areq); 421 + int ret; 422 + 423 + if (req->needs_inv) 424 + ret = safexcel_ahash_send_inv(async, ring, request, 425 + commands, results); 426 + else 427 + ret = safexcel_ahash_send_req(async, ring, request, 428 + commands, results); 429 + return ret; 430 + } 431 + 432 432 static int safexcel_ahash_exit_inv(struct crypto_tfm *tfm) 433 433 { 434 434 struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); 435 435 struct safexcel_crypto_priv *priv = ctx->priv; 436 - struct ahash_request req; 436 + AHASH_REQUEST_ON_STACK(req, __crypto_ahash_cast(tfm)); 437 + struct safexcel_ahash_req *rctx = ahash_request_ctx(req); 437 438 struct safexcel_inv_result result = {}; 438 439 int ring = ctx->base.ring; 439 440 440 - memset(&req, 0, sizeof(struct ahash_request)); 441 + memset(req, 0, sizeof(struct ahash_request)); 441 442 442 443 /* create invalidation request */ 443 444 init_completion(&result.completion); 444 - ahash_request_set_callback(&req, CRYPTO_TFM_REQ_MAY_BACKLOG, 445 + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 445 446 safexcel_inv_complete, &result); 446 447 447 - ahash_request_set_tfm(&req, __crypto_ahash_cast(tfm)); 448 - ctx = crypto_tfm_ctx(req.base.tfm); 448 + ahash_request_set_tfm(req, __crypto_ahash_cast(tfm)); 449 + ctx = crypto_tfm_ctx(req->base.tfm); 449 450 ctx->base.exit_inv = true; 450 - ctx->base.send = safexcel_ahash_send_inv; 451 + rctx->needs_inv = true; 451 452 452 453 spin_lock_bh(&priv->ring[ring].queue_lock); 453 - crypto_enqueue_request(&priv->ring[ring].queue, &req.base); 454 + crypto_enqueue_request(&priv->ring[ring].queue, &req->base); 454 455 spin_unlock_bh(&priv->ring[ring].queue_lock); 455 456 456 457 if (!priv->ring[ring].need_dequeue) ··· 516 481 struct safexcel_crypto_priv *priv = ctx->priv; 517 482 int ret, ring; 518 483 519 - ctx->base.send = safexcel_ahash_send; 484 + req->needs_inv = false; 520 485 521 486 if (req->processed && ctx->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED) 522 487 ctx->base.needs_inv = safexcel_ahash_needs_inv_get(areq); 523 488 524 489 if (ctx->base.ctxr) { 525 - if (ctx->base.needs_inv) 526 - ctx->base.send = safexcel_ahash_send_inv; 490 + if (ctx->base.needs_inv) { 491 + ctx->base.needs_inv = false; 492 + req->needs_inv = true; 493 + } 527 494 } else { 528 495 ctx->base.ring = safexcel_select_ring(priv); 529 496 ctx->base.ctxr = dma_pool_zalloc(priv->context_pool, ··· 659 622 struct safexcel_alg_template, alg.ahash); 660 623 661 624 ctx->priv = tmpl->priv; 625 + ctx->base.send = safexcel_ahash_send; 626 + ctx->base.handle_result = safexcel_handle_result; 662 627 663 628 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), 664 629 sizeof(struct safexcel_ahash_req));
+3
drivers/crypto/n2_core.c
··· 1625 1625 CWQ_ENTRY_SIZE, 0, NULL); 1626 1626 if (!queue_cache[HV_NCS_QTYPE_CWQ - 1]) { 1627 1627 kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]); 1628 + queue_cache[HV_NCS_QTYPE_MAU - 1] = NULL; 1628 1629 return -ENOMEM; 1629 1630 } 1630 1631 return 0; ··· 1635 1634 { 1636 1635 kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]); 1637 1636 kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_CWQ - 1]); 1637 + queue_cache[HV_NCS_QTYPE_MAU - 1] = NULL; 1638 + queue_cache[HV_NCS_QTYPE_CWQ - 1] = NULL; 1638 1639 } 1639 1640 1640 1641 static long spu_queue_register_workfn(void *arg)
+3 -2
include/crypto/if_alg.h
··· 18 18 #include <linux/if_alg.h> 19 19 #include <linux/scatterlist.h> 20 20 #include <linux/types.h> 21 + #include <linux/atomic.h> 21 22 #include <net/sock.h> 22 23 23 24 #include <crypto/aead.h> ··· 151 150 struct crypto_wait wait; 152 151 153 152 size_t used; 154 - size_t rcvused; 153 + atomic_t rcvused; 155 154 156 155 bool more; 157 156 bool merge; ··· 216 215 struct af_alg_ctx *ctx = ask->private; 217 216 218 217 return max_t(int, max_t(int, sk->sk_rcvbuf & PAGE_MASK, PAGE_SIZE) - 219 - ctx->rcvused, 0); 218 + atomic_read(&ctx->rcvused), 0); 220 219 } 221 220 222 221 /**
+17 -1
lib/mpi/longlong.h
··· 671 671 ************** MIPS/64 ************** 672 672 ***************************************/ 673 673 #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 674 - #if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) 674 + #if defined(__mips_isa_rev) && __mips_isa_rev >= 6 675 + /* 676 + * GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C 677 + * code below, so we special case MIPS64r6 until the compiler can do better. 678 + */ 679 + #define umul_ppmm(w1, w0, u, v) \ 680 + do { \ 681 + __asm__ ("dmulu %0,%1,%2" \ 682 + : "=d" ((UDItype)(w0)) \ 683 + : "d" ((UDItype)(u)), \ 684 + "d" ((UDItype)(v))); \ 685 + __asm__ ("dmuhu %0,%1,%2" \ 686 + : "=d" ((UDItype)(w1)) \ 687 + : "d" ((UDItype)(u)), \ 688 + "d" ((UDItype)(v))); \ 689 + } while (0) 690 + #elif (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) 675 691 #define umul_ppmm(w1, w0, u, v) \ 676 692 do { \ 677 693 typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \