7 // #define DEBUG_PATCHERY
9 #define H_SET_DABR 0x28
10 #define INS_SC1 0x44000022
11 #define INS_SC1_REPLACE 0x7c000268
13 extern volatile uint32_t sc1ins;
15 static unsigned long hcall(uint32_t inst, unsigned long arg0, unsigned long arg1)
17 register unsigned long r3 asm("r3") = arg0;
18 register unsigned long r4 asm("r4") = arg1;
19 register unsigned long r5 asm("r5") = inst;
20 asm volatile("bl 1f \n"
33 : "r" (r3), "r" (r4), "r" (r5)
34 : "ctr", "r0", "r6", "r7", "r8", "r9", "r10", "r11",
35 "r12", "r13", "r31", "lr", "cc");
39 static int check_broken_sc1(void)
44 * Check if we can do a simple hcall. If it works, we are running in
45 * a sane environment and everything's fine. If it doesn't, we need
46 * to patch the hypercall instruction to something that traps into
49 r = hcall(INS_SC1, H_SET_DABR, 0);
50 if (r == H_SUCCESS || r == H_HARDWARE) {
55 /* We found a broken sc1 host! */
59 int patch_broken_sc1(void *start, void *end, uint32_t *test_ins)
62 /* The sc 1 instruction */
63 uint32_t sc1 = INS_SC1;
64 /* An illegal instruction that KVM interprets as sc 1 */
65 uint32_t sc1_replacement = INS_SC1_REPLACE;
66 int is_le = (test_ins && *test_ins == 0x48000008);
71 /* The host is sane, get out of here */
72 if (!check_broken_sc1())
75 /* We only get here with a broken sc1 implementation */
77 /* Trim the range we scan to not cover the data section */
79 /* This is the cpu table matcher for 970FX */
80 uint32_t end_bytes[] = { 0xffff0000, 0x3c0000 };
82 * The .__start symbol contains a trap instruction followed
85 uint32_t start_bytes[] = { 0x7fe00008, 0, 0, 0, 0 };
88 end_bytes[0] = bswap_32(end_bytes[0]);
89 end_bytes[1] = bswap_32(end_bytes[1]);
90 start_bytes[1] = bswap_32(start_bytes[1]);
93 /* Find the start of the text section */
94 for (p = test_ins; (long)p > (long)start; p--) {
95 if (p[0] == start_bytes[0] &&
96 p[1] == start_bytes[1] &&
97 p[2] == start_bytes[2] &&
98 p[3] == start_bytes[3] &&
99 p[4] == start_bytes[4]) {
101 * We found a match of the instruction sequence
107 * which marks the beginning of the .text
108 * section on all Linux kernels I've checked.
110 #ifdef DEBUG_PATCHERY
111 printf("Shortened start from %p to %p\n", end, p);
118 /* Find the end of the text section */
119 for (p = start; (long)p < (long)end; p++) {
120 if (p[0] == end_bytes[0] && p[1] == end_bytes[1]) {
122 * We found a match of the PPC970FX entry in the
123 * guest kernel's CPU table. That table is
124 * usually found early in the .data section and
125 * thus marks the end of the .text section for
126 * us which we need to patch.
128 #ifdef DEBUG_PATCHERY
129 printf("Shortened end from %p to %p\n", end, p);
139 * The kernel was built for LE mode, so our sc1 and replacement
140 * opcodes are in the wrong byte order. Reverse them.
143 sc1_replacement = bswap_32(sc1_replacement);
146 /* Patch all sc 1 instructions to reserved instruction 31/308 */
147 for (p = start; (long)p < (long)end; p++) {
149 *p = sc1_replacement;
150 flush_cache(p, sizeof(*p));
151 #ifdef DEBUG_PATCHERY
157 #ifdef DEBUG_PATCHERY
158 printf("Patched %d instructions (%p - %p)\n", cnt, start, end);