diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 14 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal.c | 40 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 23 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 29 |
9 files changed, 89 insertions, 44 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index c60bbec25c1f..1f0937d7d4b5 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -453,7 +453,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
453 | .icache_bsize = 128, | 453 | .icache_bsize = 128, |
454 | .dcache_bsize = 128, | 454 | .dcache_bsize = 128, |
455 | .oprofile_type = PPC_OPROFILE_POWER4, | 455 | .oprofile_type = PPC_OPROFILE_POWER4, |
456 | .oprofile_cpu_type = "ppc64/ibm-compat-v1", | 456 | .oprofile_cpu_type = 0, |
457 | .cpu_setup = __setup_cpu_power8, | 457 | .cpu_setup = __setup_cpu_power8, |
458 | .cpu_restore = __restore_cpu_power8, | 458 | .cpu_restore = __restore_cpu_power8, |
459 | .platform = "power8", | 459 | .platform = "power8", |
@@ -482,7 +482,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
482 | .cpu_name = "POWER7+ (raw)", | 482 | .cpu_name = "POWER7+ (raw)", |
483 | .cpu_features = CPU_FTRS_POWER7, | 483 | .cpu_features = CPU_FTRS_POWER7, |
484 | .cpu_user_features = COMMON_USER_POWER7, | 484 | .cpu_user_features = COMMON_USER_POWER7, |
485 | .cpu_user_features = COMMON_USER2_POWER7, | 485 | .cpu_user_features2 = COMMON_USER2_POWER7, |
486 | .mmu_features = MMU_FTRS_POWER7, | 486 | .mmu_features = MMU_FTRS_POWER7, |
487 | .icache_bsize = 128, | 487 | .icache_bsize = 128, |
488 | .dcache_bsize = 128, | 488 | .dcache_bsize = 128, |
@@ -506,7 +506,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
506 | .dcache_bsize = 128, | 506 | .dcache_bsize = 128, |
507 | .num_pmcs = 6, | 507 | .num_pmcs = 6, |
508 | .pmc_type = PPC_PMC_IBM, | 508 | .pmc_type = PPC_PMC_IBM, |
509 | .oprofile_cpu_type = "ppc64/power8", | 509 | .oprofile_cpu_type = 0, |
510 | .oprofile_type = PPC_OPROFILE_POWER4, | 510 | .oprofile_type = PPC_OPROFILE_POWER4, |
511 | .cpu_setup = __setup_cpu_power8, | 511 | .cpu_setup = __setup_cpu_power8, |
512 | .cpu_restore = __restore_cpu_power8, | 512 | .cpu_restore = __restore_cpu_power8, |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index d22e73e4618b..22b45a4955cd 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -849,7 +849,7 @@ resume_kernel: | |||
849 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ | 849 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ |
850 | CURRENT_THREAD_INFO(r9, r1) | 850 | CURRENT_THREAD_INFO(r9, r1) |
851 | lwz r8,TI_FLAGS(r9) | 851 | lwz r8,TI_FLAGS(r9) |
852 | andis. r8,r8,_TIF_EMULATE_STACK_STORE@h | 852 | andis. r0,r8,_TIF_EMULATE_STACK_STORE@h |
853 | beq+ 1f | 853 | beq+ 1f |
854 | 854 | ||
855 | addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ | 855 | addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 0e9095e47b5b..246b11c4fe7e 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -501,6 +501,13 @@ BEGIN_FTR_SECTION | |||
501 | ldarx r6,0,r1 | 501 | ldarx r6,0,r1 |
502 | END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS) | 502 | END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS) |
503 | 503 | ||
504 | #ifdef CONFIG_PPC_BOOK3S | ||
505 | /* Cancel all explict user streams as they will have no use after context | ||
506 | * switch and will stop the HW from creating streams itself | ||
507 | */ | ||
508 | DCBT_STOP_ALL_STREAM_IDS(r6) | ||
509 | #endif | ||
510 | |||
504 | addi r6,r4,-THREAD /* Convert THREAD to 'current' */ | 511 | addi r6,r4,-THREAD /* Convert THREAD to 'current' */ |
505 | std r6,PACACURRENT(r13) /* Set new 'current' */ | 512 | std r6,PACACURRENT(r13) /* Set new 'current' */ |
506 | 513 | ||
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index e9acf50dd5b2..7f2273cc3c7d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -657,15 +657,6 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
657 | * ranges. However, some machines (thanks Apple !) tend to split their | 657 | * ranges. However, some machines (thanks Apple !) tend to split their |
658 | * space into lots of small contiguous ranges. So we have to coalesce. | 658 | * space into lots of small contiguous ranges. So we have to coalesce. |
659 | * | 659 | * |
660 | * - We can only cope with all memory ranges having the same offset | ||
661 | * between CPU addresses and PCI addresses. Unfortunately, some bridges | ||
662 | * are setup for a large 1:1 mapping along with a small "window" which | ||
663 | * maps PCI address 0 to some arbitrary high address of the CPU space in | ||
664 | * order to give access to the ISA memory hole. | ||
665 | * The way out of here that I've chosen for now is to always set the | ||
666 | * offset based on the first resource found, then override it if we | ||
667 | * have a different offset and the previous was set by an ISA hole. | ||
668 | * | ||
669 | * - Some busses have IO space not starting at 0, which causes trouble with | 660 | * - Some busses have IO space not starting at 0, which causes trouble with |
670 | * the way we do our IO resource renumbering. The code somewhat deals with | 661 | * the way we do our IO resource renumbering. The code somewhat deals with |
671 | * it for 64 bits but I would expect problems on 32 bits. | 662 | * it for 64 bits but I would expect problems on 32 bits. |
@@ -680,10 +671,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
680 | int rlen; | 671 | int rlen; |
681 | int pna = of_n_addr_cells(dev); | 672 | int pna = of_n_addr_cells(dev); |
682 | int np = pna + 5; | 673 | int np = pna + 5; |
683 | int memno = 0, isa_hole = -1; | 674 | int memno = 0; |
684 | u32 pci_space; | 675 | u32 pci_space; |
685 | unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; | 676 | unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; |
686 | unsigned long long isa_mb = 0; | ||
687 | struct resource *res; | 677 | struct resource *res; |
688 | 678 | ||
689 | printk(KERN_INFO "PCI host bridge %s %s ranges:\n", | 679 | printk(KERN_INFO "PCI host bridge %s %s ranges:\n", |
@@ -777,8 +767,6 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
777 | } | 767 | } |
778 | /* Handles ISA memory hole space here */ | 768 | /* Handles ISA memory hole space here */ |
779 | if (pci_addr == 0) { | 769 | if (pci_addr == 0) { |
780 | isa_mb = cpu_addr; | ||
781 | isa_hole = memno; | ||
782 | if (primary || isa_mem_base == 0) | 770 | if (primary || isa_mem_base == 0) |
783 | isa_mem_base = cpu_addr; | 771 | isa_mem_base = cpu_addr; |
784 | hose->isa_mem_phys = cpu_addr; | 772 | hose->isa_mem_phys = cpu_addr; |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 577a8aa69c6e..457e97aa2945 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
19 | #include <asm/unistd.h> | 19 | #include <asm/unistd.h> |
20 | #include <asm/debug.h> | 20 | #include <asm/debug.h> |
21 | #include <asm/tm.h> | ||
21 | 22 | ||
22 | #include "signal.h" | 23 | #include "signal.h" |
23 | 24 | ||
@@ -30,13 +31,13 @@ int show_unhandled_signals = 1; | |||
30 | /* | 31 | /* |
31 | * Allocate space for the signal frame | 32 | * Allocate space for the signal frame |
32 | */ | 33 | */ |
33 | void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 34 | void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, |
34 | size_t frame_size, int is_32) | 35 | size_t frame_size, int is_32) |
35 | { | 36 | { |
36 | unsigned long oldsp, newsp; | 37 | unsigned long oldsp, newsp; |
37 | 38 | ||
38 | /* Default to using normal stack */ | 39 | /* Default to using normal stack */ |
39 | oldsp = get_clean_sp(regs, is_32); | 40 | oldsp = get_clean_sp(sp, is_32); |
40 | 41 | ||
41 | /* Check for alt stack */ | 42 | /* Check for alt stack */ |
42 | if ((ka->sa.sa_flags & SA_ONSTACK) && | 43 | if ((ka->sa.sa_flags & SA_ONSTACK) && |
@@ -175,3 +176,38 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | |||
175 | 176 | ||
176 | user_enter(); | 177 | user_enter(); |
177 | } | 178 | } |
179 | |||
180 | unsigned long get_tm_stackpointer(struct pt_regs *regs) | ||
181 | { | ||
182 | /* When in an active transaction that takes a signal, we need to be | ||
183 | * careful with the stack. It's possible that the stack has moved back | ||
184 | * up after the tbegin. The obvious case here is when the tbegin is | ||
185 | * called inside a function that returns before a tend. In this case, | ||
186 | * the stack is part of the checkpointed transactional memory state. | ||
187 | * If we write over this non transactionally or in suspend, we are in | ||
188 | * trouble because if we get a tm abort, the program counter and stack | ||
189 | * pointer will be back at the tbegin but our in memory stack won't be | ||
190 | * valid anymore. | ||
191 | * | ||
192 | * To avoid this, when taking a signal in an active transaction, we | ||
193 | * need to use the stack pointer from the checkpointed state, rather | ||
194 | * than the speculated state. This ensures that the signal context | ||
195 | * (written tm suspended) will be written below the stack required for | ||
196 | * the rollback. The transaction is aborted becuase of the treclaim, | ||
197 | * so any memory written between the tbegin and the signal will be | ||
198 | * rolled back anyway. | ||
199 | * | ||
200 | * For signals taken in non-TM or suspended mode, we use the | ||
201 | * normal/non-checkpointed stack pointer. | ||
202 | */ | ||
203 | |||
204 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
205 | if (MSR_TM_ACTIVE(regs->msr)) { | ||
206 | tm_enable(); | ||
207 | tm_reclaim(¤t->thread, regs->msr, TM_CAUSE_SIGNAL); | ||
208 | if (MSR_TM_TRANSACTIONAL(regs->msr)) | ||
209 | return current->thread.ckpt_regs.gpr[1]; | ||
210 | } | ||
211 | #endif | ||
212 | return regs->gpr[1]; | ||
213 | } | ||
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index ec84c901ceab..c69b9aeb9f23 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); | 13 | extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); |
14 | 14 | ||
15 | extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 15 | extern void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, |
16 | size_t frame_size, int is_32); | 16 | size_t frame_size, int is_32); |
17 | 17 | ||
18 | extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, | 18 | extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 95068bf569ad..201385c3a1ae 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -503,12 +503,6 @@ static int save_tm_user_regs(struct pt_regs *regs, | |||
503 | { | 503 | { |
504 | unsigned long msr = regs->msr; | 504 | unsigned long msr = regs->msr; |
505 | 505 | ||
506 | /* tm_reclaim rolls back all reg states, updating thread.ckpt_regs, | ||
507 | * thread.transact_fpr[], thread.transact_vr[], etc. | ||
508 | */ | ||
509 | tm_enable(); | ||
510 | tm_reclaim(¤t->thread, msr, TM_CAUSE_SIGNAL); | ||
511 | |||
512 | /* Make sure floating point registers are stored in regs */ | 506 | /* Make sure floating point registers are stored in regs */ |
513 | flush_fp_to_thread(current); | 507 | flush_fp_to_thread(current); |
514 | 508 | ||
@@ -965,7 +959,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
965 | 959 | ||
966 | /* Set up Signal Frame */ | 960 | /* Set up Signal Frame */ |
967 | /* Put a Real Time Context onto stack */ | 961 | /* Put a Real Time Context onto stack */ |
968 | rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1); | 962 | rt_sf = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*rt_sf), 1); |
969 | addr = rt_sf; | 963 | addr = rt_sf; |
970 | if (unlikely(rt_sf == NULL)) | 964 | if (unlikely(rt_sf == NULL)) |
971 | goto badframe; | 965 | goto badframe; |
@@ -1403,7 +1397,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
1403 | unsigned long tramp; | 1397 | unsigned long tramp; |
1404 | 1398 | ||
1405 | /* Set up Signal Frame */ | 1399 | /* Set up Signal Frame */ |
1406 | frame = get_sigframe(ka, regs, sizeof(*frame), 1); | 1400 | frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 1); |
1407 | if (unlikely(frame == NULL)) | 1401 | if (unlikely(frame == NULL)) |
1408 | goto badframe; | 1402 | goto badframe; |
1409 | sc = (struct sigcontext __user *) &frame->sctx; | 1403 | sc = (struct sigcontext __user *) &frame->sctx; |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index c1794286098c..345947367ec0 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -154,11 +154,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
154 | * As above, but Transactional Memory is in use, so deliver sigcontexts | 154 | * As above, but Transactional Memory is in use, so deliver sigcontexts |
155 | * containing checkpointed and transactional register states. | 155 | * containing checkpointed and transactional register states. |
156 | * | 156 | * |
157 | * To do this, we treclaim to gather both sets of registers and set up the | 157 | * To do this, we treclaim (done before entering here) to gather both sets of |
158 | * 'normal' sigcontext registers with rolled-back register values such that a | 158 | * registers and set up the 'normal' sigcontext registers with rolled-back |
159 | * simple signal handler sees a correct checkpointed register state. | 159 | * register values such that a simple signal handler sees a correct |
160 | * If interested, a TM-aware sighandler can examine the transactional registers | 160 | * checkpointed register state. If interested, a TM-aware sighandler can |
161 | * in the 2nd sigcontext to determine the real origin of the signal. | 161 | * examine the transactional registers in the 2nd sigcontext to determine the |
162 | * real origin of the signal. | ||
162 | */ | 163 | */ |
163 | static long setup_tm_sigcontexts(struct sigcontext __user *sc, | 164 | static long setup_tm_sigcontexts(struct sigcontext __user *sc, |
164 | struct sigcontext __user *tm_sc, | 165 | struct sigcontext __user *tm_sc, |
@@ -184,16 +185,6 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc, | |||
184 | 185 | ||
185 | BUG_ON(!MSR_TM_ACTIVE(regs->msr)); | 186 | BUG_ON(!MSR_TM_ACTIVE(regs->msr)); |
186 | 187 | ||
187 | /* tm_reclaim rolls back all reg states, saving checkpointed (older) | ||
188 | * GPRs to thread.ckpt_regs and (if used) FPRs to (newer) | ||
189 | * thread.transact_fp and/or VRs to (newer) thread.transact_vr. | ||
190 | * THEN we save out FP/VRs, if necessary, to the checkpointed (older) | ||
191 | * thread.fr[]/vr[]s. The transactional (newer) GPRs are on the | ||
192 | * stack, in *regs. | ||
193 | */ | ||
194 | tm_enable(); | ||
195 | tm_reclaim(¤t->thread, msr, TM_CAUSE_SIGNAL); | ||
196 | |||
197 | flush_fp_to_thread(current); | 188 | flush_fp_to_thread(current); |
198 | 189 | ||
199 | #ifdef CONFIG_ALTIVEC | 190 | #ifdef CONFIG_ALTIVEC |
@@ -711,7 +702,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, | |||
711 | unsigned long newsp = 0; | 702 | unsigned long newsp = 0; |
712 | long err = 0; | 703 | long err = 0; |
713 | 704 | ||
714 | frame = get_sigframe(ka, regs, sizeof(*frame), 0); | 705 | frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 0); |
715 | if (unlikely(frame == NULL)) | 706 | if (unlikely(frame == NULL)) |
716 | goto badframe; | 707 | goto badframe; |
717 | 708 | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index a7a648f6b750..f18c79c324ef 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #ifdef CONFIG_PPC64 | 53 | #ifdef CONFIG_PPC64 |
54 | #include <asm/firmware.h> | 54 | #include <asm/firmware.h> |
55 | #include <asm/processor.h> | 55 | #include <asm/processor.h> |
56 | #include <asm/tm.h> | ||
56 | #endif | 57 | #endif |
57 | #include <asm/kexec.h> | 58 | #include <asm/kexec.h> |
58 | #include <asm/ppc-opcode.h> | 59 | #include <asm/ppc-opcode.h> |
@@ -932,6 +933,28 @@ static int emulate_isel(struct pt_regs *regs, u32 instword) | |||
932 | return 0; | 933 | return 0; |
933 | } | 934 | } |
934 | 935 | ||
936 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
937 | static inline bool tm_abort_check(struct pt_regs *regs, int cause) | ||
938 | { | ||
939 | /* If we're emulating a load/store in an active transaction, we cannot | ||
940 | * emulate it as the kernel operates in transaction suspended context. | ||
941 | * We need to abort the transaction. This creates a persistent TM | ||
942 | * abort so tell the user what caused it with a new code. | ||
943 | */ | ||
944 | if (MSR_TM_TRANSACTIONAL(regs->msr)) { | ||
945 | tm_enable(); | ||
946 | tm_abort(cause); | ||
947 | return true; | ||
948 | } | ||
949 | return false; | ||
950 | } | ||
951 | #else | ||
952 | static inline bool tm_abort_check(struct pt_regs *regs, int reason) | ||
953 | { | ||
954 | return false; | ||
955 | } | ||
956 | #endif | ||
957 | |||
935 | static int emulate_instruction(struct pt_regs *regs) | 958 | static int emulate_instruction(struct pt_regs *regs) |
936 | { | 959 | { |
937 | u32 instword; | 960 | u32 instword; |
@@ -971,6 +994,9 @@ static int emulate_instruction(struct pt_regs *regs) | |||
971 | 994 | ||
972 | /* Emulate load/store string insn. */ | 995 | /* Emulate load/store string insn. */ |
973 | if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { | 996 | if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { |
997 | if (tm_abort_check(regs, | ||
998 | TM_CAUSE_EMULATE | TM_CAUSE_PERSISTENT)) | ||
999 | return -EINVAL; | ||
974 | PPC_WARN_EMULATED(string, regs); | 1000 | PPC_WARN_EMULATED(string, regs); |
975 | return emulate_string_inst(regs, instword); | 1001 | return emulate_string_inst(regs, instword); |
976 | } | 1002 | } |
@@ -1148,6 +1174,9 @@ void alignment_exception(struct pt_regs *regs) | |||
1148 | if (!arch_irq_disabled_regs(regs)) | 1174 | if (!arch_irq_disabled_regs(regs)) |
1149 | local_irq_enable(); | 1175 | local_irq_enable(); |
1150 | 1176 | ||
1177 | if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT)) | ||
1178 | goto bail; | ||
1179 | |||
1151 | /* we don't implement logging of alignment exceptions */ | 1180 | /* we don't implement logging of alignment exceptions */ |
1152 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) | 1181 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) |
1153 | fixed = fix_alignment(regs); | 1182 | fixed = fix_alignment(regs); |