aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grumain.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/sgi-gru/grumain.c')
-rw-r--r--drivers/misc/sgi-gru/grumain.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 5fc7b5ecde6..ec3f7a17d22 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -326,6 +326,7 @@ static struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
326 gts->ts_vma = vma; 326 gts->ts_vma = vma;
327 gts->ts_tlb_int_select = -1; 327 gts->ts_tlb_int_select = -1;
328 gts->ts_gms = gru_register_mmu_notifier(); 328 gts->ts_gms = gru_register_mmu_notifier();
329 gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT);
329 if (!gts->ts_gms) 330 if (!gts->ts_gms)
330 goto err; 331 goto err;
331 332
@@ -552,7 +553,8 @@ static void gru_load_context(struct gru_thread_state *gts)
552 cch->tlb_int_select = gts->ts_tlb_int_select; 553 cch->tlb_int_select = gts->ts_tlb_int_select;
553 } 554 }
554 cch->tfm_done_bit_enable = 0; 555 cch->tfm_done_bit_enable = 0;
555 err = cch_allocate(cch, asid, gts->ts_cbr_map, gts->ts_dsr_map); 556 err = cch_allocate(cch, asid, gts->ts_sizeavail, gts->ts_cbr_map,
557 gts->ts_dsr_map);
556 if (err) { 558 if (err) {
557 gru_dbg(grudev, 559 gru_dbg(grudev,
558 "err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n", 560 "err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n",
@@ -573,11 +575,12 @@ static void gru_load_context(struct gru_thread_state *gts)
573/* 575/*
574 * Update fields in an active CCH: 576 * Update fields in an active CCH:
575 * - retarget interrupts on local blade 577 * - retarget interrupts on local blade
578 * - update sizeavail mask
576 * - force a delayed context unload by clearing the CCH asids. This 579 * - force a delayed context unload by clearing the CCH asids. This
577 * forces TLB misses for new GRU instructions. The context is unloaded 580 * forces TLB misses for new GRU instructions. The context is unloaded
578 * when the next TLB miss occurs. 581 * when the next TLB miss occurs.
579 */ 582 */
580static int gru_update_cch(struct gru_thread_state *gts, int int_select) 583int gru_update_cch(struct gru_thread_state *gts, int force_unload)
581{ 584{
582 struct gru_context_configuration_handle *cch; 585 struct gru_context_configuration_handle *cch;
583 struct gru_state *gru = gts->ts_gru; 586 struct gru_state *gru = gts->ts_gru;
@@ -591,9 +594,11 @@ static int gru_update_cch(struct gru_thread_state *gts, int int_select)
591 goto exit; 594 goto exit;
592 if (cch_interrupt(cch)) 595 if (cch_interrupt(cch))
593 BUG(); 596 BUG();
594 if (int_select >= 0) { 597 if (!force_unload) {
595 gts->ts_tlb_int_select = int_select; 598 for (i = 0; i < 8; i++)
596 cch->tlb_int_select = int_select; 599 cch->sizeavail[i] = gts->ts_sizeavail;
600 gts->ts_tlb_int_select = gru_cpu_fault_map_id();
601 cch->tlb_int_select = gru_cpu_fault_map_id();
597 } else { 602 } else {
598 for (i = 0; i < 8; i++) 603 for (i = 0; i < 8; i++)
599 cch->asid[i] = 0; 604 cch->asid[i] = 0;
@@ -625,7 +630,7 @@ static int gru_retarget_intr(struct gru_thread_state *gts)
625 630
626 gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select, 631 gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select,
627 gru_cpu_fault_map_id()); 632 gru_cpu_fault_map_id());
628 return gru_update_cch(gts, gru_cpu_fault_map_id()); 633 return gru_update_cch(gts, 0);
629} 634}
630 635
631 636