From: Andrey Ryabinin <[email protected]>

vfree() is going to use sleeping lock. free_ldt_struct()
may be called with disabled preemption, therefore we must
use vfree_atomic() here.

E.g. call trace:
        vfree()
        free_ldt_struct()
        destroy_context_ldt()
        __mmdrop()
        finish_task_switch()
        schedule_tail()
        ret_from_fork()

Signed-off-by: Andrey Ryabinin <[email protected]>
---
 arch/x86/kernel/ldt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index 6707039..4d12cdf 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -93,7 +93,7 @@ static void free_ldt_struct(struct ldt_struct *ldt)
 
        paravirt_free_ldt(ldt->entries, ldt->size);
        if (ldt->size * LDT_ENTRY_SIZE > PAGE_SIZE)
-               vfree(ldt->entries);
+               vfree_atomic(ldt->entries);
        else
                free_page((unsigned long)ldt->entries);
        kfree(ldt);
-- 
2.1.4

Reply via email to