Commit ccff9b1db693062b0a9c9070f4304deb47ef215c
Exists in
master
and in
20 other branches
Merge tag 'stable/for-linus-3.7-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
Pull Xen fixes from Konrad Rzeszutek Wilk: "This has four bug-fixes and one tiny feature that I forgot to put initially in my tree due to oversight. The feature is for kdump kernels to speed up the /proc/vmcore reading. There is a ram_is_pfn helper function that the different platforms can register for. We are now doing that. The bug-fixes cover some embarrassing struct pv_cpu_ops variables being set to NULL on Xen (but not baremetal). We had a similar issue in the past with {write|read}_msr_safe and this fills the three missing ones. The other bug-fix is to make the console output (hvc) be capable of dealing with misbehaving backends and not fall flat on its face. Lastly, a quirk for older XenBus implementations that came with an ancient v3.4 hypervisor (so RHEL5 based) - reading of certain non-existent attributes just hangs the guest during bootup - so we take precaution of not doing that on such older installations. Feature: - Register a pfn_is_ram helper to speed up reading of /proc/vmcore. Bug-fixes: - Three pvops call for Xen were undefined causing BUG_ONs. - Add a quirk so that the shutdown watches (used by kdump) are not used with older Xen (3.4). - Fix ungraceful state transition for the HVC console." * tag 'stable/for-linus-3.7-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen/pv-on-hvm kexec: add quirk for Xen 3.4 and shutdown watches. xen/bootup: allow {read|write}_cr8 pvops call. xen/bootup: allow read_tscp call for Xen PV guests. xen pv-on-hvm: add pfn_is_ram helper for kdump xen/hvc: handle backend CLOSED without CLOSING
Showing 5 changed files Side-by-side Diff
arch/x86/xen/enlighten.c
... | ... | @@ -987,7 +987,16 @@ |
987 | 987 | |
988 | 988 | native_write_cr4(cr4); |
989 | 989 | } |
990 | - | |
990 | +#ifdef CONFIG_X86_64 | |
991 | +static inline unsigned long xen_read_cr8(void) | |
992 | +{ | |
993 | + return 0; | |
994 | +} | |
995 | +static inline void xen_write_cr8(unsigned long val) | |
996 | +{ | |
997 | + BUG_ON(val); | |
998 | +} | |
999 | +#endif | |
991 | 1000 | static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) |
992 | 1001 | { |
993 | 1002 | int ret; |
... | ... | @@ -1156,6 +1165,11 @@ |
1156 | 1165 | .read_cr4_safe = native_read_cr4_safe, |
1157 | 1166 | .write_cr4 = xen_write_cr4, |
1158 | 1167 | |
1168 | +#ifdef CONFIG_X86_64 | |
1169 | + .read_cr8 = xen_read_cr8, | |
1170 | + .write_cr8 = xen_write_cr8, | |
1171 | +#endif | |
1172 | + | |
1159 | 1173 | .wbinvd = native_wbinvd, |
1160 | 1174 | |
1161 | 1175 | .read_msr = native_read_msr_safe, |
... | ... | @@ -1163,6 +1177,8 @@ |
1163 | 1177 | |
1164 | 1178 | .read_tsc = native_read_tsc, |
1165 | 1179 | .read_pmc = native_read_pmc, |
1180 | + | |
1181 | + .read_tscp = native_read_tscp, | |
1166 | 1182 | |
1167 | 1183 | .iret = xen_iret, |
1168 | 1184 | .irq_enable_sysexit = xen_sysexit, |
arch/x86/xen/mmu.c
... | ... | @@ -47,6 +47,7 @@ |
47 | 47 | #include <linux/gfp.h> |
48 | 48 | #include <linux/memblock.h> |
49 | 49 | #include <linux/seq_file.h> |
50 | +#include <linux/crash_dump.h> | |
50 | 51 | |
51 | 52 | #include <trace/events/xen.h> |
52 | 53 | |
... | ... | @@ -2381,6 +2382,43 @@ |
2381 | 2382 | EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region); |
2382 | 2383 | |
2383 | 2384 | #ifdef CONFIG_XEN_PVHVM |
2385 | +#ifdef CONFIG_PROC_VMCORE | |
2386 | +/* | |
2387 | + * This function is used in two contexts: | |
2388 | + * - the kdump kernel has to check whether a pfn of the crashed kernel | |
2389 | + * was a ballooned page. vmcore is using this function to decide | |
2390 | + * whether to access a pfn of the crashed kernel. | |
2391 | + * - the kexec kernel has to check whether a pfn was ballooned by the | |
2392 | + * previous kernel. If the pfn is ballooned, handle it properly. | |
2393 | + * Returns 0 if the pfn is not backed by a RAM page, the caller may | |
2394 | + * handle the pfn special in this case. | |
2395 | + */ | |
2396 | +static int xen_oldmem_pfn_is_ram(unsigned long pfn) | |
2397 | +{ | |
2398 | + struct xen_hvm_get_mem_type a = { | |
2399 | + .domid = DOMID_SELF, | |
2400 | + .pfn = pfn, | |
2401 | + }; | |
2402 | + int ram; | |
2403 | + | |
2404 | + if (HYPERVISOR_hvm_op(HVMOP_get_mem_type, &a)) | |
2405 | + return -ENXIO; | |
2406 | + | |
2407 | + switch (a.mem_type) { | |
2408 | + case HVMMEM_mmio_dm: | |
2409 | + ram = 0; | |
2410 | + break; | |
2411 | + case HVMMEM_ram_rw: | |
2412 | + case HVMMEM_ram_ro: | |
2413 | + default: | |
2414 | + ram = 1; | |
2415 | + break; | |
2416 | + } | |
2417 | + | |
2418 | + return ram; | |
2419 | +} | |
2420 | +#endif | |
2421 | + | |
2384 | 2422 | static void xen_hvm_exit_mmap(struct mm_struct *mm) |
2385 | 2423 | { |
2386 | 2424 | struct xen_hvm_pagetable_dying a; |
... | ... | @@ -2411,6 +2449,9 @@ |
2411 | 2449 | { |
2412 | 2450 | if (is_pagetable_dying_supported()) |
2413 | 2451 | pv_mmu_ops.exit_mmap = xen_hvm_exit_mmap; |
2452 | +#ifdef CONFIG_PROC_VMCORE | |
2453 | + register_oldmem_pfn_is_ram(&xen_oldmem_pfn_is_ram); | |
2454 | +#endif | |
2414 | 2455 | } |
2415 | 2456 | #endif |
2416 | 2457 |
drivers/tty/hvc/hvc_xen.c
... | ... | @@ -478,7 +478,6 @@ |
478 | 478 | case XenbusStateInitialising: |
479 | 479 | case XenbusStateInitialised: |
480 | 480 | case XenbusStateUnknown: |
481 | - case XenbusStateClosed: | |
482 | 481 | break; |
483 | 482 | |
484 | 483 | case XenbusStateInitWait: |
... | ... | @@ -488,6 +487,10 @@ |
488 | 487 | xenbus_switch_state(dev, XenbusStateConnected); |
489 | 488 | break; |
490 | 489 | |
490 | + case XenbusStateClosed: | |
491 | + if (dev->state == XenbusStateClosed) | |
492 | + break; | |
493 | + /* Missed the backend's CLOSING state -- fallthrough */ | |
491 | 494 | case XenbusStateClosing: |
492 | 495 | xenbus_frontend_closed(dev); |
493 | 496 | break; |
drivers/xen/xenbus/xenbus_xs.c
... | ... | @@ -48,6 +48,7 @@ |
48 | 48 | #include <xen/xenbus.h> |
49 | 49 | #include <xen/xen.h> |
50 | 50 | #include "xenbus_comms.h" |
51 | +#include <asm/xen/hypervisor.h> | |
51 | 52 | |
52 | 53 | struct xs_stored_msg { |
53 | 54 | struct list_head list; |
54 | 55 | |
55 | 56 | |
... | ... | @@ -618,12 +619,32 @@ |
618 | 619 | |
619 | 620 | return NULL; |
620 | 621 | } |
622 | +/* | |
623 | + * Certain older XenBus toolstack cannot handle reading values that are | |
624 | + * not populated. Some Xen 3.4 installation are incapable of doing this | |
625 | + * so if we are running on anything older than 4 do not attempt to read | |
626 | + * control/platform-feature-xs_reset_watches. | |
627 | + */ | |
628 | +static bool xen_strict_xenbus_quirk() | |
629 | +{ | |
630 | + uint32_t eax, ebx, ecx, edx, base; | |
621 | 631 | |
632 | + base = xen_cpuid_base(); | |
633 | + cpuid(base + 1, &eax, &ebx, &ecx, &edx); | |
634 | + | |
635 | + if ((eax >> 16) < 4) | |
636 | + return true; | |
637 | + return false; | |
638 | + | |
639 | +} | |
622 | 640 | static void xs_reset_watches(void) |
623 | 641 | { |
624 | 642 | int err, supported = 0; |
625 | 643 | |
626 | 644 | if (!xen_hvm_domain() || xen_initial_domain()) |
645 | + return; | |
646 | + | |
647 | + if (xen_strict_xenbus_quirk()) | |
627 | 648 | return; |
628 | 649 | |
629 | 650 | err = xenbus_scanf(XBT_NIL, "control", |
include/xen/interface/hvm/hvm_op.h
... | ... | @@ -43,5 +43,24 @@ |
43 | 43 | typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t; |
44 | 44 | DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_pagetable_dying_t); |
45 | 45 | |
46 | +enum hvmmem_type_t { | |
47 | + HVMMEM_ram_rw, /* Normal read/write guest RAM */ | |
48 | + HVMMEM_ram_ro, /* Read-only; writes are discarded */ | |
49 | + HVMMEM_mmio_dm, /* Reads and write go to the device model */ | |
50 | +}; | |
51 | + | |
52 | +#define HVMOP_get_mem_type 15 | |
53 | +/* Return hvmmem_type_t for the specified pfn. */ | |
54 | +struct xen_hvm_get_mem_type { | |
55 | + /* Domain to be queried. */ | |
56 | + domid_t domid; | |
57 | + /* OUT variable. */ | |
58 | + uint16_t mem_type; | |
59 | + uint16_t pad[2]; /* align next field on 8-byte boundary */ | |
60 | + /* IN variable. */ | |
61 | + uint64_t pfn; | |
62 | +}; | |
63 | +DEFINE_GUEST_HANDLE_STRUCT(xen_hvm_get_mem_type); | |
64 | + | |
46 | 65 | #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ |