diff options
| -rw-r--r-- | arch/powerpc/kernel/paca.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_64_slb.S | 83 | ||||
| -rw-r--r-- | arch/powerpc/mm/slb.c | 2 |
3 files changed, 42 insertions, 46 deletions
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index ad302f845e5d..d6e195e8cd4c 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
| @@ -98,6 +98,9 @@ static inline void free_lppacas(void) { } | |||
| 98 | /* | 98 | /* |
| 99 | * 3 persistent SLBs are registered here. The buffer will be zero | 99 | * 3 persistent SLBs are registered here. The buffer will be zero |
| 100 | * initially, hence will all be invaild until we actually write them. | 100 | * initially, hence will all be invaild until we actually write them. |
| 101 | * | ||
| 102 | * If you make the number of persistent SLB entries dynamic, please also | ||
| 103 | * update PR KVM to flush and restore them accordingly. | ||
| 101 | */ | 104 | */ |
| 102 | static struct slb_shadow *slb_shadow; | 105 | static struct slb_shadow *slb_shadow; |
| 103 | 106 | ||
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S index 84c52c6b5837..3589c4e3d49b 100644 --- a/arch/powerpc/kvm/book3s_64_slb.S +++ b/arch/powerpc/kvm/book3s_64_slb.S | |||
| @@ -17,29 +17,9 @@ | |||
| 17 | * Authors: Alexander Graf <agraf@suse.de> | 17 | * Authors: Alexander Graf <agraf@suse.de> |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #define SHADOW_SLB_ESID(num) (SLBSHADOW_SAVEAREA + (num * 0x10)) | 20 | #define SHADOW_SLB_ENTRY_LEN 0x10 |
| 21 | #define SHADOW_SLB_VSID(num) (SLBSHADOW_SAVEAREA + (num * 0x10) + 0x8) | 21 | #define OFFSET_ESID(x) (SHADOW_SLB_ENTRY_LEN * x) |
| 22 | #define UNBOLT_SLB_ENTRY(num) \ | 22 | #define OFFSET_VSID(x) ((SHADOW_SLB_ENTRY_LEN * x) + 8) |
| 23 | li r11, SHADOW_SLB_ESID(num); \ | ||
| 24 | LDX_BE r9, r12, r11; \ | ||
| 25 | /* Invalid? Skip. */; \ | ||
| 26 | rldicl. r0, r9, 37, 63; \ | ||
| 27 | beq slb_entry_skip_ ## num; \ | ||
| 28 | xoris r9, r9, SLB_ESID_V@h; \ | ||
| 29 | STDX_BE r9, r12, r11; \ | ||
| 30 | slb_entry_skip_ ## num: | ||
| 31 | |||
| 32 | #define REBOLT_SLB_ENTRY(num) \ | ||
| 33 | li r8, SHADOW_SLB_ESID(num); \ | ||
| 34 | li r7, SHADOW_SLB_VSID(num); \ | ||
| 35 | LDX_BE r10, r11, r8; \ | ||
| 36 | cmpdi r10, 0; \ | ||
| 37 | beq slb_exit_skip_ ## num; \ | ||
| 38 | oris r10, r10, SLB_ESID_V@h; \ | ||
| 39 | LDX_BE r9, r11, r7; \ | ||
| 40 | slbmte r9, r10; \ | ||
| 41 | STDX_BE r10, r11, r8; \ | ||
| 42 | slb_exit_skip_ ## num: | ||
| 43 | 23 | ||
| 44 | /****************************************************************************** | 24 | /****************************************************************************** |
| 45 | * * | 25 | * * |
| @@ -63,20 +43,15 @@ slb_exit_skip_ ## num: | |||
| 63 | * SVCPU[LR] = guest LR | 43 | * SVCPU[LR] = guest LR |
| 64 | */ | 44 | */ |
| 65 | 45 | ||
| 66 | /* Remove LPAR shadow entries */ | 46 | BEGIN_FW_FTR_SECTION |
| 67 | 47 | ||
| 68 | #if SLB_NUM_BOLTED == 3 | 48 | /* Declare SLB shadow as 0 entries big */ |
| 69 | 49 | ||
| 70 | ld r12, PACA_SLBSHADOWPTR(r13) | 50 | ld r11, PACA_SLBSHADOWPTR(r13) |
| 51 | li r8, 0 | ||
| 52 | stb r8, 3(r11) | ||
| 71 | 53 | ||
| 72 | /* Remove bolted entries */ | 54 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR) |
| 73 | UNBOLT_SLB_ENTRY(0) | ||
| 74 | UNBOLT_SLB_ENTRY(1) | ||
| 75 | UNBOLT_SLB_ENTRY(2) | ||
| 76 | |||
| 77 | #else | ||
| 78 | #error unknown number of bolted entries | ||
| 79 | #endif | ||
| 80 | 55 | ||
| 81 | /* Flush SLB */ | 56 | /* Flush SLB */ |
| 82 | 57 | ||
| @@ -99,7 +74,7 @@ slb_loop_enter: | |||
| 99 | 74 | ||
| 100 | ld r10, 0(r11) | 75 | ld r10, 0(r11) |
| 101 | 76 | ||
| 102 | rldicl. r0, r10, 37, 63 | 77 | andis. r9, r10, SLB_ESID_V@h |
| 103 | beq slb_loop_enter_skip | 78 | beq slb_loop_enter_skip |
| 104 | 79 | ||
| 105 | ld r9, 8(r11) | 80 | ld r9, 8(r11) |
| @@ -136,24 +111,42 @@ slb_do_enter: | |||
| 136 | * | 111 | * |
| 137 | */ | 112 | */ |
| 138 | 113 | ||
| 139 | /* Restore bolted entries from the shadow and fix it along the way */ | 114 | /* Remove all SLB entries that are in use. */ |
| 140 | 115 | ||
| 141 | li r0, r0 | 116 | li r0, r0 |
| 142 | slbmte r0, r0 | 117 | slbmte r0, r0 |
| 143 | slbia | 118 | slbia |
| 144 | isync | ||
| 145 | 119 | ||
| 146 | #if SLB_NUM_BOLTED == 3 | 120 | /* Restore bolted entries from the shadow */ |
| 147 | 121 | ||
| 148 | ld r11, PACA_SLBSHADOWPTR(r13) | 122 | ld r11, PACA_SLBSHADOWPTR(r13) |
| 149 | 123 | ||
| 150 | REBOLT_SLB_ENTRY(0) | 124 | BEGIN_FW_FTR_SECTION |
| 151 | REBOLT_SLB_ENTRY(1) | 125 | |
| 152 | REBOLT_SLB_ENTRY(2) | 126 | /* Declare SLB shadow as SLB_NUM_BOLTED entries big */ |
| 153 | 127 | ||
| 154 | #else | 128 | li r8, SLB_NUM_BOLTED |
| 155 | #error unknown number of bolted entries | 129 | stb r8, 3(r11) |
| 156 | #endif | 130 | |
| 131 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR) | ||
| 132 | |||
| 133 | /* Manually load all entries from shadow SLB */ | ||
| 134 | |||
| 135 | li r8, SLBSHADOW_SAVEAREA | ||
| 136 | li r7, SLBSHADOW_SAVEAREA + 8 | ||
| 137 | |||
| 138 | .rept SLB_NUM_BOLTED | ||
| 139 | LDX_BE r10, r11, r8 | ||
| 140 | cmpdi r10, 0 | ||
| 141 | beq 1f | ||
| 142 | LDX_BE r9, r11, r7 | ||
| 143 | slbmte r9, r10 | ||
| 144 | 1: addi r7, r7, SHADOW_SLB_ENTRY_LEN | ||
| 145 | addi r8, r8, SHADOW_SLB_ENTRY_LEN | ||
| 146 | .endr | ||
| 147 | |||
| 148 | isync | ||
| 149 | sync | ||
| 157 | 150 | ||
| 158 | slb_do_exit: | 151 | slb_do_exit: |
| 159 | 152 | ||
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 9d1d33cd2be5..964a5f61488a 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c | |||
| @@ -97,7 +97,7 @@ static inline void create_shadowed_slbe(unsigned long ea, int ssize, | |||
| 97 | static void __slb_flush_and_rebolt(void) | 97 | static void __slb_flush_and_rebolt(void) |
| 98 | { | 98 | { |
| 99 | /* If you change this make sure you change SLB_NUM_BOLTED | 99 | /* If you change this make sure you change SLB_NUM_BOLTED |
| 100 | * appropriately too. */ | 100 | * and PR KVM appropriately too. */ |
| 101 | unsigned long linear_llp, vmalloc_llp, lflags, vflags; | 101 | unsigned long linear_llp, vmalloc_llp, lflags, vflags; |
| 102 | unsigned long ksp_esid_data, ksp_vsid_data; | 102 | unsigned long ksp_esid_data, ksp_vsid_data; |
| 103 | 103 | ||
