@@ -180,24 +180,21 @@ void efi_sync_low_kernel_mappings(void)
180180static inline phys_addr_t
181181virt_to_phys_or_null_size (void * va , unsigned long size )
182182{
183- bool bad_size ;
183+ phys_addr_t pa ;
184184
185185 if (!va )
186186 return 0 ;
187187
188188 if (virt_addr_valid (va ))
189189 return virt_to_phys (va );
190190
191- /*
192- * A fully aligned variable on the stack is guaranteed not to
193- * cross a page bounary. Try to catch strings on the stack by
194- * checking that 'size' is a power of two.
195- */
196- bad_size = size > PAGE_SIZE || !is_power_of_2 (size );
191+ pa = slow_virt_to_phys (va );
197192
198- WARN_ON (!IS_ALIGNED ((unsigned long )va , size ) || bad_size );
193+ /* check if the object crosses a page boundary */
194+ if (WARN_ON ((pa ^ (pa + size - 1 )) & PAGE_MASK ))
195+ return 0 ;
199196
200- return slow_virt_to_phys ( va ) ;
197+ return pa ;
201198}
202199
203200#define virt_to_phys_or_null (addr ) \
@@ -568,85 +565,25 @@ efi_thunk_set_virtual_address_map(unsigned long memory_map_size,
568565
569566static efi_status_t efi_thunk_get_time (efi_time_t * tm , efi_time_cap_t * tc )
570567{
571- efi_status_t status ;
572- u32 phys_tm , phys_tc ;
573- unsigned long flags ;
574-
575- spin_lock (& rtc_lock );
576- spin_lock_irqsave (& efi_runtime_lock , flags );
577-
578- phys_tm = virt_to_phys_or_null (tm );
579- phys_tc = virt_to_phys_or_null (tc );
580-
581- status = efi_thunk (get_time , phys_tm , phys_tc );
582-
583- spin_unlock_irqrestore (& efi_runtime_lock , flags );
584- spin_unlock (& rtc_lock );
585-
586- return status ;
568+ return EFI_UNSUPPORTED ;
587569}
588570
589571static efi_status_t efi_thunk_set_time (efi_time_t * tm )
590572{
591- efi_status_t status ;
592- u32 phys_tm ;
593- unsigned long flags ;
594-
595- spin_lock (& rtc_lock );
596- spin_lock_irqsave (& efi_runtime_lock , flags );
597-
598- phys_tm = virt_to_phys_or_null (tm );
599-
600- status = efi_thunk (set_time , phys_tm );
601-
602- spin_unlock_irqrestore (& efi_runtime_lock , flags );
603- spin_unlock (& rtc_lock );
604-
605- return status ;
573+ return EFI_UNSUPPORTED ;
606574}
607575
608576static efi_status_t
609577efi_thunk_get_wakeup_time (efi_bool_t * enabled , efi_bool_t * pending ,
610578 efi_time_t * tm )
611579{
612- efi_status_t status ;
613- u32 phys_enabled , phys_pending , phys_tm ;
614- unsigned long flags ;
615-
616- spin_lock (& rtc_lock );
617- spin_lock_irqsave (& efi_runtime_lock , flags );
618-
619- phys_enabled = virt_to_phys_or_null (enabled );
620- phys_pending = virt_to_phys_or_null (pending );
621- phys_tm = virt_to_phys_or_null (tm );
622-
623- status = efi_thunk (get_wakeup_time , phys_enabled ,
624- phys_pending , phys_tm );
625-
626- spin_unlock_irqrestore (& efi_runtime_lock , flags );
627- spin_unlock (& rtc_lock );
628-
629- return status ;
580+ return EFI_UNSUPPORTED ;
630581}
631582
632583static efi_status_t
633584efi_thunk_set_wakeup_time (efi_bool_t enabled , efi_time_t * tm )
634585{
635- efi_status_t status ;
636- u32 phys_tm ;
637- unsigned long flags ;
638-
639- spin_lock (& rtc_lock );
640- spin_lock_irqsave (& efi_runtime_lock , flags );
641-
642- phys_tm = virt_to_phys_or_null (tm );
643-
644- status = efi_thunk (set_wakeup_time , enabled , phys_tm );
645-
646- spin_unlock_irqrestore (& efi_runtime_lock , flags );
647- spin_unlock (& rtc_lock );
648-
649- return status ;
586+ return EFI_UNSUPPORTED ;
650587}
651588
652589static unsigned long efi_name_size (efi_char16_t * name )
@@ -658,21 +595,28 @@ static efi_status_t
658595efi_thunk_get_variable (efi_char16_t * name , efi_guid_t * vendor ,
659596 u32 * attr , unsigned long * data_size , void * data )
660597{
598+ u8 buf [24 ] __aligned (8 );
599+ efi_guid_t * vnd = PTR_ALIGN ((efi_guid_t * )buf , sizeof (* vnd ));
661600 efi_status_t status ;
662601 u32 phys_name , phys_vendor , phys_attr ;
663602 u32 phys_data_size , phys_data ;
664603 unsigned long flags ;
665604
666605 spin_lock_irqsave (& efi_runtime_lock , flags );
667606
607+ * vnd = * vendor ;
608+
668609 phys_data_size = virt_to_phys_or_null (data_size );
669- phys_vendor = virt_to_phys_or_null (vendor );
610+ phys_vendor = virt_to_phys_or_null (vnd );
670611 phys_name = virt_to_phys_or_null_size (name , efi_name_size (name ));
671612 phys_attr = virt_to_phys_or_null (attr );
672613 phys_data = virt_to_phys_or_null_size (data , * data_size );
673614
674- status = efi_thunk (get_variable , phys_name , phys_vendor ,
675- phys_attr , phys_data_size , phys_data );
615+ if (!phys_name || (data && !phys_data ))
616+ status = EFI_INVALID_PARAMETER ;
617+ else
618+ status = efi_thunk (get_variable , phys_name , phys_vendor ,
619+ phys_attr , phys_data_size , phys_data );
676620
677621 spin_unlock_irqrestore (& efi_runtime_lock , flags );
678622
@@ -683,19 +627,25 @@ static efi_status_t
683627efi_thunk_set_variable (efi_char16_t * name , efi_guid_t * vendor ,
684628 u32 attr , unsigned long data_size , void * data )
685629{
630+ u8 buf [24 ] __aligned (8 );
631+ efi_guid_t * vnd = PTR_ALIGN ((efi_guid_t * )buf , sizeof (* vnd ));
686632 u32 phys_name , phys_vendor , phys_data ;
687633 efi_status_t status ;
688634 unsigned long flags ;
689635
690636 spin_lock_irqsave (& efi_runtime_lock , flags );
691637
638+ * vnd = * vendor ;
639+
692640 phys_name = virt_to_phys_or_null_size (name , efi_name_size (name ));
693- phys_vendor = virt_to_phys_or_null (vendor );
641+ phys_vendor = virt_to_phys_or_null (vnd );
694642 phys_data = virt_to_phys_or_null_size (data , data_size );
695643
696- /* If data_size is > sizeof(u32) we've got problems */
697- status = efi_thunk (set_variable , phys_name , phys_vendor ,
698- attr , data_size , phys_data );
644+ if (!phys_name || !phys_data )
645+ status = EFI_INVALID_PARAMETER ;
646+ else
647+ status = efi_thunk (set_variable , phys_name , phys_vendor ,
648+ attr , data_size , phys_data );
699649
700650 spin_unlock_irqrestore (& efi_runtime_lock , flags );
701651
@@ -707,20 +657,26 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor,
707657 u32 attr , unsigned long data_size ,
708658 void * data )
709659{
660+ u8 buf [24 ] __aligned (8 );
661+ efi_guid_t * vnd = PTR_ALIGN ((efi_guid_t * )buf , sizeof (* vnd ));
710662 u32 phys_name , phys_vendor , phys_data ;
711663 efi_status_t status ;
712664 unsigned long flags ;
713665
714666 if (!spin_trylock_irqsave (& efi_runtime_lock , flags ))
715667 return EFI_NOT_READY ;
716668
669+ * vnd = * vendor ;
670+
717671 phys_name = virt_to_phys_or_null_size (name , efi_name_size (name ));
718- phys_vendor = virt_to_phys_or_null (vendor );
672+ phys_vendor = virt_to_phys_or_null (vnd );
719673 phys_data = virt_to_phys_or_null_size (data , data_size );
720674
721- /* If data_size is > sizeof(u32) we've got problems */
722- status = efi_thunk (set_variable , phys_name , phys_vendor ,
723- attr , data_size , phys_data );
675+ if (!phys_name || !phys_data )
676+ status = EFI_INVALID_PARAMETER ;
677+ else
678+ status = efi_thunk (set_variable , phys_name , phys_vendor ,
679+ attr , data_size , phys_data );
724680
725681 spin_unlock_irqrestore (& efi_runtime_lock , flags );
726682
@@ -732,39 +688,36 @@ efi_thunk_get_next_variable(unsigned long *name_size,
732688 efi_char16_t * name ,
733689 efi_guid_t * vendor )
734690{
691+ u8 buf [24 ] __aligned (8 );
692+ efi_guid_t * vnd = PTR_ALIGN ((efi_guid_t * )buf , sizeof (* vnd ));
735693 efi_status_t status ;
736694 u32 phys_name_size , phys_name , phys_vendor ;
737695 unsigned long flags ;
738696
739697 spin_lock_irqsave (& efi_runtime_lock , flags );
740698
699+ * vnd = * vendor ;
700+
741701 phys_name_size = virt_to_phys_or_null (name_size );
742- phys_vendor = virt_to_phys_or_null (vendor );
702+ phys_vendor = virt_to_phys_or_null (vnd );
743703 phys_name = virt_to_phys_or_null_size (name , * name_size );
744704
745- status = efi_thunk (get_next_variable , phys_name_size ,
746- phys_name , phys_vendor );
705+ if (!phys_name )
706+ status = EFI_INVALID_PARAMETER ;
707+ else
708+ status = efi_thunk (get_next_variable , phys_name_size ,
709+ phys_name , phys_vendor );
747710
748711 spin_unlock_irqrestore (& efi_runtime_lock , flags );
749712
713+ * vendor = * vnd ;
750714 return status ;
751715}
752716
753717static efi_status_t
754718efi_thunk_get_next_high_mono_count (u32 * count )
755719{
756- efi_status_t status ;
757- u32 phys_count ;
758- unsigned long flags ;
759-
760- spin_lock_irqsave (& efi_runtime_lock , flags );
761-
762- phys_count = virt_to_phys_or_null (count );
763- status = efi_thunk (get_next_high_mono_count , phys_count );
764-
765- spin_unlock_irqrestore (& efi_runtime_lock , flags );
766-
767- return status ;
720+ return EFI_UNSUPPORTED ;
768721}
769722
770723static void
0 commit comments