@@ -9,6 +9,7 @@
#include <linux/cache.h>
#include <linux/clocksource.h>
+#include <clocksource/hyperv_timer.h>
#include <linux/elf.h>
#include <linux/err.h>
#include <linux/errno.h>
@@ -105,14 +106,22 @@ static int __vdso_init(enum arch_vdso_type arch_index)
struct page **vdso_code_pagelist;
unsigned long nr_vdso_pages;
unsigned long pfn;
+ struct ms_hyperv_tsc_page *tsc_page;
+ int tsc_page_idx;
if (memcmp(vdso_lookup[arch_index].vdso_code_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
+ /* One vDSO data page */
vdso_lookup[arch_index].nr_vdso_data_pages = 1;
+ /* Grab the Hyper-V tsc page, if enabled, add one more page */
+ tsc_page = hv_get_tsc_page();
+ if (tsc_page)
+ tsc_page_idx = vdso_lookup[arch_index].nr_vdso_data_pages++;
+
vdso_lookup[arch_index].nr_vdso_code_pages = (
vdso_lookup[arch_index].vdso_code_end -
vdso_lookup[arch_index].vdso_code_start) >>
@@ -130,6 +139,9 @@ static int __vdso_init(enum arch_vdso_type arch_index)
/* Grab the vDSO data page. */
vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data));
+ if (tsc_page)
+ vdso_pagelist[tsc_page_idx] = phys_to_page(__pa(tsc_page));
+
/* Grab the vDSO code pages. */
pfn = sym_to_pfn(vdso_lookup[arch_index].vdso_code_start);
@@ -17,7 +17,17 @@ OUTPUT_ARCH(aarch64)
SECTIONS
{
- PROVIDE(_vdso_data = . - PAGE_SIZE);
+ /*
+ * vdso data pages:
+ * vdso data (1 page)
+ * hv tsc page (1 page if enabled)
+ */
+ PROVIDE(_vdso_data = _hvclock_page - PAGE_SIZE);
+#ifdef CONFIG_HYPERV_TIMER
+ PROVIDE(_hvclock_page = . - PAGE_SIZE);
+#else
+ PROVIDE(_hvclock_page = .);
+#endif
. = VDSO_LBASE + SIZEOF_HEADERS;
.hash : { *(.hash) } :text
On Hyper-V, a tsc page has the data for adjusting cntvct numbers to clocksource cycles, and that's how Hyper-V guest kernel reads the clocksource. In order to allow userspace to read the same clocksource directly, the tsc page has to been mapped into userspace via vDSO. Use the framework for vDSO set-up in __vdso_init() to do this. Note: if HYPERV_TIMER=y but the kernel is using other clocksource or doesn't have the hyperv timer clocksource, tsc page will still be mapped into userspace. Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com> --- arch/arm64/kernel/vdso.c | 12 ++++++++++++ arch/arm64/kernel/vdso/vdso.lds.S | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-)