/* Trap handling code needs to get at a few critical values upon * trap entry and to process TSB misses. These cannot be in the * per_cpu() area as we really need to lock them into the TLB and * thus make them part of the main kernel image. As a result we * try to make this as small as possible. * * This is padded out and aligned to 64-bytes to avoid false sharing * on SMP.
*/
/* If you modify the size of this structure, please update * TRAP_BLOCK_SZ_SHIFT below.
*/ struct thread_info; struct trap_per_cpu { /* D-cache line 1: Basic thread information, cpu and device mondo queues */ struct thread_info *thread; unsignedlong pgd_paddr; unsignedlong cpu_mondo_pa; unsignedlong dev_mondo_pa;
/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */ unsignedlong resum_mondo_pa; unsignedlong resum_kernel_buf_pa; unsignedlong nonresum_mondo_pa; unsignedlong nonresum_kernel_buf_pa;
/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */ struct hv_fault_status fault_info;
/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list. */ unsignedlong cpu_mondo_block_pa; unsignedlong cpu_list_pa; unsignedlong tsb_huge; unsignedlong tsb_huge_temp;
/* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size. */ unsignedlong irq_worklist_pa; unsignedint cpu_mondo_qmask; unsignedint dev_mondo_qmask; unsignedint resum_qmask; unsignedint nonresum_qmask; unsignedlong __per_cpu_base;
} __attribute__((aligned(64))); externstruct trap_per_cpu trap_block[NR_CPUS]; void init_cur_cpu_trap(struct thread_info *); void setup_tba(void); externint ncpus_probed; extern u64 cpu_mondo_counter[NR_CPUS];
/* Clobbers TMP, current address space PGD phys address into DEST. */ #define TRAP_LOAD_PGD_PHYS(DEST, TMP) \
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
/* Clobbers TMP, loads local processor's IRQ work area into DEST. */ #define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
/* Clobbers TMP, loads DEST with current thread info pointer. */ #define TRAP_LOAD_THREAD_REG(DEST, TMP) \
TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \
ldx [DEST + TRAP_PER_CPU_THREAD], DEST;
/* Given the current thread info pointer in THR, load the per-cpu * area base of the current processor into DEST. REG1, REG2, and REG3 are * clobbered. * * You absolutely cannot use DEST as a temporary in this code. The * reason is that traps can happen during execution, and return from * trap will load the fully resolved DEST per-cpu base. This can corrupt * the calculations done by the macro mid-stream.
*/ #define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
lduh [THR + TI_CPU], REG1; \
sethi %hi(trap_block), REG2; \
sllx REG1, TRAP_BLOCK_SZ_SHIFT, REG1; \ or REG2, %lo(trap_block), REG2; \
add REG2, REG1, REG2; \
ldx [REG2 + TRAP_PER_CPU_PER_CPU_BASE], DEST;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.