|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 4/5] xen/wait: Use relative stack adjustments
On 18.07.2022 09:18, Andrew Cooper wrote:
> @@ -121,11 +121,11 @@ void wake_up_all(struct waitqueue_head *wq)
>
> static void __prepare_to_wait(struct waitqueue_vcpu *wqv)
> {
> - struct cpu_info *cpu_info = get_cpu_info();
> struct vcpu *curr = current;
> unsigned long dummy;
> + unsigned int used;
>
> - ASSERT(wqv->esp == 0);
> + ASSERT(wqv->used == 0);
Minor: Use ! like you do further down?
> @@ -154,24 +154,25 @@ static void __prepare_to_wait(struct waitqueue_vcpu
> *wqv)
> "push %%rbx; push %%rbp; push %%r12;"
> "push %%r13; push %%r14; push %%r15;"
>
> - "sub %%esp,%%ecx;"
> + "sub %%esp, %%ecx;" /* ecx = delta to cpu_info */
> "cmp %[sz], %%ecx;"
> "ja .L_skip;" /* Bail if >4k */
According to the inputs, %eax is still 0 when bailing here, so the
check below won't find "used > PAGE_SIZE". I further wonder why you
don't store directly into wqv->used, and go through %eax instead.
> - "mov %%rsp,%%rsi;"
> +
> + "mov %%ecx, %%eax;"
> + "mov %%rsp, %%rsi;" /* Copy from the stack, into wqv->stack */
>
> /* check_wakeup_from_wait() longjmp()'s to this point. */
> ".L_wq_resume: rep movsb;"
> - "mov %%rsp,%%rsi;"
>
> ".L_skip:"
> "pop %%r15; pop %%r14; pop %%r13;"
> "pop %%r12; pop %%rbp; pop %%rbx;"
> - : "=&S" (wqv->esp), "=&c" (dummy), "=&D" (dummy)
> - : "0" (0), "1" (cpu_info), "2" (wqv->stack),
> + : "=a" (used), "=D" (dummy), "=c" (dummy), "=&S" (dummy)
You can't validly drop & from =D and =c. If you want to stick to
going through %eax, I think that one wants & added as well and ...
> + : "a" (0), "D" (wqv->stack), "c" (get_cpu_info()),
... the (unused) input here dropped.
> @@ -220,14 +224,22 @@ void check_wakeup_from_wait(void)
> * the rep movs in __prepare_to_wait(), it copies from wqv->stack over
> the
> * active stack.
> *
> + * We are also bound by __prepare_to_wait()'s output constraints, so %eax
> + * needs to be wqv->used.
> + *
> * All other GPRs are available for use; they're either restored from
> * wqv->stack or explicitly clobbered.
> */
> - asm volatile ( "mov %%rdi, %%rsp;"
> + asm volatile ( "sub %%esp, %k[var];" /* var = delta to cpu_info */
> + "neg %k[var];"
> + "add %%ecx, %k[var];" /* var = -delta + wqv->used */
> +
> + "sub %[var], %%rsp;" /* Adjust %rsp down to make room */
> + "mov %%rsp, %%rdi;" /* Copy from wqv->stack, into the
> stack */
> "jmp .L_wq_resume;"
> - :
> - : "S" (wqv->stack), "D" (wqv->esp),
> - "c" ((char *)get_cpu_info() - (char *)wqv->esp)
> + : "=D" (tmp), [var] "=&r" (tmp)
> + : "S" (wqv->stack), "c" (wqv->used), "a" (wqv->used),
If you want to stick to going through %eax, then I think you need to
make it an output here: "+a" (wqv->used), so it is clear that the
register is blocked from any other use throughout the asm(). Or you
could use "=&a" and copy %ecx into %eax inside the asm(). Both may
cause the compiler to emit dead code updating wqv->used right after
the asm(), so I think not going through %eax is the more desirable
approach (but I may well be overlooking a reason why directly
dealing with wqv->used in __prepare_to_wait() isn't an option).
Strictly speaking (in particular if [right now] there wasn't just a
branch after updating %rdi) you also again want "=&D" here.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |