diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-05-02 15:29:04 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-05-02 16:20:31 -0400 |
commit | c539914dcd9a68c63305e055b14115a6a19578a8 (patch) | |
tree | b422139d5d4628c8472fdf740dced263bc238c30 | |
parent | c1be5a5b1b355d40e6cf79cc979eb66dafa24ad1 (diff) |
tile: support new Tilera hypervisor
The Tilera hypervisor shipped in releases up through MDE 4.1 launches
the client operating system (i.e. Linux) at privilege level 1 (PL1).
Starting with MDE 4.2, as part of the work to enable KVM, the
Tilera hypervisor launches Linux at PL2 instead.
This commit makes the KERNEL_PL option default to 2 for tilegx, while
still saying at 1 for tilepro, which doesn't have an updated hypervisor.
It also explains how and when you might want to choose another value.
In addition, we change a small buglet in the on-chip Ethernet driver,
where we were failing to use the KERNEL_PL constant in an API call.
To make the transition cleaner, this change also provides the updated
hv_init() API for the new hypervisor that supports announcing Linux's
compiled-in PL, so the hypervisor can generate a suitable error in the
case of a mismatched hypervisor and Linux binary.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Cc: stable@vger.linux.org
-rw-r--r-- | arch/tile/Kconfig | 14 | ||||
-rw-r--r-- | arch/tile/include/hv/hypervisor.h | 27 | ||||
-rw-r--r-- | arch/tile/kernel/head_32.S | 2 | ||||
-rw-r--r-- | arch/tile/kernel/head_64.S | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/tile/tilegx.c | 2 |
5 files changed, 45 insertions, 12 deletions
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 25877aebc685..41a2a0becc18 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -368,11 +368,17 @@ config HARDWALL | |||
368 | config KERNEL_PL | 368 | config KERNEL_PL |
369 | int "Processor protection level for kernel" | 369 | int "Processor protection level for kernel" |
370 | range 1 2 | 370 | range 1 2 |
371 | default "1" | 371 | default 2 if TILEGX |
372 | default 1 if !TILEGX | ||
372 | ---help--- | 373 | ---help--- |
373 | This setting determines the processor protection level the | 374 | Since MDE 4.2, the Tilera hypervisor runs the kernel |
374 | kernel will be built to run at. Generally you should use | 375 | at PL2 by default. If running under an older hypervisor, |
375 | the default value here. | 376 | or as a KVM guest, you must run at PL1. (The current |
377 | hypervisor may also be recompiled with "make HV_PL=2" to | ||
378 | allow it to run a kernel at PL1, but clients running at PL1 | ||
379 | are not expected to be supported indefinitely.) | ||
380 | |||
381 | If you're not sure, don't change the default. | ||
376 | 382 | ||
377 | source "arch/tile/gxio/Kconfig" | 383 | source "arch/tile/gxio/Kconfig" |
378 | 384 | ||
diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h index ccd847e2347f..837dca5328c2 100644 --- a/arch/tile/include/hv/hypervisor.h +++ b/arch/tile/include/hv/hypervisor.h | |||
@@ -107,7 +107,22 @@ | |||
107 | #define HV_DISPATCH_ENTRY_SIZE 32 | 107 | #define HV_DISPATCH_ENTRY_SIZE 32 |
108 | 108 | ||
109 | /** Version of the hypervisor interface defined by this file */ | 109 | /** Version of the hypervisor interface defined by this file */ |
110 | #define _HV_VERSION 11 | 110 | #define _HV_VERSION 13 |
111 | |||
112 | /** Last version of the hypervisor interface with old hv_init() ABI. | ||
113 | * | ||
114 | * The change from version 12 to version 13 corresponds to launching | ||
115 | * the client by default at PL2 instead of PL1 (corresponding to the | ||
116 | * hv itself running at PL3 instead of PL2). To make this explicit, | ||
117 | * the hv_init() API was also extended so the client can report its | ||
118 | * desired PL, resulting in a more helpful failure diagnostic. If you | ||
119 | * call hv_init() with _HV_VERSION_OLD_HV_INIT and omit the client_pl | ||
120 | * argument, the hypervisor will assume client_pl = 1. | ||
121 | * | ||
122 | * Note that this is a deprecated solution and we do not expect to | ||
123 | * support clients of the Tilera hypervisor running at PL1 indefinitely. | ||
124 | */ | ||
125 | #define _HV_VERSION_OLD_HV_INIT 12 | ||
111 | 126 | ||
112 | /* Index into hypervisor interface dispatch code blocks. | 127 | /* Index into hypervisor interface dispatch code blocks. |
113 | * | 128 | * |
@@ -377,7 +392,11 @@ typedef int HV_Errno; | |||
377 | #ifndef __ASSEMBLER__ | 392 | #ifndef __ASSEMBLER__ |
378 | 393 | ||
379 | /** Pass HV_VERSION to hv_init to request this version of the interface. */ | 394 | /** Pass HV_VERSION to hv_init to request this version of the interface. */ |
380 | typedef enum { HV_VERSION = _HV_VERSION } HV_VersionNumber; | 395 | typedef enum { |
396 | HV_VERSION = _HV_VERSION, | ||
397 | HV_VERSION_OLD_HV_INIT = _HV_VERSION_OLD_HV_INIT, | ||
398 | |||
399 | } HV_VersionNumber; | ||
381 | 400 | ||
382 | /** Initializes the hypervisor. | 401 | /** Initializes the hypervisor. |
383 | * | 402 | * |
@@ -385,9 +404,11 @@ typedef enum { HV_VERSION = _HV_VERSION } HV_VersionNumber; | |||
385 | * that this program expects, typically HV_VERSION. | 404 | * that this program expects, typically HV_VERSION. |
386 | * @param chip_num Architecture number of the chip the client was built for. | 405 | * @param chip_num Architecture number of the chip the client was built for. |
387 | * @param chip_rev_num Revision number of the chip the client was built for. | 406 | * @param chip_rev_num Revision number of the chip the client was built for. |
407 | * @param client_pl Privilege level the client is built for | ||
408 | * (not required if interface_version_number == HV_VERSION_OLD_HV_INIT). | ||
388 | */ | 409 | */ |
389 | void hv_init(HV_VersionNumber interface_version_number, | 410 | void hv_init(HV_VersionNumber interface_version_number, |
390 | int chip_num, int chip_rev_num); | 411 | int chip_num, int chip_rev_num, int client_pl); |
391 | 412 | ||
392 | 413 | ||
393 | /** Queries we can make for hv_sysconf(). | 414 | /** Queries we can make for hv_sysconf(). |
diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S index f71bfeeaf1a9..ac115307e5e4 100644 --- a/arch/tile/kernel/head_32.S +++ b/arch/tile/kernel/head_32.S | |||
@@ -38,7 +38,7 @@ ENTRY(_start) | |||
38 | movei r2, TILE_CHIP_REV | 38 | movei r2, TILE_CHIP_REV |
39 | } | 39 | } |
40 | { | 40 | { |
41 | moveli r0, _HV_VERSION | 41 | moveli r0, _HV_VERSION_OLD_HV_INIT |
42 | jal hv_init | 42 | jal hv_init |
43 | } | 43 | } |
44 | /* Get a reasonable default ASID in r0 */ | 44 | /* Get a reasonable default ASID in r0 */ |
diff --git a/arch/tile/kernel/head_64.S b/arch/tile/kernel/head_64.S index f9a2734f7b82..6093964fa5c7 100644 --- a/arch/tile/kernel/head_64.S +++ b/arch/tile/kernel/head_64.S | |||
@@ -34,13 +34,19 @@ | |||
34 | ENTRY(_start) | 34 | ENTRY(_start) |
35 | /* Notify the hypervisor of what version of the API we want */ | 35 | /* Notify the hypervisor of what version of the API we want */ |
36 | { | 36 | { |
37 | #if KERNEL_PL == 1 && _HV_VERSION == 13 | ||
38 | /* Support older hypervisors by asking for API version 12. */ | ||
39 | movei r0, _HV_VERSION_OLD_HV_INIT | ||
40 | #else | ||
41 | movei r0, _HV_VERSION | ||
42 | #endif | ||
37 | movei r1, TILE_CHIP | 43 | movei r1, TILE_CHIP |
38 | movei r2, TILE_CHIP_REV | ||
39 | } | 44 | } |
40 | { | 45 | { |
41 | moveli r0, _HV_VERSION | 46 | movei r2, TILE_CHIP_REV |
42 | jal hv_init | 47 | movei r3, KERNEL_PL |
43 | } | 48 | } |
49 | jal hv_init | ||
44 | /* Get a reasonable default ASID in r0 */ | 50 | /* Get a reasonable default ASID in r0 */ |
45 | { | 51 | { |
46 | move r0, zero | 52 | move r0, zero |
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 66e025ad5df1..f3c2d034b32c 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c | |||
@@ -930,7 +930,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) | |||
930 | if (info->has_iqueue) { | 930 | if (info->has_iqueue) { |
931 | gxio_mpipe_request_notif_ring_interrupt( | 931 | gxio_mpipe_request_notif_ring_interrupt( |
932 | &context, cpu_x(cpu), cpu_y(cpu), | 932 | &context, cpu_x(cpu), cpu_y(cpu), |
933 | 1, ingress_irq, info->iqueue.ring); | 933 | KERNEL_PL, ingress_irq, info->iqueue.ring); |
934 | } | 934 | } |
935 | } | 935 | } |
936 | 936 | ||