* [PATCH 0/3][linux-yocto-3.0] EFI support backports
@ 2011-12-07 19:19 Darren Hart
2011-12-07 19:19 ` [PATCH 1/3] x86/rtc: Don't recursively acquire rtc_lock Darren Hart
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Darren Hart @ 2011-12-07 19:19 UTC (permalink / raw)
To: yocto, Bruce Ashfield, Tom Zanussi
From: Darren Hart <dvhart@linux.intel.com>
The following patches have been merged back from upstream to address various
issues with the EFI boot process. These are intended to be merged with
yocto/standard/base.
Please watch for a subsequent patch adding a series of efi config fragments.
The following changes since commit ab1de8c21d2b1d084b8488496d75cc54fcd94f02:
Merge commit 'v3.0.10' into yocto/standard/base (2011-11-23 00:31:29 -0500)
are available in the git repository at:
git://git.infradead.org/users/dvhart/linux-yocto-3.0.git dvhart/standard/efi
http://git.infradead.org/users/dvhart/linux-yocto-3.0.git/shortlog/refs/heads/dvhart/standard/efi
Matt Fleming (2):
x86/rtc: Don't recursively acquire rtc_lock
x86, efi: Make efi_call_phys_prelog() CONFIG_RELOCATABLE-aware
Maurice Ma (1):
x86, efi: Convert efi_phys_get_time() args to physical addresses
arch/x86/kernel/rtc.c | 23 ++++++++++++-----------
arch/x86/platform/efi/efi.c | 3 ++-
arch/x86/platform/efi/efi_32.c | 22 +++++++++++++---------
arch/x86/platform/mrst/vrtc.c | 9 +++++++++
4 files changed, 36 insertions(+), 21 deletions(-)
--
1.7.6.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] x86/rtc: Don't recursively acquire rtc_lock
2011-12-07 19:19 [PATCH 0/3][linux-yocto-3.0] EFI support backports Darren Hart
@ 2011-12-07 19:19 ` Darren Hart
2011-12-07 19:19 ` [PATCH 2/3] x86, efi: Make efi_call_phys_prelog() CONFIG_RELOCATABLE-aware Darren Hart
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Darren Hart @ 2011-12-07 19:19 UTC (permalink / raw)
To: yocto, Bruce Ashfield, Tom Zanussi
From: Matt Fleming <matt.fleming@intel.com>
A deadlock was introduced on x86 in commit ef68c8f87ed1 ("x86:
Serialize EFI time accesses on rtc_lock") because efi_get_time()
and friends can be called with rtc_lock already held by
read_persistent_time(), e.g.:
timekeeping_init()
read_persistent_clock() <-- acquire rtc_lock
efi_get_time()
phys_efi_get_time() <-- acquire rtc_lock <DEADLOCK>
To fix this let's push the locking down into the get_wallclock()
and set_wallclock() implementations. Only the clock
implementations that access the x86 RTC directly need to acquire
rtc_lock, so it makes sense to push the locking down into the
rtc, vrtc and efi code.
The virtualization implementations don't require rtc_lock to be
held because they provide their own serialization.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Acked-by: Jan Beulich <jbeulich@novell.com>
Acked-by: Avi Kivity <avi@redhat.com> [for the virtualization aspect]
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Zhang Rui <rui.zhang@intel.com>
Cc: Josh Boyer <jwboyer@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Integrated-by: Darren Hart <dvhart@linux.intel.com>
---
arch/x86/kernel/rtc.c | 23 ++++++++++++-----------
arch/x86/platform/mrst/vrtc.c | 9 +++++++++
2 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 3f2ad26..ccdbc16 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -42,8 +42,11 @@ int mach_set_rtc_mmss(unsigned long nowtime)
{
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
+ unsigned long flags;
int retval = 0;
+ spin_lock_irqsave(&rtc_lock, flags);
+
/* tell the clock it's being set */
save_control = CMOS_READ(RTC_CONTROL);
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
@@ -93,12 +96,17 @@ int mach_set_rtc_mmss(unsigned long nowtime)
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
return retval;
}
unsigned long mach_get_cmos_time(void)
{
unsigned int status, year, mon, day, hour, min, sec, century = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
/*
* If UIP is clear, then we have >= 244 microseconds before
@@ -125,6 +133,8 @@ unsigned long mach_get_cmos_time(void)
status = CMOS_READ(RTC_CONTROL);
WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY));
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) {
sec = bcd2bin(sec);
min = bcd2bin(min);
@@ -169,24 +179,15 @@ EXPORT_SYMBOL(rtc_cmos_write);
int update_persistent_clock(struct timespec now)
{
- unsigned long flags;
- int retval;
-
- spin_lock_irqsave(&rtc_lock, flags);
- retval = x86_platform.set_wallclock(now.tv_sec);
- spin_unlock_irqrestore(&rtc_lock, flags);
-
- return retval;
+ return x86_platform.set_wallclock(now.tv_sec);
}
/* not static: needed by APM */
void read_persistent_clock(struct timespec *ts)
{
- unsigned long retval, flags;
+ unsigned long retval;
- spin_lock_irqsave(&rtc_lock, flags);
retval = x86_platform.get_wallclock();
- spin_unlock_irqrestore(&rtc_lock, flags);
ts->tv_sec = retval;
ts->tv_nsec = 0;
diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c
index 73d70d6..6d5dbcd 100644
--- a/arch/x86/platform/mrst/vrtc.c
+++ b/arch/x86/platform/mrst/vrtc.c
@@ -58,8 +58,11 @@ EXPORT_SYMBOL_GPL(vrtc_cmos_write);
unsigned long vrtc_get_time(void)
{
u8 sec, min, hour, mday, mon;
+ unsigned long flags;
u32 year;
+ spin_lock_irqsave(&rtc_lock, flags);
+
while ((vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP))
cpu_relax();
@@ -70,6 +73,8 @@ unsigned long vrtc_get_time(void)
mon = vrtc_cmos_read(RTC_MONTH);
year = vrtc_cmos_read(RTC_YEAR);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
/* vRTC YEAR reg contains the offset to 1960 */
year += 1960;
@@ -83,8 +88,10 @@ unsigned long vrtc_get_time(void)
int vrtc_set_mmss(unsigned long nowtime)
{
int real_sec, real_min;
+ unsigned long flags;
int vrtc_min;
+ spin_lock_irqsave(&rtc_lock, flags);
vrtc_min = vrtc_cmos_read(RTC_MINUTES);
real_sec = nowtime % 60;
@@ -95,6 +102,8 @@ int vrtc_set_mmss(unsigned long nowtime)
vrtc_cmos_write(real_sec, RTC_SECONDS);
vrtc_cmos_write(real_min, RTC_MINUTES);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
return 0;
}
--
1.7.6.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] x86, efi: Make efi_call_phys_prelog() CONFIG_RELOCATABLE-aware
2011-12-07 19:19 [PATCH 0/3][linux-yocto-3.0] EFI support backports Darren Hart
2011-12-07 19:19 ` [PATCH 1/3] x86/rtc: Don't recursively acquire rtc_lock Darren Hart
@ 2011-12-07 19:19 ` Darren Hart
2011-12-07 19:19 ` [PATCH 3/3] x86, efi: Convert efi_phys_get_time() args to physical addresses Darren Hart
2011-12-07 19:43 ` [PATCH 0/3][linux-yocto-3.0] EFI support backports Bruce Ashfield
3 siblings, 0 replies; 5+ messages in thread
From: Darren Hart @ 2011-12-07 19:19 UTC (permalink / raw)
To: yocto, Bruce Ashfield, Tom Zanussi
From: Matt Fleming <matt.fleming@intel.com>
efi_call_phys_prelog() assumes that the kernel was loaded at a
physical address within the first 8MB of ram, usually
0x1000000. However, this isn't the case with a CONFIG_RELOCATABLE=y
kernel which could have been loaded anywhere in the physical address
space.
Replace the hardcoded pgd_index(0) and pgd_index(PAGE_OFFSET) with the
runtime addresses of the kernel in the physical and virtual space,
respectively.
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Integrated-by: Darren Hart <dvhart@linux.intel.com>
---
arch/x86/platform/efi/efi_32.c | 22 +++++++++++++---------
1 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
index 5cab48e..1156e9a 100644
--- a/arch/x86/platform/efi/efi_32.c
+++ b/arch/x86/platform/efi/efi_32.c
@@ -44,8 +44,12 @@ void efi_call_phys_prelog(void)
{
unsigned long cr4;
unsigned long temp;
+ unsigned long phys_addr, virt_addr;
struct desc_ptr gdt_descr;
+ virt_addr = (unsigned long)_text;
+ phys_addr = virt_addr - PAGE_OFFSET;
+
local_irq_save(efi_rt_eflags);
/*
@@ -57,18 +61,18 @@ void efi_call_phys_prelog(void)
if (cr4 & X86_CR4_PAE) {
efi_bak_pg_dir_pointer[0].pgd =
- swapper_pg_dir[pgd_index(0)].pgd;
- swapper_pg_dir[0].pgd =
- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
+ swapper_pg_dir[pgd_index(phys_addr)].pgd;
+ swapper_pg_dir[pgd_index(phys_addr)].pgd =
+ swapper_pg_dir[pgd_index(virt_addr)].pgd;
} else {
efi_bak_pg_dir_pointer[0].pgd =
- swapper_pg_dir[pgd_index(0)].pgd;
+ swapper_pg_dir[pgd_index(phys_addr)].pgd;
efi_bak_pg_dir_pointer[1].pgd =
- swapper_pg_dir[pgd_index(0x400000)].pgd;
- swapper_pg_dir[pgd_index(0)].pgd =
- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
- temp = PAGE_OFFSET + 0x400000;
- swapper_pg_dir[pgd_index(0x400000)].pgd =
+ swapper_pg_dir[pgd_index(phys_addr + 0x400000)].pgd;
+ swapper_pg_dir[pgd_index(phys_addr)].pgd =
+ swapper_pg_dir[pgd_index(virt_addr)].pgd;
+ temp = virt_addr + 0x400000;
+ swapper_pg_dir[pgd_index(phys_addr + 0x400000)].pgd =
swapper_pg_dir[pgd_index(temp)].pgd;
}
--
1.7.6.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] x86, efi: Convert efi_phys_get_time() args to physical addresses
2011-12-07 19:19 [PATCH 0/3][linux-yocto-3.0] EFI support backports Darren Hart
2011-12-07 19:19 ` [PATCH 1/3] x86/rtc: Don't recursively acquire rtc_lock Darren Hart
2011-12-07 19:19 ` [PATCH 2/3] x86, efi: Make efi_call_phys_prelog() CONFIG_RELOCATABLE-aware Darren Hart
@ 2011-12-07 19:19 ` Darren Hart
2011-12-07 19:43 ` [PATCH 0/3][linux-yocto-3.0] EFI support backports Bruce Ashfield
3 siblings, 0 replies; 5+ messages in thread
From: Darren Hart @ 2011-12-07 19:19 UTC (permalink / raw)
To: yocto, Bruce Ashfield, Tom Zanussi
From: Maurice Ma <maurice.ma@intel.com>
Because callers of efi_phys_get_time() pass virtual stack addresses as
arguments, we need to find their corresponding physical addresses and
when calling GetTime() in physical mode.
Without this patch the following line is printed on boot,
"Oops: efitime: can't read time!"
Cc: Matthew Garrett <mjg@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Maurice Ma <maurice.ma@intel.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Integrated-by: Darren Hart <dvhart@linux.intel.com>
---
arch/x86/platform/efi/efi.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 899e393..4fd8217 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -167,7 +167,8 @@ static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
efi_status_t status;
efi_call_phys_prelog();
- status = efi_call_phys2(efi_phys.get_time, tm, tc);
+ status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm),
+ virt_to_phys(tc));
efi_call_phys_epilog();
return status;
}
--
1.7.6.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/3][linux-yocto-3.0] EFI support backports
2011-12-07 19:19 [PATCH 0/3][linux-yocto-3.0] EFI support backports Darren Hart
` (2 preceding siblings ...)
2011-12-07 19:19 ` [PATCH 3/3] x86, efi: Convert efi_phys_get_time() args to physical addresses Darren Hart
@ 2011-12-07 19:43 ` Bruce Ashfield
3 siblings, 0 replies; 5+ messages in thread
From: Bruce Ashfield @ 2011-12-07 19:43 UTC (permalink / raw)
To: Darren Hart; +Cc: yocto
On 11-12-07 02:19 PM, Darren Hart wrote:
> From: Darren Hart<dvhart@linux.intel.com>
>
> The following patches have been merged back from upstream to address various
> issues with the EFI boot process. These are intended to be merged with
> yocto/standard/base.
>
> Please watch for a subsequent patch adding a series of efi config fragments.
Merged to base and all the BSP branches. I've put it in with my
pending 3.0.12 pull request, which should be out ASAP.
Bruce
>
> The following changes since commit ab1de8c21d2b1d084b8488496d75cc54fcd94f02:
>
> Merge commit 'v3.0.10' into yocto/standard/base (2011-11-23 00:31:29 -0500)
>
> are available in the git repository at:
>
> git://git.infradead.org/users/dvhart/linux-yocto-3.0.git dvhart/standard/efi
> http://git.infradead.org/users/dvhart/linux-yocto-3.0.git/shortlog/refs/heads/dvhart/standard/efi
>
> Matt Fleming (2):
> x86/rtc: Don't recursively acquire rtc_lock
> x86, efi: Make efi_call_phys_prelog() CONFIG_RELOCATABLE-aware
>
> Maurice Ma (1):
> x86, efi: Convert efi_phys_get_time() args to physical addresses
>
> arch/x86/kernel/rtc.c | 23 ++++++++++++-----------
> arch/x86/platform/efi/efi.c | 3 ++-
> arch/x86/platform/efi/efi_32.c | 22 +++++++++++++---------
> arch/x86/platform/mrst/vrtc.c | 9 +++++++++
> 4 files changed, 36 insertions(+), 21 deletions(-)
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-12-07 19:43 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-07 19:19 [PATCH 0/3][linux-yocto-3.0] EFI support backports Darren Hart
2011-12-07 19:19 ` [PATCH 1/3] x86/rtc: Don't recursively acquire rtc_lock Darren Hart
2011-12-07 19:19 ` [PATCH 2/3] x86, efi: Make efi_call_phys_prelog() CONFIG_RELOCATABLE-aware Darren Hart
2011-12-07 19:19 ` [PATCH 3/3] x86, efi: Convert efi_phys_get_time() args to physical addresses Darren Hart
2011-12-07 19:43 ` [PATCH 0/3][linux-yocto-3.0] EFI support backports Bruce Ashfield
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.