diff options
Diffstat (limited to 'drivers/misc/sgi-gru/grufault.c')
-rw-r--r-- | drivers/misc/sgi-gru/grufault.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c index 3ee698ad8599..f85d27306789 100644 --- a/drivers/misc/sgi-gru/grufault.c +++ b/drivers/misc/sgi-gru/grufault.c | |||
@@ -368,6 +368,7 @@ failupm: | |||
368 | 368 | ||
369 | failfmm: | 369 | failfmm: |
370 | /* FMM state on UPM call */ | 370 | /* FMM state on UPM call */ |
371 | gru_flush_cache(tfh); | ||
371 | STAT(tlb_dropin_fail_fmm); | 372 | STAT(tlb_dropin_fail_fmm); |
372 | gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state); | 373 | gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state); |
373 | return 0; | 374 | return 0; |
@@ -497,10 +498,8 @@ int gru_handle_user_call_os(unsigned long cb) | |||
497 | if (!gts) | 498 | if (!gts) |
498 | return -EINVAL; | 499 | return -EINVAL; |
499 | 500 | ||
500 | if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) { | 501 | if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) |
501 | ret = -EINVAL; | ||
502 | goto exit; | 502 | goto exit; |
503 | } | ||
504 | 503 | ||
505 | /* | 504 | /* |
506 | * If force_unload is set, the UPM TLB fault is phony. The task | 505 | * If force_unload is set, the UPM TLB fault is phony. The task |
@@ -508,6 +507,10 @@ int gru_handle_user_call_os(unsigned long cb) | |||
508 | * unload the context. The task will page fault and assign a new | 507 | * unload the context. The task will page fault and assign a new |
509 | * context. | 508 | * context. |
510 | */ | 509 | */ |
510 | if (gts->ts_tgid_owner == current->tgid && gts->ts_blade >= 0 && | ||
511 | gts->ts_blade != uv_numa_blade_id()) | ||
512 | gts->ts_force_unload = 1; | ||
513 | |||
511 | ret = -EAGAIN; | 514 | ret = -EAGAIN; |
512 | cbrnum = thread_cbr_number(gts, ucbnum); | 515 | cbrnum = thread_cbr_number(gts, ucbnum); |
513 | if (gts->ts_force_unload) { | 516 | if (gts->ts_force_unload) { |
@@ -541,11 +544,13 @@ int gru_get_exception_detail(unsigned long arg) | |||
541 | if (!gts) | 544 | if (!gts) |
542 | return -EINVAL; | 545 | return -EINVAL; |
543 | 546 | ||
544 | if (gts->ts_gru) { | 547 | ucbnum = get_cb_number((void *)excdet.cb); |
545 | ucbnum = get_cb_number((void *)excdet.cb); | 548 | if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) { |
549 | ret = -EINVAL; | ||
550 | } else if (gts->ts_gru) { | ||
546 | cbrnum = thread_cbr_number(gts, ucbnum); | 551 | cbrnum = thread_cbr_number(gts, ucbnum); |
547 | cbe = get_cbe_by_index(gts->ts_gru, cbrnum); | 552 | cbe = get_cbe_by_index(gts->ts_gru, cbrnum); |
548 | prefetchw(cbe); /* Harmless on hardware, required for emulator */ | 553 | prefetchw(cbe);/* Harmless on hardware, required for emulator */ |
549 | excdet.opc = cbe->opccpy; | 554 | excdet.opc = cbe->opccpy; |
550 | excdet.exopc = cbe->exopccpy; | 555 | excdet.exopc = cbe->exopccpy; |
551 | excdet.ecause = cbe->ecause; | 556 | excdet.ecause = cbe->ecause; |
@@ -609,7 +614,7 @@ int gru_user_flush_tlb(unsigned long arg) | |||
609 | if (!gts) | 614 | if (!gts) |
610 | return -EINVAL; | 615 | return -EINVAL; |
611 | 616 | ||
612 | gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.vaddr + req.len); | 617 | gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.len); |
613 | gru_unlock_gts(gts); | 618 | gru_unlock_gts(gts); |
614 | 619 | ||
615 | return 0; | 620 | return 0; |