Skip to content

Commit f28cd93

Browse files
committed
arch/x86_64:g_current_regs is only used to determine if we are in irq,
with other functionalities removed. Signed-off-by: liwenxiang1 <[email protected]>
1 parent b27dc9e commit f28cd93

File tree

5 files changed

+44
-204
lines changed

5 files changed

+44
-204
lines changed

arch/x86_64/src/common/x86_64_internal.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,6 @@
122122
#define getreg32(p) inl(p)
123123
#define putreg32(v,p) outl(v,p)
124124

125-
/* Macros to handle saving and restore interrupt state. In the current
126-
* model, the state is copied from the stack to the TCB, but only a
127-
* referenced is passed to get the state from the TCB.
128-
*/
129-
130-
#define x86_64_restorestate(regs) (up_set_current_regs(regs))
131-
132125
/* ISR/IRQ stack size */
133126

134127
#if CONFIG_ARCH_INTERRUPTSTACK == 0

arch/x86_64/src/common/x86_64_switchcontext.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
7474
/* Restore addition x86_64 state */
7575

7676
x86_64_restore_auxstate(tcb);
77-
78-
/* Update current regs to signal that we need context switch */
79-
80-
x86_64_restorestate(tcb->xcp.regs);
8177
}
8278

8379
/* We are not in an interrupt handler. Copy the user C context

arch/x86_64/src/intel64/intel64_handlers.c

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
8181
/* Deliver the IRQ */
8282

8383
irq_dispatch(irq, regs);
84+
tcb = this_task();
8485

8586
/* Check for a context switch. If a context switch occurred, then
8687
* g_current_regs will have a different value than it did on entry. If an
8788
* interrupt level context switch has occurred, then the establish the
8889
* correct address environment before returning from the interrupt.
8990
*/
9091

91-
if (regs != up_current_regs())
92+
if (*running_task != tcb)
9293
{
9394
tcb = this_task();
9495

@@ -119,20 +120,12 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
119120
restore_critical_section(tcb, this_cpu());
120121
}
121122

122-
/* If a context switch occurred while processing the interrupt then
123-
* g_current_regs may have change value. If we return any value different
124-
* from the input regs, then the lower level will know that a context
125-
* switch occurred during interrupt processing.
126-
*/
127-
128-
regs = (uint64_t *)up_current_regs();
129-
130123
/* Set g_current_regs to NULL to indicate that we are no longer in an
131124
* interrupt handler.
132125
*/
133126

134127
up_set_current_regs(NULL);
135-
return regs;
128+
return tcb->xcp.regs;
136129
}
137130
#endif
138131

@@ -151,6 +144,7 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
151144
uint64_t *isr_handler(uint64_t *regs, uint64_t irq)
152145
{
153146
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
147+
struct tcb_s *tcb;
154148

155149
if (*running_task != NULL)
156150
{
@@ -196,16 +190,49 @@ uint64_t *isr_handler(uint64_t *regs, uint64_t irq)
196190
break;
197191
}
198192

199-
/* Maybe we need a context switch */
193+
tcb = this_task();
194+
195+
/* Check for a context switch. If a context switch occurred, then
196+
* g_current_regs will have a different value than it did on entry. If an
197+
* interrupt level context switch has occurred, then the establish the
198+
* correct address environment before returning from the interrupt.
199+
*/
200+
201+
if (*running_task != tcb)
202+
{
203+
#ifdef CONFIG_ARCH_ADDRENV
204+
/* Make sure that the address environment for the previously
205+
* running task is closed down gracefully (data caches dump,
206+
* MMU flushed) and set up the address environment for the new
207+
* thread at the head of the ready-to-run list.
208+
*/
209+
210+
addrenv_switch(NULL);
211+
#endif
200212

201-
regs = (uint64_t *)up_current_regs();
213+
/* Update scheduler parameters */
214+
215+
nxsched_suspend_scheduler(*running_task);
216+
nxsched_resume_scheduler(tcb);
217+
218+
/* Record the new "running" task when context switch occurred.
219+
* g_running_tasks[] is only used by assertion logic for reporting
220+
* crashes.
221+
*/
222+
223+
*running_task = tcb;
224+
225+
/* Restore the cpu lock */
226+
227+
restore_critical_section(tcb, this_cpu());
228+
}
202229

203230
/* Set g_current_regs to NULL to indicate that we are no longer in an
204231
* interrupt handler.
205232
*/
206233

207234
up_set_current_regs(NULL);
208-
return regs;
235+
return tcb->xcp.regs;
209236
#endif
210237
}
211238

arch/x86_64/src/intel64/intel64_schedulesigaction.c

Lines changed: 4 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -72,185 +72,19 @@
7272
*
7373
****************************************************************************/
7474

75-
#ifndef CONFIG_SMP
7675
void up_schedule_sigaction(struct tcb_s *tcb)
7776
{
7877
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb,
79-
this_task(), up_current_regs());
80-
81-
/* First, handle some special cases when the signal is being delivered
82-
* to the currently executing task.
83-
*/
84-
85-
if (tcb == this_task())
86-
{
87-
/* CASE 1: We are not in an interrupt handler and a task is
88-
* signalling itself for some reason.
89-
*/
90-
91-
if (!up_current_regs())
92-
{
93-
/* In this case just deliver the signal with a function call
94-
* now.
95-
*/
96-
97-
(tcb->sigdeliver)(tcb);
98-
tcb->sigdeliver = NULL;
99-
}
100-
101-
/* CASE 2: We are in an interrupt handler AND the interrupted task
102-
* is the same as the one that must receive the signal, then we
103-
* will have to modify the return state as well as the state in the
104-
* TCB.
105-
*
106-
* Hmmm... there looks like a latent bug here: The following logic
107-
* would fail in the strange case where we are in an interrupt
108-
* handler, the thread is signalling itself, but a context switch
109-
* to another task has occurred so that current_regs does not
110-
* refer to the thread of this_task()!
111-
*/
112-
113-
else
114-
{
115-
/* Save the return lr and cpsr and one scratch register. These
116-
* will be restored by the signal trampoline after the signals
117-
* have been delivered.
118-
*/
119-
120-
tcb->xcp.saved_rip = up_current_regs()[REG_RIP];
121-
tcb->xcp.saved_rsp = up_current_regs()[REG_RSP];
122-
tcb->xcp.saved_rflags = up_current_regs()[REG_RFLAGS];
123-
124-
/* Then set up to vector to the trampoline with interrupts
125-
* disabled
126-
*/
127-
128-
up_current_regs()[REG_RIP] = (uint64_t)x86_64_sigdeliver;
129-
up_current_regs()[REG_RSP] = up_current_regs()[REG_RSP] - 8;
130-
up_current_regs()[REG_RFLAGS] = 0;
131-
132-
#ifdef CONFIG_ARCH_KERNEL_STACK
133-
/* Update segments to kernel segments */
134-
135-
up_current_regs()[REG_SS] = tcb->xcp.regs[REG_SS];
136-
up_current_regs()[REG_CS] = tcb->xcp.regs[REG_CS];
137-
up_current_regs()[REG_DS] = tcb->xcp.regs[REG_DS];
138-
139-
/* Update RSP to kernel stack */
140-
141-
up_current_regs()[REG_RSP] = (uint64_t)x86_64_get_ktopstk();
142-
#endif
143-
}
144-
}
145-
146-
/* Otherwise, we are (1) signaling a task is not running
147-
* from an interrupt handler or (2) we are not in an
148-
* interrupt handler and the running task is signalling
149-
* some non-running task.
150-
*/
151-
152-
else
153-
{
154-
/* Save the return lr and cpsr and one scratch register
155-
* These will be restored by the signal trampoline after
156-
* the signals have been delivered.
157-
*/
158-
159-
tcb->xcp.saved_rip = tcb->xcp.regs[REG_RIP];
160-
tcb->xcp.saved_rsp = tcb->xcp.regs[REG_RSP];
161-
tcb->xcp.saved_rflags = tcb->xcp.regs[REG_RFLAGS];
162-
163-
/* Then set up to vector to the trampoline with interrupts
164-
* disabled
165-
*/
166-
167-
tcb->xcp.regs[REG_RIP] = (uint64_t)x86_64_sigdeliver;
168-
tcb->xcp.regs[REG_RSP] = tcb->xcp.regs[REG_RSP] - 8;
169-
tcb->xcp.regs[REG_RFLAGS] = 0;
170-
}
171-
}
172-
#else /* !CONFIG_SMP */
173-
void up_schedule_sigaction(struct tcb_s *tcb)
174-
{
175-
int cpu;
176-
int me;
177-
178-
sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb,
179-
this_task(), up_current_regs());
78+
this_task(), this_task()->xcp.regs);
18079

18180
/* First, handle some special cases when the signal is being delivered
18281
* to task that is currently executing on any CPU.
18382
*/
18483

185-
if (tcb->task_state == TSTATE_TASK_RUNNING)
84+
if (tcb == this_task() && !up_interrupt_context())
18685
{
187-
me = this_cpu();
188-
cpu = tcb->cpu;
189-
190-
/* CASE 1: We are not in an interrupt handler and a task is
191-
* signaling itself for some reason.
192-
*/
193-
194-
if (cpu == me && !up_current_regs())
195-
{
196-
/* In this case just deliver the signal now.
197-
* REVISIT: Signal handler will run in a critical section!
198-
*/
199-
200-
(tcb->sigdeliver)(tcb);
201-
tcb->sigdeliver = NULL;
202-
}
203-
204-
/* CASE 2: The task that needs to receive the signal is running.
205-
* This could happen if the task is running on another CPU OR if
206-
* we are in an interrupt handler and the task is running on this
207-
* CPU. In the former case, we will have to PAUSE the other CPU
208-
* first. But in either case, we will have to modify the return
209-
* state as well as the state in the TCB.
210-
*/
211-
212-
else
213-
{
214-
/* tcb is running on the same CPU */
215-
216-
/* Save the return lr and cpsr and one scratch register.
217-
* These will be restored by the signal trampoline after
218-
* the signals have been delivered.
219-
*/
220-
221-
tcb->xcp.saved_rip = up_current_regs()[REG_RIP];
222-
tcb->xcp.saved_rsp = up_current_regs()[REG_RSP];
223-
tcb->xcp.saved_rflags = up_current_regs()[REG_RFLAGS];
224-
225-
/* Then set up to vector to the trampoline with interrupts
226-
* disabled
227-
*/
228-
229-
up_current_regs()[REG_RIP] = (uint64_t)x86_64_sigdeliver;
230-
up_current_regs()[REG_RSP] = up_current_regs()[REG_RSP] - 8;
231-
up_current_regs()[REG_RFLAGS] = 0;
232-
233-
#ifdef CONFIG_ARCH_KERNEL_STACK
234-
/* Update segments to kernel segments */
235-
236-
up_current_regs()[REG_SS] = tcb->xcp.regs[REG_SS];
237-
up_current_regs()[REG_CS] = tcb->xcp.regs[REG_CS];
238-
up_current_regs()[REG_DS] = tcb->xcp.regs[REG_DS];
239-
240-
/* Update RSP to kernel stack */
241-
242-
up_current_regs()[REG_RSP] =
243-
(uint64_t)x86_64_get_ktopstk();
244-
#endif
245-
/* Mark that full context switch is necessary when we
246-
* return from interrupt handler.
247-
* In that case RIP, RSP and RFLAGS are changed, but
248-
* register area pointer remains the same, so we need an
249-
* additional variable to signal the need for full context switch
250-
*/
251-
252-
tcb->xcp.regs[REG_AUX] = REG_AUX_FULLCONTEXT;
253-
}
86+
(tcb->sigdeliver)(tcb);
87+
tcb->sigdeliver = NULL;
25488
}
25589

25690
/* Otherwise, we are (1) signaling a task is not running from an
@@ -278,4 +112,3 @@ void up_schedule_sigaction(struct tcb_s *tcb)
278112
tcb->xcp.regs[REG_RFLAGS] = 0;
279113
}
280114
}
281-
#endif /* CONFIG_SMP */

arch/x86_64/src/intel64/intel64_smpcall.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,7 @@
6060

6161
int x86_64_smp_call_handler(int irq, void *c, void *arg)
6262
{
63-
struct tcb_s *tcb;
64-
int cpu = this_cpu();
65-
66-
tcb = current_task(cpu);
6763
nxsched_smp_call_handler(irq, c, arg);
68-
tcb = current_task(cpu);
69-
x86_64_restorestate(tcb->xcp.regs);
7064

7165
return OK;
7266
}
@@ -93,12 +87,9 @@ int x86_64_smp_call_handler(int irq, void *c, void *arg)
9387

9488
int x86_64_smp_sched_handler(int irq, void *c, void *arg)
9589
{
96-
struct tcb_s *tcb;
9790
int cpu = this_cpu();
9891

9992
nxsched_process_delivered(cpu);
100-
tcb = current_task(cpu);
101-
x86_64_restorestate(tcb->xcp.regs);
10293

10394
return OK;
10495
}

0 commit comments

Comments
 (0)