linux/arch/ia64/kernel/traps.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Architecture-specific trap handling.
   4 *
   5 * Copyright (C) 1998-2003 Hewlett-Packard Co
   6 *      David Mosberger-Tang <davidm@hpl.hp.com>
   7 *
   8 * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/sched/signal.h>
  14#include <linux/sched/debug.h>
  15#include <linux/tty.h>
  16#include <linux/vt_kern.h>              /* For unblank_screen() */
  17#include <linux/export.h>
  18#include <linux/extable.h>
  19#include <linux/hardirq.h>
  20#include <linux/kprobes.h>
  21#include <linux/delay.h>                /* for ssleep() */
  22#include <linux/kdebug.h>
  23#include <linux/uaccess.h>
  24
  25#include <asm/fpswa.h>
  26#include <asm/intrinsics.h>
  27#include <asm/processor.h>
  28#include <asm/exception.h>
  29#include <asm/setup.h>
  30
  31fpswa_interface_t *fpswa_interface;
  32EXPORT_SYMBOL(fpswa_interface);
  33
  34void __init
  35trap_init (void)
  36{
  37        if (ia64_boot_param->fpswa)
  38                /* FPSWA fixup: make the interface pointer a kernel virtual address: */
  39                fpswa_interface = __va(ia64_boot_param->fpswa);
  40}
  41
  42int
  43die (const char *str, struct pt_regs *regs, long err)
  44{
  45        static struct {
  46                spinlock_t lock;
  47                u32 lock_owner;
  48                int lock_owner_depth;
  49        } die = {
  50                .lock = __SPIN_LOCK_UNLOCKED(die.lock),
  51                .lock_owner = -1,
  52                .lock_owner_depth = 0
  53        };
  54        static int die_counter;
  55        int cpu = get_cpu();
  56
  57        if (die.lock_owner != cpu) {
  58                console_verbose();
  59                spin_lock_irq(&die.lock);
  60                die.lock_owner = cpu;
  61                die.lock_owner_depth = 0;
  62                bust_spinlocks(1);
  63        }
  64        put_cpu();
  65
  66        if (++die.lock_owner_depth < 3) {
  67                printk("%s[%d]: %s %ld [%d]\n",
  68                current->comm, task_pid_nr(current), str, err, ++die_counter);
  69                if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
  70                    != NOTIFY_STOP)
  71                        show_regs(regs);
  72                else
  73                        regs = NULL;
  74        } else
  75                printk(KERN_ERR "Recursive die() failure, output suppressed\n");
  76
  77        bust_spinlocks(0);
  78        die.lock_owner = -1;
  79        add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
  80        spin_unlock_irq(&die.lock);
  81
  82        if (!regs)
  83                return 1;
  84
  85        if (panic_on_oops)
  86                panic("Fatal exception");
  87
  88        do_exit(SIGSEGV);
  89        return 0;
  90}
  91
  92int
  93die_if_kernel (char *str, struct pt_regs *regs, long err)
  94{
  95        if (!user_mode(regs))
  96                return die(str, regs, err);
  97        return 0;
  98}
  99
 100void
 101__kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 102{
 103        siginfo_t siginfo;
 104        int sig, code;
 105
 106        /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
 107        siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 108        siginfo.si_imm = break_num;
 109        siginfo.si_flags = 0;           /* clear __ISR_VALID */
 110        siginfo.si_isr = 0;
 111
 112        switch (break_num) {
 113              case 0: /* unknown error (used by GCC for __builtin_abort()) */
 114                if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
 115                                == NOTIFY_STOP)
 116                        return;
 117                if (die_if_kernel("bugcheck!", regs, break_num))
 118                        return;
 119                sig = SIGILL; code = ILL_ILLOPC;
 120                break;
 121
 122              case 1: /* integer divide by zero */
 123                sig = SIGFPE; code = FPE_INTDIV;
 124                break;
 125
 126              case 2: /* integer overflow */
 127                sig = SIGFPE; code = FPE_INTOVF;
 128                break;
 129
 130              case 3: /* range check/bounds check */
 131                sig = SIGFPE; code = FPE_FLTSUB;
 132                break;
 133
 134              case 4: /* null pointer dereference */
 135                sig = SIGSEGV; code = SEGV_MAPERR;
 136                break;
 137
 138              case 5: /* misaligned data */
 139                sig = SIGSEGV; code = BUS_ADRALN;
 140                break;
 141
 142              case 6: /* decimal overflow */
 143                sig = SIGFPE; code = __FPE_DECOVF;
 144                break;
 145
 146              case 7: /* decimal divide by zero */
 147                sig = SIGFPE; code = __FPE_DECDIV;
 148                break;
 149
 150              case 8: /* packed decimal error */
 151                sig = SIGFPE; code = __FPE_DECERR;
 152                break;
 153
 154              case 9: /* invalid ASCII digit */
 155                sig = SIGFPE; code = __FPE_INVASC;
 156                break;
 157
 158              case 10: /* invalid decimal digit */
 159                sig = SIGFPE; code = __FPE_INVDEC;
 160                break;
 161
 162              case 11: /* paragraph stack overflow */
 163                sig = SIGSEGV; code = __SEGV_PSTKOVF;
 164                break;
 165
 166              case 0x3f000 ... 0x3ffff: /* bundle-update in progress */
 167                sig = SIGILL; code = __ILL_BNDMOD;
 168                break;
 169
 170              default:
 171                if ((break_num < 0x40000 || break_num > 0x100000)
 172                    && die_if_kernel("Bad break", regs, break_num))
 173                        return;
 174
 175                if (break_num < 0x80000) {
 176                        sig = SIGILL; code = __ILL_BREAK;
 177                } else {
 178                        if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
 179                                        == NOTIFY_STOP)
 180                                return;
 181                        sig = SIGTRAP; code = TRAP_BRKPT;
 182                }
 183        }
 184        siginfo.si_signo = sig;
 185        siginfo.si_errno = 0;
 186        siginfo.si_code = code;
 187        force_sig_info(sig, &siginfo, current);
 188}
 189
 190/*
 191 * disabled_fph_fault() is called when a user-level process attempts to access f32..f127
 192 * and it doesn't own the fp-high register partition.  When this happens, we save the
 193 * current fph partition in the task_struct of the fpu-owner (if necessary) and then load
 194 * the fp-high partition of the current task (if necessary).  Note that the kernel has
 195 * access to fph by the time we get here, as the IVT's "Disabled FP-Register" handler takes
 196 * care of clearing psr.dfh.
 197 */
 198static inline void
 199disabled_fph_fault (struct pt_regs *regs)
 200{
 201        struct ia64_psr *psr = ia64_psr(regs);
 202
 203        /* first, grant user-level access to fph partition: */
 204        psr->dfh = 0;
 205
 206        /*
 207         * Make sure that no other task gets in on this processor
 208         * while we're claiming the FPU
 209         */
 210        preempt_disable();
 211#ifndef CONFIG_SMP
 212        {
 213                struct task_struct *fpu_owner
 214                        = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
 215
 216                if (ia64_is_local_fpu_owner(current)) {
 217                        preempt_enable_no_resched();
 218                        return;
 219                }
 220
 221                if (fpu_owner)
 222                        ia64_flush_fph(fpu_owner);
 223        }
 224#endif /* !CONFIG_SMP */
 225        ia64_set_local_fpu_owner(current);
 226        if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
 227                __ia64_load_fpu(current->thread.fph);
 228                psr->mfh = 0;
 229        } else {
 230                __ia64_init_fpu();
 231                /*
 232                 * Set mfh because the state in thread.fph does not match the state in
 233                 * the fph partition.
 234                 */
 235                psr->mfh = 1;
 236        }
 237        preempt_enable_no_resched();
 238}
 239
 240static inline int
 241fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
 242            struct pt_regs *regs)
 243{
 244        fp_state_t fp_state;
 245        fpswa_ret_t ret;
 246
 247        if (!fpswa_interface)
 248                return -1;
 249
 250        memset(&fp_state, 0, sizeof(fp_state_t));
 251
 252        /*
 253         * compute fp_state.  only FP registers f6 - f11 are used by the
 254         * kernel, so set those bits in the mask and set the low volatile
 255         * pointer to point to these registers.
 256         */
 257        fp_state.bitmask_low64 = 0xfc0;  /* bit6..bit11 */
 258
 259        fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) &regs->f6;
 260        /*
 261         * unsigned long (*EFI_FPSWA) (
 262         *      unsigned long    trap_type,
 263         *      void             *Bundle,
 264         *      unsigned long    *pipsr,
 265         *      unsigned long    *pfsr,
 266         *      unsigned long    *pisr,
 267         *      unsigned long    *ppreds,
 268         *      unsigned long    *pifs,
 269         *      void             *fp_state);
 270         */
 271        ret = (*fpswa_interface->fpswa)((unsigned long) fp_fault, bundle,
 272                                        (unsigned long *) ipsr, (unsigned long *) fpsr,
 273                                        (unsigned long *) isr, (unsigned long *) pr,
 274                                        (unsigned long *) ifs, &fp_state);
 275
 276        return ret.status;
 277}
 278
 279struct fpu_swa_msg {
 280        unsigned long count;
 281        unsigned long time;
 282};
 283static DEFINE_PER_CPU(struct fpu_swa_msg, cpulast);
 284DECLARE_PER_CPU(struct fpu_swa_msg, cpulast);
 285static struct fpu_swa_msg last __cacheline_aligned;
 286
 287
 288/*
 289 * Handle floating-point assist faults and traps.
 290 */
 291static int
 292handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
 293{
 294        long exception, bundle[2];
 295        unsigned long fault_ip;
 296        struct siginfo siginfo;
 297
 298        fault_ip = regs->cr_iip;
 299        if (!fp_fault && (ia64_psr(regs)->ri == 0))
 300                fault_ip -= 16;
 301        if (copy_from_user(bundle, (void __user *) fault_ip, sizeof(bundle)))
 302                return -1;
 303
 304        if (!(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT))  {
 305                unsigned long count, current_jiffies = jiffies;
 306                struct fpu_swa_msg *cp = this_cpu_ptr(&cpulast);
 307
 308                if (unlikely(current_jiffies > cp->time))
 309                        cp->count = 0;
 310                if (unlikely(cp->count < 5)) {
 311                        cp->count++;
 312                        cp->time = current_jiffies + 5 * HZ;
 313
 314                        /* minimize races by grabbing a copy of count BEFORE checking last.time. */
 315                        count = last.count;
 316                        barrier();
 317
 318                        /*
 319                         * Lower 4 bits are used as a count. Upper bits are a sequence
 320                         * number that is updated when count is reset. The cmpxchg will
 321                         * fail is seqno has changed. This minimizes mutiple cpus
 322                         * resetting the count.
 323                         */
 324                        if (current_jiffies > last.time)
 325                                (void) cmpxchg_acq(&last.count, count, 16 + (count & ~15));
 326
 327                        /* used fetchadd to atomically update the count */
 328                        if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) {
 329                                last.time = current_jiffies + 5 * HZ;
 330                                printk(KERN_WARNING
 331                                        "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
 332                                        current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
 333                        }
 334                }
 335        }
 336
 337        exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
 338                               &regs->cr_ifs, regs);
 339        if (fp_fault) {
 340                if (exception == 0) {
 341                        /* emulation was successful */
 342                        ia64_increment_ip(regs);
 343                } else if (exception == -1) {
 344                        printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 345                        return -1;
 346                } else {
 347                        /* is next instruction a trap? */
 348                        if (exception & 2) {
 349                                ia64_increment_ip(regs);
 350                        }
 351                        siginfo.si_signo = SIGFPE;
 352                        siginfo.si_errno = 0;
 353                        siginfo.si_code = FPE_FIXME;    /* default code */
 354                        siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 355                        if (isr & 0x11) {
 356                                siginfo.si_code = FPE_FLTINV;
 357                        } else if (isr & 0x22) {
 358                                /* denormal operand gets the same si_code as underflow 
 359                                * see arch/i386/kernel/traps.c:math_error()  */
 360                                siginfo.si_code = FPE_FLTUND;
 361                        } else if (isr & 0x44) {
 362                                siginfo.si_code = FPE_FLTDIV;
 363                        }
 364                        siginfo.si_isr = isr;
 365                        siginfo.si_flags = __ISR_VALID;
 366                        siginfo.si_imm = 0;
 367                        force_sig_info(SIGFPE, &siginfo, current);
 368                }
 369        } else {
 370                if (exception == -1) {
 371                        printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 372                        return -1;
 373                } else if (exception != 0) {
 374                        /* raise exception */
 375                        siginfo.si_signo = SIGFPE;
 376                        siginfo.si_errno = 0;
 377                        siginfo.si_code = FPE_FIXME;    /* default code */
 378                        siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 379                        if (isr & 0x880) {
 380                                siginfo.si_code = FPE_FLTOVF;
 381                        } else if (isr & 0x1100) {
 382                                siginfo.si_code = FPE_FLTUND;
 383                        } else if (isr & 0x2200) {
 384                                siginfo.si_code = FPE_FLTRES;
 385                        }
 386                        siginfo.si_isr = isr;
 387                        siginfo.si_flags = __ISR_VALID;
 388                        siginfo.si_imm = 0;
 389                        force_sig_info(SIGFPE, &siginfo, current);
 390                }
 391        }
 392        return 0;
 393}
 394
 395struct illegal_op_return {
 396        unsigned long fkt, arg1, arg2, arg3;
 397};
 398
 399struct illegal_op_return
 400ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
 401                       long arg4, long arg5, long arg6, long arg7,
 402                       struct pt_regs regs)
 403{
 404        struct illegal_op_return rv;
 405        struct siginfo si;
 406        char buf[128];
 407
 408#ifdef CONFIG_IA64_BRL_EMU
 409        {
 410                extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
 411
 412                rv = ia64_emulate_brl(&regs, ec);
 413                if (rv.fkt != (unsigned long) -1)
 414                        return rv;
 415        }
 416#endif
 417
 418        sprintf(buf, "IA-64 Illegal operation fault");
 419        rv.fkt = 0;
 420        if (die_if_kernel(buf, &regs, 0))
 421                return rv;
 422
 423        memset(&si, 0, sizeof(si));
 424        si.si_signo = SIGILL;
 425        si.si_code = ILL_ILLOPC;
 426        si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
 427        force_sig_info(SIGILL, &si, current);
 428        return rv;
 429}
 430
 431void __kprobes
 432ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 433            unsigned long iim, unsigned long itir, long arg5, long arg6,
 434            long arg7, struct pt_regs regs)
 435{
 436        unsigned long code, error = isr, iip;
 437        struct siginfo siginfo;
 438        char buf[128];
 439        int result, sig;
 440        static const char *reason[] = {
 441                "IA-64 Illegal Operation fault",
 442                "IA-64 Privileged Operation fault",
 443                "IA-64 Privileged Register fault",
 444                "IA-64 Reserved Register/Field fault",
 445                "Disabled Instruction Set Transition fault",
 446                "Unknown fault 5", "Unknown fault 6", "Unknown fault 7", "Illegal Hazard fault",
 447                "Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12",
 448                "Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
 449        };
 450
 451        if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
 452                /*
 453                 * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
 454                 * the lfetch.
 455                 */
 456                ia64_psr(&regs)->ed = 1;
 457                return;
 458        }
 459
 460        iip = regs.cr_iip + ia64_psr(&regs)->ri;
 461
 462        switch (vector) {
 463              case 24: /* General Exception */
 464                code = (isr >> 4) & 0xf;
 465                sprintf(buf, "General Exception: %s%s", reason[code],
 466                        (code == 3) ? ((isr & (1UL << 37))
 467                                       ? " (RSE access)" : " (data access)") : "");
 468                if (code == 8) {
 469# ifdef CONFIG_IA64_PRINT_HAZARDS
 470                        printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
 471                               current->comm, task_pid_nr(current),
 472                               regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);
 473# endif
 474                        return;
 475                }
 476                break;
 477
 478              case 25: /* Disabled FP-Register */
 479                if (isr & 2) {
 480                        disabled_fph_fault(&regs);
 481                        return;
 482                }
 483                sprintf(buf, "Disabled FPL fault---not supposed to happen!");
 484                break;
 485
 486              case 26: /* NaT Consumption */
 487                if (user_mode(&regs)) {
 488                        void __user *addr;
 489
 490                        if (((isr >> 4) & 0xf) == 2) {
 491                                /* NaT page consumption */
 492                                sig = SIGSEGV;
 493                                code = SEGV_ACCERR;
 494                                addr = (void __user *) ifa;
 495                        } else {
 496                                /* register NaT consumption */
 497                                sig = SIGILL;
 498                                code = ILL_ILLOPN;
 499                                addr = (void __user *) (regs.cr_iip
 500                                                        + ia64_psr(&regs)->ri);
 501                        }
 502                        siginfo.si_signo = sig;
 503                        siginfo.si_code = code;
 504                        siginfo.si_errno = 0;
 505                        siginfo.si_addr = addr;
 506                        siginfo.si_imm = vector;
 507                        siginfo.si_flags = __ISR_VALID;
 508                        siginfo.si_isr = isr;
 509                        force_sig_info(sig, &siginfo, current);
 510                        return;
 511                } else if (ia64_done_with_exception(&regs))
 512                        return;
 513                sprintf(buf, "NaT consumption");
 514                break;
 515
 516              case 31: /* Unsupported Data Reference */
 517                if (user_mode(&regs)) {
 518                        siginfo.si_signo = SIGILL;
 519                        siginfo.si_code = ILL_ILLOPN;
 520                        siginfo.si_errno = 0;
 521                        siginfo.si_addr = (void __user *) iip;
 522                        siginfo.si_imm = vector;
 523                        siginfo.si_flags = __ISR_VALID;
 524                        siginfo.si_isr = isr;
 525                        force_sig_info(SIGILL, &siginfo, current);
 526                        return;
 527                }
 528                sprintf(buf, "Unsupported data reference");
 529                break;
 530
 531              case 29: /* Debug */
 532              case 35: /* Taken Branch Trap */
 533              case 36: /* Single Step Trap */
 534                if (fsys_mode(current, &regs)) {
 535                        extern char __kernel_syscall_via_break[];
 536                        /*
 537                         * Got a trap in fsys-mode: Taken Branch Trap
 538                         * and Single Step trap need special handling;
 539                         * Debug trap is ignored (we disable it here
 540                         * and re-enable it in the lower-privilege trap).
 541                         */
 542                        if (unlikely(vector == 29)) {
 543                                set_thread_flag(TIF_DB_DISABLED);
 544                                ia64_psr(&regs)->db = 0;
 545                                ia64_psr(&regs)->lp = 1;
 546                                return;
 547                        }
 548                        /* re-do the system call via break 0x100000: */
 549                        regs.cr_iip = (unsigned long) __kernel_syscall_via_break;
 550                        ia64_psr(&regs)->ri = 0;
 551                        ia64_psr(&regs)->cpl = 3;
 552                        return;
 553                }
 554                switch (vector) {
 555                      default:
 556                      case 29:
 557                        siginfo.si_code = TRAP_HWBKPT;
 558#ifdef CONFIG_ITANIUM
 559                        /*
 560                         * Erratum 10 (IFA may contain incorrect address) now has
 561                         * "NoFix" status.  There are no plans for fixing this.
 562                         */
 563                        if (ia64_psr(&regs)->is == 0)
 564                          ifa = regs.cr_iip;
 565#endif
 566                        break;
 567                      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
 568                      case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
 569                }
 570                if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP)
 571                                == NOTIFY_STOP)
 572                        return;
 573                siginfo.si_signo = SIGTRAP;
 574                siginfo.si_errno = 0;
 575                siginfo.si_addr  = (void __user *) ifa;
 576                siginfo.si_imm   = 0;
 577                siginfo.si_flags = __ISR_VALID;
 578                siginfo.si_isr   = isr;
 579                force_sig_info(SIGTRAP, &siginfo, current);
 580                return;
 581
 582              case 32: /* fp fault */
 583              case 33: /* fp trap */
 584                result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr);
 585                if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
 586                        siginfo.si_signo = SIGFPE;
 587                        siginfo.si_errno = 0;
 588                        siginfo.si_code = FPE_FLTINV;
 589                        siginfo.si_addr = (void __user *) iip;
 590                        siginfo.si_flags = __ISR_VALID;
 591                        siginfo.si_isr = isr;
 592                        siginfo.si_imm = 0;
 593                        force_sig_info(SIGFPE, &siginfo, current);
 594                }
 595                return;
 596
 597              case 34:
 598                if (isr & 0x2) {
 599                        /* Lower-Privilege Transfer Trap */
 600
 601                        /* If we disabled debug traps during an fsyscall,
 602                         * re-enable them here.
 603                         */
 604                        if (test_thread_flag(TIF_DB_DISABLED)) {
 605                                clear_thread_flag(TIF_DB_DISABLED);
 606                                ia64_psr(&regs)->db = 1;
 607                        }
 608
 609                        /*
 610                         * Just clear PSR.lp and then return immediately:
 611                         * all the interesting work (e.g., signal delivery)
 612                         * is done in the kernel exit path.
 613                         */
 614                        ia64_psr(&regs)->lp = 0;
 615                        return;
 616                } else {
 617                        /* Unimplemented Instr. Address Trap */
 618                        if (user_mode(&regs)) {
 619                                siginfo.si_signo = SIGILL;
 620                                siginfo.si_code = ILL_BADIADDR;
 621                                siginfo.si_errno = 0;
 622                                siginfo.si_flags = 0;
 623                                siginfo.si_isr = 0;
 624                                siginfo.si_imm = 0;
 625                                siginfo.si_addr = (void __user *) iip;
 626                                force_sig_info(SIGILL, &siginfo, current);
 627                                return;
 628                        }
 629                        sprintf(buf, "Unimplemented Instruction Address fault");
 630                }
 631                break;
 632
 633              case 45:
 634                printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
 635                printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
 636                       iip, ifa, isr);
 637                force_sig(SIGSEGV, current);
 638                return;
 639
 640              case 46:
 641                printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
 642                printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
 643                       iip, ifa, isr, iim);
 644                force_sig(SIGSEGV, current);
 645                return;
 646
 647              case 47:
 648                sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
 649                break;
 650
 651              default:
 652                sprintf(buf, "Fault %lu", vector);
 653                break;
 654        }
 655        if (!die_if_kernel(buf, &regs, error))
 656                force_sig(SIGILL, current);
 657}
 658