Loading arch/x86/kernel/entry_64.S +48 −46 Original line number Diff line number Diff line Loading @@ -1231,22 +1231,24 @@ END(call_softirq) zeroentry xen_hypervisor_callback xen_do_hypervisor_callback /* # A note on the "critical region" in our callback handler. # We want to avoid stacking callback handlers due to events occurring # during handling of the last event. To do this, we keep events disabled # until we've done all processing. HOWEVER, we must enable events before # popping the stack frame (can't be done atomically) and so it would still # be possible to get enough handler activations to overflow the stack. # Although unlikely, bugs of that kind are hard to track down, so we'd # like to avoid the possibility. # So, on entry to the handler we detect whether we interrupted an # existing activation in its critical region -- if so, we pop the current # activation and restart the handler using the previous one. * A note on the "critical region" in our callback handler. * We want to avoid stacking callback handlers due to events occurring * during handling of the last event. To do this, we keep events disabled * until we've done all processing. HOWEVER, we must enable events before * popping the stack frame (can't be done atomically) and so it would still * be possible to get enough handler activations to overflow the stack. * Although unlikely, bugs of that kind are hard to track down, so we'd * like to avoid the possibility. * So, on entry to the handler we detect whether we interrupted an * existing activation in its critical region -- if so, we pop the current * activation and restart the handler using the previous one. */ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) CFI_STARTPROC /* Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will see the correct pointer to the pt_regs */ /* * Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will * see the correct pointer to the pt_regs */ movq %rdi, %rsp # we don't return, adjust the stack frame CFI_ENDPROC DEFAULT_FRAME Loading @@ -1264,17 +1266,17 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) END(do_hypervisor_callback) /* # Hypervisor uses this for application faults while it executes. # We get here for two reasons: # 1. Fault while reloading DS, ES, FS or GS # 2. Fault while executing IRET # Category 1 we do not need to fix up as Xen has already reloaded all segment # registers that could be reloaded and zeroed the others. # Category 2 we fix up by killing the current process. We cannot use the # normal Linux return path in this case because if we use the IRET hypercall # to pop the stack frame we end up in an infinite loop of failsafe callbacks. # We distinguish between categories by comparing each saved segment register # with its current contents: any discrepancy means we in category 1. * Hypervisor uses this for application faults while it executes. * We get here for two reasons: * 1. Fault while reloading DS, ES, FS or GS * 2. Fault while executing IRET * Category 1 we do not need to fix up as Xen has already reloaded all segment * registers that could be reloaded and zeroed the others. * Category 2 we fix up by killing the current process. We cannot use the * normal Linux return path in this case because if we use the IRET hypercall * to pop the stack frame we end up in an infinite loop of failsafe callbacks. * We distinguish between categories by comparing each saved segment register * with its current contents: any discrepancy means we in category 1. */ ENTRY(xen_failsafe_callback) INTR_FRAME 1 (6*8) Loading Loading
arch/x86/kernel/entry_64.S +48 −46 Original line number Diff line number Diff line Loading @@ -1231,22 +1231,24 @@ END(call_softirq) zeroentry xen_hypervisor_callback xen_do_hypervisor_callback /* # A note on the "critical region" in our callback handler. # We want to avoid stacking callback handlers due to events occurring # during handling of the last event. To do this, we keep events disabled # until we've done all processing. HOWEVER, we must enable events before # popping the stack frame (can't be done atomically) and so it would still # be possible to get enough handler activations to overflow the stack. # Although unlikely, bugs of that kind are hard to track down, so we'd # like to avoid the possibility. # So, on entry to the handler we detect whether we interrupted an # existing activation in its critical region -- if so, we pop the current # activation and restart the handler using the previous one. * A note on the "critical region" in our callback handler. * We want to avoid stacking callback handlers due to events occurring * during handling of the last event. To do this, we keep events disabled * until we've done all processing. HOWEVER, we must enable events before * popping the stack frame (can't be done atomically) and so it would still * be possible to get enough handler activations to overflow the stack. * Although unlikely, bugs of that kind are hard to track down, so we'd * like to avoid the possibility. * So, on entry to the handler we detect whether we interrupted an * existing activation in its critical region -- if so, we pop the current * activation and restart the handler using the previous one. */ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) CFI_STARTPROC /* Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will see the correct pointer to the pt_regs */ /* * Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will * see the correct pointer to the pt_regs */ movq %rdi, %rsp # we don't return, adjust the stack frame CFI_ENDPROC DEFAULT_FRAME Loading @@ -1264,17 +1266,17 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) END(do_hypervisor_callback) /* # Hypervisor uses this for application faults while it executes. # We get here for two reasons: # 1. Fault while reloading DS, ES, FS or GS # 2. Fault while executing IRET # Category 1 we do not need to fix up as Xen has already reloaded all segment # registers that could be reloaded and zeroed the others. # Category 2 we fix up by killing the current process. We cannot use the # normal Linux return path in this case because if we use the IRET hypercall # to pop the stack frame we end up in an infinite loop of failsafe callbacks. # We distinguish between categories by comparing each saved segment register # with its current contents: any discrepancy means we in category 1. * Hypervisor uses this for application faults while it executes. * We get here for two reasons: * 1. Fault while reloading DS, ES, FS or GS * 2. Fault while executing IRET * Category 1 we do not need to fix up as Xen has already reloaded all segment * registers that could be reloaded and zeroed the others. * Category 2 we fix up by killing the current process. We cannot use the * normal Linux return path in this case because if we use the IRET hypercall * to pop the stack frame we end up in an infinite loop of failsafe callbacks. * We distinguish between categories by comparing each saved segment register * with its current contents: any discrepancy means we in category 1. */ ENTRY(xen_failsafe_callback) INTR_FRAME 1 (6*8) Loading