Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] EFI x86: pass firmware call parameters on the stack

When calling into the EFI firmware, the parameters need to be passed on
the stack. The recent change to use -mregparm=3 breaks x86 EFI support.
This patch is needed to allow the new Intel-based Macs to suspend to ram
(efi.get_time is called during the suspend phase).

Signed-off-by: Frederic Riss <frederic.riss@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Frédéric Riss and committed by
Linus Torvalds
40c373cc 886ae1fa

+73 -16
+73 -16
arch/i386/kernel/efi.c
··· 473 473 } 474 474 475 475 /* 476 + * Wrap all the virtual calls in a way that forces the parameters on the stack. 477 + */ 478 + 479 + #define efi_call_virt(f, args...) \ 480 + ((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args) 481 + 482 + static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) 483 + { 484 + return efi_call_virt(get_time, tm, tc); 485 + } 486 + 487 + static efi_status_t virt_efi_set_time (efi_time_t *tm) 488 + { 489 + return efi_call_virt(set_time, tm); 490 + } 491 + 492 + static efi_status_t virt_efi_get_wakeup_time (efi_bool_t *enabled, 493 + efi_bool_t *pending, 494 + efi_time_t *tm) 495 + { 496 + return efi_call_virt(get_wakeup_time, enabled, pending, tm); 497 + } 498 + 499 + static efi_status_t virt_efi_set_wakeup_time (efi_bool_t enabled, 500 + efi_time_t *tm) 501 + { 502 + return efi_call_virt(set_wakeup_time, enabled, tm); 503 + } 504 + 505 + static efi_status_t virt_efi_get_variable (efi_char16_t *name, 506 + efi_guid_t *vendor, u32 *attr, 507 + unsigned long *data_size, void *data) 508 + { 509 + return efi_call_virt(get_variable, name, vendor, attr, data_size, data); 510 + } 511 + 512 + static efi_status_t virt_efi_get_next_variable (unsigned long *name_size, 513 + efi_char16_t *name, 514 + efi_guid_t *vendor) 515 + { 516 + return efi_call_virt(get_next_variable, name_size, name, vendor); 517 + } 518 + 519 + static efi_status_t virt_efi_set_variable (efi_char16_t *name, 520 + efi_guid_t *vendor, 521 + unsigned long attr, 522 + unsigned long data_size, void *data) 523 + { 524 + return efi_call_virt(set_variable, name, vendor, attr, data_size, data); 525 + } 526 + 527 + static efi_status_t virt_efi_get_next_high_mono_count (u32 *count) 528 + { 529 + return efi_call_virt(get_next_high_mono_count, count); 530 + } 531 + 532 + static void virt_efi_reset_system (int reset_type, efi_status_t status, 533 + unsigned long data_size, 534 + efi_char16_t *data) 535 + { 536 + efi_call_virt(reset_system, reset_type, status, data_size, data); 537 + } 538 + 539 + /* 476 540 * This function will switch the EFI runtime services to virtual mode. 477 541 * Essentially, look through the EFI memmap and map every region that 478 542 * has the runtime attribute bit set in its memory descriptor and update ··· 589 525 * pointers in the runtime service table to the new virtual addresses. 590 526 */ 591 527 592 - efi.get_time = (efi_get_time_t *) efi.systab->runtime->get_time; 593 - efi.set_time = (efi_set_time_t *) efi.systab->runtime->set_time; 594 - efi.get_wakeup_time = (efi_get_wakeup_time_t *) 595 - efi.systab->runtime->get_wakeup_time; 596 - efi.set_wakeup_time = (efi_set_wakeup_time_t *) 597 - efi.systab->runtime->set_wakeup_time; 598 - efi.get_variable = (efi_get_variable_t *) 599 - efi.systab->runtime->get_variable; 600 - efi.get_next_variable = (efi_get_next_variable_t *) 601 - efi.systab->runtime->get_next_variable; 602 - efi.set_variable = (efi_set_variable_t *) 603 - efi.systab->runtime->set_variable; 604 - efi.get_next_high_mono_count = (efi_get_next_high_mono_count_t *) 605 - efi.systab->runtime->get_next_high_mono_count; 606 - efi.reset_system = (efi_reset_system_t *) 607 - efi.systab->runtime->reset_system; 528 + efi.get_time = virt_efi_get_time; 529 + efi.set_time = virt_efi_set_time; 530 + efi.get_wakeup_time = virt_efi_get_wakeup_time; 531 + efi.set_wakeup_time = virt_efi_set_wakeup_time; 532 + efi.get_variable = virt_efi_get_variable; 533 + efi.get_next_variable = virt_efi_get_next_variable; 534 + efi.set_variable = virt_efi_set_variable; 535 + efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; 536 + efi.reset_system = virt_efi_reset_system; 608 537 } 609 538 610 539 void __init