static void manual_hpte_clear_all(void) { unsigned long size_bytes = 1UL << ppc64_pft_size; unsigned long hpte_count = size_bytes >> 4; struct { unsigned long pteh; unsigned long ptel; } ptes[4]; long lpar_rc; unsigned long i, j; /* Read in batches of 4, * invalidate only valid entries not in the VRMA * hpte_count will be a multiple of 4 */ for (i = 0; i < hpte_count; i += 4) { lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes); if (lpar_rc != H_SUCCESS) continue; for (j = 0; j < 4; j++){ if ((ptes[j].pteh & HPTE_V_VRMA_MASK) == HPTE_V_VRMA_MASK) continue; if (ptes[j].pteh & HPTE_V_VALID) plpar_pte_remove_raw(0, i + j, 0, &(ptes[j].pteh), &(ptes[j].ptel)); } } }
static void pSeries_lpar_hptab_clear(void) { unsigned long size_bytes = 1UL << ppc64_pft_size; unsigned long hpte_count = size_bytes >> 4; struct { unsigned long pteh; unsigned long ptel; } ptes[4]; long lpar_rc; unsigned long i, j; /* Read in batches of 4, * invalidate only valid entries not in the VRMA * hpte_count will be a multiple of 4 */ for (i = 0; i < hpte_count; i += 4) { lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes); if (lpar_rc != H_SUCCESS) continue; for (j = 0; j < 4; j++){ if ((ptes[j].pteh & HPTE_V_VRMA_MASK) == HPTE_V_VRMA_MASK) continue; if (ptes[j].pteh & HPTE_V_VALID) plpar_pte_remove_raw(0, i + j, 0, &(ptes[j].pteh), &(ptes[j].ptel)); } } #ifdef __LITTLE_ENDIAN__ /* * Reset exceptions to big endian. * * FIXME this is a hack for kexec, we need to reset the exception * endian before starting the new kernel and this is a convenient place * to do it. * * This is also called on boot when a fadump happens. In that case we * must not change the exception endian mode. */ if (firmware_has_feature(FW_FEATURE_SET_MODE) && !is_fadump_active()) { long rc; rc = pseries_big_endian_exceptions(); /* * At this point it is unlikely panic() will get anything * out to the user, but at least this will stop us from * continuing on further and creating an even more * difficult to debug situation. */ if (rc) panic("Could not enable big endian exceptions"); } #endif }
static void pSeries_lpar_hptab_clear(void) { unsigned long size_bytes = 1UL << ppc64_pft_size; unsigned long hpte_count = size_bytes >> 4; struct { unsigned long pteh; unsigned long ptel; } ptes[4]; long lpar_rc; unsigned long i, j; /* Read in batches of 4, * invalidate only valid entries not in the VRMA * hpte_count will be a multiple of 4 */ for (i = 0; i < hpte_count; i += 4) { lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes); if (lpar_rc != H_SUCCESS) continue; for (j = 0; j < 4; j++){ if ((ptes[j].pteh & HPTE_V_VRMA_MASK) == HPTE_V_VRMA_MASK) continue; if (ptes[j].pteh & HPTE_V_VALID) plpar_pte_remove_raw(0, i + j, 0, &(ptes[j].pteh), &(ptes[j].ptel)); } } #ifdef __LITTLE_ENDIAN__ /* Reset exceptions to big endian */ if (firmware_has_feature(FW_FEATURE_SET_MODE)) { long rc; rc = pseries_big_endian_exceptions(); /* * At this point it is unlikely panic() will get anything * out to the user, but at least this will stop us from * continuing on further and creating an even more * difficult to debug situation. */ if (rc) panic("Could not enable big endian exceptions"); } #endif }