diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h index 357bcb4..704c53c 100644 --- a/include/sbi/riscv_asm.h +++ b/include/sbi/riscv_asm.h @@ -31,7 +31,9 @@ #define PAGE_SHIFT (12) #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE - 1)) -#define SBI_TLB_FLUSH_ALL ((unsigned long)-1) + +#define SBI_TLB_FLUSH_ALL ((unsigned long)-1) +#define SBI_TLB_FLUSH_MAX_SIZE (1UL << 30) #define REG_L __REG_SEL(ld, lw) #define REG_S __REG_SEL(sd, sw) diff --git a/lib/sbi_ipi.c b/lib/sbi_ipi.c index cc0d0d4..578740c 100644 --- a/lib/sbi_ipi.c +++ b/lib/sbi_ipi.c @@ -23,8 +23,8 @@ static inline int __sbi_tlb_fifo_range_check(struct sbi_tlb_info *curr, struct sbi_tlb_info *next) { - int curr_end; - int next_end; + unsigned long curr_end; + unsigned long next_end; int ret = SBI_FIFO_UNCHANGED; if (!curr || !next) @@ -91,17 +91,29 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid, u32 event, struct sbi_scratch *remote_scratch = NULL; const struct sbi_platform *plat = sbi_platform_ptr(scratch); struct sbi_fifo *ipi_tlb_fifo; + struct sbi_tlb_info *tinfo = data; int ret = SBI_FIFO_UNCHANGED; if (sbi_platform_hart_disabled(plat, hartid)) return -1; - /* Set IPI type on remote hart's scratch area and + /* + * Set IPI type on remote hart's scratch area and * trigger the interrupt */ remote_scratch = sbi_hart_id_to_scratch(scratch, hartid); if (event == SBI_IPI_EVENT_SFENCE_VMA || event == SBI_IPI_EVENT_SFENCE_VMA_ASID) { + /* + * If address range to flush is too big then simply + * upgrade it to flush all because we can only flush + * 4KB at a time. + */ + if (tinfo->size >= SBI_TLB_FLUSH_MAX_SIZE) { + tinfo->start = 0; + tinfo->size = SBI_TLB_FLUSH_ALL; + } + ipi_tlb_fifo = sbi_tlb_fifo_head_ptr(remote_scratch); ret = sbi_fifo_inplace_update(ipi_tlb_fifo, data, sbi_tlb_fifo_update_cb);