[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH for-next RFC 0/8] Port Xen to Hyper-V



On Mon, Sep 23, 2019 at 11:09:23AM +0100, Wei Liu wrote:
> Hi all
> 
> In case you're wondering, I can already run a fully fledged Xen system on
> Hyper-V with emulated disk and network.
> 
> This is the very first stage for porting Xen to run on Hyper-V with all the
> goodies Hyper-V has to offer.  With this series, Xen can successfully detect
> Hyper-V and prints out a message.  I would like to first get the directory
> structure and kconfig options agreed upon.
> 
> There are two major areas to be worked on:
>   * Make Dom0 able to use Hyper-V's synthetic devices.
>   * Make Xen use of the synthetic timer, reference TSC and enlightenment VMCS
>     and other interfaces.
> 
> They aren't trivial, and time can be scarce on my side, so I intend to post
> patches piece meal when they are ready.
> 
> Questions and comments are welcome.

Thanks for doing this!

In the past I've played with trying to get Xen to boot as a guest on
HyperV gen2 instances, and I did manage to get it booting, Linux
however would get extremely confused because gen2 lacks emulated
devices and instead the guest is forced to use the HyperV PV devices
AFAIK.

Anyway, I had the following patch on my backlog which allowed me to
boot on gen2 instances, posting it here in case it helps you if you
plan to go that route.

Roger.
---8<---
From 7c9fad735fdc3633ed401befda26c21dc7145af8 Mon Sep 17 00:00:00 2001
From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
Date: Tue, 18 Sep 2018 11:36:42 +0200
Subject: [PATCH] x86/lapic: remove the PIT usage to calibrate the lapic timer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

And instead use NOW which is based on the TSC. This was already used
when running in shim mode, since there's likely no PIT in that
environment.

Remove printing the CPU frequency, since it's already printed earlier
at boot, and getting the CPU frequency against the TSC without any
external reference timer is pointless.

The motivation behind this change is to allow Xen to boot on HyperV
gen2 instances, which lack a PIT.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
I'm not sure about the reason behind the usage of the PIT instead of
the TSC, maybe this was done because the TSC wasn't available until
the Pentium? Xen certainly doesn't care about such hardware anymore,
and the TSC is already used unconditionally in Xen.

Linux seems to prefer to calibrate the lapic timer against the PM
timer and has already dropped PIT usage for that.

My early tests on a single box show no differences between the TSC or
the PIT for lapic timer calibration, but that's a single box.

The RFC is because I'm not sure I understand the motivation for using
the PIT in the first place, so I might be missing something relevant
that could make this patch moot.
---
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 xen/arch/x86/apic.c | 67 ++-------------------------------------------
 1 file changed, 2 insertions(+), 65 deletions(-)

diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index 88ada9d0ec..21dbeb2298 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -1010,46 +1010,6 @@ __next:
 /* used for system time scaling */
 static u32 __read_mostly bus_scale; /* scaling factor: ns -> bus cycles */
 
-/*
- * The timer chip is already set up at HZ interrupts per second here,
- * but we do not accept timer interrupts yet. We only allow the BP
- * to calibrate.
- */
-static unsigned int __init get_8254_timer_count(void)
-{
-    /*extern spinlock_t i8253_lock;*/
-    /*unsigned long flags;*/
-
-    unsigned int count;
-
-    /*spin_lock_irqsave(&i8253_lock, flags);*/
-
-    outb_p(0x00, PIT_MODE);
-    count = inb_p(PIT_CH0);
-    count |= inb_p(PIT_CH0) << 8;
-
-    /*spin_unlock_irqrestore(&i8253_lock, flags);*/
-
-    return count;
-}
-
-/* next tick in 8254 can be caught by catching timer wraparound */
-static void __init wait_8254_wraparound(void)
-{
-    unsigned int curr_count, prev_count;
-    
-    curr_count = get_8254_timer_count();
-    do {
-        prev_count = curr_count;
-        curr_count = get_8254_timer_count();
-
-        /* workaround for broken Mercury/Neptune */
-        if (prev_count >= curr_count + 0x100)
-            curr_count = get_8254_timer_count();
-        
-    } while (prev_count >= curr_count);
-}
-
 /*
  * This function sets up the local APIC timer, with a timeout of
  * 'clocks' APIC bus clock. During calibration we actually call
@@ -1092,7 +1052,7 @@ static void setup_APIC_timer(void)
     local_irq_restore(flags);
 }
 
-static void wait_tick_pvh(void)
+static void wait_tick(void)
 {
     u64 lapse_ns = 1000000000ULL / HZ;
     s_time_t start, curr_time;
@@ -1121,7 +1081,6 @@ static void wait_tick_pvh(void)
 
 static int __init calibrate_APIC_clock(void)
 {
-    unsigned long long t1, t2;
     long tt1, tt2;
     long result;
     int i;
@@ -1138,33 +1097,15 @@ static int __init calibrate_APIC_clock(void)
      */
     __setup_APIC_LVTT(1000000000);
 
-    if ( !xen_guest )
-        /*
-         * The timer chip counts down to zero. Let's wait
-         * for a wraparound to start exact measurement:
-         * (the current tick might have been already half done)
-         */
-        wait_8254_wraparound();
-    else
-        wait_tick_pvh();
-
-    /*
-     * We wrapped around just now. Let's start:
-     */
-    t1 = rdtsc_ordered();
     tt1 = apic_read(APIC_TMCCT);
 
     /*
      * Let's wait LOOPS ticks:
      */
     for (i = 0; i < LOOPS; i++)
-        if ( !xen_guest )
-            wait_8254_wraparound();
-        else
-            wait_tick_pvh();
+        wait_tick();
 
     tt2 = apic_read(APIC_TMCCT);
-    t2 = rdtsc_ordered();
 
     /*
      * The APIC bus clock counter is 32 bits only, it
@@ -1176,10 +1117,6 @@ static int __init calibrate_APIC_clock(void)
 
     result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
 
-    apic_printk(APIC_VERBOSE, "..... CPU clock speed is %ld.%04ld MHz.\n",
-                ((long)(t2 - t1) / LOOPS) / (1000000 / HZ),
-                ((long)(t2 - t1) / LOOPS) % (1000000 / HZ));
-
     apic_printk(APIC_VERBOSE, "..... host bus clock speed is %ld.%04ld MHz.\n",
                 result / (1000000 / HZ), result % (1000000 / HZ));
 
-- 
2.22.0

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.