From ad4c200cd2b4b9e45362786a8c31d83ab6202e2c Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 18 Oct 2021 23:34:35 -0500 Subject: [PATCH] linuxkm: wolfcrypt/src/memory.c: in {save,restore}_vector_registers_x86(), allow for recursive calls (some crypto calls are recursive). --- wolfcrypt/src/memory.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 49b4fb78b..314a3a82f 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -1241,16 +1241,18 @@ union fpregs_state **wolfcrypt_irq_fpu_states = NULL; return BAD_STATE_E; } - /* check for nested interrupts -- doesn't exist on x86, but make - * sure, in case something changes. - */ - if (((char *)wolfcrypt_irq_fpu_states[processor_id])[PAGE_SIZE-1] != 0) { - preempt_enable(); - pr_err("save_vector_registers_x86 called recursively for " - "cpu id %d.\n", processor_id); - return BAD_STATE_E; + /* allow for recursive calls (some crypto calls are recursive) */ + if (((unsigned char *)wolfcrypt_irq_fpu_states[processor_id])[PAGE_SIZE-1] != 0) { + if (((unsigned char *)wolfcrypt_irq_fpu_states[processor_id])[PAGE_SIZE-1] == 255) { + preempt_enable(); + pr_err("save_vector_registers_x86 recursion register overflow for " + "cpu id %d.\n", processor_id); + return BAD_STATE_E; + } else { + ++((char *)wolfcrypt_irq_fpu_states[processor_id])[PAGE_SIZE-1]; + return 0; + } } - /* note, fpregs_lock() is not needed here, because * interrupts/preemptions are already disabled here. */ @@ -1292,12 +1294,14 @@ union fpregs_state **wolfcrypt_irq_fpu_states = NULL; int processor_id = __smp_processor_id(); if ((wolfcrypt_irq_fpu_states == NULL) || (wolfcrypt_irq_fpu_states[processor_id] == NULL) || - (((char *)wolfcrypt_irq_fpu_states[processor_id])[PAGE_SIZE-1] == 0)) + (((unsigned char *)wolfcrypt_irq_fpu_states[processor_id])[PAGE_SIZE-1] == 0)) { pr_err("restore_vector_registers_x86 called for cpu id %d " "without saved context.\n", processor_id); preempt_enable(); /* just in case */ return; + } else if (--((unsigned char *)wolfcrypt_irq_fpu_states[processor_id])[PAGE_SIZE-1] > 0) { + return; } else { #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0) copy_kernel_to_fpregs(wolfcrypt_irq_fpu_states[processor_id]);